Compare commits
	
		
			27 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | bcee4a202d | ||
|  | fd07cea973 | ||
|  | cfcc17df37 | ||
|  | e4c6543963 | ||
|  | 0abb98f2db | ||
|  | cb9bd6cb5d | ||
|  | 81b44e19fe | ||
|  | 6df638449f | ||
|  | d26270ed73 | ||
|  | ed45506e64 | ||
|  | 3d0fa3ac43 | ||
|  | e0c6feefde | ||
|  | 26c274badb | ||
|  | 2e1ce5a3de | ||
|  | 703ce1c3de | ||
|  | 5dcfdc8577 | ||
|  | d66af9dfb1 | ||
|  | 1090d34d38 | ||
|  | 37730c1bb1 | ||
|  | dba93f8bb3 | ||
|  | 1c6aea6729 | ||
|  | 9b83b1367f | ||
|  | a83af9514a | ||
|  | 3f69038285 | ||
|  | cd08451cd2 | ||
|  | 90a2b8f12c | ||
|  | fc5a025bf0 | 
| @@ -36,7 +36,11 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			username = self.get_argument("u") | ||||
| 			password = self.get_argument("h") | ||||
| 			replayID = self.get_argument("c") | ||||
| 			s = rxscore.score() | ||||
|  | ||||
| 			isRelaxing = False | ||||
| 			if int(replayID) < 500000000: | ||||
| 				isRelaxing = True | ||||
|  | ||||
| 			# Login check | ||||
| 			userID = userUtils.getID(username) | ||||
| 			if userID == 0: | ||||
| @@ -46,19 +50,12 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			if userUtils.check2FA(userID, ip): | ||||
| 				raise exceptions.need2FAException(MODULE_NAME, username, ip) | ||||
|  | ||||
| 			# Get user ID | ||||
| 			if bool(s.mods & 128): # Relax | ||||
| 				replayData = glob.db.fetch("SELECT scores_relax.*, users.username AS uname FROM scores_relax LEFT JOIN users ON scores_relax.userid = users.id WHERE scores_relax.id = %s", [replayID]) | ||||
| 				# Increment 'replays watched by others' if needed | ||||
| 				if replayData is not None: | ||||
| 					if username != replayData["uname"]: | ||||
| 						userUtils.incrementReplaysWatched(replayData["userid"], replayData["play_mode"], s.mods) | ||||
| 			else: | ||||
| 				replayData = glob.db.fetch("SELECT scores.*, users.username AS uname FROM scores LEFT JOIN users ON scores.userid = users.id WHERE scores.id = %s", [replayID]) | ||||
| 				# Increment 'replays watched by others' if needed | ||||
| 				if replayData is not None: | ||||
| 					if username != replayData["uname"]: | ||||
| 						userUtils.incrementReplaysWatched(replayData["userid"], replayData["play_mode"], s.mods) | ||||
| 			replayData = glob.db.fetch("SELECT scores{relax}.*, users.username AS uname FROM scores{relax} LEFT JOIN users ON scores{relax}.userid = users.id WHERE scores{relax}.id = %s".format(relax="_relax" if isRelaxing else ""), [replayID]) | ||||
|  | ||||
| 			# Increment 'replays watched by others' if needed | ||||
| 			if replayData is not None: | ||||
| 				if username != replayData["uname"]: | ||||
| 					userUtils.incrementReplaysWatched(replayData["userid"], replayData["play_mode"], replayData["mods"]) | ||||
|  | ||||
| 			log.info("Serving replay_{}.osr".format(replayID)) | ||||
| 			fileName = ".data/replays/replay_{}.osr".format(replayID) | ||||
|   | ||||
| @@ -83,11 +83,8 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 				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)) | ||||
| 			fileNameShort = fileName[:48]+"..." if len(fileName) > 48 else fileName[:-4] | ||||
| 			log.info("[{}] Requested beatmap {}".format("RELAX" if scoreboardType == 1 and int(self.get_argument("mods")) & 128 else "VANILLA", fileNameShort)) | ||||
|  | ||||
| 			# Create beatmap object and set its data | ||||
| 			bmap = beatmap.beatmap(md5, beatmapSetID, gameMode) | ||||
|   | ||||
| @@ -111,13 +111,12 @@ class handler(requestsManager.asyncRequestHandler): | ||||
|  | ||||
| 			# Get restricted | ||||
| 			restricted = userUtils.isRestricted(userID) | ||||
| 			 | ||||
|  | ||||
| 			# Get variables for relax | ||||
| 			used_mods = int(scoreData[13]) | ||||
| 			isRelaxing = used_mods & 128 | ||||
|  | ||||
| 			# Create score object and set its data | ||||
| 			log.info("[{}] {} has submitted a score on {}...".format("RELAX" if isRelaxing else "VANILLA", username, scoreData[0])) | ||||
| 			s = rxscore.score() if isRelaxing else score.score() | ||||
| 			s.setDataFromScoreData(scoreData) | ||||
|  | ||||
| @@ -141,10 +140,13 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			# increment user playtime | ||||
| 			length = 0 | ||||
| 			if s.passed: | ||||
| 				length = userUtils.getBeatmapTime(beatmapInfo.beatmapID) | ||||
| 				try: | ||||
| 					length = userUtils.getBeatmapTime(beatmapInfo.beatmapID) | ||||
| 				except Exception: | ||||
| 					log.error("Error while contacting mirror server.") | ||||
| 			else: | ||||
| 				length = math.ceil(int(self.get_argument("ft")) / 1000) | ||||
| 				 | ||||
|  | ||||
| 			userUtils.incrementPlaytime(userID, s.gameMode, length) | ||||
| 			# Calculate PP | ||||
| 			midPPCalcException = None | ||||
| @@ -159,51 +161,51 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 				log.error("Caught an exception in pp calculation, re-raising after saving score in db") | ||||
| 				s.pp = 0 | ||||
| 				midPPCalcException = e | ||||
| 				 | ||||
|  | ||||
| 			# Restrict obvious cheaters™ | ||||
| 			if restricted == False: | ||||
| 				if isRelaxing: # Relax | ||||
| 					rxGods = [7340, 2137, 6868, 1215, 15066, 14522, 1325, 5798, 21610, 1254, 15070, 3445, 17157, 14791, 14728] # Yea yea it's a bad way of doing it, kill yourself - cmyui osu gaming | ||||
| 					rxGods = [7340, 2137, 6868, 1215, 15066, 14522, 1325, 5798, 21610, 1254, 15070, 3445, 17157, 14791, 14728, 1366, 2961, 5524, 1188, 1401, 26754, 3388, 5692, 2173, 4299] # Yea yea it's a bad way of doing it; will fix. | ||||
| 					""" | ||||
| 					CTBLIST = [] | ||||
| 					TAIKOLIST = [] | ||||
| 					""" | ||||
| 					if (s.pp >= 1200 and s.gameMode == gameModes.STD and used_mods & 1024) and userID not in rxGods: | ||||
| 					if s.gameMode == gameModes.STD and userID not in rxGods: | ||||
| 						if (s.pp >= 1100) and used_mods & 1024 and userID != 17547: # MBMasher plays too much FL; make him an exception just incase. | ||||
| 							userUtils.restrict(userID) | ||||
| 							userUtils.appendNotes(userID, "[osu!] Restricted due to too high pp gain with FLASHLIGHT ({}pp).".format(s.pp)) | ||||
| 							log.warning("[osu!] **{}** ({}) has been restricted due to too high pp gain with FLASHLIGHT **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 						elif (s.pp >= 1600): | ||||
| 							userUtils.restrict(userID) | ||||
| 							userUtils.appendNotes(userID, "[osu!] Restricted due to too high pp gain ({}pp).".format(s.pp)) | ||||
| 							log.warning("[osu!] **{}** ({}) has been restricted due to too high pp gain **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 					elif (s.pp >= 1000) and s.gameMode == gameModes.TAIKO: | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain with FLASHLIGHT ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain with FLASHLIGHT **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 					elif (s.pp >= 2000 and s.gameMode == gameModes.STD) and userID not in rxGods: | ||||
| 						userUtils.appendNotes(userID, "[osu!taiko] Restricted due to too high pp gain ({}pp).".format(s.pp)) | ||||
| 						log.warning("[osu!taiko] **{}** ({}) has been restricted due to too high pp gain **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 					elif (s.pp >= 1350) and s.gameMode == gameModes.CTB: | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 						""" | ||||
| 					elif (s.pp >= 10000 and s.gameMode == gameModes.TAIKO) and userID not in TAIKOLIST: | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 					elif s.pp >= 10000 and (s.gameMode == gameModes.CTB) and userID not in CTBLIST: | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 						""" | ||||
| 						userUtils.appendNotes(userID, "[osu!catch] Restricted due to too high pp gain ({}pp).".format(s.pp)) | ||||
| 						log.warning("[osu!catch] **{}** ({}) has been restricted due to too high pp gain **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 				else: # Vanilla | ||||
| 					if (s.pp >= 500 and s.gameMode == gameModes.STD and used_mods & 1024): | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain with FLASHLIGHT ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain with FLASHLIGHT **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 					elif (s.pp >= 700 and s.gameMode == gameModes.STD): | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 					if s.gameMode == gameModes.STD: | ||||
| 						if (s.pp >= 500) and used_mods & 1024: | ||||
| 							userUtils.restrict(userID) | ||||
| 							userUtils.appendNotes(userID, "[osu!] Restricted due to too high pp gain with FLASHLIGHT ({}pp).".format(s.pp)) | ||||
| 							log.warning("[osu!] **{}** ({}) has been restricted due to too high pp gain with FLASHLIGHT **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 						elif (s.pp >= 700): | ||||
| 							userUtils.restrict(userID) | ||||
| 							userUtils.appendNotes(userID, "[osu!] Restricted due to too high pp gain ({}pp).".format(s.pp)) | ||||
| 							log.warning("[osu!] **{}** ({}) has been restricted due to too high pp gain **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 						""" | ||||
| 					elif (s.pp >= 10000 and s.gameMode == gameModes.TAIKO): | ||||
| 					elif (s.pp >= 10000) and s.gameMode == gameModes.TAIKO: | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 					elif s.pp >= 10000 and (s.gameMode == gameModes.CTB): | ||||
| 						userUtils.appendNotes(userID, "[osu!taiko] Restricted due to too high pp gain ({}pp).".format(s.pp)) | ||||
| 						log.warning("[osu!taiko] **{}** ({}) has been restricted due to too high pp gain **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 					elif s.pp >= 10000) and (s.gameMode == gameModes.CTB: | ||||
| 						userUtils.restrict(userID) | ||||
| 						userUtils.appendNotes(userID, "Restricted due to too high pp gain ({}pp)".format(s.pp)) | ||||
| 						log.warning("**{}** ({}) has been restricted due to too high pp gain **({}pp)**".format(username, userID, s.pp), "cm") | ||||
| 						userUtils.appendNotes(userID, "[osu!catch] Restricted due to too high pp gain ({}pp).".format(s.pp)) | ||||
| 						log.warning("[osu!catch] **{}** ({}) has been restricted due to too high pp gain **({}pp)**.".format(username, userID, s.pp), "cm") | ||||
| 						""" | ||||
|  | ||||
| 			# Check notepad hack | ||||
| @@ -230,7 +232,6 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 					oldPersonalBestRank = 0 | ||||
| 					oldPersonalBest = None			 | ||||
|  | ||||
|  | ||||
| 			# Save score in db | ||||
| 			s.saveScoreInDB() | ||||
|  | ||||
| @@ -238,22 +239,23 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			haxFlags = scoreData[17].count(' ') # 4 is normal, 0 is irregular but inconsistent. | ||||
| 			if haxFlags != 4 and haxFlags != 0 and s.completed > 1 and restricted == False: | ||||
|  | ||||
| 				flagsReadable = generalUtils.calculateFlags(haxFlags, used_mods, s.gameMode) | ||||
| 				userUtils.appendNotes(userID, "-- has received clientside flags: {} [{}] (cheated score id: {})".format(haxFlags, flagsReadable, s.scoreID)) | ||||
| 				log.warning("**{}** ({}) has received clientside anti cheat flags.\n\nFlags: {}.\n[{}]\n\nScore ID: {scoreID}\nReplay: https://akatsuki.pw/web/replays/{scoreID}".format(username, userID, haxFlags, flagsReadable, scoreID=s.scoreID), "cm") | ||||
| 				flagsReadable = generalUtils.calculateFlags(int(haxFlags), used_mods, s.gameMode) | ||||
| 				if len(flagsReadable) > 1: | ||||
| 					userUtils.appendNotes(userID, "-- has received clientside flags: {} [{}] (cheated score id: {})".format(haxFlags, flagsReadable, s.scoreID)) | ||||
| 					log.warning("**{}** (https://akatsuki.pw/{relax}u/{}) has received clientside anti cheat flags.\n\nFlags: {}.\n[{}]\n\nScore ID: {scoreID}\nReplay: https://akatsuki.pw/web/replays/{scoreID}".format(username, userID, haxFlags, flagsReadable, scoreID=s.scoreID, relax="rx/" if isRelaxing else ""), "cm") | ||||
|  | ||||
| 			if s.score < 0 or s.score > (2 ** 63) - 1: | ||||
| 				userUtils.ban(userID) | ||||
| 				userUtils.appendNotes(userID, "Banned due to negative score.") | ||||
|  | ||||
| 			if s.passed: # just incase :)! | ||||
| 				if (s.score - (s.c300 * 300 + s.c100 * 100 + s.c50 * 50)) < 0 and not isRelaxing: | ||||
| 			if s.completed == 3: # just incase :)! | ||||
| 				if (s.score - (s.c300 * 300 + s.c100 * 100 + s.c50 * 50)) < 0 and not isRelaxing and s.gameMode == 0: | ||||
| 					#userUtils.ban(userID) | ||||
| 					#userUtils.appendNotes(userID, "Banned due to score being less than no-combo value.") | ||||
| 					log.cmyui("{} has submitted a score where score is less than no-combo value. (scoreID: {}, score: {}, pp:{})".format(username, s.scoreID, s.score, s.pp), discord="cm") | ||||
| 					log.cmyui("{} (https://akatsuki.pw/{relax}u/{}) has submitted a score where score is less than no-combo value. (scoreID: {}, score: {}, pp:{})".format(username, userID, s.scoreID, s.score, s.pp, relax="rx/" if isRelaxing else ""), discord="cm") | ||||
|  | ||||
| 				if s.fullCombo and s.cMiss > 0: | ||||
| 					log.cmyui("{} has submitted a score with 'fullCombo' flag, but has > 0 misses. (scoreID: {}, score: {}, pp:{})".format(username, s.scoreID, s.score, s.pp), discord="cm") | ||||
| 					log.cmyui("{} (https://akatsuki.pw/{relax}u/{}) has submitted a score with 'fullCombo' flag, but has > 0 misses. (scoreID: {}, score: {}, pp:{})".format(username, userID, s.scoreID, s.score, s.pp, relax="rx/" if isRelaxing else ""), discord="cm") | ||||
|  | ||||
| 			# Make sure the score is not memed | ||||
| 			if s.gameMode == gameModes.MANIA and s.score > 1000000: | ||||
| @@ -263,7 +265,7 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			# Ci metto la faccia, ci metto la testa e ci metto il mio cuore | ||||
| 			if ((s.mods & mods.DOUBLETIME) > 0 and (s.mods & mods.HALFTIME) > 0) \ | ||||
| 					or ((s.mods & mods.HARDROCK) > 0 and (s.mods & mods.EASY) > 0) \ | ||||
| 					or ((s.mods & mods.SUDDENDEATH) > 0 and (s.mods & mods.NOFAIL) > 0)\ | ||||
| 					or ((s.mods & mods.SUDDENDEATH) > 0 and (s.mods & mods.NOFAIL) > 0) \ | ||||
| 					or ((s.mods & mods.RELAX) > 0 and (s.mods & mods.RELAX2) > 0): | ||||
| 				userUtils.ban(userID) | ||||
| 				userUtils.appendNotes(userID, "Impossible mod combination ({}).".format(s.mods)) | ||||
| @@ -327,6 +329,11 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			# Update beatmap playcount (and passcount) | ||||
| 			beatmap.incrementPlaycount(s.fileMd5, s.passed) | ||||
|  | ||||
| 			# Print out score submission | ||||
| 			songNameFull = beatmapInfo.songName.encode().decode("ASCII", "ignore") | ||||
| 			songNameShort = songNameFull[:48]+"..." if len(songNameFull) > 48 else songNameFull[:-4] | ||||
| 			log.info("[{}] {} has submitted a score on {}...".format("RELAX" if isRelaxing else "VANILLA", username, songNameShort)) | ||||
|  | ||||
| 			# Let the api know of this score | ||||
| 			if s.scoreID: | ||||
| 				glob.redis.publish("api:score_submission", s.scoreID) | ||||
| @@ -347,7 +354,6 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 					oldUserData = glob.userStatsCache.get(userID, s.gameMode) | ||||
| 					oldRank = userUtils.getGameRank(userID, s.gameMode) | ||||
|  | ||||
|  | ||||
| 			# Always update users stats (total/ranked score, playcount, level, acc and pp) | ||||
| 			# even if not passed | ||||
|  | ||||
| @@ -401,7 +407,6 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 			if beatmapInfo is not None and beatmapInfo != False and s.passed: | ||||
| 				log.debug("Started building ranking panel.") | ||||
|  | ||||
|  | ||||
| 				if isRelaxing: # Relax | ||||
| 					# Trigger bancho stats cache update | ||||
| 					glob.redis.publish("peppy:update_rxcached_stats", userID) | ||||
| @@ -497,6 +502,7 @@ class handler(requestsManager.asyncRequestHandler): | ||||
| 					params = urlencode({"k": glob.conf.config["server"]["apikey"], "to": "#announce", "msg": annmsg}) | ||||
| 					requests.get("{}/api/v1/fokabotMessage?{}".format(glob.conf.config["server"]["banchourl"], params)) | ||||
|  | ||||
| 					# Add the #1 to the database. Yes this is spaghetti. | ||||
| 					scoreUtils.newFirst(s.scoreID, userID, s.fileMd5, s.gameMode, isRelaxing) | ||||
|  | ||||
| 				# Write message to client | ||||
|   | ||||
| @@ -4,5 +4,4 @@ def zingonify(d): | ||||
|     :param d: input dict | ||||
|     :return: zingonified dict as str | ||||
|     """ | ||||
|      | ||||
|     return "|".join(f"{k}:{v}" for k, v in d.items()) | ||||
| @@ -55,7 +55,11 @@ class scoreboard: | ||||
| 			friends = "AND (scores_relax.userid IN (SELECT user2 FROM users_relationships WHERE user1 = %(userid)s) OR scores_relax.userid = %(userid)s)" | ||||
|  | ||||
| 		# Sort and limit at the end | ||||
| 		order = "ORDER BY pp DESC" | ||||
| 		if self.beatmap.rankedStatus == rankedStatuses.LOVED: | ||||
| 			order = "ORDER BY score DESC" | ||||
| 		else: | ||||
| 			order = "ORDER BY pp DESC" | ||||
|  | ||||
| 		limit = "LIMIT 1" | ||||
|  | ||||
| 		# Build query, get params and run query | ||||
| @@ -109,7 +113,7 @@ class scoreboard: | ||||
| 			country = "" | ||||
|  | ||||
| 		# Mods ranking (ignore auto, since we use it for pp sorting) | ||||
| 		if self.mods > -1 and self.mods & modsEnum.AUTOPLAY == 0: | ||||
| 		if self.mods > -1: | ||||
| 			mods = "AND scores_relax.mods = %(mods)s" | ||||
| 		else: | ||||
| 			mods = "" | ||||
| @@ -204,24 +208,28 @@ class scoreboard: | ||||
|  | ||||
| 		# We have a score, run the huge query | ||||
| 		# Base query | ||||
| 	 | ||||
| 		overwrite = "pp" | ||||
| 		# We have a score, run the huge query | ||||
| 		# Base query | ||||
| 		query = """SELECT COUNT(*) AS rank FROM scores_relax STRAIGHT_JOIN users ON scores_relax.userid = users.id STRAIGHT_JOIN users_stats ON users.id = users_stats.id WHERE scores_relax.{0} >= ( | ||||
| 		SELECT {0} FROM scores_relax WHERE beatmap_md5 = %(md5)s AND play_mode = %(mode)s AND completed = 3 AND userid = %(userid)s LIMIT 1 | ||||
| 		) AND scores_relax.beatmap_md5 = %(md5)s AND scores_relax.play_mode = %(mode)s AND scores_relax.completed = 3 AND users.privileges & 1 > 0""".format(overwrite) | ||||
| 		query = """SELECT COUNT(*) AS rank FROM scores_relax STRAIGHT_JOIN users ON scores_relax.userid = users.id STRAIGHT_JOIN users_stats ON users.id = users_stats.id WHERE scores_relax.{PPorScore} >= ( | ||||
| 		SELECT {PPorScore} FROM scores_relax WHERE beatmap_md5 = %(md5)s AND play_mode = %(mode)s AND completed = 3 AND userid = %(userid)s LIMIT 1 | ||||
| 		) AND scores_relax.beatmap_md5 = %(md5)s AND scores_relax.play_mode = %(mode)s AND scores_relax.completed = 3 AND users.privileges & 1 > 0""".format(PPorScore="score" if self.beatmap.rankedStatus == rankedStatuses.LOVED else "pp") | ||||
|  | ||||
| 		# Country | ||||
| 		if self.country: | ||||
| 			query += " AND users_stats.country = (SELECT country FROM users_stats WHERE id = %(userid)s LIMIT 1)" | ||||
|  | ||||
| 		# Mods | ||||
| 		if self.mods > -1: | ||||
| 			query += " AND scores_relax.mods = %(mods)s" | ||||
|  | ||||
| 		# Friends | ||||
| 		if self.friends: | ||||
| 			query += " AND (scores_relax.userid IN (SELECT user2 FROM users_relationships WHERE user1 = %(userid)s) OR scores_relax.userid = %(userid)s)" | ||||
|  | ||||
| 		# Sort and limit at the end | ||||
| 		query += " ORDER BY pp DESC LIMIT 1".format(overwrite) | ||||
| 		if self.beatmap.rankedStatus == rankedStatuses.LOVED: | ||||
| 			query += " ORDER BY score DESC LIMIT 1" | ||||
| 		else: | ||||
| 			query += " ORDER BY pp DESC LIMIT 1" | ||||
|  | ||||
| 		result = glob.db.fetch(query, {"md5": self.beatmap.fileMD5, "userid": self.userID, "mode": self.gameMode, "mods": self.mods}) | ||||
| 		if result is not None: | ||||
| 			self.personalBestRank = result["rank"] | ||||
| @@ -241,10 +249,10 @@ class scoreboard: | ||||
| 			# Set personal best score rank | ||||
| 			self.setPersonalBestRank()	# sets self.personalBestRank with the huge query | ||||
| 			self.scores[0].rank = self.personalBestRank | ||||
| 			data += self.scores[0].getData(pp=True) | ||||
| 			data += self.scores[0].getData() | ||||
|  | ||||
| 		# Output top 50 scores | ||||
| 		for i in self.scores[1:]: | ||||
| 			data += i.getData(pp=True) | ||||
| 			data += i.getData(pp=self.beatmap.rankedStatus != rankedStatuses.LOVED) | ||||
|  | ||||
| 		return data | ||||
|   | ||||
| @@ -206,11 +206,16 @@ class score: | ||||
| 			self.rank, | ||||
| 			self.date) | ||||
|  | ||||
| 	def setCompletedStatus(self): | ||||
| 	def setCompletedStatus(self, b = None): | ||||
| 		""" | ||||
| 		Set this score completed status and rankedScoreIncrease | ||||
| 		""" | ||||
| 		self.completed = 0 | ||||
|  | ||||
| 		# Create beatmap object | ||||
| 		if b is None: | ||||
| 			b = beatmap.beatmap(self.fileMd5, 0) | ||||
|  | ||||
| 		if self.passed == True and scoreUtils.isRankable(self.mods): | ||||
| 			# Get userID | ||||
| 			userID = userUtils.getID(self.playerName) | ||||
| @@ -232,17 +237,31 @@ class score: | ||||
| 				self.oldPersonalBest = 0 | ||||
| 			else: | ||||
| 				# Compare personal best's score with current score | ||||
| 				if self.pp > personalBest["pp"]: | ||||
| 					# New best score | ||||
| 				if b.rankedStatus == rankedStatuses.RANKED: | ||||
| 					self.completed = 3 | ||||
| 					self.rankedScoreIncrease = self.score-personalBest["score"] | ||||
| 					self.oldPersonalBest = personalBest["id"] | ||||
| 				else: | ||||
| 					self.completed = 2 | ||||
| 					self.rankedScoreIncrease = 0 | ||||
| 					self.oldPersonalBest = 0 | ||||
| 					self.calculatePP() | ||||
| 					if self.pp > personalBest["pp"]: | ||||
| 						# New best score | ||||
| 						self.completed = 3 | ||||
| 						self.rankedScoreIncrease = self.score-personalBest["score"] | ||||
| 						self.oldPersonalBest = personalBest["id"] | ||||
| 					else: | ||||
| 						self.completed = 2 | ||||
| 						self.rankedScoreIncrease = 0 | ||||
| 						self.oldPersonalBest = 0 | ||||
| 				elif b.rankedStatus == rankedStatuses.LOVED: | ||||
| 					if self.score > personalBest["score"]: | ||||
| 						# New best score | ||||
| 						self.completed = 3 | ||||
| 						self.rankedScoreIncrease = self.score-personalBest["score"] | ||||
| 						self.oldPersonalBest = personalBest["id"] | ||||
| 					else: | ||||
| 						self.completed = 2 | ||||
| 						self.rankedScoreIncrease = 0 | ||||
| 						self.oldPersonalBest = 0 | ||||
| 					self.completed = 3	 | ||||
|  | ||||
| 		log.info("Completed status: {}".format(self.completed)) | ||||
| 		#log.info("Completed status: {}".format(self.completed)) | ||||
|  | ||||
| 	def saveScoreInDB(self): | ||||
| 		""" | ||||
|   | ||||
| @@ -205,11 +205,16 @@ class score: | ||||
| 			self.rank, | ||||
| 			self.date) | ||||
|  | ||||
| 	def setCompletedStatus(self): | ||||
| 	def setCompletedStatus(self, b = None): | ||||
| 		""" | ||||
| 		Set this score completed status and rankedScoreIncrease | ||||
| 		""" | ||||
| 		self.completed = 0 | ||||
|  | ||||
| 		# Create beatmap object | ||||
| 		if b is None: | ||||
| 			b = beatmap.beatmap(self.fileMd5, 0) | ||||
|  | ||||
| 		if self.passed == True and scoreUtils.isRankable(self.mods): | ||||
| 			# Get userID | ||||
| 			userID = userUtils.getID(self.playerName) | ||||
| @@ -231,17 +236,28 @@ class score: | ||||
| 				self.oldPersonalBest = 0 | ||||
| 			else: | ||||
| 				# Compare personal best's score with current score | ||||
| 				if self.pp > personalBest["pp"]: | ||||
| 					# New best score | ||||
| 					self.completed = 3 | ||||
| 					self.rankedScoreIncrease = self.score-personalBest["score"] | ||||
| 					self.oldPersonalBest = personalBest["id"] | ||||
| 				else: | ||||
| 					self.completed = 2 | ||||
| 					self.rankedScoreIncrease = 0 | ||||
| 					self.oldPersonalBest = 0 | ||||
| 				if b.rankedStatus == rankedStatuses.RANKED: | ||||
| 					if self.pp > personalBest["pp"]: | ||||
| 						# New best score | ||||
| 						self.completed = 3 | ||||
| 						self.rankedScoreIncrease = self.score-personalBest["score"] | ||||
| 						self.oldPersonalBest = personalBest["id"] | ||||
| 					else: | ||||
| 						self.completed = 2 | ||||
| 						self.rankedScoreIncrease = 0 | ||||
| 						self.oldPersonalBest = 0 | ||||
| 				elif b.rankedStatus == rankedStatuses.LOVED: | ||||
| 					if self.score > personalBest["score"]: | ||||
| 						# New best score | ||||
| 						self.completed = 3 | ||||
| 						self.rankedScoreIncrease = self.score-personalBest["score"] | ||||
| 						self.oldPersonalBest = personalBest["id"] | ||||
| 					else: | ||||
| 						self.completed = 2 | ||||
| 						self.rankedScoreIncrease = 0 | ||||
| 						self.oldPersonalBest = 0 | ||||
|  | ||||
| 		log.info("Completed status: {}".format(self.completed)) | ||||
| 		#log.info("Completed status: {}".format(self.completed)) | ||||
|  | ||||
| 	def saveScoreInDB(self): | ||||
| 		""" | ||||
|   | ||||
| @@ -109,7 +109,7 @@ class scoreboard: | ||||
| 			country = "" | ||||
|  | ||||
| 		# Mods ranking (ignore auto, since we use it for pp sorting) | ||||
| 		if self.mods > -1 and self.mods & modsEnum.AUTOPLAY == 0: | ||||
| 		if self.mods > -1: | ||||
| 			mods = "AND scores.mods = %(mods)s" | ||||
| 		else: | ||||
| 			mods = "" | ||||
| @@ -204,15 +204,19 @@ class scoreboard: | ||||
| 		query = """SELECT COUNT(*) AS rank FROM scores STRAIGHT_JOIN users ON scores.userid = users.id STRAIGHT_JOIN users_stats ON users.id = users_stats.id WHERE scores.score >= ( | ||||
| 		SELECT score FROM scores WHERE beatmap_md5 = %(md5)s AND play_mode = %(mode)s AND completed = 3 AND userid = %(userid)s LIMIT 1 | ||||
| 		) AND scores.beatmap_md5 = %(md5)s AND scores.play_mode = %(mode)s AND scores.completed = 3 AND users.privileges & 1 > 0""" | ||||
|  | ||||
| 		# Country | ||||
| 		if self.country: | ||||
| 			query += " AND users_stats.country = (SELECT country FROM users_stats WHERE id = %(userid)s LIMIT 1)" | ||||
|  | ||||
| 		# Mods | ||||
| 		if self.mods > -1: | ||||
| 			query += " AND scores.mods = %(mods)s" | ||||
|  | ||||
| 		# Friends | ||||
| 		if self.friends: | ||||
| 			query += " AND (scores.userid IN (SELECT user2 FROM users_relationships WHERE user1 = %(userid)s) OR scores.userid = %(userid)s)" | ||||
|  | ||||
| 		# Sort and limit at the end | ||||
| 		query += " ORDER BY score DESC LIMIT 1" | ||||
| 		result = glob.db.fetch(query, {"md5": self.beatmap.fileMD5, "userid": self.userID, "mode": self.gameMode, "mods": self.mods}) | ||||
| @@ -238,6 +242,6 @@ class scoreboard: | ||||
|  | ||||
| 		# Output top 50 scores | ||||
| 		for i in self.scores[1:]: | ||||
| 			data += i.getData(pp=self.mods > -1 and self.mods & modsEnum.AUTOPLAY > 0) | ||||
| 			data += i.getData(pp=self.mods > -1) | ||||
|  | ||||
| 		return data | ||||
|   | ||||
		Reference in New Issue
	
	Block a user