2019-12-08 22:43:49 +01:00
|
|
|
|
from typing import Optional, Dict, List, Tuple, Any
|
2021-09-07 19:56:15 +02:00
|
|
|
|
from typing_extensions import Final
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
from bemani.backend.reflec.base import ReflecBeatBase
|
|
|
|
|
from bemani.backend.reflec.limelight import ReflecBeatLimelight
|
|
|
|
|
|
2021-08-20 06:43:13 +02:00
|
|
|
|
from bemani.common import Profile, ValidatedDict, VersionConstants, ID, Time
|
2019-12-08 22:43:49 +01:00
|
|
|
|
from bemani.data import UserID, Achievement
|
|
|
|
|
from bemani.protocol import Node
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ReflecBeatColette(ReflecBeatBase):
|
|
|
|
|
|
2021-09-07 19:56:15 +02:00
|
|
|
|
name: str = "REFLEC BEAT colette"
|
|
|
|
|
version: int = VersionConstants.REFLEC_BEAT_COLETTE
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Clear types according to the game
|
2021-09-07 19:56:15 +02:00
|
|
|
|
GAME_CLEAR_TYPE_NO_PLAY: Final[int] = 0
|
|
|
|
|
GAME_CLEAR_TYPE_FAILED: Final[int] = 1
|
|
|
|
|
GAME_CLEAR_TYPE_CLEARED: Final[int] = 2
|
|
|
|
|
GAME_CLEAR_TYPE_ALMOST_COMBO: Final[int] = 3
|
|
|
|
|
GAME_CLEAR_TYPE_FULL_COMBO: Final[int] = 4
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def previous_version(self) -> Optional[ReflecBeatBase]:
|
|
|
|
|
return ReflecBeatLimelight(self.data, self.config, self.model)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def get_settings(cls) -> Dict[str, Any]:
|
|
|
|
|
"""
|
|
|
|
|
Return all of our front-end modifiably settings.
|
|
|
|
|
"""
|
|
|
|
|
return {
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"bools": [
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"name": "Force Song Unlock",
|
|
|
|
|
"tip": "Force unlock all songs.",
|
|
|
|
|
"category": "game_config",
|
|
|
|
|
"setting": "force_unlock_songs",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
],
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"ints": [],
|
2019-12-08 22:43:49 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def __db_to_game_clear_type(self, db_clear_type: int, db_combo_type: int) -> int:
|
|
|
|
|
if db_clear_type == self.CLEAR_TYPE_NO_PLAY:
|
|
|
|
|
return self.GAME_CLEAR_TYPE_NO_PLAY
|
|
|
|
|
if db_clear_type == self.CLEAR_TYPE_FAILED:
|
|
|
|
|
return self.GAME_CLEAR_TYPE_FAILED
|
|
|
|
|
if db_clear_type in [
|
|
|
|
|
self.CLEAR_TYPE_CLEARED,
|
|
|
|
|
self.CLEAR_TYPE_HARD_CLEARED,
|
|
|
|
|
self.CLEAR_TYPE_S_HARD_CLEARED,
|
|
|
|
|
]:
|
|
|
|
|
if db_combo_type == self.COMBO_TYPE_NONE:
|
|
|
|
|
return self.GAME_CLEAR_TYPE_CLEARED
|
|
|
|
|
if db_combo_type == self.COMBO_TYPE_ALMOST_COMBO:
|
|
|
|
|
return self.GAME_CLEAR_TYPE_ALMOST_COMBO
|
|
|
|
|
if db_combo_type in [
|
|
|
|
|
self.COMBO_TYPE_FULL_COMBO,
|
|
|
|
|
self.COMBO_TYPE_FULL_COMBO_ALL_JUST,
|
|
|
|
|
]:
|
|
|
|
|
return self.GAME_CLEAR_TYPE_FULL_COMBO
|
2022-10-15 20:56:30 +02:00
|
|
|
|
raise Exception(f"Invalid db_combo_type {db_combo_type}")
|
|
|
|
|
raise Exception(f"Invalid db_clear_type {db_clear_type}")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def __game_to_db_clear_type(self, game_clear_type: int) -> Tuple[int, int]:
|
|
|
|
|
if game_clear_type == self.GAME_CLEAR_TYPE_NO_PLAY:
|
|
|
|
|
return (self.CLEAR_TYPE_NO_PLAY, self.COMBO_TYPE_NONE)
|
|
|
|
|
if game_clear_type == self.GAME_CLEAR_TYPE_FAILED:
|
|
|
|
|
return (self.CLEAR_TYPE_FAILED, self.COMBO_TYPE_NONE)
|
|
|
|
|
if game_clear_type == self.GAME_CLEAR_TYPE_CLEARED:
|
|
|
|
|
return (self.CLEAR_TYPE_CLEARED, self.COMBO_TYPE_NONE)
|
|
|
|
|
if game_clear_type == self.GAME_CLEAR_TYPE_ALMOST_COMBO:
|
|
|
|
|
return (self.CLEAR_TYPE_CLEARED, self.COMBO_TYPE_ALMOST_COMBO)
|
|
|
|
|
if game_clear_type == self.GAME_CLEAR_TYPE_FULL_COMBO:
|
|
|
|
|
return (self.CLEAR_TYPE_CLEARED, self.COMBO_TYPE_FULL_COMBO)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
raise Exception(f"Invalid game_clear_type {game_clear_type}")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_pcb_error_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("pcb")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_pcb_uptime_update_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("pcb")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_pcb_boot_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
shop_id = ID.parse_machine_id(request.child_value("lid"))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
machine = self.get_machine_by_id(shop_id)
|
|
|
|
|
if machine is not None:
|
|
|
|
|
machine_name = machine.name
|
2022-10-15 20:56:30 +02:00
|
|
|
|
close = machine.data.get_bool("close")
|
|
|
|
|
hour = machine.data.get_int("hour")
|
|
|
|
|
minute = machine.data.get_int("minute")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
else:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
machine_name = ""
|
2019-12-08 22:43:49 +01:00
|
|
|
|
close = False
|
|
|
|
|
hour = 0
|
|
|
|
|
minute = 0
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("pcb")
|
|
|
|
|
sinfo = Node.void("sinfo")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(sinfo)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
sinfo.add_child(Node.string("nm", machine_name))
|
|
|
|
|
sinfo.add_child(Node.bool("cl_enbl", close))
|
|
|
|
|
sinfo.add_child(Node.u8("cl_h", hour))
|
|
|
|
|
sinfo.add_child(Node.u8("cl_m", minute))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_shop_setting_write_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("shop")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_shop_info_write_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
self.update_machine_name(request.child_value("sinfo/nm"))
|
|
|
|
|
self.update_machine_data(
|
|
|
|
|
{
|
|
|
|
|
"close": request.child_value("sinfo/cl_enbl"),
|
|
|
|
|
"hour": request.child_value("sinfo/cl_h"),
|
|
|
|
|
"minute": request.child_value("sinfo/cl_m"),
|
|
|
|
|
"pref": request.child_value("sinfo/prf"),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
return Node.void("shop")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def __add_event_info(self, root: Node) -> None:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
event_ctrl = Node.void("event_ctrl")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(event_ctrl)
|
|
|
|
|
|
|
|
|
|
events: Dict[int, int] = {
|
|
|
|
|
# Tricolette Park unlock event.
|
|
|
|
|
9: 0,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (eventid, phase) in events.items():
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = Node.void("data")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
event_ctrl.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data.add_child(Node.s32("type", eventid))
|
|
|
|
|
data.add_child(Node.s32("phase", phase))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
item_lock_ctrl = Node.void("item_lock_ctrl")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(item_lock_ctrl)
|
|
|
|
|
# Contains zero or more nodes like:
|
|
|
|
|
# <item>
|
|
|
|
|
# <type __type="u8">any</type>
|
|
|
|
|
# <id __type="u16">any</id>
|
|
|
|
|
# <param __type="u16">0-3</param>
|
|
|
|
|
# </item>
|
|
|
|
|
|
|
|
|
|
def handle_info_common_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("info")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
self.__add_event_info(root)
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_info_ranking_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
version = request.child_value("ver")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("info")
|
|
|
|
|
root.add_child(Node.s32("ver", version))
|
|
|
|
|
ranking = Node.void("ranking")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(ranking)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
def add_hitchart(
|
|
|
|
|
name: str, start: int, end: int, hitchart: List[Tuple[int, int]]
|
|
|
|
|
) -> None:
|
2019-12-08 22:43:49 +01:00
|
|
|
|
base = Node.void(name)
|
|
|
|
|
ranking.add_child(base)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
base.add_child(Node.s32("bt", start))
|
|
|
|
|
base.add_child(Node.s32("et", end))
|
|
|
|
|
new = Node.void("new")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
base.add_child(new)
|
|
|
|
|
|
|
|
|
|
for (mid, plays) in hitchart:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
d = Node.void("d")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
new.add_child(d)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
d.add_child(Node.s16("mid", mid))
|
|
|
|
|
d.add_child(Node.s32("cnt", plays))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Weekly hit chart
|
|
|
|
|
add_hitchart(
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"weekly",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
Time.now() - Time.SECONDS_IN_WEEK,
|
|
|
|
|
Time.now(),
|
|
|
|
|
self.data.local.music.get_hit_chart(self.game, self.version, 1024, 7),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Monthly hit chart
|
|
|
|
|
add_hitchart(
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"monthly",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
Time.now() - Time.SECONDS_IN_DAY * 30,
|
|
|
|
|
Time.now(),
|
|
|
|
|
self.data.local.music.get_hit_chart(self.game, self.version, 1024, 30),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# All time hit chart
|
|
|
|
|
add_hitchart(
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"total",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
Time.now() - Time.SECONDS_IN_DAY * 365,
|
|
|
|
|
Time.now(),
|
|
|
|
|
self.data.local.music.get_hit_chart(self.game, self.version, 1024, 365),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_info_pzlcmt_read_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
extid = request.child_value("uid")
|
|
|
|
|
teamid = request.child_value("tid")
|
|
|
|
|
limit = request.child_value("limit")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
|
|
|
|
|
|
|
|
|
|
comments = [
|
2022-10-15 20:56:30 +02:00
|
|
|
|
achievement
|
|
|
|
|
for achievement in self.data.local.user.get_all_time_based_achievements(
|
|
|
|
|
self.game, self.version
|
|
|
|
|
)
|
|
|
|
|
if achievement[1].type == "puzzle_comment"
|
2019-12-08 22:43:49 +01:00
|
|
|
|
]
|
|
|
|
|
comments.sort(key=lambda x: x[1].timestamp, reverse=True)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
favorites = [comment for comment in comments if comment[0] == userid]
|
2019-12-08 22:43:49 +01:00
|
|
|
|
teamcomments = [
|
2022-10-15 20:56:30 +02:00
|
|
|
|
comment
|
|
|
|
|
for comment in comments
|
|
|
|
|
if comment[1].data.get_int("teamid") == teamid
|
2019-12-08 22:43:49 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
# Cap all comment blocks to the limit
|
|
|
|
|
if limit >= 0:
|
|
|
|
|
comments = comments[:limit]
|
|
|
|
|
favorites = favorites[:limit]
|
|
|
|
|
teamcomments = teamcomments[:limit]
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("info")
|
|
|
|
|
comment = Node.void("comment")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(comment)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
comment.add_child(Node.s32("time", Time.now()))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Mapping of profiles to userIDs
|
|
|
|
|
uid_mapping = {
|
|
|
|
|
uid: prof for (uid, prof) in self.get_any_profiles([c[0] for c in comments])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Handle anonymous comments by returning a default profile
|
2021-08-20 06:43:13 +02:00
|
|
|
|
uid_mapping[UserID(0)] = Profile(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
"",
|
|
|
|
|
0,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
{"name": "PLAYER"},
|
2021-08-20 06:43:13 +02:00
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def add_comments(name: str, selected: List[Tuple[UserID, Achievement]]) -> None:
|
|
|
|
|
for (uid, ach) in selected:
|
|
|
|
|
cmnt = Node.void(name)
|
|
|
|
|
root.add_child(cmnt)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
cmnt.add_child(Node.s32("uid", uid_mapping[uid].extid))
|
|
|
|
|
cmnt.add_child(Node.string("name", uid_mapping[uid].get_str("name")))
|
|
|
|
|
cmnt.add_child(Node.s16("icon", ach.data.get_int("icon")))
|
|
|
|
|
cmnt.add_child(Node.s8("bln", ach.data.get_int("bln")))
|
|
|
|
|
cmnt.add_child(Node.s32("tid", ach.data.get_int("teamid")))
|
|
|
|
|
cmnt.add_child(Node.string("t_name", ach.data.get_str("teamname")))
|
|
|
|
|
cmnt.add_child(Node.s8("pref", ach.data.get_int("prefecture")))
|
|
|
|
|
cmnt.add_child(Node.s32("time", ach.timestamp))
|
|
|
|
|
cmnt.add_child(Node.string("comment", ach.data.get_str("comment")))
|
|
|
|
|
cmnt.add_child(Node.bool("is_tweet", ach.data.get_bool("tweet")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Add all comments
|
2022-10-15 20:56:30 +02:00
|
|
|
|
add_comments("c", comments)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Add personal comments (favorites)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
add_comments("cf", favorites)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Add team comments
|
2022-10-15 20:56:30 +02:00
|
|
|
|
add_comments("ct", teamcomments)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_info_pzlcmt_write_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
extid = request.child_value("uid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
|
|
|
|
|
if userid is None:
|
|
|
|
|
# Anonymous comment
|
|
|
|
|
userid = UserID(0)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
icon = request.child_value("icon")
|
|
|
|
|
bln = request.child_value("bln")
|
|
|
|
|
teamid = request.child_value("tid")
|
|
|
|
|
teamname = request.child_value("t_name")
|
|
|
|
|
prefecture = request.child_value("pref")
|
|
|
|
|
comment = request.child_value("comment")
|
|
|
|
|
is_tweet = request.child_value("is_tweet")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Link comment to user's profile
|
|
|
|
|
self.data.local.user.put_time_based_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
0, # We never have an ID for this, since comments are add-only
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"puzzle_comment",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"icon": icon,
|
|
|
|
|
"bln": bln,
|
|
|
|
|
"teamid": teamid,
|
|
|
|
|
"teamname": teamname,
|
|
|
|
|
"prefecture": prefecture,
|
|
|
|
|
"comment": comment,
|
|
|
|
|
"tweet": is_tweet,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("info")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_jbrbcollabo_save_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
jbrbcollabo = Node.void("jbrbcollabo")
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("marathontype", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("smith_start", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("pastel_start", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("smith_run", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("pastel_run", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("smith_ouen", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("pastel_ouen", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("smith_water_run", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("pastel_water_run", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("getwater", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("smith_goal", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("pastel_goal", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("distancetype", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_2_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_3_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_2_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_3_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_2_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_3_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_2_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_3_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_2_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_3_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_2_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_3_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_2_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_2_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("start_flg", False))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
return jbrbcollabo
|
|
|
|
|
|
|
|
|
|
def handle_lobby_entry_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("lobby")
|
|
|
|
|
root.add_child(Node.s32("interval", 120))
|
|
|
|
|
root.add_child(Node.s32("interval_p", 120))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Create a lobby entry for this user
|
2022-10-15 20:56:30 +02:00
|
|
|
|
extid = request.child_value("e/uid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
|
|
|
|
|
if userid is not None:
|
|
|
|
|
profile = self.get_profile(userid)
|
|
|
|
|
self.data.local.lobby.put_lobby(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"mid": request.child_value("e/mid"),
|
|
|
|
|
"ng": request.child_value("e/ng"),
|
|
|
|
|
"mopt": request.child_value("e/mopt"),
|
|
|
|
|
"tid": request.child_value("e/tid"),
|
|
|
|
|
"tn": request.child_value("e/tn"),
|
|
|
|
|
"topt": request.child_value("e/topt"),
|
|
|
|
|
"lid": request.child_value("e/lid"),
|
|
|
|
|
"sn": request.child_value("e/sn"),
|
|
|
|
|
"pref": request.child_value("e/pref"),
|
|
|
|
|
"stg": request.child_value("e/stg"),
|
|
|
|
|
"pside": request.child_value("e/pside"),
|
|
|
|
|
"eatime": request.child_value("e/eatime"),
|
|
|
|
|
"ga": request.child_value("e/ga"),
|
|
|
|
|
"gp": request.child_value("e/gp"),
|
|
|
|
|
"la": request.child_value("e/la"),
|
|
|
|
|
"ver": request.child_value("e/ver"),
|
|
|
|
|
},
|
2019-12-08 22:43:49 +01:00
|
|
|
|
)
|
|
|
|
|
lobby = self.data.local.lobby.get_lobby(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root.add_child(Node.s32("eid", lobby.get_int("id")))
|
|
|
|
|
e = Node.void("e")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(e)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
e.add_child(Node.s32("eid", lobby.get_int("id")))
|
|
|
|
|
e.add_child(Node.u16("mid", lobby.get_int("mid")))
|
|
|
|
|
e.add_child(Node.u8("ng", lobby.get_int("ng")))
|
|
|
|
|
e.add_child(Node.s32("uid", profile.extid))
|
|
|
|
|
e.add_child(Node.s32("uattr", profile.get_int("uattr")))
|
|
|
|
|
e.add_child(Node.string("pn", profile.get_str("name")))
|
|
|
|
|
e.add_child(Node.s16("mg", profile.get_int("mg")))
|
|
|
|
|
e.add_child(Node.s32("mopt", lobby.get_int("mopt")))
|
|
|
|
|
e.add_child(Node.s32("tid", lobby.get_int("tid")))
|
|
|
|
|
e.add_child(Node.string("tn", lobby.get_str("tn")))
|
|
|
|
|
e.add_child(Node.s32("topt", lobby.get_int("topt")))
|
|
|
|
|
e.add_child(Node.string("lid", lobby.get_str("lid")))
|
|
|
|
|
e.add_child(Node.string("sn", lobby.get_str("sn")))
|
|
|
|
|
e.add_child(Node.u8("pref", lobby.get_int("pref")))
|
|
|
|
|
e.add_child(Node.s8("stg", lobby.get_int("stg")))
|
|
|
|
|
e.add_child(Node.s8("pside", lobby.get_int("pside")))
|
|
|
|
|
e.add_child(Node.s16("eatime", lobby.get_int("eatime")))
|
|
|
|
|
e.add_child(Node.u8_array("ga", lobby.get_int_array("ga", 4)))
|
|
|
|
|
e.add_child(Node.u16("gp", lobby.get_int("gp")))
|
|
|
|
|
e.add_child(Node.u8_array("la", lobby.get_int_array("la", 4)))
|
|
|
|
|
e.add_child(Node.u8("ver", lobby.get_int("ver")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_lobby_read_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("lobby")
|
|
|
|
|
root.add_child(Node.s32("interval", 120))
|
|
|
|
|
root.add_child(Node.s32("interval_p", 120))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Look up all lobbies matching the criteria specified
|
2022-10-15 20:56:30 +02:00
|
|
|
|
ver = request.child_value("var")
|
|
|
|
|
mg = request.child_value("m_grade") # noqa: F841
|
|
|
|
|
extid = request.child_value("uid")
|
|
|
|
|
limit = request.child_value("max")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
|
|
|
|
|
if userid is not None:
|
|
|
|
|
lobbies = self.data.local.lobby.get_all_lobbies(self.game, self.version)
|
|
|
|
|
for (user, lobby) in lobbies:
|
|
|
|
|
if limit <= 0:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if user == userid:
|
|
|
|
|
# If we have our own lobby, don't return it
|
|
|
|
|
continue
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if ver != lobby.get_int("ver"):
|
2019-12-08 22:43:49 +01:00
|
|
|
|
# Don't return lobby data for different versions
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
profile = self.get_profile(user)
|
|
|
|
|
if profile is None:
|
|
|
|
|
# No profile info, don't return this lobby
|
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
e = Node.void("e")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(e)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
e.add_child(Node.s32("eid", lobby.get_int("id")))
|
|
|
|
|
e.add_child(Node.u16("mid", lobby.get_int("mid")))
|
|
|
|
|
e.add_child(Node.u8("ng", lobby.get_int("ng")))
|
|
|
|
|
e.add_child(Node.s32("uid", profile.extid))
|
|
|
|
|
e.add_child(Node.s32("uattr", profile.get_int("uattr")))
|
|
|
|
|
e.add_child(Node.string("pn", profile.get_str("name")))
|
|
|
|
|
e.add_child(Node.s16("mg", profile.get_int("mg")))
|
|
|
|
|
e.add_child(Node.s32("mopt", lobby.get_int("mopt")))
|
|
|
|
|
e.add_child(Node.s32("tid", lobby.get_int("tid")))
|
|
|
|
|
e.add_child(Node.string("tn", lobby.get_str("tn")))
|
|
|
|
|
e.add_child(Node.s32("topt", lobby.get_int("topt")))
|
|
|
|
|
e.add_child(Node.string("lid", lobby.get_str("lid")))
|
|
|
|
|
e.add_child(Node.string("sn", lobby.get_str("sn")))
|
|
|
|
|
e.add_child(Node.u8("pref", lobby.get_int("pref")))
|
|
|
|
|
e.add_child(Node.s8("stg", lobby.get_int("stg")))
|
|
|
|
|
e.add_child(Node.s8("pside", lobby.get_int("pside")))
|
|
|
|
|
e.add_child(Node.s16("eatime", lobby.get_int("eatime")))
|
|
|
|
|
e.add_child(Node.u8_array("ga", lobby.get_int_array("ga", 4)))
|
|
|
|
|
e.add_child(Node.u16("gp", lobby.get_int("gp")))
|
|
|
|
|
e.add_child(Node.u8_array("la", lobby.get_int_array("la", 4)))
|
|
|
|
|
e.add_child(Node.u8("ver", lobby.get_int("ver")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
limit = limit - 1
|
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_lobby_delete_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eid = request.child_value("eid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
self.data.local.lobby.destroy_lobby(eid)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("lobby")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_player_start_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("player")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Create a new play session based on info from the request
|
2022-10-15 20:56:30 +02:00
|
|
|
|
refid = request.child_value("rid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
|
|
|
|
|
if userid is not None:
|
|
|
|
|
self.data.local.lobby.put_play_session_info(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"ga": request.child_value("ga"),
|
|
|
|
|
"gp": request.child_value("gp"),
|
|
|
|
|
"la": request.child_value("la"),
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
info = self.data.local.lobby.get_play_session_info(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
)
|
|
|
|
|
if info is not None:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
play_id = info.get_int("id")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
else:
|
|
|
|
|
play_id = 0
|
|
|
|
|
else:
|
|
|
|
|
play_id = 0
|
|
|
|
|
|
|
|
|
|
# Session stuff, and resend global defaults
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root.add_child(Node.s32("plyid", play_id))
|
|
|
|
|
root.add_child(Node.u64("start_time", Time.now() * 1000))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
self.__add_event_info(root)
|
|
|
|
|
|
|
|
|
|
# Event settings and such
|
2022-10-15 20:56:30 +02:00
|
|
|
|
lincle_link_4 = Node.void("lincle_link_4")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(lincle_link_4)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
lincle_link_4.add_child(Node.u32("qpro", 0))
|
|
|
|
|
lincle_link_4.add_child(Node.u32("glass", 0))
|
|
|
|
|
lincle_link_4.add_child(Node.u32("treasure", 0))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_0", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_1", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_2", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_3", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_4", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_5", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0_6", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_0", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_1", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_2", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_3", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_iidx_4", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_0", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_1", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_2", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_3", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_4", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_5", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0_6", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_0", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_1", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_2", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_3", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("for_rb_4", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("qproflg", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("glassflg", False))
|
|
|
|
|
lincle_link_4.add_child(Node.bool("complete", False))
|
|
|
|
|
|
|
|
|
|
jbrbcollabo = Node.void("jbrbcollabo")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(jbrbcollabo)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_2_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_3_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_2_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_3_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run1_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_2_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_3_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_2_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_3_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run2_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_2_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_3_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_2_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_3_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run3_4_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("marathontype", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("smith_start", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u32("pastel_start", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("smith_ouen", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("pastel_ouen", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.u16("distancetype", 0))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("smith_goal", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("pastel_goal", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_1_j_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_1_r_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_2_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("run4_2_flg", False))
|
|
|
|
|
jbrbcollabo.add_child(Node.bool("start_flg", False))
|
|
|
|
|
|
|
|
|
|
tricolettepark = Node.void("tricolettepark")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(tricolettepark)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
tricolettepark.add_child(Node.s32("open_music", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss0_damage", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss1_damage", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss2_damage", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss3_damage", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss0_stun", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss1_stun", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss2_stun", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("boss3_stun", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("magic_gauge", -1))
|
|
|
|
|
tricolettepark.add_child(Node.s32("today_party", -1))
|
|
|
|
|
tricolettepark.add_child(Node.bool("union_magic", False))
|
|
|
|
|
tricolettepark.add_child(Node.bool("is_complete", False))
|
|
|
|
|
tricolettepark.add_child(Node.float("base_attack_rate", 1.0))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_player_delete_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("player")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_player_end_request(self, request: Node) -> Node:
|
|
|
|
|
# Destroy play session based on info from the request
|
2022-10-15 20:56:30 +02:00
|
|
|
|
refid = request.child_value("rid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
|
|
|
|
|
if userid is not None:
|
|
|
|
|
# Kill any lingering lobbies by this user
|
|
|
|
|
lobby = self.data.local.lobby.get_lobby(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
)
|
|
|
|
|
if lobby is not None:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
self.data.local.lobby.destroy_lobby(lobby.get_int("id"))
|
|
|
|
|
self.data.local.lobby.destroy_play_session_info(
|
|
|
|
|
self.game, self.version, userid
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("player")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_player_succeed_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
refid = request.child_value("rid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
|
|
|
|
|
if userid is not None:
|
|
|
|
|
previous_version = self.previous_version()
|
|
|
|
|
profile = previous_version.get_profile(userid)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
achievements = self.data.local.user.get_achievements(
|
|
|
|
|
previous_version.game, previous_version.version, userid
|
|
|
|
|
)
|
|
|
|
|
scores = self.data.remote.music.get_scores(
|
|
|
|
|
previous_version.game, previous_version.version, userid
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
else:
|
|
|
|
|
profile = None
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("player")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
if profile is None:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root.add_child(Node.string("name", ""))
|
|
|
|
|
root.add_child(Node.s16("lv", -1))
|
|
|
|
|
root.add_child(Node.s32("exp", -1))
|
|
|
|
|
root.add_child(Node.s32("grd", -1))
|
|
|
|
|
root.add_child(Node.s32("ap", -1))
|
|
|
|
|
|
|
|
|
|
root.add_child(Node.void("released"))
|
|
|
|
|
root.add_child(Node.void("mrecord"))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
else:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root.add_child(Node.string("name", profile.get_str("name")))
|
|
|
|
|
root.add_child(Node.s16("lv", profile.get_int("lvl")))
|
|
|
|
|
root.add_child(Node.s32("exp", profile.get_int("exp")))
|
|
|
|
|
root.add_child(Node.s32("grd", profile.get_int("mg"))) # This is a guess
|
|
|
|
|
root.add_child(Node.s32("ap", profile.get_int("ap")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
released = Node.void("released")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(released)
|
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type != "item_0":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
released.add_child(Node.s16("i", item.id))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
mrecord = Node.void("mrecord")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(mrecord)
|
|
|
|
|
for score in scores:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
mrec = Node.void("mrec")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
mrecord.add_child(mrec)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
mrec.add_child(Node.s16("mid", score.id))
|
|
|
|
|
mrec.add_child(Node.s8("ntgrd", score.chart))
|
|
|
|
|
mrec.add_child(Node.s32("pc", score.plays))
|
|
|
|
|
mrec.add_child(
|
|
|
|
|
Node.s8(
|
|
|
|
|
"ct",
|
|
|
|
|
self.__db_to_game_clear_type(
|
|
|
|
|
score.data.get_int("clear_type"),
|
|
|
|
|
score.data.get_int("combo_type"),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
mrec.add_child(Node.s16("ar", score.data.get_int("achievement_rate")))
|
|
|
|
|
mrec.add_child(Node.s16("scr", score.points))
|
|
|
|
|
mrec.add_child(Node.s16("cmb", score.data.get_int("combo")))
|
|
|
|
|
mrec.add_child(Node.s16("ms", score.data.get_int("miss_count")))
|
|
|
|
|
mrec.add_child(Node.u16("ver", 0))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
def handle_player_read_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
refid = request.child_value("rid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
profile = self.get_profile_by_refid(refid)
|
|
|
|
|
if profile:
|
|
|
|
|
return profile
|
2022-10-15 20:56:30 +02:00
|
|
|
|
return Node.void("player")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
def handle_player_write_request(self, request: Node) -> Node:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
refid = request.child_value("pdata/account/rid")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
profile = self.put_profile_by_refid(refid, request)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("player")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
if profile is None:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root.add_child(Node.s32("uid", 0))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
else:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root.add_child(Node.s32("uid", profile.extid))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
return root
|
|
|
|
|
|
2021-08-20 06:43:13 +02:00
|
|
|
|
def format_profile(self, userid: UserID, profile: Profile) -> Node:
|
2019-12-08 22:43:49 +01:00
|
|
|
|
statistics = self.get_play_statistics(userid)
|
|
|
|
|
game_config = self.get_game_config()
|
2022-10-15 20:56:30 +02:00
|
|
|
|
achievements = self.data.local.user.get_achievements(
|
|
|
|
|
self.game, self.version, userid
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
scores = self.data.remote.music.get_scores(self.game, self.version, userid)
|
|
|
|
|
links = self.data.local.user.get_links(self.game, self.version, userid)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
root = Node.void("player")
|
|
|
|
|
pdata = Node.void("pdata")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
root.add_child(pdata)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
account = Node.void("account")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(account)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
account.add_child(Node.s32("usrid", profile.extid))
|
|
|
|
|
account.add_child(Node.s32("tpc", statistics.total_plays))
|
|
|
|
|
account.add_child(Node.s32("dpc", statistics.today_plays))
|
|
|
|
|
account.add_child(Node.s32("crd", 1))
|
|
|
|
|
account.add_child(Node.s32("brd", 1))
|
|
|
|
|
account.add_child(Node.s32("tdc", statistics.total_days))
|
|
|
|
|
account.add_child(Node.s32("intrvld", 0))
|
|
|
|
|
account.add_child(Node.s16("ver", 5))
|
|
|
|
|
account.add_child(Node.u64("pst", 0))
|
|
|
|
|
account.add_child(Node.u64("st", Time.now() * 1000))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Base account info
|
2022-10-15 20:56:30 +02:00
|
|
|
|
base = Node.void("base")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(base)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
base.add_child(Node.string("name", profile.get_str("name")))
|
|
|
|
|
base.add_child(Node.s32("exp", profile.get_int("exp")))
|
|
|
|
|
base.add_child(Node.s32("lv", profile.get_int("lvl")))
|
|
|
|
|
base.add_child(Node.s32("mg", profile.get_int("mg")))
|
|
|
|
|
base.add_child(Node.s32("ap", profile.get_int("ap")))
|
|
|
|
|
base.add_child(Node.s32("tid", profile.get_int("team_id", -1)))
|
|
|
|
|
base.add_child(Node.string("tname", profile.get_str("team_name", "")))
|
|
|
|
|
base.add_child(Node.string("cmnt", ""))
|
|
|
|
|
base.add_child(Node.s32("uattr", profile.get_int("uattr")))
|
|
|
|
|
base.add_child(
|
|
|
|
|
Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 50))
|
|
|
|
|
)
|
|
|
|
|
base.add_child(Node.s32("tbs", -1))
|
|
|
|
|
base.add_child(Node.s32("tbs_r", -1))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Rivals
|
2022-10-15 20:56:30 +02:00
|
|
|
|
rival = Node.void("rival")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(rival)
|
|
|
|
|
slotid = 0
|
|
|
|
|
for link in links:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if link.type != "rival":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
rprofile = self.get_profile(link.other_userid)
|
|
|
|
|
if rprofile is None:
|
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
r = Node.void("r")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
rival.add_child(r)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
r.add_child(Node.s32("slot_id", slotid))
|
|
|
|
|
r.add_child(Node.s32("id", rprofile.extid))
|
|
|
|
|
r.add_child(Node.string("name", rprofile.get_str("name")))
|
|
|
|
|
r.add_child(Node.bool("friend", True))
|
|
|
|
|
r.add_child(Node.bool("locked", False))
|
|
|
|
|
r.add_child(Node.s32("rc", 0))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
slotid = slotid + 1
|
|
|
|
|
|
|
|
|
|
# Player customizations
|
2022-10-15 20:56:30 +02:00
|
|
|
|
custom = Node.void("custom")
|
|
|
|
|
customdict = profile.get_dict("custom")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(custom)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
custom.add_child(Node.u8("st_shot", customdict.get_int("st_shot")))
|
|
|
|
|
custom.add_child(Node.u8("st_frame", customdict.get_int("st_frame")))
|
|
|
|
|
custom.add_child(Node.u8("st_expl", customdict.get_int("st_expl")))
|
|
|
|
|
custom.add_child(Node.u8("st_bg", customdict.get_int("st_bg")))
|
|
|
|
|
custom.add_child(Node.u8("st_shot_vol", customdict.get_int("st_shot_vol")))
|
|
|
|
|
custom.add_child(Node.u8("st_bg_bri", customdict.get_int("st_bg_bri")))
|
|
|
|
|
custom.add_child(Node.u8("st_obj_size", customdict.get_int("st_obj_size")))
|
|
|
|
|
custom.add_child(Node.u8("st_jr_gauge", customdict.get_int("st_jr_gauge")))
|
|
|
|
|
custom.add_child(Node.u8("st_clr_gauge", customdict.get_int("st_clr_gauge")))
|
|
|
|
|
custom.add_child(Node.u8("st_jdg_disp", customdict.get_int("st_jdg_disp")))
|
|
|
|
|
custom.add_child(Node.u8("st_tm_disp", customdict.get_int("st_tm_disp")))
|
|
|
|
|
custom.add_child(Node.u8("st_rnd", customdict.get_int("st_rnd")))
|
|
|
|
|
custom.add_child(
|
|
|
|
|
Node.s16_array("schat_0", customdict.get_int_array("schat_0", 9))
|
|
|
|
|
)
|
|
|
|
|
custom.add_child(
|
|
|
|
|
Node.s16_array("schat_1", customdict.get_int_array("schat_1", 9))
|
|
|
|
|
)
|
|
|
|
|
custom.add_child(
|
|
|
|
|
Node.s16_array("ichat_0", customdict.get_int_array("ichat_0", 6))
|
|
|
|
|
)
|
|
|
|
|
custom.add_child(
|
|
|
|
|
Node.s16_array("ichat_1", customdict.get_int_array("ichat_1", 6))
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Player external config
|
2022-10-15 20:56:30 +02:00
|
|
|
|
config = Node.void("config")
|
|
|
|
|
configdict = profile.get_dict("config")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(config)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
config.add_child(Node.u8("msel_bgm", configdict.get_int("msel_bgm")))
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.u8("narrowdown_type", configdict.get_int("narrowdown_type"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(Node.s16("icon_id", configdict.get_int("icon_id")))
|
|
|
|
|
config.add_child(Node.s16("byword_0", configdict.get_int("byword_0")))
|
|
|
|
|
config.add_child(Node.s16("byword_1", configdict.get_int("byword_1")))
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.bool("is_auto_byword_0", configdict.get_bool("is_auto_byword_0"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.bool("is_auto_byword_1", configdict.get_bool("is_auto_byword_1"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(Node.u8("mrec_type", configdict.get_int("mrec_type")))
|
|
|
|
|
config.add_child(Node.u8("tab_sel", configdict.get_int("tab_sel")))
|
|
|
|
|
config.add_child(Node.u8("card_disp", configdict.get_int("card_disp")))
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.u8("score_tab_disp", configdict.get_int("score_tab_disp"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.s16("last_music_id", configdict.get_int("last_music_id", -1))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.u8("last_note_grade", configdict.get_int("last_note_grade"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(Node.u8("sort_type", configdict.get_int("sort_type")))
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.u8("rival_panel_type", configdict.get_int("rival_panel_type"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.u64("random_entry_work", configdict.get_int("random_entry_work"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.u8("folder_lamp_type", configdict.get_int("folder_lamp_type"))
|
|
|
|
|
)
|
|
|
|
|
config.add_child(Node.bool("is_tweet", configdict.get_bool("is_tweet")))
|
|
|
|
|
config.add_child(
|
|
|
|
|
Node.bool("is_link_twitter", configdict.get_bool("is_link_twitter"))
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Stamps
|
2022-10-15 20:56:30 +02:00
|
|
|
|
stamp = Node.void("stamp")
|
|
|
|
|
stampdict = profile.get_dict("stamp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(stamp)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
stamp.add_child(
|
|
|
|
|
Node.s32_array("stmpcnt", stampdict.get_int_array("stmpcnt", 5))
|
|
|
|
|
)
|
|
|
|
|
stamp.add_child(
|
|
|
|
|
Node.s32_array("tcktcnt", stampdict.get_int_array("tcktcnt", 5))
|
|
|
|
|
)
|
|
|
|
|
stamp.add_child(Node.s64("area", stampdict.get_int("area")))
|
|
|
|
|
stamp.add_child(Node.s64("prfvst", stampdict.get_int("prfvst")))
|
|
|
|
|
stamp.add_child(Node.s32("reserve", stampdict.get_int("reserve")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Unlocks
|
2022-10-15 20:56:30 +02:00
|
|
|
|
released = Node.void("released")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(released)
|
|
|
|
|
|
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type[:5] != "item_":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
itemtype = int(item.type[5:])
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if game_config.get_bool("force_unlock_songs") and itemtype == 0:
|
2019-12-08 22:43:49 +01:00
|
|
|
|
# Don't echo unlocks when we're force unlocking, we'll do it later
|
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
info = Node.void("info")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
released.add_child(info)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
info.add_child(Node.u8("type", itemtype))
|
|
|
|
|
info.add_child(Node.u16("id", item.id))
|
|
|
|
|
info.add_child(Node.u16("param", item.data.get_int("param")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if game_config.get_bool("force_unlock_songs"):
|
2019-12-08 22:43:49 +01:00
|
|
|
|
ids: Dict[int, int] = {}
|
|
|
|
|
songs = self.data.local.music.get_all_songs(self.game, self.version)
|
|
|
|
|
for song in songs:
|
|
|
|
|
if song.id not in ids:
|
|
|
|
|
ids[song.id] = 0
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if song.data.get_int("difficulty") > 0:
|
2019-12-08 22:43:49 +01:00
|
|
|
|
ids[song.id] = ids[song.id] | (1 << song.chart)
|
|
|
|
|
|
|
|
|
|
for songid in ids:
|
|
|
|
|
if ids[songid] == 0:
|
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
info = Node.void("info")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
released.add_child(info)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
info.add_child(Node.u8("type", 0))
|
|
|
|
|
info.add_child(Node.u16("id", songid))
|
|
|
|
|
info.add_child(Node.u16("param", ids[songid]))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Favorite songs
|
2022-10-15 20:56:30 +02:00
|
|
|
|
fav_music_slot = Node.void("fav_music_slot")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(fav_music_slot)
|
|
|
|
|
|
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type != "music":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
slot = Node.void("slot")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
fav_music_slot.add_child(slot)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
slot.add_child(Node.u8("slot_id", item.id))
|
|
|
|
|
slot.add_child(Node.s16("music_id", item.data.get_int("music_id")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Event stuff
|
2022-10-15 20:56:30 +02:00
|
|
|
|
order = Node.void("order")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(order)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
order.add_child(Node.s32("exp", profile.get_int("order_exp")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type != "order":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = Node.void("d")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
order.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data.add_child(Node.s16("order", item.id))
|
|
|
|
|
data.add_child(Node.s16("slt", item.data.get_int("slt")))
|
|
|
|
|
data.add_child(Node.s32("ccnt", item.data.get_int("ccnt")))
|
|
|
|
|
data.add_child(Node.s32("fcnt", item.data.get_int("fcnt")))
|
|
|
|
|
data.add_child(Node.s32("fcnt1", item.data.get_int("fcnt1")))
|
|
|
|
|
data.add_child(Node.s32("prm", item.data.get_int("param")))
|
|
|
|
|
|
|
|
|
|
seedpod = Node.void("seedpod")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(seedpod)
|
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type != "seedpod":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = Node.void("data")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
seedpod.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data.add_child(Node.s16("id", item.id))
|
|
|
|
|
data.add_child(Node.s16("pod", item.data.get_int("pod")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eqpexp = Node.void("eqpexp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(eqpexp)
|
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type[:7] != "eqpexp_":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
stype = int(item.type[7:])
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = Node.void("data")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
eqpexp.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data.add_child(Node.s16("id", item.id))
|
|
|
|
|
data.add_child(Node.s32("exp", item.data.get_int("exp")))
|
|
|
|
|
data.add_child(Node.s16("stype", stype))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eventexp = Node.void("evntexp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(eventexp)
|
|
|
|
|
for item in achievements:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if item.type != "eventexp":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = Node.void("data")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
eventexp.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data.add_child(Node.s16("id", item.id))
|
|
|
|
|
data.add_child(Node.s32("exp", item.data.get_int("exp")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Scores
|
2022-10-15 20:56:30 +02:00
|
|
|
|
record = Node.void("record")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(record)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
record_old = Node.void("record_old")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
pdata.add_child(record_old)
|
|
|
|
|
|
|
|
|
|
for score in scores:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
rec = Node.void("rec")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
record.add_child(rec)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
rec.add_child(Node.s16("mid", score.id))
|
|
|
|
|
rec.add_child(Node.s8("ntgrd", score.chart))
|
|
|
|
|
rec.add_child(Node.s32("pc", score.plays))
|
|
|
|
|
rec.add_child(
|
|
|
|
|
Node.s8(
|
|
|
|
|
"ct",
|
|
|
|
|
self.__db_to_game_clear_type(
|
|
|
|
|
score.data.get_int("clear_type"),
|
|
|
|
|
score.data.get_int("combo_type"),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
rec.add_child(Node.s16("ar", score.data.get_int("achievement_rate")))
|
|
|
|
|
rec.add_child(Node.s16("scr", score.points))
|
|
|
|
|
rec.add_child(Node.s16("cmb", score.data.get_int("combo")))
|
|
|
|
|
rec.add_child(Node.s16("ms", score.data.get_int("miss_count")))
|
|
|
|
|
rec.add_child(Node.s32("bscrt", score.timestamp))
|
|
|
|
|
rec.add_child(
|
|
|
|
|
Node.s32("bart", score.data.get_int("best_achievement_rate_time"))
|
|
|
|
|
)
|
|
|
|
|
rec.add_child(Node.s32("bctt", score.data.get_int("best_clear_type_time")))
|
|
|
|
|
rec.add_child(Node.s32("bmst", score.data.get_int("best_miss_count_time")))
|
|
|
|
|
rec.add_child(Node.s32("time", score.data.get_int("last_played_time")))
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
return root
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
def unformat_profile(
|
|
|
|
|
self, userid: UserID, request: Node, oldprofile: Profile
|
|
|
|
|
) -> Profile:
|
2019-12-08 22:43:49 +01:00
|
|
|
|
game_config = self.get_game_config()
|
2021-09-07 19:56:15 +02:00
|
|
|
|
newprofile = oldprofile.clone()
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
newprofile.replace_int(
|
|
|
|
|
"lid", ID.parse_machine_id(request.child_value("pdata/account/lid"))
|
|
|
|
|
)
|
|
|
|
|
newprofile.replace_str("name", request.child_value("pdata/base/name"))
|
|
|
|
|
newprofile.replace_int("exp", request.child_value("pdata/base/exp"))
|
|
|
|
|
newprofile.replace_int("lvl", request.child_value("pdata/base/lvl"))
|
|
|
|
|
newprofile.replace_int("mg", request.child_value("pdata/base/mg"))
|
|
|
|
|
newprofile.replace_int("ap", request.child_value("pdata/base/ap"))
|
|
|
|
|
newprofile.replace_int_array(
|
|
|
|
|
"hidden_param", 50, request.child_value("pdata/base/hidden_param")
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
configdict = newprofile.get_dict("config")
|
|
|
|
|
config = request.child("pdata/config")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if config:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
configdict.replace_int("msel_bgm", config.child_value("msel_bgm"))
|
|
|
|
|
configdict.replace_int(
|
|
|
|
|
"narrowdown_type", config.child_value("narrowdown_type")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_int("icon_id", config.child_value("icon_id"))
|
|
|
|
|
configdict.replace_int("byword_0", config.child_value("byword_0"))
|
|
|
|
|
configdict.replace_int("byword_1", config.child_value("byword_1"))
|
|
|
|
|
configdict.replace_bool(
|
|
|
|
|
"is_auto_byword_0", config.child_value("is_auto_byword_0")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_bool(
|
|
|
|
|
"is_auto_byword_1", config.child_value("is_auto_byword_1")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_int("mrec_type", config.child_value("mrec_type"))
|
|
|
|
|
configdict.replace_int("tab_sel", config.child_value("tab_sel"))
|
|
|
|
|
configdict.replace_int("card_disp", config.child_value("card_disp"))
|
|
|
|
|
configdict.replace_int(
|
|
|
|
|
"score_tab_disp", config.child_value("score_tab_disp")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_int("last_music_id", config.child_value("last_music_id"))
|
|
|
|
|
configdict.replace_int(
|
|
|
|
|
"last_note_grade", config.child_value("last_note_grade")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_int("sort_type", config.child_value("sort_type"))
|
|
|
|
|
configdict.replace_int(
|
|
|
|
|
"rival_panel_type", config.child_value("rival_panel_type")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_int(
|
|
|
|
|
"random_entry_work", config.child_value("random_entry_work")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_int(
|
|
|
|
|
"folder_lamp_type", config.child_value("folder_lamp_type")
|
|
|
|
|
)
|
|
|
|
|
configdict.replace_bool("is_tweet", config.child_value("is_tweet"))
|
|
|
|
|
configdict.replace_bool(
|
|
|
|
|
"is_link_twitter", config.child_value("is_link_twitter")
|
|
|
|
|
)
|
|
|
|
|
newprofile.replace_dict("config", configdict)
|
|
|
|
|
|
|
|
|
|
customdict = newprofile.get_dict("custom")
|
|
|
|
|
custom = request.child("pdata/custom")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if custom:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
customdict.replace_int("st_shot", custom.child_value("st_shot"))
|
|
|
|
|
customdict.replace_int("st_frame", custom.child_value("st_frame"))
|
|
|
|
|
customdict.replace_int("st_expl", custom.child_value("st_expl"))
|
|
|
|
|
customdict.replace_int("st_bg", custom.child_value("st_bg"))
|
|
|
|
|
customdict.replace_int("st_shot_vol", custom.child_value("st_shot_vol"))
|
|
|
|
|
customdict.replace_int("st_bg_bri", custom.child_value("st_bg_bri"))
|
|
|
|
|
customdict.replace_int("st_obj_size", custom.child_value("st_obj_size"))
|
|
|
|
|
customdict.replace_int("st_jr_gauge", custom.child_value("st_jr_gauge"))
|
|
|
|
|
customdict.replace_int("st_clr_gauge", custom.child_value("st_clr_gauge"))
|
|
|
|
|
customdict.replace_int("st_jdg_disp", custom.child_value("st_jdg_disp"))
|
|
|
|
|
customdict.replace_int("st_tm_disp", custom.child_value("st_tm_disp"))
|
|
|
|
|
customdict.replace_int("st_rnd", custom.child_value("st_rnd"))
|
|
|
|
|
customdict.replace_int_array("schat_0", 9, custom.child_value("schat_0"))
|
|
|
|
|
customdict.replace_int_array("schat_1", 9, custom.child_value("schat_1"))
|
|
|
|
|
customdict.replace_int_array("ichat_0", 6, custom.child_value("ichat_0"))
|
|
|
|
|
customdict.replace_int_array("ichat_1", 6, custom.child_value("ichat_1"))
|
|
|
|
|
newprofile.replace_dict("custom", customdict)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Stamps
|
2022-10-15 20:56:30 +02:00
|
|
|
|
stampdict = newprofile.get_dict("stamp")
|
|
|
|
|
stamp = request.child("pdata/stamp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if stamp:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
stampdict.replace_int_array("stmpcnt", 5, stamp.child_value("stmpcnt"))
|
|
|
|
|
stampdict.replace_int_array("tcktcnt", 5, stamp.child_value("tcktcnt"))
|
|
|
|
|
stampdict.replace_int("area", stamp.child_value("area"))
|
|
|
|
|
stampdict.replace_int("prfvst", stamp.child_value("prfvst"))
|
|
|
|
|
stampdict.replace_int("reserve", stamp.child_value("reserve"))
|
|
|
|
|
newprofile.replace_dict("stamp", stampdict)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Unlockable orders
|
2022-10-15 20:56:30 +02:00
|
|
|
|
newprofile.replace_int("order_exp", request.child_value("pdata/order/exp"))
|
|
|
|
|
order = request.child("pdata/order")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if order:
|
|
|
|
|
for child in order.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "d":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
orderid = child.child_value("order")
|
|
|
|
|
slt = child.child_value("slt")
|
|
|
|
|
ccnt = child.child_value("ccnt")
|
|
|
|
|
fcnt = child.child_value("fcnt")
|
|
|
|
|
fcnt1 = child.child_value("fcnt1")
|
|
|
|
|
param = child.child_value("prm")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
if slt == -1:
|
|
|
|
|
# The game doesn't return valid data for this selection
|
|
|
|
|
# type, so be sure not to accidentally overwrite the
|
|
|
|
|
# finished flags.
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
self.data.local.user.put_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
orderid,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"order",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"slt": slt,
|
|
|
|
|
"ccnt": ccnt,
|
|
|
|
|
"fcnt": fcnt,
|
|
|
|
|
"fcnt1": fcnt1,
|
|
|
|
|
"param": param,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Music unlocks and other stuff
|
2022-10-15 20:56:30 +02:00
|
|
|
|
released = request.child("pdata/released")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if released:
|
|
|
|
|
for child in released.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "info":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
item_id = child.child_value("id")
|
|
|
|
|
item_type = child.child_value("type")
|
|
|
|
|
param = child.child_value("param")
|
|
|
|
|
if game_config.get_bool("force_unlock_songs") and item_type == 0:
|
2019-12-08 22:43:49 +01:00
|
|
|
|
# Don't save unlocks when we're force unlocking
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
self.data.local.user.put_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
item_id,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
f"item_{item_type}",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"param": param,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Favorite music
|
2022-10-15 20:56:30 +02:00
|
|
|
|
fav_music_slot = request.child("pdata/fav_music_slot")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if fav_music_slot:
|
|
|
|
|
for child in fav_music_slot.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "slot":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
slot_id = child.child_value("slot_id")
|
|
|
|
|
music_id = child.child_value("music_id")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if music_id == -1:
|
|
|
|
|
# Delete this favorite
|
|
|
|
|
self.data.local.user.destroy_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
slot_id,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"music",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
# Add/update this favorite
|
|
|
|
|
self.data.local.user.put_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
slot_id,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"music",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"music_id": music_id,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Event stuff
|
2022-10-15 20:56:30 +02:00
|
|
|
|
seedpod = request.child("pdata/seedpod")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if seedpod:
|
|
|
|
|
for child in seedpod.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "data":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
seedpod_id = child.child_value("id")
|
|
|
|
|
seedpod_pod = child.child_value("pod")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
self.data.local.user.put_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
seedpod_id,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"seedpod",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"pod": seedpod_pod,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eventexp = request.child("pdata/evntexp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if eventexp:
|
|
|
|
|
for child in eventexp.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "data":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eventexp_id = child.child_value("id")
|
|
|
|
|
eventexp_exp = child.child_value("exp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Experience is additive, so load it first and add the updated amount
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = (
|
|
|
|
|
self.data.local.user.get_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
eventexp_id,
|
|
|
|
|
"eventexp",
|
|
|
|
|
)
|
|
|
|
|
or ValidatedDict()
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
self.data.local.user.put_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
eventexp_id,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"eventexp",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"exp": data.get_int("exp") + eventexp_exp,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eqpexp = request.child("pdata/eqpexp")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if eqpexp:
|
|
|
|
|
for child in eqpexp.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "data":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
eqpexp_id = child.child_value("id")
|
|
|
|
|
eqpexp_exp = child.child_value("exp")
|
|
|
|
|
eqpexp_stype = child.child_value("stype")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
# Experience is additive, so load it first and add the updated amount
|
2022-10-15 20:56:30 +02:00
|
|
|
|
data = (
|
|
|
|
|
self.data.local.user.get_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
eqpexp_id,
|
|
|
|
|
f"eqpexp_{eqpexp_stype}",
|
|
|
|
|
)
|
|
|
|
|
or ValidatedDict()
|
|
|
|
|
)
|
2019-12-08 22:43:49 +01:00
|
|
|
|
|
|
|
|
|
self.data.local.user.put_achievement(
|
|
|
|
|
self.game,
|
|
|
|
|
self.version,
|
|
|
|
|
userid,
|
|
|
|
|
eqpexp_id,
|
2022-10-15 20:56:30 +02:00
|
|
|
|
f"eqpexp_{eqpexp_stype}",
|
2019-12-08 22:43:49 +01:00
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
|
"exp": data.get_int("exp") + eqpexp_exp,
|
2019-12-08 22:43:49 +01:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Grab any new records set during this play session
|
2022-10-15 20:56:30 +02:00
|
|
|
|
songplays = request.child("pdata/stglog")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if songplays:
|
|
|
|
|
for child in songplays.children:
|
2022-10-15 20:56:30 +02:00
|
|
|
|
if child.name != "log":
|
2019-12-08 22:43:49 +01:00
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
songid = child.child_value("mid")
|
|
|
|
|
chart = child.child_value("ng")
|
|
|
|
|
clear_type = child.child_value("ct")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
if songid == 0 and chart == 0 and clear_type == -1:
|
|
|
|
|
# Dummy song save during profile create
|
|
|
|
|
continue
|
|
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
|
points = child.child_value("sc")
|
|
|
|
|
achievement_rate = child.child_value("ar")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
clear_type, combo_type = self.__game_to_db_clear_type(clear_type)
|
2022-10-15 20:56:30 +02:00
|
|
|
|
combo = child.child_value("cmb")
|
|
|
|
|
miss_count = child.child_value("jt_ms")
|
2019-12-08 22:43:49 +01:00
|
|
|
|
self.update_score(
|
|
|
|
|
userid,
|
|
|
|
|
songid,
|
|
|
|
|
chart,
|
|
|
|
|
points,
|
|
|
|
|
achievement_rate,
|
|
|
|
|
clear_type,
|
|
|
|
|
combo_type,
|
|
|
|
|
miss_count,
|
|
|
|
|
combo=combo,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Keep track of play statistics
|
|
|
|
|
self.update_play_statistics(userid)
|
|
|
|
|
|
|
|
|
|
return newprofile
|