1
0
Fork 0
artemis/titles/wacca/reverse.py

320 lines
12 KiB
Python

from typing import Any, List, Dict
from datetime import datetime, timedelta
import json
from core.config import CoreConfig
from titles.wacca.lilyr import WaccaLilyR
from titles.wacca.config import WaccaConfig
from titles.wacca.const import WaccaConstants
from titles.wacca.handlers import *
class WaccaReverse(WaccaLilyR):
def __init__(self, cfg: CoreConfig, game_cfg: WaccaConfig) -> None:
super().__init__(cfg, game_cfg)
self.version = WaccaConstants.VER_WACCA_REVERSE
self.season = 3
self.OPTIONS_DEFAULTS["set_nav_id"] = 310001
self.allowed_stages = [
(3014, 14),
(3013, 13),
(3012, 12),
(3011, 11),
(3010, 10),
(3009, 9),
(3008, 8),
(3007, 7),
(3006, 6),
(3005, 5),
(3004, 4),
(3003, 3),
(3002, 2),
(3001, 1),
# Touhou
(210001, 0),
(210002, 0),
(210003, 0),
# Final spurt
(310001, 0),
(310002, 0),
(310003, 0),
# boss remix
(310004, 0),
(310005, 0),
(310006, 0),
]
def handle_user_status_login_request(self, data: Dict) -> Dict:
resp = super().handle_user_status_login_request(data)
resp["params"].append([])
return resp
def handle_user_status_getDetail_request(self, data: Dict) -> Dict:
req = UserStatusGetDetailRequest(data)
resp = UserStatusGetDetailResponseV4()
profile = self.data.profile.get_profile(req.userId)
if profile is None:
self.logger.warn(f"Unknown profile {req.userId}")
return resp.make()
self.logger.info(f"Get detail for profile {req.userId}")
user_id = profile["user"]
profile_scores = self.data.score.get_best_scores(user_id)
profile_items = self.data.item.get_items(user_id)
profile_song_unlocks = self.data.item.get_song_unlocks(user_id)
profile_options = self.data.profile.get_options(user_id)
profile_favorites = self.data.profile.get_favorite_songs(user_id)
profile_gates = self.data.profile.get_gates(user_id)
profile_bingo = self.data.profile.get_bingo(user_id)
profile_trophies = self.data.item.get_trophies(user_id)
profile_tickets = self.data.item.get_tickets(user_id)
if profile["gate_tutorial_flags"] is not None:
for x in profile["gate_tutorial_flags"]:
resp.gateTutorialFlags.append(GateTutorialFlag(x[0], x[1]))
if profile["vip_expire_time"] is None:
resp.userStatus.vipExpireTime = 0
else:
resp.userStatus.vipExpireTime = int(profile["vip_expire_time"].timestamp())
if profile["always_vip"] or self.game_config.mods.always_vip:
resp.userStatus.vipExpireTime = int(
(self.srvtime + timedelta(days=31)).timestamp()
)
resp.songUpdateTime = int(profile["last_login_date"].timestamp())
resp.lastSongInfo = LastSongDetail(
profile["last_song_id"],
profile["last_song_difficulty"],
profile["last_folder_order"],
profile["last_folder_id"],
profile["last_song_order"],
)
resp.songPlayStatus = [resp.lastSongInfo.lastSongId, 1]
resp.userStatus.userId = profile["id"]
resp.userStatus.username = profile["username"]
resp.userStatus.xp = profile["xp"]
resp.userStatus.danLevel = profile["dan_level"]
resp.userStatus.danType = profile["dan_type"]
resp.userStatus.wp = profile["wp"]
resp.userStatus.useCount = profile["login_count"]
resp.userStatus.loginDays = profile["login_count_days"]
resp.userStatus.loginConsecutiveDays = profile["login_count_days_consec"]
resp.userStatus.loginsToday = profile["login_count_today"]
resp.userStatus.rating = profile["rating"]
if self.game_config.mods.infinite_wp:
resp.userStatus.wp = 999999
for fav in profile_favorites:
resp.favorites.append(fav["song_id"])
if profile["friend_view_1"] is not None:
pass
if profile["friend_view_2"] is not None:
pass
if profile["friend_view_3"] is not None:
pass
resp.seasonalPlayModeCounts.append(
PlayModeCounts(self.season, 1, profile["playcount_single"])
)
resp.seasonalPlayModeCounts.append(
PlayModeCounts(self.season, 2, profile["playcount_multi_vs"])
)
resp.seasonalPlayModeCounts.append(
PlayModeCounts(self.season, 3, profile["playcount_multi_coop"])
)
resp.seasonalPlayModeCounts.append(
PlayModeCounts(self.season, 4, profile["playcount_stageup"])
)
resp.seasonalPlayModeCounts.append(
PlayModeCounts(self.season, 5, profile["playcount_time_free"])
)
# For some fucking reason if this isn't here time play is disabled
resp.seasonalPlayModeCounts.append(PlayModeCounts(0, 1, 1))
for opt in profile_options:
resp.options.append(UserOption(opt["opt_id"], opt["value"]))
if profile_bingo is not None:
resp.bingoStatus = BingoDetail(profile_bingo["page_number"])
for x in profile_bingo["page_progress"]:
resp.bingoStatus.pageStatus.append(BingoPageStatus(x[0], x[1], x[2]))
for gate in self.game_config.gates.enabled_gates:
added_gate = False
for user_gate in profile_gates:
if user_gate["gate_id"] == gate:
resp.gateInfo.append(
GateDetailV2(
user_gate["gate_id"],
user_gate["page"],
user_gate["progress"],
user_gate["loops"],
int(user_gate["last_used"].timestamp()),
user_gate["mission_flag"],
)
)
resp.seasonInfo.cumulativeGatePts += user_gate["total_points"]
added_gate = True
break
if not added_gate:
resp.gateInfo.append(GateDetailV2(gate))
for unlock in profile_song_unlocks:
for x in range(1, unlock["highest_difficulty"] + 1):
resp.userItems.songUnlocks.append(
SongUnlock(
unlock["song_id"], x, 0, int(unlock["acquire_date"].timestamp())
)
)
for song in profile_scores:
resp.seasonInfo.cumulativeScore += song["score"]
clear_cts = SongDetailClearCounts(
song["play_ct"],
song["clear_ct"],
song["missless_ct"],
song["fullcombo_ct"],
song["allmarv_ct"],
)
grade_cts = SongDetailGradeCountsV2(
song["grade_d_ct"],
song["grade_c_ct"],
song["grade_b_ct"],
song["grade_a_ct"],
song["grade_aa_ct"],
song["grade_aaa_ct"],
song["grade_s_ct"],
song["grade_ss_ct"],
song["grade_sss_ct"],
song["grade_master_ct"],
song["grade_sp_ct"],
song["grade_ssp_ct"],
song["grade_sssp_ct"],
)
deets = BestScoreDetailV2(song["song_id"], song["chart_id"])
deets.clearCounts = clear_cts
deets.clearCountsSeason = clear_cts
deets.gradeCounts = grade_cts
deets.score = song["score"]
deets.bestCombo = song["best_combo"]
deets.lowestMissCtMaybe = song["lowest_miss_ct"]
deets.rating = song["rating"]
resp.scores.append(deets)
for trophy in profile_trophies:
resp.userItems.trophies.append(
TrophyItem(
trophy["trophy_id"],
trophy["season"],
trophy["progress"],
trophy["badge_type"],
)
)
if self.game_config.mods.infinite_tickets:
for x in range(5):
resp.userItems.tickets.append(TicketItem(x, 106002, 0))
else:
for ticket in profile_tickets:
if ticket["expire_date"] is None:
expire = int((self.srvtime + timedelta(days=30)).timestamp())
else:
expire = int(ticket["expire_date"].timestamp())
resp.userItems.tickets.append(
TicketItem(ticket["id"], ticket["ticket_id"], expire)
)
if profile_items:
for item in profile_items:
try:
if item["type"] == WaccaConstants.ITEM_TYPES["icon"]:
resp.userItems.icons.append(
IconItem(
item["item_id"],
1,
item["use_count"],
int(item["acquire_date"].timestamp()),
)
)
elif item["type"] == WaccaConstants.ITEM_TYPES["navigator"]:
resp.userItems.navigators.append(
NavigatorItem(
item["item_id"],
1,
int(item["acquire_date"].timestamp()),
item["use_count"],
item["use_count"],
)
)
else:
itm_send = GenericItemSend(
item["item_id"], 1, int(item["acquire_date"].timestamp())
)
if item["type"] == WaccaConstants.ITEM_TYPES["title"]:
resp.userItems.titles.append(itm_send)
elif item["type"] == WaccaConstants.ITEM_TYPES["user_plate"]:
resp.userItems.plates.append(itm_send)
elif item["type"] == WaccaConstants.ITEM_TYPES["touch_effect"]:
resp.userItems.touchEffect.append(itm_send)
elif item["type"] == WaccaConstants.ITEM_TYPES["note_color"]:
resp.userItems.noteColors.append(itm_send)
elif item["type"] == WaccaConstants.ITEM_TYPES["note_sound"]:
resp.userItems.noteSounds.append(itm_send)
except:
self.logger.error(
f"{__name__} Failed to load item {item['item_id']} for user {profile['user']}"
)
resp.seasonInfo.level = profile["xp"]
resp.seasonInfo.wpObtained = profile["wp_total"]
resp.seasonInfo.wpSpent = profile["wp_spent"]
resp.seasonInfo.titlesObtained = len(resp.userItems.titles)
resp.seasonInfo.iconsObtained = len(resp.userItems.icons)
resp.seasonInfo.noteColorsObtained = len(resp.userItems.noteColors)
resp.seasonInfo.noteSoundsObtained = len(resp.userItems.noteSounds)
resp.seasonInfo.platesObtained = len(resp.userItems.plates)
return resp.make()
def handle_user_status_create_request(self, data: Dict) -> Dict:
req = UserStatusCreateRequest(data)
resp = super().handle_user_status_create_request(data)
self.data.item.put_item(
req.aimeId, WaccaConstants.ITEM_TYPES["navigator"], 310001
) # Added reverse
self.data.item.put_item(
req.aimeId, WaccaConstants.ITEM_TYPES["navigator"], 310002
) # Added reverse
return resp