1
0
mirror of synced 2024-12-01 00:57:16 +01:00

Move wacca from megaime develop branch, should at least partially fix #3 #4 and #5

This commit is contained in:
Hay1tsme 2023-02-22 22:22:03 -05:00
parent 026fcc5182
commit c3aac4c38e
13 changed files with 309 additions and 341 deletions

View File

@ -78,8 +78,12 @@ class WaccaBase():
resp = HousingGetResponse(housing_id)
return resp.make()
def handle_advertise_GetRanking_request(self, data: Dict) -> Dict:
req = AdvertiseGetRankingRequest(data)
return AdvertiseGetRankingResponse().make()
def handle_housing_start_request(self, data: Dict) -> Dict:
req = HousingStartRequest(data)
req = HousingStartRequestV1(data)
resp = HousingStartResponseV1(
1,
@ -103,7 +107,69 @@ class WaccaBase():
self.logger.info(f"Log out user {req.userId} from {req.chipId}")
return BaseResponse().make()
def handle_user_status_login_request(self, data: Dict) -> List[Any]:
def handle_user_status_get_request(self, data: Dict)-> Dict:
req = UserStatusGetRequest(data)
resp = UserStatusGetV1Response()
ver_split = req.appVersion.split(".")
profile = self.data.profile.get_profile(aime_id=req.aimeId)
if profile is None:
self.logger.info(f"No user exists for aime id {req.aimeId}")
resp.profileStatus = ProfileStatus.ProfileRegister
return resp.make()
self.logger.info(f"User preview for {req.aimeId} from {req.chipId}")
if profile["last_game_ver"] is None:
profile_ver_split = ver_split
resp.lastGameVersion = req.appVersion
else:
profile_ver_split = profile["last_game_ver"].split(".")
resp.lastGameVersion = profile["last_game_ver"]
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"]
set_title_id = self.data.profile.get_options(WaccaConstants.OPTIONS["set_title_id"], profile["user"])
if set_title_id is None:
set_title_id = self.OPTIONS_DEFAULTS["set_title_id"]
resp.setTitleId = set_title_id
set_icon_id = self.data.profile.get_options(WaccaConstants.OPTIONS["set_title_id"], profile["user"])
if set_icon_id is None:
set_icon_id = self.OPTIONS_DEFAULTS["set_icon_id"]
resp.setIconId = set_icon_id
if int(ver_split[0]) > int(profile_ver_split[0]):
resp.versionStatus = PlayVersionStatus.VersionUpgrade
elif int(ver_split[0]) < int(profile_ver_split[0]):
resp.versionStatus = PlayVersionStatus.VersionTooNew
else:
if int(ver_split[1]) > int(profile_ver_split[1]):
resp.versionStatus = PlayVersionStatus.VersionUpgrade
elif int(ver_split[1]) < int(profile_ver_split[1]):
resp.versionStatus = PlayVersionStatus.VersionTooNew
else:
if int(ver_split[2]) > int(profile_ver_split[2]):
resp.versionStatus = PlayVersionStatus.VersionUpgrade
elif int(ver_split[2]) < int(profile_ver_split[2]):
resp.versionStatus = PlayVersionStatus.VersionTooNew
return resp.make()
def handle_user_status_login_request(self, data: Dict)-> Dict:
req = UserStatusLoginRequest(data)
resp = UserStatusLoginResponseV1()
is_new_day = False
@ -140,119 +206,7 @@ class WaccaBase():
return resp.make()
def handle_user_status_get_request(self, data: Dict) -> List[Any]:
req = UserStatusGetRequest(data)
resp = UserStatusGetV1Response()
ver_split = req.appVersion.split(".")
profile = self.data.profile.get_profile(aime_id=req.aimeId)
if profile is None:
self.logger.info(f"No user exists for aime id {req.aimeId}")
return resp.make()
self.logger.info(f"User preview for {req.aimeId} from {req.chipId}")
if profile["last_game_ver"] is None:
profile_ver_split = ver_split
resp.lastGameVersion = req.appVersion
else:
profile_ver_split = profile["last_game_ver"].split(".")
resp.lastGameVersion = profile["last_game_ver"]
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"]
set_title_id = self.data.profile.get_options(WaccaConstants.OPTIONS["set_title_id"], profile["user"])
if set_title_id is None:
set_title_id = self.OPTIONS_DEFAULTS["set_title_id"]
resp.setTitleId = set_title_id
set_icon_id = self.data.profile.get_options(WaccaConstants.OPTIONS["set_title_id"], profile["user"])
if set_icon_id is None:
set_icon_id = self.OPTIONS_DEFAULTS["set_icon_id"]
resp.setIconId = set_icon_id
if profile["last_login_date"].timestamp() < int((datetime.now().replace(hour=0,minute=0,second=0,microsecond=0) - timedelta(days=1)).timestamp()):
resp.userStatus.loginConsecutiveDays = 0
if int(ver_split[0]) > int(profile_ver_split[0]):
resp.versionStatus = PlayVersionStatus.VersionUpgrade
elif int(ver_split[0]) < int(profile_ver_split[0]):
resp.versionStatus = PlayVersionStatus.VersionTooNew
else:
if int(ver_split[1]) > int(profile_ver_split[1]):
resp.versionStatus = PlayVersionStatus.VersionUpgrade
elif int(ver_split[1]) < int(profile_ver_split[1]):
resp.versionStatus = PlayVersionStatus.VersionTooNew
else:
if int(ver_split[2]) > int(profile_ver_split[2]):
resp.versionStatus = PlayVersionStatus.VersionUpgrade
elif int(ver_split[2]) < int(profile_ver_split[2]):
resp.versionStatus = PlayVersionStatus.VersionTooNew
if profile["always_vip"]:
resp.userStatus.vipExpireTime = int((datetime.now() + timedelta(days=30)).timestamp())
elif profile["vip_expire_time"] is not None:
resp.userStatus.vipExpireTime = int(profile["vip_expire_time"].timestamp())
return resp.make()
def handle_user_status_login_request(self, data: Dict) -> List[Any]:
req = UserStatusLoginRequest(data)
resp = UserStatusLoginResponseV2()
is_new_day = False
is_consec_day = False
is_consec_day = True
if req.userId == 0:
self.logger.info(f"Guest login on {req.chipId}")
resp.lastLoginDate = 0
else:
profile = self.data.profile.get_profile(req.userId)
if profile is None:
self.logger.warn(f"Unknown user id {req.userId} attempted login from {req.chipId}")
return resp.make()
self.logger.info(f"User {req.userId} login on {req.chipId}")
last_login_time = int(profile["last_login_date"].timestamp())
resp.lastLoginDate = last_login_time
# If somebodies login timestamp < midnight of current day, then they are logging in for the first time today
if last_login_time < int(datetime.now().replace(hour=0,minute=0,second=0,microsecond=0).timestamp()):
is_new_day = True
is_consec_day = True
# If somebodies login timestamp > midnight of current day + 1 day, then they broke their daily login streak
elif last_login_time > int((datetime.now().replace(hour=0,minute=0,second=0,microsecond=0) + timedelta(days=1)).timestamp()):
is_consec_day = False
# else, they are simply logging in again on the same day, and we don't need to do anything for that
self.data.profile.session_login(req.userId, is_new_day, is_consec_day)
resp.vipInfo.pageYear = datetime.now().year
resp.vipInfo.pageMonth = datetime.now().month
resp.vipInfo.pageDay = datetime.now().day
resp.vipInfo.numItem = 1
resp.firstLoginDaily = int(is_new_day)
return resp.make()
def handle_user_status_create_request(self, data: Dict) -> List[Any]:
def handle_user_status_create_request(self, data: Dict)-> Dict:
req = UserStatusCreateRequest(data)
profileId = self.data.profile.create_profile(req.aimeId, req.username, self.version)
@ -284,7 +238,7 @@ class WaccaBase():
return UserStatusCreateResponseV2(profileId, req.username).make()
def handle_user_status_getDetail_request(self, data: Dict) -> List[Any]:
def handle_user_status_getDetail_request(self, data: Dict)-> Dict:
req = UserStatusGetDetailRequest(data)
resp = UserStatusGetDetailResponseV1()
@ -303,15 +257,6 @@ class WaccaBase():
profile_trophies = self.data.item.get_trophies(user_id)
profile_tickets = self.data.item.get_tickets(user_id)
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.songPlayStatus = [profile["last_song_id"], 1]
@ -322,8 +267,6 @@ class WaccaBase():
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"]
if self.game_config.mods.infinite_wp:
resp.userStatus.wp = 999999
@ -346,13 +289,9 @@ class WaccaBase():
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())))
if x > 2:
resp.scores.append(BestScoreDetailV1(unlock["song_id"], x))
empty_scores = len(resp.scores)
for song in profile_scores:
resp.seasonInfo.cumulativeScore += song["score"]
empty_score_idx = resp.find_score_idx(song["song_id"], song["chart_id"], 0, empty_scores)
clear_cts = SongDetailClearCounts(
song["play_ct"],
@ -368,16 +307,6 @@ class WaccaBase():
song["grade_master_ct"]
)
if empty_score_idx is not None:
resp.scores[empty_score_idx].clearCounts = clear_cts
resp.scores[empty_score_idx].clearCountsSeason = clear_cts
resp.scores[empty_score_idx].gradeCounts = grade_cts
resp.scores[empty_score_idx].score = song["score"]
resp.scores[empty_score_idx].bestCombo = song["best_combo"]
resp.scores[empty_score_idx].lowestMissCtMaybe = song["lowest_miss_ct"]
resp.scores[empty_score_idx].rating = song["rating"]
else:
deets = BestScoreDetailV1(song["song_id"], song["chart_id"])
deets.clearCounts = clear_cts
deets.clearCountsSeason = clear_cts
@ -387,6 +316,8 @@ class WaccaBase():
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"]))
@ -434,7 +365,7 @@ class WaccaBase():
return resp.make()
def handle_user_trial_get_request(self, data: Dict) -> List[Any]:
def handle_user_trial_get_request(self, data: Dict)-> Dict:
req = UserTrialGetRequest(data)
resp = UserTrialGetResponse()
@ -445,10 +376,6 @@ class WaccaBase():
self.logger.info(f"Get trial info for user {req.profileId}")
for d in self.allowed_stages:
if d[1] > 0 and d[1] < 10:
resp.stageList.append(StageInfo(d[0], d[1]))
stages = self.data.score.get_stageup(user_id, self.version)
if stages is None:
stages = []
@ -474,7 +401,7 @@ class WaccaBase():
return resp.make()
def handle_user_trial_update_request(self, data: Dict) -> List[Any]:
def handle_user_trial_update_request(self, data: Dict)-> Dict:
req = UserTrialUpdateRequest(data)
total_score = 0
@ -496,8 +423,8 @@ class WaccaBase():
# We only care about total score for best of, even if one score happens to be lower (I think)
if total_score > (old_stage["song1_score"] + old_stage["song2_score"] + old_stage["song3_score"]):
best_score1 = req.songScores[0]
best_score2 = req.songScores[2]
best_score3 = req.songScores[3]
best_score2 = req.songScores[1]
best_score3 = req.songScores[2]
else:
best_score1 = old_stage["song1_score"]
best_score2 = old_stage["song2_score"]
@ -528,9 +455,9 @@ class WaccaBase():
self.data.item.put_item(user_id, WaccaConstants.ITEM_TYPES["icon"], current_icon)
self.data.item.put_item(user_id, WaccaConstants.ITEM_TYPES["navigator"], current_nav)
self.data.profile.update_profile_playtype(req.profileId, 4, data["appVersion"][:7])
return BaseResponse.make()
return BaseResponse().make()
def handle_user_sugoroku_update_request(self, data: Dict) -> List[Any]:
def handle_user_sugoroku_update_request(self, data: Dict)-> Dict:
ver_split = data["appVersion"].split(".")
resp = BaseResponse()
@ -552,10 +479,10 @@ class WaccaBase():
self.data.profile.update_gate(user_id, req.gateId, req.page, req.progress, req.loops, mission_flg, req.totalPts)
return resp.make()
def handle_user_info_getMyroom_request(self, data: Dict) -> List[Any]:
return UserInfogetMyroomResponse().make()
def handle_user_info_getMyroom_request(self, data: Dict)-> Dict:
return UserInfogetMyroomResponseV1().make()
def handle_user_music_unlock_request(self, data: Dict) -> List[Any]:
def handle_user_music_unlock_request(self, data: Dict)-> Dict:
req = UserMusicUnlockRequest(data)
profile = self.data.profile.get_profile(req.profileId)
@ -605,29 +532,35 @@ class WaccaBase():
return UserMusicUnlockResponse(current_wp, new_tickets).make()
def handle_user_info_getRanking_request(self, data: Dict) -> List[Any]:
def handle_user_info_getRanking_request(self, data: Dict)-> Dict:
# total score, high score by song, cumulative socre, stage up score, other score, WP ranking
# This likely requies calculating standings at regular intervals and caching the results
return UserInfogetRankingResponse().make()
def handle_user_music_update_request(self, data: Dict) -> List[Any]:
req = UserMusicUpdateRequest(data)
ver_split = req.appVersion.split(".")
def handle_user_music_update_request(self, data: Dict)-> Dict:
ver_split = data["appVersion"].split(".")
if int(ver_split[0]) >= 3:
resp = UserMusicUpdateResponseV3()
req = UserMusicUpdateRequestV2(data)
elif int(ver_split[0]) >= 2:
resp = UserMusicUpdateResponseV2()
req = UserMusicUpdateRequestV2(data)
else:
resp = UserMusicUpdateResponseV1()
req = UserMusicUpdateRequestV1(data)
resp.songDetail.songId = req.songDetail.songId
resp.songDetail.difficulty = req.songDetail.difficulty
if req.profileId == 0:
self.logger.info(f"Guest score for song {req.songDetail.songId} difficulty {req.songDetail.difficulty}")
return resp.make()
profile = self.data.profile.get_profile(req.profileId)
if profile is None:
self.logger.warn(f"handle_user_music_update_request: No profile for game_id {req.profileId}")
return BaseResponse().make()
return resp.make()
user_id = profile["user"]
self.util_put_items(req.profileId, user_id, req.itemsObtained)
@ -715,18 +648,18 @@ class WaccaBase():
return resp.make()
#TODO: Coop and vs data
def handle_user_music_updateCoop_request(self, data: Dict) -> List[Any]:
def handle_user_music_updateCoop_request(self, data: Dict)-> Dict:
coop_info = data["params"][4]
return self.handle_user_music_update_request(data)
def handle_user_music_updateVersus_request(self, data: Dict) -> List[Any]:
def handle_user_music_updateVersus_request(self, data: Dict)-> Dict:
vs_info = data["params"][4]
return self.handle_user_music_update_request(data)
def handle_user_music_updateTrial_request(self, data: Dict) -> List[Any]:
def handle_user_music_updateTrial_request(self, data: Dict)-> Dict:
return self.handle_user_music_update_request(data)
def handle_user_mission_update_request(self, data: Dict) -> List[Any]:
def handle_user_mission_update_request(self, data: Dict)-> Dict:
req = UserMissionUpdateRequest(data)
page_status = req.params[1][1]
@ -742,7 +675,7 @@ class WaccaBase():
return BaseResponse().make()
def handle_user_goods_purchase_request(self, data: Dict) -> List[Any]:
def handle_user_goods_purchase_request(self, data: Dict)-> Dict:
req = UserGoodsPurchaseRequest(data)
resp = UserGoodsPurchaseResponse()
@ -775,13 +708,13 @@ class WaccaBase():
return resp.make()
def handle_competition_status_login_request(self, data: Dict) -> List[Any]:
def handle_competition_status_login_request(self, data: Dict)-> Dict:
return BaseResponse().make()
def handle_competition_status_update_request(self, data: Dict) -> List[Any]:
def handle_competition_status_update_request(self, data: Dict)-> Dict:
return BaseResponse().make()
def handle_user_rating_update_request(self, data: Dict) -> List[Any]:
def handle_user_rating_update_request(self, data: Dict)-> Dict:
req = UserRatingUpdateRequest(data)
user_id = self.data.profile.profile_to_aime_user(req.profileId)
@ -797,8 +730,8 @@ class WaccaBase():
return BaseResponse().make()
def handle_user_status_update_request(self, data: Dict) -> List[Any]:
req = UserStatusUpdateRequestV2(data)
def handle_user_status_update_request(self, data: Dict)-> Dict:
req = UserStatusUpdateRequestV1(data)
user_id = self.data.profile.profile_to_aime_user(req.profileId)
if user_id is None:
@ -807,8 +740,6 @@ class WaccaBase():
self.util_put_items(req.profileId, user_id, req.itemsRecieved)
self.data.profile.update_profile_playtype(req.profileId, req.playType.value, data["appVersion"][:7])
self.data.profile.update_profile_lastplayed(req.profileId, req.lastSongInfo.lastSongId, req.lastSongInfo.lastSongDiff,
req.lastSongInfo.lastFolderOrd, req.lastSongInfo.lastFolderId, req.lastSongInfo.lastSongOrd)
current_icon = self.data.profile.get_options(user_id, WaccaConstants.OPTIONS["set_icon_id"])
current_nav = self.data.profile.get_options(user_id, WaccaConstants.OPTIONS["set_nav_id"])
@ -826,7 +757,7 @@ class WaccaBase():
self.data.item.put_item(user_id, WaccaConstants.ITEM_TYPES["navigator"], current_nav)
return BaseResponse().make()
def handle_user_info_update_request(self, data: Dict) -> List[Any]:
def handle_user_info_update_request(self, data: Dict)-> Dict:
req = UserInfoUpdateRequest(data)
user_id = self.data.profile.profile_to_aime_user(req.profileId)
@ -845,7 +776,7 @@ class WaccaBase():
return BaseResponse().make()
def handle_user_vip_get_request(self, data: Dict) -> List[Any]:
def handle_user_vip_get_request(self, data: Dict)-> Dict:
req = UserVipGetRequest(data)
resp = UserVipGetResponse()
@ -868,7 +799,7 @@ class WaccaBase():
return resp.make()
def handle_user_vip_start_request(self, data: Dict) -> List[Any]:
def handle_user_vip_start_request(self, data: Dict)-> Dict:
req = UserVipStartRequest(data)
profile = self.data.profile.get_profile(req.profileId)

