def onTextMessage(self, payload): #print("Text message received: {0}".format(payload)) packet = json.loads(payload) type = packet["type"] if self.stat == "l": if type == "l00": # Input state ready if self.player is not None or self.pendingStat is None: self.sendClose() return self.pendingStat = None self.stopDCTimer() if self.address != "127.0.0.1" and self.server.getPlayerCountByAddress( self.address) >= self.server.maxSimulIP: self.exception("Too many connections") self.sendClose() return for b in self.server.blocked: if b[0] == self.address: self.blocked = True self.setState("g") # Ingame return name = packet["name"] team = packet["team"][:3].strip().upper() priv = packet["private"] skin = int(packet["skin"]) if "skin" in packet else 0 self.player = Player( self, name if self.username != "" else ("*" + name), team if team != "" else self.server.defaultTeam, self.server.getMatch( team, priv if "private" in packet else False), skin if skin in range(NUM_SKINS) else 0) self.loginSuccess() self.server.players.append(self.player) self.setState("g") # Ingame elif type == "llg": #login if self.username != "" or self.player is not None or self.pendingStat is None: self.sendClose() return self.stopDCTimer() username = packet["username"].upper() if self.address in self.server.loginBlocked: self.sendJSON({ "type": "llg", "status": False, "msg": "max login tries reached.\ntry again in one minute." }) return elif username in self.server.authd: self.sendJSON({ "type": "llg", "status": False, "msg": "account already in use" }) return status, msg = datastore.login(username, packet["password"]) if status: self.username = username self.session = msg["session"] self.server.authd.append(self.username) else: if self.address not in self.server.maxLoginTries: self.server.maxLoginTries[self.address] = 1 else: self.server.maxLoginTries[self.address] += 1 if self.server.maxLoginTries[self.address] >= 4: del self.server.maxLoginTries[self.address] self.server.loginBlocked.append(self.address) reactor.callLater(60, self.server.loginBlocked.remove, self.address) self.sendJSON({"type": "llg", "status": status, "msg": msg}) elif type == "llo": #logout if self.username == "" or self.player is not None or self.pendingStat is None: self.sendClose() return datastore.logout(self.session) self.sendJSON({"type": "llo"}) elif type == "lrg": #register if self.username != "" or self.address not in self.server.captchas or self.player is not None or self.pendingStat is None: self.sendClose() return self.stopDCTimer() username = packet["username"].upper() if CP_IMPORT and len(packet["captcha"]) != 5: status, msg = False, "invalid captcha" elif CP_IMPORT and packet["captcha"].upper( ) != self.server.captchas[self.address]: status, msg = False, "incorrect captcha" elif self.server.checkCurse(username): status, msg = False, "please choose a different username" else: status, msg = datastore.register(username, packet["password"]) if status: del self.server.captchas[self.address] self.username = username self.session = msg["session"] self.server.authd.append(self.username) self.sendJSON({"type": "lrg", "status": status, "msg": msg}) elif type == "lrc": #request captcha if self.username != "" or self.player is not None or self.pendingStat is None: self.sendClose() return if not CP_IMPORT: self.server.captchas[self.address] = "" self.sendJSON({"type": "lrc", "data": ""}) return self.stopDCTimer() cp = ''.join( random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(5)) self.server.captchas[self.address] = cp imageCaptcha = ImageCaptcha() image = imageCaptcha.generate_image(cp) imgByteArr = BytesIO() image.save(imgByteArr, format='PNG') imgByteArr = imgByteArr.getvalue() self.sendJSON({ "type": "lrc", "data": base64.b64encode(imgByteArr).decode("utf-8") }) elif type == "lrs": #resume session if self.username != "" or self.player is not None or self.pendingStat is None: self.sendClose() return self.stopDCTimer() status, msg = datastore.resumeSession(packet["session"]) if status: if msg["username"] in self.server.authd: self.sendJSON({ "type": "lrs", "status": False, "msg": "account already in use" }) return self.username = msg["username"] self.session = msg["session"] self.server.authd.append(self.username) self.sendJSON({"type": "lrs", "status": status, "msg": msg}) elif type == "lpr": #update profile if self.username == "" or self.player is not None or self.pendingStat is None: self.sendClose() return datastore.updateAccount(self.username, packet) elif self.stat == "g": if type == "g00": # Ingame state ready if self.player is None or self.pendingStat is None: if self.blocked: self.sendJSON({ "packets": [{ "game": "jail", "type": "g01" }], "type": "s01" }) return self.sendClose() return self.pendingStat = None self.player.onEnterIngame() elif type == "g03": # World load completed if self.player is None: if self.blocked: self.sendBin(0x02, Buffer().writeInt16(0).writeInt16(0)) self.startDCTimer(15) return self.sendClose() return self.player.onLoadComplete() elif type == "g50": # Vote to start if self.player is None or self.player.voted or self.player.match.playing: return self.player.voted = True self.player.match.voteStart() elif type == "g51": # (SPECIAL) Force start if self.server.mcode and self.server.mcode in packet["code"]: self.player.match.start(True) elif type == "gsl": # Level select if self.player is None or self.player.team != "" or not self.player.match.private: return levelName = packet["name"] if levelName == "custom": try: self.player.match.selectCustomLevel(packet["data"]) except Exception as e: estr = str(e) estr = "\n".join(estr.split("\n")[:10]) self.sendJSON({ "type": "gsl", "name": levelName, "status": "error", "message": estr }) return self.sendJSON({ "type": "gsl", "name": levelName, "status": "success", "message": "" }) else: self.player.match.selectLevel(levelName)
def onTextMessage(self, payload): #print("Text message received: {0}".format(payload)) packet = json.loads(payload) type = packet["type"] if self.stat == "l": if type == "l00": # Input state ready if self.player is not None or self.pendingStat is None: self.sendClose2() return self.pendingStat = None self.stopDCTimer() if self.address != "127.0.0.1" and self.server.getPlayerCountByAddress( self.address) >= self.server.maxSimulIP: self.sendClose2() return if self.server.shuttingDown: self.setState("g") # Ingame return for b in self.server.blocked: if b[0] == self.address: self.blocked = True self.setState("g") # Ingame return if self.username != "": if self.accountPriv["isBanned"]: self.blocked = True self.setState("g") # Ingame return name = packet["name"] team = packet["team"][:3].strip().upper() priv = packet["private"] if "private" in packet else False skin = int(packet["skin"]) if "skin" in packet else 0 if not self.account and self.server.restrictPublicSkins and 0 < len( self.server.guestSkins): if not skin in self.server.guestSkins: skin = self.server.guestSkins[0] gm = int(packet["gm"]) if "gm" in packet else 0 gm = gm if gm in range(NUM_GM) else 0 gm = ["royale", "pvp", "hell"][gm] isDev = self.account[ "isDev"] if "isDev" in self.account else False self.player = Player( self, name, (team if (team != "" or priv) else self.server.defaultTeam).lower(), self.server.getMatch(team, priv, gm), skin if skin in range(self.server.skinCount) else 0, gm, isDev) #if priv: # self.maxConLifeTimer.cancel() self.loginSuccess() self.server.players.append(self.player) self.setState("g") # Ingame elif type == "llg": #login if self.username != "" or self.player is not None or self.pendingStat is None: self.sendClose2() return self.stopDCTimer() username = packet["username"].upper() if self.address in self.server.loginBlocked: self.sendJSON({ "type": "llg", "status": False, "msg": "max login tries reached.\ntry again in one minute." }) return elif username in self.server.authd: self.sendJSON({ "type": "llg", "status": False, "msg": "account already in use" }) return status, msg, self.accountPriv = datastore.login( self.dbSession, username, packet["password"]) j = {"type": "llg", "status": status, "msg": msg} if status: self.account = msg j["username"] = self.username = username self.session = msg["session"] self.server.authd.append(self.username) else: if self.address not in self.server.maxLoginTries: self.server.maxLoginTries[self.address] = 1 else: self.server.maxLoginTries[self.address] += 1 if self.server.maxLoginTries[self.address] >= 4: del self.server.maxLoginTries[self.address] self.server.loginBlocked.append(self.address) reactor.callLater(60, self.server.loginBlocked.remove, self.address) self.sendJSON(j) elif type == "llo": #logout if self.username == "" or self.player is not None or self.pendingStat is None: self.sendClose2() return datastore.logout(self.dbSession, self.session) self.sendJSON({"type": "llo"}) elif type == "lrg": #register if self.username != "" or self.address not in self.server.captchas or self.player is not None or self.pendingStat is None: self.sendClose2() return self.stopDCTimer() username = packet["username"].upper() if CP_IMPORT and len(packet["captcha"]) != 5: status, msg = False, "invalid captcha" elif CP_IMPORT and packet["captcha"].upper( ) != self.server.captchas[self.address]: status, msg = False, "incorrect captcha" elif util.checkCurse(username): status, msg = False, "please choose a different username" else: status, msg, self.accountPriv = datastore.register( self.dbSession, username, packet["password"]) if status: del self.server.captchas[self.address] self.account = msg self.username = username self.session = msg["session"] self.server.authd.append(self.username) self.sendJSON({"type": "lrg", "status": status, "msg": msg}) elif type == "lrc": #request captcha if self.username != "" or self.player is not None or self.pendingStat is None: self.sendClose2() return if not CP_IMPORT: self.server.captchas[self.address] = "" self.sendJSON({"type": "lrc", "data": ""}) return self.stopDCTimer() cp = ''.join( random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(5)) self.server.captchas[self.address] = cp imageCaptcha = ImageCaptcha() image = imageCaptcha.generate_image(cp) imgByteArr = BytesIO() image.save(imgByteArr, format='PNG') imgByteArr = imgByteArr.getvalue() self.sendJSON({ "type": "lrc", "data": base64.b64encode(imgByteArr).decode("utf-8") }) elif type == "lrs": #resume session if self.username != "" or self.player is not None or self.pendingStat is None: self.sendClose2() return self.stopDCTimer() status, msg, self.accountPriv = datastore.resumeSession( self.dbSession, packet["session"]) j = {"type": "lrs", "status": status, "msg": msg} if status: if msg["username"] in self.server.authd: self.sendJSON({ "type": "lrs", "status": False, "msg": "account already in use" }) return j["username"] = self.username = msg["username"] self.account = msg self.session = msg["session"] self.server.authd.append(self.username) self.sendJSON(j) elif type == "lpr": #update profile if self.username == "" or self.player is not None or self.pendingStat is None: self.sendClose2() return res = datastore.updateAccount(self.dbSession, self.username, packet) j = { "type": "lpr", "status": res[0], "changes": res[1], "msg": res[2] } self.sendJSON(j) elif type == "lpc": #password change if self.username == "" or self.player is not None or self.pendingStat is None: self.sendClose2() return datastore.changePassword(self.dbSession, self.username, packet["password"]) elif self.stat == "g": if type == "g00": # Ingame state ready if self.player is None or self.pendingStat is None: if self.server.shuttingDown: levelName, levelData = self.server.getRandomLevel( "maintenance", None) self.sendJSON({ "packets": [{ "game": levelName, "levelData": json.dumps(levelData), "type": "g01" }], "type": "s01" }) return if self.blocked: levelName, levelData = self.server.getRandomLevel( "jail", None) self.sendJSON({ "packets": [{ "game": levelName, "levelData": json.dumps(levelData), "type": "g01" }], "type": "s01" }) return self.sendClose2() return self.pendingStat = None self.player.onEnterIngame() elif type == "g03": # World load completed if self.player is None: if self.blocked or self.server.shuttingDown: self.sendBin( 0x02, Buffer().writeInt16(0).writeInt16(0).writeInt8(0)) #self.startDCTimer(15) return self.sendClose2() return self.player.onLoadComplete() elif type == "g50": # Vote to start if self.player is None or self.player.voted or self.player.match.playing: return self.player.voted = True self.player.match.voteStart() elif type == "g51": # (SPECIAL) Force start if self.server.mcode and self.server.mcode in packet["code"]: self.player.match.start(True) elif type == "gsl": # Level select if self.player is None or ( (not self.server.enableLevelSelectInMultiPrivate and self.player.team != "") or not self.player.match.private ) and not self.player.isDev: return levelName = packet["name"] if levelName == "custom": try: self.player.match.selectCustomLevel(packet["data"]) except Exception as e: estr = str(e) estr = "\n".join(estr.split("\n")[:10]) self.sendJSON({ "type": "gsl", "name": levelName, "status": "error", "message": estr }) return self.sendJSON({ "type": "gsl", "name": levelName, "status": "success", "message": "" }) else: self.player.match.selectLevel(levelName) elif type == "gbn": # ban player if not self.account["isDev"]: self.sendClose2() pid = packet["pid"] ban = packet["ban"] self.player.match.banPlayer(pid, ban) elif type == "gnm": # rename player if not self.account["isDev"]: self.sendClose2() pid = packet["pid"] newName = packet["name"] self.player.match.renamePlayer(pid, newName) elif type == "gsq": # resquad player if not self.account["isDev"]: self.sendClose2() pid = packet["pid"] newName = packet["name"].lower() if len(newName) > 3: newName = newName[:3] self.player.match.resquadPlayer(pid, newName) else: print("unknown message! " + payload)