This repository has been archived on 2022-02-23. You can view files and clone it, but cannot push or open issues or pull requests.
lets/secret/achievements/utils.py

115 lines
4.1 KiB
Python

from objects import glob
from common.ripple import userUtils
from os.path import dirname, basename, isfile
import glob as _glob
import importlib
import json
from secret.achievements import common
def load_achievements():
"""Load all the achievements from handler list into glob.achievementClasses,
and sets glob.ACHIEVEMENTS_VERSION to the highest version number in our achievement list.
"""
modules = _glob.glob("secret/achievements/handlers/*.py")
modules = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith("__init__.py")]
# ^ cat face
for module in modules:
module = importlib.import_module("secret.achievements.handlers." + module)
module.load()
if module.ORDER in glob.achievementClasses:
print("\n!!! FOUND OVERLAPPING ACHIEVEMENT ORDER FOR {}!!!".format(module.ORDER))
print("Unable to load {} due to {} already loaded in slot {}\n".format(module.__name__, glob.achievementClasses[module.ORDER].__name__, module.ORDER))
continue
glob.achievementClasses[module.ORDER] = module
glob.ACHIEVEMENTS_VERSION = max(glob.ACHIEVEMENTS_VERSION, module.VERSION)
print("Loaded {} achievement classes!".format(len(glob.achievementClasses)), end=" ")
def unlock_achievements_update(userID, version):
"""Scans the user for past achievements they should have unlocked
Arguments:
userID {int} -- User id of a player
version {int} -- Last achivement version the player had
Returns:
Array -- List of achievements
"""
achievements = []
# Scan all past achivement versions from the user's achivement version to the latest
index = 1
for handler in glob.achievementClasses.values():
if handler.VERSION > version:
achievements += [x + index for x in handler.update(userID)]
index += handler.LENGTH
# Update achivement version for user
userUtils.updateAchievementsVersion(userID)
return achievements
def unlock_achievements(score, beatmap, user_data):
"""Return array of achievements the current play recived
Arguments:
score {Score} -- Score data recived from replay
beatmap {Beatmap} -- Played beatmap
user_data {dict} -- Info about the current player
Returns:
Array -- List of achievements for the current play
"""
achievements = []
userID = userUtils.getID(score.playerName)
user_cache = common.get_usercache(userID)
# Get current gamemode and change value std to osu
gamemode_index = score.gameMode
# Check if user should run achivement recheck
if user_cache["version"] < glob.ACHIEVEMENTS_VERSION:
achievements += unlock_achievements_update(userID, user_cache["version"])
# Check if gameplay should get new achivement
index = 1
for handler in glob.achievementClasses.values():
achievements += [x + index for x in handler.handle(gamemode_index, score, beatmap, user_data)]
index += handler.LENGTH
# Add pending achievements that were added though redis or mysql
achievements += [-x for x in user_cache["achievements"] if x < 0] # Negative achievements id's means its pending
# Remove pending achievements from redis object since we added it to the post achievements
user_cache["achievements"] = [x for x in user_cache["achievements"] if x > 0]
# Remove duplicated achievements (incase of unlock_achievements_update adding stuff)
achievements = list(set(achievements))
# Remove already achived achievements from list
achievements = [x for x in achievements if x not in user_cache["achievements"]]
user_cache["achievements"] += achievements
glob.redis.set("lets:user_achievement_cache:{}".format(userID), json.dumps(user_cache), 1800)
for achievement in achievements:
userUtils.unlockAchievement(userID, achievement)
return achievements
def achievements_response(achievements):
achievement_objects = []
index = 1
for handler in glob.achievementClasses.values():
achievement_objects += [handler.ACHIEVEMENTS[x - index] for x in achievements if len(handler.ACHIEVEMENTS) > x - index and x - index >= 0]
index += handler.LENGTH
achievements_packed = []
for achievement_object in achievement_objects:
achievements_packed.append("+".join([achievement_object["icon"], achievement_object["name"], achievement_object["description"]]))
return "/".join(achievements_packed)