View File

@ -1,6 +1,6 @@
from typing import List, Dict
from titles.wacca.handlers.base import BaseResponse
from titles.wacca.handlers.base import BaseResponse, BaseRequest
from titles.wacca.handlers.helpers import Notice
# ---advertise/GetNews---
@ -33,13 +33,33 @@ class GetNewsResponseV1(BaseResponse):
class GetNewsResponseV2(GetNewsResponseV1):
stoppedProducts: list[int] = []
def make(self) -> Dict:
super().make()
self.params.append(self.stoppedProducts)
return super(GetNewsResponseV1, self).make()
class GetNewsResponseV3(GetNewsResponseV2):
stoppedNavs: list[int] = []
stoppedNavVoices: list[int] = []
def make(self) -> Dict:
super().make()
self.params.append(self.stoppedProducts)
self.params.append(self.stoppedNavs)
self.params.append(self.stoppedNavVoices)
return super(GetNewsResponseV1, self).make()
# ---advertise/GetRanking---
class AdvertiseGetRankingRequest(BaseRequest):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.resourceVer: int = self.params[0]
class AdvertiseGetRankingResponse(BaseResponse):
def __init__(self) -> None:
super().__init__()
def make(self) -> Dict:
return super().make()

View File

@ -1,4 +1,4 @@
from typing import List, Dict, Any
from typing import List, Optional, Any
from enum import Enum
from titles.wacca.const import WaccaConstants
@ -41,9 +41,6 @@ class Notice():
int(self.showWelcomeScreen), self.startTime, self.endTime, self.voiceline]
class UserOption():
opt_id: int
opt_val: Any
def __init__(self, opt_id: int = 0, opt_val: Any = 0) -> None:
self.opt_id = opt_id
self.opt_val = opt_val
@ -53,7 +50,7 @@ class UserOption():
class UserStatusV1():
def __init__(self) -> None:
self.userId: int = -1
self.userId: int = 0
self.username: str = ""
self.userType: int = 1
self.xp: int = 0
@ -62,10 +59,6 @@ class UserStatusV1():
self.wp: int = 0
self.titlePartIds: List[int] = [0, 0, 0]
self.useCount: int = 0
self.loginDays: int = 0
self.loginConsecutive: int = 0
self.loginConsecutiveDays: int = 0
self.vipExpireTime: int = 0
def make(self) -> List:
return [
@ -78,21 +71,25 @@ class UserStatusV1():
self.wp,
self.titlePartIds,
self.useCount,
self.loginDays,
self.loginConsecutive,
self.loginConsecutiveDays,
self.vipExpireTime
]
class UserStatusV2(UserStatusV1):
def __init__(self) -> None:
super().__init__()
self.loginDays: int = 0
self.loginConsecutive: int = 0
self.loginConsecutiveDays: int = 0
self.loginsToday: int = 0
self.rating: int = 0
self.vipExpireTime: int = 0
def make(self) -> List:
ret = super().make()
ret.append(self.loginDays)
ret.append(self.loginConsecutive)
ret.append(self.loginConsecutiveDays)
ret.append(self.vipExpireTime)
ret.append(self.loginsToday)
ret.append(self.rating)
@ -336,7 +333,7 @@ class UserItemInfoV3(UserItemInfoV2):
class SongDetailClearCounts():
def __init__(self, play_ct: int = 0, clear_ct: int = 0, ml_ct: int = 0, fc_ct: int = 0,
am_ct: int = 0, counts: List[int] = None) -> None:
am_ct: int = 0, counts: Optional[List[int]] = None) -> None:
if counts is None:
self.playCt = play_ct
self.clearCt = clear_ct
@ -367,7 +364,7 @@ class SongDetailGradeCountsV1():
masterCt: int
def __init__(self, d: int = 0, c: int = 0, b: int = 0, a: int = 0, aa: int = 0, aaa: int = 0, s: int = 0,
ss: int = 0, sss: int = 0, master: int = 0, counts: List[int] = None) -> None:
ss: int = 0, sss: int = 0, master: int = 0, counts: Optional[List[int]] = None) -> None:
if counts is None:
self.dCt = d
self.cCt = c
@ -401,7 +398,7 @@ class SongDetailGradeCountsV2(SongDetailGradeCountsV1):
ssspCt: int
def __init__(self, d: int = 0, c: int = 0, b: int = 0, a: int = 0, aa: int = 0, aaa: int = 0, s: int = 0,
ss: int = 0, sss: int = 0, master: int = 0, sp: int = 0, ssp: int = 0, sssp: int = 0, counts: List[int] = None, ) -> None:
ss: int = 0, sss: int = 0, master: int = 0, sp: int = 0, ssp: int = 0, sssp: int = 0, counts: Optional[List[int]] = None) -> None:
super().__init__(d, c, b, a, aa, aaa, s, ss, sss, master, counts)
if counts is None:
self.spCt = sp
@ -464,25 +461,8 @@ class SongUpdateJudgementCounts():
def make(self) -> List:
return [self.marvCt, self.greatCt, self.goodCt, self.missCt]
class SongUpdateDetail():
songId: int
difficulty: int
level: float
score: int
judgements: SongUpdateJudgementCounts
maxCombo: int
grade: WaccaConstants.GRADES
flagCleared: bool
flagMissless: bool
flagFullcombo: bool
flagAllMarvelous: bool
flagGiveUp: bool
skillPt: int
fastCt: int
slowCt: int
flagNewRecord: bool
def __init__(self, data: List = None) -> None:
class SongUpdateDetailV1():
def __init__(self, data: List) -> None:
if data is not None:
self.songId = data[0]
self.difficulty = data[1]
@ -498,8 +478,15 @@ class SongUpdateDetail():
self.flagFullcombo = False if data[9] == 0 else True
self.flagAllMarvelous = False if data[10] == 0 else True
self.flagGiveUp = False if data[11] == 0 else True
self.skillPt = data[12]
self.fastCt = 0
self.slowCt = 0
self.flagNewRecord = False
class SongUpdateDetailV2(SongUpdateDetailV1):
def __init__(self, data: List) -> None:
super().__init__(data)
if data is not None:
self.fastCt = data[13]
self.slowCt = data[14]
self.flagNewRecord = False if data[15] == 0 else True
@ -583,7 +570,7 @@ class GateDetailV2(GateDetailV1):
return super().make() + [self.missionFlg]
class GachaInfo():
def make() -> List:
def make(self) -> List:
return []
class LastSongDetail():
@ -609,17 +596,6 @@ class FriendDetail():
def make(self) -> List:
return []
class UserOption():
id = 1
val = 1
def __init__(self, id: int = 1, val: int = val) -> None:
self.id = id
self.val = val
def make(self) -> List:
return [self.id, self.val]
class LoginBonusInfo():
def __init__(self) -> None:
self.tickets: List[TicketItem] = []
@ -682,19 +658,6 @@ class PlayType(Enum):
PlayTypeCoop = 3
PlayTypeStageup = 4
class SongRatingUpdate():
song_id = 0
difficulty = 0
rating = 0
def __init__(self, song: int = 0, difficulty: int = 0, rating: int = 0) -> None:
self.song_id = song
self.difficulty = difficulty
self.rating = rating
def make(self) -> List:
return [self.song_id, self.difficulty, self.rating]
class StageInfo():
danId: int = 0
danLevel: int = 0
@ -740,7 +703,6 @@ class MusicUpdateDetailV1():
self.lowestMissCount = 0
self.maxSkillPts = 0
self.locked = 0
self.rating = 0
def make(self) -> List:
return [
@ -753,10 +715,17 @@ class MusicUpdateDetailV1():
self.lowestMissCount,
self.maxSkillPts,
self.locked,
self.rating
]
class MusicUpdateDetailV2(MusicUpdateDetailV1):
def __init__(self) -> None:
super().__init__()
self.rating = 0
def make(self) -> List:
return super().make() + [self.rating]
class MusicUpdateDetailV3(MusicUpdateDetailV2):
def __init__(self) -> None:
super().__init__()
self.grades = SongDetailGradeCountsV2()

