summaryrefslogtreecommitdiff
path: root/server/piztor/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'server/piztor/server.py')
-rw-r--r--server/piztor/server.py240
1 files changed, 202 insertions, 38 deletions
diff --git a/server/piztor/server.py b/server/piztor/server.py
index 980ae03..7996e0a 100644
--- a/server/piztor/server.py
+++ b/server/piztor/server.py
@@ -44,6 +44,7 @@ class _SectionSize:
LONGITUDE = 8
PADDING = 1
DEADLINE = 4
+ MARKER_ID = 1
_MAX_AUTH_HEAD_SIZE = _SectionSize.USER_TOKEN + \
MAX_USERNAME_SIZE + \
@@ -54,6 +55,7 @@ _HEADER_SIZE = _SectionSize.LENGTH + \
_MAX_TEXT_MESG_SIZE = 1024
_MAX_SUB_LIST_SIZE = 10
_MAX_PENDING_PUSH = 10
+_INIT_MARKER_NUM = 2
class _OptCode:
user_auth = 0x00
@@ -65,6 +67,8 @@ class _OptCode:
send_text_mesg = 0x06
set_marker = 0x07
change_password = 0x08
+ check_in = 0x09
+ game_start = 0x0A
class _StatusCode:
sucess = 0x00
@@ -72,6 +76,7 @@ class _StatusCode:
insuf_lvl = 0x02
wrong_pass = 0x03
grp_not_found = 0x04
+ checkin_fail = 0x05
class PushData(object):
from hashlib import sha256
@@ -91,8 +96,16 @@ class PushLocationData(PushData):
self.pack(0x01, struct.pack("!Ldd", uid, lat, lng))
class PushMarkerData(PushData):
- def __init__(self, perm, lat, lng, deadline):
- self.pack(0x02, struct.pack("!Bddl", perm, lat, lng, deadline))
+ def __init__(self, perm, lat, lng, deadline, mid, score):
+ self.pack(0x02, struct.pack("!BddlBL", perm, lat, lng, deadline,
+ mid, score))
+class PushMarkerRemovalData(PushData):
+ def __init__(self, mid):
+ self.pack(0x03, struct.pack("!B", mid))
+
+class PushScoreData(PushData):
+ def __init__(self, score1, score2):
+ self.pack(0x04, struct.pack("!LL", score1, score2))
class PushTunnel(object):
def __init__(self, uid):
@@ -126,8 +139,8 @@ class PushTunnel(object):
def push(self):
if self.blocked:
return
- #print "Pushing via " + str(self.uid)
- #print "Pending size: " + str(len(self.pending))
+ print "Pushing via " + str(self.uid)
+ print "Pending size: " + str(len(self.pending))
#logger.info("Pushing...")
if (self.conn is None) or len(self.pending) == 0:
return
@@ -335,6 +348,17 @@ class UserAuthHandler(RequestHandler):
# USER_ENTRY
reply += RequestHandler.pack_user_entry(user)
reply += RequestHandler.pack_sub_list(user)
+ score1 = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == 5889).one().score
+ score2 = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == 5890).one().score
+
+ for mrk in self.session.query(MarkerInfo).all():
+ if mrk.status != MARKER_DISPLAYED:
+ continue
+ reply += struct.pack("!BddlBL", 2, mrk.lat, mrk.lng, 0x7fffffff,
+ mrk.id, mrk.score)
+ reply += struct.pack("!LL", score1, score2)
return self.pack(reply)
@@ -357,9 +381,9 @@ class UpdateLocationHandler(RequestHandler):
except struct.error:
raise BadReqError("Update location: Malformed request body")
-# logger.info("Trying to update location with "
-# "(token = {0}, username = {1}, lat = {2}, lng = {3})"\
-# .format(get_hex(token), username, lat, lng))
+ logger.info("Trying to update location with "
+ "(token = {0}, username = {1}, lat = {2}, lng = {3})"\
+ .format(get_hex(token), username, lat, lng))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -384,15 +408,6 @@ class UpdateLocationHandler(RequestHandler):
pdata = PushLocationData(u.id, lat, lng)
for user in comp.subscribers:
uid = user.id
- if uid == uauth.uid: continue
- if pt.has_key(uid):
- tunnel = pt[uid]
- tunnel.add(pdata)
- tunnel.push()
-
- for user in sec.subscribers:
- uid = user.id
- if uid == uauth.uid: continue
if pt.has_key(uid):
tunnel = pt[uid]
tunnel.add(pdata)
@@ -638,6 +653,32 @@ class SetMarkerHandler(RequestHandler):
_SectionSize.LATITUDE + \
_SectionSize.LONGITUDE + \
_SectionSize.DEADLINE
+ @classmethod
+ def push_new_marker(cls, u, session):
+ left = session.query(MarkerInfo) \
+ .filter(MarkerInfo.status == MARKER_FRESH).all()
+ if len(left) == 0:
+ logger.warn("All markers have been used!")
+ return
+ marker = left[0]
+ marker.status = MARKER_DISPLAYED
+ session.commit()
+ pdata = PushMarkerData(perm = 2, lat = marker.lat, \
+ lng = marker.lng, \
+ deadline = 0x7fffffff, \
+ mid = marker.id, \
+ score = marker.score)
+ ulist = session.query(UserModel) \
+ .filter(UserModel.comp_id == u.comp_id).all()
+
+ pt = RequestHandler.push_tunnels
+ for user in ulist:
+ uid = user.id
+ if pt.has_key(uid):
+ tunnel = pt[uid]
+ tunnel.add(pdata)
+ tunnel.push()
+
def handle(self, tr_data, conn):
self.check_size(tr_data)
@@ -645,15 +686,15 @@ class SetMarkerHandler(RequestHandler):
try:
token, = struct.unpack("!32s", tr_data[:32])
username, tail = RequestHandler.trunc_padding(tr_data[32:])
- lat, lng, deadline = struct.unpack("!ddl", tail)
+ lat, lng, deadline, mid, score = struct.unpack("!ddlBL", tail)
if username is None:
raise struct.error
except struct.error:
raise BadReqError("Set marker: Malformed request body")
-# logger.info("Trying to set marker with "
-# "(token = {0}, username = {1})"\
-# .format(get_hex(token), username))
+ logger.info("Trying to set marker with "
+ "(token = {0}, username = {1})"\
+ .format(get_hex(token), username))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -661,24 +702,8 @@ class SetMarkerHandler(RequestHandler):
logger.warning("Authentication failure")
return self.pack(struct.pack("!B", _StatusCode.auth_fail))
- pt = RequestHandler.push_tunnels
- u = uauth.user
- if u.perm == _PermCode.section:
- ulist = self.session.query(UserModel) \
- .filter(UserModel.sec_id == u.sec_id).all()
- elif u.perm == _PermCode.company:
- ulist = self.session.query(UserModel) \
- .filter(UserModel.comp_id == u.comp_id).all()
- else:
- return self.pack(struct.pack("!B", _StatusCode.insuf_lvl))
+ SetMarkerHandler.push_new_marker(uauth.user, self.session)
- for user in ulist:
- uid = user.id
- if uid == uauth.uid: continue
- if pt.has_key(uid):
- tunnel = pt[uid]
- tunnel.add(PushMarkerData(u.perm, lat, lng, deadline))
- tunnel.push()
logger.info("Set marker successfully!")
return self.pack(struct.pack("!B", _StatusCode.sucess))
@@ -727,6 +752,143 @@ class ChangePasswordHandler(RequestHandler):
return self.pack(struct.pack("!B", _StatusCode.sucess))
+class CheckInHandler(RequestHandler):
+
+ _optcode = _OptCode.check_in
+ _max_tr_data_size = _MAX_AUTH_HEAD_SIZE + \
+ _SectionSize.MARKER_ID
+
+ def handle(self, tr_data, conn):
+ self.check_size(tr_data)
+ logger.info("Reading check-in data...")
+ try:
+ token, = struct.unpack("!32s", tr_data[:32])
+ username, tail = RequestHandler.trunc_padding(tr_data[32:])
+ if username is None:
+ raise struct.error
+ mid, = struct.unpack("!B", tail)
+ except struct.error:
+ raise BadReqError("Check-in: Malformed request body")
+
+ logger.info("Trying to check-in with "
+ "(token = {0}, username = {1}, mid = {2})"\
+ .format(get_hex(token), username, str(mid)))
+
+ uauth = RequestHandler.get_uauth(token, username, self.session)
+ # Authentication failure
+ if uauth is None:
+ logger.warning("Authentication failure")
+ return self.pack(struct.pack("!B", _StatusCode.auth_fail))
+
+ try:
+ marker = self.session.query(MarkerInfo) \
+ .filter(MarkerInfo.id == mid).one()
+ except NoResultFound:
+ raise BadReqError("Check-in: no such marker")
+
+ if marker.status != MARKER_DISPLAYED:
+ return self.pack(struct.pack("!B", _StatusCode.checkin_fail))
+ marker.status = MARKER_CHECKED
+
+ pt = RequestHandler.push_tunnels
+ u = uauth.user
+
+ comp = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == u.comp_id).one()
+ sec = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == u.sec_id).one()
+
+ sec.score += marker.score
+ logger.info("Player {0} got score: {1}".format(username, str(marker.score)))
+
+ score1 = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == 5889).one().score
+ score2 = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == 5890).one().score
+
+ pdata = PushMarkerRemovalData(mid)
+ for user in comp.subscribers:
+ uid = user.id
+ if pt.has_key(uid):
+ tunnel = pt[uid]
+ tunnel.add(pdata)
+ tunnel.add(PushScoreData(score1, score2))
+ tunnel.push()
+
+ SetMarkerHandler.push_new_marker(u, self.session)
+
+ logger.info("User checked in successfully!")
+ self.session.commit()
+ return self.pack(struct.pack("!B", _StatusCode.sucess))
+
+class GameStartHandler(RequestHandler):
+
+ _optcode = _OptCode.game_start
+ _max_tr_data_size = _MAX_AUTH_HEAD_SIZE
+
+ def handle(self, tr_data, conn):
+ self.check_size(tr_data)
+ logger.info("Reading game-start data...")
+ try:
+ token, = struct.unpack("!32s", tr_data[:32])
+ username, tail = RequestHandler.trunc_padding(tr_data[32:])
+ if username is None:
+ raise struct.error
+ except struct.error:
+ raise BadReqError("Game-start: Malformed request body")
+
+ logger.info("Trying to game-start with "
+ "(token = {0}, username = {1})"\
+ .format(get_hex(token), username))
+
+ uauth = RequestHandler.get_uauth(token, username, self.session)
+ # Authentication failure
+ if uauth is None:
+ logger.warning("Authentication failure")
+ return self.pack(struct.pack("!B", _StatusCode.auth_fail))
+
+
+ pt = RequestHandler.push_tunnels
+ u = uauth.user
+
+ if u.perm != 2:
+ logger.warning("Insufficient privilege")
+ return self.pack(struct.pack("!B", _StatusCode.insuf_lvl))
+
+ team1 = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == 5889).one()
+ team2 = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == 5890).one()
+
+ team1.score = 0
+ team2.score = 0
+
+ for mrk in self.session.query(MarkerInfo).all():
+ mrk.status = MARKER_FRESH
+
+ users1 = self.session.query(UserModel) \
+ .filter(UserModel.sec_id == team1.id)
+
+ users2 = self.session.query(UserModel) \
+ .filter(UserModel.sec_id == team2.id)
+
+ for i in xrange(_INIT_MARKER_NUM):
+ SetMarkerHandler.push_new_marker(u, self.session)
+
+ comp = self.session.query(GroupInfo) \
+ .filter(GroupInfo.id == u.comp_id).one()
+
+ for user in comp.subscribers:
+ uid = user.id
+ if pt.has_key(uid):
+ tunnel = pt[uid]
+ tunnel.add(PushScoreData(team1.score, team2.score))
+ tunnel.push()
+
+ logger.info("GAME START!")
+ self.session.commit()
+ return self.pack(struct.pack("!B", _StatusCode.sucess))
+
class PTP(Protocol, TimeoutMixin):
@@ -738,7 +900,9 @@ class PTP(Protocol, TimeoutMixin):
OpenPushTunnelHandler,
SendTextMessageHandler,
SetMarkerHandler,
- ChangePasswordHandler]
+ ChangePasswordHandler,
+ CheckInHandler,
+ GameStartHandler]
handler_num = len(handlers)