import json import tornado.gen import tornado.web from objects import beatmap from objects import scoreboard from objects import relaxboard from common.constants import privileges from common.log import logUtils as log from common.ripple import userUtils from common.web import requestsManager from constants import exceptions from objects import glob from common.constants import mods from common.sentry import sentry MODULE_NAME = "get_scores" class handler(requestsManager.asyncRequestHandler): """ Handler for /web/osu-osz2-getscores.php """ @tornado.web.asynchronous @tornado.gen.engine @sentry.captureTornado def asyncGet(self): try: # Get request ip ip = self.getRequestIP() # Print arguments if glob.debug: requestsManager.printArguments(self) # TODO: Maintenance check # Check required arguments if not requestsManager.checkArguments(self.request.arguments, ["c", "f", "i", "m", "us", "v", "vv", "mods"]): raise exceptions.invalidArgumentsException(MODULE_NAME) # GET parameters md5 = self.get_argument("c") fileName = self.get_argument("f") beatmapSetID = self.get_argument("i") gameMode = self.get_argument("m") username = self.get_argument("us") password = self.get_argument("ha") scoreboardType = int(self.get_argument("v")) scoreboardVersion = int(self.get_argument("vv")) # Login and ban check userID = userUtils.getID(username) if userID == 0: raise exceptions.loginFailedException(MODULE_NAME, userID) if not userUtils.checkLogin(userID, password, ip): raise exceptions.loginFailedException(MODULE_NAME, username) if userUtils.check2FA(userID, ip): raise exceptions.need2FAException(MODULE_NAME, username, ip) # Ban check is pointless here, since there's no message on the client #if userHelper.isBanned(userID) == True: # raise exceptions.userBannedException(MODULE_NAME, username) # Hax check if "a" in self.request.arguments: if int(self.get_argument("a")) == 1 and not userUtils.getAqn(userID): log.warning("Found AQN folder on user {} ({})".format(username, userID), "cm") userUtils.setAqn(userID) # Scoreboard type isDonor = userUtils.getPrivileges(userID) & privileges.USER_DONOR > 0 country = False friends = False modsFilter = -1 mods = int(self.get_argument("mods")) if scoreboardType == 4: # Country leaderboard country = True elif scoreboardType == 2: # Mods leaderboard, replace mods (-1, every mod) with "mods" GET parameters modsFilter = int(self.get_argument("mods")) elif scoreboardType == 3 and isDonor: # Friends leaderboard friends = True # Console output fileNameShort = fileName[:32]+"..." if len(fileName) > 32 else fileName[:-4] if scoreboardType == 1 and int(self.get_argument("mods")) & 128: log.info("[RELAX] Requested beatmap {} ({})".format(fileNameShort, md5)) else: log.info("[VANILLA] Requested beatmap {} ({})".format(fileNameShort, md5)) # Create beatmap object and set its data bmap = beatmap.beatmap(md5, beatmapSetID, gameMode) if int(self.get_argument("mods")) & 128: glob.redis.publish("peppy:update_rxcached_stats", userID) else: glob.redis.publish("peppy:update_cached_stats", userID) if bool(mods & 128): sboard = relaxboard.scoreboard(username, gameMode, bmap, setScores=True, country=country, mods=modsFilter, friends=friends) else: sboard = scoreboard.scoreboard(username, gameMode, bmap, setScores=True, country=country, mods=modsFilter, friends=friends) # Data to return data = "" data += bmap.getData(sboard.totalScores, scoreboardVersion) data += sboard.getScoresData() self.write(data) # Datadog stats glob.dog.increment(glob.DATADOG_PREFIX+".served_leaderboards") except exceptions.need2FAException: self.write("error: 2fa") except exceptions.invalidArgumentsException: self.write("error: meme") except exceptions.userBannedException: self.write("error: ban") except exceptions.loginFailedException: self.write("error: pass")