View File

@ -15,12 +15,22 @@ class HousingGetResponse(BaseResponse):
return super().make()
# ---housing/start----
class HousingStartRequest(BaseRequest):
class HousingStartRequestV1(BaseRequest):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.unknown0: str = self.params[0]
self.errorLog: str = self.params[1]
self.unknown2: str = self.params[2]
self.info: List[HousingInfo] = []
for info in self.params[2]:
self.info.append(HousingInfo(info[0], info[1]))
class HousingStartRequestV2(HousingStartRequestV1):
def __init__(self, data: Dict) -> None:
super(HousingStartRequestV1, self).__init__(data)
self.unknown0: str = self.params[0]
self.errorLog: str = self.params[1]
self.creditLog: str = self.params[2]
self.info: List[HousingInfo] = []
for info in self.params[3]:

View File

@ -23,14 +23,37 @@ class UserInfogetMyroomRequest(BaseRequest):
super().__init__(data)
self.game_id = int(self.params[0])
class UserInfogetMyroomResponse(BaseResponse):
class UserInfogetMyroomResponseV1(BaseResponse):
def __init__(self) -> None:
super().__init__()
self.titleViewBadge = 0
self.iconViewBadge = 0
self.trophyViewBadge = 0
self.noteColorViewBadge = 0
self.noteSoundViewBadge = 0
self.userViewingInfo = []
def make(self) -> Dict:
self.params = [
0,0,0,0,0,[],0,0,0
self.titleViewBadge,
self.iconViewBadge,
self.trophyViewBadge,
self.noteColorViewBadge,
self.noteSoundViewBadge,
self.userViewingInfo,
]
return super().make()
class UserInfogetMyroomResponseV2(UserInfogetMyroomResponseV1):
def __init__(self) -> None:
super().__init__()
def make(self) -> Dict:
super().make()
self.params += [0, 0, 0]
return super(UserInfogetMyroomResponseV1, self).make()
# ---user/info/getRanking---
class UserInfogetRankingRequest(BaseRequest):
game_id = 0

