def userJoin(self, userID): """ Add someone to users in match userID -- user id of the user return -- True if join success, False if fail (room is full) """ # Find first free slot for i in range(0, 16): if self.slots[i]["status"] == slotStatuses.free: # Occupy slot self.setSlot(i, slotStatuses.notReady, 0, userID, 0) # Send updated match data self.sendUpdate() # Console output consoleHelper.printColored( "> MPROOM{}: {} joined the room".format( self.matchID, userID), bcolors.BLUE) return True return False
def scheduleShutdown(sendRestartTime, restart, message = ""): """ Schedule a server shutdown/restart sendRestartTime -- time (seconds) to wait before sending server restart packets to every client restart -- if True, server will restart. if False, server will shudown message -- if set, send that message to every client to warn about the shutdown/restart """ # Console output consoleHelper.printColored("[!] Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+20), bcolors.PINK) consoleHelper.printColored("[!] Sending server restart packets in {} seconds...".format(sendRestartTime), bcolors.PINK) # Send notification if set if (message != ""): glob.tokens.enqueueAll(serverPackets.notification(message)) # Schedule server restart packet threading.Timer(sendRestartTime, glob.tokens.enqueueAll, [serverPackets.banchoRestart(50000)]).start() # Restart/shutdown if (restart): action = restartServer else: action = shutdownServer # Schedule actual server shutdown/restart 20 seconds after server restart packet, so everyone gets it threading.Timer(sendRestartTime+20, action).start()
def handle(userToken, _): # get usertoken data userID = userToken.userID username = userToken.username requestToken = userToken.token # Big client meme here. If someone logs out and logs in right after, # the old logout packet will still be in the queue and will be sent to # the server, so we accept logout packets sent at least 5 seconds after login # if the user logs out before 5 seconds, he will be disconnected later with timeout check if (int(time.time()-userToken.loginTime) >= 5): # Stop spectating if needed if (userToken.spectating != 0): # The user was spectating someone spectatorHostToken = glob.tokens.getTokenFromUserID(userToken.spectating) if (spectatorHostToken != None): # The host is still online, send removeSpectator to him spectatorHostToken.enqueue(serverPackets.removeSpectator(userID)) # Part all joined channels for i in userToken.joinedChannels: glob.channels.channels[i].userPart(userID) # TODO: Lobby left if joined # Enqueue our disconnection to everyone else glob.tokens.enqueueAll(serverPackets.userLogout(userID)) # Delete token glob.tokens.deleteToken(requestToken) # Console output consoleHelper.printColored("> {} have been disconnected.".format(username), bcolors.YELLOW)
def toggleSlotLock(self, slotID): """ Lock a slot Same as calling setSlot and then sendUpdate slotID -- slot number """ # Get token of user in that slot (if there's someone) if self.slots[slotID]["userID"] > -1: token = glob.tokens.getTokenFromUserID( self.slots[slotID]["userID"]) else: token = None # Check if slot is already locked if self.slots[slotID]["status"] == slotStatuses.locked: newStatus = slotStatuses.free else: newStatus = slotStatuses.locked # Set new slot status self.setSlot(slotID, newStatus, 0, -1, 0) if token != None: # Send updated settings to kicked user, so he returns to lobby token.enqueue(serverPackets.updateMatch(self.matchID)) # Send updates to everyone else self.sendUpdate() consoleHelper.printColored( "> MPROOM{}: Slot{} {}".format( self.matchID, slotID, "locked" if newStatus == slotStatuses.locked else "unlocked"), bcolors.BLUE)
def checkTeams(self): """ Check if match teams are valid return -- True if valid, False if invalid """ if match.matchTeamType != matchTeamTypes.teamVs or matchTeamTypes != matchTeamTypes.tagTeamVs: # Teams are always valid if we have no teams return True # We have teams, check if they are valid firstTeam = -1 for i in range(0, 16): if self.slots[i]["userID"] > -1 and (self.slots[i]["status"] & slotStatuses.noMap) == 0: if firstTeam == -1: firstTeam = self.slots[i]["team"] elif firstTeam != self.slots[i]["teams"]: consoleHelper.printColored( "> MPROOM{}: Teams are valid".format(self.matchID), bcolors.BLUE) return True consoleHelper.printColored( "> MPROOM{}: Invalid teams!".format(self.matchID), bcolors.RED) return False
def playerCompleted(self, userID): """ Set userID's slot completed to True userID -- ID of user """ slotID = self.getUserSlotID(userID) if slotID == None: return self.setSlot(slotID, None, None, None, None, None, None, True) # Console output consoleHelper.printColored("> MPROOM{}: User {} has completed".format(self.matchID, userID), bcolors.BLUE) # Check all completed total = 0 completed = 0 for i in range(0,16): if self.slots[i]["status"] == slotStatuses.playing: total+=1 if self.slots[i]["complete"] == True: completed+=1 if total == completed: self.allPlayersCompleted()
def allPlayersCompleted(self): """Cleanup match stuff and send match end packet to everyone""" # Reset inProgress self.inProgress = False # Reset slots for i in range(0,16): if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing: self.slots[i]["status"] = slotStatuses.notReady self.slots[i]["loaded"] = False self.slots[i]["skip"] = False self.slots[i]["complete"] = False # Send match update self.sendUpdate() # Send match complete for i in range(0,16): if self.slots[i]["userID"] > -1: token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if token != None: token.enqueue(serverPackets.matchComplete()) # Console output consoleHelper.printColored("> MPROOM{}: Match completed".format(self.matchID), bcolors.BLUE)
def pingLoop(self): """ Pings MySQL server. We need to ping/execute a query at least once every 8 hours or the connection will die. If called once, will recall after 30 minutes and so on, forever CALL THIS FUNCTION ONLY ONCE! """ # Default loop time time = self.pingTime # Make sure the connection is alive try: # Try to ping and reconnect if not connected self.connection.ping() if self.disconnected == True: # If we were disconnected, set disconnected to false and print message self.disconnected = False consoleHelper.printColored("> Reconnected to MySQL server!", bcolors.GREEN) except: # Can't ping MySQL server. Show error and call loop in 5 seconds consoleHelper.printColored("[!] CRITICAL!! MySQL connection died! Make sure your MySQL server is running! Checking again in 5 seconds...", bcolors.RED) self.disconnected = True time = 5 # Schedule a new check (endless loop) threading.Timer(time, self.pingLoop).start()
def toggleSlotLock(self, slotID): """ Lock a slot Same as calling setSlot and then sendUpdate slotID -- slot number """ # Get token of user in that slot (if there's someone) if self.slots[slotID]["userID"] > -1: token = glob.tokens.getTokenFromUserID(self.slots[slotID]["userID"]) else: token = None # Check if slot is already locked if self.slots[slotID]["status"] == slotStatuses.locked: newStatus = slotStatuses.free else: newStatus = slotStatuses.locked # Set new slot status self.setSlot(slotID, newStatus, 0, -1, 0) if token != None: # Send updated settings to kicked user, so he returns to lobby token.enqueue(serverPackets.updateMatch(self.matchID)) # Send updates to everyone else self.sendUpdate() consoleHelper.printColored("> MPROOM{}: Slot{} {}".format(self.matchID, slotID, "locked" if newStatus == slotStatuses.locked else "unlocked"), bcolors.BLUE)
def handle(userToken, packetData): # get token data userID = userToken.userID # Send spectator frames to every spectator consoleHelper.printColored("> {}'s spectators: {}".format(str(userID), str(userToken.spectators)), bcolors.BLUE) for i in userToken.spectators: # Send to every user but host if i != userID: try: # Get spectator token object spectatorToken = glob.tokens.getTokenFromUserID(i) # Make sure the token exists if spectatorToken == None: raise exceptions.stopSpectating # Make sure this user is spectating us if spectatorToken.spectating != userID: raise exceptions.stopSpectating # Everything seems fine, send spectator frames to this spectator spectatorToken.enqueue(serverPackets.spectatorFrames(packetData[7:])) except exceptions.stopSpectating: # Remove this user from spectators userToken.removeSpectator(i) userToken.enqueue(serverPackets.removeSpectator(i))
def usersTimeoutCheckLoop(self, __timeoutTime = 100, __checkTime = 100): """ Deletes all timed out users. If called once, will recall after __checkTime seconds and so on, forever CALL THIS FUNCTION ONLY ONCE! __timeoutTime - seconds of inactivity required to disconnect someone (Default: 100) __checkTime - seconds between loops (Default: 100) """ timedOutTokens = [] # timed out users timeoutLimit = time.time()-__timeoutTime for key, value in self.tokens.items(): # Check timeout (fokabot is ignored) if (value.pingTime < timeoutLimit and value.userID != 999): # That user has timed out, add to disconnected tokens # We can't delete it while iterating or items() throws an error timedOutTokens.append(key) # Send logout packet to everyone # TODO: Move to event handler self.enqueueAll(serverPackets.userLogout(value.userID)) # Console output consoleHelper.printColored("> {} has been disconnected (timeout)".format(value.username), bcolors.YELLOW) # Delete timed out users from self.tokens # i is token string (dictionary key) for i in timedOutTokens: self.tokens.pop(i) # Schedule a new check (endless loop) threading.Timer(__checkTime, self.usersTimeoutCheckLoop, [__timeoutTime, __checkTime]).start()
def userChangeSlot(self, userID, newSlotID): """ Change userID slot to newSlotID userID -- user that changed slot newSlotID -- slot id of new slot """ # Make sure the user is in room oldSlotID = self.getUserSlotID(userID) if oldSlotID == None: return # Make sure there is no one inside new slot if self.slots[newSlotID]["userID"] > -1: return # Get old slot data oldData = self.slots[oldSlotID].copy() # Free old slot self.setSlot(oldSlotID, slotStatuses.free, 0, -1, 0) # Occupy new slot self.setSlot(newSlotID, oldData["status"], oldData["team"], userID, oldData["mods"]) # Send updated match data self.sendUpdate() # Console output consoleHelper.printColored( "> MPROOM{}: {} moved to slot {}".format(self.matchID, userID, newSlotID), bcolors.BLUE)
def scheduleShutdown(sendRestartTime, restart, message=""): """ Schedule a server shutdown/restart sendRestartTime -- time (seconds) to wait before sending server restart packets to every client restart -- if True, server will restart. if False, server will shudown message -- if set, send that message to every client to warn about the shutdown/restart """ # Console output consoleHelper.printColored( "[!] Pep.py will {} in {} seconds!".format( "restart" if restart else "shutdown", sendRestartTime + 20), bcolors.PINK) consoleHelper.printColored( "[!] Sending server restart packets in {} seconds...".format( sendRestartTime), bcolors.PINK) # Send notification if set if message != "": glob.tokens.enqueueAll(serverPackets.notification(message)) # Schedule server restart packet threading.Timer(sendRestartTime, glob.tokens.enqueueAll, [serverPackets.banchoRestart(50000)]).start() glob.restarting = True # Restart/shutdown if restart: action = restartServer else: action = shutdownServer # Schedule actual server shutdown/restart 20 seconds after server restart packet, so everyone gets it threading.Timer(sendRestartTime + 20, action).start()
def playerCompleted(self, userID): """ Set userID's slot completed to True userID -- ID of user """ slotID = self.getUserSlotID(userID) if slotID == None: return self.setSlot(slotID, None, None, None, None, None, None, True) # Console output consoleHelper.printColored( "> MPROOM{}: User {} has completed".format(self.matchID, userID), bcolors.BLUE) # Check all completed total = 0 completed = 0 for i in range(0, 16): if self.slots[i]["status"] == slotStatuses.playing: total += 1 if self.slots[i]["complete"] == True: completed += 1 if total == completed: self.allPlayersCompleted()
def userChangeSlot(self, userID, newSlotID): """ Change userID slot to newSlotID userID -- user that changed slot newSlotID -- slot id of new slot """ # Make sure the user is in room oldSlotID = self.getUserSlotID(userID) if oldSlotID == None: return # Make sure there is no one inside new slot if self.slots[newSlotID]["userID"] > -1: return # Get old slot data oldData = self.slots[oldSlotID].copy() # Free old slot self.setSlot(oldSlotID, slotStatuses.free, 0, -1, 0) # Occupy new slot self.setSlot(newSlotID, oldData["status"], oldData["team"], userID, oldData["mods"]) # Send updated match data self.sendUpdate() # Console output consoleHelper.printColored("> MPROOM{}: {} moved to slot {}".format(self.matchID, userID, newSlotID), bcolors.BLUE)
def allPlayersCompleted(self): """Cleanup match stuff and send match end packet to everyone""" # Reset inProgress self.inProgress = False # Reset slots for i in range(0, 16): if self.slots[i]["userID"] > -1 and self.slots[i][ "status"] == slotStatuses.playing: self.slots[i]["status"] = slotStatuses.notReady self.slots[i]["loaded"] = False self.slots[i]["skip"] = False self.slots[i]["complete"] = False # Send match update self.sendUpdate() # Send match complete for i in range(0, 16): if self.slots[i]["userID"] > -1: token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if token != None: token.enqueue(serverPackets.matchComplete()) # Console output consoleHelper.printColored( "> MPROOM{}: Match completed".format(self.matchID), bcolors.BLUE)
def playerLoaded(self, userID): """ Set a player loaded status to True userID -- ID of user """ slotID = self.getUserSlotID(userID) if slotID == None: return # Set loaded to True self.slots[slotID]["loaded"] = True consoleHelper.printColored( "> MPROOM{}: User {} loaded".format(self.matchID, userID), bcolors.BLUE) # Check all loaded total = 0 loaded = 0 for i in range(0, 16): if self.slots[i]["status"] == slotStatuses.playing: total += 1 if self.slots[i]["loaded"] == True: loaded += 1 if total == loaded: self.allPlayersLoaded()
def handle(userToken, packetData): # get token data userID = userToken.userID # Send spectator frames to every spectator consoleHelper.printColored( "> {}'s spectators: {}".format(str(userID), str(userToken.spectators)), bcolors.BLUE) for i in userToken.spectators: # Send to every user but host if i != userID: try: # Get spectator token object spectatorToken = glob.tokens.getTokenFromUserID(i) # Make sure the token exists if spectatorToken == None: raise exceptions.stopSpectating # Make sure this user is spectating us if spectatorToken.spectating != userID: raise exceptions.stopSpectating # Everything seems fine, send spectator frames to this spectator spectatorToken.enqueue( serverPackets.spectatorFrames(packetData[7:])) except exceptions.stopSpectating: # Remove this user from spectators userToken.removeSpectator(i) userToken.enqueue(serverPackets.removeSpectator(i))
def ciTrigger(): # Ci restart trigger # Get ket from GET key = flask.request.args.get('k') # Get request ip requestIP = flask.request.headers.get('X-Real-IP') if (requestIP == None): requestIP = flask.request.remote_addr # Check key if (key is None or key != glob.conf.config["ci"]["key"]): consoleHelper.printColored( "[!] Invalid ci trigger from {}".format(requestIP), bcolors.RED) return flask.jsonify({"response": "-1"}) # Ci event triggered, schedule server shutdown consoleHelper.printColored( "[!] Ci event triggered from {}".format(requestIP), bcolors.PINK) systemHelper.scheduleShutdown( 5, False, "A new Bancho update is available and the server will be restarted in 5 seconds. Thank you for your patience." ) return flask.jsonify({"response": "1"})
def playerLoaded(self, userID): """ Set a player loaded status to True userID -- ID of user """ slotID = self.getUserSlotID(userID) if slotID == None: return # Set loaded to True self.slots[slotID]["loaded"] = True consoleHelper.printColored("> MPROOM{}: User {} loaded".format(self.matchID, userID), bcolors.BLUE) # Check all loaded total = 0 loaded = 0 for i in range(0,16): if self.slots[i]["status"] == slotStatuses.playing: total+=1 if self.slots[i]["loaded"] == True: loaded+=1 if total == loaded: self.allPlayersLoaded()
def pingLoop(self): """ Pings MySQL server. We need to ping/execute a query at least once every 8 hours or the connection will die. If called once, will recall after 30 minutes and so on, forever CALL THIS FUNCTION ONLY ONCE! """ # Default loop time time = self.pingTime # Make sure the connection is alive try: # Try to ping and reconnect if not connected self.connection.ping() if (self.disconnected == True): # If we were disconnected, set disconnected to false and print message self.disconnected = False consoleHelper.printColored("> Reconnected to MySQL server!", bcolors.GREEN) except: # Can't ping MySQL server. Show error and call loop in 5 seconds consoleHelper.printColored( "[!] CRITICAL!! MySQL connection died! Make sure your MySQL server is running! Checking again in 5 seconds...", bcolors.RED) self.disconnected = True time = 5 # Schedule a new check (endless loop) threading.Timer(time, self.pingLoop).start()
def playerSkip(self, userID): """ Set a player skip status to True userID -- ID of user """ slotID = self.getUserSlotID(userID) if slotID == None: return # Set skip to True self.slots[slotID]["skip"] = True consoleHelper.printColored("> MPROOM{}: User {} skipped".format(self.matchID, userID), bcolors.BLUE) # Send skip packet to every playing useR for i in range(0,16): uid = self.slots[i]["userID"] if self.slots[i]["status"] == slotStatuses.playing and uid > -1: token = glob.tokens.getTokenFromUserID(uid) if token != None: print("Enqueueueue {}".format(uid)) token.enqueue(serverPackets.playerSkipped(uid)) # Check all skipped total = 0 skipped = 0 for i in range(0,16): if self.slots[i]["status"] == slotStatuses.playing: total+=1 if self.slots[i]["skip"] == True: skipped+=1 if total == skipped: self.allPlayersSkipped()
def allPlayersLoaded(self): """Send allPlayersLoaded packet to every playing usr in match""" for i in range(0,16): if (self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing): token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if (token != None): token.enqueue(serverPackets.allPlayersLoaded()) consoleHelper.printColored("> MPROOM{}: All players loaded! Corrispondere iniziare in 3...".format(self.matchID), bcolors.BLUE)
def kick(self): """Kick this user from the server""" # Send packet to target consoleHelper.printColored("> {} has been disconnected. (kick)".format(self.username), bcolors.YELLOW) self.enqueue(serverPackets.notification("You have been kicked from the server. Please login again.")) self.enqueue(serverPackets.loginFailed()) # Logout event logoutEvent.handle(self, None)
def allPlayersSkipped(self): """Send allPlayersSkipped packet to every playing usr in match""" for i in range(0,16): if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing: token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if token != None: token.enqueue(serverPackets.allPlayersSkipped()) consoleHelper.printColored("> MPROOM{}: All players skipped!".format(self.matchID), bcolors.BLUE)
def changeMatchMods(self, mods): """ Set match global mods mods -- mods bitwise int thing """ # Set new mods and send update self.mods = mods self.sendUpdate() consoleHelper.printColored("> MPROOM{}: Mods changed to {}".format(self.matchID, self.mods), bcolors.BLUE)
def setSlotMods(self, slotID, mods): """ Set slotID mods. Same as calling setSlot and then sendUpdate slotID -- slot number mods -- new mods """ # Set new slot data and send update self.setSlot(slotID, None, None, None, mods) self.sendUpdate() consoleHelper.printColored("> MPROOM{}: Slot{} mods changed to {}".format(self.matchID, slotID, mods), bcolors.BLUE)
def allPlayersSkipped(self): """Send allPlayersSkipped packet to every playing usr in match""" for i in range(0, 16): if self.slots[i]["userID"] > -1 and self.slots[i][ "status"] == slotStatuses.playing: token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if token != None: token.enqueue(serverPackets.allPlayersSkipped()) consoleHelper.printColored( "> MPROOM{}: All players skipped!".format(self.matchID), bcolors.BLUE)
def allPlayersLoaded(self): """Send allPlayersLoaded packet to every playing usr in match""" for i in range(0, 16): if (self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing): token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if (token != None): token.enqueue(serverPackets.allPlayersLoaded()) consoleHelper.printColored( "> MPROOM{}: All players loaded! Corrispondere iniziare in 3...". format(self.matchID), bcolors.BLUE)
def changeMatchMods(self, mods): """ Set match global mods mods -- mods bitwise int thing """ # Set new mods and send update self.mods = mods self.sendUpdate() consoleHelper.printColored( "> MPROOM{}: Mods changed to {}".format(self.matchID, self.mods), bcolors.BLUE)
def setSlotMods(self, slotID, mods): """ Set slotID mods. Same as calling setSlot and then sendUpdate slotID -- slot number mods -- new mods """ # Set new slot data and send update self.setSlot(slotID, None, None, None, mods) self.sendUpdate() consoleHelper.printColored( "> MPROOM{}: Slot{} mods changed to {}".format( self.matchID, slotID, mods), bcolors.BLUE)
def kick(self): """Kick this user from the server""" # Send packet to target consoleHelper.printColored( "> {} has been disconnected. (kick)".format(self.username), bcolors.YELLOW) self.enqueue( serverPackets.notification( "You have been kicked from the server. Please login again.")) self.enqueue(serverPackets.loginFailed()) # Logout event logoutEvent.handle(self, None)
def handle(userToken, _): # Get usertoken data userID = userToken.userID username = userToken.username # Remove user from users in lobby glob.matches.lobbyUserPart(userID) # Part lobby channel channelPartEvent.partChannel(userToken, "#lobby", True) # Console output consoleHelper.printColored("> {} has left multiplayer lobby".format(username), bcolors.BLUE)
def handle(userToken, _): # Get usertoken data userID = userToken.userID username = userToken.username # Remove user from users in lobby glob.matches.lobbyUserPart(userID) # Part lobby channel channelPartEvent.partChannel(userToken, "#lobby", True) # Console output consoleHelper.printColored( "> {} has left multiplayer lobby".format(username), bcolors.BLUE)
def handle(userToken, _): # Get userToken data username = userToken.username userID = userToken.userID # Add user to users in lobby glob.matches.lobbyUserJoin(userID) # Send matches data for key, _ in glob.matches.matches.items(): userToken.enqueue(serverPackets.createMatch(key)) # Console output consoleHelper.printColored("> {} has joined multiplayer lobby".format(username), bcolors.BLUE)
def setHost(self, newHost): """ Set room host to newHost and send him host packet newHost -- new host userID """ self.hostUserID = newHost # Send host packet to new host token = glob.tokens.getTokenFromUserID(newHost) if token != None: token.enqueue(serverPackets.matchTransferHost()) consoleHelper.printColored("> MPROOM{}: {} is now the host".format(self.matchID, newHost), bcolors.BLUE)
def handle(userToken, _): # Get userToken data username = userToken.username userID = userToken.userID # Add user to users in lobby glob.matches.lobbyUserJoin(userID) # Send matches data for key, _ in glob.matches.matches.items(): userToken.enqueue(serverPackets.createMatch(key)) # Console output consoleHelper.printColored( "> {} has joined multiplayer lobby".format(username), bcolors.BLUE)
def setHost(self, newHost): """ Set room host to newHost and send him host packet newHost -- new host userID """ self.hostUserID = newHost # Send host packet to new host token = glob.tokens.getTokenFromUserID(newHost) if token != None: token.enqueue(serverPackets.matchTransferHost()) consoleHelper.printColored( "> MPROOM{}: {} is now the host".format(self.matchID, newHost), bcolors.BLUE)
def handle(userToken, packetData): # get usertoken data userID = userToken.userID try: # We don't have the beatmap, we can't spectate target = userToken.spectating targetToken = glob.tokens.getTokenFromUserID(target) # Send the packet to host targetToken.enqueue(serverPackets.noSongSpectator(userID)) except exceptions.tokenNotFoundException: # Stop spectating if token not found consoleHelper.printColored( "[!] Spectator can't spectate: token not found", bcolors.RED) userToken.stopSpectating()
def toggleSlotReady(self, slotID): """ Switch slotID ready/not ready status Same as calling setSlot and then sendUpdate slotID -- slot number """ # Update ready status and setnd update oldStatus = self.slots[slotID]["status"] if oldStatus == slotStatuses.ready: newStatus = slotStatuses.notReady else: newStatus = slotStatuses.ready self.setSlot(slotID, newStatus, None, None, None) self.sendUpdate() consoleHelper.printColored("> MPROOM{}: Slot{} changed ready status to {}".format(self.matchID, slotID, self.slots[slotID]["status"]), bcolors.BLUE)
def getCountry(ip): """ Get country from IP address ip -- IP Address return -- Country code (2 letters) """ # Default value, sent if API is memeing country = "XX" try: # Try to get country from Pikolo Aul's Go-Sanic ip API country = json.loads(urllib.request.urlopen("{}/{}".format(url, ip)).read().decode())["country"] except: consoleHelper.printColored("[!] Error in get country", bcolors.RED) return country
def getLocation(ip): """ Get latitude and longitude from IP address ip -- IP address return -- [latitude, longitude] """ # Default value, sent if API is memeing data = [0,0] try: # Try to get position from Pikolo Aul's Go-Sanic ip API data = json.loads(urllib.request.urlopen("{}/{}".format(url, ip)).read().decode())["loc"].split(",") except: consoleHelper.printColored("[!] Error in get position", bcolors.RED) return [float(data[0]), float(data[1])]
def handle(userToken, packetData): try: # get usertoken data userID = userToken.userID # Read packet data packetData = clientPackets.createMatch(packetData) # Create a match object # TODO: Player number check matchID = glob.matches.createMatch(packetData["matchName"], packetData["matchPassword"], packetData["beatmapID"], packetData["beatmapName"], packetData["beatmapMD5"], packetData["gameMode"], userID) # Make sure the match has been created if matchID not in glob.matches.matches: raise exceptions.matchCreateError # Get match object match = glob.matches.matches[matchID] # Join that match joinMatchEvent.joinMatch(userToken, matchID, packetData["matchPassword"]) # Give host to match creator match.setHost(userID) # Send match create packet to everyone in lobby for i in glob.matches.usersInLobby: # Make sure this user is still connected token = glob.tokens.getTokenFromUserID(i) if token != None: token.enqueue(serverPackets.createMatch(matchID)) # Console output consoleHelper.printColored("> MPROOM{}: Room created!".format(matchID), bcolors.BLUE) except exceptions.matchCreateError: consoleHelper.printColored("[!] Error while creating match!", bcolors.RED)
def toggleSlotReady(self, slotID): """ Switch slotID ready/not ready status Same as calling setSlot and then sendUpdate slotID -- slot number """ # Update ready status and setnd update oldStatus = self.slots[slotID]["status"] if oldStatus == slotStatuses.ready: newStatus = slotStatuses.notReady else: newStatus = slotStatuses.ready self.setSlot(slotID, newStatus, None, None, None) self.sendUpdate() consoleHelper.printColored( "> MPROOM{}: Slot{} changed ready status to {}".format( self.matchID, slotID, self.slots[slotID]["status"]), bcolors.BLUE)
def getCountry(ip): """ Get country from IP address ip -- IP Address return -- Country code (2 letters) """ # Default value, sent if API is memeing country = "XX" try: # Try to get country from Pikolo Aul's Go-Sanic ip API country = json.loads( urllib.request.urlopen(url + "/" + ip).read().decode())["country"] except: consoleHelper.printColored("[!] Error in get country", bcolors.RED) return country
def changePassword(self, newPassword): """ Change match password to newPassword newPassword -- new password string """ self.matchPassword = newPassword # Send password change to every user in match for i in range(0,16): if self.slots[i]["userID"] > -1: token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if token != None: token.enqueue(serverPackets.changeMatchPassword(self.matchPassword)) # Send new match settings too self.sendUpdate() # Console output consoleHelper.printColored("> MPROOM{}: Password changed to {}".format(self.matchID, self.matchPassword), bcolors.BLUE)
def getLocation(ip): """ Get latitude and longitude from IP address ip -- IP address return -- [latitude, longitude] """ # Default value, sent if API is memeing data = [0, 0] try: # Try to get position from Pikolo Aul's Go-Sanic ip API data = json.loads( urllib.request.urlopen("{}/{}".format( url, ip)).read().decode())["loc"].split(",") except: consoleHelper.printColored("[!] Error in get position", bcolors.RED) return [float(data[0]), float(data[1])]
def playerFailed(self, userID): """ Send userID's failed packet to everyone in match userID -- ID of user """ # Make sure the user is in room slotID = self.getUserSlotID(userID) if slotID == None: return # Send packet to everyone for i in range(0,16): uid = self.slots[i]["userID"] if uid > -1: token = glob.tokens.getTokenFromUserID(uid) if token != None: token.enqueue(serverPackets.playerFailed(slotID)) # Console output consoleHelper.printColored("> MPROOM{}: {} has failed!".format(self.matchID, userID), bcolors.BLUE)
def ciTrigger(): # Ci restart trigger # Get ket from GET key = flask.request.args.get('k') # Get request ip requestIP = flask.request.headers.get('X-Real-IP') if (requestIP == None): requestIP = flask.request.remote_addr # Check key if (key is None or key != glob.conf.config["ci"]["key"]): consoleHelper.printColored("[!] Invalid ci trigger from {}".format(requestIP), bcolors.RED) return flask.jsonify({"response" : "-1"}) # Ci event triggered, schedule server shutdown consoleHelper.printColored("[!] Ci event triggered from {}".format(requestIP), bcolors.PINK) systemHelper.scheduleShutdown(5, False, "A new Bancho update is available and the server will be restarted in 5 seconds. Thank you for your patience.") return flask.jsonify({"response" : "1"})
def partChannel(userToken, channelName, kick = False): # Get usertoken data username = userToken.username userID = userToken.userID # Remove us from joined users and joined channels if channelName in glob.channels.channels: # Check that user is in channel if channelName in userToken.joinedChannels: userToken.partChannel(channelName) # Check if user is in channel if userID in glob.channels.channels[channelName].connectedUsers: glob.channels.channels[channelName].userPart(userID) # Force close tab if needed if kick == True: userToken.enqueue(serverPackets.channelKicked(channelName)) # Console output consoleHelper.printColored("> {} parted channel {}".format(username, channelName), bcolors.YELLOW)
def handle(userToken, _): try: # get user token data userID = userToken.userID username = userToken.username # Remove our userID from host's spectators target = userToken.spectating targetToken = glob.tokens.getTokenFromUserID(target) if targetToken == None: raise exceptions.tokenNotFoundException targetToken.removeSpectator(userID) # Send the spectator left packet to host targetToken.enqueue(serverPackets.removeSpectator(userID)) # Console output # TODO: Move messages in stop spectating consoleHelper.printColored( "> {} are no longer spectating whoever they were spectating". format(username), bcolors.PINK) consoleHelper.printColored( "> {}'s spectators: {}".format(str(target), str(targetToken.spectators)), bcolors.BLUE) except exceptions.tokenNotFoundException: consoleHelper.printColored("[!] Spectator stop: token not found", bcolors.RED) finally: # Set our spectating user to 0 userToken.stopSpectating()
def handle(userToken, _): try: # get user token data userID = userToken.userID username = userToken.username # Remove our userID from host's spectators target = userToken.spectating targetToken = glob.tokens.getTokenFromUserID(target) if (targetToken == None): raise exceptions.tokenNotFoundException targetToken.removeSpectator(userID) # Send the spectator left packet to host targetToken.enqueue(serverPackets.removeSpectator(userID)) # Console output # TODO: Move messages in stop spectating consoleHelper.printColored("> {} are no longer spectating whoever they were spectating".format(username), bcolors.PINK) consoleHelper.printColored("> {}'s spectators: {}".format(str(target), str(targetToken.spectators)), bcolors.BLUE) except exceptions.tokenNotFoundException: consoleHelper.printColored("[!] Spectator stop: token not found", bcolors.RED) finally: # Set our spectating user to 0 userToken.stopSpectating()
def checkTeams(self): """ Check if match teams are valid return -- True if valid, False if invalid """ if match.matchTeamType != matchTeamTypes.teamVs or matchTeamTypes != matchTeamTypes.tagTeamVs: # Teams are always valid if we have no teams return True # We have teams, check if they are valid firstTeam = -1 for i in range(0,16): if self.slots[i]["userID"] > -1 and (self.slots[i]["status"]&slotStatuses.noMap) == 0: if firstTeam == -1: firstTeam = self.slots[i]["team"] elif firstTeam != self.slots[i]["teams"]: consoleHelper.printColored("> MPROOM{}: Teams are valid".format(self.matchID), bcolors.BLUE) return True consoleHelper.printColored("> MPROOM{}: Invalid teams!".format(self.matchID), bcolors.RED) return False
def userLeft(self, userID): """ Remove someone from users in match userID -- user if of the user """ # Make sure the user is in room slotID = self.getUserSlotID(userID) if slotID == None: return # Set that slot to free self.setSlot(slotID, slotStatuses.free, 0, -1, 0) # Check if everyone left if self.countUsers() == 0: # Dispose match glob.matches.disposeMatch(self.matchID) consoleHelper.printColored( "> MPROOM{}: Room disposed".format(self.matchID), bcolors.BLUE) return # Check if host left if userID == self.hostUserID: # Give host to someone else for i in range(0, 16): uid = self.slots[i]["userID"] if uid > -1: self.setHost(uid) break # Send updated match data self.sendUpdate() # Console output consoleHelper.printColored( "> MPROOM{}: {} left the room".format(self.matchID, userID), bcolors.BLUE)
def playerFailed(self, userID): """ Send userID's failed packet to everyone in match userID -- ID of user """ # Make sure the user is in room slotID = self.getUserSlotID(userID) if slotID == None: return # Send packet to everyone for i in range(0, 16): uid = self.slots[i]["userID"] if uid > -1: token = glob.tokens.getTokenFromUserID(uid) if token != None: token.enqueue(serverPackets.playerFailed(slotID)) # Console output consoleHelper.printColored( "> MPROOM{}: {} has failed!".format(self.matchID, userID), bcolors.BLUE)
def changePassword(self, newPassword): """ Change match password to newPassword newPassword -- new password string """ self.matchPassword = newPassword # Send password change to every user in match for i in range(0, 16): if self.slots[i]["userID"] > -1: token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"]) if token != None: token.enqueue( serverPackets.changeMatchPassword(self.matchPassword)) # Send new match settings too self.sendUpdate() # Console output consoleHelper.printColored( "> MPROOM{}: Password changed to {}".format( self.matchID, self.matchPassword), bcolors.BLUE)
def userJoin(self, userID): """ Add someone to users in match userID -- user id of the user return -- True if join success, False if fail (room is full) """ # Find first free slot for i in range(0,16): if self.slots[i]["status"] == slotStatuses.free: # Occupy slot self.setSlot(i, slotStatuses.notReady, 0, userID, 0) # Send updated match data self.sendUpdate() # Console output consoleHelper.printColored("> MPROOM{}: {} joined the room".format(self.matchID, userID), bcolors.BLUE) return True return False
def userLeft(self, userID): """ Remove someone from users in match userID -- user if of the user """ # Make sure the user is in room slotID = self.getUserSlotID(userID) if slotID == None: return # Set that slot to free self.setSlot(slotID, slotStatuses.free, 0, -1, 0) # Check if everyone left if self.countUsers() == 0: # Dispose match glob.matches.disposeMatch(self.matchID) consoleHelper.printColored("> MPROOM{}: Room disposed".format(self.matchID), bcolors.BLUE) return # Check if host left if userID == self.hostUserID: # Give host to someone else for i in range(0,16): uid = self.slots[i]["userID"] if uid > -1: self.setHost(uid) break # Send updated match data self.sendUpdate() # Console output consoleHelper.printColored("> MPROOM{}: {} left the room".format(self.matchID, userID), bcolors.BLUE)