Skip to content
This repository has been archived by the owner on Jun 10, 2023. It is now read-only.

Commit

Permalink
add level leaderboards
Browse files Browse the repository at this point in the history
  • Loading branch information
RealistikDash committed Oct 13, 2020
1 parent 08237bd commit 7382189
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 7 deletions.
69 changes: 67 additions & 2 deletions handlers/levelextras.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
from helpers.commenthelper import comment_helper
from helpers.userhelper import user_helper
from helpers.levelhelper import level_helper
from helpers.generalhelper import wave_string
from helpers.generalhelper import wave_string, joint_string
from helpers.timehelper import time_ago, get_timestamp
from helpers.auth import auth
from helpers.crypthelper import decode_base64
from helpers.filterhelper import check_comment
from helpers.priveliegehelper import priv_helper
from helpers.crypthelper import decode_base64
from helpers.lang import lang
from helpers.scorehelper import score_helper
from objects.comments import Comment, CommentBan
from gdpys.client import client
from objects.levels import Rating
from objects.levels import Rating, Score
from constants import ResponseCodes, Permissions
from config import user_config
import aiohttp
Expand Down Expand Up @@ -145,3 +146,67 @@ async def rate_level_handler(request : aiohttp.web.Request):
)
await level_helper.rate_level(rating)
return aiohttp.web.Response(text=ResponseCodes.generic_success)

async def level_scores_handler(request : aiohttp.web.Request) -> aiohttp.web.Response:
"""Handles score submission and score leaderboards."""
post_data = await request.post()

# Authentication
account_id = int(post_data["accountID"]) # Lets declare this as we will re-use it later
if not auth.check_gjp(account_id, post_data["gjp"]):
return aiohttp.web.Response(text=ResponseCodes.generic_fail)

# Creating the current score object.
level_id = int(post_data["levelID"])
percent = int(post_data.get("percent", 0))
attempts = int(post_data.get("s1", 8354)) - 8354 # Rob tried to pull a sneaky on us
coins = int(post_data.get("s9", 5819)) - 5819
score = Score(
ID = None, # It is a new score
account_id=account_id,
level_id=level_id,
percentage=percent,
timestamp=get_timestamp(),
attempts=attempts,
coins=coins
)

logging.debug(score)
# Checking and overwriting the score.
if await score_helper.overwrite_score(score=score) and score.percentage > 0:
logging.debug(lang.debug("overwrite_score"))
old_score = await score_helper.get_score_for_user(score.account_id, score.level_id)
if old_score is not None:
await score_helper.delete_score(old_score.ID)
# TODO: Implement anticheat (Cheatless V2)
await score_helper.save_score_to_db(score)

# Scores leaderboard.
lb_type = int(post_data["type"])
lbs_get = { # Budget switch statement.
1 : score_helper.get_from_db
}.get(lb_type, score_helper.get_from_db)
leaderboards = await lbs_get(level_id)

# Creating the server response.
response = ""
for i in range(len(leaderboards)):
lb_score : Score = leaderboards[i]
user = await user_helper.get_object(lb_score.account_id)
response += joint_string({
1 : user.username,
2 : user.user_id,
3 : lb_score.percentage,
6 : i+1, # +1 since it starts from 0
9 : user.icon,
10 : user.colour1,
11 : user.colour2,
13 : lb_score.coins,
14 : user.icon_type,
15 : 0,
16 : user.account_id,
42 : time_ago(lb_score.timestamp)
}) + "|"
response = response[:-1]
logging.debug(response)
return aiohttp.web.Response(text=response)
8 changes: 5 additions & 3 deletions helpers/scorehelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def _score_obj_from_tuple(self, db_result : tuple) -> Score:
return Score(
ID = db_result[0],
account_id=db_result[1],
levelID = db_result[2],
level_id = db_result[2],
percentage=db_result[3],
timestamp=int(db_result[4]),
attempts=db_result[5],
Expand All @@ -25,7 +25,7 @@ async def get_from_db(self, level_id : int) -> list:
"""Gets a list of user scores from database for level."""
logging.debug(lang.debug("level_scores_gotten", level_id))
async with myconn.conn.cursor() as mycursor:
await mycursor.execute("SELECT scoreID, accountID, levelID, percent, uploadDate, attempts, coins FROM levelscores WHERE levelID = %s", (level_id,))
await mycursor.execute("SELECT scoreID, accountID, levelID, percent, uploadDate, attempts, coins FROM levelscores WHERE levelID = %s ORDER BY percent DESC LIMIT 100", (level_id,))
return [self._score_obj_from_tuple(i) for i in await mycursor.fetchall()]

async def get_from_db_filtered(self, level_id : int, filters : list):
Expand All @@ -52,7 +52,7 @@ async def delete_score(self, score_id : int):
async def get_score_for_user(self, account_id : int, level_id : int) -> Score:
"""Returns the top score for user on a certain level (can return None)."""
async with myconn.conn.cursor() as mycursor:
await mycursor.execute("SELECT scoreID, accountID, levelID, percent, uploadDate, attempts, coins FROM levelscores WHERE levelID = %s AND accountID = %s ORDER BY percent DESC LIMIT 1", (level_id,))
await mycursor.execute("SELECT scoreID, accountID, levelID, percent, uploadDate, attempts, coins FROM levelscores WHERE levelID = %s AND accountID = %s ORDER BY percent DESC LIMIT 1", (level_id, account_id))
score_db = await mycursor.fetchone()

if score_db is None: # No score set by user on that level.
Expand All @@ -69,3 +69,5 @@ async def overwrite_score(self, score : Score) -> bool:
return True # It is a new score.

return score.percentage > curr_score.percentage # Replace based on percentage

score_helper = ScoreHelper() # Global score helper.
3 changes: 2 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"cp_gain" : "{0} has gained {1} CP!",
"obj_caching" : "The object does not exist! Caching from database.",
"level_scores_gotten" : "Fetched level leaderboards for level {0}.",
"no_score" : "This user has not set a score on this level."
"no_score" : "This user has not set a score on this level.",
"overwrite_score" : "Overwriting this score."
},
"runtime": {
"shutdown": "Shutting down! Bye!",
Expand Down
3 changes: 2 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from handlers.songs import featured_artists_handler, get_songinfo_handler
from handlers.levels import level_search_modular_hanlder, download_level, upload_level_handler, get_daily_handler, get_map_packs_handler, get_gauntlets_handler
from handlers.rewards import quests_handler
from handlers.levelextras import level_comments_handler, post_comment_handler, rate_level_handler
from handlers.levelextras import level_comments_handler, post_comment_handler, rate_level_handler, level_scores_handler
from helpers.userhelper import user_helper
from helpers.songhelper import songs
from helpers.ratelimit import rate_limiter
Expand Down Expand Up @@ -54,6 +54,7 @@ def config_routes(app: web.Application) -> None:
app.router.add_post("/database/getGJDailyLevel.php", get_daily_handler)
app.router.add_post("/database/getGJMapPacks21.php", get_map_packs_handler)
app.router.add_post("/database/getGJGauntlets21.php", get_gauntlets_handler)
app.router.add_post("/database/getGJLevelScores211.php", level_scores_handler)
#app.add_subapp("/api/", api)
app.add_subapp("/tools/", tools)

Expand Down

0 comments on commit 7382189

Please sign in to comment.