View File

@ -25,7 +25,7 @@ class UserGoodsPurchaseResponse(BaseResponse):
for ticket in tickets:
self.tickets.append(TicketItem(ticket[0], ticket[1], ticket[2]))
def make(self) -> List:
def make(self) -> Dict:
tix = []
for ticket in self.tickets:
tix.append(ticket.make())

View File

@ -1,22 +1,28 @@
from typing import List, Dict
from titles.wacca.handlers.base import BaseRequest, BaseResponse
from titles.wacca.handlers.helpers import GenericItemRecv, SongUpdateDetail, TicketItem
from titles.wacca.handlers.helpers import MusicUpdateDetailV1, MusicUpdateDetailV2
from titles.wacca.handlers.helpers import SeasonalInfoV2, SeasonalInfoV1
from titles.wacca.handlers.helpers import GenericItemRecv, SongUpdateDetailV2, TicketItem
from titles.wacca.handlers.helpers import MusicUpdateDetailV2, MusicUpdateDetailV3
from titles.wacca.handlers.helpers import SeasonalInfoV2, SeasonalInfoV1, SongUpdateDetailV1
from titles.wacca.handlers.helpers import MusicUpdateDetailV1
# ---user/music/update---
class UserMusicUpdateRequest(BaseRequest):
class UserMusicUpdateRequestV1(BaseRequest):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.profileId: int = self.params[0]
self.songNumber: int = self.params[1]
self.songDetail = SongUpdateDetail(self.params[2])
self.songDetail = SongUpdateDetailV1(self.params[2])
self.itemsObtained: List[GenericItemRecv] = []
for itm in data["params"][3]:
self.itemsObtained.append(GenericItemRecv(itm[0], itm[1], itm[2]))
class UserMusicUpdateRequestV2(UserMusicUpdateRequestV1):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.songDetail = SongUpdateDetailV2(self.params[2])
class UserMusicUpdateResponseV1(BaseResponse):
def __init__(self) -> None:
super().__init__()
@ -37,21 +43,22 @@ class UserMusicUpdateResponseV1(BaseResponse):
class UserMusicUpdateResponseV2(UserMusicUpdateResponseV1):
def __init__(self) -> None:
super().__init__()
self.songDetail = MusicUpdateDetailV2()
self.seasonInfo = SeasonalInfoV2()
class UserMusicUpdateResponseV3(UserMusicUpdateResponseV2):
def __init__(self) -> None:
super().__init__()
self.songDetail = MusicUpdateDetailV2()
self.songDetail = MusicUpdateDetailV3()
# ---user/music/updateCoop---
class UserMusicUpdateCoopRequest(UserMusicUpdateRequest):
class UserMusicUpdateCoopRequest(UserMusicUpdateRequestV2):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.coopData = self.params[4]
# ---user/music/updateVs---
class UserMusicUpdateVsRequest(UserMusicUpdateRequest):
class UserMusicUpdateVsRequest(UserMusicUpdateRequestV2):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.vsData = self.params[4]
@ -77,7 +84,7 @@ class UserMusicUnlockResponse(BaseResponse):
for ticket in tickets_remaining:
self.tickets.append(TicketItem(ticket[0], ticket[1], ticket[2]))
def make(self) -> List:
def make(self)-> Dict:
tickets = []
for ticket in self.tickets:

