forked from Hay1tsme/artemis
userbox, avatar, mapicon, and voice ui configuration
This commit is contained in:
@ -11,7 +11,7 @@ from core.frontend import FE_Base, UserSession
|
||||
from core.config import CoreConfig
|
||||
from .database import ChuniData
|
||||
from .config import ChuniConfig
|
||||
from .const import ChuniConstants
|
||||
from .const import ChuniConstants, AvatarCategory, ItemKind
|
||||
|
||||
|
||||
def pairwise(iterable):
|
||||
@ -99,6 +99,12 @@ class ChuniFrontend(FE_Base):
|
||||
Route("/{index}", self.render_GET_playlog, methods=['GET']),
|
||||
]),
|
||||
Route("/favorites", self.render_GET_favorites, methods=['GET']),
|
||||
Route("/userbox", self.render_GET_userbox, methods=['GET']),
|
||||
Route("/avatar", self.render_GET_avatar, methods=['GET']),
|
||||
Route("/update.map-icon", self.update_map_icon, methods=['POST']),
|
||||
Route("/update.system-voice", self.update_system_voice, methods=['POST']),
|
||||
Route("/update.userbox", self.update_userbox, methods=['POST']),
|
||||
Route("/update.avatar", self.update_avatar, methods=['POST']),
|
||||
Route("/update.name", self.update_name, methods=['POST']),
|
||||
Route("/update.favorite_music_playlog", self.update_favorite_music_playlog, methods=['POST']),
|
||||
Route("/update.favorite_music_favorites", self.update_favorite_music_favorites, methods=['POST']),
|
||||
@ -123,15 +129,33 @@ class ChuniFrontend(FE_Base):
|
||||
usr_sesh.chunithm_version = versions[0]
|
||||
profile = await self.data.profile.get_profile_data(usr_sesh.user_id, usr_sesh.chunithm_version)
|
||||
|
||||
user_id = usr_sesh.user_id
|
||||
version = usr_sesh.chunithm_version
|
||||
|
||||
# While map icons and system voices weren't present prior to AMAZON, we don't need to bother checking
|
||||
# version here - it'll just end up being empty sets and the jinja will ignore the variables anyway.
|
||||
user_map_icons = await self.data.item.get_items(user_id, ItemKind.MAP_ICON.value)
|
||||
user_map_icons = [icon["itemId"] for icon in user_map_icons] + [profile.mapIconId]
|
||||
user_system_voices = await self.data.item.get_items(user_id, ItemKind.SYSTEM_VOICE.value)
|
||||
user_system_voices = [icon["itemId"] for icon in user_system_voices] + [profile.voiceId]
|
||||
|
||||
map_icons, total_map_icons = await self.get_available_map_icons(version, user_map_icons)
|
||||
system_voices, total_system_voices = await self.get_available_system_voices(version, user_system_voices)
|
||||
|
||||
resp = Response(template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh),
|
||||
user_id=usr_sesh.user_id,
|
||||
user_id=user_id,
|
||||
profile=profile,
|
||||
version_list=ChuniConstants.VERSION_NAMES,
|
||||
versions=versions,
|
||||
cur_version=usr_sesh.chunithm_version
|
||||
cur_version=version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(version),
|
||||
map_icons=map_icons,
|
||||
system_voices=system_voices,
|
||||
total_map_icons=total_map_icons,
|
||||
total_system_voices=total_system_voices
|
||||
), media_type="text/html; charset=utf-8")
|
||||
|
||||
if usr_sesh.chunithm_version >= 0:
|
||||
@ -189,6 +213,8 @@ class ChuniFrontend(FE_Base):
|
||||
profile=profile,
|
||||
hot_list=hot_list,
|
||||
base_list=base_list,
|
||||
cur_version=usr_sesh.chunithm_version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(usr_sesh.chunithm_version)
|
||||
), media_type="text/html; charset=utf-8")
|
||||
else:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
@ -217,7 +243,9 @@ class ChuniFrontend(FE_Base):
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh),
|
||||
playlog_count=0
|
||||
playlog_count=0,
|
||||
cur_version=version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(version)
|
||||
), media_type="text/html; charset=utf-8")
|
||||
playlog = await self.data.score.get_playlogs_limited(user_id, version, index, 20)
|
||||
playlog_with_title = []
|
||||
@ -257,6 +285,7 @@ class ChuniFrontend(FE_Base):
|
||||
user_id=user_id,
|
||||
playlog=playlog_with_title,
|
||||
playlog_count=playlog_count,
|
||||
cur_version=version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(version)
|
||||
), media_type="text/html; charset=utf-8")
|
||||
else:
|
||||
@ -319,11 +348,318 @@ class ChuniFrontend(FE_Base):
|
||||
user_id=user_id,
|
||||
favorites_by_genre=favorites_by_genre,
|
||||
favorites_count=favorites_count,
|
||||
cur_version=version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(version)
|
||||
), media_type="text/html; charset=utf-8")
|
||||
else:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
async def get_available_map_icons(self, version: int, user_unlocked_items: List[int]) -> (List[dict], int):
|
||||
items = dict()
|
||||
rows = await self.data.static.get_map_icons(version)
|
||||
if rows:
|
||||
for row in rows:
|
||||
# Only include items that are either available by default or in the user unlocked list
|
||||
if row["defaultHave"] or row["mapIconId"] in user_unlocked_items:
|
||||
item = dict()
|
||||
item["id"] = row["mapIconId"]
|
||||
item["name"] = row["name"]
|
||||
item["iconPath"] = path.splitext(row["iconPath"])[0] + ".png"
|
||||
items[row["mapIconId"]] = item
|
||||
|
||||
return (items, len(rows))
|
||||
|
||||
async def get_available_system_voices(self, version: int, user_unlocked_items: List[int]) -> (List[dict], int):
|
||||
items = dict()
|
||||
rows = await self.data.static.get_system_voices(version)
|
||||
if rows:
|
||||
for row in rows:
|
||||
# Only include items that are either available by default or in the user unlocked list
|
||||
if row["defaultHave"] or row["voiceId"] in user_unlocked_items:
|
||||
item = dict()
|
||||
item["id"] = row["voiceId"]
|
||||
item["name"] = row["name"]
|
||||
item["imagePath"] = path.splitext(row["imagePath"])[0] + ".png"
|
||||
items[row["voiceId"]] = item
|
||||
|
||||
return (items, len(rows))
|
||||
|
||||
async def get_available_nameplates(self, version: int, user_unlocked_items: List[int]) -> (List[dict], int):
|
||||
items = dict()
|
||||
rows = await self.data.static.get_nameplates(version)
|
||||
if rows:
|
||||
for row in rows:
|
||||
# Only include items that are either available by default or in the user unlocked list
|
||||
if row["defaultHave"] or row["nameplateId"] in user_unlocked_items:
|
||||
item = dict()
|
||||
item["id"] = row["nameplateId"]
|
||||
item["name"] = row["name"]
|
||||
item["texturePath"] = path.splitext(row["texturePath"])[0] + ".png"
|
||||
items[row["nameplateId"]] = item
|
||||
|
||||
return (items, len(rows))
|
||||
|
||||
async def get_available_trophies(self, version: int, user_unlocked_items: List[int]) -> (List[dict], int):
|
||||
items = dict()
|
||||
rows = await self.data.static.get_trophies(version)
|
||||
if rows:
|
||||
for row in rows:
|
||||
# Only include items that are either available by default or in the user unlocked list
|
||||
if row["defaultHave"] or row["trophyId"] in user_unlocked_items:
|
||||
item = dict()
|
||||
item["id"] = row["trophyId"]
|
||||
item["name"] = row["name"]
|
||||
item["rarity"] = row["rareType"]
|
||||
items[row["trophyId"]] = item
|
||||
|
||||
return (items, len(rows))
|
||||
|
||||
async def get_available_characters(self, version: int, user_unlocked_items: List[int]) -> (List[dict], int):
|
||||
items = dict()
|
||||
rows = await self.data.static.get_characters(version)
|
||||
if rows:
|
||||
for row in rows:
|
||||
# Only include items that are either available by default or in the user unlocked list
|
||||
if row["defaultHave"] or row["characterId"] in user_unlocked_items:
|
||||
item = dict()
|
||||
item["id"] = row["characterId"]
|
||||
item["name"] = row["name"]
|
||||
item["iconPath"] = path.splitext(row["imagePath3"])[0] + ".png"
|
||||
items[row["characterId"]] = item
|
||||
|
||||
return (items, len(rows))
|
||||
|
||||
async def get_available_avatar_items(self, version: int, category: AvatarCategory, user_unlocked_items: List[int]) -> (List[dict], int):
|
||||
items = dict()
|
||||
rows = await self.data.static.get_avatar_items(version, category.value)
|
||||
if rows:
|
||||
for row in rows:
|
||||
# Only include items that are either available by default or in the user unlocked list
|
||||
if row["defaultHave"] or row["avatarAccessoryId"] in user_unlocked_items:
|
||||
item = dict()
|
||||
item["id"] = row["avatarAccessoryId"]
|
||||
item["name"] = row["name"]
|
||||
item["iconPath"] = path.splitext(row["iconPath"])[0] + ".png"
|
||||
item["texturePath"] = path.splitext(row["texturePath"])[0] + ".png"
|
||||
items[row["avatarAccessoryId"]] = item
|
||||
|
||||
return (items, len(rows))
|
||||
|
||||
async def render_GET_userbox(self, request: Request) -> bytes:
|
||||
template = self.environment.get_template(
|
||||
"titles/chuni/templates/chuni_userbox.jinja"
|
||||
)
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
usr_sesh = UserSession()
|
||||
|
||||
if usr_sesh.user_id > 0:
|
||||
if usr_sesh.chunithm_version < 0:
|
||||
return RedirectResponse("/game/chuni/", 303)
|
||||
|
||||
user_id = usr_sesh.user_id
|
||||
version = usr_sesh.chunithm_version
|
||||
|
||||
# Get the user profile so we know how the userbox is currently configured
|
||||
profile = await self.data.profile.get_profile_data(user_id, version)
|
||||
# Get all the user unlocked components so we know what to populate as options
|
||||
user_nameplates = await self.data.item.get_items(user_id, ItemKind.NAMEPLATE.value)
|
||||
user_nameplates = [item["itemId"] for item in user_nameplates] + [profile.nameplateId]
|
||||
user_trophies = await self.data.item.get_items(user_id, ItemKind.TROPHY.value)
|
||||
user_trophies = [item["itemId"] for item in user_trophies] + [profile.trophyId]
|
||||
user_characters = await self.data.item.get_characters(user_id)
|
||||
user_characters = [chara["characterId"] for chara in user_characters] + [profile.charaIllustId]
|
||||
|
||||
# Build up available list of components
|
||||
nameplates, total_nameplates = await self.get_available_nameplates(version, user_nameplates)
|
||||
trophies, total_trophies = await self.get_available_trophies(version, user_trophies)
|
||||
characters, total_characters = await self.get_available_characters(version, user_characters)
|
||||
|
||||
# Get the user's team
|
||||
team_name = "ARTEMiS"
|
||||
if profile["teamId"]:
|
||||
team = await self.data.profile.get_team_by_id(profile["teamId"])
|
||||
team_name = team["teamName"]
|
||||
# Figure out the rating color we should use (rank maps to the stylesheet)
|
||||
rating = profile.playerRating / 100;
|
||||
rating_rank = 0
|
||||
if rating >= 16:
|
||||
rating_rank = 8
|
||||
elif rating >= 15.25:
|
||||
rating_rank = 7
|
||||
elif rating >= 14.5:
|
||||
rating_rank = 6
|
||||
elif rating >= 13.25:
|
||||
rating_rank = 5
|
||||
elif rating >= 12:
|
||||
rating_rank = 4
|
||||
elif rating >= 10:
|
||||
rating_rank = 3
|
||||
elif rating >= 7:
|
||||
rating_rank = 2
|
||||
elif rating >= 4:
|
||||
rating_rank = 1
|
||||
|
||||
return Response(template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh),
|
||||
user_id=user_id,
|
||||
cur_version=version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(version),
|
||||
profile=profile,
|
||||
team_name=team_name,
|
||||
rating_rank=rating_rank,
|
||||
nameplates=nameplates,
|
||||
trophies=trophies,
|
||||
characters=characters,
|
||||
total_nameplates=total_nameplates,
|
||||
total_trophies=total_trophies,
|
||||
total_characters=total_characters
|
||||
), media_type="text/html; charset=utf-8")
|
||||
else:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
async def render_GET_avatar(self, request: Request) -> bytes:
|
||||
template = self.environment.get_template(
|
||||
"titles/chuni/templates/chuni_avatar.jinja"
|
||||
)
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
usr_sesh = UserSession()
|
||||
|
||||
if usr_sesh.user_id > 0:
|
||||
if usr_sesh.chunithm_version < 11:
|
||||
# Avatar configuration only for NEW!! and newer
|
||||
return RedirectResponse("/game/chuni/", 303)
|
||||
|
||||
user_id = usr_sesh.user_id
|
||||
version = usr_sesh.chunithm_version
|
||||
|
||||
# Get the user profile so we know what avatar items are currently in use
|
||||
profile = await self.data.profile.get_profile_data(user_id, version)
|
||||
# Get all the user avatar accessories so we know what to populate
|
||||
user_accessories = await self.data.item.get_items(user_id, ItemKind.AVATAR_ACCESSORY.value)
|
||||
user_accessories = [item["itemId"] for item in user_accessories] + \
|
||||
[profile.avatarBack, profile.avatarItem, profile.avatarWear, \
|
||||
profile.avatarFront, profile.avatarSkin, profile.avatarHead, profile.avatarFace]
|
||||
|
||||
# Build up available list of items for each avatar category
|
||||
wears, total_wears = await self.get_available_avatar_items(version, AvatarCategory.WEAR, user_accessories)
|
||||
faces, total_faces = await self.get_available_avatar_items(version, AvatarCategory.FACE, user_accessories)
|
||||
heads, total_heads = await self.get_available_avatar_items(version, AvatarCategory.HEAD, user_accessories)
|
||||
skins, total_skins = await self.get_available_avatar_items(version, AvatarCategory.SKIN, user_accessories)
|
||||
items, total_items = await self.get_available_avatar_items(version, AvatarCategory.ITEM, user_accessories)
|
||||
fronts, total_fronts = await self.get_available_avatar_items(version, AvatarCategory.FRONT, user_accessories)
|
||||
backs, total_backs = await self.get_available_avatar_items(version, AvatarCategory.BACK, user_accessories)
|
||||
|
||||
return Response(template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh),
|
||||
user_id=user_id,
|
||||
cur_version=version,
|
||||
cur_version_name=ChuniConstants.game_ver_to_string(version),
|
||||
profile=profile,
|
||||
wears=wears,
|
||||
faces=faces,
|
||||
heads=heads,
|
||||
skins=skins,
|
||||
items=items,
|
||||
fronts=fronts,
|
||||
backs=backs,
|
||||
total_wears=total_wears,
|
||||
total_faces=total_faces,
|
||||
total_heads=total_heads,
|
||||
total_skins=total_skins,
|
||||
total_items=total_items,
|
||||
total_fronts=total_fronts,
|
||||
total_backs=total_backs
|
||||
), media_type="text/html; charset=utf-8")
|
||||
else:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
async def update_map_icon(self, request: Request) -> bytes:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
form_data = await request.form()
|
||||
new_map_icon: str = form_data.get("id")
|
||||
|
||||
if not new_map_icon:
|
||||
return RedirectResponse("/gate/?e=4", 303)
|
||||
|
||||
if not await self.data.profile.update_map_icon(usr_sesh.user_id, usr_sesh.chunithm_version, new_map_icon):
|
||||
return RedirectResponse("/gate/?e=999", 303)
|
||||
|
||||
return RedirectResponse("/game/chuni/", 303)
|
||||
|
||||
async def update_system_voice(self, request: Request) -> bytes:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
form_data = await request.form()
|
||||
new_system_voice: str = form_data.get("id")
|
||||
|
||||
if not new_system_voice:
|
||||
return RedirectResponse("/gate/?e=4", 303)
|
||||
|
||||
if not await self.data.profile.update_system_voice(usr_sesh.user_id, usr_sesh.chunithm_version, new_system_voice):
|
||||
return RedirectResponse("/gate/?e=999", 303)
|
||||
|
||||
return RedirectResponse("/game/chuni/", 303)
|
||||
|
||||
async def update_userbox(self, request: Request) -> bytes:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
form_data = await request.form()
|
||||
new_nameplate: str = form_data.get("nameplate")
|
||||
new_trophy: str = form_data.get("trophy")
|
||||
new_character: str = form_data.get("character")
|
||||
|
||||
if not new_nameplate or \
|
||||
not new_trophy or \
|
||||
not new_character:
|
||||
return RedirectResponse("/game/chuni/userbox?e=4", 303)
|
||||
|
||||
if not await self.data.profile.update_userbox(usr_sesh.user_id, usr_sesh.chunithm_version, new_nameplate, new_trophy, new_character):
|
||||
return RedirectResponse("/gate/?e=999", 303)
|
||||
|
||||
return RedirectResponse("/game/chuni/userbox", 303)
|
||||
|
||||
async def update_avatar(self, request: Request) -> bytes:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
form_data = await request.form()
|
||||
new_wear: str = form_data.get("wear")
|
||||
new_face: str = form_data.get("face")
|
||||
new_head: str = form_data.get("head")
|
||||
new_skin: str = form_data.get("skin")
|
||||
new_item: str = form_data.get("item")
|
||||
new_front: str = form_data.get("front")
|
||||
new_back: str = form_data.get("back")
|
||||
|
||||
if not new_wear or \
|
||||
not new_face or \
|
||||
not new_head or \
|
||||
not new_skin or \
|
||||
not new_item or \
|
||||
not new_front or \
|
||||
not new_back:
|
||||
return RedirectResponse("/game/chuni/avatar?e=4", 303)
|
||||
|
||||
if not await self.data.profile.update_avatar(usr_sesh.user_id, usr_sesh.chunithm_version, new_wear, new_face, new_head, new_skin, new_item, new_front, new_back):
|
||||
return RedirectResponse("/gate/?e=999", 303)
|
||||
|
||||
return RedirectResponse("/game/chuni/avatar", 303)
|
||||
|
||||
|
||||
async def update_name(self, request: Request) -> bytes:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
|
Reference in New Issue
Block a user