Exemple #1
0
    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)
Exemple #2
0
    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)