View File

@ -65,11 +65,11 @@ class UserStatusGetDetailResponseV1(BaseResponse):
self.userItems: UserItemInfoV1 = UserItemInfoV1()
self.scores: List[BestScoreDetailV1] = []
self.songPlayStatus: List[int] = [0,0]
self.seasonInfo: SeasonalInfoV1 = []
self.seasonInfo: SeasonalInfoV1 = SeasonalInfoV1()
self.playAreaList: List = [ [0],[0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0],[0,0,0,0],[0,0,0,0,0,0,0],[0] ]
self.songUpdateTime: int = 0
def make(self) -> List:
def make(self)-> Dict:
opts = []
play_modes = []
scores = []
@ -97,7 +97,7 @@ class UserStatusGetDetailResponseV1(BaseResponse):
return super().make()
def find_score_idx(self, song_id: int, difficulty: int = 1, start_idx: int = 0, stop_idx: int = None) -> Optional[int]:
def find_score_idx(self, song_id: int, difficulty: int = 1, start_idx: int = 0, stop_idx: Optional[int] = None) -> Optional[int]:
if stop_idx is None or stop_idx > len(self.scores):
stop_idx = len(self.scores)
@ -122,7 +122,7 @@ class UserStatusGetDetailResponseV2(UserStatusGetDetailResponseV1):
self.gatchaInfo: List[GachaInfo] = []
self.friendList: List[FriendDetail] = []
def make(self) -> List:
def make(self)-> Dict:
super().make()
gates = []
friends = []
@ -164,7 +164,7 @@ class UserStatusGetDetailResponseV4(UserStatusGetDetailResponseV3):
self.bingoStatus: BingoDetail = BingoDetail(0)
self.scores: List[BestScoreDetailV2] = []
def make(self) -> List:
def make(self)-> Dict:
super().make()
self.params.append(self.bingoStatus.make())
@ -187,7 +187,8 @@ class UserStatusLoginResponseV1(BaseResponse):
self.firstLoginDaily = is_first_login_daily
self.lastLoginDate = last_login_date
def make(self) -> List:
def make(self)-> Dict:
super().make()
daily = []
consec = []
other = []
@ -205,25 +206,24 @@ class UserStatusLoginResponseV1(BaseResponse):
return super().make()
class UserStatusLoginResponseV2(UserStatusLoginResponseV1):
vipInfo: VipInfo
lastLoginDate: int = 0
def __init__(self, is_first_login_daily: bool = False, last_login_date: int = 0) -> None:
super().__init__(is_first_login_daily)
self.lastLoginDate = last_login_date
self.vipInfo = VipInfo()
def make(self) -> List:
def make(self)-> Dict:
super().make()
self.params.append(self.vipInfo.make())
self.params.append(self.lastLoginDate)
return super(UserStatusLoginResponseV1, self).make()
class UserStatusLoginResponseV3(UserStatusLoginResponseV2):
unk: List = []
def __init__(self, is_first_login_daily: bool = False, last_login_date: int = 0) -> None:
super().__init__(is_first_login_daily, last_login_date)
self.unk: List = []
def make(self) -> List:
def make(self)-> Dict:
super().make()
self.params.append(self.unk)
return super(UserStatusLoginResponseV1, self).make()
@ -242,7 +242,7 @@ class UserStatusCreateResponseV1(BaseResponse):
self.userStatus.userId = userId
self.userStatus.username = username
def make(self) -> List:
def make(self)-> Dict:
self.params = [
self.userStatus.make()
]

