def fokabotResponse(fro, chan, message): """ Check if a message has triggered fokabot (and return its response) fro -- sender username (for permissions stuff with admin commands) chan -- channel name message -- message return -- fokabot's response string or False """ for i in fokabotCommands.commands: # Loop though all commands if i["trigger"] in message: # message has triggered a command # Make sure the user has right permissions if i["minRank"] > 1: # Get rank from db only if minrank > 1, so we save some CPU if userHelper.getRankPrivileges(userHelper.getID(fro)) < i["minRank"]: return False # Check argument number message = message.split(" ") if i["syntax"] != "" and len(message) <= len(i["syntax"].split(" ")): return "Wrong syntax: {} {}".format(i["trigger"], i["syntax"]) # Return response or execute callback if i["callback"] == None: return i["response"] else: return i["callback"](fro, chan, message[1:]) # No commands triggered return False
def silence(fro, chan, message): for i in message: i = i.lower() target = message[0].replace("_", " ") amount = message[1] unit = message[2] reason = ' '.join(message[3:]) # Get target user ID targetUserID = userHelper.getID(target) # Make sure the user exists if targetUserID == False: return "{}: user not found".format(target) # Calculate silence seconds if unit == 's': silenceTime = int(amount) elif unit == 'm': silenceTime = int(amount) * 60 elif unit == 'h': silenceTime = int(amount) * 3600 elif unit == 'd': silenceTime = int(amount) * 86400 else: return "Invalid time unit (s/m/h/d)." # Max silence time is 7 days if silenceTime > 604800: return "Invalid silence time. Max silence time is 7 days." # Calculate silence end time endTime = int(time.time()) + silenceTime # Update silence end in db userHelper.silence(targetUserID, endTime, reason) # Send silence packet to target if he's connected targetToken = glob.tokens.getTokenFromUsername(target) if targetToken != None: targetToken.enqueue(serverPackets.silenceEndTime(silenceTime)) return "{} has been silenced for the following reason: {}".format( target, reason)
def silence(fro, chan, message): for i in message: i = i.lower() target = message[0].replace("_", " ") amount = message[1] unit = message[2] reason = ' '.join(message[3:]) # Get target user ID targetUserID = userHelper.getID(target) # Make sure the user exists if targetUserID == False: return "{}: user not found".format(target) # Calculate silence seconds if unit == 's': silenceTime = int(amount) elif unit == 'm': silenceTime = int(amount)*60 elif unit == 'h': silenceTime = int(amount)*3600 elif unit == 'd': silenceTime = int(amount)*86400 else: return "Invalid time unit (s/m/h/d)." # Max silence time is 7 days if silenceTime > 604800: return "Invalid silence time. Max silence time is 7 days." # Calculate silence end time endTime = int(time.time())+silenceTime # Update silence end in db userHelper.silence(targetUserID, endTime, reason) # Send silence packet to target if he's connected targetToken = glob.tokens.getTokenFromUsername(target) if targetToken != None: targetToken.enqueue(serverPackets.silenceEndTime(silenceTime)) return "{} has been silenced for the following reason: {}".format(target, reason)
def removeSilence(fro, chan, message): # Get parameters for i in message: i = i.lower() target = message[0].replace("_", " ") # Make sure the user exists targetUserID = userHelper.getID(target) if targetUserID == False: return "{}: user not found".format(target) # Reset user silence time and reason in db userHelper.silence(targetUserID, 0, "") # Send new silence end packet to user if he's online targetToken = glob.tokens.getTokenFromUsername(target) if targetToken != None: targetToken.enqueue(serverPackets.silenceEndTime(0)) return "{}'s silence reset".format(target)
def handle(flaskRequest): # Data to return responseTokenString = "ayy" responseData = bytes() # Get IP from flask request requestIP = flaskRequest.headers.get('X-Real-IP') if requestIP == None: requestIP = flaskRequest.remote_addr # Console output print("> Accepting connection from {}...".format(requestIP)) # Split POST body so we can get username/password/hardware data # 2:-3 thing is because requestData has some escape stuff that we don't need loginData = str(flaskRequest.data)[2:-3].split("\\n") # Process login print("> Processing login request for {}...".format(loginData[0])) try: # If true, print error to console err = False # Try to get the ID from username userID = userHelper.getID(str(loginData[0])) if userID == False: # Invalid username raise exceptions.loginFailedException() if userHelper.checkLogin(userID, loginData[1]) == False: # Invalid password raise exceptions.loginFailedException() # Make sure we are not banned userAllowed = userHelper.getAllowed(userID) if userAllowed == 0: # Banned raise exceptions.loginBannedException() # No login errors! # Delete old tokens for that user and generate a new one glob.tokens.deleteOldTokens(userID) responseToken = glob.tokens.addToken(userID) responseTokenString = responseToken.token # Get silence end userSilenceEnd = max( 0, userHelper.getSilenceEnd(userID) - int(time.time())) # Get supporter/GMT userRank = userHelper.getRankPrivileges(userID) userGMT = False userSupporter = True if userRank >= 3: userGMT = True # Server restarting check if glob.restarting == True: raise exceptions.banchoRestartingException() # Maintenance check if glob.banchoConf.config["banchoMaintenance"] == True: if userGMT == False: # We are not mod/admin, delete token, send notification and logout glob.tokens.deleteToken(responseTokenString) raise exceptions.banchoMaintenanceException() else: # We are mod/admin, send warning notification and continue responseToken.enqueue( serverPackets.notification( "Bancho is in maintenance mode. Only mods/admins have full access to the server.\nType !system maintenance off in chat to turn off maintenance mode." )) # Send all needed login packets responseToken.enqueue(serverPackets.silenceEndTime(userSilenceEnd)) responseToken.enqueue(serverPackets.userID(userID)) responseToken.enqueue(serverPackets.protocolVersion()) responseToken.enqueue( serverPackets.userSupporterGMT(userSupporter, userGMT)) responseToken.enqueue(serverPackets.userPanel(userID)) responseToken.enqueue(serverPackets.userStats(userID)) # Channel info end (before starting!?! wtf bancho?) responseToken.enqueue(serverPackets.channelInfoEnd()) # Default opened channels # TODO: Configurable default channels channelJoinEvent.joinChannel(responseToken, "#osu") channelJoinEvent.joinChannel(responseToken, "#announce") if userRank >= 3: # Join admin chanenl if we are mod/admin # TODO: Separate channels for mods and admins channelJoinEvent.joinChannel(responseToken, "#admin") # Output channels info for key, value in glob.channels.channels.items(): if value.publicRead == True: responseToken.enqueue(serverPackets.channelInfo(key)) responseToken.enqueue(serverPackets.friendList(userID)) # Send main menu icon and login notification if needed if glob.banchoConf.config["menuIcon"] != "": responseToken.enqueue( serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"])) if glob.banchoConf.config["loginNotification"] != "": responseToken.enqueue( serverPackets.notification( glob.banchoConf.config["loginNotification"])) # Get everyone else userpanel # TODO: Better online users handling for key, value in glob.tokens.tokens.items(): responseToken.enqueue(serverPackets.userPanel(value.userID)) responseToken.enqueue(serverPackets.userStats(value.userID)) # Send online users IDs array responseToken.enqueue(serverPackets.onlineUsers()) # Get location and country from ip.zxq.co or database if generalFunctions.stringToBool( glob.conf.config["server"]["localizeusers"]): # Get location and country from IP location = locationHelper.getLocation(requestIP) country = countryHelper.getCountryID( locationHelper.getCountry(requestIP)) else: # Set location to 0,0 and get country from db print("[!] Location skipped") location = [0, 0] country = countryHelper.getCountryID(userHelper.getCountry(userID)) # Set location and country responseToken.setLocation(location) responseToken.setCountry(country) # Send to everyone our userpanel and userStats (so they now we have logged in) glob.tokens.enqueueAll(serverPackets.userPanel(userID)) glob.tokens.enqueueAll(serverPackets.userStats(userID)) # Set reponse data to right value and reset our queue responseData = responseToken.queue responseToken.resetQueue() # Print logged in message consoleHelper.printColored( "> {} logged in ({})".format(loginData[0], responseToken.token), bcolors.GREEN) except exceptions.loginFailedException: # Login failed error packet # (we don't use enqueue because we don't have a token since login has failed) err = True responseData += serverPackets.loginFailed() except exceptions.loginBannedException: # Login banned error packet err = True responseData += serverPackets.loginBanned() except exceptions.banchoMaintenanceException: # Bancho is in maintenance mode responseData += serverPackets.notification( "Our bancho server is in maintenance mode. Please try to login again later." ) responseData += serverPackets.loginError() except exceptions.banchoRestartingException: # Bancho is restarting responseData += serverPackets.notification( "Bancho is restarting. Try again in a few minutes.") responseData += serverPackets.loginError() finally: # Print login failed message to console if needed if err == True: consoleHelper.printColored( "> {}'s login failed".format(loginData[0]), bcolors.YELLOW) return (responseTokenString, responseData)
def sendMessage(fro, to, message): return packetHelper.buildPacket( packetIDs.server_sendMessage, [[fro, dataTypes.string], [message, dataTypes.string], [to, dataTypes.string], [userHelper.getID(fro), dataTypes.sInt32]])
def handle(flaskRequest): # Data to return responseTokenString = "ayy" responseData = bytes() # Get IP from flask request requestIP = flaskRequest.headers.get('X-Real-IP') if requestIP == None: requestIP = flaskRequest.remote_addr # Console output print("> Accepting connection from {}...".format(requestIP)) # Split POST body so we can get username/password/hardware data # 2:-3 thing is because requestData has some escape stuff that we don't need loginData = str(flaskRequest.data)[2:-3].split("\\n") # Process login print("> Processing login request for {}...".format(loginData[0])) try: # If true, print error to console err = False # Try to get the ID from username userID = userHelper.getID(str(loginData[0])) if userID == False: # Invalid username raise exceptions.loginFailedException() if userHelper.checkLogin(userID, loginData[1]) == False: # Invalid password raise exceptions.loginFailedException() # Make sure we are not banned userAllowed = userHelper.getAllowed(userID) if userAllowed == 0: # Banned raise exceptions.loginBannedException() # No login errors! # Delete old tokens for that user and generate a new one glob.tokens.deleteOldTokens(userID) responseToken = glob.tokens.addToken(userID) responseTokenString = responseToken.token # Get silence end userSilenceEnd = max(0, userHelper.getSilenceEnd(userID)-int(time.time())) # Get supporter/GMT userRank = userHelper.getRankPrivileges(userID) userGMT = False userSupporter = True if userRank >= 3: userGMT = True # Server restarting check if glob.restarting == True: raise exceptions.banchoRestartingException() # Maintenance check if glob.banchoConf.config["banchoMaintenance"] == True: if userGMT == False: # We are not mod/admin, delete token, send notification and logout glob.tokens.deleteToken(responseTokenString) raise exceptions.banchoMaintenanceException() else: # We are mod/admin, send warning notification and continue responseToken.enqueue(serverPackets.notification("Bancho is in maintenance mode. Only mods/admins have full access to the server.\nType !system maintenance off in chat to turn off maintenance mode.")) # Send all needed login packets responseToken.enqueue(serverPackets.silenceEndTime(userSilenceEnd)) responseToken.enqueue(serverPackets.userID(userID)) responseToken.enqueue(serverPackets.protocolVersion()) responseToken.enqueue(serverPackets.userSupporterGMT(userSupporter, userGMT)) responseToken.enqueue(serverPackets.userPanel(userID)) responseToken.enqueue(serverPackets.userStats(userID)) # Channel info end (before starting!?! wtf bancho?) responseToken.enqueue(serverPackets.channelInfoEnd()) # Default opened channels # TODO: Configurable default channels channelJoinEvent.joinChannel(responseToken, "#osu") channelJoinEvent.joinChannel(responseToken, "#announce") if userRank >= 3: # Join admin chanenl if we are mod/admin # TODO: Separate channels for mods and admins channelJoinEvent.joinChannel(responseToken, "#admin") # Output channels info for key, value in glob.channels.channels.items(): if value.publicRead == True: responseToken.enqueue(serverPackets.channelInfo(key)) responseToken.enqueue(serverPackets.friendList(userID)) # Send main menu icon and login notification if needed if glob.banchoConf.config["menuIcon"] != "": responseToken.enqueue(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"])) if glob.banchoConf.config["loginNotification"] != "": responseToken.enqueue(serverPackets.notification(glob.banchoConf.config["loginNotification"])) # Get everyone else userpanel # TODO: Better online users handling for key, value in glob.tokens.tokens.items(): responseToken.enqueue(serverPackets.userPanel(value.userID)) responseToken.enqueue(serverPackets.userStats(value.userID)) # Send online users IDs array responseToken.enqueue(serverPackets.onlineUsers()) # Get location and country from ip.zxq.co or database if generalFunctions.stringToBool(glob.conf.config["server"]["localizeusers"]): # Get location and country from IP location = locationHelper.getLocation(requestIP) country = countryHelper.getCountryID(locationHelper.getCountry(requestIP)) else: # Set location to 0,0 and get country from db print("[!] Location skipped") location = [0,0] country = countryHelper.getCountryID(userHelper.getCountry(userID)) # Set location and country responseToken.setLocation(location) responseToken.setCountry(country) # Send to everyone our userpanel and userStats (so they now we have logged in) glob.tokens.enqueueAll(serverPackets.userPanel(userID)) glob.tokens.enqueueAll(serverPackets.userStats(userID)) # Set reponse data to right value and reset our queue responseData = responseToken.queue responseToken.resetQueue() # Print logged in message consoleHelper.printColored("> {} logged in ({})".format(loginData[0], responseToken.token), bcolors.GREEN) except exceptions.loginFailedException: # Login failed error packet # (we don't use enqueue because we don't have a token since login has failed) err = True responseData += serverPackets.loginFailed() except exceptions.loginBannedException: # Login banned error packet err = True responseData += serverPackets.loginBanned() except exceptions.banchoMaintenanceException: # Bancho is in maintenance mode responseData += serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later.") responseData += serverPackets.loginError() except exceptions.banchoRestartingException: # Bancho is restarting responseData += serverPackets.notification("Bancho is restarting. Try again in a few minutes.") responseData += serverPackets.loginError() finally: # Print login failed message to console if needed if err == True: consoleHelper.printColored("> {}'s login failed".format(loginData[0]), bcolors.YELLOW) return (responseTokenString, responseData)
def sendMessage(fro, to, message): return packetHelper.buildPacket(packetIDs.server_sendMessage, [[fro, dataTypes.string], [message, dataTypes.string], [to, dataTypes.string], [userHelper.getID(fro), dataTypes.sInt32]])