def handleUsernameChange(userID, newUsername, targetToken=None): try: userUtils.appendNotes( userID, "Username change: '{}' -> '{}'".format( userUtils.getUsername(userID), newUsername)) userUtils.changeUsername(userID, newUsername=newUsername) if targetToken != None: targetToken.kick( "Your username has been changed to {}. Please log in again.". format(newUsername), "username_change") except userUtils.usernameAlreadyInUseError: log.rap(999, "Username change: {} is already in use!", through="Bancho") if targetToken != None: targetToken.kick( "There was a critical error while trying to change your username. Please contact a developer.", "username_change_fail") except userUtils.invalidUsernameError: log.rap(999, "Username change: {} is not a valid username!", through="Bancho") if targetToken != None: targetToken.kick( "There was a critical error while trying to change your username. Please contact a developer.", "username_change_fail")
def setDataFromDict(self, data, rank=None): """ Set this object's score data from dictionary Doesn't set playerUserID data -- score dictionarty rank -- rank in scoreboard. Optional. """ #print(str(data)) self.scoreID = data["id"] if "username" in data: self.playerName = userUtils.getClan(data["userid"]) else: self.playerName = userUtils.getUsername(data["userid"]) self.playerUserID = data["userid"] self.score = data["score"] self.maxCombo = data["max_combo"] self.gameMode = data["play_mode"] self.c50 = data["50_count"] self.c100 = data["100_count"] self.c300 = data["300_count"] self.cMiss = data["misses_count"] self.cKatu = data["katus_count"] self.cGeki = data["gekis_count"] self.fullCombo = True if data["full_combo"] == 1 else False self.mods = data["mods"] self.rank = rank if rank is not None else "" self.date = data["time"] self.fileMd5 = data["beatmap_md5"] self.completed = data["completed"] #if "pp" in data: self.pp = data["pp"] self.calculateAccuracy()
def getRankInfo(userID, gameMode): """ Get userID's current rank, user above us and pp/score difference :param userID: user :param gameMode: gameMode number :return: {"nextUsername": "", "difference": 0, "currentRank": 0} """ data = {"nextUsername": "", "difference": 0, "currentRank": 0} k = "ripple:leaderboard_auto:{}".format( scoreUtils.readableGameMode(gameMode)) position = userUtils.getGameRankAP(userID, gameMode) - 1 log.debug("Our position is {}".format(position)) if position is not None and position > 0: aboveUs = glob.redis.zrevrange(k, position - 1, position) log.debug("{} is above us".format(aboveUs)) if aboveUs is not None and len(aboveUs) > 0 and aboveUs[0].isdigit(): # Get our rank, next rank username and pp/score difference myScore = glob.redis.zscore(k, userID) otherScore = glob.redis.zscore(k, aboveUs[0]) nextUsername = userUtils.getUsername(aboveUs[0]) if nextUsername is not None and myScore is not None and otherScore is not None: data["nextUsername"] = nextUsername data["difference"] = int(myScore) - int(otherScore) else: position = 0 data["currentRank"] = position + 1 return data
def listReferee(response, token, sender, channel, message): _match = getCurrentMatch(channel) msg = "List of referees:" for refUserID in _match.referees: msg += "\n - {}".format(userUtils.getUsername(refUserID)) msg += f"\n - {sender}" response.split_lines = True response.setContent(token, msg)
def connect(): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(): """ Connect FokaBot to Bancho. You can change FokaBot's name in RAP and FokaBot will still work as intended. :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.UNKNOWN token.actionText = "\nWelcome to osu!minase have fun" glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE token.actionText = "\nThank you for playing Ryumi! <3" glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def rap(userID, message, discord=False, through="FokaBot"): """ Log a message to Admin Logs. :param userID: admin user ID :param message: message content, without username :param discord: if True, send the message to discord :param through: through string. Default: FokaBot :return: """ glob.db.execute("INSERT INTO rap_logs (id, userid, text, datetime, through) VALUES (NULL, %s, %s, %s, %s)", [userID, message, int(time.time()), through]) username = userUtils.getUsername(userID) logMessage("{} {}".format(username, message), discord=True)
def connect(): """ Connect FokaBot to Bancho. :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE token.country = 244 token.actionText = " Enjoy Mikoto v3" glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(timeOffset=9): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE token.actionText = "\n-- Welcome to Ainu --" token.timeOffset = timeOffset token.timezone = 24 + token.timeOffset token.country = 111 glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(timeOffset = 9): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE token.actionText = "\nChoo Choo" token.pp = 0 token.accuracy = 0 token.playcount = 0 token.totalScore = 0 token.timeOffset = timeOffset token.timezone = 24+token.timeOffset token.country = 111 glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE token.actionText = "\n欢迎来到卡服" token.pp = 1 token.accuracy = 0.997 token.playcount = 2000 token.totalScore = 940857703 token.timeOffset = 0 token.timezone = 24 + 8 token.country = 48 glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(timeOffset=9): """ Connect FokaBot to Bancho :return: """ commandBuckets.clear() glob.BOT_NAME = userUtils.getUsername(1) token = glob.tokens.addToken(1) token.actionID = actions.IDLE token.actionText = "\n-- Welcome to Datenshi --" #token.pp = 69 #token.accuracy = 0.9885 #token.playcount = 26956 #token.totalScore = 237228316533 token.timeOffset = timeOffset token.timezone = 24 + token.timeOffset token.country = 111 glob.streams.broadcast("main", serverPackets.userPanel(1))
def asyncGet(self): try: # Get request ip ip = self.getRequestIP() # Check arguments if not requestsManager.checkArguments(self.request.arguments, ["c", "k"]): raise exceptions.invalidArgumentsException(MODULE_NAME) # Get arguments key = self.get_argument("k") targetID = self.get_argument("c") if key is None or key != generalUtils.stringMd5( glob.conf.config["server"]["apikey"]): raise exceptions.invalidArgumentsException(MODULE_NAME) targetUsername = userUtils.getUsername(targetID) if (targetUsername is None): raise exceptions.invalidArgumentsException(MODULE_NAME) # Serve replay log.info("Serving {}.txt".format(targetUsername)) fileName = ".data/pl/{}.txt".format(targetUsername) if os.path.isfile(fileName): with open(fileName, "rb") as f: fileContent = f.read() self.write(fileContent) self.set_header("Content-length", len(fileContent)) self.set_header("Content-Description", "File Transfer") self.set_header( "Content-Disposition", "attachment; filename=\"{}_trace.txt\"".format( targetUsername)) else: log.warning("Trace {} doesn't exist".format(targetUsername)) self.write("") except exceptions.invalidArgumentsException: pass except exceptions.loginFailedException: pass
def connect(): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.IDLE token.actionText = random.choice([ "\n-- Sotarks is gay! --", "\n-- ck was here --", "\n-- Welcome to Kurikku --", "\n-- KotRik is not a gay --", "\n-- osu!godland is deprecated --", "\n-- rarenai #1 in 2019 --", "\n-- Plz don't use aoba switcher, it sucks --", "\n-- Maybe u wanna play HDDTHR? --", "\n-- 727pp isn't comming( --", "\n-- flipzky is too lazy to make tourney ;d --", "\n-- i wanna 100 players online ;d --" ]) glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def connect(): """ Connect FokaBot to Bancho :return: """ glob.BOT_NAME = userUtils.getUsername(999) token = glob.tokens.addToken(999) token.actionID = actions.WATCHING token.actionText = "over RealistikOsu!" token.pp = 69 token.accuracy = 0.69 token.playcount = 69 token.totalScore = 1337 token.timeOffset = 0 token.timezone = 24 token.country = 2 #this is retared, f**k it im keeping it as europe, couldnt find the uk as its ordered stupidly token.location = (39.01955903386848, 125.75276158057767 ) # Pyongyang red square glob.streams.broadcast("main", serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def help(response, token, sender, channel, message): userID = userUtils.getID(sender) for command, command_data in commands.items(): chat.sendMessage( glob.BOT_NAME, sender, f"mp {command} {command_data.syntax} {('(requires %s or higher)' % (command_data.perm,) if command_data.perm != 'basic' else '') if command_data.mpOnly else '*can be used outside mp room*'}" .strip()) chat.sendMessage( glob.BOT_NAME, sender, "This command still underwent heavy rewriting, those ugly terms and such will go soon(TM)." ) chat.sendMessage( glob.BOT_NAME, sender, "Let (us) me know about the bancho mimicking that I need to do, I'll do my best!" ) gloryID = 3 # oi. if userID == gloryID: chat.sendMessage(glob.BOT_NAME, sender, "-- a note that you left behind.") else: gloryName = userUtils.getUsername(gloryID) chat.sendMessage(glob.BOT_NAME, sender, f"-- {gloryName}.") pass
def call(m, *args, user_id=None, discord_m=False, embed_args=None): try: if flavours.config is None: cache_config() username = None if user_id != None: username = userUtils.getUsername(user_id) m = m.replace("USERNAME()", username) if flavours.config["webhook"]["enable"] and discord_m: if embed_args != None: embed = Webhook(flavours.config["webhook"]["url"], **embed_args, footer="Caker by Sunpy @osufx", footer_icon="http://i.imgur.com/NCYspz8.png") else: embed = Webhook(flavours.config["webhook"]["url"], msg=m) embed.post() except Exception as e: s_print("Unable to call police; {}".format(str(e))) s_print(m)
def getRankInfo(userID, gameMode, mode='normal'): """ Get userID's current rank, user above us and pp/score difference :param userID: user :param gameMode: gameMode number :return: {"nextUsername": "", "difference": 0, "currentRank": 0} """ data = {"nextUsername": "", "difference": 0, "currentRank": 0} if features.RANKING_SCOREV2 and mode == 'alternative': k = "ripple:leaderboard_alt:{}" position = userUtils.getGameRankAlt(userID, gameMode) - 1 elif mode == 'relax': k = "ripple:leaderboard_relax:{}" position = userUtils.getGameRankRx(userID, gameMode) - 1 else: k = "ripple:leaderboard:{}" position = userUtils.getGameRank(userID, gameMode) - 1 k = k.format(scoreUtils.readableGameMode(gameMode)) log.debug("Our position is {}".format(position)) if position is not None and position > 0: aboveUs = glob.redis.zrevrange(k, position - 1, position) log.debug("{} is above us".format(aboveUs)) if aboveUs is not None and len(aboveUs) > 0 and aboveUs[0].isdigit(): # Get our rank, next rank username and pp/score difference myScore = glob.redis.zscore(k, userID) otherScore = glob.redis.zscore(k, aboveUs[0]) nextUsername = userUtils.getUsername(aboveUs[0]) if nextUsername is not None and myScore is not None and otherScore is not None: data["nextUsername"] = nextUsername data["difference"] = int(myScore) - int(otherScore) else: position = 0 data["currentRank"] = position + 1 return data
def __init__(self, userID, token_=None, ip="", irc=False, timeOffset=0, tournament=False): """ Create a token object and set userID and token :param userID: user associated to this token :param token_: if passed, set token to that value if not passed, token will be generated :param ip: client ip. optional. :param irc: if True, set this token as IRC client. Default: False. :param timeOffset: the time offset from UTC for this user. Default: 0. :param tournament: if True, flag this client as a tournement client. Default: True. """ # Set stuff self.userID = userID self.username = userUtils.getUsername(self.userID) self.safeUsername = userUtils.getSafeUsername(self.userID) self.privileges = userUtils.getPrivileges(self.userID) self.admin = userUtils.isInPrivilegeGroup(self.userID, "developer")\ or userUtils.isInPrivilegeGroup(self.userID, "community manager")\ or userUtils.isInPrivilegeGroup(self.userID, "chat mod") self.irc = irc self.kicked = False self.restricted = userUtils.isRestricted(self.userID) self.loginTime = int(time.time()) self.pingTime = self.loginTime self.timeOffset = timeOffset self.streams = [] self.tournament = tournament self.messagesBuffer = [] # Default variables self.spectators = [] # TODO: Move those two vars to a class self.spectating = None self.spectatingUserID = 0 # we need this in case we the host gets DCed self.location = [0, 0] self.joinedChannels = [] self.ip = ip self.country = 0 self.location = [0, 0] self.awayMessage = "" self.sentAway = [] self.matchID = -1 self.tillerino = [0, 0, -1.0] # beatmap, mods, acc self.silenceEndTime = 0 self.queue = bytes() # Spam protection self.spamRate = 0 # Stats cache if userID == 1000: self.actionID = actions.WATCHING else: self.actionID = actions.IDLE if userID == 1000: self.actionText = "HentaiHaven" else: self.actionText = "" self.actionMd5 = "" self.actionMods = 0 self.gameMode = gameModes.STD self.beatmapID = 0 self.rankedScore = 0 self.accuracy = 0.0 self.playcount = 0 self.totalScore = 0 self.gameRank = 0 self.pp = 0 # Relax self.relaxing = False self.relaxAnnounce = False # Generate/set token if token_ is not None: self.token = token_ else: self.token = str(uuid.uuid4()) # Locks self.processingLock = threading.Lock( ) # Acquired while there's an incoming packet from this user self._bufferLock = threading.Lock( ) # Acquired while writing to packets buffer self._spectLock = threading.RLock() # Set stats self.updateCachedStats() # If we have a valid ip, save bancho session in DB so we can cache LETS logins if ip != "": userUtils.saveBanchoSession(self.userID, self.ip) # Join main stream self.joinStream("main")
def eat(score, processes, detected, flags): if flavours.config is None: police.cache_config() do_restrict = False for toppings in detected: if toppings["ban"]: do_restrict = True tag_list = [x["tag"] for x in detected] hax_flags = flags & ~ice_coffee.IGNORE_HAX_FLAGS beatmap_id = get_beatmap_id(score.fileMd5)["beatmap_id"] username = userUtils.getUsername(score.playerUserID) fields = [{ "name": "BeatmapID: {}".format(beatmap_id), "value": "[Download Beatmap](http://{}/b/{})".format( flavours.config["urls"]["main_domain"], beatmap_id), "inline": True }, { "name": "ScoreID: {}".format(score.scoreID), "value": "[Download Replay](http://{}/web/replays/{})".format( flavours.config["urls"]["main_domain"], score.scoreID), "inline": True }] if len(detected) > 0: reason = " & ".join(tag_list) if len(reason) > 86: reason = "reasons..." extra_data = "" if hax_flags != 0: extra_data = "\nHad bad flags: ({}) -> ({})".format( flags, make_flags_string(flags)) if do_restrict: userUtils.restrict(score.playerUserID) userUtils.appendNotes(score.playerUserID, "Restricted due to {}".format(reason)) police.call("{} was restricted for: {} {}".format( username, reason, extra_data), discord_m=True, embed_args={ "color": 0xd9534f, "title": "Bad cake detected", "title_url": "http://old.{}/index.php?p=129&sid={}".format( flavours.config["urls"]["main_domain"], score.scoreID), "desc": "Restricted for: {} {}".format(reason, extra_data), "author": username, "author_icon": "http://a.{}/{}".format( flavours.config["urls"]["main_domain"], score.playerUserID), "author_url": "http://{}/u/{}".format( flavours.config["urls"]["main_domain"], score.playerUserID), "thumbnail": flavours.config["images"]["bad_cake_ban"], "fields": fields }) else: userUtils.appendNotes(score.playerUserID, reason) police.call("{} submitted bad cake: {} {}".format( username, reason, extra_data), discord_m=True, embed_args={ "color": 0xf0ad4e, "title": "Bad cake detected", "title_url": "http://old.{}/index.php?p=129&sid={}".format( flavours.config["urls"]["main_domain"], score.scoreID), "desc": "Had bad cake: {} {}".format(reason, extra_data), "author": username, "author_icon": "http://a.{}/{}".format( flavours.config["urls"]["main_domain"], score.playerUserID), "author_url": "http://{}/u/{}".format( flavours.config["urls"]["main_domain"], score.playerUserID), "thumbnail": flavours.config["images"]["bad_cake"], "fields": fields }) elif hax_flags != 0: police.call( "{} submitted bad flags: ({}) -> ({})".format( username, flags, make_flags_string(flags)), discord_m=True, embed_args={ "color": 0xf0ad4e, "title": "Bad flags detected", "title_url": "http://old.{}/index.php?p=129&sid={}".format( flavours.config["urls"]["main_domain"], score.scoreID), "desc": "({}) -> ({})".format(flags, make_flags_string(flags)), "author": username, "author_icon": "http://a.{}/{}".format(flavours.config["urls"]["main_domain"], score.playerUserID), "author_url": "http://{}/u/{}".format(flavours.config["urls"]["main_domain"], score.playerUserID), "thumbnail": flavours.config["images"]["bad_flag"], "fields": fields }) glob.db.execute( "INSERT INTO cakes(id, userid, score_id, processes, detected, flags) VALUES (NULL,%s,%s,%s,%s,%s)", [ score.playerUserID, score.scoreID, json.dumps(processes), json.dumps(tag_list), flags ])
def edit_map(fro, chan, message): # Edit maps ranking status ingame. // Added by cmyui :) // cmyui why u dont like PEP8? messages = [m.lower() for m in message] rank_type = message[0] map_type = message[1] map_id = message[2] # Get persons username & ID user_id = userUtils.getID(fro) name = userUtils.getUsername(user_id) typeBM = None # Figure out what to do if rank_type == 'rank': rank_typed_str = 'ranke' rank_type_id = 2 freeze_status = 1 elif rank_type == 'love': rank_typed_str = 'love' rank_type_id = 5 freeze_status = 1 elif rank_type == 'unrank': rank_typed_str = 'unranke' rank_type_id = 0 freeze_status = 0 # Grab beatmap_data from db beatmap_data = glob.db.fetch("SELECT * FROM beatmaps WHERE beatmap_id = {} LIMIT 1".format(map_id)) if map_type == 'set': glob.db.execute( "UPDATE beatmaps SET ranked = {}, ranked_status_freezed = {} WHERE beatmapset_id = {} LIMIT 100".format( rank_type_id, freeze_status, beatmap_data["beatmapset_id"])) if freeze_status == 1: glob.db.execute("""UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmapset_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 3""".format( beatmap_data["beatmapset_id"])) typeBM = 'set' elif map_type == 'map': glob.db.execute( "UPDATE beatmaps SET ranked = {}, ranked_status_freezed = {} WHERE beatmap_id = {} LIMIT 1".format( rank_type_id, freeze_status, map_id)) if freeze_status == 1: glob.db.execute("""UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 3""".format( beatmap_data["beatmap_id"])) typeBM = 'beatmap' else: return "Please specify whether it is a set/map. eg: '!map unrank/rank/love set/map 123456'" # Announce / Log to AP logs when ranked status is changed if rank_type == "love": log.rap(user_id, "has {}d beatmap ({}): {} ({}).".format(rank_type, map_type, beatmap_data["song_name"], map_id), True) if map_type == 'set': msg = "{} has loved beatmap set: [https://osu.ppy.sh/s/{} {}]".format(name, beatmap_data["beatmapset_id"], beatmap_data["song_name"]) else: msg = "{} has loved beatmap: [https://osu.ppy.sh/s/{} {}]".format(name, map_id, beatmap_data["song_name"]) glob.db.execute( "UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 2".format( beatmap_data["beatmap_id"])) elif rank_type == "rank": log.rap(user_id, "has {}ed beatmap ({}): {} ({}).".format(rank_type, map_type, beatmap_data["song_name"], map_id), True) if map_type == 'set': msg = "{} has {}ed beatmap set: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type, beatmap_data["beatmapset_id"], beatmap_data["song_name"]) else: msg = "{} has {}ed beatmap: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type, map_id, beatmap_data["song_name"]) glob.db.execute( "UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 2".format( beatmap_data["beatmap_id"])) else: log.rap(user_id, "has {}ed beatmap ({}): {} ({}).".format(rank_type, map_type, beatmap_data["song_name"], map_id), True) if map_type == 'set': msg = "{} has {}ed beatmap set: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type, beatmap_data["beatmapset_id"], beatmap_data["song_name"]) else: msg = "{} has {}ed beatmap: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type, map_id, beatmap_data["song_name"]) glob.db.execute( "UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 2".format( beatmap_data["beatmap_id"])) need_params = { 'token': glob.conf.config["discord"]["krbotToken"], 'poster': fro, 'type': rank_typed_str } if typeBM == 'set': need_params['sid'] = beatmap_data["beatmapset_id"] else: need_params['bid'] = beatmap_data["beatmap_id"] requests.get(glob.conf.config["discord"]["krbot"] + "api/v1/submitMap", params=need_params) chat.sendMessage(glob.BOT_NAME, "#nowranked", msg) return msg
def __init__(self, userID, token_=None, ip="", irc=False, timeOffset=0, tournament=False, ignoreDM=False): """ Create a token object and set userID and token :param userID: user associated to this token :param token_: if passed, set token to that value if not passed, token will be generated :param ip: client ip. optional. :param irc: if True, set this token as IRC client. Default: False. :param timeOffset: the time offset from UTC for this user. Default: 0. :param tournament: if True, flag this client as a tournement client. Default: True. """ # Set stuff self.userID = userID self.username = userUtils.getUsername(self.userID) self.safeUsername = userUtils.getSafeUsername(self.userID) self.privileges = userUtils.getPrivileges(self.userID) self.admin = userUtils.isInPrivilegeGroup(self.userID, "Developer")\ or userUtils.isInPrivilegeGroup(self.userID, "Community Manager")\ or userUtils.isInPrivilegeGroup(self.userID, "Chat Moderators") self.irc = irc self.kicked = False self.restricted = userUtils.isRestricted(self.userID) self.loginTime = int(time.time()) self.pingTime = self.loginTime self.timeOffset = timeOffset self.streams = [] self.tournament = tournament self.messagesBuffer = [] # Default variables self.spectators = [] # TODO: Move those two vars to a class self.spectating = None self.spectatingUserID = 0 # we need this in case we the host gets DCed self.location = [0, 0] self.joinedChannels = [] self.ip = ip self.country = 0 self.location = [0, 0] self.awayMessage = "" self.sentAway = [] self.matchID = -1 self.tillerino = [0, 0, -1.0] # beatmap, mods, acc self.silenceEndTime = 0 self.queue = bytes() # Spam protection self.spamRate = 0 # Stats cache def check_hax_initial(): stmt = [ "SELECT initial_status_type as aid, initial_status_text as atxt", "FROM bancho_status_hax", "WHERE user_id = %s AND NOT", "(initial_status_type IS NULL OR initial_status_text IS NULL OR length(initial_status_text) < 1)" ] result = glob.db.fetch(" ".join(stmt), [userID]) if result is None: self.actionID, self.actionText = actions.IDLE, "" else: self.actionID, self.actionText = result['aid'], result['atxt'] pass check_hax_initial() self.actionMd5 = "" self.actionMods = 0 self.gameMode = gameModes.STD self.beatmapID = 0 self.rankedScore = 0 self.accuracy = 0.0 self.playcount = 0 self.totalScore = 0 self.gameRank = 0 self.noticeFlags = [] self.pp = 0 self._ignoreDM = ignoreDM self.specialMode = 0 # Generate/set token if token_ is not None: self.token = token_ else: self.token = str(uuid.uuid4()) # Locks self.processingLock = threading.Lock( ) # Acquired while there's an incoming packet from this user self._bufferLock = threading.Lock( ) # Acquired while writing to packets buffer self._spectLock = threading.RLock() # Set stats self.updateCachedStats() # If we have a valid ip, save bancho session in DB so we can cache LETS logins if ip != "": userUtils.saveBanchoSession(self.userID, self.ip) # Join main stream self.joinStream("main")
def allPlayersCompleted(self): """ Cleanup match stuff and send match end packet to everyone :return: """ # Collect some info about the match that just ended to send to the api infoToSend = { "id": self.matchID, "name": self.matchName, "beatmap_id": self.beatmapID, "mods": self.mods, "game_mode": self.gameMode, "host_id": self.hostUserID, "host_user_name": userUtils.getUsername(self.hostUserID), "game_type": self.matchTeamType, "game_score_condition": self.matchScoringType, "game_mod_mode": self.matchModMode, "scores": {} } # Add score info for each player for i in range(0, 16): if self.slots[i].user is not None and self.slots[ i].status == slotStatuses.PLAYING: infoToSend["scores"][glob.tokens.tokens[ self.slots[i].user].userID] = { "score": self.slots[i].score, "mods": self.slots[i].mods, "failed": self.slots[i].failed, "pass": self.slots[i].passed, "team": self.slots[i].team, "username": userUtils.getUsername(glob.tokens.tokens[ self.slots[i].user].userID) # vinse shit ;3 } # Send the info to the api glob.redis.publish("api:mp_complete_match", json.dumps(infoToSend)) self.games.append(json.dumps(infoToSend)) # Reset inProgress self.inProgress = False # Reset slots self.resetSlots() # Send match update self.sendUpdates() # Send match complete glob.streams.broadcast(self.streamName, serverPackets.matchComplete()) # Destroy playing stream glob.streams.dispose(self.playingStreamName) glob.streams.remove(self.playingStreamName) # Console output log.info("MPROOM{}: Match completed".format(self.matchID)) # If this is a tournament match, then we send a notification in the chat # saying that the match has completed. chanName = "#multi_{}".format(self.matchID) if self.isTourney and (chanName in glob.channels.channels): chat.sendMessage(glob.BOT_NAME, chanName, "Match has just finished.")