View File

@ -1,6 +1,6 @@
from typing import Dict, List
from titles.wacca.handlers.base import BaseRequest, BaseResponse
from titles.wacca.handlers.helpers import StageInfo, StageupClearType
from titles.wacca.handlers.helpers import StageInfo, StageupClearType, GenericItemRecv
# --user/trial/get--
class UserTrialGetRequest(BaseRequest):
@ -28,15 +28,18 @@ class UserTrialGetResponse(BaseResponse):
class UserTrialUpdateRequest(BaseRequest):
def __init__(self, data: Dict) -> None:
super().__init__(data)
self.profileId = self.params[0]
self.stageId = self.params[1]
self.stageLevel = self.params[2]
self.profileId: int = self.params[0]
self.stageId: int = self.params[1]
self.stageLevel: int = self.params[2]
self.clearType = StageupClearType(self.params[3])
self.songScores = self.params[4]
self.numSongsCleared = self.params[5]
self.itemsObtained = self.params[6]
self.songScores: List[int] = self.params[4]
self.numSongsCleared: int = self.params[5]
self.itemsObtained: List[GenericItemRecv] = []
self.unk7: List = []
for x in self.params[6]:
self.itemsObtained.append(GenericItemRecv(x[0], x[1], x[2]))
if len(self.params) == 8:
self.unk7 = self.params[7]

View File

@ -36,7 +36,27 @@ class WaccaLily(WaccaS):
(210003, 0),
]
def handle_user_status_get_request(self, data: Dict) -> List[Any]:
def handle_advertise_GetNews_request(self, data: Dict)-> Dict:
resp = GetNewsResponseV3()
return resp.make()
def handle_housing_start_request(self, data: Dict) -> Dict:
req = HousingStartRequestV2(data)
resp = HousingStartResponseV1(
1,
[ # Recomended songs
1269,1007,1270,1002,1020,1003,1008,1211,1018,1092,1056,32,
1260,1230,1258,1251,2212,1264,1125,1037,2001,1272,1126,1119,
1104,1070,1047,1044,1027,1004,1001,24,2068,2062,2021,1275,
1249,1207,1203,1107,1021,1009,9,4,3,23,22,2014,13,1276,1247,
1240,1237,1128,1114,1110,1109,1102,1045,1043,1036,1035,1030,
1023,1015
]
)
return resp.make()
def handle_user_status_get_request(self, data: Dict)-> Dict:
req = UserStatusGetRequest(data)
resp = UserStatusGetV2Response()
ver_split = req.appVersion.split(".")
@ -115,7 +135,7 @@ class WaccaLily(WaccaS):
return resp.make()
def handle_user_status_login_request(self, data: Dict) -> List[Any]:
def handle_user_status_login_request(self, data: Dict)-> Dict:
req = UserStatusLoginRequest(data)
resp = UserStatusLoginResponseV2()
is_new_day = False
@ -156,7 +176,7 @@ class WaccaLily(WaccaS):
return resp.make()
def handle_user_status_getDetail_request(self, data: Dict) -> List[Any]:
def handle_user_status_getDetail_request(self, data: Dict)-> Dict:
req = UserStatusGetDetailRequest(data)
ver_split = req.appVersion.split(".")
if int(ver_split[1]) >= 53:
@ -255,13 +275,9 @@ class WaccaLily(WaccaS):
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())))
if x > 2:
resp.scores.append(BestScoreDetailV1(unlock["song_id"], x))
empty_scores = len(resp.scores)
for song in profile_scores:
resp.seasonInfo.cumulativeScore += song["score"]
empty_score_idx = resp.find_score_idx(song["song_id"], song["chart_id"], 0, empty_scores)
clear_cts = SongDetailClearCounts(
song["play_ct"],
@ -277,16 +293,6 @@ class WaccaLily(WaccaS):
song["grade_master_ct"]
)
if empty_score_idx is not None:
resp.scores[empty_score_idx].clearCounts = clear_cts
resp.scores[empty_score_idx].clearCountsSeason = clear_cts
resp.scores[empty_score_idx].gradeCounts = grade_cts
resp.scores[empty_score_idx].score = song["score"]
resp.scores[empty_score_idx].bestCombo = song["best_combo"]
resp.scores[empty_score_idx].lowestMissCtMaybe = song["lowest_miss_ct"]
resp.scores[empty_score_idx].rating = song["rating"]
else:
deets = BestScoreDetailV1(song["song_id"], song["chart_id"])
deets.clearCounts = clear_cts
deets.clearCountsSeason = clear_cts
@ -296,6 +302,8 @@ class WaccaLily(WaccaS):
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"]))
@ -349,3 +357,13 @@ class WaccaLily(WaccaS):
resp.seasonInfo.platesObtained = len(resp.userItems.plates)
return resp.make()
def handle_user_info_getMyroom_request(self, data: Dict)-> Dict:
return UserInfogetMyroomResponseV2().make()
def handle_user_status_update_request(self, data: Dict)-> Dict:
super().handle_user_status_update_request(data)
req = UserStatusUpdateRequestV2(data)
self.data.profile.update_profile_lastplayed(req.profileId, req.lastSongInfo.lastSongId, req.lastSongInfo.lastSongDiff,
req.lastSongInfo.lastFolderOrd, req.lastSongInfo.lastFolderId, req.lastSongInfo.lastSongOrd)
return BaseResponse().make()

View File

@ -35,7 +35,7 @@ class WaccaLilyR(WaccaLily):
(210003, 0),
]
def handle_user_status_create_request(self, data: Dict) -> List[Any]:
def handle_user_status_create_request(self, data: Dict)-> Dict:
req = UserStatusCreateRequest(data)
resp = super().handle_user_status_create_request(data)
@ -50,5 +50,5 @@ class WaccaLilyR(WaccaLily):
return resp
def handle_user_status_logout_request(self, data: Dict) -> List[Any]:
def handle_user_status_logout_request(self, data: Dict)-> Dict:
return BaseResponse().make()

View File

@ -46,12 +46,12 @@ class WaccaReverse(WaccaLilyR):
(310006, 0),
]
def handle_user_status_login_request(self, data: Dict) -> List[Any]:
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) -> List[Any]:
def handle_user_status_getDetail_request(self, data: Dict)-> Dict:
req = UserStatusGetDetailRequest(data)
resp = UserStatusGetDetailResponseV4()
@ -148,13 +148,9 @@ class WaccaReverse(WaccaLilyR):
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())))
if x > 2:
resp.scores.append(BestScoreDetailV2(unlock["song_id"], x))
empty_scores = len(resp.scores)
for song in profile_scores:
resp.seasonInfo.cumulativeScore += song["score"]
empty_score_idx = resp.find_score_idx(song["song_id"], song["chart_id"], 0, empty_scores)
clear_cts = SongDetailClearCounts(
song["play_ct"],
@ -170,16 +166,6 @@ class WaccaReverse(WaccaLilyR):
song["grade_master_ct"], song["grade_sp_ct"], song["grade_ssp_ct"], song["grade_sssp_ct"]
)
if empty_score_idx is not None:
resp.scores[empty_score_idx].clearCounts = clear_cts
resp.scores[empty_score_idx].clearCountsSeason = clear_cts
resp.scores[empty_score_idx].gradeCounts = grade_cts
resp.scores[empty_score_idx].score = song["score"]
resp.scores[empty_score_idx].bestCombo = song["best_combo"]
resp.scores[empty_score_idx].lowestMissCtMaybe = song["lowest_miss_ct"]
resp.scores[empty_score_idx].rating = song["rating"]
else:
deets = BestScoreDetailV2(song["song_id"], song["chart_id"])
deets.clearCounts = clear_cts
deets.clearCountsSeason = clear_cts
@ -188,6 +174,7 @@ class WaccaReverse(WaccaLilyR):
deets.bestCombo = song["best_combo"]
deets.lowestMissCtMaybe = song["lowest_miss_ct"]
deets.rating = song["rating"]
resp.scores.append(deets)
for trophy in profile_trophies:
@ -247,7 +234,7 @@ class WaccaReverse(WaccaLilyR):
return resp.make()
def handle_user_status_create_request(self, data: Dict) -> List[Any]:
def handle_user_status_create_request(self, data: Dict)-> Dict:
req = UserStatusCreateRequest(data)
resp = super().handle_user_status_create_request(data)

View File

@ -30,6 +30,6 @@ class WaccaS(WaccaBase):
super().__init__(cfg, game_cfg)
self.version = WaccaConstants.VER_WACCA_S
def handle_advertise_GetNews_request(self, data: Dict) -> List[Any]:
def handle_advertise_GetNews_request(self, data: Dict) -> Dict:
resp = GetNewsResponseV2()
return resp.make()