1
0
mirror of synced 2024-09-23 19:08:21 +02:00

Make black do 120 character lines instead of 80.

This commit is contained in:
Jennifer Taylor 2024-01-02 02:46:24 +00:00
parent d3413715f3
commit f6a9aa69fd
211 changed files with 3914 additions and 12437 deletions

View File

@ -91,9 +91,7 @@ def jsonify(func: Callable) -> Callable:
@app.errorhandler(Exception)
def server_exception(exception: Any) -> Response:
stack = "".join(
traceback.format_exception(type(exception), exception, exception.__traceback__)
)
stack = "".join(traceback.format_exception(type(exception), exception, exception.__traceback__))
print(stack)
try:
g.data.local.network.put_event(

View File

@ -14,15 +14,11 @@ class BaseObject:
various fetch versions.
"""
def __init__(
self, data: Data, game: GameConstants, version: int, omnimix: bool
) -> None:
def __init__(self, data: Data, game: GameConstants, version: int, omnimix: bool) -> None:
self.data = data
self.game = game
self.version = version
self.omnimix = omnimix
def fetch_v1(
self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]
) -> Any:
def fetch_v1(self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]) -> Any:
raise APIException("Object fetch not supported for this version!")

View File

@ -65,9 +65,7 @@ class CatalogObject(BaseObject):
}
return {
"difficulty": song.data.get_int("difficulty"),
"category": categorymapping.get(
song.data.get_int("version", defaultcategory), "1"
),
"category": categorymapping.get(song.data.get_int("version", defaultcategory), "1"),
"bpm_min": song.data.get_int("bpm_min"),
"bpm_max": song.data.get_int("bpm_max"),
}
@ -228,9 +226,7 @@ class CatalogObject(BaseObject):
else:
return self.version
def fetch_v1(
self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]
) -> Dict[str, List[Dict[str, Any]]]:
def fetch_v1(self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]) -> Dict[str, List[Dict[str, Any]]]:
# Verify IDs
if idtype != APIConstants.ID_TYPE_SERVER:
raise APIException(
@ -240,10 +236,7 @@ class CatalogObject(BaseObject):
# Fetch the songs
songs = self.data.local.music.get_all_songs(self.game, self.music_version)
if (
self.game == GameConstants.JUBEAT
and self.version == VersionConstants.JUBEAT_CLAN
):
if self.game == GameConstants.JUBEAT and self.version == VersionConstants.JUBEAT_CLAN:
# There's always a special case. We don't store all music IDs since those in
# the range of 80000301-80000347 are actually the same song, but copy-pasted
# for different prefectures and slightly different charts. So, we need to copy

View File

@ -74,15 +74,11 @@ class ProfileObject(BaseObject):
return base
def fetch_v1(
self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]
) -> List[Dict[str, Any]]:
def fetch_v1(self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]) -> List[Dict[str, Any]]:
# Fetch the profiles
profiles: List[Tuple[UserID, Profile]] = []
if idtype == APIConstants.ID_TYPE_SERVER:
profiles.extend(
self.data.local.user.get_all_profiles(self.game, self.version)
)
profiles.extend(self.data.local.user.get_all_profiles(self.game, self.version))
elif idtype == APIConstants.ID_TYPE_SONG:
raise APIException(
"Unsupported ID for lookup!",
@ -108,9 +104,7 @@ class ProfileObject(BaseObject):
# in the case that we returned scores for a user that doesn't have a
# profile on a particular version. We allow that on this network, so in
# order to not break remote networks, try our best to return any profile.
profile = self.data.local.user.get_any_profile(
self.game, self.version, userid
)
profile = self.data.local.user.get_any_profile(self.game, self.version, userid)
if profile is not None:
profiles.append((userid, profile))
else:

View File

@ -235,9 +235,7 @@ class RecordsObject(BaseObject):
else:
return self.version
def fetch_v1(
self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]
) -> List[Dict[str, Any]]:
def fetch_v1(self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]) -> List[Dict[str, Any]]:
since = params.get("since")
until = params.get("until")
@ -247,9 +245,7 @@ class RecordsObject(BaseObject):
# Because of the way this query works, we can't apply since/until to it directly.
# If we did, it would miss higher scores earned before since or after until, and
# incorrectly report records.
records.extend(
self.data.local.music.get_all_records(self.game, self.music_version)
)
records.extend(self.data.local.music.get_all_records(self.game, self.music_version))
elif idtype == APIConstants.ID_TYPE_SONG:
if len(ids) == 1:
songid = int(ids[0])
@ -273,9 +269,7 @@ class RecordsObject(BaseObject):
cardid = ids[2]
userid = self.data.local.user.from_cardid(cardid)
if userid is not None:
score = self.data.local.music.get_score(
self.game, self.music_version, userid, songid, chart
)
score = self.data.local.music.get_score(self.game, self.music_version, userid, songid, chart)
if score is not None:
records.append((userid, score))
elif idtype == APIConstants.ID_TYPE_CARD:

View File

@ -17,9 +17,7 @@ class StatisticsObject(BaseObject):
"combos": stats.get("combos", -1),
}
def __format_user_statistics(
self, cardids: List[str], stats: Dict[str, Any]
) -> Dict[str, Any]:
def __format_user_statistics(self, cardids: List[str], stats: Dict[str, Any]) -> Dict[str, Any]:
base = self.__format_statistics(stats)
base["cards"] = cardids
return base
@ -48,20 +46,11 @@ class StatisticsObject(BaseObject):
}:
return True
if self.game == GameConstants.IIDX:
return (
attempt.data.get_int("clear_status")
!= DBConstants.IIDX_CLEAR_STATUS_NO_PLAY
)
return attempt.data.get_int("clear_status") != DBConstants.IIDX_CLEAR_STATUS_NO_PLAY
if self.game == GameConstants.REFLEC_BEAT:
return (
attempt.data.get_int("clear_type")
!= DBConstants.REFLEC_BEAT_CLEAR_TYPE_NO_PLAY
)
return attempt.data.get_int("clear_type") != DBConstants.REFLEC_BEAT_CLEAR_TYPE_NO_PLAY
if self.game == GameConstants.SDVX:
return (
attempt.data.get_int("clear_type")
!= DBConstants.SDVX_CLEAR_TYPE_NO_PLAY
)
return attempt.data.get_int("clear_type") != DBConstants.SDVX_CLEAR_TYPE_NO_PLAY
return False
@ -72,17 +61,11 @@ class StatisticsObject(BaseObject):
if self.game == GameConstants.DDR:
return attempt.data.get_int("rank") != DBConstants.DDR_RANK_E
if self.game == GameConstants.IIDX:
return (
attempt.data.get_int("clear_status")
!= DBConstants.IIDX_CLEAR_STATUS_FAILED
)
return attempt.data.get_int("clear_status") != DBConstants.IIDX_CLEAR_STATUS_FAILED
if self.game == GameConstants.JUBEAT:
return attempt.data.get_int("medal") != DBConstants.JUBEAT_PLAY_MEDAL_FAILED
if self.game == GameConstants.MUSECA:
return (
attempt.data.get_int("clear_type")
!= DBConstants.MUSECA_CLEAR_TYPE_FAILED
)
return attempt.data.get_int("clear_type") != DBConstants.MUSECA_CLEAR_TYPE_FAILED
if self.game == GameConstants.POPN_MUSIC:
return attempt.data.get_int("medal") not in [
DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_FAILED,
@ -90,14 +73,9 @@ class StatisticsObject(BaseObject):
DBConstants.POPN_MUSIC_PLAY_MEDAL_STAR_FAILED,
]
if self.game == GameConstants.REFLEC_BEAT:
return (
attempt.data.get_int("clear_type")
!= DBConstants.REFLEC_BEAT_CLEAR_TYPE_FAILED
)
return attempt.data.get_int("clear_type") != DBConstants.REFLEC_BEAT_CLEAR_TYPE_FAILED
if self.game == GameConstants.SDVX:
return attempt.data.get_int(
"grade"
) != DBConstants.SDVX_GRADE_NO_PLAY and attempt.data.get_int(
return attempt.data.get_int("grade") != DBConstants.SDVX_GRADE_NO_PLAY and attempt.data.get_int(
"clear_type"
) not in [
DBConstants.SDVX_CLEAR_TYPE_NO_PLAY,
@ -113,10 +91,7 @@ class StatisticsObject(BaseObject):
if self.game == GameConstants.DDR:
return attempt.data.get_int("halo") != DBConstants.DDR_HALO_NONE
if self.game == GameConstants.IIDX:
return (
attempt.data.get_int("clear_status")
== DBConstants.IIDX_CLEAR_STATUS_FULL_COMBO
)
return attempt.data.get_int("clear_status") == DBConstants.IIDX_CLEAR_STATUS_FULL_COMBO
if self.game == GameConstants.JUBEAT:
return attempt.data.get_int("medal") in [
DBConstants.JUBEAT_PLAY_MEDAL_FULL_COMBO,
@ -124,10 +99,7 @@ class StatisticsObject(BaseObject):
DBConstants.JUBEAT_PLAY_MEDAL_EXCELLENT,
]
if self.game == GameConstants.MUSECA:
return (
attempt.data.get_int("clear_type")
== DBConstants.MUSECA_CLEAR_TYPE_FULL_COMBO
)
return attempt.data.get_int("clear_type") == DBConstants.MUSECA_CLEAR_TYPE_FULL_COMBO
if self.game == GameConstants.POPN_MUSIC:
return attempt.data.get_int("medal") in [
DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_FULL_COMBO,
@ -213,20 +185,13 @@ class StatisticsObject(BaseObject):
return retval
def fetch_v1(
self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]
) -> List[Dict[str, Any]]:
def fetch_v1(self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]) -> List[Dict[str, Any]]:
retval: List[Dict[str, Any]] = []
# Fetch the attempts
if idtype == APIConstants.ID_TYPE_SERVER:
retval = self.__aggregate_global(
[
attempt[1]
for attempt in self.data.local.music.get_all_attempts(
self.game, self.music_version
)
]
[attempt[1] for attempt in self.data.local.music.get_all_attempts(self.game, self.music_version)]
)
elif idtype == APIConstants.ID_TYPE_SONG:
if len(ids) == 1:
@ -272,9 +237,7 @@ class StatisticsObject(BaseObject):
id_to_cards[userid] = self.data.local.user.get_cards(userid)
attempts.extend(
self.data.local.music.get_all_attempts(
self.game, self.music_version, userid=userid
)
self.data.local.music.get_all_attempts(self.game, self.music_version, userid=userid)
)
retval = self.__aggregate_local(id_to_cards, attempts)
else:

View File

@ -226,9 +226,7 @@ class Base(ABC):
return Base(data, config, model)
else:
# Return the registered module providing this game
return cls.__registered_games[model.gamecode].create(
data, config, model, parentmodel=parentmodel
)
return cls.__registered_games[model.gamecode].create(data, config, model, parentmodel=parentmodel)
@classmethod
def register(cls, gamecode: str, handler: Type[Factory]) -> None:
@ -244,9 +242,7 @@ class Base(ABC):
cls.__registered_handlers.add(handler)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Config
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Config) -> List[Tuple[str, Dict[str, Any]]]:
"""
Run any out-of-band scheduled work that is applicable to this game.
"""
@ -297,10 +293,7 @@ class Base(ABC):
Returns:
True if the profile exists, False if not.
"""
return (
self.data.local.user.get_profile(self.game, self.version, userid)
is not None
)
return self.data.local.user.get_profile(self.game, self.version, userid) is not None
def get_profile(self, userid: UserID) -> Optional[Profile]:
"""
@ -354,15 +347,11 @@ class Base(ABC):
or an empty dictionary if nothing was found.
"""
userids = list(set(userids))
profiles = self.data.remote.user.get_any_profiles(
self.game, self.version, userids
)
profiles = self.data.remote.user.get_any_profiles(self.game, self.version, userids)
return [
(
userid,
profile
if profile is not None
else Profile(self.game, self.version, "", 0),
profile if profile is not None else Profile(self.game, self.version, "", 0),
)
for (userid, profile) in profiles
]
@ -379,9 +368,7 @@ class Base(ABC):
raise Exception("Trying to save a remote profile locally!")
self.data.local.user.put_profile(self.game, self.version, userid, profile)
def update_play_statistics(
self, userid: UserID, stats: Optional[PlayStatistics] = None
) -> None:
def update_play_statistics(self, userid: UserID, stats: Optional[PlayStatistics] = None) -> None:
"""
Given a user ID, calculate new play statistics.
@ -397,9 +384,7 @@ class Base(ABC):
# We store the play statistics in a series-wide settings blob so its available
# across all game versions, since it isn't game-specific.
settings = self.data.local.game.get_settings(
self.game, userid
) or ValidatedDict({})
settings = self.data.local.game.get_settings(self.game, userid) or ValidatedDict({})
if stats is not None:
for key in stats:
@ -418,9 +403,7 @@ class Base(ABC):
settings[key] = stats[key]
settings.replace_int("total_plays", settings.get_int("total_plays") + 1)
settings.replace_int(
"first_play_timestamp", settings.get_int("first_play_timestamp", Time.now())
)
settings.replace_int("first_play_timestamp", settings.get_int("first_play_timestamp", Time.now()))
settings.replace_int("last_play_timestamp", Time.now())
last_play_date = settings.get_int_array("last_play_date", 3)
@ -445,9 +428,7 @@ class Base(ABC):
and last_play_date[2] == yesterday_play_date[2]
):
# We played yesterday, add one to consecutive days
settings.replace_int(
"consecutive_days", settings.get_int("consecutive_days") + 1
)
settings.replace_int("consecutive_days", settings.get_int("consecutive_days") + 1)
else:
# We haven't played yesterday, so we have only one consecutive day.
settings.replace_int("consecutive_days", 1)
@ -490,13 +471,9 @@ class Base(ABC):
def get_machine_region(self) -> int:
arcade = self.get_arcade()
if arcade is None:
return RegionConstants.db_to_game_region(
self.requires_extended_regions, self.config.server.region
)
return RegionConstants.db_to_game_region(self.requires_extended_regions, self.config.server.region)
else:
return RegionConstants.db_to_game_region(
self.requires_extended_regions, arcade.region
)
return RegionConstants.db_to_game_region(self.requires_extended_regions, arcade.region)
def get_game_config(self) -> ValidatedDict:
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
@ -504,9 +481,7 @@ class Base(ABC):
# If this machine belongs to an arcade, use its settings. If the settings aren't present,
# default to the game's defaults.
if machine.arcade is not None:
settings = self.data.local.machine.get_settings(
machine.arcade, self.game, self.version, "game_config"
)
settings = self.data.local.machine.get_settings(machine.arcade, self.game, self.version, "game_config")
if settings is None:
settings = ValidatedDict()
return settings
@ -582,11 +557,7 @@ class Base(ABC):
total_days = settings.get_int("total_days", 1)
consecutive_days = settings.get_int("consecutive_days", 1)
else:
if (
last_play_date[0] != 0
and last_play_date[1] != 0
and last_play_date[2] != 0
):
if last_play_date[0] != 0 and last_play_date[1] != 0 and last_play_date[2] != 0:
# We've played before but not today, so the total days is
# the stored count plus today.
total_days = settings.get_int("total_days") + 1

View File

@ -98,9 +98,7 @@ class TheStarBishiBashi(
data = data.replace(";", "#;")
return data
def __generate_setting(
self, key: str, values: Union[int, str, Sequence[int], Sequence[str]]
) -> str:
def __generate_setting(self, key: str, values: Union[int, str, Sequence[int], Sequence[str]]) -> str:
if isinstance(values, Iterable) and not isinstance(values, str):
values = ",".join(self.__escape_string(x) for x in values)
else:
@ -184,9 +182,7 @@ class TheStarBishiBashi(
enable_dlc_levels = game_config.get_bool("enable_dlc_levels")
if enable_dlc_levels:
settings["MAL"] = 1
force_unlock_characters = game_config.get_bool(
"force_unlock_eamuse_characters"
)
force_unlock_characters = game_config.get_bool("force_unlock_eamuse_characters")
if force_unlock_characters:
settings["ALL"] = 1
scrolling_message = game_config.get_str("big_announcement")
@ -197,9 +193,7 @@ class TheStarBishiBashi(
settings["IM"] = bb_message
# Generate system message
settings_str = ";".join(
self.__generate_setting(key, vals) for key, vals in settings.items()
)
settings_str = ";".join(self.__generate_setting(key, vals) for key, vals in settings.items())
# Send it to the client, making sure to inform the client that it was valid.
root.add_child(
@ -223,9 +217,7 @@ class TheStarBishiBashi(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is None:
root = Node.void("playerdata")
root.add_child(
Node.s32("result", 1)
) # Unclear if this is the right thing to do here.
root.add_child(Node.s32("result", 1)) # Unclear if this is the right thing to do here.
return root
# Extract new profile info from old profile
@ -258,14 +250,10 @@ class TheStarBishiBashi(
return self.format_profile(userid, profiletype, profile)
else:
root = Node.void("playerdata")
root.add_child(
Node.s32("result", 1)
) # Unclear if this is the right thing to do here.
root.add_child(Node.s32("result", 1)) # Unclear if this is the right thing to do here.
return root
def format_profile(
self, userid: UserID, profiletype: str, profile: Profile
) -> Node:
def format_profile(self, userid: UserID, profiletype: str, profile: Profile) -> Node:
root = Node.void("playerdata")
root.add_child(Node.s32("result", 0))
player = Node.void("player")
@ -342,9 +330,7 @@ class TheStarBishiBashi(
player.add_child(Node.u32("record_num", records))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile, is_new: bool
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile, is_new: bool) -> Profile:
# Profile save request, data values are base64 encoded.
# d is a CSV, and bin1 is binary data.
newprofile = oldprofile.clone()

View File

@ -43,10 +43,7 @@ class CardManagerHandler(Base):
refid = self.data.local.user.get_refid(self.game, self.version, userid)
paseli_enabled = self.supports_paseli and self.config.paseli.enabled
newflag = (
self.data.remote.user.get_any_profile(self.game, self.version, userid)
is None
)
newflag = self.data.remote.user.get_any_profile(self.game, self.version, userid) is None
root = Node.void("cardmng")
root.set_attribute("refid", refid)
@ -81,9 +78,7 @@ class CardManagerHandler(Base):
else:
valid = False
root = Node.void("cardmng")
root.set_attribute(
"status", str(Status.SUCCESS if valid else Status.INVALID_PIN)
)
root.set_attribute("status", str(Status.SUCCESS if valid else Status.INVALID_PIN))
return root
def handle_cardmng_getrefid_request(self, request: Node) -> Node:

View File

@ -177,9 +177,7 @@ class CoreHandler(Base):
root = Node.void("facility")
root.set_attribute("expire", "600")
location = Node.void("location")
location.add_child(
Node.string("id", ID.format_machine_id(machine.id, region=country))
)
location.add_child(Node.string("id", ID.format_machine_id(machine.id, region=country)))
location.add_child(Node.string("country", country))
location.add_child(Node.string("region", regionstr))
location.add_child(Node.string("name", machine.name))
@ -213,21 +211,11 @@ class CoreHandler(Base):
eapass.add_child(Node.u16("valid", 365))
url = Node.void("url")
url.add_child(
Node.string("eapass", self.config.server.uri or "www.ea-pass.konami.net")
)
url.add_child(
Node.string("arcadefan", self.config.server.uri or "www.konami.jp/am")
)
url.add_child(
Node.string("konaminetdx", self.config.server.uri or "http://am.573.jp")
)
url.add_child(
Node.string("konamiid", self.config.server.uri or "https://id.konami.net")
)
url.add_child(
Node.string("eagate", self.config.server.uri or "http://eagate.573.jp")
)
url.add_child(Node.string("eapass", self.config.server.uri or "www.ea-pass.konami.net"))
url.add_child(Node.string("arcadefan", self.config.server.uri or "www.konami.jp/am"))
url.add_child(Node.string("konaminetdx", self.config.server.uri or "http://am.573.jp"))
url.add_child(Node.string("konamiid", self.config.server.uri or "https://id.konami.net"))
url.add_child(Node.string("eagate", self.config.server.uri or "http://eagate.573.jp"))
share.add_child(eacoin)
share.add_child(url)

View File

@ -65,9 +65,7 @@ class PASELIHandler(Base):
# enabled, so there's no way to find a balance.
balance = 0
else:
balance = self.data.local.user.get_balance(
userid, self.config.machine.arcade
)
balance = self.data.local.user.get_balance(userid, self.config.machine.arcade)
root.add_child(Node.s16("sequence", 0))
root.add_child(Node.u8("acstatus", 0))
@ -158,17 +156,13 @@ class PASELIHandler(Base):
else:
# Look up the new balance based on this delta. If there isn't enough,
# we will end up returning None here and exit without performing.
balance = self.data.local.user.update_balance(
userid, self.config.machine.arcade, -payment
)
balance = self.data.local.user.update_balance(userid, self.config.machine.arcade, -payment)
if balance is None:
print("Not enough balance for eacoin consume request")
return make_resp(
1,
self.data.local.user.get_balance(
userid, self.config.machine.arcade
),
self.data.local.user.get_balance(userid, self.config.machine.arcade),
)
else:
self.data.local.network.put_event(
@ -253,16 +247,13 @@ class PASELIHandler(Base):
end_of_week = beginning_of_today
beginning_of_week = end_of_week - Time.SECONDS_IN_WEEK
topic.add_child(
Node.string("sumfrom", Time.format(beginning_of_week, date_format))
)
topic.add_child(Node.string("sumfrom", Time.format(beginning_of_week, date_format)))
topic.add_child(Node.string("sumto", Time.format(end_of_week, date_format)))
today_total = sum(
[
-event.data.get_int("delta")
for event in events
if event.timestamp >= beginning_of_today
and event.timestamp < end_of_today
if event.timestamp >= beginning_of_today and event.timestamp < end_of_today
]
)
@ -270,15 +261,13 @@ class PASELIHandler(Base):
[
-event.data.get_int("delta")
for event in events
if event.timestamp >= beginning_of_today
and event.timestamp < end_of_today
if event.timestamp >= beginning_of_today and event.timestamp < end_of_today
]
)
week_txns = [
-event.data.get_int("delta")
for event in events
if event.timestamp >= beginning_of_week
and event.timestamp < end_of_week
if event.timestamp >= beginning_of_week and event.timestamp < end_of_week
]
week_total = sum(week_txns)
if len(week_txns) > 0:
@ -298,8 +287,7 @@ class PASELIHandler(Base):
[
-event.data.get_int("delta")
for event in events
if event.timestamp >= start_of_day
and event.timestamp < end_of_day
if event.timestamp >= start_of_day and event.timestamp < end_of_day
]
)
)
@ -317,14 +305,10 @@ class PASELIHandler(Base):
topic.add_child(
Node.string(
"sumfrom",
Time.format(
end_of_52_weeks - (52 * Time.SECONDS_IN_WEEK), date_format
),
Time.format(end_of_52_weeks - (52 * Time.SECONDS_IN_WEEK), date_format),
)
)
topic.add_child(
Node.string("sumto", Time.format(end_of_52_weeks, date_format))
)
topic.add_child(Node.string("sumto", Time.format(end_of_52_weeks, date_format)))
# We index backwards, where index 0 = the first week back, 1 = the next week back after that, etc...
items = []
@ -337,8 +321,7 @@ class PASELIHandler(Base):
[
-event.data.get_int("delta")
for event in events
if event.timestamp >= beginning_of_range
and event.timestamp < end_of_range
if event.timestamp >= beginning_of_range and event.timestamp < end_of_range
]
)
)
@ -366,9 +349,7 @@ class PASELIHandler(Base):
hours = [0] * 24
for event in events:
event_hour = int(
(event.timestamp % Time.SECONDS_IN_DAY) / Time.SECONDS_IN_HOUR
)
event_hour = int((event.timestamp % Time.SECONDS_IN_DAY) / Time.SECONDS_IN_HOUR)
hours[event_hour] = hours[event_hour] - event.data.get_int("delta")
if event.timestamp < start_ts:
start_ts = event.timestamp
@ -399,15 +380,11 @@ class PASELIHandler(Base):
item = Node.void("item")
history.add_child(item)
item.add_child(
Node.string("date", Time.format(event.timestamp, time_format))
)
item.add_child(Node.string("date", Time.format(event.timestamp, time_format)))
item.add_child(Node.s32("consume", -event.data.get_int("delta")))
item.add_child(Node.s32("service", -event.data.get_int("service")))
item.add_child(Node.string("cardtype", ""))
item.add_child(
Node.string("cardno", " " * self.paseli_padding + card_no)
)
item.add_child(Node.string("cardno", " " * self.paseli_padding + card_no))
item.add_child(Node.string("title", ""))
item.add_child(Node.string("systemid", ""))
@ -417,9 +394,7 @@ class PASELIHandler(Base):
last_month = Time.timestamp_from_date(year, month - 1)
month_before = Time.timestamp_from_date(year, month - 2)
topic.add_child(
Node.string("sumfrom", Time.format(month_before, date_format))
)
topic.add_child(Node.string("sumfrom", Time.format(month_before, date_format)))
topic.add_child(Node.string("sumto", Time.format(this_month, date_format)))
for start, end in [(month_before, last_month), (last_month, this_month)]:
@ -439,8 +414,7 @@ class PASELIHandler(Base):
[
-event.data.get_int("delta")
for event in events
if event.timestamp >= begin_ts
and event.timestamp < end_ts
if event.timestamp >= begin_ts and event.timestamp < end_ts
]
)
)

View File

@ -127,18 +127,14 @@ class DDRBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("game")
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
"""
Base handler for a score list. Given a userid, profile and a score list,
return a Node representing a score list. Should be overridden.
"""
return Node.void("game")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -164,9 +160,7 @@ class DDRBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Now, return it
return self.format_profile(userid, profile)
def new_profile_by_refid(
self, refid: Optional[str], name: Optional[str], area: Optional[int]
) -> None:
def new_profile_by_refid(self, refid: Optional[str], name: Optional[str], area: Optional[int]) -> None:
"""
Given a RefID and a name/area, create a new profile.
"""

View File

@ -63,10 +63,7 @@ class DDRGameHiscoreHandler(DDRBase):
sortedrecords[score.id] = {}
sortedrecords[score.id][score.chart] = (userid, score)
missing_profiles.append(userid)
users = {
userid: profile
for (userid, profile) in self.get_any_profiles(missing_profiles)
}
users = {userid: profile for (userid, profile) in self.get_any_profiles(missing_profiles)}
game = Node.void("game")
for song in sortedrecords:
@ -90,11 +87,7 @@ class DDRGameHiscoreHandler(DDRBase):
typenode.add_child(Node.string("name", users[userid].get_str("name")))
typenode.add_child(Node.u32("score", score.points))
typenode.add_child(
Node.u16(
"area", users[userid].get_int("area", self.get_machine_region())
)
)
typenode.add_child(Node.u16("area", users[userid].get_int("area", self.get_machine_region())))
typenode.add_child(Node.u8("rank", gamerank))
typenode.add_child(Node.u8("combo_type", combo_type))
typenode.add_child(Node.u32("code", users[userid].extid))
@ -109,16 +102,12 @@ class DDRGameAreaHiscoreHandler(DDRBase):
# First, get all users that are in the current shop's area
area_users = {
uid: prof
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)
if prof.get_int("area", self.get_machine_region()) == shop_area
}
# Second, look up records belonging only to those users
records = self.data.local.music.get_all_records(
self.game, self.music_version, userlist=list(area_users.keys())
)
records = self.data.local.music.get_all_records(self.game, self.music_version, userlist=list(area_users.keys()))
# Now, do the same lazy thing as 'hiscore' because I don't want
# to think about how to change this knowing that we only pulled
@ -137,10 +126,7 @@ class DDRGameAreaHiscoreHandler(DDRBase):
for chart in area_records[song]:
userid, score = area_records[song][chart]
if (
area_users[userid].get_int("area", self.get_machine_region())
!= shop_area
):
if area_users[userid].get_int("area", self.get_machine_region()) != shop_area:
# Don't return this, this user isn't in this area
continue
try:
@ -155,9 +141,7 @@ class DDRGameAreaHiscoreHandler(DDRBase):
music.add_child(typenode)
typenode.set_attribute("diff", str(gamechart))
typenode.add_child(
Node.string("name", area_users[userid].get_str("name"))
)
typenode.add_child(Node.string("name", area_users[userid].get_str("name")))
typenode.add_child(Node.u32("score", score.points))
typenode.add_child(
Node.u16(
@ -309,9 +293,7 @@ class DDRGameOldHandler(DDRBase):
oldprofile = previous_version.get_profile(userid)
if oldprofile is not None:
game.set_attribute("name", oldprofile.get_str("name"))
game.set_attribute(
"area", str(oldprofile.get_int("area", self.get_machine_region()))
)
game.set_attribute("area", str(oldprofile.get_int("area", self.get_machine_region())))
return game
@ -361,9 +343,7 @@ class DDRGameFriendHandler(DDRBase):
game.set_attribute("data", "1")
game.add_child(Node.u32("code", friend.extid))
game.add_child(Node.string("name", friend.get_str("name")))
game.add_child(
Node.u8("area", friend.get_int("area", self.get_machine_region()))
)
game.add_child(Node.u8("area", friend.get_int("area", self.get_machine_region())))
game.add_child(Node.u32("exp", play_stats.get_int("exp")))
game.add_child(Node.u32("star", friend.get_int("star")))
@ -421,9 +401,7 @@ class DDRGameLoadCourseHandler(DDRBase):
coursedata = [0] * 3200
if userid is not None:
for course in self.data.local.user.get_achievements(
self.game, self.version, userid
):
for course in self.data.local.user.get_achievements(self.game, self.version, userid):
if course.type != "course":
continue
@ -438,9 +416,7 @@ class DDRGameLoadCourseHandler(DDRBase):
coursedata[index + 0] = int(course.data.get_int("score") / 10000)
coursedata[index + 1] = course.data.get_int("score") % 10000
coursedata[index + 2] = course.data.get_int("combo")
coursedata[index + 3] = self.db_to_game_rank(
course.data.get_int("rank")
)
coursedata[index + 3] = self.db_to_game_rank(course.data.get_int("rank"))
coursedata[index + 5] = course.data.get_int("stage")
coursedata[index + 6] = course.data.get_int("combo_type")

View File

@ -171,9 +171,7 @@ class DDR2013(
flag.set_attribute("area", str(self.get_machine_region()))
flag.set_attribute("is_final", "1")
hit_chart = self.data.local.music.get_hit_chart(
self.game, self.music_version, self.GAME_MAX_SONGS
)
hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS)
counts_by_reflink = [0] * self.GAME_MAX_SONGS
for reflink, plays in hit_chart:
if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
@ -194,9 +192,7 @@ class DDR2013(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
scores = []
@ -284,14 +280,10 @@ class DDR2013(
root.add_child(Node.string("seq", ""))
root.add_child(Node.u32("code", profile.extid))
root.add_child(Node.string("name", profile.get_str("name")))
root.add_child(
Node.u8("area", profile.get_int("area", self.get_machine_region()))
)
root.add_child(Node.u8("area", profile.get_int("area", self.get_machine_region())))
root.add_child(Node.u32("cnt_s", play_stats.get_int("single_plays")))
root.add_child(Node.u32("cnt_d", play_stats.get_int("double_plays")))
root.add_child(
Node.u32("cnt_b", play_stats.get_int("battle_plays"))
) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_b", play_stats.get_int("battle_plays"))) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_m0", play_stats.get_int("cnt_m0")))
root.add_child(Node.u32("cnt_m1", play_stats.get_int("cnt_m1")))
root.add_child(Node.u32("cnt_m2", play_stats.get_int("cnt_m2")))
@ -309,11 +301,7 @@ class DDR2013(
chara = Node.void("chara")
root.add_child(chara)
chara.set_attribute("my", str(profile.get_int("chara", 30)))
root.add_child(
Node.u16_array(
"chara_opt", profile.get_int_array("chara_opt", 96, [208] * 96)
)
)
root.add_child(Node.u16_array("chara_opt", profile.get_int_array("chara_opt", 96, [208] * 96)))
# Drill rankings
if "title_gr" in profile:
@ -361,9 +349,7 @@ class DDR2013(
last.set_attribute("rival1", str(lastdict.get_int("rival1", -1)))
last.set_attribute("rival2", str(lastdict.get_int("rival2", -1)))
last.set_attribute("rival3", str(lastdict.get_int("rival3", -1)))
last.set_attribute(
"fri", str(lastdict.get_int("rival1", -1))
) # This literally goes to the same memory in 2013
last.set_attribute("fri", str(lastdict.get_int("rival1", -1))) # This literally goes to the same memory in 2013
last.set_attribute("style", str(lastdict.get_int("style")))
last.set_attribute("mode", str(lastdict.get_int("mode")))
last.set_attribute("cate", str(lastdict.get_int("cate")))
@ -407,9 +393,7 @@ class DDR2013(
root.add_child(Node.s16_array("opt_ex", profile.get_int_array("opt_ex", 16)))
# Unlock flags
root.add_child(
Node.u8_array("flag", profile.get_int_array("flag", 256, [1] * 256))
)
root.add_child(Node.u8_array("flag", profile.get_int_array("flag", 256, [1] * 256)))
# Ranking display?
root.add_child(Node.u16_array("rank", profile.get_int_array("rank", 100)))
@ -431,9 +415,7 @@ class DDR2013(
friendnode.set_attribute("up", "0")
friendnode.add_child(Node.u32("code", friend.extid))
friendnode.add_child(Node.string("name", friend.get_str("name")))
friendnode.add_child(
Node.u8("area", friend.get_int("area", self.get_machine_region()))
)
friendnode.add_child(Node.u8("area", friend.get_int("area", self.get_machine_region())))
friendnode.add_child(Node.u32("exp", play_stats.get_int("exp")))
friendnode.add_child(Node.u32("star", friend.get_int("star")))
@ -484,9 +466,7 @@ class DDR2013(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -691,9 +671,7 @@ class DDR2013(
newfriends[pos] = None
else:
# Try looking up the userid
newfriends[pos] = self.data.remote.user.from_extid(
self.game, self.version, code
)
newfriends[pos] = self.data.remote.user.from_extid(self.game, self.version, code)
# Diff the set of links to determine updates
for i in range(10):

View File

@ -166,9 +166,7 @@ class DDR2014(
flag.set_attribute("is_final", "0")
# Last month's hit chart
hit_chart = self.data.local.music.get_hit_chart(
self.game, self.music_version, self.GAME_MAX_SONGS, 30
)
hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS, 30)
counts_by_reflink = [0] * self.GAME_MAX_SONGS
for reflink, plays in hit_chart:
if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
@ -176,9 +174,7 @@ class DDR2014(
game.add_child(Node.u32_array("cnt_music_monthly", counts_by_reflink))
# Last week's hit chart
hit_chart = self.data.local.music.get_hit_chart(
self.game, self.music_version, self.GAME_MAX_SONGS, 7
)
hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS, 7)
counts_by_reflink = [0] * self.GAME_MAX_SONGS
for reflink, plays in hit_chart:
if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
@ -186,9 +182,7 @@ class DDR2014(
game.add_child(Node.u32_array("cnt_music_weekly", counts_by_reflink))
# Last day's hit chart
hit_chart = self.data.local.music.get_hit_chart(
self.game, self.music_version, self.GAME_MAX_SONGS, 1
)
hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS, 1)
counts_by_reflink = [0] * self.GAME_MAX_SONGS
for reflink, plays in hit_chart:
if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
@ -209,9 +203,7 @@ class DDR2014(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
scores = []
@ -338,14 +330,10 @@ class DDR2014(
root.add_child(Node.string("seq", ""))
root.add_child(Node.u32("code", profile.extid))
root.add_child(Node.string("name", profile.get_str("name")))
root.add_child(
Node.u8("area", profile.get_int("area", self.get_machine_region()))
)
root.add_child(Node.u8("area", profile.get_int("area", self.get_machine_region())))
root.add_child(Node.u32("cnt_s", play_stats.get_int("single_plays")))
root.add_child(Node.u32("cnt_d", play_stats.get_int("double_plays")))
root.add_child(
Node.u32("cnt_b", play_stats.get_int("battle_plays"))
) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_b", play_stats.get_int("battle_plays"))) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_m0", play_stats.get_int("cnt_m0")))
root.add_child(Node.u32("cnt_m1", play_stats.get_int("cnt_m1")))
root.add_child(Node.u32("cnt_m2", play_stats.get_int("cnt_m2")))
@ -363,11 +351,7 @@ class DDR2014(
chara = Node.void("chara")
root.add_child(chara)
chara.set_attribute("my", str(profile.get_int("chara", 30)))
root.add_child(
Node.u16_array(
"chara_opt", profile.get_int_array("chara_opt", 96, [208] * 96)
)
)
root.add_child(Node.u16_array("chara_opt", profile.get_int_array("chara_opt", 96, [208] * 96)))
# Drill rankings
if "title_gr" in profile:
@ -420,9 +404,7 @@ class DDR2014(
last.set_attribute("rival1", str(lastdict.get_int("rival1", -1)))
last.set_attribute("rival2", str(lastdict.get_int("rival2", -1)))
last.set_attribute("rival3", str(lastdict.get_int("rival3", -1)))
last.set_attribute(
"fri", str(lastdict.get_int("rival1", -1))
) # This literally goes to the same memory in 2014
last.set_attribute("fri", str(lastdict.get_int("rival1", -1))) # This literally goes to the same memory in 2014
last.set_attribute("style", str(lastdict.get_int("style")))
last.set_attribute("mode", str(lastdict.get_int("mode")))
last.set_attribute("cate", str(lastdict.get_int("cate")))
@ -462,17 +444,11 @@ class DDR2014(
root.add_child(option_ver)
option_ver.set_attribute("ver", str(profile.get_int("option_ver", 2)))
if "option_02" in profile:
root.add_child(
Node.s16_array("option_02", profile.get_int_array("option_02", 24))
)
root.add_child(Node.s16_array("option_02", profile.get_int_array("option_02", 24)))
# Unlock flags
root.add_child(
Node.u8_array("flag", profile.get_int_array("flag", 512, [1] * 512)[:256])
)
root.add_child(
Node.u8_array("flag_ex", profile.get_int_array("flag", 512, [1] * 512))
)
root.add_child(Node.u8_array("flag", profile.get_int_array("flag", 512, [1] * 512)[:256]))
root.add_child(Node.u8_array("flag_ex", profile.get_int_array("flag", 512, [1] * 512)))
# Ranking display?
root.add_child(Node.u16_array("rank", profile.get_int_array("rank", 100)))
@ -494,9 +470,7 @@ class DDR2014(
friendnode.set_attribute("up", "0")
friendnode.add_child(Node.u32("code", friend.extid))
friendnode.add_child(Node.string("name", friend.get_str("name")))
friendnode.add_child(
Node.u8("area", friend.get_int("area", self.get_machine_region()))
)
friendnode.add_child(Node.u8("area", friend.get_int("area", self.get_machine_region())))
friendnode.add_child(Node.u32("exp", play_stats.get_int("exp")))
friendnode.add_child(Node.u32("star", friend.get_int("star")))
@ -553,9 +527,7 @@ class DDR2014(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -760,9 +732,7 @@ class DDR2014(
newfriends[pos] = None
else:
# Try looking up the userid
newfriends[pos] = self.data.remote.user.from_extid(
self.game, self.version, code
)
newfriends[pos] = self.data.remote.user.from_extid(self.game, self.version, code)
# Diff the set of links to determine updates
for i in range(10):

View File

@ -113,9 +113,7 @@ class DDRAce(
return DDR2014(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
# DDR Ace has a weird bug where it sends a profile save for a blank
# profile before reading it back when creating a new profile. If there
# is no profile on read-back, it errors out, and it also uses the name
@ -134,10 +132,7 @@ class DDRAce(
events = []
for userid, profile in profiles:
if (
profile.get_str("name") == ""
and profile.get_int("write_time") < several_minutes_ago
):
if profile.get_str("name") == "" and profile.get_int("write_time") < several_minutes_ago:
data.local.user.delete_profile(cls.game, cls.version, userid)
events.append(
(
@ -255,21 +250,15 @@ class DDRAce(
tax.add_child(Node.s32("phase", 0))
return tax
def __handle_userload(
self, userid: Optional[UserID], requestdata: Node, response: Node
) -> None:
def __handle_userload(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
has_profile: bool = False
achievements: List[Achievement] = []
scores: List[Score] = []
if userid is not None:
has_profile = self.has_profile(userid)
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Place scores into an arrangement for easier distribution to Ace.
scores_by_mcode: Dict[int, List[Optional[Score]]] = {}
@ -304,11 +293,7 @@ class DDRAce(
note.add_child(Node.s32("ghostid", 0))
else:
note.add_child(Node.u16("count", score.plays))
note.add_child(
Node.u8(
"rank", self.db_to_game_rank(score.data.get_int("rank"))
)
)
note.add_child(Node.u8("rank", self.db_to_game_rank(score.data.get_int("rank"))))
note.add_child(
Node.u8(
"clearkind",
@ -401,9 +386,7 @@ class DDRAce(
eventdata.add_child(Node.u32("eventno", 0))
eventdata.add_child(Node.s64("condition", 0))
eventdata.add_child(Node.u32("reward", 0))
eventdata.add_child(
Node.s32("comptime", 1 if playerstats.get_bool("completed") else 0)
)
eventdata.add_child(Node.s32("comptime", 1 if playerstats.get_bool("completed") else 0))
eventdata.add_child(Node.s64("savedata", 0))
for evtprogress in progress:
@ -414,21 +397,11 @@ class DDRAce(
eventdata.add_child(Node.s32("eventtype", int(evtprogress.type)))
eventdata.add_child(Node.u32("eventno", 0))
eventdata.add_child(Node.s64("condition", 0))
eventdata.add_child(
Node.u32(
"reward", rewards.get(evtprogress.type, {}).get(evtprogress.id)
)
)
eventdata.add_child(
Node.s32("comptime", 1 if evtprogress.data.get_bool("completed") else 0)
)
eventdata.add_child(
Node.s64("savedata", evtprogress.data.get_int("progress"))
)
eventdata.add_child(Node.u32("reward", rewards.get(evtprogress.type, {}).get(evtprogress.id)))
eventdata.add_child(Node.s32("comptime", 1 if evtprogress.data.get_bool("completed") else 0))
eventdata.add_child(Node.s64("savedata", evtprogress.data.get_int("progress")))
def __handle_usersave(
self, userid: Optional[UserID], requestdata: Node, response: Node
) -> None:
def __handle_usersave(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
if userid is None:
# the game sends us empty user ID strings when a guest is playing.
# Return early so it doesn't wait a minute and a half to show the
@ -537,9 +510,7 @@ class DDRAce(
ghost=ghost,
)
def __handle_rivalload(
self, userid: Optional[UserID], requestdata: Node, response: Node
) -> None:
def __handle_rivalload(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
data = Node.void("data")
response.add_child(data)
data.add_child(Node.s32("recordtype", requestdata.child_value("loadflag")))
@ -567,9 +538,7 @@ class DDRAce(
if loadkind == self.GAME_RIVAL_TYPE_WORLD:
# Just load all scores for this network
scores = self.data.remote.music.get_all_records(
self.game, self.music_version
)
scores = self.data.remote.music.get_all_records(self.game, self.music_version)
elif loadkind == self.GAME_RIVAL_TYPE_AREA:
if thismachine.arcade is not None:
match_arcade = thismachine.arcade
@ -595,14 +564,10 @@ class DDRAce(
userids.append(userid)
# Load all scores for users in the area
scores = self.data.local.music.get_all_records(
self.game, self.music_version, userlist=userids
)
scores = self.data.local.music.get_all_records(self.game, self.music_version, userlist=userids)
elif loadkind == self.GAME_RIVAL_TYPE_MACHINE:
# Load up all scores and filter them by those earned at this location
scores = self.data.local.music.get_all_records(
self.game, self.music_version, locationlist=[thismachine.id]
)
scores = self.data.local.music.get_all_records(self.game, self.music_version, locationlist=[thismachine.id])
elif loadkind in [
self.GAME_RIVAL_TYPE_RIVAL1,
self.GAME_RIVAL_TYPE_RIVAL2,
@ -611,17 +576,13 @@ class DDRAce(
# Load up this user's highscores, format the way the below code expects it
extid = requestdata.child_value("ddrcode")
otherid = self.data.remote.user.from_extid(self.game, self.version, extid)
userscores = self.data.remote.music.get_scores(
self.game, self.music_version, otherid
)
userscores = self.data.remote.music.get_scores(self.game, self.music_version, otherid)
scores = [(otherid, score) for score in userscores]
else:
# Nothing here
scores = []
missing_users = [
userid for (userid, _) in scores if userid not in profiles_by_userid
]
missing_users = [userid for (userid, _) in scores if userid not in profiles_by_userid]
for userid, profile in self.get_any_profiles(missing_users):
profiles_by_userid[userid] = profile
@ -634,12 +595,8 @@ class DDRAce(
data.add_child(record)
record.add_child(Node.u32("mcode", score.id))
record.add_child(Node.u8("notetype", self.db_to_game_chart(score.chart)))
record.add_child(
Node.u8("rank", self.db_to_game_rank(score.data.get_int("rank")))
)
record.add_child(
Node.u8("clearkind", self.db_to_game_halo(score.data.get_int("halo")))
)
record.add_child(Node.u8("rank", self.db_to_game_rank(score.data.get_int("rank"))))
record.add_child(Node.u8("clearkind", self.db_to_game_halo(score.data.get_int("halo"))))
record.add_child(Node.u8("flagdata", 0))
record.add_child(Node.string("name", profiledata.get_str("name")))
record.add_child(Node.s32("area", profiledata.get_int("area", 58)))
@ -647,9 +604,7 @@ class DDRAce(
record.add_child(Node.s32("score", score.points))
record.add_child(Node.s32("ghostid", score.key))
def __handle_usernew(
self, userid: Optional[UserID], requestdata: Node, response: Node
) -> None:
def __handle_usernew(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
if userid is None:
raise Exception("Expecting valid UserID to create new profile!")
@ -669,26 +624,18 @@ class DDRAce(
response.add_child(Node.s32("code", profile.extid))
response.add_child(Node.string("shoparea", ""))
def __handle_inheritance(
self, userid: Optional[UserID], requestdata: Node, response: Node
) -> None:
def __handle_inheritance(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
if userid is not None:
previous_version = self.previous_version()
profile = previous_version.get_profile(userid)
else:
profile = None
response.add_child(
Node.s32("InheritanceStatus", 1 if profile is not None else 0)
)
response.add_child(Node.s32("InheritanceStatus", 1 if profile is not None else 0))
def __handle_ghostload(
self, userid: Optional[UserID], requestdata: Node, response: Node
) -> None:
def __handle_ghostload(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
ghostid = requestdata.child_value("ghostid")
ghost = self.data.local.music.get_score_by_key(
self.game, self.music_version, ghostid
)
ghost = self.data.local.music.get_score_by_key(self.game, self.music_version, ghostid)
if ghost is None:
return
@ -708,9 +655,7 @@ class DDRAce(
ghostdata.add_child(Node.s32("ghostsize", len(score.data["ghost"])))
ghostdata.add_child(Node.string("ghost", score.data["ghost"]))
def handle_playerdata_usergamedata_advanced_request(
self, request: Node
) -> Optional[Node]:
def handle_playerdata_usergamedata_advanced_request(self, request: Node) -> Optional[Node]:
playerdata = Node.void("playerdata")
# DDR Ace decides to be difficult and have a third level of packet switching
@ -748,9 +693,7 @@ class DDRAce(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
profile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
usergamedata = profile.get_dict("usergamedata")
for record in request.child("data/record").children:
@ -781,30 +724,19 @@ class DDRAce(
profile.replace_bool(
"workout_mode",
int(
strdatalist[self.GAME_COMMON_WEIGHT_DISPLAY_OFFSET].decode(
"ascii"
),
strdatalist[self.GAME_COMMON_WEIGHT_DISPLAY_OFFSET].decode("ascii"),
16,
)
!= 0,
)
profile.replace_int(
"weight",
int(
float(
strdatalist[self.GAME_COMMON_WEIGHT_OFFSET].decode(
"ascii"
)
)
* 10
),
int(float(strdatalist[self.GAME_COMMON_WEIGHT_OFFSET].decode("ascii")) * 10),
)
profile.replace_int(
"character",
int(
strdatalist[self.GAME_COMMON_CHARACTER_OFFSET].decode(
"ascii"
),
strdatalist[self.GAME_COMMON_CHARACTER_OFFSET].decode("ascii"),
16,
),
)
@ -812,36 +744,28 @@ class DDRAce(
profile.replace_int(
"combo",
int(
strdatalist[self.GAME_OPTION_COMBO_POSITION_OFFSET].decode(
"ascii"
),
strdatalist[self.GAME_OPTION_COMBO_POSITION_OFFSET].decode("ascii"),
16,
),
)
profile.replace_int(
"early_late",
int(
strdatalist[self.GAME_OPTION_FAST_SLOW_OFFSET].decode(
"ascii"
),
strdatalist[self.GAME_OPTION_FAST_SLOW_OFFSET].decode("ascii"),
16,
),
)
profile.replace_int(
"arrowskin",
int(
strdatalist[self.GAME_OPTION_ARROW_SKIN_OFFSET].decode(
"ascii"
),
strdatalist[self.GAME_OPTION_ARROW_SKIN_OFFSET].decode("ascii"),
16,
),
)
profile.replace_int(
"guidelines",
int(
strdatalist[self.GAME_OPTION_GUIDELINE_OFFSET].decode(
"ascii"
),
strdatalist[self.GAME_OPTION_GUIDELINE_OFFSET].decode("ascii"),
16,
),
)
@ -907,45 +831,39 @@ class DDRAce(
old_profile = previous_version.get_profile(userid)
if old_profile is not None:
name = old_profile.get_str("name")
area = old_profile.get_int(
"area", self.get_machine_region()
)
area = old_profile.get_int("area", self.get_machine_region())
else:
area = self.get_machine_region()
common = usergamedata[ptype]["strdata"].split(b",")
common[self.GAME_COMMON_NAME_OFFSET] = name.encode("ascii")
common[self.GAME_COMMON_AREA_OFFSET] = acehex(area).encode(
"ascii"
)
common[self.GAME_COMMON_AREA_OFFSET] = acehex(area).encode("ascii")
common[self.GAME_COMMON_WEIGHT_DISPLAY_OFFSET] = (
b"1" if profile.get_bool("workout_mode") else b"0"
)
common[self.GAME_COMMON_WEIGHT_OFFSET] = str(
float(profile.get_int("weight")) / 10.0
).encode("ascii")
common[self.GAME_COMMON_CHARACTER_OFFSET] = acehex(
profile.get_int("character")
).encode("ascii")
common[self.GAME_COMMON_CHARACTER_OFFSET] = acehex(profile.get_int("character")).encode(
"ascii"
)
usergamedata[ptype]["strdata"] = b",".join(common)
if ptype == "OPTION":
# Return user settings for frontend
option = usergamedata[ptype]["strdata"].split(b",")
option[self.GAME_OPTION_FAST_SLOW_OFFSET] = acehex(
profile.get_int("early_late")
).encode("ascii")
option[self.GAME_OPTION_COMBO_POSITION_OFFSET] = acehex(
profile.get_int("combo")
).encode("ascii")
option[self.GAME_OPTION_ARROW_SKIN_OFFSET] = acehex(
profile.get_int("arrowskin")
).encode("ascii")
option[self.GAME_OPTION_GUIDELINE_OFFSET] = acehex(
profile.get_int("guidelines")
).encode("ascii")
option[self.GAME_OPTION_FILTER_OFFSET] = acehex(
profile.get_int("filter")
).encode("ascii")
option[self.GAME_OPTION_FAST_SLOW_OFFSET] = acehex(profile.get_int("early_late")).encode(
"ascii"
)
option[self.GAME_OPTION_COMBO_POSITION_OFFSET] = acehex(profile.get_int("combo")).encode(
"ascii"
)
option[self.GAME_OPTION_ARROW_SKIN_OFFSET] = acehex(profile.get_int("arrowskin")).encode(
"ascii"
)
option[self.GAME_OPTION_GUIDELINE_OFFSET] = acehex(profile.get_int("guidelines")).encode(
"ascii"
)
option[self.GAME_OPTION_FILTER_OFFSET] = acehex(profile.get_int("filter")).encode("ascii")
usergamedata[ptype]["strdata"] = b",".join(option)
if ptype == "LAST":
# Return the number of calories expended in the last day
@ -959,9 +877,7 @@ class DDRAce(
total = sum([w.data.get_int("calories") for w in workouts])
last = usergamedata[ptype]["strdata"].split(b",")
last[self.GAME_LAST_CALORIES_OFFSET] = acehex(total).encode(
"ascii"
)
last[self.GAME_LAST_CALORIES_OFFSET] = acehex(total).encode("ascii")
usergamedata[ptype]["strdata"] = b",".join(last)
if ptype == "RIVAL":
# Fill in the DDR code and active status of the three active
@ -1003,24 +919,18 @@ class DDRAce(
}[rivalno]
rival[activeslot] = acehex(rivalno).encode("ascii")
rival[ddrcodeslot] = acehex(friendprofile.extid).encode(
"ascii"
)
rival[ddrcodeslot] = acehex(friendprofile.extid).encode("ascii")
usergamedata[ptype]["strdata"] = b",".join(rival)
dnode = Node.string(
"d",
base64.b64encode(usergamedata[ptype]["strdata"]).decode(
"ascii"
),
base64.b64encode(usergamedata[ptype]["strdata"]).decode("ascii"),
)
dnode.add_child(
Node.string(
"bin1",
base64.b64encode(usergamedata[ptype]["bindata"]).decode(
"ascii"
),
base64.b64encode(usergamedata[ptype]["bindata"]).decode("ascii"),
)
)
record.add_child(dnode)

View File

@ -156,9 +156,7 @@ class DDRX2(
flag.set_attribute("s1", "0")
flag.set_attribute("t", "0")
hit_chart = self.data.local.music.get_hit_chart(
self.game, self.music_version, self.GAME_MAX_SONGS
)
hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS)
counts_by_reflink = [0] * self.GAME_MAX_SONGS
for reflink, plays in hit_chart:
if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
@ -180,10 +178,7 @@ class DDRX2(
sortedrecords[score.id] = {}
sortedrecords[score.id][score.chart] = (userid, score)
missing_profiles.append(userid)
users = {
userid: profile
for (userid, profile) in self.get_any_profiles(missing_profiles)
}
users = {userid: profile for (userid, profile) in self.get_any_profiles(missing_profiles)}
game = Node.void("game")
for song in sortedrecords:
@ -207,11 +202,7 @@ class DDRX2(
typenode.add_child(Node.string("name", users[userid].get_str("name")))
typenode.add_child(Node.u32("score", score.points))
typenode.add_child(
Node.u16(
"area", users[userid].get_int("area", self.get_machine_region())
)
)
typenode.add_child(Node.u16("area", users[userid].get_int("area", self.get_machine_region())))
typenode.add_child(Node.u8("rank", gamerank))
typenode.add_child(Node.u8("combo_type", combo_type))
@ -229,9 +220,7 @@ class DDRX2(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
scores = []
@ -317,14 +306,10 @@ class DDRX2(
root.add_child(Node.string("seq", ""))
root.add_child(Node.u32("code", profile.extid))
root.add_child(Node.string("name", profile.get_str("name")))
root.add_child(
Node.u8("area", profile.get_int("area", self.get_machine_region()))
)
root.add_child(Node.u8("area", profile.get_int("area", self.get_machine_region())))
root.add_child(Node.u32("cnt_s", play_stats.get_int("single_plays")))
root.add_child(Node.u32("cnt_d", play_stats.get_int("double_plays")))
root.add_child(
Node.u32("cnt_b", play_stats.get_int("battle_plays"))
) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_b", play_stats.get_int("battle_plays"))) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_m0", play_stats.get_int("cnt_m0")))
root.add_child(Node.u32("cnt_m1", play_stats.get_int("cnt_m1")))
root.add_child(Node.u32("cnt_m2", play_stats.get_int("cnt_m2")))
@ -342,9 +327,7 @@ class DDRX2(
if "chara" in profile:
chara.set_attribute("my", str(profile.get_int("chara")))
root.add_child(
Node.u8_array("chara_opt", profile.get_int_array("chara_opt", 96))
)
root.add_child(Node.u8_array("chara_opt", profile.get_int_array("chara_opt", 96)))
# Drill rankings
if "title" in profile:
@ -387,53 +370,31 @@ class DDRX2(
e_panel_dict = profile.get_dict("e_panel")
if "play_id" in e_panel_dict:
e_panel.set_attribute("play_id", str(e_panel_dict.get_int("play_id")))
e_panel.add_child(
Node.u8_array("cell", e_panel_dict.get_int_array("cell", 24))
)
e_panel.add_child(
Node.u8_array(
"panel_state", e_panel_dict.get_int_array("panel_state", 6)
)
)
e_panel.add_child(Node.u8_array("cell", e_panel_dict.get_int_array("cell", 24)))
e_panel.add_child(Node.u8_array("panel_state", e_panel_dict.get_int_array("panel_state", 6)))
if "e_pix" in profile:
e_pix = Node.void("e_pix")
root.add_child(e_pix)
e_pix_dict = profile.get_dict("e_pix")
if "max_distance" in e_pix_dict:
e_pix.set_attribute(
"max_distance", str(e_pix_dict.get_int("max_distance"))
)
e_pix.set_attribute("max_distance", str(e_pix_dict.get_int("max_distance")))
if "max_planet" in e_pix_dict:
e_pix.set_attribute("max_planet", str(e_pix_dict.get_int("max_planet")))
if "total_distance" in e_pix_dict:
e_pix.set_attribute(
"total_distance", str(e_pix_dict.get_int("total_distance"))
)
e_pix.set_attribute("total_distance", str(e_pix_dict.get_int("total_distance")))
if "total_planet" in e_pix_dict:
e_pix.set_attribute(
"total_planet", str(e_pix_dict.get_int("total_planet"))
)
e_pix.set_attribute("total_planet", str(e_pix_dict.get_int("total_planet")))
if "border_character" in e_pix_dict:
e_pix.set_attribute(
"border_character", str(e_pix_dict.get_int("border_character"))
)
e_pix.set_attribute("border_character", str(e_pix_dict.get_int("border_character")))
if "border_balloon" in e_pix_dict:
e_pix.set_attribute(
"border_balloon", str(e_pix_dict.get_int("border_balloon"))
)
e_pix.set_attribute("border_balloon", str(e_pix_dict.get_int("border_balloon")))
if "border_music_aftr" in e_pix_dict:
e_pix.set_attribute(
"border_music_aftr", str(e_pix_dict.get_int("border_music_aftr"))
)
e_pix.set_attribute("border_music_aftr", str(e_pix_dict.get_int("border_music_aftr")))
if "border_music_meii" in e_pix_dict:
e_pix.set_attribute(
"border_music_meii", str(e_pix_dict.get_int("border_music_meii"))
)
e_pix.set_attribute("border_music_meii", str(e_pix_dict.get_int("border_music_meii")))
if "border_music_dirt" in e_pix_dict:
e_pix.set_attribute(
"border_music_dirt", str(e_pix_dict.get_int("border_music_dirt"))
)
e_pix.set_attribute("border_music_dirt", str(e_pix_dict.get_int("border_music_dirt")))
if "flags" in e_pix_dict:
e_pix.set_attribute("flags", str(e_pix_dict.get_int("flags")))
@ -488,9 +449,7 @@ class DDRX2(
root.add_child(Node.s16_array("opt_ex", profile.get_int_array("opt_ex", 16)))
# Unlock flags
root.add_child(
Node.u8_array("flag", profile.get_int_array("flag", 256, [1] * 256))
)
root.add_child(Node.u8_array("flag", profile.get_int_array("flag", 256, [1] * 256)))
# Ranking display?
root.add_child(Node.u16_array("rank", profile.get_int_array("rank", 100)))
@ -512,9 +471,7 @@ class DDRX2(
friendnode.set_attribute("up", "0")
friendnode.add_child(Node.u32("code", friend.extid))
friendnode.add_child(Node.string("name", friend.get_str("name")))
friendnode.add_child(
Node.u8("area", friend.get_int("area", self.get_machine_region()))
)
friendnode.add_child(Node.u8("area", friend.get_int("area", self.get_machine_region())))
friendnode.add_child(Node.u32("exp", play_stats.get_int("exp")))
friendnode.add_child(Node.u32("star", friend.get_int("star")))
@ -558,9 +515,7 @@ class DDRX2(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -656,9 +611,7 @@ class DDRX2(
e_panel_dict = newprofile.get_dict("e_panel")
e_panel_dict.replace_int("play_id", intish(e_panel.attribute("play_id")))
e_panel_dict.replace_int_array("cell", 24, e_panel.child_value("cell"))
e_panel_dict.replace_int_array(
"panel_state", 6, e_panel.child_value("panel_state")
)
e_panel_dict.replace_int_array("panel_state", 6, e_panel.child_value("panel_state"))
newprofile.replace_dict("e_panel", e_panel_dict)
e_pix = request.child("e_pix")
@ -777,9 +730,7 @@ class DDRX2(
newfriends[pos] = None
else:
# Try looking up the userid
newfriends[pos] = self.data.remote.user.from_extid(
self.game, self.version, code
)
newfriends[pos] = self.data.remote.user.from_extid(self.game, self.version, code)
# Diff the set of links to determine updates
for i in range(10):

View File

@ -165,9 +165,7 @@ class DDRX3(
flag.set_attribute("s1", "0")
flag.set_attribute("t", "0")
hit_chart = self.data.local.music.get_hit_chart(
self.game, self.music_version, self.GAME_MAX_SONGS
)
hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS)
counts_by_reflink = [0] * self.GAME_MAX_SONGS
for reflink, plays in hit_chart:
if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
@ -188,14 +186,10 @@ class DDRX3(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
old_scores = [
score
for score in self.data.local.user.get_achievements(
self.game, self.music_version, userid
)
for score in self.data.local.user.get_achievements(self.game, self.music_version, userid)
if score.type == "2ndmix"
]
else:
@ -236,12 +230,8 @@ class DDRX3(
if "score" in scoredict:
# We played the normal version of this song
gamerank = self.db_to_game_rank(
scoredict["score"].data.get_int("rank")
)
combo_type = self.db_to_game_halo(
scoredict["score"].data.get_int("halo")
)
gamerank = self.db_to_game_rank(scoredict["score"].data.get_int("rank"))
combo_type = self.db_to_game_halo(scoredict["score"].data.get_int("halo"))
points = scoredict["score"].points # type: ignore
plays = scoredict["score"].plays # type: ignore
else:
@ -366,14 +356,10 @@ class DDRX3(
root.add_child(Node.string("seq", ""))
root.add_child(Node.u32("code", profile.extid))
root.add_child(Node.string("name", profile.get_str("name")))
root.add_child(
Node.u8("area", profile.get_int("area", self.get_machine_region()))
)
root.add_child(Node.u8("area", profile.get_int("area", self.get_machine_region())))
root.add_child(Node.u32("cnt_s", play_stats.get_int("single_plays")))
root.add_child(Node.u32("cnt_d", play_stats.get_int("double_plays")))
root.add_child(
Node.u32("cnt_b", play_stats.get_int("battle_plays"))
) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_b", play_stats.get_int("battle_plays"))) # This could be wrong, its a guess
root.add_child(Node.u32("cnt_m0", play_stats.get_int("cnt_m0")))
root.add_child(Node.u32("cnt_m1", play_stats.get_int("cnt_m1")))
root.add_child(Node.u32("cnt_m2", play_stats.get_int("cnt_m2")))
@ -391,11 +377,7 @@ class DDRX3(
chara = Node.void("chara")
root.add_child(chara)
chara.set_attribute("my", str(profile.get_int("chara", 30)))
root.add_child(
Node.u16_array(
"chara_opt", profile.get_int_array("chara_opt", 96, [208] * 96)
)
)
root.add_child(Node.u16_array("chara_opt", profile.get_int_array("chara_opt", 96, [208] * 96)))
# Drill rankings
if "title_gr" in profile:
@ -443,9 +425,7 @@ class DDRX3(
last.set_attribute("rival1", str(lastdict.get_int("rival1", -1)))
last.set_attribute("rival2", str(lastdict.get_int("rival2", -1)))
last.set_attribute("rival3", str(lastdict.get_int("rival3", -1)))
last.set_attribute(
"fri", str(lastdict.get_int("rival1", -1))
) # This literally goes to the same memory in X3
last.set_attribute("fri", str(lastdict.get_int("rival1", -1))) # This literally goes to the same memory in X3
last.set_attribute("style", str(lastdict.get_int("style")))
last.set_attribute("mode", str(lastdict.get_int("mode")))
last.set_attribute("cate", str(lastdict.get_int("cate")))
@ -489,9 +469,7 @@ class DDRX3(
root.add_child(Node.s16_array("opt_ex", profile.get_int_array("opt_ex", 16)))
# Unlock flags
root.add_child(
Node.u8_array("flag", profile.get_int_array("flag", 256, [1] * 256))
)
root.add_child(Node.u8_array("flag", profile.get_int_array("flag", 256, [1] * 256)))
# Ranking display?
root.add_child(Node.u16_array("rank", profile.get_int_array("rank", 100)))
@ -513,9 +491,7 @@ class DDRX3(
friendnode.set_attribute("up", "0")
friendnode.add_child(Node.u32("code", friend.extid))
friendnode.add_child(Node.string("name", friend.get_str("name")))
friendnode.add_child(
Node.u8("area", friend.get_int("area", self.get_machine_region()))
)
friendnode.add_child(Node.u8("area", friend.get_int("area", self.get_machine_region())))
friendnode.add_child(Node.u32("exp", play_stats.get_int("exp")))
friendnode.add_child(Node.u32("star", friend.get_int("star")))
@ -566,9 +542,7 @@ class DDRX3(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -773,9 +747,7 @@ class DDRX3(
newfriends[pos] = None
else:
# Try looking up the userid
newfriends[pos] = self.data.remote.user.from_extid(
self.game, self.version, code
)
newfriends[pos] = self.data.remote.user.from_extid(self.game, self.version, code)
# Diff the set of links to determine updates
for i in range(10):

View File

@ -79,9 +79,7 @@ class Dispatch:
pcb = self.__data.local.machine.get_machine(pcbid)
if self.__config.server.enforce_pcbid and pcb is None:
self.log("Unrecognized PCBID {}", pcbid)
raise UnrecognizedPCBIDException(
pcbid, modelstring, self.__config.client.address
)
raise UnrecognizedPCBIDException(pcbid, modelstring, self.__config.client.address)
# If we don't have a Machine, but we aren't enforcing, we must create it
if pcb is None:
@ -120,9 +118,7 @@ class Dispatch:
pcb.game,
game.game,
)
raise UnrecognizedPCBIDException(
pcbid, modelstring, config.client.address
)
raise UnrecognizedPCBIDException(pcbid, modelstring, config.client.address)
if pcb.version is not None:
if pcb.version > 0 and pcb.version != game.version:
self.log(
@ -133,9 +129,7 @@ class Dispatch:
game.game,
game.version,
)
raise UnrecognizedPCBIDException(
pcbid, modelstring, config.client.address
)
raise UnrecognizedPCBIDException(pcbid, modelstring, config.client.address)
if pcb.version < 0 and (-pcb.version) < game.version:
self.log(
"PCBID {} assigned to game {} maximum version {}, but connected from game {} version {}",
@ -145,9 +139,7 @@ class Dispatch:
game.game,
game.version,
)
raise UnrecognizedPCBIDException(
pcbid, modelstring, config.client.address
)
raise UnrecognizedPCBIDException(pcbid, modelstring, config.client.address)
# First, try to handle with specific service/method function
try:

View File

@ -115,9 +115,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("pc")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -145,9 +143,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
return None
return self.format_profile(userid, profile)
def new_profile_by_refid(
self, refid: Optional[str], name: Optional[str], pid: Optional[int]
) -> Profile:
def new_profile_by_refid(self, refid: Optional[str], name: Optional[str], pid: Optional[int]) -> Profile:
"""
Given a RefID and an optional name, create a profile and then return
that newly created profile.
@ -169,9 +165,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
{
"name": name,
"pid": pid,
"settings": {
"flags": 223 # Default to turning on all optional folders
},
"settings": {"flags": 223}, # Default to turning on all optional folders
},
)
self.put_profile(userid, profile)
@ -253,27 +247,18 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
}
# We saw an attempt, keep the total attempts in sync.
attempts[attempt.id][attempt.chart]["total"] = (
attempts[attempt.id][attempt.chart]["total"] + 1
)
attempts[attempt.id][attempt.chart]["total"] = attempts[attempt.id][attempt.chart]["total"] + 1
if (
attempt.data.get_int("clear_status", self.CLEAR_STATUS_FAILED)
== self.CLEAR_STATUS_FAILED
):
if attempt.data.get_int("clear_status", self.CLEAR_STATUS_FAILED) == self.CLEAR_STATUS_FAILED:
# This attempt was a failure, so don't count it against clears of full combos
continue
# It was at least a clear
attempts[attempt.id][attempt.chart]["clears"] = (
attempts[attempt.id][attempt.chart]["clears"] + 1
)
attempts[attempt.id][attempt.chart]["clears"] = attempts[attempt.id][attempt.chart]["clears"] + 1
if attempt.data.get_int("clear_status") == self.CLEAR_STATUS_FULL_COMBO:
# This was a full combo clear, so it also counts here
attempts[attempt.id][attempt.chart]["fcs"] = (
attempts[attempt.id][attempt.chart]["fcs"] + 1
)
attempts[attempt.id][attempt.chart]["fcs"] = attempts[attempt.id][attempt.chart]["fcs"] + 1
# Merge in remote attempts
for songid in remote_attempts:
@ -288,15 +273,9 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"fcs": 0,
}
attempts[songid][songchart]["total"] += remote_attempts[songid][
songchart
]["plays"]
attempts[songid][songchart]["clears"] += remote_attempts[songid][
songchart
]["clears"]
attempts[songid][songchart]["fcs"] += remote_attempts[songid][
songchart
]["combos"]
attempts[songid][songchart]["total"] += remote_attempts[songid][songchart]["plays"]
attempts[songid][songchart]["clears"] += remote_attempts[songid][songchart]["clears"]
attempts[songid][songchart]["fcs"] += remote_attempts[songid][songchart]["combos"]
# If requesting a specific song/chart, make sure its in the dict
if songid is not None:
@ -399,16 +378,12 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
highscore = ex_score >= oldscore.points
ex_score = max(ex_score, oldscore.points)
scoredata = oldscore.data
scoredata.replace_int(
"clear_status", max(scoredata.get_int("clear_status"), clear_status)
)
scoredata.replace_int("clear_status", max(scoredata.get_int("clear_status"), clear_status))
if miss_count != -1:
if scoredata.get_int("miss_count", -1) == -1:
scoredata.replace_int("miss_count", miss_count)
else:
scoredata.replace_int(
"miss_count", min(scoredata.get_int("miss_count"), miss_count)
)
scoredata.replace_int("miss_count", min(scoredata.get_int("miss_count"), miss_count))
if raised:
scoredata.replace_int("pgreats", pgreats)
scoredata.replace_int("greats", greats)
@ -514,12 +489,8 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
if dan_score is None:
dan_score = ValidatedDict()
dan_score.replace_int("percent", max(percent, dan_score.get_int("percent")))
dan_score.replace_int(
"stages_cleared", max(stages_cleared, dan_score.get_int("stages_cleared"))
)
self.data.local.user.put_achievement(
self.game, self.version, userid, rank, dantype, dan_score
)
dan_score.replace_int("stages_cleared", max(stages_cleared, dan_score.get_int("stages_cleared")))
self.data.local.user.put_achievement(self.game, self.version, userid, rank, dantype, dan_score)
def db_to_game_status(self, db_status: int) -> int:
"""
@ -545,9 +516,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
raise Exception("Implement in sub-class!")
def make_score_struct(
self, scores: List[Score], cltype: int, index: int
) -> List[List[int]]:
def make_score_struct(self, scores: List[Score], cltype: int, index: int) -> List[List[int]]:
scorestruct: Dict[int, List[int]] = {}
for score in scores:
@ -595,9 +564,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
-1, # Miss count another,
]
scorestruct[musicid][chartindex + 2] = self.db_to_game_status(
score.data.get_int("clear_status")
)
scorestruct[musicid][chartindex + 2] = self.db_to_game_status(score.data.get_int("clear_status"))
scorestruct[musicid][chartindex + 5] = score.points
scorestruct[musicid][chartindex + 8] = score.data.get_int("miss_count", -1)
@ -698,9 +665,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
if ghost_type == self.GHOST_TYPE_RIVAL:
rival_extid = int(parameter)
rival_userid = self.data.remote.user.from_extid(
self.game, self.version, rival_extid
)
rival_userid = self.data.remote.user.from_extid(self.game, self.version, rival_extid)
if rival_userid is not None:
rival_profile = self.get_profile(rival_userid)
rival_score = self.data.remote.music.get_score(
@ -720,10 +685,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
or ghost_type == self.GHOST_TYPE_GLOBAL_AVERAGE
or ghost_type == self.GHOST_TYPE_LOCAL_AVERAGE
):
if (
ghost_type == self.GHOST_TYPE_LOCAL_TOP
or ghost_type == self.GHOST_TYPE_LOCAL_AVERAGE
):
if ghost_type == self.GHOST_TYPE_LOCAL_TOP or ghost_type == self.GHOST_TYPE_LOCAL_AVERAGE:
all_scores = sorted(
self.data.local.music.get_all_scores(
game=self.game,
@ -756,9 +718,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
all_scores = [
score
for score in all_scores
if self.user_joined_arcade(
machine, self.get_any_profile(score[0])
)
if self.user_joined_arcade(machine, self.get_any_profile(score[0]))
]
else:
# Not joined an arcade, so nobody matches our scores
@ -775,10 +735,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
reverse=True,
)
if (
ghost_type == self.GHOST_TYPE_GLOBAL_TOP
or ghost_type == self.GHOST_TYPE_LOCAL_TOP
):
if ghost_type == self.GHOST_TYPE_GLOBAL_TOP or ghost_type == self.GHOST_TYPE_LOCAL_TOP:
for potential_top in all_scores:
top_userid = potential_top[0]
top_score = potential_top[1]
@ -793,23 +750,15 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
}
break
if (
ghost_type == self.GHOST_TYPE_GLOBAL_AVERAGE
or ghost_type == self.GHOST_TYPE_LOCAL_AVERAGE
):
average_score, delta_ghost = self.delta_score(
[score[1] for score in all_scores], ghost_length
)
if ghost_type == self.GHOST_TYPE_GLOBAL_AVERAGE or ghost_type == self.GHOST_TYPE_LOCAL_AVERAGE:
average_score, delta_ghost = self.delta_score([score[1] for score in all_scores], ghost_length)
if average_score is not None and delta_ghost is not None:
ghost_score = {
"score": average_score,
"ghost": bytes([0] * ghost_length),
}
if (
ghost_type == self.GHOST_TYPE_DAN_TOP
or ghost_type == self.GHOST_TYPE_DAN_AVERAGE
):
if ghost_type == self.GHOST_TYPE_DAN_TOP or ghost_type == self.GHOST_TYPE_DAN_AVERAGE:
is_dp = chart not in [
self.CHART_TYPE_N7,
self.CHART_TYPE_H7,
@ -839,20 +788,13 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
key=lambda s: s[1].points,
reverse=True,
)
all_profiles = self.data.local.user.get_all_profiles(
self.game, self.version
)
all_profiles = self.data.local.user.get_all_profiles(self.game, self.version)
relevant_userids = {
profile[0]
for profile in all_profiles
if profile[1].get_int(
self.DAN_RANKING_DOUBLE if is_dp else self.DAN_RANKING_SINGLE
)
== dan_rank
if profile[1].get_int(self.DAN_RANKING_DOUBLE if is_dp else self.DAN_RANKING_SINGLE) == dan_rank
}
relevant_scores = [
score for score in all_scores if score[0] in relevant_userids
]
relevant_scores = [score for score in all_scores if score[0] in relevant_userids]
if ghost_type == self.GHOST_TYPE_DAN_TOP:
for potential_top in relevant_scores:
top_userid = potential_top[0]
@ -869,23 +811,17 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
break
if ghost_type == self.GHOST_TYPE_DAN_AVERAGE:
average_score, delta_ghost = self.delta_score(
[score[1] for score in relevant_scores], ghost_length
)
average_score, delta_ghost = self.delta_score([score[1] for score in relevant_scores], ghost_length)
if average_score is not None and delta_ghost is not None:
ghost_score = {
"score": average_score,
"ghost": bytes([0] * ghost_length),
}
if (
ghost_type == self.GHOST_TYPE_RIVAL_TOP
or ghost_type == self.GHOST_TYPE_RIVAL_AVERAGE
):
if ghost_type == self.GHOST_TYPE_RIVAL_TOP or ghost_type == self.GHOST_TYPE_RIVAL_AVERAGE:
rival_extids = [int(e[1:-1]) for e in parameter.split(",")]
rival_userids = [
self.data.remote.user.from_extid(self.game, self.version, rival_extid)
for rival_extid in rival_extids
self.data.remote.user.from_extid(self.game, self.version, rival_extid) for rival_extid in rival_extids
]
all_scores = sorted(
@ -918,9 +854,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
break
if ghost_type == self.GHOST_TYPE_RIVAL_AVERAGE:
average_score, delta_ghost = self.delta_score(
[score[1] for score in all_scores], ghost_length
)
average_score, delta_ghost = self.delta_score([score[1] for score in all_scores], ghost_length)
if average_score is not None and delta_ghost is not None:
ghost_score = {
"score": average_score,

View File

@ -107,28 +107,15 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
return IIDXSinobuz(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -152,9 +139,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -389,9 +374,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root = Node.void("IIDX25shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -414,9 +397,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return Node.void("IIDX25shop")
@ -436,9 +417,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -575,16 +554,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root = Node.void("IIDX25music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -628,16 +598,12 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
continue
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -645,10 +611,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -675,9 +638,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -768,18 +729,11 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
shop_id = ID.parse_machine_id(request.attribute("location_id"))
if not global_scores:
all_scores = [
score
for score in all_scores
if (score[0] == userid or score[1].location == shop_id)
]
all_scores = [score for score in all_scores if (score[0] == userid or score[1].location == shop_id)]
# Find our actual index
oldindex = None
@ -830,9 +784,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -853,11 +805,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
all_players[uid] = prof
if not global_scores:
all_scores = [
score
for score in all_scores
if (score[0] == userid or score[1].location == shop_id)
]
all_scores = [score for score in all_scores if (score[0] == userid or score[1].location == shop_id)]
# Find our actual index
ourindex = None
@ -990,13 +938,9 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
}
for item in request.children:
if item.name == "music_list":
music_list[int(item.child_value("index"))] = int(
item.child_value("total_notes")
)
music_list[int(item.child_value("index"))] = int(item.child_value("total_notes"))
if item.name == "cpu_list":
cpu_list[int(item.child_value("index"))] = int(
item.child_value("grade_id")
)
cpu_list[int(item.child_value("index"))] = int(item.child_value("grade_id"))
for index in range(4):
cpu_score_list = Node.void("cpu_score_list")
cpu_score_list.add_child(Node.s32("index", index))
@ -1099,9 +1043,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root.add_child(event1_phase)
event1_phase.set_attribute("phase", str(event1))
extra_boss_event = Node.void(
"extra_boss_event"
) # Always enable IIDX AIR RACE 5
extra_boss_event = Node.void("extra_boss_event") # Always enable IIDX AIR RACE 5
root.add_child(extra_boss_event)
extra_boss_event.set_attribute("phase", "4")
@ -1270,9 +1212,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
used_secret_ids: List[int] = []
for c in secret_courses:
if c["id"] in used_secret_ids:
raise Exception(
"Cannot have multiple secret courses with the same ID!"
)
raise Exception("Cannot have multiple secret courses with the same ID!")
elif c["id"] < 0 or c["id"] >= 20:
raise Exception("Secret course ID is out of bounds!")
else:
@ -1483,25 +1423,15 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root.add_child(arena_cpu_define)
arena_cpu_define.add_child(Node.s32("play_style", playstyle))
arena_cpu_define.add_child(Node.s32("arena_class", arena_class))
arena_cpu_define.add_child(
Node.s32("grade_id", cpu_grades[arena_class])
)
arena_cpu_define.add_child(
Node.s32("low_music_difficult", cpu_low_diff[arena_class])
)
arena_cpu_define.add_child(
Node.s32("high_music_difficult", cpu_high_diff[arena_class])
)
arena_cpu_define.add_child(
Node.bool("is_leggendaria", arena_class >= 13)
)
arena_cpu_define.add_child(Node.s32("grade_id", cpu_grades[arena_class]))
arena_cpu_define.add_child(Node.s32("low_music_difficult", cpu_low_diff[arena_class]))
arena_cpu_define.add_child(Node.s32("high_music_difficult", cpu_high_diff[arena_class]))
arena_cpu_define.add_child(Node.bool("is_leggendaria", arena_class >= 13))
for matching_class in range(21):
matching_class_range = Node.void("matching_class_range")
root.add_child(matching_class_range)
matching_class_range.add_child(Node.s32("play_style", playstyle))
matching_class_range.add_child(
Node.s32("matching_class", matching_class)
)
matching_class_range.add_child(Node.s32("matching_class", matching_class))
matching_class_range.add_child(Node.s32("low_arena_class", 1))
matching_class_range.add_child(Node.s32("high_arena_class", 20))
return root
@ -1551,9 +1481,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
best_clear_string = clear_map.get(best_clear, "NO PLAY")
now_clear_string = clear_map.get(now_clear, "NO PLAY")
# let's get the song info first
song = self.data.local.music.get_song(
self.game, self.music_version, music_id, self.game_to_db_chart(class_id)
)
song = self.data.local.music.get_song(self.game, self.music_version, music_id, self.game_to_db_chart(class_id))
notecount = song.data.get("notecount", 0)
# Construct the dictionary for the broadcast
card_data = {
@ -1678,15 +1606,9 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
secret.add_child(Node.s64_array("flg2", [-1, -1, -1]))
secret.add_child(Node.s64_array("flg3", [-1, -1, -1]))
else:
secret.add_child(
Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3))
)
secret.add_child(
Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3))
)
secret.add_child(
Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3))
)
secret.add_child(Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3)))
secret.add_child(Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3)))
secret.add_child(Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3)))
# Favorites
for folder in ["favorite1", "favorite2", "favorite3"]:
@ -1748,9 +1670,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
)
),
)
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in achievements:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1822,21 +1742,11 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
qpro_secrete_dict = profile.get_dict("qpro_secret")
qpro_secret = Node.void("qpro_secret")
root.add_child(qpro_secret)
qpro_secret.add_child(
Node.s64_array("head", qpro_secrete_dict.get_int_array("head", 5))
)
qpro_secret.add_child(
Node.s64_array("hair", qpro_secrete_dict.get_int_array("hair", 5))
)
qpro_secret.add_child(
Node.s64_array("face", qpro_secrete_dict.get_int_array("face", 5))
)
qpro_secret.add_child(
Node.s64_array("body", qpro_secrete_dict.get_int_array("body", 5))
)
qpro_secret.add_child(
Node.s64_array("hand", qpro_secrete_dict.get_int_array("hand", 5))
)
qpro_secret.add_child(Node.s64_array("head", qpro_secrete_dict.get_int_array("head", 5)))
qpro_secret.add_child(Node.s64_array("hair", qpro_secrete_dict.get_int_array("hair", 5)))
qpro_secret.add_child(Node.s64_array("face", qpro_secrete_dict.get_int_array("face", 5)))
qpro_secret.add_child(Node.s64_array("body", qpro_secrete_dict.get_int_array("body", 5)))
qpro_secret.add_child(Node.s64_array("hand", qpro_secrete_dict.get_int_array("hand", 5)))
# Rivals
rlist = Node.void("rlist")
@ -1908,9 +1818,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
[
courseid, # course ID
coursechart, # course chart
self.db_to_game_status(
course.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(course.data.get_int("clear_status")), # course clear status
course.data.get_int("pgnum"), # flashing great count
course.data.get_int("gnum"), # great count
],
@ -1928,9 +1836,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
[
courseid, # course ID
coursechart, # course chart
self.db_to_game_status(
course.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(course.data.get_int("clear_status")), # course clear status
course.data.get_int("pgnum"), # flashing great count
course.data.get_int("gnum"), # great count
],
@ -1965,12 +1871,8 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
dj_rank_node = Node.void("dj_rank")
root.add_child(dj_rank_node)
dj_rank_node.set_attribute("style", str(dj_rank.id))
dj_rank_node.add_child(
Node.s32_array("rank", dj_rank.data.get_int_array("rank", 15))
)
dj_rank_node.add_child(
Node.s32_array("point", dj_rank.data.get_int_array("point", 15))
)
dj_rank_node.add_child(Node.s32_array("rank", dj_rank.data.get_int_array("rank", 15)))
dj_rank_node.add_child(Node.s32_array("point", dj_rank.data.get_int_array("point", 15)))
for i in range(2):
for j in range(15):
@ -1997,24 +1899,12 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
event1 = Node.void("event1")
root.add_child(event1)
event1.set_attribute("tuneup_point", str(event1_dict.get_int("tuneup_point")))
event1.set_attribute(
"body_parts_list", str(event1_dict.get_int("body_parts_list"))
)
event1.set_attribute(
"engine_parts_list", str(event1_dict.get_int("engine_parts_list"))
)
event1.set_attribute(
"tire_parts_list", str(event1_dict.get_int("tire_parts_list"))
)
event1.set_attribute(
"body_equip_parts", str(event1_dict.get_int("body_equip_parts"))
)
event1.set_attribute(
"engine_equip_parts", str(event1_dict.get_int("engine_equip_parts"))
)
event1.set_attribute(
"tire_equip_parts", str(event1_dict.get_int("tire_equip_parts"))
)
event1.set_attribute("body_parts_list", str(event1_dict.get_int("body_parts_list")))
event1.set_attribute("engine_parts_list", str(event1_dict.get_int("engine_parts_list")))
event1.set_attribute("tire_parts_list", str(event1_dict.get_int("tire_parts_list")))
event1.set_attribute("body_equip_parts", str(event1_dict.get_int("body_equip_parts")))
event1.set_attribute("engine_equip_parts", str(event1_dict.get_int("engine_equip_parts")))
event1.set_attribute("tire_equip_parts", str(event1_dict.get_int("tire_equip_parts")))
event1.set_attribute("gift_point", str(event1_dict.get_int("play_gift")))
for map_data in achievements:
@ -2023,59 +1913,29 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
map_data_node = Node.void("map_data")
event1.add_child(map_data_node)
map_data_node.set_attribute("map_id", str(map_data.id))
map_data_node.set_attribute(
"play_num", str(map_data.data.get_int("play_num"))
)
map_data_node.set_attribute(
"progress", str(map_data.data.get_int("progress"))
)
map_data_node.set_attribute(
"boost_fuel", str(map_data.data.get_int("boost_fuel"))
)
map_data_node.set_attribute(
"is_clear", str(map_data.data.get_int("is_clear"))
)
map_data_node.set_attribute(
"rare_defeat_list", str(map_data.data.get_int("rare_defeat_list"))
)
map_data_node.set_attribute(
"rare1_appearance", str(map_data.data.get_int("rare1_appearance"))
)
map_data_node.set_attribute(
"rare2_appearance", str(map_data.data.get_int("rare2_appearance"))
)
map_data_node.set_attribute(
"rare3_appearance", str(map_data.data.get_int("rare3_appearance"))
)
map_data_node.set_attribute(
"rare4_appearance", str(map_data.data.get_int("rare4_appearance"))
)
map_data_node.set_attribute(
"rare5_appearance", str(map_data.data.get_int("rare5_appearance"))
)
map_data_node.set_attribute(
"rare6_appearance", str(map_data.data.get_int("rare6_appearance"))
)
map_data_node.set_attribute("play_num", str(map_data.data.get_int("play_num")))
map_data_node.set_attribute("progress", str(map_data.data.get_int("progress")))
map_data_node.set_attribute("boost_fuel", str(map_data.data.get_int("boost_fuel")))
map_data_node.set_attribute("is_clear", str(map_data.data.get_int("is_clear")))
map_data_node.set_attribute("rare_defeat_list", str(map_data.data.get_int("rare_defeat_list")))
map_data_node.set_attribute("rare1_appearance", str(map_data.data.get_int("rare1_appearance")))
map_data_node.set_attribute("rare2_appearance", str(map_data.data.get_int("rare2_appearance")))
map_data_node.set_attribute("rare3_appearance", str(map_data.data.get_int("rare3_appearance")))
map_data_node.set_attribute("rare4_appearance", str(map_data.data.get_int("rare4_appearance")))
map_data_node.set_attribute("rare5_appearance", str(map_data.data.get_int("rare5_appearance")))
map_data_node.set_attribute("rare6_appearance", str(map_data.data.get_int("rare6_appearance")))
# OMES Data
omes_dict = profile.get_dict("omes")
onemore_data = Node.void("onemore_event")
root.add_child(onemore_data)
for i in range(6):
onemore_data.set_attribute(
f"defeat_{i}", str(omes_dict.get_int(f"defeat_{i}"))
)
onemore_data.set_attribute(f"defeat_{i}", str(omes_dict.get_int(f"defeat_{i}")))
for i in range(3):
i = i + 1
onemore_data.set_attribute(
f"challenge_num_{i}_n", str(omes_dict.get_int(f"challenge_num_{i}_n"))
)
onemore_data.set_attribute(
f"challenge_num_{i}_h", str(omes_dict.get_int(f"challenge_num_{i}_h"))
)
onemore_data.set_attribute(
f"challenge_num_{i}_a", str(omes_dict.get_int(f"challenge_num_{i}_a"))
)
onemore_data.set_attribute(f"challenge_num_{i}_n", str(omes_dict.get_int(f"challenge_num_{i}_n")))
onemore_data.set_attribute(f"challenge_num_{i}_h", str(omes_dict.get_int(f"challenge_num_{i}_h")))
onemore_data.set_attribute(f"challenge_num_{i}_a", str(omes_dict.get_int(f"challenge_num_{i}_a")))
# Step up mode
step_dict = profile.get_dict("step")
@ -2084,18 +1944,14 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
step.set_attribute("enemy_damage", str(step_dict.get_int("enemy_damage")))
step.set_attribute("progress", str(step_dict.get_int("progress")))
step.set_attribute("point", str(step_dict.get_int("point")))
step.set_attribute(
"enemy_defeat_flg", str(step_dict.get_int("enemy_defeat_flg"))
)
step.set_attribute("enemy_defeat_flg", str(step_dict.get_int("enemy_defeat_flg")))
step.set_attribute("sp_level", str(step_dict.get_int("sp_level")))
step.set_attribute("dp_level", str(step_dict.get_int("dp_level")))
step.set_attribute("sp_mplay", str(step_dict.get_int("sp_mplay")))
step.set_attribute("dp_mplay", str(step_dict.get_int("dp_mplay")))
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -2118,36 +1974,24 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
achievement_node.set_attribute("pack", "0")
achievement_node.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievement_node.set_attribute(
"pack", str(daily_played.get_int("pack_flg"))
)
achievement_node.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievement_node.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievement_node.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievement_node.set_attribute(
"last_weekly", str(profile.get_int("last_weekly"))
)
achievement_node.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
achievement_node.set_attribute("weekly_num", str(profile.get_int("weekly_num")))
# Prefecture visit flag
achievement_node.set_attribute("visit_flg", str(profile.get_int("visit_flg")))
# Number of rivals beaten
achievement_node.set_attribute(
"rival_crush", str(profile.get_int("rival_crush"))
)
achievement_node.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievement_node.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 20))
)
achievement_node.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 20)))
# Track deller
deller = Node.void("deller")
@ -2170,9 +2014,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
detail.set_attribute("course_id", str(rank.id))
detail.set_attribute("n_point", str(rank.data.get_int("normal_points")))
detail.set_attribute("h_point", str(rank.data.get_int("hyper_points")))
detail.set_attribute(
"a_point", str(rank.data.get_int("another_points"))
)
detail.set_attribute("a_point", str(rank.data.get_int("another_points")))
nostalgia = Node.void("nostalgia_open")
root.add_child(nostalgia)
@ -2185,9 +2027,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
pay_per_use.set_attribute("item_num", "99")
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -2239,12 +2079,8 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
newprofile.replace_int("d_gauge_disp", int(request.attribute("d_gauge_disp")))
newprofile.replace_int("s_lane_brignt", int(request.attribute("s_lane_brignt")))
newprofile.replace_int("d_lane_brignt", int(request.attribute("d_lane_brignt")))
newprofile.replace_int(
"s_camera_layout", int(request.attribute("s_camera_layout"))
)
newprofile.replace_int(
"d_camera_layout", int(request.attribute("d_camera_layout"))
)
newprofile.replace_int("s_camera_layout", int(request.attribute("s_camera_layout")))
newprofile.replace_int("d_camera_layout", int(request.attribute("d_camera_layout")))
newprofile.replace_int("s_lift", int(request.attribute("s_lift")))
newprofile.replace_int("d_lift", int(request.attribute("d_lift")))
newprofile.replace_int("mode", int(request.attribute("mode")))
@ -2272,15 +2108,9 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:
@ -2304,9 +2134,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
# Deller saving
deller = request.child("deller")
if deller is not None:
newprofile.replace_int(
"deller", newprofile.get_int("deller") + int(deller.attribute("deller"))
)
newprofile.replace_int("deller", newprofile.get_int("deller") + int(deller.attribute("deller")))
# Secret course expert point saving
expert_point = request.child("expert_point")
@ -2370,22 +2198,14 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
for i in range(self.FAVORITE_LIST_LENGTH):
singles.append(
{
"id": struct.unpack(
"<L", single_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", single_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[0],
}
)
doubles.append(
{
"id": struct.unpack(
"<L", double_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", double_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[0],
}
)
@ -2426,27 +2246,13 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
event1 = request.child("event1")
if event1 is not None:
event1_dict = newprofile.get_dict("event1")
event1_dict.replace_int(
"tuneup_point", int(event1.attribute("tuneup_point"))
)
event1_dict.replace_int(
"body_parts_list", int(event1.attribute("body_parts_list"))
)
event1_dict.replace_int(
"engine_parts_list", int(event1.attribute("engine_parts_list"))
)
event1_dict.replace_int(
"tire_parts_list", int(event1.attribute("tire_parts_list"))
)
event1_dict.replace_int(
"body_equip_parts", int(event1.attribute("body_equip_parts"))
)
event1_dict.replace_int(
"engine_equip_parts", int(event1.attribute("engine_equip_parts"))
)
event1_dict.replace_int(
"tire_equip_parts", int(event1.attribute("tire_equip_parts"))
)
event1_dict.replace_int("tuneup_point", int(event1.attribute("tuneup_point")))
event1_dict.replace_int("body_parts_list", int(event1.attribute("body_parts_list")))
event1_dict.replace_int("engine_parts_list", int(event1.attribute("engine_parts_list")))
event1_dict.replace_int("tire_parts_list", int(event1.attribute("tire_parts_list")))
event1_dict.replace_int("body_equip_parts", int(event1.attribute("body_equip_parts")))
event1_dict.replace_int("engine_equip_parts", int(event1.attribute("engine_equip_parts")))
event1_dict.replace_int("tire_equip_parts", int(event1.attribute("tire_equip_parts")))
event1_dict.replace_int("play_gift", int(event1.attribute("play_gift")))
event1_dict.replace_bool("is_use_gift", event1.child_value("is_use_gift"))
for map_data in event1.children:
@ -2494,9 +2300,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
step_dict.replace_int("enemy_damage", int(step.attribute("enemy_damage")))
step_dict.replace_int("progress", int(step.attribute("progress")))
step_dict.replace_int("point", int(step.attribute("point")))
step_dict.replace_int(
"enemy_defeat_flg", int(step.attribute("enemy_defeat_flg"))
)
step_dict.replace_int("enemy_defeat_flg", int(step.attribute("enemy_defeat_flg")))
step_dict.replace_int("sp_level", int(step.attribute("sp_level")))
step_dict.replace_int("dp_level", int(step.attribute("dp_level")))
step_dict.replace_int("sp_mplay", int(step.attribute("sp_mplay")))
@ -2518,21 +2322,11 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
qpro_secret = request.child("qpro_secret")
if qpro_secret is not None:
qpro_secret_dict = newprofile.get_dict("qpro_secret")
qpro_secret_dict.replace_int_array(
"head", 5, qpro_secret.child_value("head")
)
qpro_secret_dict.replace_int_array(
"hair", 5, qpro_secret.child_value("hair")
)
qpro_secret_dict.replace_int_array(
"face", 5, qpro_secret.child_value("face")
)
qpro_secret_dict.replace_int_array(
"body", 5, qpro_secret.child_value("body")
)
qpro_secret_dict.replace_int_array(
"hand", 5, qpro_secret.child_value("hand")
)
qpro_secret_dict.replace_int_array("head", 5, qpro_secret.child_value("head"))
qpro_secret_dict.replace_int_array("hair", 5, qpro_secret.child_value("hair"))
qpro_secret_dict.replace_int_array("face", 5, qpro_secret.child_value("face"))
qpro_secret_dict.replace_int_array("body", 5, qpro_secret.child_value("body"))
qpro_secret_dict.replace_int_array("hand", 5, qpro_secret.child_value("hand"))
newprofile.replace_dict("qpro_secret", qpro_secret_dict)
# Orb data saving
@ -2549,9 +2343,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
if onemore_data is not None:
omes_dict = newprofile.get_dict("omes")
for i in range(6):
omes_dict.replace_int(
f"defeat_{i}", int(onemore_data.attribute(f"defeat_{i}"))
)
omes_dict.replace_int(f"defeat_{i}", int(onemore_data.attribute(f"defeat_{i}")))
for i in range(3):
i = i + 1
omes_dict.replace_int(

View File

@ -104,28 +104,15 @@ class IIDXCopula(IIDXCourse, IIDXBase):
return IIDXPendual(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -149,9 +136,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -357,9 +342,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root = Node.void("IIDX23shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -383,9 +366,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return root
@ -410,9 +391,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -527,16 +506,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root = Node.void("IIDX23music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -580,16 +550,12 @@ class IIDXCopula(IIDXCourse, IIDXBase):
continue
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -597,10 +563,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -643,19 +606,13 @@ class IIDXCopula(IIDXCourse, IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
if not global_scores:
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -707,9 +664,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -733,10 +688,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -884,9 +836,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -1318,9 +1268,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
used_secret_ids: List[int] = []
for c in secret_courses:
if c["id"] in used_secret_ids:
raise Exception(
"Cannot have multiple secret courses with the same ID!"
)
raise Exception("Cannot have multiple secret courses with the same ID!")
elif c["id"] < 0 or c["id"] >= 20:
raise Exception("Secret course ID is out of bounds!")
else:
@ -1497,9 +1445,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
best_clear_string = clear_map.get(best_clear, "NO PLAY")
now_clear_string = clear_map.get(now_clear, "NO PLAY")
# let's get the song info first
song = self.data.local.music.get_song(
self.game, self.music_version, music_id, self.game_to_db_chart(class_id)
)
song = self.data.local.music.get_song(self.game, self.music_version, music_id, self.game_to_db_chart(class_id))
notecount = song.data.get("notecount", 0)
# Construct the dictionary for the broadcast
card_data = {
@ -1609,15 +1555,9 @@ class IIDXCopula(IIDXCourse, IIDXBase):
secret.add_child(Node.s64_array("flg2", [-1, -1, -1, -1]))
secret.add_child(Node.s64_array("flg3", [-1, -1, -1, -1]))
else:
secret.add_child(
Node.s64_array("flg1", secret_dict.get_int_array("flg1", 4))
)
secret.add_child(
Node.s64_array("flg2", secret_dict.get_int_array("flg2", 4))
)
secret.add_child(
Node.s64_array("flg3", secret_dict.get_int_array("flg3", 4))
)
secret.add_child(Node.s64_array("flg1", secret_dict.get_int_array("flg1", 4)))
secret.add_child(Node.s64_array("flg2", secret_dict.get_int_array("flg2", 4)))
secret.add_child(Node.s64_array("flg3", secret_dict.get_int_array("flg3", 4)))
# Favorites
for folder in ["favorite1", "favorite2", "favorite3"]:
@ -1679,9 +1619,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
)
),
)
rankings = self.data.local.user.get_achievements(
self.game, self.version, userid
)
rankings = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in rankings:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1822,9 +1760,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
[
int(rank.id / 6), # course ID
rank.id % 6, # course chart
self.db_to_game_status(
rank.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(rank.data.get_int("clear_status")), # course clear status
rank.data.get_int("pgnum"), # flashing great count
rank.data.get_int("gnum"), # great count
],
@ -1841,9 +1777,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
[
int(rank.id / 6), # course ID
rank.id % 6, # course chart
self.db_to_game_status(
rank.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(rank.data.get_int("clear_status")), # course clear status
rank.data.get_int("pgnum"), # flashing great count
rank.data.get_int("gnum"), # great count
],
@ -1881,16 +1815,12 @@ class IIDXCopula(IIDXCourse, IIDXBase):
step.add_child(
Node.binary(
"tokimeki",
step_dict.get_bytes(
"tokimeki", b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
),
step_dict.get_bytes("tokimeki", b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
)
)
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -1913,15 +1843,11 @@ class IIDXCopula(IIDXCourse, IIDXBase):
achievements.set_attribute("pack", "0")
achievements.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievements.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievements.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievements.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievements.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
@ -1934,9 +1860,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
achievements.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievements.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 10))
)
achievements.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 10)))
# Track deller
deller = Node.void("deller")
@ -1959,9 +1883,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
detail.set_attribute("course_id", str(rank.id))
detail.set_attribute("n_point", str(rank.data.get_int("normal_points")))
detail.set_attribute("h_point", str(rank.data.get_int("hyper_points")))
detail.set_attribute(
"a_point", str(rank.data.get_int("another_points"))
)
detail.set_attribute("a_point", str(rank.data.get_int("another_points")))
# Tokotoko Line Event
if "event1" in profile:
@ -1969,31 +1891,15 @@ class IIDXCopula(IIDXCourse, IIDXBase):
event1_dict = profile.get_dict("event1")
event1_data = Node.void("event1_data")
root.add_child(event1_data)
event1_data.set_attribute(
"point_map_0", str(event1_dict.get_int("point_map_0"))
)
event1_data.set_attribute(
"point_map_1", str(event1_dict.get_int("point_map_1"))
)
event1_data.set_attribute(
"point_map_2", str(event1_dict.get_int("point_map_2"))
)
event1_data.set_attribute(
"point_map_3", str(event1_dict.get_int("point_map_3"))
)
event1_data.set_attribute(
"point_map_4", str(event1_dict.get_int("point_map_4"))
)
event1_data.set_attribute(
"hold_point", str(event1_dict.get_int("hold_point"))
)
event1_data.set_attribute("point_map_0", str(event1_dict.get_int("point_map_0")))
event1_data.set_attribute("point_map_1", str(event1_dict.get_int("point_map_1")))
event1_data.set_attribute("point_map_2", str(event1_dict.get_int("point_map_2")))
event1_data.set_attribute("point_map_3", str(event1_dict.get_int("point_map_3")))
event1_data.set_attribute("point_map_4", str(event1_dict.get_int("point_map_4")))
event1_data.set_attribute("hold_point", str(event1_dict.get_int("hold_point")))
event1_data.set_attribute("last_map", str(event1_dict.get_int("last_map")))
event1_data.set_attribute(
"rank_point", str(event1_dict.get_int("rank_point"))
)
event1_data.set_attribute(
"tips_list", str(event1_dict.get_int("tips_list"))
)
event1_data.set_attribute("rank_point", str(event1_dict.get_int("rank_point")))
event1_data.set_attribute("tips_list", str(event1_dict.get_int("tips_list")))
event1_data.set_attribute("gift_point", "0")
# Mystery Line Event
@ -2004,16 +1910,10 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root.add_child(event2_data)
event2_data.set_attribute("play_num", str(event2_dict.get_int("play_num")))
event2_data.set_attribute("now_area", str(event2_dict.get_int("now_area")))
event2_data.set_attribute(
"now_note_grade", str(event2_dict.get_int("now_note_grade"))
)
event2_data.set_attribute(
"stop_area_time", str(event2_dict.get_int("stop_area_time"))
)
event2_data.set_attribute("now_note_grade", str(event2_dict.get_int("now_note_grade")))
event2_data.set_attribute("stop_area_time", str(event2_dict.get_int("stop_area_time")))
areas = self.data.local.user.get_achievements(
self.game, self.version, userid
)
areas = self.data.local.user.get_achievements(self.game, self.version, userid)
for area in areas:
if area.type != "event2_area_data":
continue
@ -2021,18 +1921,10 @@ class IIDXCopula(IIDXCourse, IIDXBase):
event2_area_data = Node.void("event2_area_data")
event2_data.add_child(event2_area_data)
event2_area_data.set_attribute("area_no", str(area.id))
event2_area_data.set_attribute(
"area_play", str(area.data.get_int("play_num"))
)
event2_area_data.set_attribute(
"normal_point", str(area.data.get_int("normal_point"))
)
event2_area_data.set_attribute(
"hyper_point", str(area.data.get_int("hyper_point"))
)
event2_area_data.set_attribute(
"another_point", str(area.data.get_int("another_point"))
)
event2_area_data.set_attribute("area_play", str(area.data.get_int("play_num")))
event2_area_data.set_attribute("normal_point", str(area.data.get_int("normal_point")))
event2_area_data.set_attribute("hyper_point", str(area.data.get_int("hyper_point")))
event2_area_data.set_attribute("another_point", str(area.data.get_int("another_point")))
# One More Event
if "onemore" in profile:
@ -2040,42 +1932,22 @@ class IIDXCopula(IIDXCourse, IIDXBase):
onemore_dict = profile.get_dict("onemore")
onemore_data = Node.void("onemore_data")
root.add_child(onemore_data)
onemore_data.set_attribute(
"defeat_0", str(onemore_dict.get_int("defeat_0"))
)
onemore_data.set_attribute(
"defeat_1", str(onemore_dict.get_int("defeat_1"))
)
onemore_data.set_attribute(
"defeat_2", str(onemore_dict.get_int("defeat_2"))
)
onemore_data.set_attribute(
"defeat_3", str(onemore_dict.get_int("defeat_3"))
)
onemore_data.set_attribute(
"defeat_4", str(onemore_dict.get_int("defeat_4"))
)
onemore_data.set_attribute(
"defeat_5", str(onemore_dict.get_int("defeat_5"))
)
onemore_data.set_attribute(
"challenge_num_n", str(onemore_dict.get_int("challenge_num_n"))
)
onemore_data.set_attribute(
"challenge_num_h", str(onemore_dict.get_int("challenge_num_h"))
)
onemore_data.set_attribute(
"challenge_num_a", str(onemore_dict.get_int("challenge_num_a"))
)
onemore_data.set_attribute("defeat_0", str(onemore_dict.get_int("defeat_0")))
onemore_data.set_attribute("defeat_1", str(onemore_dict.get_int("defeat_1")))
onemore_data.set_attribute("defeat_2", str(onemore_dict.get_int("defeat_2")))
onemore_data.set_attribute("defeat_3", str(onemore_dict.get_int("defeat_3")))
onemore_data.set_attribute("defeat_4", str(onemore_dict.get_int("defeat_4")))
onemore_data.set_attribute("defeat_5", str(onemore_dict.get_int("defeat_5")))
onemore_data.set_attribute("challenge_num_n", str(onemore_dict.get_int("challenge_num_n")))
onemore_data.set_attribute("challenge_num_h", str(onemore_dict.get_int("challenge_num_h")))
onemore_data.set_attribute("challenge_num_a", str(onemore_dict.get_int("challenge_num_a")))
# Ea app features
if self.data.triggers.has_broadcast_destination(self.game):
root.add_child(Node.void("bind_eaappli"))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -2151,15 +2023,9 @@ class IIDXCopula(IIDXCourse, IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:
@ -2183,9 +2049,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
# Deller saving
deller = request.child("deller")
if deller is not None:
newprofile.replace_int(
"deller", newprofile.get_int("deller") + int(deller.attribute("deller"))
)
newprofile.replace_int("deller", newprofile.get_int("deller") + int(deller.attribute("deller")))
# Secret course expert point saving
expert_point = request.child("expert_point")
@ -2249,22 +2113,14 @@ class IIDXCopula(IIDXCourse, IIDXBase):
for i in range(self.FAVORITE_LIST_LENGTH):
singles.append(
{
"id": struct.unpack(
"<L", single_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", single_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[0],
}
)
doubles.append(
{
"id": struct.unpack(
"<L", double_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", double_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[0],
}
)
@ -2312,47 +2168,25 @@ class IIDXCopula(IIDXCourse, IIDXBase):
event1_data = request.child("event1_data")
if event1_data is not None:
event1_dict = newprofile.get_dict("event1")
event1_dict.replace_int(
"hold_point", int(event1_data.attribute("hold_point"))
)
event1_dict.replace_int("hold_point", int(event1_data.attribute("hold_point")))
event1_dict.replace_int("last_map", int(event1_data.attribute("last_map")))
event1_dict.replace_int(
"rank_point", int(event1_data.attribute("rank_point"))
)
event1_dict.replace_int(
"tips_list", int(event1_data.attribute("tips_list"))
)
event1_dict.replace_int(
"point_map_0", int(event1_data.attribute("point_map_0"))
)
event1_dict.replace_int(
"point_map_1", int(event1_data.attribute("point_map_1"))
)
event1_dict.replace_int(
"point_map_2", int(event1_data.attribute("point_map_2"))
)
event1_dict.replace_int(
"point_map_3", int(event1_data.attribute("point_map_3"))
)
event1_dict.replace_int(
"point_map_4", int(event1_data.attribute("point_map_4"))
)
event1_dict.replace_int("rank_point", int(event1_data.attribute("rank_point")))
event1_dict.replace_int("tips_list", int(event1_data.attribute("tips_list")))
event1_dict.replace_int("point_map_0", int(event1_data.attribute("point_map_0")))
event1_dict.replace_int("point_map_1", int(event1_data.attribute("point_map_1")))
event1_dict.replace_int("point_map_2", int(event1_data.attribute("point_map_2")))
event1_dict.replace_int("point_map_3", int(event1_data.attribute("point_map_3")))
event1_dict.replace_int("point_map_4", int(event1_data.attribute("point_map_4")))
newprofile.replace_dict("event1", event1_dict)
# Mystery Line Event
event2_data = request.child("event2_data")
if event2_data is not None:
event2_dict = newprofile.get_dict("event2")
event2_dict.replace_int(
"now_area", int(event2_data.attribute("now_stay_area"))
)
event2_dict.replace_int(
"now_note_grade", int(event2_data.attribute("now_stay_note_grade"))
)
event2_dict.replace_int("now_area", int(event2_data.attribute("now_stay_area")))
event2_dict.replace_int("now_note_grade", int(event2_data.attribute("now_stay_note_grade")))
event2_dict.replace_int("play_num", int(event2_data.attribute("play_num")))
event2_dict.replace_int(
"stop_area_time", int(event2_data.attribute("stop_area_time"))
)
event2_dict.replace_int("stop_area_time", int(event2_data.attribute("stop_area_time")))
newprofile.replace_dict("event2", event2_dict)
for area_data in event2_data.children:
@ -2378,33 +2212,15 @@ class IIDXCopula(IIDXCourse, IIDXBase):
onemore_data = request.child("onemore_data")
if onemore_data is not None:
onemore_dict = newprofile.get_dict("onemore")
onemore_dict.replace_int(
"defeat_0", int(onemore_data.attribute("defeat_0"))
)
onemore_dict.replace_int(
"defeat_1", int(onemore_data.attribute("defeat_1"))
)
onemore_dict.replace_int(
"defeat_2", int(onemore_data.attribute("defeat_2"))
)
onemore_dict.replace_int(
"defeat_3", int(onemore_data.attribute("defeat_3"))
)
onemore_dict.replace_int(
"defeat_4", int(onemore_data.attribute("defeat_4"))
)
onemore_dict.replace_int(
"defeat_5", int(onemore_data.attribute("defeat_5"))
)
onemore_dict.replace_int(
"challenge_num_n", int(onemore_data.attribute("challenge_num_n"))
)
onemore_dict.replace_int(
"challenge_num_h", int(onemore_data.attribute("challenge_num_h"))
)
onemore_dict.replace_int(
"challenge_num_a", int(onemore_data.attribute("challenge_num_a"))
)
onemore_dict.replace_int("defeat_0", int(onemore_data.attribute("defeat_0")))
onemore_dict.replace_int("defeat_1", int(onemore_data.attribute("defeat_1")))
onemore_dict.replace_int("defeat_2", int(onemore_data.attribute("defeat_2")))
onemore_dict.replace_int("defeat_3", int(onemore_data.attribute("defeat_3")))
onemore_dict.replace_int("defeat_4", int(onemore_data.attribute("defeat_4")))
onemore_dict.replace_int("defeat_5", int(onemore_data.attribute("defeat_5")))
onemore_dict.replace_int("challenge_num_n", int(onemore_data.attribute("challenge_num_n")))
onemore_dict.replace_int("challenge_num_h", int(onemore_data.attribute("challenge_num_h")))
onemore_dict.replace_int("challenge_num_a", int(onemore_data.attribute("challenge_num_a")))
newprofile.replace_dict("onemore", onemore_dict)
# Keep track of play statistics across all mixes

View File

@ -56,12 +56,8 @@ class IIDXCourse(IIDXBase):
)
if course_score is None:
course_score = ValidatedDict()
course_score.replace_int(
"clear_status", max(clear_status, course_score.get_int("clear_status"))
)
old_ex_score = (course_score.get_int("pgnum") * 2) + course_score.get_int(
"gnum"
)
course_score.replace_int("clear_status", max(clear_status, course_score.get_int("clear_status")))
old_ex_score = (course_score.get_int("pgnum") * 2) + course_score.get_int("gnum")
if old_ex_score < ((pgreats * 2) + greats):
course_score.replace_int("pgnum", pgreats)
course_score.replace_int("gnum", greats)

View File

@ -101,28 +101,15 @@ class IIDXPendual(IIDXCourse, IIDXBase):
return IIDXSpada(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -146,9 +133,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -243,9 +228,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
root = Node.void("IIDX22shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -269,9 +252,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return root
@ -291,9 +272,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -530,16 +509,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
root = Node.void("IIDX22music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -583,16 +553,12 @@ class IIDXPendual(IIDXCourse, IIDXBase):
continue
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -600,10 +566,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -646,19 +609,13 @@ class IIDXPendual(IIDXCourse, IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
if not global_scores:
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -710,9 +667,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -736,10 +691,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -887,9 +839,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -1240,9 +1190,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
used_secret_ids: List[int] = []
for c in secret_courses:
if c["id"] in used_secret_ids:
raise Exception(
"Cannot have multiple secret courses with the same ID!"
)
raise Exception("Cannot have multiple secret courses with the same ID!")
elif c["id"] < 0 or c["id"] >= 10:
raise Exception("Secret course ID is out of bounds!")
else:
@ -1272,13 +1220,9 @@ class IIDXPendual(IIDXCourse, IIDXBase):
common_timeshift_phase = Node.void("common_timeshift_phase")
root.add_child(common_timeshift_phase)
if timeshift_override == 0:
common_timeshift_phase.set_attribute(
"phase", "1" if (days_since_epoch % 2) == 0 else "2"
)
common_timeshift_phase.set_attribute("phase", "1" if (days_since_epoch % 2) == 0 else "2")
elif timeshift_override == 1:
common_timeshift_phase.set_attribute(
"phase", "2" if (days_since_epoch % 2) == 0 else "1"
)
common_timeshift_phase.set_attribute("phase", "2" if (days_since_epoch % 2) == 0 else "1")
elif timeshift_override == 2:
common_timeshift_phase.set_attribute("phase", "1")
elif timeshift_override == 3:
@ -1306,9 +1250,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
# Ranking details in title screen
rankingcharts = []
for mid, _plays in self.data.local.music.get_hit_chart(
self.game, self.music_version, 20
):
for mid, _plays in self.data.local.music.get_hit_chart(self.game, self.music_version, 20):
rankingcharts.append(mid)
root.add_child(Node.u16_array("monthly_mranking", rankingcharts))
root.add_child(Node.u16_array("total_mranking", rankingcharts))
@ -1467,9 +1409,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
best_clear_string = clear_map.get(best_clear, "NO PLAY")
now_clear_string = clear_map.get(now_clear, "NO PLAY")
# let's get the song info first
song = self.data.local.music.get_song(
self.game, self.music_version, music_id, self.game_to_db_chart(class_id)
)
song = self.data.local.music.get_song(self.game, self.music_version, music_id, self.game_to_db_chart(class_id))
notecount = song.data.get("notecount", 0)
# Construct the dictionary for the broadcast
card_data = {
@ -1578,9 +1518,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
join_shop.set_attribute("join_name", machine.name)
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -1611,15 +1549,9 @@ class IIDXPendual(IIDXCourse, IIDXBase):
secret.add_child(Node.s64_array("flg2", [-1, -1, -1]))
secret.add_child(Node.s64_array("flg3", [-1, -1, -1]))
else:
secret.add_child(
Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3))
)
secret.add_child(
Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3))
)
secret.add_child(
Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3))
)
secret.add_child(Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3)))
secret.add_child(Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3)))
secret.add_child(Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3)))
# Tran medals and shit
achievements = Node.void("achievements")
@ -1630,15 +1562,11 @@ class IIDXPendual(IIDXCourse, IIDXBase):
achievements.set_attribute("pack", "0")
achievements.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievements.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievements.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievements.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievements.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
@ -1651,9 +1579,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
achievements.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievements.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 10))
)
achievements.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 10)))
# User settings
settings_dict = profile.get_dict("settings")
@ -1699,9 +1625,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
)
),
)
rankings = self.data.local.user.get_achievements(
self.game, self.version, userid
)
rankings = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in rankings:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1739,9 +1663,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
[
int(rank.id / 6), # course ID
rank.id % 6, # course chart
self.db_to_game_status(
rank.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(rank.data.get_int("clear_status")), # course clear status
rank.data.get_int("pgnum"), # flashing great count
rank.data.get_int("gnum"), # great count
],
@ -1758,9 +1680,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
[
int(rank.id / 6), # course ID
rank.id % 6, # course chart
self.db_to_game_status(
rank.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(rank.data.get_int("clear_status")), # course clear status
rank.data.get_int("pgnum"), # flashing great count
rank.data.get_int("gnum"), # great count
],
@ -1776,9 +1696,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
detail.set_attribute("course_id", str(rank.id))
detail.set_attribute("n_point", str(rank.data.get_int("normal_points")))
detail.set_attribute("h_point", str(rank.data.get_int("hyper_points")))
detail.set_attribute(
"a_point", str(rank.data.get_int("another_points"))
)
detail.set_attribute("a_point", str(rank.data.get_int("another_points")))
# Qpro data
qpro_dict = profile.get_dict("qpro")
@ -1880,9 +1798,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
step.add_child(
Node.binary(
"album",
step_dict.get_bytes(
"album", b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
),
step_dict.get_bytes("album", b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
)
)
@ -1962,9 +1878,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
present_time_sandglass.set_attribute("item_num", "99")
# TODO: Same as above.
pointsdict = profile.get_dict(
"point_events"
) # used for summer, dcat, and pyramid
pointsdict = profile.get_dict("point_events") # used for summer, dcat, and pyramid
# destiny event
dcat = Node.void("destiny_catharsis")
root.add_child(dcat)
@ -1980,46 +1894,20 @@ class IIDXPendual(IIDXCourse, IIDXBase):
cdive = Node.void("chrono_diver")
root.add_child(cdive)
cdive.set_attribute("play_count", str(diverdict.get_int("play_count", 0)))
cdive.set_attribute(
"present_unlock", str(diverdict.get_int("present_unlock", 0))
)
cdive.set_attribute("present_unlock", str(diverdict.get_int("present_unlock", 0)))
cdive.set_attribute("future_unlock", str(diverdict.get_int("future_unlock", 0)))
cdive.set_attribute(
"success_count_0_n", str(diverdict.get_int("success_count_0_n", 0))
)
cdive.set_attribute(
"success_count_0_h", str(diverdict.get_int("success_count_0_h", 0))
)
cdive.set_attribute(
"success_count_0_a", str(diverdict.get_int("success_count_0_a", 0))
)
cdive.set_attribute(
"success_count_1_n", str(diverdict.get_int("success_count_1_n", 0))
)
cdive.set_attribute(
"success_count_1_h", str(diverdict.get_int("success_count_1_h", 0))
)
cdive.set_attribute(
"success_count_1_a", str(diverdict.get_int("success_count_1_a", 0))
)
cdive.set_attribute(
"success_count_2_n", str(diverdict.get_int("success_count_2_n", 0))
)
cdive.set_attribute(
"success_count_2_h", str(diverdict.get_int("success_count_2_h", 0))
)
cdive.set_attribute(
"success_count_2_a", str(diverdict.get_int("success_count_2_a", 0))
)
cdive.set_attribute(
"success_count_3_n", str(diverdict.get_int("success_count_3_n", 0))
)
cdive.set_attribute(
"success_count_3_h", str(diverdict.get_int("success_count_3_h", 0))
)
cdive.set_attribute(
"success_count_3_a", str(diverdict.get_int("success_count_3_a", 0))
)
cdive.set_attribute("success_count_0_n", str(diverdict.get_int("success_count_0_n", 0)))
cdive.set_attribute("success_count_0_h", str(diverdict.get_int("success_count_0_h", 0)))
cdive.set_attribute("success_count_0_a", str(diverdict.get_int("success_count_0_a", 0)))
cdive.set_attribute("success_count_1_n", str(diverdict.get_int("success_count_1_n", 0)))
cdive.set_attribute("success_count_1_h", str(diverdict.get_int("success_count_1_h", 0)))
cdive.set_attribute("success_count_1_a", str(diverdict.get_int("success_count_1_a", 0)))
cdive.set_attribute("success_count_2_n", str(diverdict.get_int("success_count_2_n", 0)))
cdive.set_attribute("success_count_2_h", str(diverdict.get_int("success_count_2_h", 0)))
cdive.set_attribute("success_count_2_a", str(diverdict.get_int("success_count_2_a", 0)))
cdive.set_attribute("success_count_3_n", str(diverdict.get_int("success_count_3_n", 0)))
cdive.set_attribute("success_count_3_h", str(diverdict.get_int("success_count_3_h", 0)))
cdive.set_attribute("success_count_3_a", str(diverdict.get_int("success_count_3_a", 0)))
cdive.set_attribute("story_list", str(diverdict.get_int("story_list", 0)))
# reflec beat collaboration
@ -2048,9 +1936,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -2126,15 +2012,9 @@ class IIDXPendual(IIDXCourse, IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:
@ -2158,9 +2038,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
# Deller saving
deller = request.child("deller")
if deller is not None:
newprofile.replace_int(
"deller", newprofile.get_int("deller") + int(deller.attribute("deller"))
)
newprofile.replace_int("deller", newprofile.get_int("deller") + int(deller.attribute("deller")))
# Secret course expert point saving
expert_point = request.child("expert_point")
@ -2212,17 +2090,13 @@ class IIDXPendual(IIDXCourse, IIDXBase):
for i in range(self.FAVORITE_LIST_LENGTH):
singles.append(
{
"id": struct.unpack(
"<L", single_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"id": struct.unpack("<L", single_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[0],
}
)
doubles.append(
{
"id": struct.unpack(
"<L", double_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"id": struct.unpack("<L", double_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[0],
}
)
@ -2272,61 +2146,29 @@ class IIDXPendual(IIDXCourse, IIDXBase):
diverdict = newprofile.get_dict("diver_dict")
diverreq = request.child("chrono_diver")
if diverreq is not None:
diverdict.replace_int(
"future_unlock", int(diverreq.attribute("future_unlock"))
)
diverdict.replace_int("future_unlock", int(diverreq.attribute("future_unlock")))
diverdict.replace_int("play_count", int(diverreq.attribute("play_count")))
diverdict.replace_int(
"present_unlock", int(diverreq.attribute("present_unlock"))
)
diverdict.replace_int("present_unlock", int(diverreq.attribute("present_unlock")))
diverdict.replace_int("story_list", int(diverreq.attribute("story_list")))
diverdict.replace_int(
"success_count_0_a", int(diverreq.attribute("success_count_0_a"))
)
diverdict.replace_int(
"success_count_0_h", int(diverreq.attribute("success_count_0_h"))
)
diverdict.replace_int(
"success_count_0_n", int(diverreq.attribute("success_count_0_n"))
)
diverdict.replace_int(
"success_count_1_a", int(diverreq.attribute("success_count_1_a"))
)
diverdict.replace_int(
"success_count_1_h", int(diverreq.attribute("success_count_1_h"))
)
diverdict.replace_int(
"success_count_1_n", int(diverreq.attribute("success_count_1_n"))
)
diverdict.replace_int(
"success_count_2_a", int(diverreq.attribute("success_count_2_a"))
)
diverdict.replace_int(
"success_count_2_h", int(diverreq.attribute("success_count_2_h"))
)
diverdict.replace_int(
"success_count_2_n", int(diverreq.attribute("success_count_2_n"))
)
diverdict.replace_int(
"success_count_3_a", int(diverreq.attribute("success_count_3_a"))
)
diverdict.replace_int(
"success_count_3_h", int(diverreq.attribute("success_count_3_h"))
)
diverdict.replace_int(
"success_count_3_n", int(diverreq.attribute("success_count_3_n"))
)
diverdict.replace_int("success_count_0_a", int(diverreq.attribute("success_count_0_a")))
diverdict.replace_int("success_count_0_h", int(diverreq.attribute("success_count_0_h")))
diverdict.replace_int("success_count_0_n", int(diverreq.attribute("success_count_0_n")))
diverdict.replace_int("success_count_1_a", int(diverreq.attribute("success_count_1_a")))
diverdict.replace_int("success_count_1_h", int(diverreq.attribute("success_count_1_h")))
diverdict.replace_int("success_count_1_n", int(diverreq.attribute("success_count_1_n")))
diverdict.replace_int("success_count_2_a", int(diverreq.attribute("success_count_2_a")))
diverdict.replace_int("success_count_2_h", int(diverreq.attribute("success_count_2_h")))
diverdict.replace_int("success_count_2_n", int(diverreq.attribute("success_count_2_n")))
diverdict.replace_int("success_count_3_a", int(diverreq.attribute("success_count_3_a")))
diverdict.replace_int("success_count_3_h", int(diverreq.attribute("success_count_3_h")))
diverdict.replace_int("success_count_3_n", int(diverreq.attribute("success_count_3_n")))
newprofile.replace_dict("diver_dict", diverdict)
reflecdict = newprofile.get_dict("reflec_collab")
reflecreq = request.child("reflec_collabo")
if reflecreq is not None:
reflecdict.replace_int(
"phase1_item", int(reflecreq.attribute("phase1_iidx_item"))
)
reflecdict.replace_int(
"phase2_item", int(reflecreq.attribute("phase2_iidx_item"))
)
reflecdict.replace_int("phase1_item", int(reflecreq.attribute("phase1_iidx_item")))
reflecdict.replace_int("phase2_item", int(reflecreq.attribute("phase2_iidx_item")))
newprofile.replace_dict("reflec_collab", reflecdict)
# boss event pendual tailsman points
@ -2342,42 +2184,18 @@ class IIDXPendual(IIDXCourse, IIDXBase):
chorddict = newprofile.get_dict("chord_dict")
chordreq = request.child("qpronicle_chord")
if chordreq is not None:
chorddict.replace_int(
"is_first_select_map", int(chordreq.attribute("is_first_select_map"))
)
chorddict.replace_int(
"is_use_login_bonus", int(chordreq.attribute("is_use_login_bonus"))
)
chorddict.replace_int(
"last_select_map", int(chordreq.attribute("last_select_map"))
)
chorddict.replace_int(
"patona_leader", int(chordreq.attribute("patona_leader"))
)
chorddict.replace_int(
"patona_sub_1", int(chordreq.attribute("patona_sub_1"))
)
chorddict.replace_int(
"patona_sub_2", int(chordreq.attribute("patona_sub_2"))
)
chorddict.replace_int(
"rare_enemy_damage1", int(chordreq.attribute("rare_enemy_damage1"))
)
chorddict.replace_int(
"rare_enemy_damage2", int(chordreq.attribute("rare_enemy_damage2"))
)
chorddict.replace_int(
"rare_enemy_damage3", int(chordreq.attribute("rare_enemy_damage3"))
)
chorddict.replace_int(
"rare_enemy_damage4", int(chordreq.attribute("rare_enemy_damage4"))
)
chorddict.replace_int(
"rare_enemy_damage5", int(chordreq.attribute("rare_enemy_damage5"))
)
chorddict.replace_int(
"story_view_list", int(chordreq.attribute("story_view_list"))
)
chorddict.replace_int("is_first_select_map", int(chordreq.attribute("is_first_select_map")))
chorddict.replace_int("is_use_login_bonus", int(chordreq.attribute("is_use_login_bonus")))
chorddict.replace_int("last_select_map", int(chordreq.attribute("last_select_map")))
chorddict.replace_int("patona_leader", int(chordreq.attribute("patona_leader")))
chorddict.replace_int("patona_sub_1", int(chordreq.attribute("patona_sub_1")))
chorddict.replace_int("patona_sub_2", int(chordreq.attribute("patona_sub_2")))
chorddict.replace_int("rare_enemy_damage1", int(chordreq.attribute("rare_enemy_damage1")))
chorddict.replace_int("rare_enemy_damage2", int(chordreq.attribute("rare_enemy_damage2")))
chorddict.replace_int("rare_enemy_damage3", int(chordreq.attribute("rare_enemy_damage3")))
chorddict.replace_int("rare_enemy_damage4", int(chordreq.attribute("rare_enemy_damage4")))
chorddict.replace_int("rare_enemy_damage5", int(chordreq.attribute("rare_enemy_damage5")))
chorddict.replace_int("story_view_list", int(chordreq.attribute("story_view_list")))
newprofile.replace_dict("chord_dict", chorddict)
# Keep track of play statistics across all mixes

View File

@ -107,28 +107,15 @@ class IIDXRootage(IIDXCourse, IIDXBase):
return IIDXCannonBallers(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -152,9 +139,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -390,9 +375,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root = Node.void("IIDX26shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -415,9 +398,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return Node.void("IIDX26shop")
@ -429,16 +410,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root = Node.void("IIDX26music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -482,16 +454,12 @@ class IIDXRootage(IIDXCourse, IIDXBase):
continue
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -499,10 +467,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -529,9 +494,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -622,18 +585,11 @@ class IIDXRootage(IIDXCourse, IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
shop_id = ID.parse_machine_id(request.attribute("location_id"))
if not global_scores:
all_scores = [
score
for score in all_scores
if (score[0] == userid or score[1].location == shop_id)
]
all_scores = [score for score in all_scores if (score[0] == userid or score[1].location == shop_id)]
# Find our actual index
oldindex = None
@ -684,9 +640,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -707,11 +661,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
all_players[uid] = prof
if not global_scores:
all_scores = [
score
for score in all_scores
if (score[0] == userid or score[1].location == shop_id)
]
all_scores = [score for score in all_scores if (score[0] == userid or score[1].location == shop_id)]
# Find our actual index
ourindex = None
@ -844,13 +794,9 @@ class IIDXRootage(IIDXCourse, IIDXBase):
}
for item in request.children:
if item.name == "music_list":
music_list[int(item.child_value("index"))] = int(
item.child_value("total_notes")
)
music_list[int(item.child_value("index"))] = int(item.child_value("total_notes"))
if item.name == "cpu_list":
cpu_list[int(item.child_value("index"))] = int(
item.child_value("grade_id")
)
cpu_list[int(item.child_value("index"))] = int(item.child_value("grade_id"))
for index in range(4):
cpu_score_list = Node.void("cpu_score_list")
cpu_score_list.add_child(Node.s32("index", index))
@ -991,9 +937,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root.set_attribute("pflg", "0")
return root
def handle_IIDX26pc_shopregister_request(
self, request: Node
) -> Node: # Not used anymore????
def handle_IIDX26pc_shopregister_request(self, request: Node) -> Node: # Not used anymore????
root = Node.void("IIDX26pc")
return root
@ -1115,9 +1059,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
best_clear_string = clear_map.get(best_clear, "NO PLAY")
now_clear_string = clear_map.get(now_clear, "NO PLAY")
# let's get the song info first
song = self.data.local.music.get_song(
self.game, self.music_version, music_id, self.game_to_db_chart(class_id)
)
song = self.data.local.music.get_song(self.game, self.music_version, music_id, self.game_to_db_chart(class_id))
notecount = song.data.get("notecount", 0)
# Construct the dictionary for the broadcast
card_data = {
@ -1239,25 +1181,15 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root.add_child(arena_cpu_define)
arena_cpu_define.add_child(Node.s32("play_style", playstyle))
arena_cpu_define.add_child(Node.s32("arena_class", arena_class))
arena_cpu_define.add_child(
Node.s32("grade_id", cpu_grades[arena_class])
)
arena_cpu_define.add_child(
Node.s32("low_music_difficult", cpu_low_diff[arena_class])
)
arena_cpu_define.add_child(
Node.s32("high_music_difficult", cpu_high_diff[arena_class])
)
arena_cpu_define.add_child(
Node.bool("is_leggendaria", arena_class >= 13)
)
arena_cpu_define.add_child(Node.s32("grade_id", cpu_grades[arena_class]))
arena_cpu_define.add_child(Node.s32("low_music_difficult", cpu_low_diff[arena_class]))
arena_cpu_define.add_child(Node.s32("high_music_difficult", cpu_high_diff[arena_class]))
arena_cpu_define.add_child(Node.bool("is_leggendaria", arena_class >= 13))
for matching_class in range(21):
matching_class_range = Node.void("matching_class_range")
root.add_child(matching_class_range)
matching_class_range.add_child(Node.s32("play_style", playstyle))
matching_class_range.add_child(
Node.s32("matching_class", matching_class)
)
matching_class_range.add_child(Node.s32("matching_class", matching_class))
matching_class_range.add_child(Node.s32("low_arena_class", 1))
matching_class_range.add_child(Node.s32("high_arena_class", 20))
return root
@ -1330,12 +1262,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
pcdata.set_attribute("d_camera_layout", str(profile.get_int("d_camera_layout")))
pcdata.set_attribute("s_ghost_score", str(profile.get_int("s_ghost_score")))
pcdata.set_attribute("d_ghost_score", str(profile.get_int("d_ghost_score")))
pcdata.set_attribute(
"s_tsujigiri_disp", str(profile.get_int("s_tsujigiri_disp"))
)
pcdata.set_attribute(
"d_tsujigiri_disp", str(profile.get_int("d_tsujigiri_disp"))
)
pcdata.set_attribute("s_tsujigiri_disp", str(profile.get_int("s_tsujigiri_disp")))
pcdata.set_attribute("d_tsujigiri_disp", str(profile.get_int("d_tsujigiri_disp")))
# KAC stuff
# kac_entry_info = Node.void('kac_entry_info')
@ -1363,15 +1291,9 @@ class IIDXRootage(IIDXCourse, IIDXBase):
secret.add_child(Node.s64_array("flg2", [-1, -1, -1]))
secret.add_child(Node.s64_array("flg3", [-1, -1, -1]))
else:
secret.add_child(
Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3))
)
secret.add_child(
Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3))
)
secret.add_child(
Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3))
)
secret.add_child(Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3)))
secret.add_child(Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3)))
secret.add_child(Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3)))
# Favorites
for folder in ["favorite1", "favorite2", "favorite3"]:
@ -1420,21 +1342,11 @@ class IIDXRootage(IIDXCourse, IIDXBase):
qpro_secrete_dict = profile.get_dict("qpro_secret")
qpro_secret = Node.void("qpro_secret")
root.add_child(qpro_secret)
qpro_secret.add_child(
Node.s64_array("head", qpro_secrete_dict.get_int_array("head", 5))
)
qpro_secret.add_child(
Node.s64_array("hair", qpro_secrete_dict.get_int_array("hair", 5))
)
qpro_secret.add_child(
Node.s64_array("face", qpro_secrete_dict.get_int_array("face", 5))
)
qpro_secret.add_child(
Node.s64_array("body", qpro_secrete_dict.get_int_array("body", 5))
)
qpro_secret.add_child(
Node.s64_array("hand", qpro_secrete_dict.get_int_array("hand", 5))
)
qpro_secret.add_child(Node.s64_array("head", qpro_secrete_dict.get_int_array("head", 5)))
qpro_secret.add_child(Node.s64_array("hair", qpro_secrete_dict.get_int_array("hair", 5)))
qpro_secret.add_child(Node.s64_array("face", qpro_secrete_dict.get_int_array("face", 5)))
qpro_secret.add_child(Node.s64_array("body", qpro_secrete_dict.get_int_array("body", 5)))
qpro_secret.add_child(Node.s64_array("hand", qpro_secrete_dict.get_int_array("hand", 5)))
# DAN rankings
grade = Node.void("grade")
@ -1457,9 +1369,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
)
),
)
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in achievements:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1604,12 +1514,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
dj_rank_node = Node.void("dj_rank")
root.add_child(dj_rank_node)
dj_rank_node.set_attribute("style", str(dj_rank.id))
dj_rank_node.add_child(
Node.s32_array("rank", dj_rank.data.get_int_array("rank", 15))
)
dj_rank_node.add_child(
Node.s32_array("point", dj_rank.data.get_int_array("point", 15))
)
dj_rank_node.add_child(Node.s32_array("rank", dj_rank.data.get_int_array("rank", 15)))
dj_rank_node.add_child(Node.s32_array("point", dj_rank.data.get_int_array("point", 15)))
dj_rank_ranking_node = Node.void("dj_rank_ranking")
root.add_child(dj_rank_ranking_node)
@ -1655,25 +1561,13 @@ class IIDXRootage(IIDXCourse, IIDXBase):
event1_dict = profile.get_dict("event1")
event1 = Node.void("event1")
root.add_child(event1)
event1.set_attribute(
"event_play_num", str(event1_dict.get_int("event_play_num"))
)
event1.set_attribute("event_play_num", str(event1_dict.get_int("event_play_num")))
event1.set_attribute("fragment_num", str(event1_dict.get_int("fragment_num")))
event1.set_attribute(
"last_select_map_id", str(event1_dict.get_int("last_select_map"))
)
event1.set_attribute(
"read_tips_list", str(event1_dict.get_int("read_tips_list"))
)
event1.set_attribute(
"continuous_correct", str(event1_dict.get_int("continuous_correct"))
)
event1.set_attribute(
"bookshelf_release_num", str(event1_dict.get_int("bookshelf_release_num"))
)
event1.add_child(
Node.binary("quiz_control_list", event1_dict.get_bytes("quiz_control_list"))
)
event1.set_attribute("last_select_map_id", str(event1_dict.get_int("last_select_map")))
event1.set_attribute("read_tips_list", str(event1_dict.get_int("read_tips_list")))
event1.set_attribute("continuous_correct", str(event1_dict.get_int("continuous_correct")))
event1.set_attribute("bookshelf_release_num", str(event1_dict.get_int("bookshelf_release_num")))
event1.add_child(Node.binary("quiz_control_list", event1_dict.get_bytes("quiz_control_list")))
for map_data in achievements:
if map_data.type != "map_data":
continue
@ -1681,9 +1575,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
map_data_node = Node.void("map_data")
event1.add_child(map_data_node)
map_data_node.set_attribute("map_id", str(map_data.id))
map_data_node.set_attribute(
"play_num", str(map_data.data.get_int("play_num"))
)
map_data_node.set_attribute("play_num", str(map_data.data.get_int("play_num")))
map_data_node.set_attribute(
"last_select_route_id",
str(map_data.data.get_int("last_select_route_id")),
@ -1692,14 +1584,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
"bookshelf_release_num",
str(map_data.data.get_int("bookshelf_release_num")),
)
map_data_node.add_child(
Node.bool("is_clear", map_data.data.get_bool("is_clear"))
)
map_data_node.add_child(
Node.binary(
"map_route_damage", map_data.data.get_bytes("map_route_damage")
)
)
map_data_node.add_child(Node.bool("is_clear", map_data.data.get_bool("is_clear")))
map_data_node.add_child(Node.binary("map_route_damage", map_data.data.get_bytes("map_route_damage")))
# DELABITY LABORATORY event
event2_dict = profile.get_dict("event2")
@ -1707,27 +1593,13 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root.add_child(event2)
event2.set_attribute("play_num", str(event2_dict.get_int("play_num")))
event2.set_attribute("delabity", str(event2_dict.get_int("delabity")))
event2.set_attribute(
"floor_0_last_area", str(event2_dict.get_int("floor_0_last_area"))
)
event2.set_attribute(
"floor_1_last_area", str(event2_dict.get_int("floor_1_last_area"))
)
event2.set_attribute(
"floor_2_last_area", str(event2_dict.get_int("floor_2_last_area"))
)
event2.set_attribute(
"floor_3_last_area", str(event2_dict.get_int("floor_3_last_area"))
)
event2.set_attribute(
"floor_4_last_area", str(event2_dict.get_int("floor_4_last_area"))
)
event2.set_attribute(
"floor_clear_flg_list", str(event2_dict.get_int("floor_clear_flg_list"))
)
event2.set_attribute(
"last_select_floor", str(event2_dict.get_int("last_select_floor"))
)
event2.set_attribute("floor_0_last_area", str(event2_dict.get_int("floor_0_last_area")))
event2.set_attribute("floor_1_last_area", str(event2_dict.get_int("floor_1_last_area")))
event2.set_attribute("floor_2_last_area", str(event2_dict.get_int("floor_2_last_area")))
event2.set_attribute("floor_3_last_area", str(event2_dict.get_int("floor_3_last_area")))
event2.set_attribute("floor_4_last_area", str(event2_dict.get_int("floor_4_last_area")))
event2.set_attribute("floor_clear_flg_list", str(event2_dict.get_int("floor_clear_flg_list")))
event2.set_attribute("last_select_floor", str(event2_dict.get_int("last_select_floor")))
event2.set_attribute("tips_list", str(event2_dict.get_int("tips_list")))
areas = self.data.local.user.get_achievements(self.game, self.version, userid)
@ -1738,45 +1610,25 @@ class IIDXRootage(IIDXCourse, IIDXBase):
event2.add_child(area_data)
area_data.set_attribute("area_id", str(area.id))
area_data.set_attribute("floor_id", str(area.data.get_int("floor_id")))
area_data.set_attribute(
"last_select_note", str(area.data.get_int("last_select_note"))
)
area_data.set_attribute(
"normal_play_num", str(area.data.get_int("normal_play_num"))
)
area_data.set_attribute(
"hyper_play_num", str(area.data.get_int("hyper_play_num"))
)
area_data.set_attribute(
"another_play_num", str(area.data.get_int("another_play_num"))
)
area_data.set_attribute(
"area_clear_flg_list", str(area.data.get_int("area_clear_flg_list"))
)
area_data.set_attribute(
"normal_grade_point", str(area.data.get_int("normal_grade_point"))
)
area_data.set_attribute(
"hyper_grade_point", str(area.data.get_int("hyper_grade_point"))
)
area_data.set_attribute(
"another_grade_point", str(area.data.get_int("another_grade_point"))
)
area_data.set_attribute("last_select_note", str(area.data.get_int("last_select_note")))
area_data.set_attribute("normal_play_num", str(area.data.get_int("normal_play_num")))
area_data.set_attribute("hyper_play_num", str(area.data.get_int("hyper_play_num")))
area_data.set_attribute("another_play_num", str(area.data.get_int("another_play_num")))
area_data.set_attribute("area_clear_flg_list", str(area.data.get_int("area_clear_flg_list")))
area_data.set_attribute("normal_grade_point", str(area.data.get_int("normal_grade_point")))
area_data.set_attribute("hyper_grade_point", str(area.data.get_int("hyper_grade_point")))
area_data.set_attribute("another_grade_point", str(area.data.get_int("another_grade_point")))
tonyutsu = Node.void("tonyutsu")
tonyutsu_dict = profile.get_dict("tonyutsu")
tonyutsu.set_attribute(
"platinum_pass", str(tonyutsu_dict.get_int("platiunum_pass"))
)
tonyutsu.set_attribute("platinum_pass", str(tonyutsu_dict.get_int("platiunum_pass")))
tonyutsu.set_attribute("black_pass", str(tonyutsu_dict.get_int("black_pass")))
extra_boss_event_dict = profile.get_dict("extra_boss_event")
extra_boss_event = Node.void("extra_boss_event")
root.add_child(extra_boss_event)
for i in range(9):
extra_boss_event.set_attribute(
f"orb_{i}", str(extra_boss_event_dict.get_int(f"orb_{i}"))
)
extra_boss_event.set_attribute(f"orb_{i}", str(extra_boss_event_dict.get_int(f"orb_{i}")))
# Step up mode
step_dict = profile.get_dict("step")
@ -1784,49 +1636,25 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root.add_child(step)
step.set_attribute("enemy_damage", str(step_dict.get_int("enemy_damage")))
step.set_attribute("progress", str(step_dict.get_int("progress")))
step.add_child(
Node.bool("is_track_ticket", step_dict.get_bool("is_track_ticket"))
)
step.add_child(Node.bool("is_track_ticket", step_dict.get_bool("is_track_ticket")))
step.set_attribute("sp_level", str(step_dict.get_int("sp_level")))
step.set_attribute("dp_level", str(step_dict.get_int("dp_level")))
step.set_attribute(
"sp_mission_point", str(step_dict.get_int("sp_mission_point"))
)
step.set_attribute(
"dp_mission_point", str(step_dict.get_int("dp_mission_point"))
)
step.set_attribute(
"sp_dj_mission_level", str(step_dict.get_int("sp_dj_mission_level@"))
)
step.set_attribute(
"dp_dj_mission_level", str(step_dict.get_int("dp_dj_mission_level@"))
)
step.set_attribute(
"sp_clear_mission_level", str(step_dict.get_int("sp_clear_mission_level"))
)
step.set_attribute(
"dp_clear_mission_level", str(step_dict.get_int("dp_clear_mission_level"))
)
step.set_attribute(
"sp_dj_mission_clear", str(step_dict.get_int("sp_dj_mission_clear"))
)
step.set_attribute(
"dp_dj_mission_clear", str(step_dict.get_int("dp_dj_mission_clear"))
)
step.set_attribute(
"sp_clear_mission_clear", str(step_dict.get_int("sp_clear_mission_clear"))
)
step.set_attribute(
"dp_clear_mission_clear", str(step_dict.get_int("dp_clear_mission_clear"))
)
step.set_attribute("sp_mission_point", str(step_dict.get_int("sp_mission_point")))
step.set_attribute("dp_mission_point", str(step_dict.get_int("dp_mission_point")))
step.set_attribute("sp_dj_mission_level", str(step_dict.get_int("sp_dj_mission_level@")))
step.set_attribute("dp_dj_mission_level", str(step_dict.get_int("dp_dj_mission_level@")))
step.set_attribute("sp_clear_mission_level", str(step_dict.get_int("sp_clear_mission_level")))
step.set_attribute("dp_clear_mission_level", str(step_dict.get_int("dp_clear_mission_level")))
step.set_attribute("sp_dj_mission_clear", str(step_dict.get_int("sp_dj_mission_clear")))
step.set_attribute("dp_dj_mission_clear", str(step_dict.get_int("dp_dj_mission_clear")))
step.set_attribute("sp_clear_mission_clear", str(step_dict.get_int("sp_clear_mission_clear")))
step.set_attribute("dp_clear_mission_clear", str(step_dict.get_int("dp_clear_mission_clear")))
step.set_attribute("sp_mplay", str(step_dict.get_int("sp_mplay")))
step.set_attribute("dp_mplay", str(step_dict.get_int("dp_mplay")))
step.set_attribute("tips_read_list", str(step_dict.get_int("tips_read_list")))
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -1849,36 +1677,24 @@ class IIDXRootage(IIDXCourse, IIDXBase):
achievement_node.set_attribute("pack", "0")
achievement_node.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievement_node.set_attribute(
"pack", str(daily_played.get_int("pack_flg"))
)
achievement_node.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievement_node.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievement_node.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievement_node.set_attribute(
"last_weekly", str(profile.get_int("last_weekly"))
)
achievement_node.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
achievement_node.set_attribute("weekly_num", str(profile.get_int("weekly_num")))
# Prefecture visit flag
achievement_node.set_attribute("visit_flg", str(profile.get_int("visit_flg")))
# Number of rivals beaten
achievement_node.set_attribute(
"rival_crush", str(profile.get_int("rival_crush"))
)
achievement_node.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievement_node.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 20))
)
achievement_node.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 20)))
# Track deller
deller = Node.void("deller")
@ -1902,9 +1718,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
detail.set_attribute("course_id", str(rank.id))
detail.set_attribute("n_point", str(rank.data.get_int("normal_points")))
detail.set_attribute("h_point", str(rank.data.get_int("hyper_points")))
detail.set_attribute(
"a_point", str(rank.data.get_int("another_points"))
)
detail.set_attribute("a_point", str(rank.data.get_int("another_points")))
nostalgia = Node.void("nostalgia_open")
root.add_child(nostalgia)
@ -1918,9 +1732,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -1972,20 +1784,12 @@ class IIDXRootage(IIDXCourse, IIDXBase):
newprofile.replace_int("d_gauge_disp", int(request.attribute("d_gauge_disp")))
newprofile.replace_int("s_lane_brignt", int(request.attribute("s_lane_brignt")))
newprofile.replace_int("d_lane_brignt", int(request.attribute("d_lane_brignt")))
newprofile.replace_int(
"s_camera_layout", int(request.attribute("s_camera_layout"))
)
newprofile.replace_int(
"d_camera_layout", int(request.attribute("d_camera_layout"))
)
newprofile.replace_int("s_camera_layout", int(request.attribute("s_camera_layout")))
newprofile.replace_int("d_camera_layout", int(request.attribute("d_camera_layout")))
newprofile.replace_int("s_ghost_score", int(request.attribute("s_ghost_score")))
newprofile.replace_int("d_ghost_score", int(request.attribute("d_ghost_score")))
newprofile.replace_int(
"s_tsujigiri_disp", int(request.attribute("s_tsujigiri_disp"))
)
newprofile.replace_int(
"d_tsujigiri_disp", int(request.attribute("d_tsujigiri_disp"))
)
newprofile.replace_int("s_tsujigiri_disp", int(request.attribute("s_tsujigiri_disp")))
newprofile.replace_int("d_tsujigiri_disp", int(request.attribute("d_tsujigiri_disp")))
newprofile.replace_int("s_lift", int(request.attribute("s_lift")))
newprofile.replace_int("d_lift", int(request.attribute("d_lift")))
newprofile.replace_int("mode", int(request.attribute("mode")))
@ -2014,15 +1818,9 @@ class IIDXRootage(IIDXCourse, IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:
@ -2046,9 +1844,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
# Deller saving
deller = request.child("deller")
if deller is not None:
newprofile.replace_int(
"deller", newprofile.get_int("deller") + int(deller.attribute("deller"))
)
newprofile.replace_int("deller", newprofile.get_int("deller") + int(deller.attribute("deller")))
# Secret course expert point saving
expert_point = request.child("expert_point")
@ -2112,22 +1908,14 @@ class IIDXRootage(IIDXCourse, IIDXBase):
for i in range(self.FAVORITE_LIST_LENGTH):
singles.append(
{
"id": struct.unpack(
"<L", single_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", single_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[0],
}
)
doubles.append(
{
"id": struct.unpack(
"<L", double_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", double_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[0],
}
)
@ -2172,21 +1960,11 @@ class IIDXRootage(IIDXCourse, IIDXBase):
event1_dict.increment_int("event_play_num")
last_select_map = int(event1.attribute("last_select_map_id"))
event1_dict.replace_int("play_gift", int(event1.attribute("play_gift")))
event1_dict.replace_int(
"fragment_num", int(event1.attribute("fragment_num"))
)
event1_dict.replace_int(
"continuous_correct", int(event1.attribute("continuous_correct"))
)
event1_dict.replace_int(
"bookshelf_release_num", int(event1.attribute("bookshelf_release_num"))
)
event1_dict.replace_int(
"read_tips_list", int(event1.attribute("read_tips_list"))
)
event1_dict.replace_bytes(
"quiz_control_list", event1.child_value("quiz_control_list")
)
event1_dict.replace_int("fragment_num", int(event1.attribute("fragment_num")))
event1_dict.replace_int("continuous_correct", int(event1.attribute("continuous_correct")))
event1_dict.replace_int("bookshelf_release_num", int(event1.attribute("bookshelf_release_num")))
event1_dict.replace_int("read_tips_list", int(event1.attribute("read_tips_list")))
event1_dict.replace_bytes("quiz_control_list", event1.child_value("quiz_control_list"))
# Save any map data, also see if we need to update last_select_map
for map_data in event1.children:
if map_data.name != "map_data":
@ -2227,27 +2005,13 @@ class IIDXRootage(IIDXCourse, IIDXBase):
event2_dict = newprofile.get_dict("event2")
event2_dict.replace_int("play_num", int(event2.attribute("play_num")))
event2_dict.replace_int("delabity", int(event2.attribute("delabity")))
event2_dict.replace_int(
"floor_0_last_area", int(event2.attribute("floor_0_last_area"))
)
event2_dict.replace_int(
"floor_1_last_area", int(event2.attribute("floor_1_last_area"))
)
event2_dict.replace_int(
"floor_2_last_area", int(event2.attribute("floor_2_last_area"))
)
event2_dict.replace_int(
"floor_3_last_area", int(event2.attribute("floor_3_last_area"))
)
event2_dict.replace_int(
"floor_4_last_area", int(event2.attribute("floor_4_last_area"))
)
event2_dict.replace_int(
"floor_clear_flg_list", int(event2.attribute("floor_clear_flg_list"))
)
event2_dict.replace_int(
"last_select_floor", int(event2.attribute("last_select_floor"))
)
event2_dict.replace_int("floor_0_last_area", int(event2.attribute("floor_0_last_area")))
event2_dict.replace_int("floor_1_last_area", int(event2.attribute("floor_1_last_area")))
event2_dict.replace_int("floor_2_last_area", int(event2.attribute("floor_2_last_area")))
event2_dict.replace_int("floor_3_last_area", int(event2.attribute("floor_3_last_area")))
event2_dict.replace_int("floor_4_last_area", int(event2.attribute("floor_4_last_area")))
event2_dict.replace_int("floor_clear_flg_list", int(event2.attribute("floor_clear_flg_list")))
event2_dict.replace_int("last_select_floor", int(event2.attribute("last_select_floor")))
event2_dict.replace_int("tips_list", int(event2.attribute("tips_list")))
for area_data in event2.children:
@ -2263,26 +2027,14 @@ class IIDXRootage(IIDXCourse, IIDXBase):
f"area_data_floor_{floor_id}", # Save floor_id twice since the game seems to key by both
{
"floor_id": floor_id,
"last_select_note": int(
area_data.attribute("last_select_note")
),
"last_select_note": int(area_data.attribute("last_select_note")),
"normal_play_num": int(area_data.attribute("normal_play_num")),
"hyper_play_num": int(area_data.attribute("hyper_play_num")),
"another_play_num": int(
area_data.attribute("another_play_num")
),
"area_clear_flg_list": int(
area_data.attribute("area_clear_flg_list")
),
"normal_grade_point": int(
area_data.attribute("normal_grade_point")
),
"hyper_grade_point": int(
area_data.attribute("hyper_grade_point")
),
"another_grade_point": int(
area_data.attribute("another_grade_point")
),
"another_play_num": int(area_data.attribute("another_play_num")),
"area_clear_flg_list": int(area_data.attribute("area_clear_flg_list")),
"normal_grade_point": int(area_data.attribute("normal_grade_point")),
"hyper_grade_point": int(area_data.attribute("hyper_grade_point")),
"another_grade_point": int(area_data.attribute("another_grade_point")),
},
)
@ -2292,9 +2044,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
if extra_boss_event is not None:
extra_boss_event_dict = newprofile.get_dict("extra_boss_event")
for i in range(9):
extra_boss_event_dict.replace_int(
f"orb_{i}", int(extra_boss_event.attribute(f"orb_{i}"))
)
extra_boss_event_dict.replace_int(f"orb_{i}", int(extra_boss_event.attribute(f"orb_{i}")))
newprofile.replace_dict("extra_boss_event", extra_boss_event_dict)
# Step-up mode
@ -2303,25 +2053,15 @@ class IIDXRootage(IIDXCourse, IIDXBase):
step_dict = newprofile.get_dict("step")
step_dict.replace_int("enemy_damage", int(step.attribute("enemy_damage")))
step_dict.replace_int("progress", int(step.attribute("progress")))
step_dict.replace_bool(
"is_track_ticket", bool(step.child_value("is_track_ticket"))
)
step_dict.replace_bool("is_track_ticket", bool(step.child_value("is_track_ticket")))
step_dict.replace_int("sp_level", int(step.attribute("sp_level")))
step_dict.replace_int("dp_level", int(step.attribute("dp_level")))
step_dict.replace_int("sp_mplay", int(step.attribute("sp_mplay")))
step_dict.replace_int("dp_mplay", int(step.attribute("dp_mplay")))
step_dict.replace_int(
"sp_mission_point", str(step_dict.get_int("sp_mission_point"))
)
step_dict.replace_int(
"dp_mission_point", str(step_dict.get_int("dp_mission_point"))
)
step_dict.replace_int(
"sp_dj_mission_level", str(step_dict.get_int("sp_dj_mission_level@"))
)
step_dict.replace_int(
"dp_dj_mission_level", str(step_dict.get_int("dp_dj_mission_level@"))
)
step_dict.replace_int("sp_mission_point", str(step_dict.get_int("sp_mission_point")))
step_dict.replace_int("dp_mission_point", str(step_dict.get_int("dp_mission_point")))
step_dict.replace_int("sp_dj_mission_level", str(step_dict.get_int("sp_dj_mission_level@")))
step_dict.replace_int("dp_dj_mission_level", str(step_dict.get_int("dp_dj_mission_level@")))
step_dict.replace_int(
"sp_clear_mission_level",
str(step_dict.get_int("sp_clear_mission_level")),
@ -2330,12 +2070,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
"dp_clear_mission_level",
str(step_dict.get_int("dp_clear_mission_level")),
)
step_dict.replace_int(
"sp_dj_mission_clear", str(step_dict.get_int("sp_dj_mission_clear"))
)
step_dict.replace_int(
"dp_dj_mission_clear", str(step_dict.get_int("dp_dj_mission_clear"))
)
step_dict.replace_int("sp_dj_mission_clear", str(step_dict.get_int("sp_dj_mission_clear")))
step_dict.replace_int("dp_dj_mission_clear", str(step_dict.get_int("dp_dj_mission_clear")))
step_dict.replace_int(
"sp_clear_mission_clear",
str(step_dict.get_int("sp_clear_mission_clear")),
@ -2344,9 +2080,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
"dp_clear_mission_clear",
str(step_dict.get_int("dp_clear_mission_clear")),
)
step_dict.replace_int(
"tips_read_list", str(step_dict.get_int("tips_read_list"))
)
step_dict.replace_int("tips_read_list", str(step_dict.get_int("tips_read_list")))
newprofile.replace_dict("step", step_dict)
# QPro equip in step-up mode
@ -2364,21 +2098,11 @@ class IIDXRootage(IIDXCourse, IIDXBase):
qpro_secret = request.child("qpro_secret")
if qpro_secret is not None:
qpro_secret_dict = newprofile.get_dict("qpro_secret")
qpro_secret_dict.replace_int_array(
"head", 5, qpro_secret.child_value("head")
)
qpro_secret_dict.replace_int_array(
"hair", 5, qpro_secret.child_value("hair")
)
qpro_secret_dict.replace_int_array(
"face", 5, qpro_secret.child_value("face")
)
qpro_secret_dict.replace_int_array(
"body", 5, qpro_secret.child_value("body")
)
qpro_secret_dict.replace_int_array(
"hand", 5, qpro_secret.child_value("hand")
)
qpro_secret_dict.replace_int_array("head", 5, qpro_secret.child_value("head"))
qpro_secret_dict.replace_int_array("hair", 5, qpro_secret.child_value("hair"))
qpro_secret_dict.replace_int_array("face", 5, qpro_secret.child_value("face"))
qpro_secret_dict.replace_int_array("body", 5, qpro_secret.child_value("body"))
qpro_secret_dict.replace_int_array("hand", 5, qpro_secret.child_value("hand"))
newprofile.replace_dict("qpro_secret", qpro_secret_dict)
# Orb data saving
@ -2394,9 +2118,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
tonyutsu = request.child("tonyutsu")
if tonyutsu is not None:
tonyutsu_dict = newprofile.get_dict("tonyutsu")
tonyutsu_dict.replace_int(
"platinum_pass", tonyutsu.attribute("platinum_pass")
)
tonyutsu_dict.replace_int("platinum_pass", tonyutsu.attribute("platinum_pass"))
tonyutsu_dict.replace_int("black_pass", tonyutsu.attribute("black_pass"))
# Keep track of play statistics across all mixes

View File

@ -105,28 +105,15 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
return IIDXCopula(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -150,9 +137,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -387,9 +372,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root = Node.void("IIDX24shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -412,9 +395,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return Node.void("IIDX24shop")
@ -434,9 +415,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -574,16 +553,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root = Node.void("IIDX24music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -627,16 +597,12 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
continue
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -644,10 +610,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -674,9 +637,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -767,19 +728,13 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
if not global_scores:
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -831,9 +786,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -857,10 +810,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -1324,9 +1274,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
used_secret_ids: List[int] = []
for c in secret_courses:
if c["id"] in used_secret_ids:
raise Exception(
"Cannot have multiple secret courses with the same ID!"
)
raise Exception("Cannot have multiple secret courses with the same ID!")
elif c["id"] < 0 or c["id"] >= 20:
raise Exception("Secret course ID is out of bounds!")
else:
@ -1503,9 +1451,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
best_clear_string = clear_map.get(best_clear, "NO PLAY")
now_clear_string = clear_map.get(now_clear, "NO PLAY")
# let's get the song info first
song = self.data.local.music.get_song(
self.game, self.music_version, music_id, self.game_to_db_chart(class_id)
)
song = self.data.local.music.get_song(self.game, self.music_version, music_id, self.game_to_db_chart(class_id))
notecount = song.data.get("notecount", 0)
# Construct the dictionary for the broadcast
card_data = {
@ -1622,15 +1568,9 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
secret.add_child(Node.s64_array("flg2", [-1, -1, -1]))
secret.add_child(Node.s64_array("flg3", [-1, -1, -1]))
else:
secret.add_child(
Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3))
)
secret.add_child(
Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3))
)
secret.add_child(
Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3))
)
secret.add_child(Node.s64_array("flg1", secret_dict.get_int_array("flg1", 3)))
secret.add_child(Node.s64_array("flg2", secret_dict.get_int_array("flg2", 3)))
secret.add_child(Node.s64_array("flg3", secret_dict.get_int_array("flg3", 3)))
# Favorites
for folder in ["favorite1", "favorite2", "favorite3"]:
@ -1692,9 +1632,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
)
),
)
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in achievements:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1766,21 +1704,11 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
qpro_secrete_dict = profile.get_dict("qpro_secret")
qpro_secret = Node.void("qpro_secret")
root.add_child(qpro_secret)
qpro_secret.add_child(
Node.s64_array("head", qpro_secrete_dict.get_int_array("head", 5))
)
qpro_secret.add_child(
Node.s64_array("hair", qpro_secrete_dict.get_int_array("hair", 5))
)
qpro_secret.add_child(
Node.s64_array("face", qpro_secrete_dict.get_int_array("face", 5))
)
qpro_secret.add_child(
Node.s64_array("body", qpro_secrete_dict.get_int_array("body", 5))
)
qpro_secret.add_child(
Node.s64_array("hand", qpro_secrete_dict.get_int_array("hand", 5))
)
qpro_secret.add_child(Node.s64_array("head", qpro_secrete_dict.get_int_array("head", 5)))
qpro_secret.add_child(Node.s64_array("hair", qpro_secrete_dict.get_int_array("hair", 5)))
qpro_secret.add_child(Node.s64_array("face", qpro_secrete_dict.get_int_array("face", 5)))
qpro_secret.add_child(Node.s64_array("body", qpro_secrete_dict.get_int_array("body", 5)))
qpro_secret.add_child(Node.s64_array("hand", qpro_secrete_dict.get_int_array("hand", 5)))
# Rivals
rlist = Node.void("rlist")
@ -1861,9 +1789,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
[
courseid, # course ID
coursechart, # course chart
self.db_to_game_status(
course.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(course.data.get_int("clear_status")), # course clear status
course.data.get_int("pgnum"), # flashing great count
course.data.get_int("gnum"), # great count
],
@ -1881,9 +1807,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
[
courseid, # course ID
coursechart, # course chart
self.db_to_game_status(
course.data.get_int("clear_status")
), # course clear status
self.db_to_game_status(course.data.get_int("clear_status")), # course clear status
course.data.get_int("pgnum"), # flashing great count
course.data.get_int("gnum"), # great count
],
@ -1918,20 +1842,14 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
ninja_rank_node = Node.void("ninja_rank")
root.add_child(ninja_rank_node)
ninja_rank_node.set_attribute("style", str(ninja_rank.id))
ninja_rank_node.add_child(
Node.s32_array("rank", ninja_rank.data.get_int_array("rank", 13))
)
ninja_rank_node.add_child(
Node.s32_array("point", ninja_rank.data.get_int_array("point", 13))
)
ninja_rank_node.add_child(Node.s32_array("rank", ninja_rank.data.get_int_array("rank", 13)))
ninja_rank_node.add_child(Node.s32_array("point", ninja_rank.data.get_int_array("point", 13)))
# SINOBUZ Den event
event1_dict = profile.get_dict("event1")
event1 = Node.void("event1")
root.add_child(event1)
event1.set_attribute(
"last_select_map", str(event1_dict.get_int("last_select_map"))
)
event1.set_attribute("last_select_map", str(event1_dict.get_int("last_select_map")))
event1.set_attribute("hold_rice", str(event1_dict.get_int("hold_rice")))
event1.set_attribute("tax_rice", str(event1_dict.get_int("tax_rice")))
event1.set_attribute("tips_list", str(event1_dict.get_int("tips_list")))
@ -1943,32 +1861,14 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
map_data_node = Node.void("map_data")
event1.add_child(map_data_node)
map_data_node.set_attribute("map_id", str(map_data.id))
map_data_node.set_attribute(
"play_num", str(map_data.data.get_int("play_num"))
)
map_data_node.set_attribute(
"progress", str(map_data.data.get_int("progress"))
)
map_data_node.set_attribute(
"battle_point", str(map_data.data.get_int("battle_point"))
)
map_data_node.set_attribute(
"rice_point", str(map_data.data.get_int("rice_point"))
)
map_data_node.set_attribute(
"is_clear", "1" if map_data.data.get_bool("is_clear") else "0"
)
map_data_node.add_child(
Node.binary("ninjyutsu", map_data.data.get_bytes("ninjyutsu"))
)
map_data_node.add_child(
Node.binary(
"map_card_damage", map_data.data.get_bytes("map_card_damage")
)
)
map_data_node.add_child(
Node.binary("map_card_clear", map_data.data.get_bytes("map_card_clear"))
)
map_data_node.set_attribute("play_num", str(map_data.data.get_int("play_num")))
map_data_node.set_attribute("progress", str(map_data.data.get_int("progress")))
map_data_node.set_attribute("battle_point", str(map_data.data.get_int("battle_point")))
map_data_node.set_attribute("rice_point", str(map_data.data.get_int("rice_point")))
map_data_node.set_attribute("is_clear", "1" if map_data.data.get_bool("is_clear") else "0")
map_data_node.add_child(Node.binary("ninjyutsu", map_data.data.get_bytes("ninjyutsu")))
map_data_node.add_child(Node.binary("map_card_damage", map_data.data.get_bytes("map_card_damage")))
map_data_node.add_child(Node.binary("map_card_clear", map_data.data.get_bytes("map_card_clear")))
# Shichikenden event
event2_dict = profile.get_dict("event2")
@ -1976,20 +1876,14 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root.add_child(event2)
event2.set_attribute("play_num", str(event2_dict.get_int("play_num")))
event2.set_attribute("chakra_point", str(event2_dict.get_int("chakra_point")))
event2.set_attribute(
"last_select_ryuha", str(event2_dict.get_int("last_select_ryuha"))
)
event2.set_attribute("last_select_ryuha", str(event2_dict.get_int("last_select_ryuha")))
event2.add_child(
Node.binary(
"last_select_dojo",
event2_dict.get_bytes("last_select_dojo", b"\0" * 12),
)
)
event2.add_child(
Node.binary(
"enemy_damage", event2_dict.get_bytes("enemy_damage", b"\0" * 532)
)
)
event2.add_child(Node.binary("enemy_damage", event2_dict.get_bytes("enemy_damage", b"\0" * 532)))
# OMES Data
omes_dict = profile.get_dict("omes")
@ -2002,15 +1896,9 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
onemore_data.set_attribute("defeat_4", str(omes_dict.get_int("defeat_4")))
onemore_data.set_attribute("defeat_5", str(omes_dict.get_int("defeat_5")))
onemore_data.set_attribute("defeat_6", str(omes_dict.get_int("defeat_6")))
onemore_data.set_attribute(
"challenge_num_n", str(omes_dict.get_int("challenge_num_n"))
)
onemore_data.set_attribute(
"challenge_num_h", str(omes_dict.get_int("challenge_num_h"))
)
onemore_data.set_attribute(
"challenge_num_a", str(omes_dict.get_int("challenge_num_a"))
)
onemore_data.set_attribute("challenge_num_n", str(omes_dict.get_int("challenge_num_n")))
onemore_data.set_attribute("challenge_num_h", str(omes_dict.get_int("challenge_num_h")))
onemore_data.set_attribute("challenge_num_a", str(omes_dict.get_int("challenge_num_a")))
# If the user joined a particular shop, let the game know.
if "shop_location" in profile:
@ -2030,18 +1918,14 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root.add_child(step)
step.set_attribute("enemy_damage", str(step_dict.get_int("enemy_damage")))
step.set_attribute("progress", str(step_dict.get_int("progress")))
step.set_attribute(
"enemy_defeat_flg", str(step_dict.get_int("enemy_defeat_flg"))
)
step.set_attribute("enemy_defeat_flg", str(step_dict.get_int("enemy_defeat_flg")))
step.set_attribute("sp_level", str(step_dict.get_int("sp_level")))
step.set_attribute("dp_level", str(step_dict.get_int("dp_level")))
step.set_attribute("sp_mplay", str(step_dict.get_int("sp_mplay")))
step.set_attribute("dp_mplay", str(step_dict.get_int("dp_mplay")))
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -2064,36 +1948,24 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
achievement_node.set_attribute("pack", "0")
achievement_node.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievement_node.set_attribute(
"pack", str(daily_played.get_int("pack_flg"))
)
achievement_node.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievement_node.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievement_node.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievement_node.set_attribute(
"last_weekly", str(profile.get_int("last_weekly"))
)
achievement_node.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
achievement_node.set_attribute("weekly_num", str(profile.get_int("weekly_num")))
# Prefecture visit flag
achievement_node.set_attribute("visit_flg", str(profile.get_int("visit_flg")))
# Number of rivals beaten
achievement_node.set_attribute(
"rival_crush", str(profile.get_int("rival_crush"))
)
achievement_node.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievement_node.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 10))
)
achievement_node.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 10)))
# Track deller
deller = Node.void("deller")
@ -2116,9 +1988,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
detail.set_attribute("course_id", str(rank.id))
detail.set_attribute("n_point", str(rank.data.get_int("normal_points")))
detail.set_attribute("h_point", str(rank.data.get_int("hyper_points")))
detail.set_attribute(
"a_point", str(rank.data.get_int("another_points"))
)
detail.set_attribute("a_point", str(rank.data.get_int("another_points")))
nostalgia = Node.void("nostalgia_open")
root.add_child(nostalgia)
@ -2128,9 +1998,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root.add_child(Node.void("bind_eaappli"))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -2206,15 +2074,9 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:
@ -2238,9 +2100,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
# Deller saving
deller = request.child("deller")
if deller is not None:
newprofile.replace_int(
"deller", newprofile.get_int("deller") + int(deller.attribute("deller"))
)
newprofile.replace_int("deller", newprofile.get_int("deller") + int(deller.attribute("deller")))
# Secret course expert point saving
expert_point = request.child("expert_point")
@ -2304,22 +2164,14 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
for i in range(self.FAVORITE_LIST_LENGTH):
singles.append(
{
"id": struct.unpack(
"<L", single_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", single_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[0],
}
)
doubles.append(
{
"id": struct.unpack(
"<L", double_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[
0
],
"id": struct.unpack("<L", double_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[0],
}
)
@ -2412,18 +2264,10 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
if event2 is not None:
event2_dict = newprofile.get_dict("event2")
event2_dict.replace_int("play_num", int(event2.attribute("play_num")))
event2_dict.replace_int(
"last_select_ryuha", int(event2.attribute("last_select_ryuha"))
)
event2_dict.replace_int(
"chakra_point", int(event2.attribute("chakra_point"))
)
event2_dict.replace_bytes(
"last_select_dojo", event2.child_value("last_select_dojo")
)
event2_dict.replace_bytes(
"enemy_damage", event2.child_value("enemy_damage")
)
event2_dict.replace_int("last_select_ryuha", int(event2.attribute("last_select_ryuha")))
event2_dict.replace_int("chakra_point", int(event2.attribute("chakra_point")))
event2_dict.replace_bytes("last_select_dojo", event2.child_value("last_select_dojo"))
event2_dict.replace_bytes("enemy_damage", event2.child_value("enemy_damage"))
newprofile.replace_dict("event2", event2_dict)
# Step-up mode
@ -2432,9 +2276,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
step_dict = newprofile.get_dict("step")
step_dict.replace_int("enemy_damage", int(step.attribute("enemy_damage")))
step_dict.replace_int("progress", int(step.attribute("progress")))
step_dict.replace_int(
"enemy_defeat_flg", int(step.attribute("enemy_defeat_flg"))
)
step_dict.replace_int("enemy_defeat_flg", int(step.attribute("enemy_defeat_flg")))
step_dict.replace_int("sp_level", int(step.attribute("sp_level")))
step_dict.replace_int("dp_level", int(step.attribute("dp_level")))
step_dict.replace_int("sp_mplay", int(step.attribute("sp_mplay")))
@ -2456,21 +2298,11 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
qpro_secret = request.child("qpro_secret")
if qpro_secret is not None:
qpro_secret_dict = newprofile.get_dict("qpro_secret")
qpro_secret_dict.replace_int_array(
"head", 5, qpro_secret.child_value("head")
)
qpro_secret_dict.replace_int_array(
"hair", 5, qpro_secret.child_value("hair")
)
qpro_secret_dict.replace_int_array(
"face", 5, qpro_secret.child_value("face")
)
qpro_secret_dict.replace_int_array(
"body", 5, qpro_secret.child_value("body")
)
qpro_secret_dict.replace_int_array(
"hand", 5, qpro_secret.child_value("hand")
)
qpro_secret_dict.replace_int_array("head", 5, qpro_secret.child_value("head"))
qpro_secret_dict.replace_int_array("hair", 5, qpro_secret.child_value("hair"))
qpro_secret_dict.replace_int_array("face", 5, qpro_secret.child_value("face"))
qpro_secret_dict.replace_int_array("body", 5, qpro_secret.child_value("body"))
qpro_secret_dict.replace_int_array("hand", 5, qpro_secret.child_value("hand"))
newprofile.replace_dict("qpro_secret", qpro_secret_dict)
# Orb data saving
@ -2493,15 +2325,9 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
omes_dict.replace_int("defeat_4", int(onemore_data.attribute("defeat_4")))
omes_dict.replace_int("defeat_5", int(onemore_data.attribute("defeat_5")))
omes_dict.replace_int("defeat_6", int(onemore_data.attribute("defeat_6")))
omes_dict.replace_int(
"challenge_num_n", int(onemore_data.attribute("challenge_num_n"))
)
omes_dict.replace_int(
"challenge_num_h", int(onemore_data.attribute("challenge_num_h"))
)
omes_dict.replace_int(
"challenge_num_a", int(onemore_data.attribute("challenge_num_a"))
)
omes_dict.replace_int("challenge_num_n", int(onemore_data.attribute("challenge_num_n")))
omes_dict.replace_int("challenge_num_h", int(onemore_data.attribute("challenge_num_h")))
omes_dict.replace_int("challenge_num_a", int(onemore_data.attribute("challenge_num_a")))
newprofile.replace_dict("omes", omes_dict)
# Keep track of play statistics across all mixes

View File

@ -100,28 +100,15 @@ class IIDXSpada(IIDXBase):
return IIDXTricoro(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -145,9 +132,7 @@ class IIDXSpada(IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -345,9 +330,7 @@ class IIDXSpada(IIDXBase):
root = Node.void("IIDX21shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -371,9 +354,7 @@ class IIDXSpada(IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return root
@ -393,9 +374,7 @@ class IIDXSpada(IIDXBase):
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -474,16 +453,7 @@ class IIDXSpada(IIDXBase):
root = Node.void("IIDX21music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -527,16 +497,12 @@ class IIDXSpada(IIDXBase):
continue
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -544,10 +510,7 @@ class IIDXSpada(IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -590,19 +553,13 @@ class IIDXSpada(IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
if not global_scores:
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -654,9 +611,7 @@ class IIDXSpada(IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -680,10 +635,7 @@ class IIDXSpada(IIDXBase):
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -831,9 +783,7 @@ class IIDXSpada(IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -1128,9 +1078,7 @@ class IIDXSpada(IIDXBase):
best_clear_string = clear_map.get(best_clear, "NO PLAY")
now_clear_string = clear_map.get(now_clear, "NO PLAY")
# let's get the song info first
song = self.data.local.music.get_song(
self.game, self.music_version, music_id, self.game_to_db_chart(class_id)
)
song = self.data.local.music.get_song(self.game, self.music_version, music_id, self.game_to_db_chart(class_id))
notecount = song.data.get("notecount", 0)
# Construct the dictionary for the broadcast
card_data = {
@ -1235,9 +1183,7 @@ class IIDXSpada(IIDXBase):
join_shop.set_attribute("join_name", machine.name)
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -1268,15 +1214,9 @@ class IIDXSpada(IIDXBase):
secret.add_child(Node.s64_array("flg2", [-1, -1]))
secret.add_child(Node.s64_array("flg3", [-1, -1]))
else:
secret.add_child(
Node.s64_array("flg1", secret_dict.get_int_array("flg1", 2))
)
secret.add_child(
Node.s64_array("flg2", secret_dict.get_int_array("flg2", 2))
)
secret.add_child(
Node.s64_array("flg3", secret_dict.get_int_array("flg3", 2))
)
secret.add_child(Node.s64_array("flg1", secret_dict.get_int_array("flg1", 2)))
secret.add_child(Node.s64_array("flg2", secret_dict.get_int_array("flg2", 2)))
secret.add_child(Node.s64_array("flg3", secret_dict.get_int_array("flg3", 2)))
# Tran medals and shit
achievements = Node.void("achievements")
@ -1287,15 +1227,11 @@ class IIDXSpada(IIDXBase):
achievements.set_attribute("pack", "0")
achievements.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievements.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievements.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievements.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievements.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
@ -1308,9 +1244,7 @@ class IIDXSpada(IIDXBase):
achievements.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievements.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 10))
)
achievements.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 10)))
# User settings
settings_dict = profile.get_dict("settings")
@ -1356,9 +1290,7 @@ class IIDXSpada(IIDXBase):
)
),
)
rankings = self.data.local.user.get_achievements(
self.game, self.version, userid
)
rankings = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in rankings:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1483,9 +1415,7 @@ class IIDXSpada(IIDXBase):
step.add_child(
Node.binary(
"album",
step_dict.get_bytes(
"album", b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
),
step_dict.get_bytes("album", b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
)
)
@ -1614,13 +1544,9 @@ class IIDXSpada(IIDXBase):
"boss6_damage",
]:
boss1.set_attribute(attr, str(boss1_dict.get_int(attr)))
boss1.add_child(
Node.s32_array("level", boss1_dict.get_int_array("level", 7))
)
boss1.add_child(Node.s32_array("level", boss1_dict.get_int_array("level", 7)))
if "durability" in boss1_dict:
boss1.add_child(
Node.binary("durability", boss1_dict.get_bytes("durability"))
)
boss1.add_child(Node.binary("durability", boss1_dict.get_bytes("durability")))
# Events copied from Tricoro, but might still allow unlocks in this version?
gakuen = Node.void("gakuen")
@ -1646,9 +1572,7 @@ class IIDXSpada(IIDXBase):
root.add_child(Node.void("bind_eaappli"))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -1720,15 +1644,9 @@ class IIDXSpada(IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:
@ -1752,9 +1670,7 @@ class IIDXSpada(IIDXBase):
# Deller saving
deller = request.child("deller")
if deller is not None:
newprofile.replace_int(
"deller", newprofile.get_int("deller") + int(deller.attribute("deller"))
)
newprofile.replace_int("deller", newprofile.get_int("deller") + int(deller.attribute("deller")))
# Favorites saving
favorite = request.child("favorite")
@ -1769,17 +1685,13 @@ class IIDXSpada(IIDXBase):
for i in range(self.FAVORITE_LIST_LENGTH):
singles.append(
{
"id": struct.unpack(
"<L", single_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"id": struct.unpack("<L", single_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", single_chart_bin[i : (i + 1)])[0],
}
)
doubles.append(
{
"id": struct.unpack(
"<L", double_music_bin[(i * 4) : ((i + 1) * 4)]
)[0],
"id": struct.unpack("<L", double_music_bin[(i * 4) : ((i + 1) * 4)])[0],
"chart": struct.unpack("B", double_chart_bin[i : (i + 1)])[0],
}
)

View File

@ -92,28 +92,15 @@ class IIDXTricoro(IIDXBase):
return IIDXLincle(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert dailies into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "daily_charts", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "daily_charts", "daily"):
# Generate a new list of three dailies.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = list(
set(
[
song.id
for song in data.local.music.get_all_songs(
cls.game, cls.version
)
]
)
)
all_songs = list(set([song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]))
if len(all_songs) >= 3:
daily_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -137,9 +124,7 @@ class IIDXTricoro(IIDXBase):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "daily_charts", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "daily_charts", "daily")
return events
@classmethod
@ -324,9 +309,7 @@ class IIDXTricoro(IIDXBase):
root = Node.void("shop")
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -350,9 +333,7 @@ class IIDXTricoro(IIDXBase):
course.replace_int("music_2", request.child_value("music_2"))
course.replace_int("music_3", request.child_value("music_3"))
course.replace_bool("valid", request.child_value("valid"))
self.data.local.machine.put_settings(
machine.arcade, self.game, self.music_version, "shop_course", course
)
self.data.local.machine.put_settings(machine.arcade, self.game, self.music_version, "shop_course", course)
return root
@ -372,9 +353,7 @@ class IIDXTricoro(IIDXBase):
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
course = self.data.local.machine.get_settings(
machine.arcade, self.game, self.music_version, "shop_course"
)
course = self.data.local.machine.get_settings(machine.arcade, self.game, self.music_version, "shop_course")
else:
course = None
@ -453,16 +432,7 @@ class IIDXTricoro(IIDXBase):
root = Node.void("music")
attempts = self.get_clear_rates()
all_songs = list(
set(
[
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
]
)
)
all_songs = list(set([song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)]))
for song in all_songs:
clears = []
fcs = []
@ -507,16 +477,12 @@ class IIDXTricoro(IIDXBase):
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
# Grab score data for user/rival
scoredata = self.make_score_struct(
scores,
self.CLEAR_TYPE_SINGLE
if cltype == self.GAME_CLTYPE_SINGLE
else self.CLEAR_TYPE_DOUBLE,
self.CLEAR_TYPE_SINGLE if cltype == self.GAME_CLTYPE_SINGLE else self.CLEAR_TYPE_DOUBLE,
rivalid,
)
for s in scoredata:
@ -524,10 +490,7 @@ class IIDXTricoro(IIDXBase):
# Grab most played for user/rival
most_played = [
play[0]
for play in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
play[0] for play in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)
]
if len(most_played) < 20:
most_played.extend([0] * (20 - len(most_played)))
@ -570,19 +533,13 @@ class IIDXTricoro(IIDXBase):
key=lambda s: (s[1].points, s[1].timestamp),
reverse=True,
)
all_players = {
uid: prof
for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])
}
all_players = {uid: prof for (uid, prof) in self.get_any_profiles([s[0] for s in all_scores])}
if not global_scores:
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -633,9 +590,7 @@ class IIDXTricoro(IIDXBase):
# Shop ranking
shopdata = Node.void("shopdata")
root.add_child(shopdata)
shopdata.set_attribute(
"rank", "-1" if oldindex is None else str(oldindex + 1)
)
shopdata.set_attribute("rank", "-1" if oldindex is None else str(oldindex + 1))
# Grab the rank of some other players on this song
ranklist = Node.void("ranklist")
@ -659,10 +614,7 @@ class IIDXTricoro(IIDXBase):
all_scores = [
score
for score in all_scores
if (
score[0] == userid
or self.user_joined_arcade(machine, all_players[score[0]])
)
if (score[0] == userid or self.user_joined_arcade(machine, all_players[score[0]]))
]
# Find our actual index
@ -809,9 +761,7 @@ class IIDXTricoro(IIDXBase):
if userid is not None:
# Try to look up previous ghost for user
my_score = self.data.remote.music.get_score(
self.game, self.music_version, userid, musicid, chart
)
my_score = self.data.remote.music.get_score(self.game, self.music_version, userid, musicid, chart)
if my_score is not None:
mydata = Node.binary("mydata", my_score.data.get_bytes("ghost"))
mydata.set_attribute("score", str(my_score.points))
@ -1114,9 +1064,7 @@ class IIDXTricoro(IIDXBase):
)
),
)
rankings = self.data.local.user.get_achievements(
self.game, self.version, userid
)
rankings = self.data.local.user.get_achievements(self.game, self.version, userid)
for rank in rankings:
if rank.type == self.DAN_RANKING_SINGLE:
grade.add_child(
@ -1274,18 +1222,12 @@ class IIDXTricoro(IIDXBase):
step.set_attribute("dp_mplay", str(step_dict.get_int("dp_mplay")))
step.set_attribute("review", str(step_dict.get_int("review")))
if "stamp" in step_dict:
step.add_child(
Node.binary("stamp", step_dict.get_bytes("stamp", bytes([0] * 36)))
)
step.add_child(Node.binary("stamp", step_dict.get_bytes("stamp", bytes([0] * 36))))
if "help" in step_dict:
step.add_child(
Node.binary("help", step_dict.get_bytes("help", bytes([0] * 6)))
)
step.add_child(Node.binary("help", step_dict.get_bytes("help", bytes([0] * 6))))
# Daily recommendations
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "dailies"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "dailies")
if entry is not None:
packinfo = Node.void("packinfo")
root.add_child(packinfo)
@ -1328,15 +1270,11 @@ class IIDXTricoro(IIDXBase):
achievements.set_attribute("pack", "0")
achievements.set_attribute("pack_comp", "0")
else:
daily_played = self.data.local.user.get_achievement(
self.game, self.version, userid, pack_id, "daily"
)
daily_played = self.data.local.user.get_achievement(self.game, self.version, userid, pack_id, "daily")
if daily_played is None:
daily_played = ValidatedDict()
achievements.set_attribute("pack", str(daily_played.get_int("pack_flg")))
achievements.set_attribute(
"pack_comp", str(daily_played.get_int("pack_comp"))
)
achievements.set_attribute("pack_comp", str(daily_played.get_int("pack_comp")))
# Weeklies
achievements.set_attribute("last_weekly", str(profile.get_int("last_weekly")))
@ -1349,9 +1287,7 @@ class IIDXTricoro(IIDXBase):
achievements.set_attribute("rival_crush", str(profile.get_int("rival_crush")))
# Tran medals
achievements.add_child(
Node.s64_array("trophy", profile.get_int_array("trophy", 10))
)
achievements.add_child(Node.s64_array("trophy", profile.get_int_array("trophy", 10)))
# Link5 data
if "link5" in profile:
@ -1403,9 +1339,7 @@ class IIDXTricoro(IIDXBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
play_stats = self.get_play_statistics(userid)
@ -1459,15 +1393,9 @@ class IIDXTricoro(IIDXBase):
# Basic achievements
achievements = request.child("achievements")
if achievements is not None:
newprofile.replace_int(
"visit_flg", int(achievements.attribute("visit_flg"))
)
newprofile.replace_int(
"last_weekly", int(achievements.attribute("last_weekly"))
)
newprofile.replace_int(
"weekly_num", int(achievements.attribute("weekly_num"))
)
newprofile.replace_int("visit_flg", int(achievements.attribute("visit_flg")))
newprofile.replace_int("last_weekly", int(achievements.attribute("last_weekly")))
newprofile.replace_int("weekly_num", int(achievements.attribute("weekly_num")))
pack_id = int(achievements.attribute("pack_id"))
if pack_id > 0:

View File

@ -30,13 +30,9 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
PLAY_MEDAL_FAILED: Final[int] = DBConstants.JUBEAT_PLAY_MEDAL_FAILED
PLAY_MEDAL_CLEARED: Final[int] = DBConstants.JUBEAT_PLAY_MEDAL_CLEARED
PLAY_MEDAL_NEARLY_FULL_COMBO: Final[
int
] = DBConstants.JUBEAT_PLAY_MEDAL_NEARLY_FULL_COMBO
PLAY_MEDAL_NEARLY_FULL_COMBO: Final[int] = DBConstants.JUBEAT_PLAY_MEDAL_NEARLY_FULL_COMBO
PLAY_MEDAL_FULL_COMBO: Final[int] = DBConstants.JUBEAT_PLAY_MEDAL_FULL_COMBO
PLAY_MEDAL_NEARLY_EXCELLENT: Final[
int
] = DBConstants.JUBEAT_PLAY_MEDAL_NEARLY_EXCELLENT
PLAY_MEDAL_NEARLY_EXCELLENT: Final[int] = DBConstants.JUBEAT_PLAY_MEDAL_NEARLY_EXCELLENT
PLAY_MEDAL_EXCELLENT: Final[int] = DBConstants.JUBEAT_PLAY_MEDAL_EXCELLENT
CHART_TYPE_BASIC: Final[int] = 0
@ -86,18 +82,14 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("gametop")
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
"""
Base handler for a score list. Given a userid, profile and a score list,
return a Node representing a score list. Should be overridden.
"""
return Node.void("gametop")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -159,9 +151,7 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
return self.format_profile(userid, profile)
def get_scores_by_extid(
self, extid: Optional[int], partition: int, total_partitions: int
) -> Optional[Node]:
def get_scores_by_extid(self, extid: Optional[int], partition: int, total_partitions: int) -> Optional[Node]:
"""
Given an ExtID, return a formatted score node. Similar rationale to
get_profile_by_refid. Note that this takes into account the game's
@ -183,9 +173,7 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# We fetch all scores on the first partition and then divy up
# the scores across total_partitions fetches. If it is small
# enough, we don't bother.
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
# We will want to fetch the remaining scores that were in our
# cache.
@ -205,9 +193,7 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# last iteration.
if partition == total_partitions:
if rest:
raise Exception(
"Logic error, should not have gotten additional scores to cache on last iteration!"
)
raise Exception("Logic error, should not have gotten additional scores to cache on last iteration!")
self.cache.delete(cache_key)
else:
self.cache.set(cache_key, rest, timeout=60)
@ -339,10 +325,7 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
for gameitem in gameitems:
if gameitem.type == "emblem":
if (
gameitem.data.get_int("layer") == 2
and gameitem.data.get_int("rarity") == 1
):
if gameitem.data.get_int("layer") == 2 and gameitem.data.get_int("rarity") == 1:
default_main.add(gameitem.id)
return default_main

View File

@ -83,16 +83,12 @@ class JubeatClan(
return JubeatQubell(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert daily FC challenges into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "fc_challenge", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "fc_challenge", "daily"):
# Generate a new list of two FC challenge songs. Skip a particular song range since these are all a single song ID.
# Jubeat Clan has an unlock event where you have to play different charts for the same song, and the charts are
# loaded in based on the cabinet's prefecture. So, no matter where you are, you will only see one song within this
@ -129,9 +125,7 @@ class JubeatClan(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "fc_challenge", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "fc_challenge", "daily")
return events
@classmethod
@ -1098,36 +1092,21 @@ class JubeatClan(
valid_courses: Set[int] = set()
for course in self.__get_course_list():
if course["id"] < 1:
raise Exception(
f"Invalid course ID {course['id']} found in course list!"
)
raise Exception(f"Invalid course ID {course['id']} found in course list!")
if course["id"] in valid_courses:
raise Exception(f"Duplicate ID {course['id']} found in course list!")
if (
course["clear_type"] == self.COURSE_CLEAR_HAZARD
and "hazard_type" not in course
):
if course["clear_type"] == self.COURSE_CLEAR_HAZARD and "hazard_type" not in course:
raise Exception(f"Need 'hazard_type' set in course {course['id']}!")
if (
course["course_type"] == self.COURSE_TYPE_TIME_BASED
and "end_time" not in course
):
if course["course_type"] == self.COURSE_TYPE_TIME_BASED and "end_time" not in course:
raise Exception(f"Need 'end_time' set in course {course['id']}!")
if (
course["clear_type"]
in [self.COURSE_CLEAR_SCORE, self.COURSE_CLEAR_COMBINED_SCORE]
course["clear_type"] in [self.COURSE_CLEAR_SCORE, self.COURSE_CLEAR_COMBINED_SCORE]
and "score" not in course
):
raise Exception(f"Need 'score' set in course {course['id']}!")
if (
course["clear_type"] == self.COURSE_CLEAR_SCORE
and course["score"] > 1000000
):
if course["clear_type"] == self.COURSE_CLEAR_SCORE and course["score"] > 1000000:
raise Exception(f"Invalid per-coure score in course {course['id']}!")
if (
course["clear_type"] == self.COURSE_CLEAR_COMBINED_SCORE
and course["score"] <= 1000000
):
if course["clear_type"] == self.COURSE_CLEAR_COMBINED_SCORE and course["score"] <= 1000000:
raise Exception(f"Invalid combined score in course {course['id']}!")
valid_courses.add(course["id"])
@ -1139,11 +1118,7 @@ class JubeatClan(
clan_course.set_attribute("id", str(course["id"]))
clan_course.set_attribute("course_type", str(course["course_type"]))
clan_course.add_child(Node.s32("difficulty", course["difficulty"]))
clan_course.add_child(
Node.u64(
"etime", (course["end_time"] if "end_time" in course else 0) * 1000
)
)
clan_course.add_child(Node.u64("etime", (course["end_time"] if "end_time" in course else 0) * 1000))
clan_course.add_child(Node.string("name", course["name"]))
# List of included songs
@ -1169,9 +1144,7 @@ class JubeatClan(
clan_course.add_child(clear)
ex_option = Node.void("ex_option")
clear.add_child(ex_option)
ex_option.add_child(
Node.bool("is_hard", course["hard"] if "hard" in course else False)
)
ex_option.add_child(Node.bool("is_hard", course["hard"] if "hard" in course else False))
ex_option.add_child(
Node.s32(
"hazard_type",
@ -1179,9 +1152,7 @@ class JubeatClan(
)
)
clear.set_attribute("type", str(course["clear_type"]))
clear.add_child(
Node.s32("score", course["score"] if "score" in course else 0)
)
clear.add_child(Node.s32("score", course["score"] if "score" in course else 0))
reward_list = Node.void("reward_list")
clear.add_child(reward_list)
@ -1404,9 +1375,7 @@ class JubeatClan(
# Grab unlock progress
item = player.child("item")
if item is not None:
owned_emblems = self.calculate_owned_items(
item.child_value("emblem_list")
)
owned_emblems = self.calculate_owned_items(item.child_value("emblem_list"))
for index in owned_emblems:
self.data.local.user.put_achievement(
self.game,
@ -1443,9 +1412,7 @@ class JubeatClan(
return Node.void("gameend")
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void("gametop")
datanode = Node.void("data")
root.add_child(datanode)
@ -1518,24 +1485,12 @@ class JubeatClan(
playdata.add_child(musicdata)
musicdata.set_attribute("music_id", scoreid)
musicdata.add_child(
Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3))
)
musicdata.add_child(
Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3))
)
musicdata.add_child(
Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3))
)
musicdata.add_child(
Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3))
)
musicdata.add_child(
Node.s32_array("score", scoredata.get_int_array("points", 3))
)
musicdata.add_child(
Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3))
)
musicdata.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3)))
musicdata.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3)))
musicdata.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3)))
musicdata.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3)))
musicdata.add_child(Node.s32_array("score", scoredata.get_int_array("points", 3)))
musicdata.add_child(Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3)))
for i, ghost in enumerate(scoredata.get("ghost", [None, None, None])):
if ghost is None:
@ -1557,9 +1512,7 @@ class JubeatClan(
force_unlock = game_config.get_bool("force_song_unlock")
# Calculate all of our achievement-backed entities.
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
owned_songs: Set[int] = set()
owned_secrets: Set[int] = set()
event_completion: Dict[int, bool] = {}
@ -1567,9 +1520,7 @@ class JubeatClan(
owned_emblems: Set[int] = set()
for achievement in achievements:
if achievement.type == "event":
event_completion[achievement.id] = achievement.data.get_bool(
"is_completed"
)
event_completion[achievement.id] = achievement.data.get_bool("is_completed")
elif achievement.type == "course":
course_completion[achievement.id] = achievement.data
elif achievement.type == "emblem":
@ -1610,12 +1561,8 @@ class JubeatClan(
info.add_child(Node.s32("match_cnt", profile.get_int("match_cnt")))
info.add_child(Node.s32("beat_cnt", profile.get_int("beat_cnt")))
info.add_child(Node.s32("mynews_cnt", profile.get_int("mynews_cnt")))
info.add_child(
Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points"))
)
info.add_child(
Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played"))
)
info.add_child(Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points")))
info.add_child(Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played")))
# Looks to be set to true when there's an old profile, stops tutorial from
# happening on first load.
@ -1665,68 +1612,30 @@ class JubeatClan(
# Secret unlocks
item = Node.void("item")
player.add_child(item)
item.add_child(
Node.s32_array(
"music_list", profile.get_int_array("music_list", 64, [-1] * 64)
)
)
item.add_child(Node.s32_array("music_list", profile.get_int_array("music_list", 64, [-1] * 64)))
item.add_child(
Node.s32_array(
"secret_list",
([-1] * 64)
if force_unlock
else self.create_owned_items(owned_songs, 64),
)
)
item.add_child(
Node.s32_array(
"theme_list", profile.get_int_array("theme_list", 16, [-1] * 16)
)
)
item.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list", 16, [-1] * 16)
)
)
item.add_child(
Node.s32_array(
"title_list", profile.get_int_array("title_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array(
"parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96))
)
item.add_child(
Node.s32_array(
"commu_list", profile.get_int_array("commu_list", 16, [-1] * 16)
([-1] * 64) if force_unlock else self.create_owned_items(owned_songs, 64),
)
)
item.add_child(Node.s32_array("theme_list", profile.get_int_array("theme_list", 16, [-1] * 16)))
item.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list", 16, [-1] * 16)))
item.add_child(Node.s32_array("title_list", profile.get_int_array("title_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96)))
item.add_child(Node.s32_array("commu_list", profile.get_int_array("commu_list", 16, [-1] * 16)))
new = Node.void("new")
item.add_child(new)
new.add_child(
Node.s32_array(
"secret_list",
([-1] * 64)
if force_unlock
else self.create_owned_items(owned_secrets, 64),
)
)
new.add_child(
Node.s32_array(
"theme_list", profile.get_int_array("theme_list_new", 16, [-1] * 16)
)
)
new.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list_new", 16, [-1] * 16)
([-1] * 64) if force_unlock else self.create_owned_items(owned_secrets, 64),
)
)
new.add_child(Node.s32_array("theme_list", profile.get_int_array("theme_list_new", 16, [-1] * 16)))
new.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list_new", 16, [-1] * 16)))
# Add rivals to profile.
rivallist = Node.void("rivallist")
@ -1765,9 +1674,7 @@ class JubeatClan(
lab_edit_seq.set_attribute("count", "0")
# Full combo challenge
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -1826,11 +1733,7 @@ class JubeatClan(
state = 0x0
state |= self.EVENT_STATUS_OPEN if eventdata["enabled"] else 0
state |= (
self.EVENT_STATUS_COMPLETE
if event_completion.get(eventid, False)
else 0
)
state |= self.EVENT_STATUS_COMPLETE if event_completion.get(eventid, False) else 0
event.add_child(Node.u8("state", state))
# JBox stuff
@ -1900,9 +1803,7 @@ class JubeatClan(
bestentry.replace_int("songid", achievement.id)
bestentry.replace_int("chart", chart)
jubeat_entries.append(bestentry)
jubeat_entries = sorted(
jubeat_entries, key=lambda entry: entry.get_int("value"), reverse=True
)
jubeat_entries = sorted(jubeat_entries, key=lambda entry: entry.get_int("value"), reverse=True)
# Now, give the game the list.
for i, entry in enumerate(jubeat_entries):
@ -1916,9 +1817,7 @@ class JubeatClan(
target_music.add_child(Node.s8("seq", entry.get_int("chart")))
target_music.add_child(Node.s32("score", entry.get_int("score")))
target_music.add_child(Node.s32("value", entry.get_int("value")))
target_music.add_child(
Node.bool("is_hard_mode", entry.get_bool("hard_mode"))
)
target_music.add_child(Node.bool("is_hard_mode", entry.get_bool("hard_mode")))
# Team stuff
team = Node.void("team")
@ -1964,9 +1863,7 @@ class JubeatClan(
status = 0
status |= self.COURSE_STATUS_SEEN if status_dict.get_bool("seen") else 0
status |= self.COURSE_STATUS_PLAYED if status_dict.get_bool("played") else 0
status |= (
self.COURSE_STATUS_CLEARED if status_dict.get_bool("cleared") else 0
)
status |= self.COURSE_STATUS_CLEARED if status_dict.get_bool("cleared") else 0
clan_course = Node.void("clan_course")
clan_course_list.add_child(clan_course)
@ -2051,9 +1948,7 @@ class JubeatClan(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_bool("saved", True)
data = request.child("data")
@ -2092,12 +1987,8 @@ class JubeatClan(
newprofile.replace_int("beat_cnt", info.child_value("beat_cnt"))
newprofile.replace_int("mynews_cnt", info.child_value("mynews_cnt"))
newprofile.replace_int(
"bonus_tune_points", info.child_value("bonus_tune_points")
)
newprofile.replace_bool(
"is_bonus_tune_played", info.child_value("is_bonus_tune_played")
)
newprofile.replace_int("bonus_tune_points", info.child_value("bonus_tune_points"))
newprofile.replace_bool("is_bonus_tune_played", info.child_value("is_bonus_tune_played"))
# Grab last settings
lastnode = player.child("last")
@ -2122,30 +2013,16 @@ class JubeatClan(
# Grab unlock progress
item = player.child("item")
if item is not None:
newprofile.replace_int_array(
"music_list", 64, item.child_value("music_list")
)
newprofile.replace_int_array(
"theme_list", 16, item.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list", 16, item.child_value("marker_list")
)
newprofile.replace_int_array(
"title_list", 160, item.child_value("title_list")
)
newprofile.replace_int_array(
"parts_list", 160, item.child_value("parts_list")
)
newprofile.replace_int_array(
"commu_list", 16, item.child_value("commu_list")
)
newprofile.replace_int_array("music_list", 64, item.child_value("music_list"))
newprofile.replace_int_array("theme_list", 16, item.child_value("theme_list"))
newprofile.replace_int_array("marker_list", 16, item.child_value("marker_list"))
newprofile.replace_int_array("title_list", 160, item.child_value("title_list"))
newprofile.replace_int_array("parts_list", 160, item.child_value("parts_list"))
newprofile.replace_int_array("commu_list", 16, item.child_value("commu_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_songs = self.calculate_owned_items(
item.child_value("secret_list")
)
owned_songs = self.calculate_owned_items(item.child_value("secret_list"))
for index in owned_songs:
self.data.local.user.put_achievement(
self.game,
@ -2169,18 +2046,12 @@ class JubeatClan(
newitem = item.child("new")
if newitem is not None:
newprofile.replace_int_array(
"theme_list_new", 16, newitem.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list_new", 16, newitem.child_value("marker_list")
)
newprofile.replace_int_array("theme_list_new", 16, newitem.child_value("theme_list"))
newprofile.replace_int_array("marker_list_new", 16, newitem.child_value("marker_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_secrets = self.calculate_owned_items(
newitem.child_value("secret_list")
)
owned_secrets = self.calculate_owned_items(newitem.child_value("secret_list"))
for index in owned_secrets:
self.data.local.user.put_achievement(
self.game,
@ -2375,9 +2246,7 @@ class JubeatClan(
if flags & bit > 0:
medal = max(medal, mapping[bit])
self.update_score(
userid, timestamp, songid, chart, points, medal, combo, ghost, stats
)
self.update_score(userid, timestamp, songid, chart, points, medal, combo, ghost, stats)
# Born stuff
born = player.child("born")
@ -2458,9 +2327,7 @@ class JubeatClan(
oldcourse = ValidatedDict()
oldcourse.replace_bool("seen", oldcourse.get_bool("seen") or is_seen)
oldcourse.replace_bool(
"played", oldcourse.get_bool("played") or is_played
)
oldcourse.replace_bool("played", oldcourse.get_bool("played") or is_played)
# Save it as an achievement
self.data.local.user.put_achievement(

View File

@ -143,22 +143,15 @@ class JubeatFesto(
}[db_chart]
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert daily FC challenges into the DB.
"""
events: List[Tuple[str, Dict[str, Any]]] = []
if data.local.network.should_schedule(
cls.game, cls.version, "fc_challenge", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "fc_challenge", "daily"):
# Generate a new list of two FC challenge songs.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = set(
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
)
all_songs = set(song.id for song in data.local.music.get_all_songs(cls.game, cls.version))
if len(all_songs) >= 2:
daily_songs = random.sample(all_songs, 2)
data.local.game.put_time_sensitive_settings(
@ -184,12 +177,8 @@ class JubeatFesto(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "fc_challenge", "daily"
)
if data.local.network.should_schedule(
cls.game, cls.version, "random_course", "daily"
):
data.local.network.mark_scheduled(cls.game, cls.version, "fc_challenge", "daily")
if data.local.network.should_schedule(cls.game, cls.version, "random_course", "daily"):
# Generate a new list of three random songs for random course mode.
start_time, end_time = data.local.network.get_schedule_duration("daily")
@ -216,11 +205,7 @@ class JubeatFesto(
cls.CHART_TYPE_HARD_EXTREME: cls.CHART_TYPE_EXTREME,
}[chart]
all_tens = [
song
for song in data.local.music.get_all_songs(cls.game, cls.version)
if is_ten(song)
]
all_tens = [song for song in data.local.music.get_all_songs(cls.game, cls.version) if is_ten(song)]
if len(all_tens) >= 3:
course_songs = random.sample(all_tens, 3)
data.local.game.put_time_sensitive_settings(
@ -266,9 +251,7 @@ class JubeatFesto(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "random_course", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "random_course", "daily")
return events
@classmethod
@ -324,9 +307,7 @@ class JubeatFesto(
# If it is available, then grab the random course. If we haven't generated that course, then
# just don't bother trying to create it.
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "random_course"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "random_course")
random_course: List[Dict[str, Any]] = []
if entry is not None:
@ -521,9 +502,7 @@ class JubeatFesto(
"music": [
[
(
70000057
if dataver < 2019062100
else (90000079 if dataver < 2022021600 else 20000031),
70000057 if dataver < 2019062100 else (90000079 if dataver < 2022021600 else 20000031),
0,
),
(60000100, 0),
@ -543,9 +522,7 @@ class JubeatFesto(
"music": [
[
(
80000020
if dataver < 2019062100
else (90000082 if dataver < 2022021600 else 60000092),
80000020 if dataver < 2019062100 else (90000082 if dataver < 2022021600 else 60000092),
0,
),
(90000031, 0),
@ -556,9 +533,7 @@ class JubeatFesto(
80000034
if dataver < 2020062900
else (
30000108
if dataver < 2020091300
else (40000107 if dataver < 2021020100 else 30000004)
30000108 if dataver < 2020091300 else (40000107 if dataver < 2021020100 else 30000004)
),
0,
),
@ -579,9 +554,7 @@ class JubeatFesto(
"music": [
[
(
70000148
if dataver < 2020021900
else (90000040 if dataver < 2021081600 else 80000097),
70000148 if dataver < 2020021900 else (90000040 if dataver < 2021081600 else 80000097),
0,
),
(50000296 if dataver < 2021081600 else 90000029, 0),
@ -665,9 +638,7 @@ class JubeatFesto(
[
(50000242, 0),
(
80000034
if dataver < 2020063000
else (90000079 if dataver < 2022021600 else 50000277),
80000034 if dataver < 2020063000 else (90000079 if dataver < 2022021600 else 50000277),
1,
),
(90000037 if dataver < 2021081600 else 50000294, 1),
@ -675,9 +646,7 @@ class JubeatFesto(
[(50000260, 1), (50000261, 1)],
[
(
70000085
if dataver < 2019062100
else (90000081 if dataver < 2022021600 else 90000143),
70000085 if dataver < 2019062100 else (90000081 if dataver < 2022021600 else 90000143),
1,
),
],
@ -695,9 +664,7 @@ class JubeatFesto(
(20000111 if dataver < 2019062100 else 90000034, 1),
(90000037 if dataver < 2021081600 else 90000107, 1),
(
70000131
if dataver < 2019111800
else (90000042 if dataver < 2021081600 else 90000140),
70000131 if dataver < 2019111800 else (90000042 if dataver < 2021081600 else 90000140),
1,
),
],
@ -1753,9 +1720,7 @@ class JubeatFesto(
game_config = self.get_game_config()
konami_logo_50th = Node.void("konami_logo_50th")
info.add_child(konami_logo_50th)
konami_logo_50th.add_child(
Node.bool("is_available", game_config.get_bool("50th_anniversary"))
)
konami_logo_50th.add_child(Node.bool("is_available", game_config.get_bool("50th_anniversary")))
expert_option = Node.void("expert_option")
info.add_child(expert_option)
@ -1780,36 +1745,21 @@ class JubeatFesto(
dataver = self.model.version or 2022052400
for course in self.__get_course_list():
if course["id"] < 1:
raise Exception(
f"Invalid course ID {course['id']} found in course list!"
)
raise Exception(f"Invalid course ID {course['id']} found in course list!")
if course["id"] in valid_courses:
raise Exception(f"Duplicate ID {course['id']} found in course list!")
if (
course["clear_type"] == self.COURSE_CLEAR_HAZARD
and "hazard_type" not in course
):
if course["clear_type"] == self.COURSE_CLEAR_HAZARD and "hazard_type" not in course:
raise Exception(f"Need 'hazard_type' set in course {course['id']}!")
if (
course["course_type"] == self.COURSE_TYPE_TIME_BASED
and "end_time" not in course
):
if course["course_type"] == self.COURSE_TYPE_TIME_BASED and "end_time" not in course:
raise Exception(f"Need 'end_time' set in course {course['id']}!")
if (
course["clear_type"]
in [self.COURSE_CLEAR_SCORE, self.COURSE_CLEAR_COMBINED_SCORE]
course["clear_type"] in [self.COURSE_CLEAR_SCORE, self.COURSE_CLEAR_COMBINED_SCORE]
and "score" not in course
):
raise Exception(f"Need 'score' set in course {course['id']}!")
if (
course["clear_type"] == self.COURSE_CLEAR_SCORE
and course["score"] > 1000000
):
if course["clear_type"] == self.COURSE_CLEAR_SCORE and course["score"] > 1000000:
raise Exception(f"Invalid per-coure score in course {course['id']}!")
if (
course["clear_type"] == self.COURSE_CLEAR_COMBINED_SCORE
and course["score"] <= 1000000
):
if course["clear_type"] == self.COURSE_CLEAR_COMBINED_SCORE and course["score"] <= 1000000:
raise Exception(f"Invalid combined score in course {course['id']}!")
valid_courses.add(course["id"])
@ -1821,11 +1771,7 @@ class JubeatFesto(
clan_course.set_attribute("id", str(course["id"]))
clan_course.set_attribute("course_type", str(course["course_type"]))
clan_course.add_child(Node.s32("difficulty", course["difficulty"]))
clan_course.add_child(
Node.u64(
"etime", (course["end_time"] if "end_time" in course else 0) * 1000
)
)
clan_course.add_child(Node.u64("etime", (course["end_time"] if "end_time" in course else 0) * 1000))
clan_course.add_child(Node.string("name", course["name"]))
# List of included songs
@ -1851,9 +1797,7 @@ class JubeatFesto(
clan_course.add_child(clear)
ex_option = Node.void("ex_option")
clear.add_child(ex_option)
ex_option.add_child(
Node.bool("is_hard", course["hard"] if "hard" in course else False)
)
ex_option.add_child(Node.bool("is_hard", course["hard"] if "hard" in course else False))
ex_option.add_child(
Node.s32(
"hazard_type",
@ -1861,9 +1805,7 @@ class JubeatFesto(
)
)
clear.set_attribute("type", str(course["clear_type"]))
clear.add_child(
Node.s32("score", course["score"] if "score" in course else 0)
)
clear.add_child(Node.s32("score", course["score"] if "score" in course else 0))
reward_list = Node.void("reward_list")
clear.add_child(reward_list)
@ -1965,9 +1907,7 @@ class JubeatFesto(
if game_config.get_bool("festo_dungeon"):
festo_dungeon = Node.void("festo_dungeon")
info.add_child(festo_dungeon)
festo_dungeon.add_child(
Node.u64("etime", (Time.now() + Time.SECONDS_IN_WEEK) * 1000)
)
festo_dungeon.add_child(Node.u64("etime", (Time.now() + Time.SECONDS_IN_WEEK) * 1000))
# Unsupported team_battle nodes.
info.add_child(Node.void("team_battle"))
@ -2205,9 +2145,7 @@ class JubeatFesto(
# Grab unlock progress
item = player.child("item")
if item is not None:
owned_emblems = self.calculate_owned_items(
item.child_value("emblem_list")
)
owned_emblems = self.calculate_owned_items(item.child_value("emblem_list"))
for index in owned_emblems:
self.data.local.user.put_achievement(
self.game,
@ -2244,9 +2182,7 @@ class JubeatFesto(
return Node.void("gameend")
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void("gametop")
datanode = Node.void("data")
root.add_child(datanode)
@ -2324,43 +2260,15 @@ class JubeatFesto(
normalnode = Node.void("normal")
musicdata.add_child(normalnode)
normalnode.add_child(
Node.s32_array(
"play_cnt", scoredata.get_int_array("normal_play_cnt", 3)
)
)
normalnode.add_child(
Node.s32_array(
"clear_cnt", scoredata.get_int_array("normal_clear_cnt", 3)
)
)
normalnode.add_child(
Node.s32_array(
"fc_cnt", scoredata.get_int_array("normal_fc_cnt", 3)
)
)
normalnode.add_child(
Node.s32_array(
"ex_cnt", scoredata.get_int_array("normal_ex_cnt", 3)
)
)
normalnode.add_child(
Node.s32_array("score", scoredata.get_int_array("normal_points", 3))
)
normalnode.add_child(
Node.s8_array(
"clear", scoredata.get_int_array("normal_clear_flags", 3)
)
)
normalnode.add_child(
Node.s32_array(
"music_rate", scoredata.get_int_array("normal_music_rate", 3)
)
)
normalnode.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("normal_play_cnt", 3)))
normalnode.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("normal_clear_cnt", 3)))
normalnode.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("normal_fc_cnt", 3)))
normalnode.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("normal_ex_cnt", 3)))
normalnode.add_child(Node.s32_array("score", scoredata.get_int_array("normal_points", 3)))
normalnode.add_child(Node.s8_array("clear", scoredata.get_int_array("normal_clear_flags", 3)))
normalnode.add_child(Node.s32_array("music_rate", scoredata.get_int_array("normal_music_rate", 3)))
for i, ghost in enumerate(
scoredata.get("normal_ghost", [None, None, None])
):
for i, ghost in enumerate(scoredata.get("normal_ghost", [None, None, None])):
if ghost is None:
continue
@ -2372,39 +2280,15 @@ class JubeatFesto(
hardnode = Node.void("hard")
musicdata.add_child(hardnode)
hardnode.add_child(
Node.s32_array(
"play_cnt", scoredata.get_int_array("hard_play_cnt", 3)
)
)
hardnode.add_child(
Node.s32_array(
"clear_cnt", scoredata.get_int_array("hard_clear_cnt", 3)
)
)
hardnode.add_child(
Node.s32_array("fc_cnt", scoredata.get_int_array("hard_fc_cnt", 3))
)
hardnode.add_child(
Node.s32_array("ex_cnt", scoredata.get_int_array("hard_ex_cnt", 3))
)
hardnode.add_child(
Node.s32_array("score", scoredata.get_int_array("hard_points", 3))
)
hardnode.add_child(
Node.s8_array(
"clear", scoredata.get_int_array("hard_clear_flags", 3)
)
)
hardnode.add_child(
Node.s32_array(
"music_rate", scoredata.get_int_array("hard_music_rate", 3)
)
)
hardnode.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("hard_play_cnt", 3)))
hardnode.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("hard_clear_cnt", 3)))
hardnode.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("hard_fc_cnt", 3)))
hardnode.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("hard_ex_cnt", 3)))
hardnode.add_child(Node.s32_array("score", scoredata.get_int_array("hard_points", 3)))
hardnode.add_child(Node.s8_array("clear", scoredata.get_int_array("hard_clear_flags", 3)))
hardnode.add_child(Node.s32_array("music_rate", scoredata.get_int_array("hard_music_rate", 3)))
for i, ghost in enumerate(
scoredata.get("hard_ghost", [None, None, None])
):
for i, ghost in enumerate(scoredata.get("hard_ghost", [None, None, None])):
if ghost is None:
continue
@ -2424,9 +2308,7 @@ class JubeatFesto(
force_unlock = game_config.get_bool("force_song_unlock")
# Calculate all of our achievement-backed entities.
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
owned_songs: Set[int] = set()
owned_secrets: Set[int] = set()
owned_emblems: Set[int] = set()
@ -2434,9 +2316,7 @@ class JubeatFesto(
course_completion: Dict[int, ValidatedDict] = {}
for achievement in achievements:
if achievement.type == "event":
event_completion[achievement.id] = achievement.data.get_bool(
"is_completed"
)
event_completion[achievement.id] = achievement.data.get_bool("is_completed")
elif achievement.type == "course":
course_completion[achievement.id] = achievement.data
elif achievement.type == "emblem":
@ -2480,12 +2360,8 @@ class JubeatFesto(
info.add_child(Node.s32("mtg_entry_cnt", profile.get_int("mtg_entry_cnt")))
info.add_child(Node.s32("mtg_hold_cnt", profile.get_int("mtg_hold_cnt")))
info.add_child(Node.u8("mtg_result", profile.get_int("mtg_result")))
info.add_child(
Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points"))
)
info.add_child(
Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played"))
)
info.add_child(Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points")))
info.add_child(Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played")))
# Looks to be set to true when there's an old profile, stops tutorial from
# happening on first load.
@ -2532,55 +2408,27 @@ class JubeatFesto(
# Default music availability, I think? The game doesn't seem to make much use of this, so I think
# we can safely set it to all 1's much like we do the open_music_list bitfield in global settings.
item.add_child(
Node.s32_array(
"music_list", profile.get_int_array("music_list", 64, [-1] * 64)
)
)
item.add_child(Node.s32_array("music_list", profile.get_int_array("music_list", 64, [-1] * 64)))
# Song unlocks, force everything on if force unlocked, otherwise default to what the game granted.
item.add_child(
Node.s32_array(
"secret_list",
([-1] * 64)
if force_unlock
else self.create_owned_items(owned_songs, 64),
([-1] * 64) if force_unlock else self.create_owned_items(owned_songs, 64),
)
)
# We force unlock all themes, markers, titles, and parts, regardless of what the client ended up earning.
item.add_child(
Node.s32_array(
"theme_list", profile.get_int_array("theme_list", 16, [-1] * 16)
)
)
item.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list", 16, [-1] * 16)
)
)
item.add_child(
Node.s32_array(
"title_list", profile.get_int_array("title_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array(
"parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)
)
)
item.add_child(Node.s32_array("theme_list", profile.get_int_array("theme_list", 16, [-1] * 16)))
item.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list", 16, [-1] * 16)))
item.add_child(Node.s32_array("title_list", profile.get_int_array("title_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)))
# These get earned by unlocking them through JBOX.
item.add_child(
Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96))
)
item.add_child(Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96)))
# I got no idea wtf this is, so I'm defaulting it to all on like the above ones.
item.add_child(
Node.s32_array(
"commu_list", profile.get_int_array("commu_list", 16, [-1] * 16)
)
)
item.add_child(Node.s32_array("commu_list", profile.get_int_array("commu_list", 16, [-1] * 16)))
# I have no idea what these are for. I figured it was for the server to grant songs/themes/markers
# outside of gameplay, but the game doesn't seem to react to setting values here. So, lets set them
@ -2592,21 +2440,11 @@ class JubeatFesto(
new.add_child(
Node.s32_array(
"secret_list",
([-1] * 64)
if force_unlock
else self.create_owned_items(owned_secrets, 64),
)
)
new.add_child(
Node.s32_array(
"theme_list", profile.get_int_array("theme_list_new", 16, [-1] * 16)
)
)
new.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list_new", 16, [-1] * 16)
([-1] * 64) if force_unlock else self.create_owned_items(owned_secrets, 64),
)
)
new.add_child(Node.s32_array("theme_list", profile.get_int_array("theme_list_new", 16, [-1] * 16)))
new.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list_new", 16, [-1] * 16)))
# Add rivals to profile.
rivallist = Node.void("rivallist")
@ -2643,9 +2481,7 @@ class JubeatFesto(
lab_edit_seq.set_attribute("count", "0")
# Full combo challenge
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -2705,11 +2541,7 @@ class JubeatFesto(
state = 0x0
state |= self.EVENT_STATUS_OPEN if eventdata["enabled"] else 0
state |= (
self.EVENT_STATUS_COMPLETE
if event_completion.get(eventid, False)
else 0
)
state |= self.EVENT_STATUS_COMPLETE if event_completion.get(eventid, False) else 0
event.add_child(Node.u8("state", state))
# JBox stuff
@ -2776,9 +2608,7 @@ class JubeatFesto(
status = 0
status |= self.COURSE_STATUS_SEEN if status_dict.get_bool("seen") else 0
status |= self.COURSE_STATUS_PLAYED if status_dict.get_bool("played") else 0
status |= (
self.COURSE_STATUS_CLEARED if status_dict.get_bool("cleared") else 0
)
status |= self.COURSE_STATUS_CLEARED if status_dict.get_bool("cleared") else 0
coursenode = Node.void("course")
course_list.add_child(coursenode)
@ -2871,20 +2701,14 @@ class JubeatFesto(
# Festo dungeon
festo_dungeon = Node.void("festo_dungeon")
player.add_child(festo_dungeon)
festo_dungeon.add_child(
Node.s32("phase", profile.get_int("festo_dungeon_phase"))
)
festo_dungeon.add_child(
Node.s32("clear_flag", profile.get_int("festo_dungeon_clear_flag"))
)
festo_dungeon.add_child(Node.s32("phase", profile.get_int("festo_dungeon_phase")))
festo_dungeon.add_child(Node.s32("clear_flag", profile.get_int("festo_dungeon_clear_flag")))
# Missing travel event, which I do not want to implement.
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_bool("saved", True)
data = request.child("data")
@ -2923,12 +2747,8 @@ class JubeatFesto(
newprofile.replace_int("beat_cnt", info.child_value("beat_cnt"))
newprofile.replace_int("mynews_cnt", info.child_value("mynews_cnt"))
newprofile.replace_int(
"bonus_tune_points", info.child_value("bonus_tune_points")
)
newprofile.replace_bool(
"is_bonus_tune_played", info.child_value("is_bonus_tune_played")
)
newprofile.replace_int("bonus_tune_points", info.child_value("bonus_tune_points"))
newprofile.replace_bool("is_bonus_tune_played", info.child_value("is_bonus_tune_played"))
# Grab last settings
lastnode = player.child("last")
@ -2953,30 +2773,16 @@ class JubeatFesto(
# Grab unlock progress
item = player.child("item")
if item is not None:
newprofile.replace_int_array(
"music_list", 64, item.child_value("music_list")
)
newprofile.replace_int_array(
"theme_list", 16, item.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list", 16, item.child_value("marker_list")
)
newprofile.replace_int_array(
"title_list", 160, item.child_value("title_list")
)
newprofile.replace_int_array(
"parts_list", 160, item.child_value("parts_list")
)
newprofile.replace_int_array(
"commu_list", 16, item.child_value("commu_list")
)
newprofile.replace_int_array("music_list", 64, item.child_value("music_list"))
newprofile.replace_int_array("theme_list", 16, item.child_value("theme_list"))
newprofile.replace_int_array("marker_list", 16, item.child_value("marker_list"))
newprofile.replace_int_array("title_list", 160, item.child_value("title_list"))
newprofile.replace_int_array("parts_list", 160, item.child_value("parts_list"))
newprofile.replace_int_array("commu_list", 16, item.child_value("commu_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_songs = self.calculate_owned_items(
item.child_value("secret_list")
)
owned_songs = self.calculate_owned_items(item.child_value("secret_list"))
for index in owned_songs:
self.data.local.user.put_achievement(
self.game,
@ -3000,18 +2806,12 @@ class JubeatFesto(
newitem = item.child("new")
if newitem is not None:
newprofile.replace_int_array(
"theme_list_new", 16, newitem.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list_new", 16, newitem.child_value("marker_list")
)
newprofile.replace_int_array("theme_list_new", 16, newitem.child_value("theme_list"))
newprofile.replace_int_array("marker_list_new", 16, newitem.child_value("marker_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_secrets = self.calculate_owned_items(
newitem.child_value("secret_list")
)
owned_secrets = self.calculate_owned_items(newitem.child_value("secret_list"))
for index in owned_secrets:
self.data.local.user.put_achievement(
self.game,
@ -3226,9 +3026,7 @@ class JubeatFesto(
# Save it back
newprofile.replace_dict("pick_up_chart", pick_up_chart)
newprofile.replace_float(
"pick_up_jubility", float(hot_music_list.attribute("param")) / 10
)
newprofile.replace_float("pick_up_jubility", float(hot_music_list.attribute("param")) / 10)
# Common jubility stuff
other_music_list = target_music.child("other_music_list")
@ -3251,9 +3049,7 @@ class JubeatFesto(
# Save it back
newprofile.replace_dict("common_chart", common_chart)
newprofile.replace_float(
"common_jubility", float(other_music_list.attribute("param")) / 10
)
newprofile.replace_float("common_jubility", float(other_music_list.attribute("param")) / 10)
# Clan course saving
clan_course_list = player.child("course_list")
@ -3281,9 +3077,7 @@ class JubeatFesto(
oldcourse = ValidatedDict()
oldcourse.replace_bool("seen", oldcourse.get_bool("seen") or is_seen)
oldcourse.replace_bool(
"played", oldcourse.get_bool("played") or is_played
)
oldcourse.replace_bool("played", oldcourse.get_bool("played") or is_played)
# Save it as an achievement
self.data.local.user.put_achievement(
@ -3335,12 +3129,8 @@ class JubeatFesto(
festo_dungeon = player.child("festo_dungeon")
if festo_dungeon is not None:
newprofile.replace_int(
"festo_dungeon_phase", festo_dungeon.child_value("phase")
)
newprofile.replace_int(
"festo_dungeon_clear_flag", festo_dungeon.child_value("clear_flag")
)
newprofile.replace_int("festo_dungeon_phase", festo_dungeon.child_value("phase"))
newprofile.replace_int("festo_dungeon_clear_flag", festo_dungeon.child_value("clear_flag"))
# Keep track of play statistics
self.update_play_statistics(userid)

View File

@ -199,9 +199,7 @@ class JubeatProp(
return cls.__rank_to_class(cls.__class_to_rank(cur_class, cur_subclass) - 1)
@classmethod
def _get_league_buckets(
cls, scores: List[Tuple[UserID, int]]
) -> Tuple[List[UserID], List[UserID], List[UserID]]:
def _get_league_buckets(cls, scores: List[Tuple[UserID, int]]) -> Tuple[List[UserID], List[UserID], List[UserID]]:
"""
Given a list of userid, score tuples, return a tuple containing three lists.
The first list is the top 30% scorer IDs, the next list is the middle 40%
@ -253,9 +251,7 @@ class JubeatProp(
scores.append(
(
userid,
league_score["score"][0]
+ league_score["score"][1]
+ league_score["score"][2],
league_score["score"][0] + league_score["score"][1] + league_score["score"][2],
)
)
else:
@ -264,9 +260,7 @@ class JubeatProp(
return scores, absentees
@classmethod
def _get_league_absentees(
cls, data: Data, current_id: int, absentees: List[UserID]
) -> List[UserID]:
def _get_league_absentees(cls, data: Data, current_id: int, absentees: List[UserID]) -> List[UserID]:
"""
Given a list of user IDs that didn't play for some number of weeks, return
a subset of those IDs that have been absent enough weeks to get a demotion.
@ -333,22 +327,15 @@ class JubeatProp(
data.local.user.put_profile(cls.game, cls.version, userid, profile)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Once a week, insert a new league course. Every day, insert new FC challenge courses.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "league_course", "weekly"
):
if data.local.network.should_schedule(cls.game, cls.version, "league_course", "weekly"):
# Generate a new league course list, save it to the DB.
start_time, end_time = data.local.network.get_schedule_duration("weekly")
all_songs = set(
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
)
all_songs = set(song.id for song in data.local.music.get_all_songs(cls.game, cls.version))
if len(all_songs) >= 3:
league_songs = random.sample(all_songs, 3)
data.local.game.put_time_sensitive_settings(
@ -390,19 +377,12 @@ class JubeatProp(
cls._modify_profile(data, userid, "demote")
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "league_course", "weekly"
)
data.local.network.mark_scheduled(cls.game, cls.version, "league_course", "weekly")
if data.local.network.should_schedule(
cls.game, cls.version, "fc_challenge", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "fc_challenge", "daily"):
# Generate a new list of two FC challenge songs.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = set(
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
)
all_songs = set(song.id for song in data.local.music.get_all_songs(cls.game, cls.version))
if len(all_songs) >= 2:
daily_songs = random.sample(all_songs, 2)
data.local.game.put_time_sensitive_settings(
@ -428,9 +408,7 @@ class JubeatProp(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "fc_challenge", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "fc_challenge", "daily")
return events
@ -466,9 +444,7 @@ class JubeatProp(
info.add_child(only_now_music)
# Full combo challenge?
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -803,11 +779,7 @@ class JubeatProp(
result.add_child(Node.s32_array("score", scores))
# Last course ID
data.add_child(
Node.s32(
"last_course_id", profile.get_dict("last").get_int("last_course_id", -1)
)
)
data.add_child(Node.s32("last_course_id", profile.get_dict("last").get_int("last_course_id", -1)))
return gametop
@ -830,9 +802,7 @@ class JubeatProp(
data.add_child(league_list)
# Look up the current league charts in the DB
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "league"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "league")
if entry is not None:
# Just get the week number, use that as the ID
leagueid = int(entry["start_time"] / 604800)
@ -870,27 +840,15 @@ class JubeatProp(
result = Node.void("result")
player.add_child(result)
league_score = self.data.local.user.get_achievement(
self.game, self.version, userid, leagueid, "league"
)
league_score = self.data.local.user.get_achievement(self.game, self.version, userid, leagueid, "league")
if league_score is None:
league_score = ValidatedDict()
result.add_child(
Node.s32_array("score", league_score.get_int_array("score", 3, [0] * 3))
)
result.add_child(
Node.s8_array("clear", league_score.get_int_array("clear", 3, [0] * 3))
)
result.add_child(Node.s32_array("score", league_score.get_int_array("score", 3, [0] * 3)))
result.add_child(Node.s8_array("clear", league_score.get_int_array("clear", 3, [0] * 3)))
data.add_child(
Node.s32("last_class", profile.get_dict("last").get_int("league_class", 1))
)
data.add_child(
Node.s32(
"last_subclass", profile.get_dict("last").get_int("league_subclass", 5)
)
)
data.add_child(Node.s32("last_class", profile.get_dict("last").get_int("league_class", 1)))
data.add_child(Node.s32("last_subclass", profile.get_dict("last").get_int("league_subclass", 5)))
data.add_child(Node.bool("is_checked", profile.get_bool("league_is_checked")))
return gametop
@ -905,9 +863,7 @@ class JubeatProp(
force_unlock = game_config.get_bool("force_song_unlock")
# Allow figuring out owned emblems.
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
owned_songs: Set[int] = set()
owned_secrets: Set[int] = set()
owned_emblems: Set[int] = set()
@ -953,12 +909,8 @@ class JubeatProp(
info.add_child(Node.s32("match_cnt", profile.get_int("match_cnt")))
info.add_child(Node.s32("beat_cnt", profile.get_int("beat_cnt")))
info.add_child(Node.s32("mynews_cnt", profile.get_int("mynews_cnt")))
info.add_child(
Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points"))
)
info.add_child(
Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played"))
)
info.add_child(Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points")))
info.add_child(Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played")))
# Looks to be set to true when there's an old profile, stops tutorial from
# happening on first load.
@ -1008,55 +960,29 @@ class JubeatProp(
# Secret unlocks
item = Node.void("item")
player.add_child(item)
item.add_child(
Node.s32_array(
"music_list", profile.get_int_array("music_list", 32, [-1] * 32)
)
)
item.add_child(Node.s32_array("music_list", profile.get_int_array("music_list", 32, [-1] * 32)))
item.add_child(
Node.s32_array(
"secret_list",
([-1] * 32)
if force_unlock
else self.create_owned_items(owned_songs, 32),
([-1] * 32) if force_unlock else self.create_owned_items(owned_songs, 32),
)
)
item.add_child(Node.s16("theme_list", profile.get_int("theme_list", -1)))
item.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list", 2, [-1] * 2)
)
)
item.add_child(
Node.s32_array(
"title_list", profile.get_int_array("title_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array(
"parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96))
)
item.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list", 2, [-1] * 2)))
item.add_child(Node.s32_array("title_list", profile.get_int_array("title_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96)))
new = Node.void("new")
item.add_child(new)
new.add_child(
Node.s32_array(
"secret_list",
([-1] * 32)
if force_unlock
else self.create_owned_items(owned_secrets, 32),
([-1] * 32) if force_unlock else self.create_owned_items(owned_secrets, 32),
)
)
new.add_child(Node.s16("theme_list", profile.get_int("theme_list_new", -1)))
new.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list_new", 2, [-1] * 2)
)
)
new.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list_new", 2, [-1] * 2)))
# Sane defaults for unknown/who cares nodes
history = Node.void("history")
@ -1070,9 +996,7 @@ class JubeatProp(
cabinet_survey.add_child(Node.u32("read_flag", 0))
kaitou_bisco = Node.void("kaitou_bisco")
player.add_child(kaitou_bisco)
kaitou_bisco.add_child(
Node.u32("read_flag", profile.get_int("kaitou_bisco_read_flag"))
)
kaitou_bisco.add_child(Node.u32("read_flag", profile.get_int("kaitou_bisco_read_flag")))
navi = Node.void("navi")
player.add_child(navi)
navi.add_child(Node.u32("flag", profile.get_int("navi_flag")))
@ -1089,15 +1013,11 @@ class JubeatProp(
event.set_attribute("type", str(achievement.id))
state = 0x0
state = (
state + 0x2 if achievement.data.get_bool("is_completed") else 0x0
)
state = state + 0x2 if achievement.data.get_bool("is_completed") else 0x0
event.add_child(Node.u8("state", state))
# Full combo challenge
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -1161,15 +1081,9 @@ class JubeatProp(
league = Node.void("league")
rival.add_child(league)
league.add_child(
Node.bool(
"is_first_play", rprofile.get_bool("league_is_first_play", True)
)
)
league.add_child(Node.bool("is_first_play", rprofile.get_bool("league_is_first_play", True)))
league.add_child(Node.s32("class", rprofile.get_int("league_class", 1)))
league.add_child(
Node.s32("subclass", rprofile.get_int("league_subclass", 5))
)
league.add_child(Node.s32("subclass", rprofile.get_int("league_subclass", 5)))
# Lazy way of keeping track of rivals, since we can only have 3
# or the game with throw up.
@ -1214,17 +1128,13 @@ class JubeatProp(
player.add_child(career)
career.add_child(Node.s16("level", careerdict.get_int("level", 1)))
career.add_child(Node.s32("point", careerdict.get_int("point")))
career.add_child(
Node.s32_array("param", careerdict.get_int_array("param", 10, [-1] * 10))
)
career.add_child(Node.s32_array("param", careerdict.get_int_array("param", 10, [-1] * 10)))
career.add_child(Node.bool("is_unlocked", careerdict.get_bool("is_unlocked")))
# League stuff
league = Node.void("league")
player.add_child(league)
league.add_child(
Node.bool("is_first_play", profile.get_bool("league_is_first_play", True))
)
league.add_child(Node.bool("is_first_play", profile.get_bool("league_is_first_play", True)))
league.add_child(Node.s32("class", profile.get_int("league_class", 1)))
league.add_child(Node.s32("subclass", profile.get_int("league_subclass", 5)))
@ -1276,9 +1186,7 @@ class JubeatProp(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_bool("saved", True)
data = request.child("data")
@ -1318,17 +1226,11 @@ class JubeatProp(
newprofile.replace_int("clear_cnt", info.child_value("clear_cnt"))
newprofile.replace_int("match_cnt", info.child_value("match_cnt"))
newprofile.replace_int("beat_cnt", info.child_value("beat_cnt"))
newprofile.replace_int(
"total_best_score", info.child_value("total_best_score")
)
newprofile.replace_int("total_best_score", info.child_value("total_best_score"))
newprofile.replace_int("mynews_cnt", info.child_value("mynews_cnt"))
newprofile.replace_int(
"bonus_tune_points", info.child_value("bonus_tune_points")
)
newprofile.replace_bool(
"is_bonus_tune_played", info.child_value("is_bonus_tune_played")
)
newprofile.replace_int("bonus_tune_points", info.child_value("bonus_tune_points"))
newprofile.replace_bool("is_bonus_tune_played", info.child_value("is_bonus_tune_played"))
# Grab last settings (finally mostly in its own node!)
lastnode = player.child("last")
@ -1353,25 +1255,15 @@ class JubeatProp(
# Grab unlock progress
item = player.child("item")
if item is not None:
newprofile.replace_int_array(
"title_list", 160, item.child_value("title_list")
)
newprofile.replace_int_array("title_list", 160, item.child_value("title_list"))
newprofile.replace_int("theme_list", item.child_value("theme_list"))
newprofile.replace_int_array(
"marker_list", 2, item.child_value("marker_list")
)
newprofile.replace_int_array(
"parts_list", 160, item.child_value("parts_list")
)
newprofile.replace_int_array(
"music_list", 32, item.child_value("music_list")
)
newprofile.replace_int_array("marker_list", 2, item.child_value("marker_list"))
newprofile.replace_int_array("parts_list", 160, item.child_value("parts_list"))
newprofile.replace_int_array("music_list", 32, item.child_value("music_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_songs = self.calculate_owned_items(
item.child_value("secret_list")
)
owned_songs = self.calculate_owned_items(item.child_value("secret_list"))
for index in owned_songs:
self.data.local.user.put_achievement(
self.game,
@ -1395,18 +1287,12 @@ class JubeatProp(
newitem = item.child("new")
if newitem is not None:
newprofile.replace_int(
"theme_list_new", newitem.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list_new", 2, newitem.child_value("marker_list")
)
newprofile.replace_int("theme_list_new", newitem.child_value("theme_list"))
newprofile.replace_int_array("marker_list_new", 2, newitem.child_value("marker_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_secrets = self.calculate_owned_items(
newitem.child_value("secret_list")
)
owned_secrets = self.calculate_owned_items(newitem.child_value("secret_list"))
for index in owned_secrets:
self.data.local.user.put_achievement(
self.game,
@ -1478,9 +1364,7 @@ class JubeatProp(
# A whole bunch of miscelaneous shit
newprofile.replace_int("navi_flag", player.child_value("navi/flag"))
newprofile.replace_int(
"kaitou_bisco_read_flag", player.child_value("kaitou_bisco/read_flag")
)
newprofile.replace_int("kaitou_bisco_read_flag", player.child_value("kaitou_bisco/read_flag"))
# Get timestamps for played songs
timestamps: Dict[int, int] = {}
@ -1527,9 +1411,7 @@ class JubeatProp(
if flags & bit > 0:
medal = max(medal, mapping[bit])
self.update_score(
userid, timestamp, songid, chart, points, medal, combo, ghost
)
self.update_score(userid, timestamp, songid, chart, points, medal, combo, ghost)
# If this was a course save, grab and save that info too
course = player.child("course")
@ -1558,12 +1440,8 @@ class JubeatProp(
league = player.child("league")
if league is not None:
leagueid = league.child_value("league_id")
newprofile.replace_bool(
"league_is_checked", league.child_value("is_checked")
)
newprofile.replace_bool(
"league_is_first_play", league.child_value("is_first_play")
)
newprofile.replace_bool("league_is_checked", league.child_value("is_checked"))
newprofile.replace_bool("league_is_first_play", league.child_value("is_first_play"))
# Extract scores
score = [0] * 3
@ -1605,9 +1483,7 @@ class JubeatProp(
return newprofile
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void("gametop")
datanode = Node.void("data")
root.add_child(datanode)
@ -1673,24 +1549,12 @@ class JubeatProp(
playdata.add_child(musicdata)
musicdata.set_attribute("music_id", scoreid)
musicdata.add_child(
Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3))
)
musicdata.add_child(
Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3))
)
musicdata.add_child(
Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3))
)
musicdata.add_child(
Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3))
)
musicdata.add_child(
Node.s32_array("score", scoredata.get_int_array("points", 3))
)
musicdata.add_child(
Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3))
)
musicdata.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3)))
musicdata.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3)))
musicdata.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3)))
musicdata.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3)))
musicdata.add_child(Node.s32_array("score", scoredata.get_int_array("points", 3)))
musicdata.add_child(Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3)))
ghosts = scoredata.get("ghost", [None, None, None])
for i in range(len(ghosts)):

View File

@ -56,22 +56,15 @@ class JubeatQubell(
return JubeatProp(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert daily FC challenges into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "fc_challenge", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "fc_challenge", "daily"):
# Generate a new list of two FC challenge songs.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = set(
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
)
all_songs = set(song.id for song in data.local.music.get_all_songs(cls.game, cls.version))
if len(all_songs) >= 2:
daily_songs = random.sample(all_songs, 2)
data.local.game.put_time_sensitive_settings(
@ -97,9 +90,7 @@ class JubeatQubell(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "fc_challenge", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "fc_challenge", "daily")
return events
@classmethod
@ -674,9 +665,7 @@ class JubeatQubell(
# Grab unlock progress
item = player.child("item")
if item is not None:
owned_emblems = self.calculate_owned_items(
item.child_value("emblem_list")
)
owned_emblems = self.calculate_owned_items(item.child_value("emblem_list"))
for index in owned_emblems:
self.data.local.user.put_achievement(
self.game,
@ -722,9 +711,7 @@ class JubeatQubell(
game_config = self.get_game_config()
force_unlock = game_config.get_bool("force_song_unlock")
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
owned_songs: Set[int] = set()
owned_secrets: Set[int] = set()
owned_emblems: Set[int] = set()
@ -773,12 +760,8 @@ class JubeatQubell(
info.add_child(Node.s32("match_cnt", profile.get_int("match_cnt")))
info.add_child(Node.s32("beat_cnt", profile.get_int("beat_cnt")))
info.add_child(Node.s32("mynews_cnt", profile.get_int("mynews_cnt")))
info.add_child(
Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points"))
)
info.add_child(
Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played"))
)
info.add_child(Node.s32("bonus_tune_points", profile.get_int("bonus_tune_points")))
info.add_child(Node.bool("is_bonus_tune_played", profile.get_bool("is_bonus_tune_played")))
# Looks to be set to true when there's an old profile, stops tutorial from
# happening on first load.
@ -829,63 +812,29 @@ class JubeatQubell(
# Secret unlocks
item = Node.void("item")
player.add_child(item)
item.add_child(
Node.s32_array(
"music_list", profile.get_int_array("music_list", 64, [-1] * 64)
)
)
item.add_child(Node.s32_array("music_list", profile.get_int_array("music_list", 64, [-1] * 64)))
item.add_child(
Node.s32_array(
"secret_list",
([-1] * 64)
if force_unlock
else self.create_owned_items(owned_songs, 64),
([-1] * 64) if force_unlock else self.create_owned_items(owned_songs, 64),
)
)
item.add_child(
Node.s32_array(
"theme_list", profile.get_int_array("theme_list", 16, [-1] * 16)
)
)
item.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list", 16, [-1] * 16)
)
)
item.add_child(
Node.s32_array(
"title_list", profile.get_int_array("title_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array(
"parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)
)
)
item.add_child(
Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96))
)
item.add_child(Node.s32_array("theme_list", profile.get_int_array("theme_list", 16, [-1] * 16)))
item.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list", 16, [-1] * 16)))
item.add_child(Node.s32_array("title_list", profile.get_int_array("title_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("parts_list", profile.get_int_array("parts_list", 160, [-1] * 160)))
item.add_child(Node.s32_array("emblem_list", self.create_owned_items(owned_emblems, 96)))
new = Node.void("new")
item.add_child(new)
new.add_child(
Node.s32_array(
"secret_list",
([-1] * 64)
if force_unlock
else self.create_owned_items(owned_secrets, 64),
)
)
new.add_child(
Node.s32_array(
"theme_list", profile.get_int_array("theme_list_new", 16, [-1] * 16)
)
)
new.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list_new", 16, [-1] * 16)
([-1] * 64) if force_unlock else self.create_owned_items(owned_secrets, 64),
)
)
new.add_child(Node.s32_array("theme_list", profile.get_int_array("theme_list_new", 16, [-1] * 16)))
new.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list_new", 16, [-1] * 16)))
# Add rivals to profile.
rivallist = Node.void("rivallist")
@ -924,9 +873,7 @@ class JubeatQubell(
lab_edit_seq.set_attribute("count", "0")
# Full combo challenge
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -987,9 +934,7 @@ class JubeatQubell(
event.set_attribute("type", str(achievement.id))
state = 0x0
state = (
state + 0x2 if achievement.data.get_bool("is_completed") else 0x0
)
state = state + 0x2 if achievement.data.get_bool("is_completed") else 0x0
event.add_child(Node.u8("state", state))
# JBox stuff
@ -1025,9 +970,7 @@ class JubeatQubell(
main.add_child(stage)
stage.set_attribute("number", str(digdigdict.get_int("stage_number", 1)))
stage.add_child(Node.s32("point", digdigdict.get_int("point")))
stage.add_child(
Node.s32_array("param", digdigdict.get_int_array("param", 12, [0] * 12))
)
stage.add_child(Node.s32_array("param", digdigdict.get_int_array("param", 12, [0] * 12)))
# Emerald eternal stages
eternal = Node.void("eternal")
@ -1035,42 +978,20 @@ class JubeatQubell(
eternal.add_child(Node.s32("ratio", 1))
eternal.add_child(Node.s64("used_point", eternaldict.get_int("used_point")))
eternal.add_child(Node.s64("point", eternaldict.get_int("point")))
eternal.add_child(
Node.s64("excavated_point", eternaldict.get_int("excavated_point"))
)
eternal.add_child(Node.s64("excavated_point", eternaldict.get_int("excavated_point")))
cube = Node.void("cube")
eternal.add_child(cube)
cube.add_child(
Node.s8_array("state", eternaldict.get_int_array("state", 12, [0] * 12))
)
cube.add_child(Node.s8_array("state", eternaldict.get_int_array("state", 12, [0] * 12)))
item = Node.void("item")
cube.add_child(item)
item.add_child(
Node.s32_array("kind", eternaldict.get_int_array("item_kind", 12, [0] * 12))
)
item.add_child(
Node.s32_array(
"value", eternaldict.get_int_array("item_value", 12, [0] * 12)
)
)
item.add_child(Node.s32_array("kind", eternaldict.get_int_array("item_kind", 12, [0] * 12)))
item.add_child(Node.s32_array("value", eternaldict.get_int_array("item_value", 12, [0] * 12)))
norma = Node.void("norma")
cube.add_child(norma)
norma.add_child(Node.s64_array("till_time", [0] * 12))
norma.add_child(
Node.s32_array(
"kind", eternaldict.get_int_array("norma_kind", 12, [0] * 12)
)
)
norma.add_child(
Node.s32_array(
"value", eternaldict.get_int_array("norma_value", 12, [0] * 12)
)
)
norma.add_child(
Node.s32_array(
"param", eternaldict.get_int_array("norma_param", 12, [0] * 12)
)
)
norma.add_child(Node.s32_array("kind", eternaldict.get_int_array("norma_kind", 12, [0] * 12)))
norma.add_child(Node.s32_array("value", eternaldict.get_int_array("norma_value", 12, [0] * 12)))
norma.add_child(Node.s32_array("param", eternaldict.get_int_array("norma_param", 12, [0] * 12)))
if self.ENABLE_GARNET:
# Garnet
@ -1084,14 +1005,8 @@ class JubeatQubell(
olddict.get_int_array("excavated_point", 5, [0] * 5),
)
)
old.add_child(
Node.s32_array(
"excavated", olddict.get_int_array("excavated", 5, [0] * 5)
)
)
old.add_child(
Node.s32_array("param", olddict.get_int_array("param", 5, [0] * 5))
)
old.add_child(Node.s32_array("excavated", olddict.get_int_array("excavated", 5, [0] * 5)))
old.add_child(Node.s32_array("param", olddict.get_int_array("param", 5, [0] * 5)))
# This should have a bunch of sub-nodes with the following format. Note that only
# the first ten nodes are saved even if more are read. Presumably this is the list
# of old songs we are allowing the player to unlock? Doesn't matter, we're disabling
@ -1110,9 +1025,7 @@ class JubeatQubell(
main.add_child(stage_list)
# Stage numbers are between 1 and 13 inclusive.
for i in range(1, 14):
stage_flags = self.data.local.user.get_achievement(
self.game, self.version, userid, i, "stage"
)
stage_flags = self.data.local.user.get_achievement(self.game, self.version, userid, i, "stage")
if stage_flags is None:
stage_flags = ValidatedDict()
@ -1167,9 +1080,7 @@ class JubeatQubell(
return root
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void("gametop")
datanode = Node.void("data")
root.add_child(datanode)
@ -1235,24 +1146,12 @@ class JubeatQubell(
playdata.add_child(musicdata)
musicdata.set_attribute("music_id", scoreid)
musicdata.add_child(
Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3))
)
musicdata.add_child(
Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3))
)
musicdata.add_child(
Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3))
)
musicdata.add_child(
Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3))
)
musicdata.add_child(
Node.s32_array("score", scoredata.get_int_array("points", 3))
)
musicdata.add_child(
Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3))
)
musicdata.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3)))
musicdata.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3)))
musicdata.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3)))
musicdata.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3)))
musicdata.add_child(Node.s32_array("score", scoredata.get_int_array("points", 3)))
musicdata.add_child(Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3)))
ghosts = scoredata.get("ghost", [None, None, None])
for i in range(len(ghosts)):
@ -1266,9 +1165,7 @@ class JubeatQubell(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_bool("saved", True)
data = request.child("data")
@ -1309,12 +1206,8 @@ class JubeatQubell(
newprofile.replace_int("beat_cnt", info.child_value("beat_cnt"))
newprofile.replace_int("mynews_cnt", info.child_value("mynews_cnt"))
newprofile.replace_int(
"bonus_tune_points", info.child_value("bonus_tune_points")
)
newprofile.replace_bool(
"is_bonus_tune_played", info.child_value("is_bonus_tune_played")
)
newprofile.replace_int("bonus_tune_points", info.child_value("bonus_tune_points"))
newprofile.replace_bool("is_bonus_tune_played", info.child_value("is_bonus_tune_played"))
# Grab last settings
lastnode = player.child("last")
@ -1340,27 +1233,15 @@ class JubeatQubell(
# Grab unlock progress
item = player.child("item")
if item is not None:
newprofile.replace_int_array(
"music_list", 64, item.child_value("music_list")
)
newprofile.replace_int_array(
"theme_list", 16, item.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list", 16, item.child_value("marker_list")
)
newprofile.replace_int_array(
"title_list", 160, item.child_value("title_list")
)
newprofile.replace_int_array(
"parts_list", 160, item.child_value("parts_list")
)
newprofile.replace_int_array("music_list", 64, item.child_value("music_list"))
newprofile.replace_int_array("theme_list", 16, item.child_value("theme_list"))
newprofile.replace_int_array("marker_list", 16, item.child_value("marker_list"))
newprofile.replace_int_array("title_list", 160, item.child_value("title_list"))
newprofile.replace_int_array("parts_list", 160, item.child_value("parts_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_songs = self.calculate_owned_items(
item.child_value("secret_list")
)
owned_songs = self.calculate_owned_items(item.child_value("secret_list"))
for index in owned_songs:
self.data.local.user.put_achievement(
self.game,
@ -1384,18 +1265,12 @@ class JubeatQubell(
newitem = item.child("new")
if newitem is not None:
newprofile.replace_int_array(
"theme_list_new", 16, newitem.child_value("theme_list")
)
newprofile.replace_int_array(
"marker_list_new", 16, newitem.child_value("marker_list")
)
newprofile.replace_int_array("theme_list_new", 16, newitem.child_value("theme_list"))
newprofile.replace_int_array("marker_list_new", 16, newitem.child_value("marker_list"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_secrets = self.calculate_owned_items(
newitem.child_value("secret_list")
)
owned_secrets = self.calculate_owned_items(newitem.child_value("secret_list"))
for index in owned_secrets:
self.data.local.user.put_achievement(
self.game,
@ -1492,27 +1367,13 @@ class JubeatQubell(
if eternal is not None:
eternaldict.replace_int("used_point", eternal.child_value("used_point"))
eternaldict.replace_int("point", eternal.child_value("point"))
eternaldict.replace_int(
"excavated_point", eternal.child_value("excavated_point")
)
eternaldict.replace_int_array(
"state", 12, eternal.child_value("cube/state")
)
eternaldict.replace_int_array(
"item_kind", 12, eternal.child_value("cube/item/kind")
)
eternaldict.replace_int_array(
"item_value", 12, eternal.child_value("cube/item/value")
)
eternaldict.replace_int_array(
"norma_kind", 12, eternal.child_value("cube/norma/kind")
)
eternaldict.replace_int_array(
"norma_value", 12, eternal.child_value("cube/norma/value")
)
eternaldict.replace_int_array(
"norma_param", 12, eternal.child_value("cube/norma/param")
)
eternaldict.replace_int("excavated_point", eternal.child_value("excavated_point"))
eternaldict.replace_int_array("state", 12, eternal.child_value("cube/state"))
eternaldict.replace_int_array("item_kind", 12, eternal.child_value("cube/item/kind"))
eternaldict.replace_int_array("item_value", 12, eternal.child_value("cube/item/value"))
eternaldict.replace_int_array("norma_kind", 12, eternal.child_value("cube/norma/kind"))
eternaldict.replace_int_array("norma_value", 12, eternal.child_value("cube/norma/value"))
eternaldict.replace_int_array("norma_param", 12, eternal.child_value("cube/norma/param"))
digdigdict.replace_dict("eternal", eternaldict)
if self.ENABLE_GARNET:
@ -1521,12 +1382,8 @@ class JubeatQubell(
if old is not None:
olddict.replace_int("need_point", old.child_value("need_point"))
olddict.replace_int("point", old.child_value("point"))
olddict.replace_int_array(
"excavated_point", 5, old.child_value("excavated_point")
)
olddict.replace_int_array(
"excavated", 5, old.child_value("excavated")
)
olddict.replace_int_array("excavated_point", 5, old.child_value("excavated_point"))
olddict.replace_int_array("excavated", 5, old.child_value("excavated"))
olddict.replace_int_array("param", 5, old.child_value("param"))
digdigdict.replace_dict("old", olddict)
@ -1599,9 +1456,7 @@ class JubeatQubell(
if flags & bit > 0:
medal = max(medal, mapping[bit])
self.update_score(
userid, timestamp, songid, chart, points, medal, combo, ghost, stats
)
self.update_score(userid, timestamp, songid, chart, points, medal, combo, ghost, stats)
# Born stuff
born = player.child("born")

View File

@ -34,22 +34,15 @@ class JubeatSaucer(
return JubeatCopiousAppend(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert daily FC challenges into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "fc_challenge", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "fc_challenge", "daily"):
# Generate a new list of two FC challenge songs.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = set(
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
)
all_songs = set(song.id for song in data.local.music.get_all_songs(cls.game, cls.version))
if all_songs:
today_song = random.sample(all_songs, 1)[0]
data.local.game.put_time_sensitive_settings(
@ -73,9 +66,7 @@ class JubeatSaucer(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "fc_challenge", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "fc_challenge", "daily")
return events
@classmethod
@ -215,9 +206,7 @@ class JubeatSaucer(
force_unlock = game_config.get_bool("force_song_unlock")
# Allow figuring out owned songs.
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
owned_songs: Set[int] = set()
owned_secrets: Set[int] = set()
for achievement in achievements:
@ -242,9 +231,7 @@ class JubeatSaucer(
info.add_child(Node.s32("beat_cnt", profile.get_int("beat_cnt")))
info.add_child(Node.s32("mynews_cnt", profile.get_int("mynews_cnt")))
if "total_best_score" in profile:
info.add_child(
Node.s32("total_best_score", profile.get_int("total_best_score"))
)
info.add_child(Node.s32("total_best_score", profile.get_int("total_best_score")))
# Looks to be set to true when there's an old profile, stops tutorial from
# happening on first load.
@ -266,9 +253,7 @@ class JubeatSaucer(
item.add_child(
Node.s32_array(
"secret_list",
([-1] * 32)
if force_unlock
else self.create_owned_items(owned_songs, 32),
([-1] * 32) if force_unlock else self.create_owned_items(owned_songs, 32),
)
)
item.add_child(
@ -282,25 +267,15 @@ class JubeatSaucer(
)
)
item.add_child(Node.s16("theme_list", profile.get_int("theme_list", -1)))
item.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list", 2, [-1] * 2)
)
)
item.add_child(
Node.s32_array(
"parts_list", profile.get_int_array("parts_list", 96, [-1] * 96)
)
)
item.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list", 2, [-1] * 2)))
item.add_child(Node.s32_array("parts_list", profile.get_int_array("parts_list", 96, [-1] * 96)))
new = Node.void("new")
item.add_child(new)
new.add_child(
Node.s32_array(
"secret_list",
([-1] * 32)
if force_unlock
else self.create_owned_items(owned_secrets, 32),
([-1] * 32) if force_unlock else self.create_owned_items(owned_secrets, 32),
)
)
new.add_child(
@ -314,11 +289,7 @@ class JubeatSaucer(
)
)
new.add_child(Node.s16("theme_list", profile.get_int("theme_list_new", -1)))
new.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list_new", 2, [-1] * 2)
)
)
new.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list_new", 2, [-1] * 2)))
# Last played data, for showing cursor and such
lastdict = profile.get_dict("last")
@ -393,9 +364,7 @@ class JubeatSaucer(
collabo.add_child(Node.bool("completed", False))
# Daily FC challenge.
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -510,9 +479,7 @@ class JubeatSaucer(
music.add_child(Node.s32("price_s32", routedata["price"]))
# Look up any updated satisfaction stored by the game
routesaved = self.data.local.user.get_achievement(
self.game, self.version, userid, route_no + 1, "route"
)
routesaved = self.data.local.user.get_achievement(self.game, self.version, userid, route_no + 1, "route")
if routesaved is None:
routesaved = ValidatedDict()
satisfaction = routesaved.get_int("satisfaction", routedata["satisfaction"])
@ -697,9 +664,7 @@ class JubeatSaucer(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_bool("saved", True)
data = request.child("data")
@ -727,44 +692,28 @@ class JubeatSaucer(
newprofile.replace_int("save_cnt", info.child_value("save_cnt"))
newprofile.replace_int("saved_cnt", info.child_value("saved_cnt"))
newprofile.replace_int("fc_cnt", info.child_value("fc_cnt"))
newprofile.replace_int(
"ex_cnt", info.child_value("exc_cnt")
) # Not a mistake, Jubeat is weird
newprofile.replace_int("ex_cnt", info.child_value("exc_cnt")) # Not a mistake, Jubeat is weird
newprofile.replace_int("pf_cnt", info.child_value("pf_cnt"))
newprofile.replace_int("clear_cnt", info.child_value("clear_cnt"))
newprofile.replace_int("match_cnt", info.child_value("match_cnt"))
newprofile.replace_int("beat_cnt", info.child_value("beat_cnt"))
newprofile.replace_int(
"total_best_score", info.child_value("total_best_score")
)
newprofile.replace_int("total_best_score", info.child_value("total_best_score"))
newprofile.replace_int("mynews_cnt", info.child_value("mynews_cnt"))
# Grab unlock progress
item = player.child("item")
if item is not None:
newprofile.replace_int_array(
"title_list", 96, item.child_value("title_list")
)
newprofile.replace_int_array("title_list", 96, item.child_value("title_list"))
newprofile.replace_int("theme_list", item.child_value("theme_list"))
newprofile.replace_int_array(
"marker_list", 2, item.child_value("marker_list")
)
newprofile.replace_int_array(
"parts_list", 96, item.child_value("parts_list")
)
newprofile.replace_int_array(
"title_list_new", 96, item.child_value("title_new")
)
newprofile.replace_int_array("marker_list", 2, item.child_value("marker_list"))
newprofile.replace_int_array("parts_list", 96, item.child_value("parts_list"))
newprofile.replace_int_array("title_list_new", 96, item.child_value("title_new"))
newprofile.replace_int("theme_list_new", item.child_value("theme_new"))
newprofile.replace_int_array(
"marker_list_new", 2, item.child_value("marker_new")
)
newprofile.replace_int_array("marker_list_new", 2, item.child_value("marker_new"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_songs = self.calculate_owned_items(
item.child_value("secret_list")
)
owned_songs = self.calculate_owned_items(item.child_value("secret_list"))
for index in owned_songs:
self.data.local.user.put_achievement(
self.game,
@ -775,9 +724,7 @@ class JubeatSaucer(
{},
)
owned_secrets = self.calculate_owned_items(
item.child_value("secret_new")
)
owned_secrets = self.calculate_owned_items(item.child_value("secret_new"))
for index in owned_secrets:
self.data.local.user.put_achievement(
self.game,
@ -791,9 +738,7 @@ class JubeatSaucer(
# Grab bistro progress
bistro = player.child("bistro")
if bistro is not None:
newprofile.replace_int(
"bistro_carry_over", bistro.child_value("carry_over")
)
newprofile.replace_int("bistro_carry_over", bistro.child_value("carry_over"))
chefdata = newprofile.get_dict("chef")
chef = bistro.child("chef")
@ -877,9 +822,7 @@ class JubeatSaucer(
if flags & bit > 0:
medal = max(medal, mapping[bit])
self.update_score(
userid, timestamp, songid, chart, points, medal, combo, ghost
)
self.update_score(userid, timestamp, songid, chart, points, medal, combo, ghost)
# Save back last information gleaned from results
newprofile.replace_dict("last", last)
@ -889,9 +832,7 @@ class JubeatSaucer(
return newprofile
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void("gametop")
datanode = Node.void("data")
root.add_child(datanode)
@ -958,24 +899,12 @@ class JubeatSaucer(
playdata.add_child(musicdata)
musicdata.set_attribute("music_id", scoreid)
musicdata.add_child(
Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3))
)
musicdata.add_child(
Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3))
)
musicdata.add_child(
Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3))
)
musicdata.add_child(
Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3))
)
musicdata.add_child(
Node.s32_array("score", scoredata.get_int_array("points", 3))
)
musicdata.add_child(
Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3))
)
musicdata.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3)))
musicdata.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3)))
musicdata.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3)))
musicdata.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3)))
musicdata.add_child(Node.s32_array("score", scoredata.get_int_array("points", 3)))
musicdata.add_child(Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3)))
ghosts = scoredata.get("ghost", [None, None, None])
for i in range(len(ghosts)):

View File

@ -46,22 +46,15 @@ class JubeatSaucerFulfill(
return JubeatSaucer(self.data, self.config, self.model)
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Insert daily FC challenges into the DB.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "fc_challenge", "daily"
):
if data.local.network.should_schedule(cls.game, cls.version, "fc_challenge", "daily"):
# Generate a new list of two FC challenge songs.
start_time, end_time = data.local.network.get_schedule_duration("daily")
all_songs = set(
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
)
all_songs = set(song.id for song in data.local.music.get_all_songs(cls.game, cls.version))
if len(all_songs) >= 2:
daily_songs = random.sample(all_songs, 2)
data.local.game.put_time_sensitive_settings(
@ -87,9 +80,7 @@ class JubeatSaucerFulfill(
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "fc_challenge", "daily"
)
data.local.network.mark_scheduled(cls.game, cls.version, "fc_challenge", "daily")
return events
@classmethod
@ -289,9 +280,7 @@ class JubeatSaucerFulfill(
result.add_child(Node.s32_array("score", scores))
# Last course ID
last_course_id = Node.s32(
"last_course_id", profile.get_dict("last").get_int("last_course_id", -1)
)
last_course_id = Node.s32("last_course_id", profile.get_dict("last").get_int("last_course_id", -1))
data.add_child(last_course_id)
return gametop
@ -350,9 +339,7 @@ class JubeatSaucerFulfill(
force_unlock = game_config.get_bool("force_song_unlock")
# Allow figuring out owned songs.
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
owned_songs: Set[int] = set()
owned_secrets: Set[int] = set()
for achievement in achievements:
@ -377,13 +364,9 @@ class JubeatSaucerFulfill(
info.add_child(Node.s32("beat_cnt", profile.get_int("beat_cnt")))
info.add_child(Node.s32("mynews_cnt", profile.get_int("mynews_cnt")))
info.add_child(Node.s32("extra_point", profile.get_int("extra_point")))
info.add_child(
Node.bool("is_extra_played", profile.get_bool("is_extra_played"))
)
info.add_child(Node.bool("is_extra_played", profile.get_bool("is_extra_played")))
if "total_best_score" in profile:
info.add_child(
Node.s32("total_best_score", profile.get_int("total_best_score"))
)
info.add_child(Node.s32("total_best_score", profile.get_int("total_best_score")))
# Looks to be set to true when there's an old profile, stops tutorial from
# happening on first load.
@ -412,9 +395,7 @@ class JubeatSaucerFulfill(
item.add_child(
Node.s32_array(
"secret_list",
([-1] * 32)
if force_unlock
else self.create_owned_items(owned_songs, 32),
([-1] * 32) if force_unlock else self.create_owned_items(owned_songs, 32),
)
)
item.add_child(
@ -428,25 +409,15 @@ class JubeatSaucerFulfill(
)
)
item.add_child(Node.s16("theme_list", profile.get_int("theme_list", -1)))
item.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list", 2, [-1] * 2)
)
)
item.add_child(
Node.s32_array(
"parts_list", profile.get_int_array("parts_list", 96, [-1] * 96)
)
)
item.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list", 2, [-1] * 2)))
item.add_child(Node.s32_array("parts_list", profile.get_int_array("parts_list", 96, [-1] * 96)))
new = Node.void("new")
item.add_child(new)
new.add_child(
Node.s32_array(
"secret_list",
([-1] * 32)
if force_unlock
else self.create_owned_items(owned_secrets, 32),
([-1] * 32) if force_unlock else self.create_owned_items(owned_secrets, 32),
)
)
new.add_child(
@ -460,11 +431,7 @@ class JubeatSaucerFulfill(
)
)
new.add_child(Node.s16("theme_list", profile.get_int("theme_list_new", -1)))
new.add_child(
Node.s32_array(
"marker_list", profile.get_int_array("marker_list_new", 2, [-1] * 2)
)
)
new.add_child(Node.s32_array("marker_list", profile.get_int_array("marker_list_new", 2, [-1] * 2)))
# Last played data, for showing cursor and such
lastdict = profile.get_dict("last")
@ -498,37 +465,23 @@ class JubeatSaucerFulfill(
player.add_child(macchiato)
macchiato.add_child(Node.s32("pack_id", macchiatodict.get_int("pack_id")))
macchiato.add_child(Node.u16("bean_num", macchiatodict.get_int("bean_num")))
macchiato.add_child(
Node.s32("daily_milk_num", macchiatodict.get_int("daily_milk_num"))
)
macchiato.add_child(Node.s32("daily_milk_num", macchiatodict.get_int("daily_milk_num")))
macchiato.add_child(
Node.bool(
"is_received_daily_milk",
macchiatodict.get_bool("is_received_daily_milk"),
)
)
macchiato.add_child(
Node.s32("today_tune_cnt", macchiatodict.get_int("today_tune_cnt"))
)
macchiato.add_child(Node.s32("today_tune_cnt", macchiatodict.get_int("today_tune_cnt")))
macchiato.add_child(
Node.s32_array(
"daily_milk_bonus",
macchiatodict.get_int_array(
"daily_milk_bonus", 9, [-1, -1, -1, -1, -1, -1, -1, -1, -1]
),
macchiatodict.get_int_array("daily_milk_bonus", 9, [-1, -1, -1, -1, -1, -1, -1, -1, -1]),
)
)
macchiato.add_child(
Node.s32("daily_play_burst", macchiatodict.get_int("daily_play_burst"))
)
macchiato.add_child(
Node.bool(
"sub_menu_is_completed", macchiatodict.get_bool("sub_menu_is_completed")
)
)
macchiato.add_child(
Node.s32("compensation_milk", macchiatodict.get_int("compensation_milk"))
)
macchiato.add_child(Node.s32("daily_play_burst", macchiatodict.get_int("daily_play_burst")))
macchiato.add_child(Node.bool("sub_menu_is_completed", macchiatodict.get_bool("sub_menu_is_completed")))
macchiato.add_child(Node.s32("compensation_milk", macchiatodict.get_int("compensation_milk")))
macchiato.add_child(Node.s32("match_cnt", macchiatodict.get_int("match_cnt")))
# Probably never will support this
@ -593,9 +546,7 @@ class JubeatSaucerFulfill(
rivallist.set_attribute("count", str(rivalcount))
# Full combo daily challenge.
entry = self.data.local.game.get_time_sensitive_settings(
self.game, self.version, "fc_challenge"
)
entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, "fc_challenge")
if entry is None:
entry = ValidatedDict()
@ -779,9 +730,7 @@ class JubeatSaucerFulfill(
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_bool("saved", True)
data = request.child("data")
@ -809,21 +758,15 @@ class JubeatSaucerFulfill(
newprofile.replace_int("save_cnt", info.child_value("save_cnt"))
newprofile.replace_int("saved_cnt", info.child_value("saved_cnt"))
newprofile.replace_int("fc_cnt", info.child_value("fc_cnt"))
newprofile.replace_int(
"ex_cnt", info.child_value("exc_cnt")
) # Not a mistake, Jubeat is weird
newprofile.replace_int("ex_cnt", info.child_value("exc_cnt")) # Not a mistake, Jubeat is weird
newprofile.replace_int("pf_cnt", info.child_value("pf_cnt"))
newprofile.replace_int("clear_cnt", info.child_value("clear_cnt"))
newprofile.replace_int("match_cnt", info.child_value("match_cnt"))
newprofile.replace_int("beat_cnt", info.child_value("beat_cnt"))
newprofile.replace_int(
"total_best_score", info.child_value("total_best_score")
)
newprofile.replace_int("total_best_score", info.child_value("total_best_score"))
newprofile.replace_int("mynews_cnt", info.child_value("mynews_cnt"))
newprofile.replace_int("extra_point", info.child_value("extra_point"))
newprofile.replace_bool(
"is_extra_played", info.child_value("is_extra_played")
)
newprofile.replace_bool("is_extra_played", info.child_value("is_extra_played"))
last.replace_int("expert_option", info.child_value("expert_option"))
last.replace_int("matching", info.child_value("matching"))
@ -833,29 +776,17 @@ class JubeatSaucerFulfill(
# Grab unlock progress
item = player.child("item")
if item is not None:
newprofile.replace_int_array(
"title_list", 96, item.child_value("title_list")
)
newprofile.replace_int_array("title_list", 96, item.child_value("title_list"))
newprofile.replace_int("theme_list", item.child_value("theme_list"))
newprofile.replace_int_array(
"marker_list", 2, item.child_value("marker_list")
)
newprofile.replace_int_array(
"parts_list", 96, item.child_value("parts_list")
)
newprofile.replace_int_array(
"title_list_new", 96, item.child_value("title_new")
)
newprofile.replace_int_array("marker_list", 2, item.child_value("marker_list"))
newprofile.replace_int_array("parts_list", 96, item.child_value("parts_list"))
newprofile.replace_int_array("title_list_new", 96, item.child_value("title_new"))
newprofile.replace_int("theme_list_new", item.child_value("theme_new"))
newprofile.replace_int_array(
"marker_list_new", 2, item.child_value("marker_new")
)
newprofile.replace_int_array("marker_list_new", 2, item.child_value("marker_new"))
if not force_unlock:
# Don't persist if we're force-unlocked, this data will be bogus.
owned_songs = self.calculate_owned_items(
item.child_value("secret_list")
)
owned_songs = self.calculate_owned_items(item.child_value("secret_list"))
for index in owned_songs:
self.data.local.user.put_achievement(
self.game,
@ -866,9 +797,7 @@ class JubeatSaucerFulfill(
{},
)
owned_secrets = self.calculate_owned_items(
item.child_value("secret_new")
)
owned_secrets = self.calculate_owned_items(item.child_value("secret_new"))
for index in owned_secrets:
self.data.local.user.put_achievement(
self.game,
@ -885,31 +814,19 @@ class JubeatSaucerFulfill(
if macchiato is not None:
macchiatodict.replace_int("pack_id", macchiato.child_value("pack_id"))
macchiatodict.replace_int("bean_num", macchiato.child_value("bean_num"))
macchiatodict.replace_int(
"daily_milk_num", macchiato.child_value("daily_milk_num")
)
macchiatodict.replace_int("daily_milk_num", macchiato.child_value("daily_milk_num"))
macchiatodict.replace_bool(
"is_received_daily_milk",
macchiato.child_value("is_received_daily_milk"),
)
macchiatodict.replace_bool(
"sub_menu_is_completed", macchiato.child_value("sub_menu_is_completed")
)
macchiatodict.replace_int(
"today_tune_cnt", macchiato.child_value("today_tune_cnt")
)
macchiatodict.replace_int_array(
"daily_milk_bonus", 9, macchiato.child_value("daily_milk_bonus")
)
macchiatodict.replace_int(
"compensation_milk", macchiato.child_value("compensation_milk")
)
macchiatodict.replace_bool("sub_menu_is_completed", macchiato.child_value("sub_menu_is_completed"))
macchiatodict.replace_int("today_tune_cnt", macchiato.child_value("today_tune_cnt"))
macchiatodict.replace_int_array("daily_milk_bonus", 9, macchiato.child_value("daily_milk_bonus"))
macchiatodict.replace_int("compensation_milk", macchiato.child_value("compensation_milk"))
macchiatodict.replace_int("match_cnt", macchiato.child_value("match_cnt"))
macchiatodict.replace_int("used_bean", macchiato.child_value("used_bean"))
macchiatodict.replace_int("used_milk", macchiato.child_value("used_milk"))
macchiatodict.replace_int(
"daily_play_burst", macchiato.child_value("daily_play_burst")
)
macchiatodict.replace_int("daily_play_burst", macchiato.child_value("daily_play_burst"))
newprofile.replace_dict("macchiato", macchiatodict)
# Get timestamps for played songs
@ -967,9 +884,7 @@ class JubeatSaucerFulfill(
if flags & bit > 0:
medal = max(medal, mapping[bit])
self.update_score(
userid, timestamp, songid, chart, points, medal, combo, ghost
)
self.update_score(userid, timestamp, songid, chart, points, medal, combo, ghost)
# Grab the course results as well
course = data.child("course")
@ -1002,9 +917,7 @@ class JubeatSaucerFulfill(
return newprofile
def format_scores(
self, userid: UserID, profile: Profile, scores: List[Score]
) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void("gametop")
datanode = Node.void("data")
root.add_child(datanode)
@ -1071,24 +984,12 @@ class JubeatSaucerFulfill(
playdata.add_child(musicdata)
musicdata.set_attribute("music_id", scoreid)
musicdata.add_child(
Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3))
)
musicdata.add_child(
Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3))
)
musicdata.add_child(
Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3))
)
musicdata.add_child(
Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3))
)
musicdata.add_child(
Node.s32_array("score", scoredata.get_int_array("points", 3))
)
musicdata.add_child(
Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3))
)
musicdata.add_child(Node.s32_array("play_cnt", scoredata.get_int_array("play_cnt", 3)))
musicdata.add_child(Node.s32_array("clear_cnt", scoredata.get_int_array("clear_cnt", 3)))
musicdata.add_child(Node.s32_array("fc_cnt", scoredata.get_int_array("fc_cnt", 3)))
musicdata.add_child(Node.s32_array("ex_cnt", scoredata.get_int_array("ex_cnt", 3)))
musicdata.add_child(Node.s32_array("score", scoredata.get_int_array("points", 3)))
musicdata.add_child(Node.s8_array("clear", scoredata.get_int_array("clear_flags", 3)))
ghosts = scoredata.get("ghost", [None, None, None])
for i in range(len(ghosts)):

View File

@ -52,7 +52,9 @@ class MetalGearArcade(
if reqtype == "S_SRVMSG" and reqkey == "INFO":
# Generate system message
settings1_str = "2011081000:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1"
settings1_str = (
"2011081000:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1"
)
settings2_str = "1,1,1,1,1,1,1,1,1,1,1,1,1,1"
# Send it to the client, making sure to inform the client that it was valid.
@ -82,9 +84,7 @@ class MetalGearArcade(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is None:
root = Node.void("playerdata")
root.add_child(
Node.s32("result", 1)
) # Unclear if this is the right thing to do here.
root.add_child(Node.s32("result", 1)) # Unclear if this is the right thing to do here.
return root
# Extract new profile info from old profile
@ -117,9 +117,7 @@ class MetalGearArcade(
return self.format_profile(userid, profiletypes, profile)
else:
root = Node.void("playerdata")
root.add_child(
Node.s32("result", 1)
) # Unclear if this is the right thing to do here.
root.add_child(Node.s32("result", 1)) # Unclear if this is the right thing to do here.
return root
def handle_playerdata_usergamedata_scorerank_request(self, request: Node) -> Node:
@ -151,9 +149,7 @@ class MetalGearArcade(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is None:
root = Node.void("matching")
root.add_child(
Node.s32("result", -1)
) # Set to error so matching doesn't happen.
root.add_child(Node.s32("result", -1)) # Set to error so matching doesn't happen.
return root
# Game sends how long it intends to wait, so we should use that.
@ -162,21 +158,13 @@ class MetalGearArcade(
# Look up active lobbies, see if there was a previous one for us.
# Matchmaking takes at most 60 seconds, so assume any lobbies older
# than this are dead.
lobbies = self.data.local.lobby.get_all_lobbies(
self.game, self.version, max_age=wait_time
)
lobbies = self.data.local.lobby.get_all_lobbies(self.game, self.version, max_age=wait_time)
previous_hosted_lobbies = [True for uid, _ in lobbies if uid == userid]
previous_joined_lobbies = [
(uid, lobby) for uid, lobby in lobbies if userid in lobby["participants"]
]
previous_joined_lobbies = [(uid, lobby) for uid, lobby in lobbies if userid in lobby["participants"]]
# See if there's a random lobby we can be slotted into. Don't choose potentially
# our old one, since it will be overwritten by a new entry, if we were ever a host.
nonfull_lobbies = [
(uid, lobby)
for uid, lobby in lobbies
if len(lobby["participants"]) < lobby["lobbysize"]
]
nonfull_lobbies = [(uid, lobby) for uid, lobby in lobbies if len(lobby["participants"]) < lobby["lobbysize"]]
# Make sure to put our session information somewhere that we can find again.
self.data.local.lobby.put_play_session_info(
@ -225,18 +213,10 @@ class MetalGearArcade(
Node.s32("result", 1)
) # Setting this to 1 makes the client consider itself a guest and join a host.
root.add_child(Node.s64("hostid", lobby.get_int("id")))
root.add_child(
Node.string("hostip_g", host_play_session_info.get_str("joinip"))
)
root.add_child(
Node.s32("hostport_g", host_play_session_info.get_int("joinport"))
)
root.add_child(
Node.string("hostip_l", host_play_session_info.get_str("localip"))
)
root.add_child(
Node.s32("hostport_l", host_play_session_info.get_int("localport"))
)
root.add_child(Node.string("hostip_g", host_play_session_info.get_str("joinip")))
root.add_child(Node.s32("hostport_g", host_play_session_info.get_int("joinport")))
root.add_child(Node.string("hostip_l", host_play_session_info.get_str("localip")))
root.add_child(Node.s32("hostport_l", host_play_session_info.get_int("localport")))
return root
# The game does weird things if you let it wait as long as its own countdown,
@ -281,16 +261,11 @@ class MetalGearArcade(
# List all lobbies out, find the one that we're either a host or a guest of.
lobbies = self.data.local.lobby.get_all_lobbies(self.game, self.version)
info_by_uid = {
uid: data
for uid, data in self.data.local.lobby.get_all_play_session_infos(
self.game, self.version
)
uid: data for uid, data in self.data.local.lobby.get_all_play_session_infos(self.game, self.version)
}
# We should be able to filter by host_id that the game gave us.
joined_lobby = [
(uid, lobby) for uid, lobby in lobbies if lobby.get_int("id") == host_id
]
joined_lobby = [(uid, lobby) for uid, lobby in lobbies if lobby.get_int("id") == host_id]
if len(joined_lobby) != 1:
# This shouldn't happen.
root = Node.void("matching")
@ -299,14 +274,10 @@ class MetalGearArcade(
# Calculate creation time, figure out when to join the match after that.
host_uid, lobby = joined_lobby[0]
time_left = max(
lobby.get_int("waittime") - (Time.now() - lobby.get_int("createtime")), 0
)
time_left = max(lobby.get_int("waittime") - (Time.now() - lobby.get_int("createtime")), 0)
root = Node.void("matching")
root.add_child(
Node.s32("result", 0 if time_left > 0 else 1)
) # We send 1 to start the match.
root.add_child(Node.s32("result", 0 if time_left > 0 else 1)) # We send 1 to start the match.
root.add_child(Node.s32("prwtime", time_left))
matchlist = Node.void("matchlist")
root.add_child(matchlist)
@ -339,9 +310,7 @@ class MetalGearArcade(
return root
def format_profile(
self, userid: UserID, profiletypes: List[str], profile: Profile
) -> Node:
def format_profile(self, userid: UserID, profiletypes: List[str], profile: Profile) -> Node:
root = Node.void("playerdata")
root.add_child(Node.s32("result", 0))
player = Node.void("player")
@ -371,9 +340,7 @@ class MetalGearArcade(
strdata = b",".join(csvs[2:])
d = Node.string("d", base64.b64encode(strdata).decode("ascii"))
record.add_child(d)
d.add_child(
Node.string("bin1", base64.b64encode(bindata).decode("ascii"))
)
d.add_child(Node.string("bin1", base64.b64encode(bindata).decode("ascii")))
# Remember that we had this record
records = records + 1
@ -381,9 +348,7 @@ class MetalGearArcade(
player.add_child(Node.u32("record_num", records))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile, is_new: bool
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile, is_new: bool) -> Profile:
# Profile save request, data values are base64 encoded.
# d is a CSV, and bin1 is binary data.
newprofile = oldprofile.clone()

View File

@ -95,9 +95,7 @@ class MusecaBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Now, return it
return self.format_profile(userid, profile)
def new_profile_by_refid(
self, refid: Optional[str], name: Optional[str], locid: Optional[int]
) -> Node:
def new_profile_by_refid(self, refid: Optional[str], name: Optional[str], locid: Optional[int]) -> Node:
"""
Given a RefID and an optional name, create a profile and then return
a formatted profile node. Similar rationale to get_profile_by_refid.
@ -130,9 +128,7 @@ class MusecaBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("game")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -177,21 +173,14 @@ class MusecaBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
}
# We saw an attempt, keep the total attempts in sync.
attempts[attempt.id][attempt.chart]["total"] = (
attempts[attempt.id][attempt.chart]["total"] + 1
)
attempts[attempt.id][attempt.chart]["total"] = attempts[attempt.id][attempt.chart]["total"] + 1
if (
attempt.data.get_int("clear_type", self.CLEAR_TYPE_FAILED)
!= self.CLEAR_TYPE_FAILED
):
if attempt.data.get_int("clear_type", self.CLEAR_TYPE_FAILED) != self.CLEAR_TYPE_FAILED:
# This attempt was a failure, so don't count it against clears of full combos
continue
# It was at least a clear
attempts[attempt.id][attempt.chart]["clears"] = (
attempts[attempt.id][attempt.chart]["clears"] + 1
)
attempts[attempt.id][attempt.chart]["clears"] = attempts[attempt.id][attempt.chart]["clears"] + 1
# Merge in remote attempts
for songid in remote_attempts:
@ -205,12 +194,8 @@ class MusecaBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"clears": 0,
}
attempts[songid][songchart]["total"] += remote_attempts[songid][
songchart
]["plays"]
attempts[songid][songchart]["clears"] += remote_attempts[songid][
songchart
]["clears"]
attempts[songid][songchart]["total"] += remote_attempts[songid][songchart]["plays"]
attempts[songid][songchart]["clears"] += remote_attempts[songid][songchart]["clears"]
return attempts
@ -280,9 +265,7 @@ class MusecaBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
scoredata = oldscore.data
# Replace grade and clear type
scoredata.replace_int(
"clear_type", max(scoredata.get_int("clear_type"), clear_type)
)
scoredata.replace_int("clear_type", max(scoredata.get_int("clear_type"), clear_type))
history.replace_int("clear_type", clear_type)
scoredata.replace_int("grade", max(scoredata.get_int("grade"), grade))
history.replace_int("grade", grade)

View File

@ -34,9 +34,7 @@ class MusecaGameHiscoreHandler(MusecaBase):
# Now, grab user records
records = self.data.remote.music.get_all_records(self.game, self.version)
users = {
uid: prof for (uid, prof) in self.get_any_profiles([r[0] for r in records])
}
users = {uid: prof for (uid, prof) in self.get_any_profiles([r[0] for r in records])}
hiscore_allover = Node.void("hiscore_allover")
game.add_child(hiscore_allover)
@ -61,14 +59,10 @@ class MusecaGameHiscoreHandler(MusecaBase):
# Now, grab local records
area_users = [
uid
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)
if prof.get_int("loc", -1) == locid
]
records = self.data.local.music.get_all_records(
self.game, self.version, userlist=area_users
)
records = self.data.local.music.get_all_records(self.game, self.version, userlist=area_users)
missing_players = [uid for (uid, _) in records if uid not in users]
for uid, prof in self.get_any_profiles(missing_players):
users[uid] = prof
@ -101,9 +95,7 @@ class MusecaGameHiscoreHandler(MusecaBase):
for songid in clears:
for chart in clears[songid]:
if clears[songid][chart]["total"] > 0:
rate = float(clears[songid][chart]["clears"]) / float(
clears[songid][chart]["total"]
)
rate = float(clears[songid][chart]["clears"]) / float(clears[songid][chart]["total"])
dnode = Node.void("d")
clear_rate.add_child(dnode)
dnode.add_child(Node.u32("id", songid))

View File

@ -177,9 +177,7 @@ class Museca1(
userid = None
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
scores = []
@ -201,11 +199,7 @@ class Museca1(
self.db_to_game_clear_type(score.data.get_int("clear_type")),
)
)
music.add_child(
Node.u32(
"score_grade", self.db_to_game_grade(score.data.get_int("grade"))
)
)
music.add_child(Node.u32("score_grade", self.db_to_game_grade(score.data.get_int("grade"))))
stats = score.data.get_dict("stats")
music.add_child(Node.u32("btn_rate", stats.get_int("btn_rate")))
music.add_child(Node.u32("long_rate", stats.get_int("long_rate")))
@ -222,9 +216,7 @@ class Museca1(
game.add_child(Node.u32("gamecoin_packet", profile.get_int("packet")))
game.add_child(Node.u32("gamecoin_block", profile.get_int("block")))
game.add_child(Node.s16("skill_name_id", profile.get_int("skill_name_id", -1)))
game.add_child(
Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20))
)
game.add_child(Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20)))
game.add_child(Node.u32("blaster_energy", profile.get_int("blaster_energy")))
game.add_child(Node.u32("blaster_count", profile.get_int("blaster_count")))
@ -253,19 +245,14 @@ class Museca1(
game.add_child(itemnode)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for item in achievements:
if item.type[:5] != "item_":
continue
itemtype = int(item.type[5:])
if (
game_config.get_bool("force_unlock_songs")
and itemtype == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and itemtype == self.GAME_CATALOG_TYPE_SONG:
# Don't echo unlocked songs, we will add all of them later
continue
@ -299,22 +286,16 @@ class Museca1(
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update blaster energy and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
earned_blaster_energy = request.child_value("earned_blaster_energy")
if earned_blaster_energy is not None:
newprofile.replace_int(
@ -325,9 +306,7 @@ class Museca1(
# Miscelaneous stuff
newprofile.replace_int("blaster_count", request.child_value("blaster_count"))
newprofile.replace_int("skill_name_id", request.child_value("skill_name_id"))
newprofile.replace_int_array(
"hidden_param", 20, request.child_value("hidden_param")
)
newprofile.replace_int_array("hidden_param", 20, request.child_value("hidden_param"))
# Update user's unlock status if we aren't force unlocked
game_config = self.get_game_config()
@ -342,10 +321,7 @@ class Museca1(
param = child.child_value("param")
diff_param = child.child_value("diff_param")
if (
game_config.get_bool("force_unlock_songs")
and item_type == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and item_type == self.GAME_CATALOG_TYPE_SONG:
# Don't save back songs, because they were force unlocked
continue

View File

@ -309,9 +309,7 @@ class Museca1Plus(
userid = None
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
scores = []
@ -334,11 +332,7 @@ class Museca1Plus(
self.db_to_game_clear_type(score.data.get_int("clear_type")),
)
)
music.add_child(
Node.u32(
"score_grade", self.db_to_game_grade(score.data.get_int("grade"))
)
)
music.add_child(Node.u32("score_grade", self.db_to_game_grade(score.data.get_int("grade"))))
stats = score.data.get_dict("stats")
music.add_child(Node.u32("btn_rate", stats.get_int("btn_rate")))
music.add_child(Node.u32("long_rate", stats.get_int("long_rate")))
@ -355,9 +349,7 @@ class Museca1Plus(
game.add_child(Node.u32("gamecoin_packet", profile.get_int("packet")))
game.add_child(Node.u32("gamecoin_block", profile.get_int("block")))
game.add_child(Node.s16("skill_name_id", profile.get_int("skill_name_id", -1)))
game.add_child(
Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20))
)
game.add_child(Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20)))
game.add_child(Node.u32("blaster_energy", profile.get_int("blaster_energy")))
game.add_child(Node.u32("blaster_count", profile.get_int("blaster_count")))
@ -391,19 +383,14 @@ class Museca1Plus(
game.add_child(itemnode)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for item in achievements:
if item.type[:5] != "item_":
continue
itemtype = int(item.type[5:])
if (
game_config.get_bool("force_unlock_songs")
and itemtype == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and itemtype == self.GAME_CATALOG_TYPE_SONG:
# Don't echo unlocked songs, we will add all of them later
continue
@ -437,22 +424,16 @@ class Museca1Plus(
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update blaster energy and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
earned_blaster_energy = request.child_value("earned_blaster_energy")
if earned_blaster_energy is not None:
newprofile.replace_int(
@ -463,9 +444,7 @@ class Museca1Plus(
# Miscelaneous stuff
newprofile.replace_int("blaster_count", request.child_value("blaster_count"))
newprofile.replace_int("skill_name_id", request.child_value("skill_name_id"))
newprofile.replace_int_array(
"hidden_param", 20, request.child_value("hidden_param")
)
newprofile.replace_int_array("hidden_param", 20, request.child_value("hidden_param"))
# Update user's unlock status if we aren't force unlocked
game_config = self.get_game_config()
@ -480,10 +459,7 @@ class Museca1Plus(
param = child.child_value("param")
diff_param = child.child_value("diff_param")
if (
game_config.get_bool("force_unlock_songs")
and item_type == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and item_type == self.GAME_CATALOG_TYPE_SONG:
# Don't save back songs, because they were force unlocked
continue

View File

@ -28,30 +28,16 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Play medals, as saved into/loaded from the DB
PLAY_MEDAL_NO_PLAY: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_NO_PLAY
PLAY_MEDAL_CIRCLE_FAILED: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_FAILED
PLAY_MEDAL_DIAMOND_FAILED: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_DIAMOND_FAILED
PLAY_MEDAL_CIRCLE_FAILED: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_FAILED
PLAY_MEDAL_DIAMOND_FAILED: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_DIAMOND_FAILED
PLAY_MEDAL_STAR_FAILED: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_STAR_FAILED
PLAY_MEDAL_EASY_CLEAR: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_EASY_CLEAR
PLAY_MEDAL_CIRCLE_CLEARED: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_CLEARED
PLAY_MEDAL_DIAMOND_CLEARED: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_DIAMOND_CLEARED
PLAY_MEDAL_CIRCLE_CLEARED: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_CLEARED
PLAY_MEDAL_DIAMOND_CLEARED: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_DIAMOND_CLEARED
PLAY_MEDAL_STAR_CLEARED: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_STAR_CLEARED
PLAY_MEDAL_CIRCLE_FULL_COMBO: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_FULL_COMBO
PLAY_MEDAL_DIAMOND_FULL_COMBO: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_DIAMOND_FULL_COMBO
PLAY_MEDAL_STAR_FULL_COMBO: Final[
int
] = DBConstants.POPN_MUSIC_PLAY_MEDAL_STAR_FULL_COMBO
PLAY_MEDAL_CIRCLE_FULL_COMBO: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_CIRCLE_FULL_COMBO
PLAY_MEDAL_DIAMOND_FULL_COMBO: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_DIAMOND_FULL_COMBO
PLAY_MEDAL_STAR_FULL_COMBO: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_STAR_FULL_COMBO
PLAY_MEDAL_PERFECT: Final[int] = DBConstants.POPN_MUSIC_PLAY_MEDAL_PERFECT
# Chart type, as saved into/loaded from the DB, and returned to game
@ -107,9 +93,7 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("playerdata")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -117,9 +101,7 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return oldprofile
def get_profile_by_refid(
self, refid: Optional[str], load_mode: int
) -> Optional[Node]:
def get_profile_by_refid(self, refid: Optional[str], load_mode: int) -> Optional[Node]:
"""
Given a RefID, return a formatted profile node. Basically every game
needs a profile lookup, even if it handles where that happens in
@ -341,9 +323,7 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
) -> None:
# Generate scorecard
profile = self.get_profile(userid)
song = self.data.local.music.get_song(
self.game, self.music_version, songid, chart
)
song = self.data.local.music.get_song(self.game, self.music_version, songid, chart)
card_medal = {
self.PLAY_MEDAL_CIRCLE_FAILED: "Failed",

View File

@ -55,22 +55,15 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
]
@classmethod
def run_scheduled_work(
cls, data: Data, config: Dict[str, Any]
) -> List[Tuple[str, Dict[str, Any]]]:
def run_scheduled_work(cls, data: Data, config: Dict[str, Any]) -> List[Tuple[str, Dict[str, Any]]]:
"""
Once a week, insert a new course.
"""
events = []
if data.local.network.should_schedule(
cls.game, cls.version, "course", "weekly"
):
if data.local.network.should_schedule(cls.game, cls.version, "course", "weekly"):
# Generate a new course list, save it to the DB.
start_time, end_time = data.local.network.get_schedule_duration("weekly")
all_songs = [
song.id
for song in data.local.music.get_all_songs(cls.game, cls.version)
]
all_songs = [song.id for song in data.local.music.get_all_songs(cls.game, cls.version)]
if all_songs:
course_song = random.choice(all_songs)
data.local.game.put_time_sensitive_settings(
@ -94,9 +87,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
)
# Mark that we did some actual work here.
data.local.network.mark_scheduled(
cls.game, cls.version, "course", "weekly"
)
data.local.network.mark_scheduled(cls.game, cls.version, "course", "weekly")
return events
def __score_to_rank(self, score: int) -> int:
@ -152,12 +143,8 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
# Gather course information and course ranking for users.
course_infos, achievements, profiles = Parallel.execute(
[
lambda: self.data.local.game.get_all_time_sensitive_settings(
self.game, self.version, "course"
),
lambda: self.data.local.user.get_all_achievements(
self.game, self.version
),
lambda: self.data.local.game.get_all_time_sensitive_settings(self.game, self.version, "course"),
lambda: self.data.local.user.get_all_achievements(self.game, self.version),
lambda: self.data.local.user.get_all_profiles(self.game, self.version),
]
)
@ -168,9 +155,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
reverse=True,
)
# Sort achievements within course ID from best to worst ranking.
achievements_by_course_id: Dict[
int, Dict[str, List[Tuple[UserID, Achievement]]]
] = {}
achievements_by_course_id: Dict[int, Dict[str, List[Tuple[UserID, Achievement]]]] = {}
type_to_chart_lut: Dict[str, str] = {
f"course_{self.GAME_CHART_TYPE_EASY}": "loc_ranking_e",
f"course_{self.GAME_CHART_TYPE_NORMAL}": "loc_ranking_n",
@ -187,9 +172,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
"loc_ranking_h": [],
"loc_ranking_ex": [],
}
achievements_by_course_id[ach.id][type_to_chart_lut[ach.type]].append(
(uid, ach)
)
achievements_by_course_id[ach.id][type_to_chart_lut[ach.type]].append((uid, ach))
for courseid in achievements_by_course_id:
for chart in [
"loc_ranking_e",
@ -204,9 +187,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
)
# Cache of userID to profile
userid_to_profile: Dict[UserID, Profile] = {
uid: profile for (uid, profile) in profiles
}
userid_to_profile: Dict[UserID, Profile] = {uid: profile for (uid, profile) in profiles}
# Course ranking info for the last 256 courses
for course_info in course_infos[:256]:
@ -216,9 +197,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
ranking_info = Node.void("ranking_info")
root.add_child(ranking_info)
ranking_info.add_child(Node.s16("course_id", course_id))
ranking_info.add_child(
Node.u64("start_date", course_info["start_time"] * 1000)
)
ranking_info.add_child(Node.u64("start_date", course_info["start_time"] * 1000))
ranking_info.add_child(Node.u64("end_date", course_info["end_time"] * 1000))
ranking_info.add_child(Node.s32("music_id", course_info["music"]))
@ -232,26 +211,16 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
chart_rankings = course_rankings.get(name, [])
for pos, (uid, ach) in enumerate(chart_rankings[:20]):
profile = userid_to_profile.get(
uid, Profile(self.game, self.version, "", 0)
)
profile = userid_to_profile.get(uid, Profile(self.game, self.version, "", 0))
subnode = Node.void(name)
ranking_info.add_child(subnode)
subnode.add_child(Node.s16("rank", pos + 1))
subnode.add_child(Node.string("name", profile.get_str("name")))
subnode.add_child(
Node.s16("chara_num", profile.get_int("chara", -1))
)
subnode.add_child(
Node.s32("total_score", ach.data.get_int("score"))
)
subnode.add_child(
Node.u8("clear_type", ach.data.get_int("clear_type"))
)
subnode.add_child(
Node.u8("clear_rank", ach.data.get_int("clear_rank"))
)
subnode.add_child(Node.s16("chara_num", profile.get_int("chara", -1)))
subnode.add_child(Node.s32("total_score", ach.data.get_int("score")))
subnode.add_child(Node.u8("clear_type", ach.data.get_int("clear_type")))
subnode.add_child(Node.u8("clear_rank", ach.data.get_int("clear_rank")))
if send_areas:
for area_id in range(1, 16):
@ -327,9 +296,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
popular.add_child(Node.s16("chara_num", charaid))
# Top 500 Popular music
for songid, _plays in self.data.local.music.get_hit_chart(
self.game, self.music_version, 500
):
for songid, _plays in self.data.local.music.get_hit_chart(self.game, self.music_version, 500):
popular_music = Node.void("popular_music")
root.add_child(popular_music)
popular_music.add_child(Node.s16("music_num", songid))
@ -418,9 +385,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
userid = None
if userid is not None:
oldprofile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -480,34 +445,23 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
# Handle fetching all scores
uids_and_courses, profile = Parallel.execute(
[
lambda: self.data.local.user.get_all_achievements(
self.game, self.version
),
lambda: self.get_profile(userid)
or Profile(self.game, self.version, "", 0),
lambda: self.data.local.user.get_all_achievements(self.game, self.version),
lambda: self.get_profile(userid) or Profile(self.game, self.version, "", 0),
]
)
# Grab a sorted list of all scores for this course and chart
global_uids_and_courses = sorted(
[
(uid, ach)
for (uid, ach) in uids_and_courses
if ach.type == course_type and ach.id == course_id
],
[(uid, ach) for (uid, ach) in uids_and_courses if ach.type == course_type and ach.id == course_id],
key=lambda uid_and_course: uid_and_course[1].data.get_int("score"),
reverse=True,
)
# Grab smaller lists that contain only sorted for our prefecture/location
pref_uids_and_courses = [
(uid, ach)
for (uid, ach) in global_uids_and_courses
if ach.data.get_int("pref") == prefecture
(uid, ach) for (uid, ach) in global_uids_and_courses if ach.data.get_int("pref") == prefecture
]
loc_uids_and_courses = [
(uid, ach)
for (uid, ach) in global_uids_and_courses
if ach.data.get_int("lid") == loc_id
(uid, ach) for (uid, ach) in global_uids_and_courses if ach.data.get_int("lid") == loc_id
]
def _get_rank(uac: List[Tuple[UserID, Achievement]]) -> Optional[int]:
@ -575,17 +529,13 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
return root
rivalid = links[no].other_userid
rivalprofile = profiles[rivalid]
scores = self.data.remote.music.get_scores(
self.game, self.music_version, rivalid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, rivalid)
# First, output general profile info.
friend = Node.void("friend")
root.add_child(friend)
friend.add_child(Node.s16("no", no))
friend.add_child(
Node.string("g_pm_id", self.format_extid(rivalprofile.extid))
) # UsaNeko formats on its own
friend.add_child(Node.string("g_pm_id", self.format_extid(rivalprofile.extid))) # UsaNeko formats on its own
friend.add_child(Node.string("name", rivalprofile.get_str("name", "なし")))
friend.add_child(Node.s16("chara_num", rivalprofile.get_int("chara", -1)))
# This might be for having non-active or non-confirmed friends, but setting to 0 makes the
@ -642,9 +592,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
),
)
achievements = self.data.local.user.get_achievements(
self.game, self.version, rivalid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, rivalid)
for achievement in achievements:
if achievement.type[:7] == "course_":
sheet = int(achievement.type[7:])
@ -652,18 +600,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
course_data = Node.void("course_data")
root.add_child(course_data)
course_data.add_child(Node.s16("course_id", achievement.id))
course_data.add_child(
Node.u8("clear_type", achievement.data.get_int("clear_type"))
)
course_data.add_child(
Node.u8("clear_rank", achievement.data.get_int("clear_rank"))
)
course_data.add_child(
Node.s32("total_score", achievement.data.get_int("score"))
)
course_data.add_child(
Node.s32("update_count", achievement.data.get_int("count"))
)
course_data.add_child(Node.u8("clear_type", achievement.data.get_int("clear_type")))
course_data.add_child(Node.u8("clear_rank", achievement.data.get_int("clear_rank")))
course_data.add_child(Node.s32("total_score", achievement.data.get_int("score")))
course_data.add_child(Node.s32("update_count", achievement.data.get_int("count")))
course_data.add_child(Node.u8("sheet_num", sheet))
return root
@ -675,9 +615,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
return Node.void("player24")
root = Node.void("player24")
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
# Skip any scores for chart types we don't support
if score.chart not in [
@ -768,9 +706,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
self.GAME_PLAY_MEDAL_STAR_FULL_COMBO: self.PLAY_MEDAL_STAR_FULL_COMBO,
self.GAME_PLAY_MEDAL_PERFECT: self.PLAY_MEDAL_PERFECT,
}[medal]
self.update_score(
userid, songid, chart, points, medal, combo=combo, stats=stats
)
self.update_score(userid, songid, chart, points, medal, combo=combo, stats=stats)
if request.child_value("is_image_store") == 1:
self.broadcast_score(userid, songid, chart, medal, points, combo, stats)
@ -804,9 +740,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
if lumina >= price:
# Update player lumina balance
profile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
profile.replace_int("player_point", lumina - price)
self.put_profile(userid, profile)
@ -833,9 +767,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
root.add_child(Node.s8("result", 1))
# Scores
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
# Skip any scores for chart types we don't support
if score.chart not in [
@ -905,57 +837,31 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
account.add_child(Node.s16("area_id", profile.get_int("area_id")))
account.add_child(Node.s16("use_navi", profile.get_int("use_navi")))
account.add_child(Node.s16("read_news", profile.get_int("read_news")))
account.add_child(
Node.s16_array("nice", profile.get_int_array("nice", 30, [-1] * 30))
)
account.add_child(
Node.s16_array(
"favorite_chara", profile.get_int_array("favorite_chara", 20, [-1] * 20)
)
)
account.add_child(
Node.s16_array(
"special_area", profile.get_int_array("special_area", 8, [-1] * 8)
)
)
account.add_child(Node.s16_array("nice", profile.get_int_array("nice", 30, [-1] * 30)))
account.add_child(Node.s16_array("favorite_chara", profile.get_int_array("favorite_chara", 20, [-1] * 20)))
account.add_child(Node.s16_array("special_area", profile.get_int_array("special_area", 8, [-1] * 8)))
account.add_child(
Node.s16_array(
"chocolate_charalist",
profile.get_int_array("chocolate_charalist", 5, [-1] * 5),
)
)
account.add_child(
Node.s32("chocolate_sp_chara", profile.get_int("chocolate_sp_chara", -1))
)
account.add_child(
Node.s32("chocolate_pass_cnt", profile.get_int("chocolate_pass_cnt"))
)
account.add_child(
Node.s32("chocolate_hon_cnt", profile.get_int("chocolate_hon_cnt"))
)
account.add_child(Node.s32("chocolate_sp_chara", profile.get_int("chocolate_sp_chara", -1)))
account.add_child(Node.s32("chocolate_pass_cnt", profile.get_int("chocolate_pass_cnt")))
account.add_child(Node.s32("chocolate_hon_cnt", profile.get_int("chocolate_hon_cnt")))
account.add_child(
Node.s16_array(
"teacher_setting",
profile.get_int_array("teacher_setting", 10, [-1] * 10),
)
)
account.add_child(
Node.bool("welcom_pack", False)
) # Set to true to grant extra stage no matter what.
account.add_child(Node.bool("welcom_pack", False)) # Set to true to grant extra stage no matter what.
account.add_child(Node.s32("ranking_node", profile.get_int("ranking_node")))
account.add_child(
Node.s32("chara_ranking_kind_id", profile.get_int("chara_ranking_kind_id"))
)
account.add_child(
Node.s8("navi_evolution_flg", profile.get_int("navi_evolution_flg"))
)
account.add_child(
Node.s32("ranking_news_last_no", profile.get_int("ranking_news_last_no"))
)
account.add_child(Node.s32("chara_ranking_kind_id", profile.get_int("chara_ranking_kind_id")))
account.add_child(Node.s8("navi_evolution_flg", profile.get_int("navi_evolution_flg")))
account.add_child(Node.s32("ranking_news_last_no", profile.get_int("ranking_news_last_no")))
account.add_child(Node.s32("power_point", profile.get_int("power_point")))
account.add_child(
Node.s32("player_point", profile.get_int("player_point", 300))
)
account.add_child(Node.s32("player_point", profile.get_int("player_point", 300)))
account.add_child(
Node.s32_array(
"power_point_list",
@ -1039,18 +945,8 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
account.add_child(Node.s16_array("license_data", [-1] * 20))
# Song statistics
last_played = [
x[0]
for x in self.data.local.music.get_last_played(
self.game, self.music_version, userid, 10
)
]
most_played = [
x[0]
for x in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
]
last_played = [x[0] for x in self.data.local.music.get_last_played(self.game, self.music_version, userid, 10)]
most_played = [x[0] for x in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)]
while len(last_played) < 10:
last_played.append(-1)
while len(most_played) < 20:
@ -1104,14 +1000,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
config.add_child(Node.u8("sheet", profile.get_int("sheet")))
config.add_child(Node.s8("category", profile.get_int("category", -1)))
config.add_child(Node.s8("sub_category", profile.get_int("sub_category", -1)))
config.add_child(
Node.s8("chara_category", profile.get_int("chara_category", -1))
)
config.add_child(Node.s8("chara_category", profile.get_int("chara_category", -1)))
config.add_child(Node.s16("course_id", profile.get_int("course_id", -1)))
config.add_child(Node.s8("course_folder", profile.get_int("course_folder", -1)))
config.add_child(
Node.s8("ms_banner_disp", profile.get_int("ms_banner_disp", -1))
)
config.add_child(Node.s8("ms_banner_disp", profile.get_int("ms_banner_disp", -1)))
config.add_child(Node.s8("ms_down_info", profile.get_int("ms_down_info", -1)))
config.add_child(Node.s8("ms_side_info", profile.get_int("ms_side_info", -1)))
config.add_child(Node.s8("ms_raise_type", profile.get_int("ms_raise_type", -1)))
@ -1134,9 +1026,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
option.add_child(Node.u8("ojama_1", option_dict.get_int("ojama_1")))
option.add_child(Node.bool("forever_0", option_dict.get_bool("forever_0")))
option.add_child(Node.bool("forever_1", option_dict.get_bool("forever_1")))
option.add_child(
Node.bool("full_setting", option_dict.get_bool("full_setting"))
)
option.add_child(Node.bool("full_setting", option_dict.get_bool("full_setting")))
option.add_child(Node.u8("judge", option_dict.get_int("judge")))
option.add_child(Node.s8("guide_se", option_dict.get_int("guide_se")))
@ -1155,18 +1045,11 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
navi_data = Node.void("navi_data")
root.add_child(navi_data)
if "navi_points" in profile:
navi_data.add_child(
Node.s32_array("raisePoint", profile.get_int_array("navi_points", 5))
)
navi_data.add_child(Node.s32_array("raisePoint", profile.get_int_array("navi_points", 5)))
game_config = self.get_game_config()
if game_config.get_bool("force_unlock_songs"):
songs = {
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
}
songs = {song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)}
for song in songs:
item = Node.void("item")
root.add_child(item)
@ -1177,9 +1060,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
item.add_child(Node.u64("get_time", 0))
# Set up achievements
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for achievement in achievements:
if achievement.type[:5] == "item_":
itemtype = int(achievement.type[5:])
@ -1243,18 +1124,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
course_data = Node.void("course_data")
root.add_child(course_data)
course_data.add_child(Node.s16("course_id", achievement.id))
course_data.add_child(
Node.u8("clear_type", achievement.data.get_int("clear_type"))
)
course_data.add_child(
Node.u8("clear_rank", achievement.data.get_int("clear_rank"))
)
course_data.add_child(
Node.s32("total_score", achievement.data.get_int("score"))
)
course_data.add_child(
Node.s32("update_count", achievement.data.get_int("count"))
)
course_data.add_child(Node.u8("clear_type", achievement.data.get_int("clear_type")))
course_data.add_child(Node.u8("clear_rank", achievement.data.get_int("clear_rank")))
course_data.add_child(Node.s32("total_score", achievement.data.get_int("score")))
course_data.add_child(Node.s32("update_count", achievement.data.get_int("count")))
course_data.add_child(Node.u8("sheet_num", sheet))
elif achievement.type == "fes":
@ -1340,9 +1213,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
account = request.child("account")
@ -1352,49 +1223,23 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
newprofile.replace_int("area_id", account.child_value("area_id"))
newprofile.replace_int("use_navi", account.child_value("use_navi"))
newprofile.replace_int("ranking_node", account.child_value("ranking_node"))
newprofile.replace_int(
"chara_ranking_kind_id", account.child_value("chara_ranking_kind_id")
)
newprofile.replace_int(
"navi_evolution_flg", account.child_value("navi_evolution_flg")
)
newprofile.replace_int(
"ranking_news_last_no", account.child_value("ranking_news_last_no")
)
newprofile.replace_int("chara_ranking_kind_id", account.child_value("chara_ranking_kind_id"))
newprofile.replace_int("navi_evolution_flg", account.child_value("navi_evolution_flg"))
newprofile.replace_int("ranking_news_last_no", account.child_value("ranking_news_last_no"))
newprofile.replace_int("power_point", account.child_value("power_point"))
newprofile.replace_int("player_point", account.child_value("player_point"))
newprofile.replace_int_array("nice", 30, account.child_value("nice"))
newprofile.replace_int_array(
"favorite_chara", 20, account.child_value("favorite_chara")
)
newprofile.replace_int_array(
"special_area", 8, account.child_value("special_area")
)
newprofile.replace_int_array(
"chocolate_charalist", 5, account.child_value("chocolate_charalist")
)
newprofile.replace_int(
"chocolate_sp_chara", account.child_value("chocolate_sp_chara")
)
newprofile.replace_int(
"chocolate_pass_cnt", account.child_value("chocolate_pass_cnt")
)
newprofile.replace_int(
"chocolate_hon_cnt", account.child_value("chocolate_hon_cnt")
)
newprofile.replace_int(
"chocolate_giri_cnt", account.child_value("chocolate_giri_cnt")
)
newprofile.replace_int(
"chocolate_kokyu_cnt", account.child_value("chocolate_kokyu_cnt")
)
newprofile.replace_int_array(
"teacher_setting", 10, account.child_value("teacher_setting")
)
newprofile.replace_int_array(
"power_point_list", 20, account.child_value("power_point_list")
)
newprofile.replace_int_array("favorite_chara", 20, account.child_value("favorite_chara"))
newprofile.replace_int_array("special_area", 8, account.child_value("special_area"))
newprofile.replace_int_array("chocolate_charalist", 5, account.child_value("chocolate_charalist"))
newprofile.replace_int("chocolate_sp_chara", account.child_value("chocolate_sp_chara"))
newprofile.replace_int("chocolate_pass_cnt", account.child_value("chocolate_pass_cnt"))
newprofile.replace_int("chocolate_hon_cnt", account.child_value("chocolate_hon_cnt"))
newprofile.replace_int("chocolate_giri_cnt", account.child_value("chocolate_giri_cnt"))
newprofile.replace_int("chocolate_kokyu_cnt", account.child_value("chocolate_kokyu_cnt"))
newprofile.replace_int_array("teacher_setting", 10, account.child_value("teacher_setting"))
newprofile.replace_int_array("power_point_list", 20, account.child_value("power_point_list"))
info = request.child("info")
if info is not None:
@ -1413,14 +1258,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
newprofile.replace_int("sheet", config.child_value("sheet"))
newprofile.replace_int("category", config.child_value("category"))
newprofile.replace_int("sub_category", config.child_value("sub_category"))
newprofile.replace_int(
"chara_category", config.child_value("chara_category")
)
newprofile.replace_int("chara_category", config.child_value("chara_category"))
newprofile.replace_int("course_id", config.child_value("course_id"))
newprofile.replace_int("course_folder", config.child_value("course_folder"))
newprofile.replace_int(
"ms_banner_disp", config.child_value("ms_banner_disp")
)
newprofile.replace_int("ms_banner_disp", config.child_value("ms_banner_disp"))
newprofile.replace_int("ms_down_info", config.child_value("ms_down_info"))
newprofile.replace_int("ms_side_info", config.child_value("ms_side_info"))
newprofile.replace_int("ms_raise_type", config.child_value("ms_raise_type"))
@ -1450,21 +1291,15 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
customize = request.child("customize")
if customize is not None:
newprofile.replace_int("effect_left", customize.child_value("effect_left"))
newprofile.replace_int(
"effect_center", customize.child_value("effect_center")
)
newprofile.replace_int(
"effect_right", customize.child_value("effect_right")
)
newprofile.replace_int("effect_center", customize.child_value("effect_center"))
newprofile.replace_int("effect_right", customize.child_value("effect_right"))
newprofile.replace_int("hukidashi", customize.child_value("hukidashi"))
newprofile.replace_int("comment_1", customize.child_value("comment_1"))
newprofile.replace_int("comment_2", customize.child_value("comment_2"))
navi_data = request.child("navi_data")
if navi_data is not None:
newprofile.replace_int_array(
"navi_points", 5, navi_data.child_value("raisePoint")
)
newprofile.replace_int_array("navi_points", 5, navi_data.child_value("raisePoint"))
# Extract navi achievements
for node in navi_data.children:

View File

@ -209,9 +209,7 @@ class PopnMusicEclale(PopnMusicBase):
rank = rank + 1
# Output the hit chart
for songid, _plays in self.data.local.music.get_hit_chart(
self.game, self.music_version, 500
):
for songid, _plays in self.data.local.music.get_hit_chart(self.game, self.music_version, 500):
popular_music = Node.void("popular_music")
root.add_child(popular_music)
popular_music.add_child(Node.s16("music_num", songid))
@ -285,9 +283,7 @@ class PopnMusicEclale(PopnMusicBase):
userid = None
if userid is not None:
oldprofile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -332,9 +328,7 @@ class PopnMusicEclale(PopnMusicBase):
if lumina >= price:
# Update player lumina balance
profile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
profile.replace_int("lumina", lumina - price)
self.put_profile(userid, profile)
@ -360,9 +354,7 @@ class PopnMusicEclale(PopnMusicBase):
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
else:
scores = []
@ -453,17 +445,13 @@ class PopnMusicEclale(PopnMusicBase):
return root
rivalid = links[no].other_userid
rivalprofile = profiles[rivalid]
scores = self.data.remote.music.get_scores(
self.game, self.music_version, rivalid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, rivalid)
# First, output general profile info.
friend = Node.void("friend")
root.add_child(friend)
friend.add_child(Node.s16("no", no))
friend.add_child(
Node.string("g_pm_id", self.format_extid(rivalprofile.extid))
) # Eclale formats on its own
friend.add_child(Node.string("g_pm_id", self.format_extid(rivalprofile.extid))) # Eclale formats on its own
friend.add_child(Node.string("name", rivalprofile.get_str("name", "なし")))
friend.add_child(Node.s16("chara_num", rivalprofile.get_int("chara", -1)))
# This might be for having non-active or non-confirmed friends, but setting to 0 makes the
@ -561,9 +549,7 @@ class PopnMusicEclale(PopnMusicBase):
self.GAME_PLAY_MEDAL_STAR_FULL_COMBO: self.PLAY_MEDAL_STAR_FULL_COMBO,
self.GAME_PLAY_MEDAL_PERFECT: self.PLAY_MEDAL_PERFECT,
}[medal]
self.update_score(
userid, songid, chart, points, medal, combo=combo, stats=stats
)
self.update_score(userid, songid, chart, points, medal, combo=combo, stats=stats)
if request.child_value("is_image_store") == 1:
self.broadcast_score(userid, songid, chart, medal, points, combo, stats)
@ -577,9 +563,7 @@ class PopnMusicEclale(PopnMusicBase):
root.add_child(Node.s8("result", 1))
# Scores
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
# Skip any scores for chart types we don't support
if score.chart not in [
@ -649,34 +633,18 @@ class PopnMusicEclale(PopnMusicBase):
account.add_child(Node.s16("area_id", profile.get_int("area_id")))
account.add_child(Node.s16("lumina", profile.get_int("lumina", 300)))
account.add_child(Node.s16("read_news", profile.get_int("read_news")))
account.add_child(
Node.bool("welcom_pack", False)
) # Set this to true to grant extra stage no matter what.
account.add_child(
Node.s16_array("medal_set", profile.get_int_array("medal_set", 4))
)
account.add_child(
Node.s16_array("nice", profile.get_int_array("nice", 30, [-1] * 30))
)
account.add_child(
Node.s16_array(
"favorite_chara", profile.get_int_array("favorite_chara", 20, [-1] * 20)
)
)
account.add_child(
Node.s16_array("special_area", profile.get_int_array("special_area", 8))
)
account.add_child(Node.bool("welcom_pack", False)) # Set this to true to grant extra stage no matter what.
account.add_child(Node.s16_array("medal_set", profile.get_int_array("medal_set", 4)))
account.add_child(Node.s16_array("nice", profile.get_int_array("nice", 30, [-1] * 30)))
account.add_child(Node.s16_array("favorite_chara", profile.get_int_array("favorite_chara", 20, [-1] * 20)))
account.add_child(Node.s16_array("special_area", profile.get_int_array("special_area", 8)))
account.add_child(
Node.s16_array(
"chocolate_charalist",
profile.get_int_array("chocolate_charalist", 5, [-1] * 5),
)
)
account.add_child(
Node.s16_array(
"teacher_setting", profile.get_int_array("teacher_setting", 10)
)
)
account.add_child(Node.s16_array("teacher_setting", profile.get_int_array("teacher_setting", 10)))
# Stuff we never change
account.add_child(Node.s8("staff", 0))
@ -687,18 +655,8 @@ class PopnMusicEclale(PopnMusicBase):
account.add_child(Node.s16_array("license_data", [-1] * 20))
# Add statistics section
last_played = [
x[0]
for x in self.data.local.music.get_last_played(
self.game, self.music_version, userid, 5
)
]
most_played = [
x[0]
for x in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 10
)
]
last_played = [x[0] for x in self.data.local.music.get_last_played(self.game, self.music_version, userid, 5)]
most_played = [x[0] for x in self.data.local.music.get_most_played(self.game, self.music_version, userid, 10)]
while len(last_played) < 5:
last_played.append(-1)
while len(most_played) < 10:
@ -753,9 +711,7 @@ class PopnMusicEclale(PopnMusicBase):
config.add_child(Node.u8("sheet", profile.get_int("sheet")))
config.add_child(Node.s8("category", profile.get_int("category", -1)))
config.add_child(Node.s8("sub_category", profile.get_int("sub_category", -1)))
config.add_child(
Node.s8("chara_category", profile.get_int("chara_category", -1))
)
config.add_child(Node.s8("chara_category", profile.get_int("chara_category", -1)))
config.add_child(Node.s16("course_id", profile.get_int("course_id", -1)))
config.add_child(Node.s8("course_folder", profile.get_int("course_folder", -1)))
config.add_child(Node.s8("ms_banner_disp", profile.get_int("ms_banner_disp")))
@ -780,9 +736,7 @@ class PopnMusicEclale(PopnMusicBase):
option.add_child(Node.u8("ojama_1", option_dict.get_int("ojama_1")))
option.add_child(Node.bool("forever_0", option_dict.get_bool("forever_0")))
option.add_child(Node.bool("forever_1", option_dict.get_bool("forever_1")))
option.add_child(
Node.bool("full_setting", option_dict.get_bool("full_setting"))
)
option.add_child(Node.bool("full_setting", option_dict.get_bool("full_setting")))
option.add_child(Node.u8("judge", option_dict.get_int("judge")))
# Unknown custom category stuff?
@ -798,12 +752,7 @@ class PopnMusicEclale(PopnMusicBase):
game_config = self.get_game_config()
if game_config.get_bool("force_unlock_songs"):
songs = {
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
}
songs = {song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)}
for song in songs:
item = Node.void("item")
root.add_child(item)
@ -813,9 +762,7 @@ class PopnMusicEclale(PopnMusicBase):
item.add_child(Node.bool("is_new", False))
# Set up achievements
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for achievement in achievements:
if achievement.type[:5] == "item_":
itemtype = int(achievement.type[5:])
@ -898,9 +845,7 @@ class PopnMusicEclale(PopnMusicBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
account = request.child("account")
@ -909,22 +854,12 @@ class PopnMusicEclale(PopnMusicBase):
newprofile.replace_int("read_news", account.child_value("read_news"))
newprofile.replace_int("area_id", account.child_value("area_id"))
newprofile.replace_int("lumina", account.child_value("lumina"))
newprofile.replace_int_array(
"medal_set", 4, account.child_value("medal_set")
)
newprofile.replace_int_array("medal_set", 4, account.child_value("medal_set"))
newprofile.replace_int_array("nice", 30, account.child_value("nice"))
newprofile.replace_int_array(
"favorite_chara", 20, account.child_value("favorite_chara")
)
newprofile.replace_int_array(
"special_area", 8, account.child_value("special_area")
)
newprofile.replace_int_array(
"chocolate_charalist", 5, account.child_value("chocolate_charalist")
)
newprofile.replace_int_array(
"teacher_setting", 10, account.child_value("teacher_setting")
)
newprofile.replace_int_array("favorite_chara", 20, account.child_value("favorite_chara"))
newprofile.replace_int_array("special_area", 8, account.child_value("special_area"))
newprofile.replace_int_array("chocolate_charalist", 5, account.child_value("chocolate_charalist"))
newprofile.replace_int_array("teacher_setting", 10, account.child_value("teacher_setting"))
info = request.child("info")
if info is not None:
@ -938,14 +873,10 @@ class PopnMusicEclale(PopnMusicBase):
newprofile.replace_int("sheet", config.child_value("sheet"))
newprofile.replace_int("category", config.child_value("category"))
newprofile.replace_int("sub_category", config.child_value("sub_category"))
newprofile.replace_int(
"chara_category", config.child_value("chara_category")
)
newprofile.replace_int("chara_category", config.child_value("chara_category"))
newprofile.replace_int("course_id", config.child_value("course_id"))
newprofile.replace_int("course_folder", config.child_value("course_folder"))
newprofile.replace_int(
"ms_banner_disp", config.child_value("ms_banner_disp")
)
newprofile.replace_int("ms_banner_disp", config.child_value("ms_banner_disp"))
newprofile.replace_int("ms_down_info", config.child_value("ms_down_info"))
newprofile.replace_int("ms_side_info", config.child_value("ms_side_info"))
newprofile.replace_int("ms_raise_type", config.child_value("ms_raise_type"))
@ -973,21 +904,15 @@ class PopnMusicEclale(PopnMusicBase):
customize = request.child("customize")
if customize is not None:
newprofile.replace_int("effect_left", customize.child_value("effect_left"))
newprofile.replace_int(
"effect_center", customize.child_value("effect_center")
)
newprofile.replace_int(
"effect_right", customize.child_value("effect_right")
)
newprofile.replace_int("effect_center", customize.child_value("effect_center"))
newprofile.replace_int("effect_right", customize.child_value("effect_right"))
newprofile.replace_int("hukidashi", customize.child_value("hukidashi"))
newprofile.replace_int("comment_1", customize.child_value("comment_1"))
newprofile.replace_int("comment_2", customize.child_value("comment_2"))
event = request.child("event")
if event is not None:
newprofile.replace_int(
"event_enemy_medal", event.child_value("enemy_medal")
)
newprofile.replace_int("event_enemy_medal", event.child_value("enemy_medal"))
newprofile.replace_int("event_hp", event.child_value("hp"))
stamp = request.child("stamp")

View File

@ -113,9 +113,7 @@ class PopnMusicFantasia(PopnMusicBase):
base.add_child(Node.u8("mode", profile.get_int("mode", 0)))
base.add_child(Node.s8("button", profile.get_int("button", 0)))
base.add_child(Node.s8("last_play_flag", profile.get_int("last_play_flag", -1)))
base.add_child(
Node.u8("medal_and_friend", profile.get_int("medal_and_friend", 0))
)
base.add_child(Node.u8("medal_and_friend", profile.get_int("medal_and_friend", 0)))
base.add_child(Node.s8("category", profile.get_int("category", -1)))
base.add_child(Node.s8("sub_category", profile.get_int("sub_category", -1)))
base.add_child(Node.s16("chara", profile.get_int("chara", -1)))
@ -128,58 +126,32 @@ class PopnMusicFantasia(PopnMusicBase):
base.add_child(Node.s32("option", profile.get_int("option", 0)))
base.add_child(Node.s16("music", profile.get_int("music", -1)))
base.add_child(Node.u16("ep", profile.get_int("ep", 0)))
base.add_child(
Node.s32_array("sp_color_flg", profile.get_int_array("sp_color_flg", 2))
)
base.add_child(Node.s32_array("sp_color_flg", profile.get_int_array("sp_color_flg", 2)))
base.add_child(Node.s32("read_news", profile.get_int("read_news", 0)))
base.add_child(
Node.s16(
"consecutive_days_coupon", profile.get_int("consecutive_days_coupon", 0)
)
)
base.add_child(Node.s16("consecutive_days_coupon", profile.get_int("consecutive_days_coupon", 0)))
base.add_child(Node.s8("staff", 0))
# Player card section
player_card_dict = profile.get_dict("player_card")
player_card = Node.void("player_card")
root.add_child(player_card)
player_card.add_child(
Node.u8_array("title", player_card_dict.get_int_array("title", 2, [0, 1]))
)
player_card.add_child(Node.u8_array("title", player_card_dict.get_int_array("title", 2, [0, 1])))
player_card.add_child(Node.u8("frame", player_card_dict.get_int("frame")))
player_card.add_child(Node.u8("base", player_card_dict.get_int("base")))
player_card.add_child(
Node.u8_array("seal", player_card_dict.get_int_array("seal", 2))
)
player_card.add_child(
Node.s32_array("get_title", player_card_dict.get_int_array("get_title", 4))
)
player_card.add_child(
Node.s32("get_frame", player_card_dict.get_int("get_frame"))
)
player_card.add_child(
Node.s32("get_base", player_card_dict.get_int("get_base"))
)
player_card.add_child(
Node.s32_array("get_seal", player_card_dict.get_int_array("get_seal", 2))
)
player_card.add_child(Node.u8_array("seal", player_card_dict.get_int_array("seal", 2)))
player_card.add_child(Node.s32_array("get_title", player_card_dict.get_int_array("get_title", 4)))
player_card.add_child(Node.s32("get_frame", player_card_dict.get_int("get_frame")))
player_card.add_child(Node.s32("get_base", player_card_dict.get_int("get_base")))
player_card.add_child(Node.s32_array("get_seal", player_card_dict.get_int_array("get_seal", 2)))
player_card.add_child(Node.s8("is_open", 1))
# Player card EX section
player_card_ex = Node.void("player_card_ex")
root.add_child(player_card_ex)
player_card_ex.add_child(
Node.s32("get_title_ex", player_card_dict.get_int("get_title_ex"))
)
player_card_ex.add_child(
Node.s32("get_frame_ex", player_card_dict.get_int("get_frame_ex"))
)
player_card_ex.add_child(
Node.s32("get_base_ex", player_card_dict.get_int("get_base_ex"))
)
player_card_ex.add_child(
Node.s32("get_seal_ex", player_card_dict.get_int("get_seal_ex"))
)
player_card_ex.add_child(Node.s32("get_title_ex", player_card_dict.get_int("get_title_ex")))
player_card_ex.add_child(Node.s32("get_frame_ex", player_card_dict.get_int("get_frame_ex")))
player_card_ex.add_child(Node.s32("get_base_ex", player_card_dict.get_int("get_base_ex")))
player_card_ex.add_child(Node.s32("get_seal_ex", player_card_dict.get_int("get_seal_ex")))
# Statistics section and scores section
statistics = self.get_play_statistics(userid)
@ -201,18 +173,8 @@ class PopnMusicFantasia(PopnMusicBase):
rivalcount += 1
base.add_child(Node.u8("active_fr_num", rivalcount))
last_played = [
x[0]
for x in self.data.local.music.get_last_played(
self.game, self.music_version, userid, 3
)
]
most_played = [
x[0]
for x in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
]
last_played = [x[0] for x in self.data.local.music.get_last_played(self.game, self.music_version, userid, 3)]
most_played = [x[0] for x in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)]
while len(last_played) < 3:
last_played.append(-1)
while len(most_played) < 20:
@ -222,9 +184,7 @@ class PopnMusicFantasia(PopnMusicBase):
clear_medal = [0] * self.GAME_MAX_MUSIC_ID
clear_medal_sub = [0] * self.GAME_MAX_MUSIC_ID
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
if score.id > self.GAME_MAX_MUSIC_ID:
continue
@ -240,9 +200,7 @@ class PopnMusicFantasia(PopnMusicBase):
if score.data.get_int("medal") == self.PLAY_MEDAL_NO_PLAY:
continue
clear_medal[score.id] = clear_medal[
score.id
] | self.__format_medal_for_score(score)
clear_medal[score.id] = clear_medal[score.id] | self.__format_medal_for_score(score)
hiscore_index = (score.id * 4) + {
self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY_POSITION,
self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL_POSITION,
@ -252,15 +210,9 @@ class PopnMusicFantasia(PopnMusicBase):
hiscore_byte_pos = int((hiscore_index * 17) / 8)
hiscore_bit_pos = int((hiscore_index * 17) % 8)
hiscore_value = score.points << hiscore_bit_pos
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (
hiscore_value & 0xFF
)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[
hiscore_byte_pos + 1
] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[
hiscore_byte_pos + 2
] | ((hiscore_value >> 16) & 0xFF)
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF)
hiscore = bytes(hiscore_array)
@ -294,9 +246,7 @@ class PopnMusicFantasia(PopnMusicBase):
reflec_data = Node.void("reflec_data")
root.add_child(reflec_data)
reflec_data.add_child(
Node.s8_array("reflec", profile.get_int_array("reflec", 2))
)
reflec_data.add_child(Node.s8_array("reflec", profile.get_int_array("reflec", 2)))
# Navigate section
for i in range(3):
@ -307,14 +257,10 @@ class PopnMusicFantasia(PopnMusicBase):
navigate.add_child(Node.s8("image", navigate_dict.get_int("image", -1)))
navigate.add_child(Node.s8("level", navigate_dict.get_int("level", -1)))
navigate.add_child(Node.s8("ojama", navigate_dict.get_int("ojama", -1)))
navigate.add_child(
Node.s16("limit_num", navigate_dict.get_int("limit_num", -1))
)
navigate.add_child(Node.s16("limit_num", navigate_dict.get_int("limit_num", -1)))
navigate.add_child(Node.s8("button", navigate_dict.get_int("button", -1)))
navigate.add_child(Node.s8("life", navigate_dict.get_int("life", -1)))
navigate.add_child(
Node.s16("progress", navigate_dict.get_int("progress", -1))
)
navigate.add_child(Node.s16("progress", navigate_dict.get_int("progress", -1)))
return root
@ -331,9 +277,7 @@ class PopnMusicFantasia(PopnMusicBase):
clear_medal = [0] * self.GAME_MAX_MUSIC_ID
hiscore_array = [0] * int((((self.GAME_MAX_MUSIC_ID * 4) * 17) + 7) / 8)
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
if score.id > self.GAME_MAX_MUSIC_ID:
continue
@ -349,9 +293,7 @@ class PopnMusicFantasia(PopnMusicBase):
if score.data.get_int("medal") == self.PLAY_MEDAL_NO_PLAY:
continue
clear_medal[score.id] = clear_medal[
score.id
] | self.__format_medal_for_score(score)
clear_medal[score.id] = clear_medal[score.id] | self.__format_medal_for_score(score)
hiscore_index = (score.id * 4) + {
self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY_POSITION,
self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL_POSITION,
@ -361,24 +303,16 @@ class PopnMusicFantasia(PopnMusicBase):
hiscore_byte_pos = int((hiscore_index * 17) / 8)
hiscore_bit_pos = int((hiscore_index * 17) % 8)
hiscore_value = score.points << hiscore_bit_pos
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (
hiscore_value & 0xFF
)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[
hiscore_byte_pos + 1
] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[
hiscore_byte_pos + 2
] | ((hiscore_value >> 16) & 0xFF)
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF)
root.add_child(Node.u16_array("clear_medal", clear_medal))
root.add_child(Node.binary("hiscore", bytes(hiscore_array)))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
# For some reason, Pop'n 20 sends us two profile saves, one with 'not done yet'
# so we only want to process the done yet node. The 'not gameover' save has
# jubeat collabo stuff set in it, but we don't use that so it doesn't matter.
@ -396,17 +330,11 @@ class PopnMusicFantasia(PopnMusicBase):
newprofile.replace_int("category", request.child_value("category"))
newprofile.replace_int("sub_category", request.child_value("sub_category"))
newprofile.replace_int("chara_category", request.child_value("chara_category"))
newprofile.replace_int(
"medal_and_friend", request.child_value("medal_and_friend")
)
newprofile.replace_int("medal_and_friend", request.child_value("medal_and_friend"))
newprofile.replace_int("ep", request.child_value("ep"))
newprofile.replace_int_array(
"sp_color_flg", 2, request.child_value("sp_color_flg")
)
newprofile.replace_int_array("sp_color_flg", 2, request.child_value("sp_color_flg"))
newprofile.replace_int("read_news", request.child_value("read_news"))
newprofile.replace_int(
"consecutive_days_coupon", request.child_value("consecutive_days_coupon")
)
newprofile.replace_int("consecutive_days_coupon", request.child_value("consecutive_days_coupon"))
newprofile.replace_int("tutorial", request.child_value("tutorial"))
newprofile.replace_int("music_open_pt", request.child_value("music_open_pt"))
newprofile.replace_int("collabo", request.child_value("collabo"))
@ -428,29 +356,17 @@ class PopnMusicFantasia(PopnMusicBase):
player_card_dict.replace_int("frame", request.child_value("frame"))
player_card_dict.replace_int("base", request.child_value("base"))
player_card_dict.replace_int_array("seal", 2, request.child_value("seal"))
player_card_dict.replace_int_array(
"get_title", 4, request.child_value("get_title")
)
player_card_dict.replace_int_array("get_title", 4, request.child_value("get_title"))
player_card_dict.replace_int("get_frame", request.child_value("get_frame"))
player_card_dict.replace_int("get_base", request.child_value("get_base"))
player_card_dict.replace_int_array(
"get_seal", 2, request.child_value("get_seal")
)
player_card_dict.replace_int_array("get_seal", 2, request.child_value("get_seal"))
player_card_ex = request.child("player_card_ex")
if player_card_ex is not None:
player_card_dict.replace_int(
"get_title_ex", player_card_ex.child_value("get_title_ex")
)
player_card_dict.replace_int(
"get_frame_ex", player_card_ex.child_value("get_frame_ex")
)
player_card_dict.replace_int(
"get_base_ex", player_card_ex.child_value("get_base_ex")
)
player_card_dict.replace_int(
"get_seal_ex", player_card_ex.child_value("get_seal_ex")
)
player_card_dict.replace_int("get_title_ex", player_card_ex.child_value("get_title_ex"))
player_card_dict.replace_int("get_frame_ex", player_card_ex.child_value("get_frame_ex"))
player_card_dict.replace_int("get_base_ex", player_card_ex.child_value("get_base_ex"))
player_card_dict.replace_int("get_seal_ex", player_card_ex.child_value("get_seal_ex"))
newprofile.replace_dict("player_card", player_card_dict)
# Extract navigate stuff
@ -462,9 +378,7 @@ class PopnMusicFantasia(PopnMusicBase):
navigate_dict.replace_int("image", navigate.child_value("image"))
navigate_dict.replace_int("level", navigate.child_value("level"))
navigate_dict.replace_int("ojama", navigate.child_value("ojama"))
navigate_dict.replace_int(
"limit_num", navigate.child_value("limit_num")
)
navigate_dict.replace_int("limit_num", navigate.child_value("limit_num"))
navigate_dict.replace_int("button", navigate.child_value("button"))
navigate_dict.replace_int("life", navigate.child_value("life"))
navigate_dict.replace_int("progress", navigate.child_value("progress"))
@ -549,9 +463,7 @@ class PopnMusicFantasia(PopnMusicBase):
machine = self.get_machine()
root = Node.void("playerdata")
root.add_child(
Node.s8("pref", machine.data.get_int("pref", self.get_machine_region()))
)
root.add_child(Node.s8("pref", machine.data.get_int("pref", self.get_machine_region())))
if refid is None:
root.add_child(Node.string("name", ""))
@ -584,9 +496,7 @@ class PopnMusicFantasia(PopnMusicBase):
root.add_child(Node.string("message", ""))
return root
oldprofile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -597,22 +507,10 @@ class PopnMusicFantasia(PopnMusicBase):
root.add_child(Node.s16("chara", newprofile.get_int("chara", -1)))
root.add_child(Node.u8("frame", player_card_dict.get_int("frame")))
root.add_child(Node.u8("base", player_card_dict.get_int("base")))
root.add_child(
Node.u8("seal_1", player_card_dict.get_int_array("seal", 2)[0])
)
root.add_child(
Node.u8("seal_2", player_card_dict.get_int_array("seal", 2)[1])
)
root.add_child(
Node.u8(
"title_1", player_card_dict.get_int_array("title", 2, [0, 1])[0]
)
)
root.add_child(
Node.u8(
"title_2", player_card_dict.get_int_array("title", 2, [0, 1])[1]
)
)
root.add_child(Node.u8("seal_1", player_card_dict.get_int_array("seal", 2)[0]))
root.add_child(Node.u8("seal_2", player_card_dict.get_int_array("seal", 2)[1]))
root.add_child(Node.u8("title_1", player_card_dict.get_int_array("title", 2, [0, 1])[0]))
root.add_child(Node.u8("title_2", player_card_dict.get_int_array("title", 2, [0, 1])[1]))
root.add_child(Node.s16("recommend_1", -1))
root.add_child(Node.s16("recommend_2", -1))
root.add_child(Node.s16("recommend_3", -1))
@ -647,9 +545,7 @@ class PopnMusicFantasia(PopnMusicBase):
for rival in links[:2]:
rivalid = rival.other_userid
rivalprofile = profiles[rivalid]
scores = self.data.remote.music.get_scores(
self.game, self.music_version, rivalid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, rivalid)
# First, output general profile info.
friend = Node.void("friend")
@ -661,9 +557,7 @@ class PopnMusicFantasia(PopnMusicBase):
# Set up some sane defaults.
friend.add_child(Node.string("name", rivalprofile.get_str("name", "なし")))
friend.add_child(
Node.string("g_pm_id", ID.format_extid(rivalprofile.extid))
)
friend.add_child(Node.string("g_pm_id", ID.format_extid(rivalprofile.extid)))
friend.add_child(Node.s16("chara", rivalprofile.get_int("chara", -1)))
# Perform hiscore/medal conversion.
@ -684,9 +578,7 @@ class PopnMusicFantasia(PopnMusicBase):
if score.data.get_int("medal") == self.PLAY_MEDAL_NO_PLAY:
continue
clear_medal[score.id] = clear_medal[
score.id
] | self.__format_medal_for_score(score)
clear_medal[score.id] = clear_medal[score.id] | self.__format_medal_for_score(score)
hiscore_index = (score.id * 4) + {
self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY_POSITION,
self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL_POSITION,
@ -696,15 +588,13 @@ class PopnMusicFantasia(PopnMusicBase):
hiscore_byte_pos = int((hiscore_index * 17) / 8)
hiscore_bit_pos = int((hiscore_index * 17) % 8)
hiscore_value = score.points << hiscore_bit_pos
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (
hiscore_value & 0xFF
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | (
(hiscore_value >> 8) & 0xFF
)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | (
(hiscore_value >> 16) & 0xFF
)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[
hiscore_byte_pos + 1
] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[
hiscore_byte_pos + 2
] | ((hiscore_value >> 16) & 0xFF)
hiscore = bytes(hiscore_array)
friend.add_child(Node.u16_array("clear_medal", clear_medal))
@ -726,14 +616,10 @@ class PopnMusicFantasia(PopnMusicBase):
root.add_child(Node.s32("game_phase", game_phase))
root.add_child(Node.s32("ir_phase", 0))
root.add_child(Node.s32("event_phase", event_phase))
root.add_child(
Node.s32("netvs_phase", 0)
) # Net taisen mode, we don't support lobbies.
root.add_child(Node.s32("netvs_phase", 0)) # Net taisen mode, we don't support lobbies.
root.add_child(Node.s32("card_phase", 6))
root.add_child(Node.s32("illust_phase", 2))
root.add_child(
Node.s32("psp_phase", 5)
) # Unlock songs from Pop'n Music Portable.
root.add_child(Node.s32("psp_phase", 5)) # Unlock songs from Pop'n Music Portable.
root.add_child(Node.s32("other_phase", 1))
root.add_child(Node.s32("jubeat_phase", 1))
root.add_child(Node.s32("public_phase", 3))

View File

@ -384,9 +384,7 @@ class PopnMusicKaimei(PopnMusicModernBase):
root = super().format_profile(userid, profile)
account = root.child("account")
account.add_child(
Node.s16("card_again_count", profile.get_int("card_again_count"))
)
account.add_child(Node.s16("card_again_count", profile.get_int("card_again_count")))
account.add_child(Node.s16("sp_riddles_id", profile.get_int("sp_riddles_id")))
# Kaimei riddles events
@ -394,11 +392,7 @@ class PopnMusicKaimei(PopnMusicModernBase):
root.add_child(event2021)
event2021.add_child(Node.u32("point", profile.get_int("point")))
event2021.add_child(Node.u8("step", profile.get_int("step")))
event2021.add_child(
Node.u32_array(
"quest_point", profile.get_int_array("quest_point", 8, [0] * 8)
)
)
event2021.add_child(Node.u32_array("quest_point", profile.get_int_array("quest_point", 8, [0] * 8)))
event2021.add_child(Node.u8("step_nos", profile.get_int("step_nos")))
event2021.add_child(
Node.u32_array(
@ -428,9 +422,7 @@ class PopnMusicKaimei(PopnMusicModernBase):
sh_riddles.add_child(Node.u32("sh_riddles_id", riddle))
# Set up kaimei riddles achievements
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for achievement in achievements:
if achievement.type == "riddle":
kaimei_gauge = achievement.data.get_int("kaimei_gauge")
@ -449,32 +441,22 @@ class PopnMusicKaimei(PopnMusicModernBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = super().unformat_profile(userid, request, oldprofile)
account = request.child("account")
if account is not None:
newprofile.replace_int(
"card_again_count", account.child_value("card_again_count")
)
newprofile.replace_int(
"sp_riddles_id", account.child_value("sp_riddles_id")
)
newprofile.replace_int("card_again_count", account.child_value("card_again_count"))
newprofile.replace_int("sp_riddles_id", account.child_value("sp_riddles_id"))
# Kaimei riddles events
event2021 = request.child("event2021")
if event2021 is not None:
newprofile.replace_int("point", event2021.child_value("point"))
newprofile.replace_int("step", event2021.child_value("step"))
newprofile.replace_int_array(
"quest_point", 8, event2021.child_value("quest_point")
)
newprofile.replace_int_array("quest_point", 8, event2021.child_value("quest_point"))
newprofile.replace_int("step_nos", event2021.child_value("step_nos"))
newprofile.replace_int_array(
"quest_point_nos", 13, event2021.child_value("quest_point_nos")
)
newprofile.replace_int_array("quest_point_nos", 13, event2021.child_value("quest_point_nos"))
# Extract kaimei riddles achievements
for node in request.children:

View File

@ -289,9 +289,7 @@ class PopnMusicLapistoria(PopnMusicBase):
if userid is None:
return root
oldprofile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -334,12 +332,8 @@ class PopnMusicLapistoria(PopnMusicBase):
return root
rivalid = links[no].other_userid
rivalprofile = profiles[rivalid]
scores = self.data.remote.music.get_scores(
self.game, self.music_version, rivalid
)
achievements = self.data.local.user.get_achievements(
self.game, self.version, rivalid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, rivalid)
achievements = self.data.local.user.get_achievements(self.game, self.version, rivalid)
# First, output general profile info.
friend = Node.void("friend")
@ -474,9 +468,7 @@ class PopnMusicLapistoria(PopnMusicBase):
self.GAME_PLAY_MEDAL_STAR_FULL_COMBO: self.PLAY_MEDAL_STAR_FULL_COMBO,
self.GAME_PLAY_MEDAL_PERFECT: self.PLAY_MEDAL_PERFECT,
}[medal]
self.update_score(
userid, songid, chart, points, medal, combo=combo, stats=stats
)
self.update_score(userid, songid, chart, points, medal, combo=combo, stats=stats)
return root
def handle_player22_write_course_request(self, request: Node) -> Node:
@ -496,9 +488,7 @@ class PopnMusicLapistoria(PopnMusicBase):
if course_id is not None:
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
pref = request.child_value("pref") or self.get_machine_region()
profile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
course = self.data.local.user.get_achievement(
self.game,
@ -569,12 +559,8 @@ class PopnMusicLapistoria(PopnMusicBase):
key=lambda entry: entry[1].data.get_int("total_score"),
reverse=True,
)
pref_ranking = [
c for c in global_ranking if c[1].data.get_int("pref") == pref
]
local_ranking = [
c for c in global_ranking if c[1].data.get_int("lid") == machine.arcade
]
pref_ranking = [c for c in global_ranking if c[1].data.get_int("pref") == pref]
local_ranking = [c for c in global_ranking if c[1].data.get_int("lid") == machine.arcade]
global_rank = len(global_ranking)
pref_rank = len(pref_ranking)
@ -630,9 +616,7 @@ class PopnMusicLapistoria(PopnMusicBase):
account.add_child(Node.s8("is_conv", 0))
account.add_child(Node.s16("item_type", 0))
account.add_child(Node.s16("item_id", 0))
account.add_child(
Node.s16_array("license_data", [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
)
account.add_child(Node.s16_array("license_data", [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]))
# Statistics section and scores section
statistics = self.get_play_statistics(userid)
@ -657,18 +641,8 @@ class PopnMusicLapistoria(PopnMusicBase):
account.add_child(Node.u8("active_fr_num", rivalcount))
# Add scores section
last_played = [
x[0]
for x in self.data.local.music.get_last_played(
self.game, self.music_version, userid, 5
)
]
most_played = [
x[0]
for x in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 10
)
]
last_played = [x[0] for x in self.data.local.music.get_last_played(self.game, self.music_version, userid, 5)]
most_played = [x[0] for x in self.data.local.music.get_most_played(self.game, self.music_version, userid, 10)]
while len(last_played) < 5:
last_played.append(-1)
while len(most_played) < 10:
@ -677,9 +651,7 @@ class PopnMusicLapistoria(PopnMusicBase):
account.add_child(Node.s16_array("my_best", most_played))
account.add_child(Node.s16_array("latest_music", last_played))
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
# Skip any scores for chart types we don't support
if score.chart not in [
@ -754,9 +726,7 @@ class PopnMusicLapistoria(PopnMusicBase):
config.add_child(Node.u8("sheet", profile.get_int("sheet", 0)))
config.add_child(Node.s8("category", profile.get_int("category", 1)))
config.add_child(Node.s8("sub_category", profile.get_int("sub_category", -1)))
config.add_child(
Node.s8("chara_category", profile.get_int("chara_category", -1))
)
config.add_child(Node.s8("chara_category", profile.get_int("chara_category", -1)))
config.add_child(Node.s16("story_id", profile.get_int("story_id", -1)))
config.add_child(Node.s16("course_id", profile.get_int("course_id", -1)))
config.add_child(Node.s8("course_folder", profile.get_int("course_folder", -1)))
@ -774,26 +744,16 @@ class PopnMusicLapistoria(PopnMusicBase):
option.add_child(Node.s16("hispeed", option_dict.get_int("hispeed", 10)))
option.add_child(Node.u8("popkun", option_dict.get_int("popkun", 0)))
option.add_child(Node.bool("hidden", option_dict.get_bool("hidden", False)))
option.add_child(
Node.s16("hidden_rate", option_dict.get_int("hidden_rate", -1))
)
option.add_child(Node.s16("hidden_rate", option_dict.get_int("hidden_rate", -1)))
option.add_child(Node.bool("sudden", option_dict.get_bool("sudden", False)))
option.add_child(
Node.s16("sudden_rate", option_dict.get_int("sudden_rate", -1))
)
option.add_child(Node.s16("sudden_rate", option_dict.get_int("sudden_rate", -1)))
option.add_child(Node.s8("randmir", option_dict.get_int("randmir", 0)))
option.add_child(Node.s8("gauge_type", option_dict.get_int("gauge_type", 0)))
option.add_child(Node.u8("ojama_0", option_dict.get_int("ojama_0", 0)))
option.add_child(Node.u8("ojama_1", option_dict.get_int("ojama_1", 0)))
option.add_child(
Node.bool("forever_0", option_dict.get_bool("forever_0", False))
)
option.add_child(
Node.bool("forever_1", option_dict.get_bool("forever_1", False))
)
option.add_child(
Node.bool("full_setting", option_dict.get_bool("full_setting", False))
)
option.add_child(Node.bool("forever_0", option_dict.get_bool("forever_0", False)))
option.add_child(Node.bool("forever_1", option_dict.get_bool("forever_1", False)))
option.add_child(Node.bool("full_setting", option_dict.get_bool("full_setting", False)))
# Set up info
info = Node.void("info")
@ -824,12 +784,7 @@ class PopnMusicLapistoria(PopnMusicBase):
game_config = self.get_game_config()
if game_config.get_bool("force_unlock_songs"):
songs = {
song.id
for song in self.data.local.music.get_all_songs(
self.game, self.music_version
)
}
songs = {song.id for song in self.data.local.music.get_all_songs(self.game, self.music_version)}
for song in songs:
item = Node.void("item")
root.add_child(item)
@ -839,9 +794,7 @@ class PopnMusicLapistoria(PopnMusicBase):
item.add_child(Node.bool("is_new", False))
# Set up achievements
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for achievement in achievements:
if achievement.type == "item":
itemtype = achievement.data.get_int("type")
@ -919,9 +872,7 @@ class PopnMusicLapistoria(PopnMusicBase):
course.add_child(Node.s32("stage3_score", stage3_score))
course.add_child(Node.s32("stage4_score", stage4_score))
course.add_child(Node.s32("total_score", total_score))
course.add_child(
Node.s16("max_cmbo", max_combo)
) # Yes, it is misspelled.
course.add_child(Node.s16("max_cmbo", max_combo)) # Yes, it is misspelled.
course.add_child(Node.s16("play_cnt", play_cnt))
course.add_child(Node.s16("all_rank", 1)) # Unclear what this does.
@ -930,9 +881,7 @@ class PopnMusicLapistoria(PopnMusicBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
account = request.child("account")
@ -953,16 +902,12 @@ class PopnMusicLapistoria(PopnMusicBase):
newprofile.replace_int("sheet", config.child_value("sheet"))
newprofile.replace_int("category", config.child_value("category"))
newprofile.replace_int("sub_category", config.child_value("sub_category"))
newprofile.replace_int(
"chara_category", config.child_value("chara_category")
)
newprofile.replace_int("chara_category", config.child_value("chara_category"))
newprofile.replace_int("story_id", config.child_value("story_id"))
newprofile.replace_int("course_id", config.child_value("course_id"))
newprofile.replace_int("course_folder", config.child_value("course_folder"))
newprofile.replace_int("story_folder", config.child_value("story_folder"))
newprofile.replace_int(
"ms_banner_disp", config.child_value("ms_banner_disp")
)
newprofile.replace_int("ms_banner_disp", config.child_value("ms_banner_disp"))
newprofile.replace_int("ms_down_info", config.child_value("ms_down_info"))
newprofile.replace_int("ms_side_info", config.child_value("ms_side_info"))
newprofile.replace_int("ms_raise_type", config.child_value("ms_raise_type"))
@ -1088,9 +1033,7 @@ class PopnMusicLapistoria(PopnMusicBase):
root.add_child(Node.s32("option", profile.get_int("option", 0)))
root.add_child(Node.s8("result", 1))
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
if score.id > self.GAME_MAX_MUSIC_ID:
continue

View File

@ -126,9 +126,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
base.add_child(Node.u8("mode", profile.get_int("mode", 0)))
base.add_child(Node.s8("button", profile.get_int("button", 0)))
base.add_child(Node.s8("last_play_flag", profile.get_int("last_play_flag", -1)))
base.add_child(
Node.u8("medal_and_friend", profile.get_int("medal_and_friend", 0))
)
base.add_child(Node.u8("medal_and_friend", profile.get_int("medal_and_friend", 0)))
base.add_child(Node.s8("category", profile.get_int("category", -1)))
base.add_child(Node.s8("sub_category", profile.get_int("sub_category", -1)))
base.add_child(Node.s16("chara", profile.get_int("chara", -1)))
@ -141,15 +139,9 @@ class PopnMusicSunnyPark(PopnMusicBase):
base.add_child(Node.s32("option", profile.get_int("option", 0)))
base.add_child(Node.s16("music", profile.get_int("music", -1)))
base.add_child(Node.u16("ep", profile.get_int("ep", 0)))
base.add_child(
Node.s32_array("sp_color_flg", profile.get_int_array("sp_color_flg", 2))
)
base.add_child(Node.s32_array("sp_color_flg", profile.get_int_array("sp_color_flg", 2)))
base.add_child(Node.s32("read_news", profile.get_int("read_news", 0)))
base.add_child(
Node.s16(
"consecutive_days_coupon", profile.get_int("consecutive_days_coupon", 0)
)
)
base.add_child(Node.s16("consecutive_days_coupon", profile.get_int("consecutive_days_coupon", 0)))
base.add_child(Node.s8("staff", 0))
# These are probably from an old event, but if they aren't present and defaulted,
# then different songs show up in the Zoo event.
@ -159,9 +151,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
profile.get_int_array("gitadora_point", 3, [2000, 2000, 2000]),
)
)
base.add_child(
Node.u8("gitadora_select", profile.get_int("gitadora_select", 2))
)
base.add_child(Node.u8("gitadora_select", profile.get_int("gitadora_select", 2)))
# Statistics section and scores section
statistics = self.get_play_statistics(userid)
@ -183,18 +173,8 @@ class PopnMusicSunnyPark(PopnMusicBase):
rivalcount += 1
base.add_child(Node.u8("active_fr_num", rivalcount))
last_played = [
x[0]
for x in self.data.local.music.get_last_played(
self.game, self.music_version, userid, 3
)
]
most_played = [
x[0]
for x in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
]
last_played = [x[0] for x in self.data.local.music.get_last_played(self.game, self.music_version, userid, 3)]
most_played = [x[0] for x in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)]
while len(last_played) < 3:
last_played.append(-1)
while len(most_played) < 20:
@ -204,9 +184,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
clear_medal = [0] * self.GAME_MAX_MUSIC_ID
clear_medal_sub = [0] * self.GAME_MAX_MUSIC_ID
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
if score.id > self.GAME_MAX_MUSIC_ID:
continue
@ -222,9 +200,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
if score.data.get_int("medal") == self.PLAY_MEDAL_NO_PLAY:
continue
clear_medal[score.id] = clear_medal[
score.id
] | self.__format_medal_for_score(score)
clear_medal[score.id] = clear_medal[score.id] | self.__format_medal_for_score(score)
hiscore_index = (score.id * 4) + {
self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY_POSITION,
self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL_POSITION,
@ -234,15 +210,9 @@ class PopnMusicSunnyPark(PopnMusicBase):
hiscore_byte_pos = int((hiscore_index * 17) / 8)
hiscore_bit_pos = int((hiscore_index * 17) % 8)
hiscore_value = score.points << hiscore_bit_pos
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (
hiscore_value & 0xFF
)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[
hiscore_byte_pos + 1
] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[
hiscore_byte_pos + 2
] | ((hiscore_value >> 16) & 0xFF)
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF)
hiscore = bytes(hiscore_array)
@ -263,85 +233,37 @@ class PopnMusicSunnyPark(PopnMusicBase):
avatar.add_child(Node.u8("body", avatar_dict.get_int("body", 0)))
avatar.add_child(Node.u8("effect", avatar_dict.get_int("effect", 0)))
avatar.add_child(Node.u8("object", avatar_dict.get_int("object", 0)))
avatar.add_child(
Node.u8_array("comment", avatar_dict.get_int_array("comment", 2))
)
avatar.add_child(
Node.s32_array("get_hair", avatar_dict.get_int_array("get_hair", 2))
)
avatar.add_child(
Node.s32_array("get_face", avatar_dict.get_int_array("get_face", 2))
)
avatar.add_child(
Node.s32_array("get_body", avatar_dict.get_int_array("get_body", 2))
)
avatar.add_child(
Node.s32_array("get_effect", avatar_dict.get_int_array("get_effect", 2))
)
avatar.add_child(
Node.s32_array("get_object", avatar_dict.get_int_array("get_object", 2))
)
avatar.add_child(
Node.s32_array(
"get_comment_over", avatar_dict.get_int_array("get_comment_over", 3)
)
)
avatar.add_child(
Node.s32_array(
"get_comment_under", avatar_dict.get_int_array("get_comment_under", 3)
)
)
avatar.add_child(Node.u8_array("comment", avatar_dict.get_int_array("comment", 2)))
avatar.add_child(Node.s32_array("get_hair", avatar_dict.get_int_array("get_hair", 2)))
avatar.add_child(Node.s32_array("get_face", avatar_dict.get_int_array("get_face", 2)))
avatar.add_child(Node.s32_array("get_body", avatar_dict.get_int_array("get_body", 2)))
avatar.add_child(Node.s32_array("get_effect", avatar_dict.get_int_array("get_effect", 2)))
avatar.add_child(Node.s32_array("get_object", avatar_dict.get_int_array("get_object", 2)))
avatar.add_child(Node.s32_array("get_comment_over", avatar_dict.get_int_array("get_comment_over", 3)))
avatar.add_child(Node.s32_array("get_comment_under", avatar_dict.get_int_array("get_comment_under", 3)))
# Avatar add section
avatar_add_dict = profile.get_dict("avatar_add")
avatar_add = Node.void("avatar_add")
root.add_child(avatar_add)
avatar_add.add_child(
Node.s32_array("get_hair", avatar_add_dict.get_int_array("get_hair", 2))
)
avatar_add.add_child(
Node.s32_array("get_face", avatar_add_dict.get_int_array("get_face", 2))
)
avatar_add.add_child(
Node.s32_array("get_body", avatar_add_dict.get_int_array("get_body", 2))
)
avatar_add.add_child(
Node.s32_array("get_effect", avatar_add_dict.get_int_array("get_effect", 2))
)
avatar_add.add_child(
Node.s32_array("get_object", avatar_add_dict.get_int_array("get_object", 2))
)
avatar_add.add_child(
Node.s32_array(
"get_comment_over", avatar_add_dict.get_int_array("get_comment_over", 2)
)
)
avatar_add.add_child(Node.s32_array("get_hair", avatar_add_dict.get_int_array("get_hair", 2)))
avatar_add.add_child(Node.s32_array("get_face", avatar_add_dict.get_int_array("get_face", 2)))
avatar_add.add_child(Node.s32_array("get_body", avatar_add_dict.get_int_array("get_body", 2)))
avatar_add.add_child(Node.s32_array("get_effect", avatar_add_dict.get_int_array("get_effect", 2)))
avatar_add.add_child(Node.s32_array("get_object", avatar_add_dict.get_int_array("get_object", 2)))
avatar_add.add_child(Node.s32_array("get_comment_over", avatar_add_dict.get_int_array("get_comment_over", 2)))
avatar_add.add_child(
Node.s32_array(
"get_comment_under",
avatar_add_dict.get_int_array("get_comment_under", 2),
)
)
avatar_add.add_child(
Node.s32_array("new_hair", avatar_add_dict.get_int_array("new_hair", 2))
)
avatar_add.add_child(
Node.s32_array("new_face", avatar_add_dict.get_int_array("new_face", 2))
)
avatar_add.add_child(
Node.s32_array("new_body", avatar_add_dict.get_int_array("new_body", 2))
)
avatar_add.add_child(
Node.s32_array("new_effect", avatar_add_dict.get_int_array("new_effect", 2))
)
avatar_add.add_child(
Node.s32_array("new_object", avatar_add_dict.get_int_array("new_object", 2))
)
avatar_add.add_child(
Node.s32_array(
"new_comment_over", avatar_add_dict.get_int_array("new_comment_over", 2)
)
)
avatar_add.add_child(Node.s32_array("new_hair", avatar_add_dict.get_int_array("new_hair", 2)))
avatar_add.add_child(Node.s32_array("new_face", avatar_add_dict.get_int_array("new_face", 2)))
avatar_add.add_child(Node.s32_array("new_body", avatar_add_dict.get_int_array("new_body", 2)))
avatar_add.add_child(Node.s32_array("new_effect", avatar_add_dict.get_int_array("new_effect", 2)))
avatar_add.add_child(Node.s32_array("new_object", avatar_add_dict.get_int_array("new_object", 2)))
avatar_add.add_child(Node.s32_array("new_comment_over", avatar_add_dict.get_int_array("new_comment_over", 2)))
avatar_add.add_child(
Node.s32_array(
"new_comment_under",
@ -383,35 +305,17 @@ class PopnMusicSunnyPark(PopnMusicBase):
zoo = Node.void("zoo")
root.add_child(zoo)
zoo.add_child(Node.u16_array("point", zoo_dict.get_int_array("point", 5)))
zoo.add_child(
Node.s32_array("music_list", zoo_dict.get_int_array("music_list", 2))
)
zoo.add_child(
Node.s8_array(
"today_play_flag", zoo_dict.get_int_array("today_play_flag", 4)
)
)
zoo.add_child(Node.s32_array("music_list", zoo_dict.get_int_array("music_list", 2)))
zoo.add_child(Node.s8_array("today_play_flag", zoo_dict.get_int_array("today_play_flag", 4)))
# Pop'n Walker event
personal_event_dict = profile.get_dict("personal_event")
personal_event = Node.void("personal_event")
root.add_child(personal_event)
personal_event.add_child(
Node.s16_array("pos", personal_event_dict.get_int_array("pos", 2))
)
personal_event.add_child(
Node.s16("point", personal_event_dict.get_int("point"))
)
personal_event.add_child(
Node.u32_array(
"walk_data", personal_event_dict.get_int_array("walk_data", 128)
)
)
personal_event.add_child(
Node.u32_array(
"event_data", personal_event_dict.get_int_array("event_data", 4)
)
)
personal_event.add_child(Node.s16_array("pos", personal_event_dict.get_int_array("pos", 2)))
personal_event.add_child(Node.s16("point", personal_event_dict.get_int("point")))
personal_event.add_child(Node.u32_array("walk_data", personal_event_dict.get_int_array("walk_data", 128)))
personal_event.add_child(Node.u32_array("event_data", personal_event_dict.get_int_array("event_data", 4)))
# We don't support triple journey, so this is stubbed out.
triple = Node.void("triple_journey")
@ -465,9 +369,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
clear_medal = [0] * self.GAME_MAX_MUSIC_ID
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
if score.id > self.GAME_MAX_MUSIC_ID:
continue
@ -483,17 +385,13 @@ class PopnMusicSunnyPark(PopnMusicBase):
if score.data.get_int("medal") == self.PLAY_MEDAL_NO_PLAY:
continue
clear_medal[score.id] = clear_medal[
score.id
] | self.__format_medal_for_score(score)
clear_medal[score.id] = clear_medal[score.id] | self.__format_medal_for_score(score)
root.add_child(Node.u16_array("clear_medal", clear_medal))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
newprofile.replace_int("option", request.child_value("option"))
newprofile.replace_int("chara", request.child_value("chara"))
@ -505,25 +403,15 @@ class PopnMusicSunnyPark(PopnMusicBase):
newprofile.replace_int("category", request.child_value("category"))
newprofile.replace_int("sub_category", request.child_value("sub_category"))
newprofile.replace_int("chara_category", request.child_value("chara_category"))
newprofile.replace_int(
"medal_and_friend", request.child_value("medal_and_friend")
)
newprofile.replace_int("medal_and_friend", request.child_value("medal_and_friend"))
newprofile.replace_int("ep", request.child_value("ep"))
newprofile.replace_int_array(
"sp_color_flg", 2, request.child_value("sp_color_flg")
)
newprofile.replace_int_array("sp_color_flg", 2, request.child_value("sp_color_flg"))
newprofile.replace_int("read_news", request.child_value("read_news"))
newprofile.replace_int(
"consecutive_days_coupon", request.child_value("consecutive_days_coupon")
)
newprofile.replace_int("consecutive_days_coupon", request.child_value("consecutive_days_coupon"))
newprofile.replace_int("tutorial", request.child_value("tutorial"))
newprofile.replace_int("music_open_pt", request.child_value("music_open_pt"))
newprofile.replace_int_array(
"gitadora_point", 3, request.child_value("gitadora_point")
)
newprofile.replace_int(
"gitadora_select", request.child_value("gitadora_select")
)
newprofile.replace_int_array("gitadora_point", 3, request.child_value("gitadora_point"))
newprofile.replace_int("gitadora_select", request.child_value("gitadora_select"))
sp_node = request.child("sp_data")
if sp_node is not None:
@ -533,29 +421,17 @@ class PopnMusicSunnyPark(PopnMusicBase):
zoo_node = request.child("zoo")
if zoo_node is not None:
zoo_dict.replace_int_array("point", 5, zoo_node.child_value("point"))
zoo_dict.replace_int_array(
"music_list", 2, zoo_node.child_value("music_list")
)
zoo_dict.replace_int_array(
"today_play_flag", 4, zoo_node.child_value("today_play_flag")
)
zoo_dict.replace_int_array("music_list", 2, zoo_node.child_value("music_list"))
zoo_dict.replace_int_array("today_play_flag", 4, zoo_node.child_value("today_play_flag"))
newprofile.replace_dict("zoo", zoo_dict)
personal_event_dict = newprofile.get_dict("personal_event")
personal_event_node = request.child("personal_event")
if personal_event_node is not None:
personal_event_dict.replace_int_array(
"pos", 2, personal_event_node.child_value("pos")
)
personal_event_dict.replace_int(
"point", personal_event_node.child_value("point")
)
personal_event_dict.replace_int_array(
"walk_data", 128, personal_event_node.child_value("walk_data")
)
personal_event_dict.replace_int_array(
"event_data", 4, personal_event_node.child_value("event_data")
)
personal_event_dict.replace_int_array("pos", 2, personal_event_node.child_value("pos"))
personal_event_dict.replace_int("point", personal_event_node.child_value("point"))
personal_event_dict.replace_int_array("walk_data", 128, personal_event_node.child_value("walk_data"))
personal_event_dict.replace_int_array("event_data", 4, personal_event_node.child_value("event_data"))
newprofile.replace_dict("personal_event", personal_event_dict)
avatar_dict = newprofile.get_dict("avatar")
@ -568,65 +444,29 @@ class PopnMusicSunnyPark(PopnMusicBase):
avatar_dict.replace_int_array("get_hair", 2, request.child_value("get_hair"))
avatar_dict.replace_int_array("get_face", 2, request.child_value("get_face"))
avatar_dict.replace_int_array("get_body", 2, request.child_value("get_body"))
avatar_dict.replace_int_array(
"get_effect", 2, request.child_value("get_effect")
)
avatar_dict.replace_int_array(
"get_object", 2, request.child_value("get_object")
)
avatar_dict.replace_int_array(
"get_comment_over", 3, request.child_value("get_comment_over")
)
avatar_dict.replace_int_array(
"get_comment_under", 3, request.child_value("get_comment_under")
)
avatar_dict.replace_int_array("get_effect", 2, request.child_value("get_effect"))
avatar_dict.replace_int_array("get_object", 2, request.child_value("get_object"))
avatar_dict.replace_int_array("get_comment_over", 3, request.child_value("get_comment_over"))
avatar_dict.replace_int_array("get_comment_under", 3, request.child_value("get_comment_under"))
newprofile.replace_dict("avatar", avatar_dict)
avatar_add_dict = newprofile.get_dict("avatar_add")
avatar_add_node = request.child("avatar_add")
if avatar_add_node is not None:
avatar_add_dict.replace_int_array(
"get_hair", 2, avatar_add_node.child_value("get_hair")
)
avatar_add_dict.replace_int_array(
"get_face", 2, avatar_add_node.child_value("get_face")
)
avatar_add_dict.replace_int_array(
"get_body", 2, avatar_add_node.child_value("get_body")
)
avatar_add_dict.replace_int_array(
"get_effect", 2, avatar_add_node.child_value("get_effect")
)
avatar_add_dict.replace_int_array(
"get_object", 2, avatar_add_node.child_value("get_object")
)
avatar_add_dict.replace_int_array(
"get_comment_over", 2, avatar_add_node.child_value("get_comment_over")
)
avatar_add_dict.replace_int_array(
"get_comment_under", 2, avatar_add_node.child_value("get_comment_under")
)
avatar_add_dict.replace_int_array(
"new_hair", 2, avatar_add_node.child_value("new_hair")
)
avatar_add_dict.replace_int_array(
"new_face", 2, avatar_add_node.child_value("new_face")
)
avatar_add_dict.replace_int_array(
"new_body", 2, avatar_add_node.child_value("new_body")
)
avatar_add_dict.replace_int_array(
"new_effect", 2, avatar_add_node.child_value("new_effect")
)
avatar_add_dict.replace_int_array(
"new_object", 2, avatar_add_node.child_value("new_object")
)
avatar_add_dict.replace_int_array(
"new_comment_over", 2, avatar_add_node.child_value("new_comment_over")
)
avatar_add_dict.replace_int_array(
"new_comment_under", 2, avatar_add_node.child_value("new_comment_under")
)
avatar_add_dict.replace_int_array("get_hair", 2, avatar_add_node.child_value("get_hair"))
avatar_add_dict.replace_int_array("get_face", 2, avatar_add_node.child_value("get_face"))
avatar_add_dict.replace_int_array("get_body", 2, avatar_add_node.child_value("get_body"))
avatar_add_dict.replace_int_array("get_effect", 2, avatar_add_node.child_value("get_effect"))
avatar_add_dict.replace_int_array("get_object", 2, avatar_add_node.child_value("get_object"))
avatar_add_dict.replace_int_array("get_comment_over", 2, avatar_add_node.child_value("get_comment_over"))
avatar_add_dict.replace_int_array("get_comment_under", 2, avatar_add_node.child_value("get_comment_under"))
avatar_add_dict.replace_int_array("new_hair", 2, avatar_add_node.child_value("new_hair"))
avatar_add_dict.replace_int_array("new_face", 2, avatar_add_node.child_value("new_face"))
avatar_add_dict.replace_int_array("new_body", 2, avatar_add_node.child_value("new_body"))
avatar_add_dict.replace_int_array("new_effect", 2, avatar_add_node.child_value("new_effect"))
avatar_add_dict.replace_int_array("new_object", 2, avatar_add_node.child_value("new_object"))
avatar_add_dict.replace_int_array("new_comment_over", 2, avatar_add_node.child_value("new_comment_over"))
avatar_add_dict.replace_int_array("new_comment_under", 2, avatar_add_node.child_value("new_comment_under"))
newprofile.replace_dict("avatar_add", avatar_add_dict)
# Keep track of play statistics
@ -736,9 +576,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
machine = self.get_machine()
root = Node.void("playerdata")
root.add_child(
Node.s8("pref", machine.data.get_int("pref", self.get_machine_region()))
)
root.add_child(Node.s8("pref", machine.data.get_int("pref", self.get_machine_region())))
if refid is None:
root.add_child(Node.string("name", ""))
root.add_child(Node.s8("get_coupon_cnt", -1))
@ -766,9 +604,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
root.add_child(Node.u8("comment_2", 0))
return root
oldprofile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -783,12 +619,8 @@ class PopnMusicSunnyPark(PopnMusicBase):
root.add_child(Node.u8("body", avatar_dict.get_int("body", 0)))
root.add_child(Node.u8("effect", avatar_dict.get_int("effect", 0)))
root.add_child(Node.u8("object", avatar_dict.get_int("object", 0)))
root.add_child(
Node.u8("comment_1", avatar_dict.get_int_array("comment", 2)[0])
)
root.add_child(
Node.u8("comment_2", avatar_dict.get_int_array("comment", 2)[1])
)
root.add_child(Node.u8("comment_1", avatar_dict.get_int_array("comment", 2)[0]))
root.add_child(Node.u8("comment_2", avatar_dict.get_int_array("comment", 2)[1]))
return root
@ -819,9 +651,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
for rival in links[:2]:
rivalid = rival.other_userid
rivalprofile = profiles[rivalid]
scores = self.data.remote.music.get_scores(
self.game, self.music_version, rivalid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, rivalid)
# First, output general profile info.
friend = Node.void("friend")
@ -833,9 +663,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
# Set up some sane defaults.
friend.add_child(Node.string("name", rivalprofile.get_str("name", "なし")))
friend.add_child(
Node.string("g_pm_id", ID.format_extid(rivalprofile.extid))
)
friend.add_child(Node.string("g_pm_id", ID.format_extid(rivalprofile.extid)))
friend.add_child(Node.s16("chara", rivalprofile.get_int("chara", -1)))
# Set up player avatar.
@ -845,9 +673,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
friend.add_child(Node.u8("body", avatar_dict.get_int("body", 0)))
friend.add_child(Node.u8("effect", avatar_dict.get_int("effect", 0)))
friend.add_child(Node.u8("object", avatar_dict.get_int("object", 0)))
friend.add_child(
Node.u8_array("comment", avatar_dict.get_int_array("comment", 2))
)
friend.add_child(Node.u8_array("comment", avatar_dict.get_int_array("comment", 2)))
# Perform hiscore/medal conversion.
hiscore_array = [0] * int((((self.GAME_MAX_MUSIC_ID * 4) * 17) + 7) / 8)
@ -867,9 +693,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
if score.data.get_int("medal") == self.PLAY_MEDAL_NO_PLAY:
continue
clear_medal[score.id] = clear_medal[
score.id
] | self.__format_medal_for_score(score)
clear_medal[score.id] = clear_medal[score.id] | self.__format_medal_for_score(score)
hiscore_index = (score.id * 4) + {
self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY_POSITION,
self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL_POSITION,
@ -879,15 +703,13 @@ class PopnMusicSunnyPark(PopnMusicBase):
hiscore_byte_pos = int((hiscore_index * 17) / 8)
hiscore_bit_pos = int((hiscore_index * 17) % 8)
hiscore_value = score.points << hiscore_bit_pos
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (
hiscore_value & 0xFF
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | (
(hiscore_value >> 8) & 0xFF
)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | (
(hiscore_value >> 16) & 0xFF
)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[
hiscore_byte_pos + 1
] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[
hiscore_byte_pos + 2
] | ((hiscore_value >> 16) & 0xFF)
hiscore = bytes(hiscore_array)
friend.add_child(Node.u16_array("clear_medal", clear_medal))

View File

@ -227,9 +227,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
# Format Scores
hiscore_array = [0] * int((((self.GAME_MAX_MUSIC_ID * 7) * 17) + 7) / 8)
scores = self.data.remote.music.get_scores(
self.game, self.music_version, userid
)
scores = self.data.remote.music.get_scores(self.game, self.music_version, userid)
for score in scores:
if score.id > self.GAME_MAX_MUSIC_ID:
continue
@ -245,12 +243,8 @@ class PopnMusicTuneStreet(PopnMusicBase):
flags = self.__format_flags_for_score(score)
flags_index = score.id * 2
binary_profile[108 + flags_index] = binary_profile[108 + flags_index] | (
flags & 0xFF
)
binary_profile[109 + flags_index] = binary_profile[109 + flags_index] | (
(flags >> 8) & 0xFF
)
binary_profile[108 + flags_index] = binary_profile[108 + flags_index] | (flags & 0xFF)
binary_profile[109 + flags_index] = binary_profile[109 + flags_index] | ((flags >> 8) & 0xFF)
if score.chart in [
self.CHART_TYPE_ENJOY_5_BUTTON,
@ -272,23 +266,12 @@ class PopnMusicTuneStreet(PopnMusicBase):
hiscore_byte_pos = int((hiscore_index * 17) / 8)
hiscore_bit_pos = int((hiscore_index * 17) % 8)
hiscore_value = score.points << hiscore_bit_pos
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (
hiscore_value & 0xFF
)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[
hiscore_byte_pos + 1
] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[
hiscore_byte_pos + 2
] | ((hiscore_value >> 16) & 0xFF)
hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF)
hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF)
hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF)
# Format most played
most_played = [
x[0]
for x in self.data.local.music.get_most_played(
self.game, self.music_version, userid, 20
)
]
most_played = [x[0] for x in self.data.local.music.get_most_played(self.game, self.music_version, userid, 20)]
while len(most_played) < 20:
most_played.append(-1)
profile_pos = 68
@ -322,9 +305,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
bought_flg = town.get_int_array("bought_flg", 3)
game_config = self.get_game_config()
force_unlock_songs = game_config.get_bool("force_unlock_songs")
force_unlock_customizations = game_config.get_bool(
"force_unlock_customizations"
)
force_unlock_customizations = game_config.get_bool("force_unlock_customizations")
if force_unlock_songs:
bought_flg[0] = 0xFFFFFFFF
@ -390,9 +371,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Extract the playmode, important for scores later
@ -404,13 +383,9 @@ class PopnMusicTuneStreet(PopnMusicBase):
if "option" in request.attributes:
newprofile.replace_int("option", int(request.attribute("option")))
if "last_play_flag" in request.attributes:
newprofile.replace_int(
"last_play_flag", int(request.attribute("last_play_flag"))
)
newprofile.replace_int("last_play_flag", int(request.attribute("last_play_flag")))
if "medal_and_friend" in request.attributes:
newprofile.replace_int(
"medal_and_friend", int(request.attribute("medal_and_friend"))
)
newprofile.replace_int("medal_and_friend", int(request.attribute("medal_and_friend")))
if "music_num" in request.attributes:
newprofile.replace_int("music", int(request.attribute("music_num")))
if "sheet_num" in request.attributes:
@ -418,23 +393,15 @@ class PopnMusicTuneStreet(PopnMusicBase):
if "category_num" in request.attributes:
newprofile.replace_int("category", int(request.attribute("category_num")))
if "read_news_no_max" in request.attributes:
newprofile.replace_int(
"read_news", int(request.attribute("read_news_no_max"))
)
newprofile.replace_int("read_news", int(request.attribute("read_news_no_max")))
if "jubeat_collabo" in request.attributes:
newprofile.replace_int(
"jubeat_collabo", int(request.attribute("jubeat_collabo"))
)
newprofile.replace_int("jubeat_collabo", int(request.attribute("jubeat_collabo")))
if "norma_point" in request.attributes:
newprofile.replace_int("norma_point", int(request.attribute("norma_point")))
if "skin_tex_note" in request.attributes:
newprofile.replace_int(
"skin_tex_note", int(request.attribute("skin_tex_note"))
)
newprofile.replace_int("skin_tex_note", int(request.attribute("skin_tex_note")))
if "skin_tex_cmn" in request.attributes:
newprofile.replace_int(
"skin_tex_cmn", int(request.attribute("skin_tex_cmn"))
)
newprofile.replace_int("skin_tex_cmn", int(request.attribute("skin_tex_cmn")))
if "skin_sd_bgm" in request.attributes:
newprofile.replace_int("skin_sd_bgm", int(request.attribute("skin_sd_bgm")))
if "skin_sd_se" in request.attributes:
@ -532,19 +499,13 @@ class PopnMusicTuneStreet(PopnMusicBase):
if "play_type" in townnode.attributes:
town.replace_int("play_type", int(townnode.attribute("play_type")))
if "base" in townnode.attributes:
town.replace_int_array(
"base", 4, [int(x) for x in townnode.attribute("base").split(",")]
)
town.replace_int_array("base", 4, [int(x) for x in townnode.attribute("base").split(",")])
if "bought_flg" in townnode.attributes:
bought_array = [
int(x) for x in townnode.attribute("bought_flg").split(",")
]
bought_array = [int(x) for x in townnode.attribute("bought_flg").split(",")]
if len(bought_array) == 3:
game_config = self.get_game_config()
force_unlock_songs = game_config.get_bool("force_unlock_songs")
force_unlock_customizations = game_config.get_bool(
"force_unlock_customizations"
)
force_unlock_customizations = game_config.get_bool("force_unlock_customizations")
old_bought_array = town.get_int_array("bought_flg", 3)
if force_unlock_songs:
@ -578,10 +539,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
town.replace_int_array(
f"building_{bid}",
8,
[
int(x)
for x in townnode.attribute(f"building_{bid}").split(",")
],
[int(x) for x in townnode.attribute(f"building_{bid}").split(",")],
)
newprofile.replace_dict("town", town)
@ -594,23 +552,17 @@ class PopnMusicTuneStreet(PopnMusicBase):
town_phase = game_config.get_int("town_phase")
root = Node.void("game")
root.set_attribute(
"game_phase", str(game_phase)
) # Phase unlocks, for song availability.
root.set_attribute("game_phase", str(game_phase)) # Phase unlocks, for song availability.
root.set_attribute("boss_battle_point", "1")
root.set_attribute("boss_diff", "100,100,100,100,100,100,100,100,100,100")
root.set_attribute("card_phase", "3")
root.set_attribute(
"event_phase", str(town_phase)
) # Town mode, for the main event.
root.set_attribute("event_phase", str(town_phase)) # Town mode, for the main event.
root.set_attribute("gfdm_phase", "2")
root.set_attribute("ir_phase", "14")
root.set_attribute("jubeat_phase", "2")
root.set_attribute("local_matching_enable", "1")
root.set_attribute("matching_sec", "120")
root.set_attribute(
"netvs_phase", "0"
) # Net taisen mode phase, maximum 18 (no lobby support).
root.set_attribute("netvs_phase", "0") # Net taisen mode phase, maximum 18 (no lobby support).
return root
def handle_game_active_request(self, request: Node) -> Node:
@ -696,9 +648,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
if userid is None:
return root
oldprofile = self.get_profile(userid) or Profile(
self.game, self.version, refid, 0
)
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:

View File

@ -26,22 +26,14 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
CLEAR_TYPE_NO_PLAY: Final[int] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_NO_PLAY
CLEAR_TYPE_FAILED: Final[int] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_FAILED
CLEAR_TYPE_CLEARED: Final[int] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_CLEARED
CLEAR_TYPE_HARD_CLEARED: Final[
int
] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_HARD_CLEARED
CLEAR_TYPE_S_HARD_CLEARED: Final[
int
] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_S_HARD_CLEARED
CLEAR_TYPE_HARD_CLEARED: Final[int] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_HARD_CLEARED
CLEAR_TYPE_S_HARD_CLEARED: Final[int] = DBConstants.REFLEC_BEAT_CLEAR_TYPE_S_HARD_CLEARED
# Combo types, as saved/loaded from the DB
COMBO_TYPE_NONE: Final[int] = DBConstants.REFLEC_BEAT_COMBO_TYPE_NONE
COMBO_TYPE_ALMOST_COMBO: Final[
int
] = DBConstants.REFLEC_BEAT_COMBO_TYPE_ALMOST_COMBO
COMBO_TYPE_ALMOST_COMBO: Final[int] = DBConstants.REFLEC_BEAT_COMBO_TYPE_ALMOST_COMBO
COMBO_TYPE_FULL_COMBO: Final[int] = DBConstants.REFLEC_BEAT_COMBO_TYPE_FULL_COMBO
COMBO_TYPE_FULL_COMBO_ALL_JUST: Final[
int
] = DBConstants.REFLEC_BEAT_COMBO_TYPE_FULL_COMBO_ALL_JUST
COMBO_TYPE_FULL_COMBO_ALL_JUST: Final[int] = DBConstants.REFLEC_BEAT_COMBO_TYPE_FULL_COMBO_ALL_JUST
# Return the local2 and lobby2 service so that matching will work on newer
# Reflec Beat games.
@ -64,9 +56,7 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("pc")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -94,9 +84,7 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
return None
return self.format_profile(userid, profile)
def put_profile_by_refid(
self, refid: Optional[str], request: Node
) -> Optional[Profile]:
def put_profile_by_refid(self, refid: Optional[str], request: Node) -> Optional[Profile]:
"""
Given a RefID and a request node, unformat the profile and save it.
"""
@ -192,17 +180,13 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Replace clear type with highest value and timestamps
if clear_type >= scoredata.get_int("clear_type"):
scoredata.replace_int(
"clear_type", max(scoredata.get_int("clear_type"), clear_type)
)
scoredata.replace_int("clear_type", max(scoredata.get_int("clear_type"), clear_type))
scoredata.replace_int("best_clear_type_time", now)
history.replace_int("clear_type", clear_type)
# Replace combo type with highest value and timestamps
if combo_type >= scoredata.get_int("combo_type"):
scoredata.replace_int(
"combo_type", max(scoredata.get_int("combo_type"), combo_type)
)
scoredata.replace_int("combo_type", max(scoredata.get_int("combo_type"), combo_type))
scoredata.replace_int("best_clear_type_time", now)
history.replace_int("combo_type", combo_type)
@ -238,10 +222,7 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Update the miss count with timestamps, either if it was lowered, or if the old value was blank.
# If the new value is -1 (we didn't get a miss count this time), never update the old value.
if miss_count >= 0:
if (
miss_count <= scoredata.get_int("miss_count", 999999)
or scoredata.get_int("miss_count") == -1
):
if miss_count <= scoredata.get_int("miss_count", 999999) or scoredata.get_int("miss_count") == -1:
scoredata.replace_int(
"miss_count",
min(scoredata.get_int("miss_count", 999999), miss_count),

View File

@ -157,9 +157,7 @@ class ReflecBeatColette(ReflecBeatBase):
ranking = Node.void("ranking")
root.add_child(ranking)
def add_hitchart(
name: str, start: int, end: int, hitchart: List[Tuple[int, int]]
) -> None:
def add_hitchart(name: str, start: int, end: int, hitchart: List[Tuple[int, int]]) -> None:
base = Node.void(name)
ranking.add_child(base)
base.add_child(Node.s32("bt", start))
@ -207,18 +205,12 @@ class ReflecBeatColette(ReflecBeatBase):
comments = [
achievement
for achievement in self.data.local.user.get_all_time_based_achievements(
self.game, self.version
)
for achievement in self.data.local.user.get_all_time_based_achievements(self.game, self.version)
if achievement[1].type == "puzzle_comment"
]
comments.sort(key=lambda x: x[1].timestamp, reverse=True)
favorites = [comment for comment in comments if comment[0] == userid]
teamcomments = [
comment
for comment in comments
if comment[1].data.get_int("teamid") == teamid
]
teamcomments = [comment for comment in comments if comment[1].data.get_int("teamid") == teamid]
# Cap all comment blocks to the limit
if limit >= 0:
@ -232,9 +224,7 @@ class ReflecBeatColette(ReflecBeatBase):
comment.add_child(Node.s32("time", Time.now()))
# Mapping of profiles to userIDs
uid_mapping = {
uid: prof for (uid, prof) in self.get_any_profiles([c[0] for c in comments])
}
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
uid_mapping[UserID(0)] = Profile(
@ -622,9 +612,7 @@ class ReflecBeatColette(ReflecBeatBase):
)
if lobby is not None:
self.data.local.lobby.destroy_lobby(lobby.get_int("id"))
self.data.local.lobby.destroy_play_session_info(
self.game, self.version, userid
)
self.data.local.lobby.destroy_play_session_info(self.game, self.version, userid)
return Node.void("player")
@ -637,9 +625,7 @@ class ReflecBeatColette(ReflecBeatBase):
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
)
scores = self.data.remote.music.get_scores(previous_version.game, previous_version.version, userid)
else:
profile = None
@ -715,9 +701,7 @@ class ReflecBeatColette(ReflecBeatBase):
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
scores = self.data.remote.music.get_scores(self.game, self.version, userid)
links = self.data.local.user.get_links(self.game, self.version, userid)
root = Node.void("player")
@ -749,9 +733,7 @@ class ReflecBeatColette(ReflecBeatBase):
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_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))
@ -793,73 +775,41 @@ class ReflecBeatColette(ReflecBeatBase):
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))
)
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)))
# Player external config
config = Node.void("config")
configdict = profile.get_dict("config")
pdata.add_child(config)
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.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.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("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.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"))
)
config.add_child(Node.bool("is_link_twitter", configdict.get_bool("is_link_twitter")))
# Stamps
stamp = Node.void("stamp")
stampdict = profile.get_dict("stamp")
pdata.add_child(stamp)
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.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")))
@ -993,73 +943,47 @@ class ReflecBeatColette(ReflecBeatBase):
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("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")))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = oldprofile.clone()
newprofile.replace_int(
"lid", ID.parse_machine_id(request.child_value("pdata/account/lid"))
)
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")
)
newprofile.replace_int_array("hidden_param", 50, request.child_value("pdata/base/hidden_param"))
configdict = newprofile.get_dict("config")
config = request.child("pdata/config")
if config:
configdict.replace_int("msel_bgm", config.child_value("msel_bgm"))
configdict.replace_int(
"narrowdown_type", config.child_value("narrowdown_type")
)
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_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("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("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_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")
)
configdict.replace_bool("is_link_twitter", config.child_value("is_link_twitter"))
newprofile.replace_dict("config", configdict)
customdict = newprofile.get_dict("custom")

View File

@ -131,9 +131,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
profile = self.get_profile(userid)
info = self.data.local.lobby.get_play_session_info(
self.game, self.version, userid
)
info = self.data.local.lobby.get_play_session_info(self.game, self.version, userid)
if profile is None or info is None:
return root
@ -214,9 +212,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
continue
profile = self.get_profile(user)
info = self.data.local.lobby.get_play_session_info(
self.game, self.version, userid
)
info = self.data.local.lobby.get_play_session_info(self.game, self.version, userid)
if profile is None or info is None:
# No profile info, don't return this lobby
return root
@ -306,16 +302,11 @@ class ReflecBeatGroovin(ReflecBeatBase):
)
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
lids = [
machine.id
for machine in self.data.local.machine.get_all_machines(machine.arcade)
]
lids = [machine.id for machine in self.data.local.machine.get_all_machines(machine.arcade)]
else:
lids = [machine.id]
relevant_profiles = [
profile for profile in all_profiles if profile[1].get_int("lid", -1) in lids
]
relevant_profiles = [profile for profile in all_profiles if profile[1].get_int("lid", -1) in lids]
for rootnode, timeoffset in [
(today, 0),
@ -343,10 +334,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
scores_by_user[userid][attempt.id][attempt.chart] = attempt
else:
# If this attempt is better than the stored one, replace it
if (
scores_by_user[userid][attempt.id][attempt.chart].points
< attempt.points
):
if scores_by_user[userid][attempt.id][attempt.chart].points < attempt.points:
scores_by_user[userid][attempt.id][attempt.chart] = attempt
# Calculate points earned by user in the day
@ -355,33 +343,20 @@ class ReflecBeatGroovin(ReflecBeatBase):
points_by_user[userid] = 0
for mid in scores_by_user[userid]:
for chart in scores_by_user[userid][mid]:
points_by_user[userid] = (
points_by_user[userid]
+ scores_by_user[userid][mid][chart].points
)
points_by_user[userid] = points_by_user[userid] + scores_by_user[userid][mid][chart].points
# Output that day's earned points
for userid, profile in relevant_profiles:
data = Node.void("data")
rootnode.add_child(data)
data.add_child(
Node.s16(
"day_id", int((Time.now() - timeoffset) / Time.SECONDS_IN_DAY)
)
)
data.add_child(Node.s16("day_id", int((Time.now() - timeoffset) / Time.SECONDS_IN_DAY)))
data.add_child(Node.s32("user_id", profile.extid))
data.add_child(
Node.s16("icon_id", profile.get_dict("config").get_int("icon_id"))
)
data.add_child(
Node.s16("point", min(points_by_user.get(userid, 0), 32767))
)
data.add_child(Node.s16("icon_id", profile.get_dict("config").get_int("icon_id")))
data.add_child(Node.s16("point", min(points_by_user.get(userid, 0), 32767)))
data.add_child(Node.s32("update_time", Time.now()))
data.add_child(Node.string("name", profile.get_str("name")))
rootnode.add_child(
Node.s32("timestamp", Time.beginning_of_today() - timeoffset)
)
rootnode.add_child(Node.s32("timestamp", Time.beginning_of_today() - timeoffset))
def handle_info_rb4common_request(self, request: Node) -> Node:
root = Node.void("info")
@ -398,9 +373,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
ranking = Node.void("ranking")
root.add_child(ranking)
def add_hitchart(
name: str, start: int, end: int, hitchart: List[Tuple[int, int]]
) -> None:
def add_hitchart(name: str, start: int, end: int, hitchart: List[Tuple[int, int]]) -> None:
base = Node.void(name)
ranking.add_child(base)
base.add_child(Node.s32("bt", start))
@ -483,17 +456,11 @@ class ReflecBeatGroovin(ReflecBeatBase):
data.add_child(
Node.s8(
"clear_type",
self.__db_to_game_clear_type(
score.data.get_int("clear_type")
),
self.__db_to_game_clear_type(score.data.get_int("clear_type")),
)
)
data.add_child(Node.s32("user_id", profile.extid))
data.add_child(
Node.s16(
"icon_id", profile.get_dict("config").get_int("icon_id")
)
)
data.add_child(Node.s16("icon_id", profile.get_dict("config").get_int("icon_id")))
data.add_child(Node.s32("score", score.points))
data.add_child(Node.s32("time", score.timestamp))
data.add_child(Node.string("name", profile.get_str("name")))
@ -508,16 +475,12 @@ class ReflecBeatGroovin(ReflecBeatBase):
comments = [
achievement
for achievement in self.data.local.user.get_all_time_based_achievements(
self.game, self.version
)
for achievement in self.data.local.user.get_all_time_based_achievements(self.game, self.version)
if achievement[1].type == "puzzle_comment"
]
comments.sort(key=lambda x: x[1].timestamp, reverse=True)
favorites = [comment for comment in comments if comment[0] == userid]
locationcomments = [
comment for comment in comments if comment[1].data.get_int("locid") == locid
]
locationcomments = [comment for comment in comments if comment[1].data.get_int("locid") == locid]
# Cap all comment blocks to the limit
if limit >= 0:
@ -531,9 +494,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
comment.add_child(Node.s32("time", Time.now()))
# Mapping of profiles to userIDs
uid_mapping = {
uid: prof for (uid, prof) in self.get_any_profiles([c[0] for c in comments])
}
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
uid_mapping[UserID(0)] = Profile(
@ -552,9 +513,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
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.string("lid", ID.format_machine_id(ach.data.get_int("locid")))
)
cmnt.add_child(Node.string("lid", ID.format_machine_id(ach.data.get_int("locid"))))
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")))
@ -654,9 +613,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
)
if lobby is not None:
self.data.local.lobby.destroy_lobby(lobby.get_int("id"))
self.data.local.lobby.destroy_play_session_info(
self.game, self.version, userid
)
self.data.local.lobby.destroy_play_session_info(self.game, self.version, userid)
return Node.void("player")
@ -664,9 +621,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
extid = request.child_value("user_id")
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
else:
achievements = []
@ -714,25 +669,18 @@ class ReflecBeatGroovin(ReflecBeatBase):
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"))
)
)
rec.add_child(Node.s8("ct", self.__db_to_game_clear_type(score.data.get_int("clear_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("ms", score.data.get_int("miss_count")))
rec.add_child(
Node.s16(
"param",
self.__db_to_game_combo_type(score.data.get_int("combo_type"))
+ score.data.get_int("param"),
self.__db_to_game_combo_type(score.data.get_int("combo_type")) + score.data.get_int("param"),
)
)
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("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")))
@ -748,9 +696,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
score = None
profile = None
else:
score = self.data.remote.music.get_score(
self.game, self.version, userid, songid, chart
)
score = self.data.remote.music.get_score(self.game, self.version, userid, songid, chart)
profile = self.get_any_profile(userid)
root = Node.void("player")
@ -762,9 +708,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
player_select_score.add_child(Node.string("name", profile.get_str("name")))
player_select_score.add_child(Node.s32("m_score", score.points))
player_select_score.add_child(Node.s32("m_scoreTime", score.timestamp))
player_select_score.add_child(
Node.s16("m_iconID", profile.get_dict("config").get_int("icon_id"))
)
player_select_score.add_child(Node.s16("m_iconID", profile.get_dict("config").get_int("icon_id")))
return root
def handle_player_rbsvLinkageSave_request(self, request: Node) -> Node:
@ -800,11 +744,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
all_songs = self.data.local.music.get_all_songs(self.game, self.version)
# Figure out what song IDs are new
new_songs = {
song.id
for song in all_songs
if song.data.get_int("folder", 0) == self.version
}
new_songs = {song.id for song in all_songs if song.data.get_int("folder", 0) == self.version}
# Now grab all participating users that had scores
all_users = {userid for (userid, score) in all_scores}
@ -815,68 +755,40 @@ class ReflecBeatGroovin(ReflecBeatBase):
userid: [
score
for (uid, score) in all_scores
if uid == userid
and score.data.get_int("clear_type") >= self.CLEAR_TYPE_CLEARED
if uid == userid and score.data.get_int("clear_type") >= self.CLEAR_TYPE_CLEARED
]
for userid in all_users
}
# Now, sum up the scores into the six categories that the game expects.
total_scores = sorted(
[
sum([score.points for score in scores])
for userid, scores in scores_by_user.items()
],
[sum([score.points for score in scores]) for userid, scores in scores_by_user.items()],
reverse=True,
)
basic_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_BASIC
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_BASIC])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
medium_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_MEDIUM
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_MEDIUM])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
hard_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_HARD
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_HARD])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
special_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_SPECIAL
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_SPECIAL])
for userid, scores in scores_by_user.items()
],
reverse=True,
@ -943,9 +855,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
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
)
scores = self.data.remote.music.get_scores(previous_version.game, previous_version.version, userid)
else:
profile = None
@ -997,15 +907,9 @@ class ReflecBeatGroovin(ReflecBeatBase):
mrec.add_child(Node.s16("ms", score.data.get_int("miss_count")))
mrec.add_child(Node.u16("ver", 0))
mrec.add_child(Node.s32("bst", score.timestamp))
mrec.add_child(
Node.s32("bat", score.data.get_int("best_achievement_rate_time"))
)
mrec.add_child(
Node.s32("bct", score.data.get_int("best_clear_type_time"))
)
mrec.add_child(
Node.s32("bmt", score.data.get_int("best_miss_count_time"))
)
mrec.add_child(Node.s32("bat", score.data.get_int("best_achievement_rate_time")))
mrec.add_child(Node.s32("bct", score.data.get_int("best_clear_type_time")))
mrec.add_child(Node.s32("bmt", score.data.get_int("best_miss_count_time")))
return root
@ -1023,9 +927,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
links = self.data.local.user.get_links(self.game, self.version, userid)
root = Node.void("player")
pdata = Node.void("pdata")
@ -1086,9 +988,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
rprofile = self.get_profile(link.other_userid)
if rprofile is None:
continue
lobbyinfo = self.data.local.lobby.get_play_session_info(
self.game, self.version, link.other_userid
)
lobbyinfo = self.data.local.lobby.get_play_session_info(self.game, self.version, link.other_userid)
if lobbyinfo is None:
lobbyinfo = ValidatedDict()
@ -1114,9 +1014,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
stamp = Node.void("stamp")
stampdict = profile.get_dict("stamp")
pdata.add_child(stamp)
stamp.add_child(
Node.s32_array("stmpcnt", stampdict.get_int_array("stmpcnt", 10))
)
stamp.add_child(Node.s32_array("stmpcnt", stampdict.get_int_array("stmpcnt", 10)))
stamp.add_child(Node.s64("area", stampdict.get_int("area")))
stamp.add_child(Node.s64("prfvst", stampdict.get_int("prfvst")))
@ -1125,48 +1023,26 @@ class ReflecBeatGroovin(ReflecBeatBase):
config = Node.void("config")
pdata.add_child(config)
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.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.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("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.u64("custom_folder_work", configdict.get_int("custom_folder_work"))
)
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.u64("custom_folder_work", configdict.get_int("custom_folder_work")))
config.add_child(Node.u8("folder_type", configdict.get_int("folder_type")))
config.add_child(
Node.u8("folder_lamp_type", configdict.get_int("folder_lamp_type"))
)
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"))
)
config.add_child(Node.bool("is_link_twitter", configdict.get_bool("is_link_twitter")))
# Customizations
customdict = profile.get_dict("custom")
@ -1186,16 +1062,10 @@ class ReflecBeatGroovin(ReflecBeatBase):
custom.add_child(Node.u8("st_rnd", customdict.get_int("st_rnd")))
custom.add_child(Node.u8("st_hazard", customdict.get_int("st_hazard")))
custom.add_child(Node.u8("st_clr_cond", customdict.get_int("st_clr_cond")))
custom.add_child(
Node.s16_array("schat_0", customdict.get_int_array("schat_0", 10))
)
custom.add_child(
Node.s16_array("schat_1", customdict.get_int_array("schat_1", 10))
)
custom.add_child(Node.s16_array("schat_0", customdict.get_int_array("schat_0", 10)))
custom.add_child(Node.s16_array("schat_1", customdict.get_int_array("schat_1", 10)))
custom.add_child(Node.u8("cheer_voice", customdict.get_int("cheer_voice")))
custom.add_child(
Node.u8("same_time_note_disp", customdict.get_int("same_time_note_disp"))
)
custom.add_child(Node.u8("same_time_note_disp", customdict.get_int("same_time_note_disp")))
# Unlocks
released = Node.void("released")
@ -1249,9 +1119,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
info.add_child(Node.u8("type", announcementtype))
info.add_child(Node.u16("id", announcement.id))
info.add_child(Node.u16("param", announcement.data.get_int("param")))
info.add_child(
Node.bool("bneedannounce", announcement.data.get_bool("need"))
)
info.add_child(Node.bool("bneedannounce", announcement.data.get_bool("need")))
# Dojo ranking return
dojo = Node.void("dojo")
@ -1268,12 +1136,8 @@ class ReflecBeatGroovin(ReflecBeatBase):
rec.add_child(Node.s32("total_ar", entry.data.get_int("ar")))
rec.add_child(Node.s32("total_score", entry.data.get_int("score")))
rec.add_child(Node.s32("play_count", entry.data.get_int("plays")))
rec.add_child(
Node.s32("last_play_time", entry.data.get_int("play_timestamp"))
)
rec.add_child(
Node.s32("record_update_time", entry.data.get_int("record_timestamp"))
)
rec.add_child(Node.s32("last_play_time", entry.data.get_int("play_timestamp")))
rec.add_child(Node.s32("record_update_time", entry.data.get_int("record_timestamp")))
rec.add_child(Node.s32("rank", 0))
# Player Parameters
@ -1289,9 +1153,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
player_param.add_child(itemnode)
itemnode.add_child(Node.s32("type", itemtype))
itemnode.add_child(Node.s32("bank", param.id))
itemnode.add_child(
Node.s32_array("data", param.data.get_int_array("data", 256))
)
itemnode.add_child(Node.s32_array("data", param.data.get_int_array("data", 256)))
# Shop score for players
self.__add_shop_score(pdata)
@ -1349,16 +1211,12 @@ class ReflecBeatGroovin(ReflecBeatBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = oldprofile.clone()
# Save base player profile info
newprofile.replace_int(
"lid", ID.parse_machine_id(request.child_value("pdata/account/lid"))
)
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"))
@ -1442,46 +1300,26 @@ class ReflecBeatGroovin(ReflecBeatBase):
config = request.child("pdata/config")
if config:
configdict.replace_int("msel_bgm", config.child_value("msel_bgm"))
configdict.replace_int(
"narrowdown_type", config.child_value("narrowdown_type")
)
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_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("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("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(
"custom_folder_work", config.child_value("custom_folder_work")
)
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("custom_folder_work", config.child_value("custom_folder_work"))
configdict.replace_int("folder_type", config.child_value("folder_type"))
configdict.replace_int(
"folder_lamp_type", config.child_value("folder_lamp_type")
)
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")
)
configdict.replace_bool("is_link_twitter", config.child_value("is_link_twitter"))
newprofile.replace_dict("config", configdict)
# Save player custom settings
@ -1505,9 +1343,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
customdict.replace_int_array("schat_0", 10, custom.child_value("schat_0"))
customdict.replace_int_array("schat_1", 10, custom.child_value("schat_1"))
customdict.replace_int("cheer_voice", custom.child_value("cheer_voice"))
customdict.replace_int(
"same_time_note_disp", custom.child_value("same_time_note_disp")
)
customdict.replace_int("same_time_note_disp", custom.child_value("same_time_note_disp"))
newprofile.replace_dict("custom", customdict)
# Save player parameter info
@ -1543,9 +1379,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
# I assume this is copypasta, but I want to be sure
extid = child.child_value("user_id")
if extid != newprofile.extid:
raise Exception(
f"Unexpected user ID, got {extid} expecting {newprofile.extid}"
)
raise Exception(f"Unexpected user ID, got {extid} expecting {newprofile.extid}")
episode_type = child.child_value("type")
episode_value0 = child.child_value("value0")
@ -1622,9 +1456,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
continue
extid = child.child_value("id")
other_userid = self.data.remote.user.from_extid(
self.game, self.version, extid
)
other_userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if other_userid is None:
continue

View File

@ -176,15 +176,11 @@ class ReflecBeatLimelight(ReflecBeatBase):
comments = [
achievement
for achievement in self.data.local.user.get_all_time_based_achievements(
self.game, self.version
)
for achievement in self.data.local.user.get_all_time_based_achievements(self.game, self.version)
if achievement[1].type == "puzzle_comment"
]
comments.sort(key=lambda x: x[1].timestamp, reverse=True)
statuses = self.data.local.lobby.get_all_play_session_infos(
self.game, self.version
)
statuses = self.data.local.lobby.get_all_play_session_infos(self.game, self.version)
statuses.sort(key=lambda x: x[1]["time"], reverse=True)
# Cap all comment blocks to the limit
@ -194,10 +190,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
# Mapping of profiles to userIDs
uid_mapping = {
uid: prof
for (uid, prof) in self.get_any_profiles(
[c[0] for c in comments] + [s[0] for s in statuses]
)
uid: prof for (uid, prof) in self.get_any_profiles([c[0] for c in comments] + [s[0] for s in statuses])
}
# Mapping of location ID to machine name
@ -254,9 +247,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
s.add_child(Node.s32("exp", uid_mapping[uid].get_int("exp")))
s.add_child(Node.s32("customize", status.get_int("customize")))
s.add_child(Node.s32("tid", uid_mapping[uid].get_int("team_id", -1)))
s.add_child(
Node.string("t_name", uid_mapping[uid].get_str("team_name", ""))
)
s.add_child(Node.string("t_name", uid_mapping[uid].get_str("team_name", "")))
s.add_child(Node.string("lid", status.get_str("lid")))
s.add_child(Node.string("s_name", lid_mapping[lid]))
s.add_child(Node.s8("pref", status.get_int("prefecture")))
@ -457,9 +448,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
refid = request.child_value("rid")
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, {}
)
self.data.local.lobby.put_play_session_info(self.game, self.version, userid, {})
root = Node.void("player")
root.add_child(Node.bool("is_suc", True))
@ -525,9 +514,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
)
if lobby is not None:
self.data.local.lobby.destroy_lobby(lobby.get_int("id"))
self.data.local.lobby.destroy_play_session_info(
self.game, self.version, userid
)
self.data.local.lobby.destroy_play_session_info(self.game, self.version, userid)
return Node.void("player")
@ -559,9 +546,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
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
)
scores = self.data.remote.music.get_scores(previous_version.game, previous_version.version, userid)
else:
profile = None
@ -598,15 +583,9 @@ class ReflecBeatLimelight(ReflecBeatBase):
mrecord.add_child(mrec)
mrec.add_child(Node.s32("mid", score.id))
mrec.add_child(Node.s32("ctype", score.chart))
mrec.add_child(
Node.s32("win", score.data.get_dict("stats").get_int("win"))
)
mrec.add_child(
Node.s32("lose", score.data.get_dict("stats").get_int("win"))
)
mrec.add_child(
Node.s32("draw", score.data.get_dict("stats").get_int("win"))
)
mrec.add_child(Node.s32("win", score.data.get_dict("stats").get_int("win")))
mrec.add_child(Node.s32("lose", score.data.get_dict("stats").get_int("win")))
mrec.add_child(Node.s32("draw", score.data.get_dict("stats").get_int("win")))
mrec.add_child(Node.s32("score", score.points))
mrec.add_child(Node.s32("combo", score.data.get_int("combo")))
mrec.add_child(Node.s32("miss", score.data.get_int("miss_count")))
@ -626,9 +605,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
scores = self.data.remote.music.get_scores(self.game, self.version, userid)
links = self.data.local.user.get_links(self.game, self.version, userid)
root = Node.void("player")
@ -672,50 +649,24 @@ class ReflecBeatLimelight(ReflecBeatBase):
custom.add_child(Node.u8("se_s", customdict.get_int("se_s")))
custom.add_child(Node.u8("se_s_v", customdict.get_int("se_s_v")))
custom.add_child(Node.s16("last_music_id", customdict.get_int("last_music_id")))
custom.add_child(
Node.u8("last_note_grade", customdict.get_int("last_note_grade"))
)
custom.add_child(Node.u8("last_note_grade", customdict.get_int("last_note_grade")))
custom.add_child(Node.u8("sort_type", customdict.get_int("sort_type")))
custom.add_child(
Node.u8("narrowdown_type", customdict.get_int("narrowdown_type"))
)
custom.add_child(
Node.bool("is_begginer", customdict.get_bool("is_begginer"))
) # Yes, this is spelled right
custom.add_child(Node.u8("narrowdown_type", customdict.get_int("narrowdown_type")))
custom.add_child(Node.bool("is_begginer", customdict.get_bool("is_begginer"))) # Yes, this is spelled right
custom.add_child(Node.bool("is_tut", customdict.get_bool("is_tut")))
custom.add_child(
Node.s16_array(
"symbol_chat_0", customdict.get_int_array("symbol_chat_0", 6)
)
)
custom.add_child(
Node.s16_array(
"symbol_chat_1", customdict.get_int_array("symbol_chat_1", 6)
)
)
custom.add_child(Node.s16_array("symbol_chat_0", customdict.get_int_array("symbol_chat_0", 6)))
custom.add_child(Node.s16_array("symbol_chat_1", customdict.get_int_array("symbol_chat_1", 6)))
custom.add_child(Node.u8("gauge_style", customdict.get_int("gauge_style")))
custom.add_child(Node.u8("obj_shade", customdict.get_int("obj_shade")))
custom.add_child(Node.u8("obj_size", customdict.get_int("obj_size")))
custom.add_child(
Node.s16_array("byword", customdict.get_int_array("byword", 2))
)
custom.add_child(
Node.bool_array(
"is_auto_byword", customdict.get_bool_array("is_auto_byword", 2)
)
)
custom.add_child(Node.s16_array("byword", customdict.get_int_array("byword", 2)))
custom.add_child(Node.bool_array("is_auto_byword", customdict.get_bool_array("is_auto_byword", 2)))
custom.add_child(Node.bool("is_tweet", customdict.get_bool("is_tweet")))
custom.add_child(
Node.bool("is_link_twitter", customdict.get_bool("is_link_twitter"))
)
custom.add_child(Node.bool("is_link_twitter", customdict.get_bool("is_link_twitter")))
custom.add_child(Node.s16("mrec_type", customdict.get_int("mrec_type")))
custom.add_child(
Node.s16("card_disp_type", customdict.get_int("card_disp_type"))
)
custom.add_child(Node.s16("card_disp_type", customdict.get_int("card_disp_type")))
custom.add_child(Node.s16("tab_sel", customdict.get_int("tab_sel")))
custom.add_child(
Node.s32_array("hidden_param", customdict.get_int_array("hidden_param", 20))
)
custom.add_child(Node.s32_array("hidden_param", customdict.get_int_array("hidden_param", 20)))
released = Node.void("released")
pdata.add_child(released)
@ -763,22 +714,14 @@ class ReflecBeatLimelight(ReflecBeatBase):
record.add_child(rec)
rec.add_child(Node.u16("mid", score.id))
rec.add_child(Node.u8("ng", score.chart))
rec.add_child(
Node.s32("point", score.data.get_dict("stats").get_int("earned_points"))
)
rec.add_child(Node.s32("point", score.data.get_dict("stats").get_int("earned_points")))
rec.add_child(Node.s32("played_time", score.timestamp))
mrec_0 = Node.void("mrec_0")
rec.add_child(mrec_0)
mrec_0.add_child(
Node.s32("win", score.data.get_dict("stats").get_int("win"))
)
mrec_0.add_child(
Node.s32("lose", score.data.get_dict("stats").get_int("lose"))
)
mrec_0.add_child(
Node.s32("draw", score.data.get_dict("stats").get_int("draw"))
)
mrec_0.add_child(Node.s32("win", score.data.get_dict("stats").get_int("win")))
mrec_0.add_child(Node.s32("lose", score.data.get_dict("stats").get_int("lose")))
mrec_0.add_child(Node.s32("draw", score.data.get_dict("stats").get_int("draw")))
mrec_0.add_child(
Node.u8(
"ct",
@ -788,9 +731,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
),
)
)
mrec_0.add_child(
Node.s16("ar", int(score.data.get_int("achievement_rate") / 10))
)
mrec_0.add_child(Node.s16("ar", int(score.data.get_int("achievement_rate") / 10)))
mrec_0.add_child(Node.s32("bs", score.points))
mrec_0.add_child(Node.s16("mc", score.data.get_int("combo")))
mrec_0.add_child(Node.s16("bmc", score.data.get_int("miss_count")))
@ -888,9 +829,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = oldprofile.clone()
@ -916,42 +855,24 @@ class ReflecBeatLimelight(ReflecBeatBase):
customdict.replace_int("se_s", custom.child_value("se_s"))
customdict.replace_int("se_s_v", custom.child_value("se_s_v"))
customdict.replace_int("last_music_id", custom.child_value("last_music_id"))
customdict.replace_int(
"last_note_grade", custom.child_value("last_note_grade")
)
customdict.replace_int("last_note_grade", custom.child_value("last_note_grade"))
customdict.replace_int("sort_type", custom.child_value("sort_type"))
customdict.replace_int(
"narrowdown_type", custom.child_value("narrowdown_type")
)
customdict.replace_bool(
"is_begginer", custom.child_value("is_begginer")
) # Yes, this is spelled right
customdict.replace_int("narrowdown_type", custom.child_value("narrowdown_type"))
customdict.replace_bool("is_begginer", custom.child_value("is_begginer")) # Yes, this is spelled right
customdict.replace_bool("is_tut", custom.child_value("is_tut"))
customdict.replace_int_array(
"symbol_chat_0", 6, custom.child_value("symbol_chat_0")
)
customdict.replace_int_array(
"symbol_chat_1", 6, custom.child_value("symbol_chat_1")
)
customdict.replace_int_array("symbol_chat_0", 6, custom.child_value("symbol_chat_0"))
customdict.replace_int_array("symbol_chat_1", 6, custom.child_value("symbol_chat_1"))
customdict.replace_int("gauge_style", custom.child_value("gauge_style"))
customdict.replace_int("obj_shade", custom.child_value("obj_shade"))
customdict.replace_int("obj_size", custom.child_value("obj_size"))
customdict.replace_int_array("byword", 2, custom.child_value("byword"))
customdict.replace_bool_array(
"is_auto_byword", 2, custom.child_value("is_auto_byword")
)
customdict.replace_bool_array("is_auto_byword", 2, custom.child_value("is_auto_byword"))
customdict.replace_bool("is_tweet", custom.child_value("is_tweet"))
customdict.replace_bool(
"is_link_twitter", custom.child_value("is_link_twitter")
)
customdict.replace_bool("is_link_twitter", custom.child_value("is_link_twitter"))
customdict.replace_int("mrec_type", custom.child_value("mrec_type"))
customdict.replace_int(
"card_disp_type", custom.child_value("card_disp_type")
)
customdict.replace_int("card_disp_type", custom.child_value("card_disp_type"))
customdict.replace_int("tab_sel", custom.child_value("tab_sel"))
customdict.replace_int_array(
"hidden_param", 20, custom.child_value("hidden_param")
)
customdict.replace_int_array("hidden_param", 20, custom.child_value("hidden_param"))
newprofile.replace_dict("custom", customdict)
# Music unlocks and other stuff
@ -1036,10 +957,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
if chart in savedrecords[songid]:
data = savedrecords[songid][chart]
if (
data["achievement_rate"] == achievement_rate
and data["points"] == points
):
if data["achievement_rate"] == achievement_rate and data["points"] == points:
# This is the same record! Use the stats from it to update our
# internal representation.
combo = data["combo"]

View File

@ -61,9 +61,7 @@ class ReflecBeat(ReflecBeatBase):
raise Exception(f"Invalid db_combo_type {db_combo_type}")
raise Exception(f"Invalid db_clear_type {db_clear_type}")
def __game_to_db_clear_type(
self, game_clear_type: int, game_achievement_rate: int
) -> Tuple[int, int]:
def __game_to_db_clear_type(self, game_clear_type: int, game_achievement_rate: 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_PLAYED:
@ -254,9 +252,7 @@ class ReflecBeat(ReflecBeatBase):
refid = request.child_value("rid")
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, {}
)
self.data.local.lobby.put_play_session_info(self.game, self.version, userid, {})
root = Node.void("player")
root.add_child(Node.bool("is_suc", True))
@ -282,9 +278,7 @@ class ReflecBeat(ReflecBeatBase):
)
if lobby is not None:
self.data.local.lobby.destroy_lobby(lobby.get_int("id"))
self.data.local.lobby.destroy_play_session_info(
self.game, self.version, userid
)
self.data.local.lobby.destroy_play_session_info(self.game, self.version, userid)
return Node.void("player")
@ -310,9 +304,7 @@ class ReflecBeat(ReflecBeatBase):
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
scores = self.data.remote.music.get_scores(self.game, self.version, userid)
root = Node.void("player")
pdata = Node.void("pdata")
@ -368,10 +360,7 @@ class ReflecBeat(ReflecBeatBase):
info.add_child(Node.u16("id", item.id))
if game_config.get_bool("force_unlock_songs"):
songs = {
song.id
for song in self.data.local.music.get_all_songs(self.game, self.version)
}
songs = {song.id for song in self.data.local.music.get_all_songs(self.game, self.version)}
for songid in songs:
info = Node.void("info")
@ -389,12 +378,8 @@ class ReflecBeat(ReflecBeatBase):
rec.add_child(Node.u16("mid", score.id))
rec.add_child(Node.u8("ng", score.chart))
rec.add_child(Node.s32("win", score.data.get_dict("stats").get_int("win")))
rec.add_child(
Node.s32("lose", score.data.get_dict("stats").get_int("lose"))
)
rec.add_child(
Node.s32("draw", score.data.get_dict("stats").get_int("draw"))
)
rec.add_child(Node.s32("lose", score.data.get_dict("stats").get_int("lose")))
rec.add_child(Node.s32("draw", score.data.get_dict("stats").get_int("draw")))
rec.add_child(
Node.u8(
"ct",
@ -404,9 +389,7 @@ class ReflecBeat(ReflecBeatBase):
),
)
)
rec.add_child(
Node.s16("ar", int(score.data.get_int("achievement_rate") / 10))
)
rec.add_child(Node.s16("ar", int(score.data.get_int("achievement_rate") / 10)))
rec.add_child(Node.s16("bs", score.points))
rec.add_child(Node.s16("mc", score.data.get_int("combo")))
rec.add_child(Node.s16("bmc", score.data.get_int("miss_count")))
@ -421,9 +404,7 @@ class ReflecBeat(ReflecBeatBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = oldprofile.clone()
@ -515,9 +496,7 @@ class ReflecBeat(ReflecBeatBase):
achievement_rate = child.child_value("myself/ar") * 10
points = child.child_value("myself/s")
clear_type, combo_type = self.__game_to_db_clear_type(
clear_type, achievement_rate
)
clear_type, combo_type = self.__game_to_db_clear_type(clear_type, achievement_rate)
combo = None
miss_count = -1
@ -527,10 +506,7 @@ class ReflecBeat(ReflecBeatBase):
if chart in savedrecords[songid]:
data = savedrecords[songid][chart]
if (
data["achievement_rate"] == achievement_rate
and data["points"] == points
):
if data["achievement_rate"] == achievement_rate and data["points"] == points:
# This is the same record! Use the stats from it to update our
# internal representation.
combo = data["combo"]

View File

@ -76,25 +76,18 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
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"))
)
)
rec.add_child(Node.s8("ct", self._db_to_game_clear_type(score.data.get_int("clear_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("ms", score.data.get_int("miss_count")))
rec.add_child(
Node.s16(
"param",
self._db_to_game_combo_type(score.data.get_int("combo_type"))
+ score.data.get_int("param"),
self._db_to_game_combo_type(score.data.get_int("combo_type")) + score.data.get_int("param"),
)
)
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("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")))
@ -111,9 +104,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
score = None
profile = None
else:
score = self.data.remote.music.get_score(
self.game, self.version, userid, songid, chart
)
score = self.data.remote.music.get_score(self.game, self.version, userid, songid, chart)
profile = self.get_any_profile(userid)
root = Node.void("player")
@ -125,14 +116,10 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
player_select_score.add_child(Node.string("name", profile.get_str("name")))
player_select_score.add_child(Node.s32("m_score", score.points))
player_select_score.add_child(Node.s32("m_scoreTime", score.timestamp))
player_select_score.add_child(
Node.s16("m_iconID", profile.get_dict("config").get_int("icon_id"))
)
player_select_score.add_child(Node.s16("m_iconID", profile.get_dict("config").get_int("icon_id")))
return root
def handle_player_rb5_player_read_rival_ranking_data_request(
self, request: Node
) -> Node:
def handle_player_rb5_player_read_rival_ranking_data_request(self, request: Node) -> Node:
extid = request.child_value("uid")
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
@ -154,13 +141,9 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
rival_data.add_child(rl)
rl.add_child(Node.s32("uid", rprofile.extid))
rl.add_child(Node.string("nm", rprofile.get_str("name")))
rl.add_child(
Node.s16("ic", rprofile.get_dict("config").get_int("icon_id"))
)
rl.add_child(Node.s16("ic", rprofile.get_dict("config").get_int("icon_id")))
scores = self.data.remote.music.get_scores(
self.game, self.version, link.other_userid
)
scores = self.data.remote.music.get_scores(self.game, self.version, link.other_userid)
scores_by_musicid: Dict[int, List[Score]] = {}
for score in scores:
if score.id not in scores_by_musicid:
@ -168,13 +151,8 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
scores_by_musicid[score.id][score.chart] = score
for mid, scores in scores_by_musicid.items():
points = [
score.points << 32 if score is not None else 0
for score in scores
]
timestamps = [
score.timestamp if score is not None else 0 for score in scores
]
points = [score.points << 32 if score is not None else 0 for score in scores]
timestamps = [score.timestamp if score is not None else 0 for score in scores]
sl = Node.void("sl")
rl.add_child(sl)
@ -206,86 +184,50 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
userid: [
score
for (uid, score) in all_scores
if uid == userid
and score.data.get_int("clear_type") >= self.CLEAR_TYPE_CLEARED
if uid == userid and score.data.get_int("clear_type") >= self.CLEAR_TYPE_CLEARED
]
for userid in all_users
}
# Now grab all user profiles for this game
all_profiles = {
profile[0]: profile[1]
for profile in self.data.remote.user.get_all_profiles(
self.game, self.version
)
profile[0]: profile[1] for profile in self.data.remote.user.get_all_profiles(self.game, self.version)
}
# Now, sum up the scores into the five categories that the game expects.
total_scores = sorted(
[
sum([score.points for score in scores])
for userid, scores in scores_by_user.items()
],
[sum([score.points for score in scores]) for userid, scores in scores_by_user.items()],
reverse=True,
)
basic_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_BASIC
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_BASIC])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
medium_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_MEDIUM
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_MEDIUM])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
hard_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_HARD
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_HARD])
for userid, scores in scores_by_user.items()
],
)
special_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_SPECIAL
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_SPECIAL])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
minigame_scores = sorted(
[
all_profiles.get(
userid, Profile(self.game, self.version, "", 0)
).get_int("mgsc")
for userid in all_users
],
[all_profiles.get(userid, Profile(self.game, self.version, "", 0)).get_int("mgsc") for userid in all_users],
reverse=True,
)
@ -351,9 +293,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
links = self.data.local.user.get_links(self.game, self.version, userid)
root = Node.void("player")
pdata = Node.void("pdata")
@ -436,9 +376,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
rprofile = self.get_profile(link.other_userid)
if rprofile is None:
continue
lobbyinfo = self.data.local.lobby.get_play_session_info(
self.game, self.version, link.other_userid
)
lobbyinfo = self.data.local.lobby.get_play_session_info(self.game, self.version, link.other_userid)
if lobbyinfo is None:
lobbyinfo = ValidatedDict()
@ -447,9 +385,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
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.s32("icon", rprofile.get_dict("config").get_int("icon_id"))
)
r.add_child(Node.s32("icon", rprofile.get_dict("config").get_int("icon_id")))
r.add_child(Node.s32("class", rprofile.get_int("class")))
r.add_child(Node.s32("class_ar", rprofile.get_int("class_ar")))
r.add_child(Node.bool("friend", True))
@ -466,48 +402,26 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
config = Node.void("config")
pdata.add_child(config)
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.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.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("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.u64("custom_folder_work", configdict.get_int("custom_folder_work"))
)
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.u64("custom_folder_work", configdict.get_int("custom_folder_work")))
config.add_child(Node.u8("folder_type", configdict.get_int("folder_type")))
config.add_child(
Node.u8("folder_lamp_type", configdict.get_int("folder_lamp_type"))
)
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"))
)
config.add_child(Node.bool("is_link_twitter", configdict.get_bool("is_link_twitter")))
# Customizations
customdict = profile.get_dict("custom")
@ -526,18 +440,10 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
custom.add_child(Node.u8("st_rnd", customdict.get_int("st_rnd")))
custom.add_child(Node.u8("st_hazard", customdict.get_int("st_hazard")))
custom.add_child(Node.u8("st_clr_cond", customdict.get_int("st_clr_cond")))
custom.add_child(
Node.u8("same_time_note_disp", customdict.get_int("same_time_note_disp"))
)
custom.add_child(
Node.u8("st_gr_gauge_type", customdict.get_int("st_gr_gauge_type"))
)
custom.add_child(
Node.s16("voice_message_set", customdict.get_int("voice_message_set", -1))
)
custom.add_child(
Node.u8("voice_message_volume", customdict.get_int("voice_message_volume"))
)
custom.add_child(Node.u8("same_time_note_disp", customdict.get_int("same_time_note_disp")))
custom.add_child(Node.u8("st_gr_gauge_type", customdict.get_int("st_gr_gauge_type")))
custom.add_child(Node.s16("voice_message_set", customdict.get_int("voice_message_set", -1)))
custom.add_child(Node.u8("voice_message_volume", customdict.get_int("voice_message_volume")))
# Unlocks
released = Node.void("released")
@ -591,9 +497,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
info.add_child(Node.u8("type", announcementtype))
info.add_child(Node.u16("id", announcement.id))
info.add_child(Node.u16("param", announcement.data.get_int("param")))
info.add_child(
Node.bool("bneedannounce", announcement.data.get_bool("need"))
)
info.add_child(Node.bool("bneedannounce", announcement.data.get_bool("need")))
# Dojo ranking return
dojo = Node.void("dojo")
@ -610,12 +514,8 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
rec.add_child(Node.s32("total_ar", entry.data.get_int("ar")))
rec.add_child(Node.s32("total_score", entry.data.get_int("score")))
rec.add_child(Node.s32("play_count", entry.data.get_int("plays")))
rec.add_child(
Node.s32("last_play_time", entry.data.get_int("play_timestamp"))
)
rec.add_child(
Node.s32("record_update_time", entry.data.get_int("record_timestamp"))
)
rec.add_child(Node.s32("last_play_time", entry.data.get_int("play_timestamp")))
rec.add_child(Node.s32("record_update_time", entry.data.get_int("record_timestamp")))
rec.add_child(Node.s32("rank", 0))
# Player Parameters
@ -631,9 +531,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
player_param.add_child(itemnode)
itemnode.add_child(Node.s32("type", itemtype))
itemnode.add_child(Node.s32("bank", param.id))
itemnode.add_child(
Node.s32_array("data", param.data.get_int_array("data", 256))
)
itemnode.add_child(Node.s32_array("data", param.data.get_int_array("data", 256)))
# Shop score for players
self._add_shop_score(pdata)
@ -644,9 +542,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
listdata = Node.void("list")
mylist.add_child(listdata)
listdata.add_child(Node.s16("idx", 0))
listdata.add_child(
Node.s16_array("mlst", profile.get_int_array("favorites", 30, [-1] * 30))
)
listdata.add_child(Node.s16_array("mlst", profile.get_int_array("favorites", 30, [-1] * 30)))
# Minigame settings
minigame = Node.void("minigame")
@ -661,16 +557,12 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = oldprofile.clone()
# Save base player profile info
newprofile.replace_int(
"lid", ID.parse_machine_id(request.child_value("pdata/account/lid"))
)
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("mg", request.child_value("pdata/base/mg"))
newprofile.replace_int("ap", request.child_value("pdata/base/ap"))
@ -680,55 +572,33 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
newprofile.replace_int("class_ar", request.child_value("pdata/base/class_ar"))
newprofile.replace_int("mgid", request.child_value("pdata/minigame/mgid"))
newprofile.replace_int("mgsc", request.child_value("pdata/minigame/sc"))
newprofile.replace_int_array(
"favorites", 30, request.child_value("pdata/mylist/list/mlst")
)
newprofile.replace_int_array("favorites", 30, request.child_value("pdata/mylist/list/mlst"))
# Save player config
configdict = newprofile.get_dict("config")
config = request.child("pdata/config")
if config:
configdict.replace_int("msel_bgm", config.child_value("msel_bgm"))
configdict.replace_int(
"narrowdown_type", config.child_value("narrowdown_type")
)
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_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("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("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(
"custom_folder_work", config.child_value("custom_folder_work")
)
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("custom_folder_work", config.child_value("custom_folder_work"))
configdict.replace_int("folder_type", config.child_value("folder_type"))
configdict.replace_int(
"folder_lamp_type", config.child_value("folder_lamp_type")
)
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")
)
configdict.replace_bool("is_link_twitter", config.child_value("is_link_twitter"))
newprofile.replace_dict("config", configdict)
# Save player custom settings
@ -747,18 +617,10 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
customdict.replace_int("st_rnd", custom.child_value("st_rnd"))
customdict.replace_int("st_hazard", custom.child_value("st_hazard"))
customdict.replace_int("st_clr_cond", custom.child_value("st_clr_cond"))
customdict.replace_int(
"same_time_note_disp", custom.child_value("same_time_note_disp")
)
customdict.replace_int(
"st_gr_gauge_type", custom.child_value("st_gr_gauge_type")
)
customdict.replace_int(
"voice_message_set", custom.child_value("voice_message_set")
)
customdict.replace_int(
"voice_message_volume", custom.child_value("voice_message_volume")
)
customdict.replace_int("same_time_note_disp", custom.child_value("same_time_note_disp"))
customdict.replace_int("st_gr_gauge_type", custom.child_value("st_gr_gauge_type"))
customdict.replace_int("voice_message_set", custom.child_value("voice_message_set"))
customdict.replace_int("voice_message_volume", custom.child_value("voice_message_volume"))
newprofile.replace_dict("custom", customdict)
# Save player parameter info
@ -794,9 +656,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
# I assume this is copypasta, but I want to be sure
extid = child.child_value("user_id")
if extid != newprofile.extid:
raise Exception(
f"Unexpected user ID, got {extid} expecting {newprofile.extid}"
)
raise Exception(f"Unexpected user ID, got {extid} expecting {newprofile.extid}")
episode_type = child.child_value("type")
episode_value0 = child.child_value("value0")
@ -923,9 +783,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
continue
extid = child.child_value("id")
other_userid = self.data.remote.user.from_extid(
self.game, self.version, extid
)
other_userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if other_userid is None:
continue

View File

@ -57,10 +57,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
mycourse_ctrl = Node.void("mycourse_ctrl")
root.add_child(mycourse_ctrl)
songs = {
song.id
for song in self.data.local.music.get_all_songs(self.game, self.version)
}
songs = {song.id for song in self.data.local.music.get_all_songs(self.game, self.version)}
for song in songs:
data = Node.void("data")
mycourse_ctrl.add_child(data)
@ -98,25 +95,18 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
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"))
)
)
rec.add_child(Node.s8("ct", self._db_to_game_clear_type(score.data.get_int("clear_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("ms", score.data.get_int("miss_count")))
rec.add_child(
Node.s16(
"param",
self._db_to_game_combo_type(score.data.get_int("combo_type"))
+ score.data.get_int("param"),
self._db_to_game_combo_type(score.data.get_int("combo_type")) + score.data.get_int("param"),
)
)
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("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")))
@ -124,9 +114,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
return root
def handle_player_rb5_player_read_rival_score_5_request(
self, request: Node
) -> Node:
def handle_player_rb5_player_read_rival_score_5_request(self, request: Node) -> Node:
extid = request.child_value("uid")
songid = request.child_value("music_id")
chart = request.child_value("note_grade")
@ -135,9 +123,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
score = None
profile = None
else:
score = self.data.remote.music.get_score(
self.game, self.version, userid, songid, chart
)
score = self.data.remote.music.get_score(self.game, self.version, userid, songid, chart)
profile = self.get_any_profile(userid)
root = Node.void("player")
@ -149,14 +135,10 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
player_select_score.add_child(Node.string("name", profile.get_str("name")))
player_select_score.add_child(Node.s32("m_score", score.points))
player_select_score.add_child(Node.s32("m_scoreTime", score.timestamp))
player_select_score.add_child(
Node.s16("m_iconID", profile.get_dict("config").get_int("icon_id"))
)
player_select_score.add_child(Node.s16("m_iconID", profile.get_dict("config").get_int("icon_id")))
return root
def handle_player_rb5_player_read_rival_ranking_data_5_request(
self, request: Node
) -> Node:
def handle_player_rb5_player_read_rival_ranking_data_5_request(self, request: Node) -> Node:
extid = request.child_value("uid")
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
@ -178,13 +160,9 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
rival_data.add_child(rl)
rl.add_child(Node.s32("uid", rprofile.extid))
rl.add_child(Node.string("nm", rprofile.get_str("name")))
rl.add_child(
Node.s16("ic", rprofile.get_dict("config").get_int("icon_id"))
)
rl.add_child(Node.s16("ic", rprofile.get_dict("config").get_int("icon_id")))
scores = self.data.remote.music.get_scores(
self.game, self.version, link.other_userid
)
scores = self.data.remote.music.get_scores(self.game, self.version, link.other_userid)
scores_by_musicid: Dict[int, List[Score]] = {}
for score in scores:
if score.id not in scores_by_musicid:
@ -192,13 +170,8 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
scores_by_musicid[score.id][score.chart] = score
for mid, scores in scores_by_musicid.items():
points = [
score.points << 32 if score is not None else 0
for score in scores
]
timestamps = [
score.timestamp if score is not None else 0 for score in scores
]
points = [score.points << 32 if score is not None else 0 for score in scores]
timestamps = [score.timestamp if score is not None else 0 for score in scores]
sl = Node.void("sl")
rl.add_child(sl)
@ -230,86 +203,50 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
userid: [
score
for (uid, score) in all_scores
if uid == userid
and score.data.get_int("clear_type") >= self.CLEAR_TYPE_CLEARED
if uid == userid and score.data.get_int("clear_type") >= self.CLEAR_TYPE_CLEARED
]
for userid in all_users
}
# Now grab all user profiles for this game
all_profiles = {
profile[0]: profile[1]
for profile in self.data.remote.user.get_all_profiles(
self.game, self.version
)
profile[0]: profile[1] for profile in self.data.remote.user.get_all_profiles(self.game, self.version)
}
# Now, sum up the scores into the five categories that the game expects.
total_scores = sorted(
[
sum([score.points for score in scores])
for userid, scores in scores_by_user.items()
],
[sum([score.points for score in scores]) for userid, scores in scores_by_user.items()],
reverse=True,
)
basic_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_BASIC
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_BASIC])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
medium_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_MEDIUM
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_MEDIUM])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
hard_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_HARD
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_HARD])
for userid, scores in scores_by_user.items()
],
)
special_scores = sorted(
[
sum(
[
score.points
for score in scores
if score.chart == self.CHART_TYPE_SPECIAL
]
)
sum([score.points for score in scores if score.chart == self.CHART_TYPE_SPECIAL])
for userid, scores in scores_by_user.items()
],
reverse=True,
)
minigame_scores = sorted(
[
all_profiles.get(
userid, Profile(self.game, self.version, "", 0)
).get_int("mgsc")
for userid in all_users
],
[all_profiles.get(userid, Profile(self.game, self.version, "", 0)).get_int("mgsc") for userid in all_users],
reverse=True,
)
@ -375,9 +312,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
links = self.data.local.user.get_links(self.game, self.version, userid)
rprofiles: Dict[UserID, Profile] = {}
root = Node.void("player")
@ -468,9 +403,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
rprofiles[link.other_userid] = rprofile
else:
rprofile = rprofiles[link.other_userid]
lobbyinfo = self.data.local.lobby.get_play_session_info(
self.game, self.version, link.other_userid
)
lobbyinfo = self.data.local.lobby.get_play_session_info(self.game, self.version, link.other_userid)
if lobbyinfo is None:
lobbyinfo = ValidatedDict()
@ -479,9 +412,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
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.s32("icon", rprofile.get_dict("config").get_int("icon_id"))
)
r.add_child(Node.s32("icon", rprofile.get_dict("config").get_int("icon_id")))
r.add_child(Node.s32("class", rprofile.get_int("class")))
r.add_child(Node.s32("class_ar", rprofile.get_int("class_ar")))
r.add_child(Node.bool("friend", True))
@ -498,48 +429,26 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
config = Node.void("config")
pdata.add_child(config)
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.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.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("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.u64("custom_folder_work", configdict.get_int("custom_folder_work"))
)
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.u64("custom_folder_work", configdict.get_int("custom_folder_work")))
config.add_child(Node.u8("folder_type", configdict.get_int("folder_type")))
config.add_child(
Node.u8("folder_lamp_type", configdict.get_int("folder_lamp_type"))
)
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"))
)
config.add_child(Node.bool("is_link_twitter", configdict.get_bool("is_link_twitter")))
# Customizations
customdict = profile.get_dict("custom")
@ -555,31 +464,17 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
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_rnd", customdict.get_int("st_rnd")))
custom.add_child(
Node.u8("st_gr_gauge_type", customdict.get_int("st_gr_gauge_type"))
)
custom.add_child(
Node.s16("voice_message_set", customdict.get_int("voice_message_set", -1))
)
custom.add_child(
Node.u8("same_time_note_disp", customdict.get_int("same_time_note_disp"))
)
custom.add_child(
Node.u8("st_score_disp_type", customdict.get_int("st_score_disp_type"))
)
custom.add_child(Node.u8("st_gr_gauge_type", customdict.get_int("st_gr_gauge_type")))
custom.add_child(Node.s16("voice_message_set", customdict.get_int("voice_message_set", -1)))
custom.add_child(Node.u8("same_time_note_disp", customdict.get_int("same_time_note_disp")))
custom.add_child(Node.u8("st_score_disp_type", customdict.get_int("st_score_disp_type")))
custom.add_child(Node.u8("st_bonus_type", customdict.get_int("st_bonus_type")))
custom.add_child(
Node.u8("st_rivalnote_type", customdict.get_int("st_rivalnote_type"))
)
custom.add_child(
Node.u8("st_topassist_type", customdict.get_int("st_topassist_type"))
)
custom.add_child(Node.u8("st_rivalnote_type", customdict.get_int("st_rivalnote_type")))
custom.add_child(Node.u8("st_topassist_type", customdict.get_int("st_topassist_type")))
custom.add_child(Node.u8("high_speed", customdict.get_int("high_speed")))
custom.add_child(Node.u8("st_hazard", customdict.get_int("st_hazard")))
custom.add_child(Node.u8("st_clr_cond", customdict.get_int("st_clr_cond")))
custom.add_child(
Node.u8("voice_message_volume", customdict.get_int("voice_message_volume"))
)
custom.add_child(Node.u8("voice_message_volume", customdict.get_int("voice_message_volume")))
# Unlocks
released = Node.void("released")
@ -635,9 +530,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
info.add_child(Node.u8("type", announcementtype))
info.add_child(Node.u16("id", announcement.id))
info.add_child(Node.u16("param", announcement.data.get_int("param")))
info.add_child(
Node.bool("bneedannounce", announcement.data.get_bool("need"))
)
info.add_child(Node.bool("bneedannounce", announcement.data.get_bool("need")))
# Dojo ranking return
dojo = Node.void("dojo")
@ -654,12 +547,8 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
rec.add_child(Node.s32("total_ar", entry.data.get_int("ar")))
rec.add_child(Node.s32("total_score", entry.data.get_int("score")))
rec.add_child(Node.s32("play_count", entry.data.get_int("plays")))
rec.add_child(
Node.s32("last_play_time", entry.data.get_int("play_timestamp"))
)
rec.add_child(
Node.s32("record_update_time", entry.data.get_int("record_timestamp"))
)
rec.add_child(Node.s32("last_play_time", entry.data.get_int("play_timestamp")))
rec.add_child(Node.s32("record_update_time", entry.data.get_int("record_timestamp")))
rec.add_child(Node.s32("rank", 0))
# Player Parameters
@ -675,9 +564,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
player_param.add_child(itemnode)
itemnode.add_child(Node.s32("type", itemtype))
itemnode.add_child(Node.s32("bank", param.id))
itemnode.add_child(
Node.s32_array("data", param.data.get_int_array("data", 256))
)
itemnode.add_child(Node.s32_array("data", param.data.get_int_array("data", 256)))
# Shop score for players
self._add_shop_score(pdata)
@ -688,9 +575,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
listdata = Node.void("list")
mylist.add_child(listdata)
listdata.add_child(Node.s16("idx", 0))
listdata.add_child(
Node.s16_array("mlst", profile.get_int_array("favorites", 30, [-1] * 30))
)
listdata.add_child(Node.s16_array("mlst", profile.get_int_array("favorites", 30, [-1] * 30)))
# Minigame settings
minigame = Node.void("minigame")
@ -724,37 +609,19 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
mycoursedict = profile.get_dict("mycourse")
pdata.add_child(mycourse)
mycourse.add_child(Node.s16("mycourse_id", 1))
mycourse.add_child(
Node.s32("music_id_1", mycoursedict.get_int("music_id_1", -1))
)
mycourse.add_child(
Node.s16("note_grade_1", mycoursedict.get_int("note_grade_1", -1))
)
mycourse.add_child(Node.s32("music_id_1", mycoursedict.get_int("music_id_1", -1)))
mycourse.add_child(Node.s16("note_grade_1", mycoursedict.get_int("note_grade_1", -1)))
mycourse.add_child(Node.s32("score_1", mycoursedict.get_int("score_1", -1)))
mycourse.add_child(
Node.s32("music_id_2", mycoursedict.get_int("music_id_2", -1))
)
mycourse.add_child(
Node.s16("note_grade_2", mycoursedict.get_int("note_grade_2", -1))
)
mycourse.add_child(Node.s32("music_id_2", mycoursedict.get_int("music_id_2", -1)))
mycourse.add_child(Node.s16("note_grade_2", mycoursedict.get_int("note_grade_2", -1)))
mycourse.add_child(Node.s32("score_2", mycoursedict.get_int("score_2", -1)))
mycourse.add_child(
Node.s32("music_id_3", mycoursedict.get_int("music_id_3", -1))
)
mycourse.add_child(
Node.s16("note_grade_3", mycoursedict.get_int("note_grade_3", -1))
)
mycourse.add_child(Node.s32("music_id_3", mycoursedict.get_int("music_id_3", -1)))
mycourse.add_child(Node.s16("note_grade_3", mycoursedict.get_int("note_grade_3", -1)))
mycourse.add_child(Node.s32("score_3", mycoursedict.get_int("score_3", -1)))
mycourse.add_child(
Node.s32("music_id_4", mycoursedict.get_int("music_id_4", -1))
)
mycourse.add_child(
Node.s16("note_grade_4", mycoursedict.get_int("note_grade_4", -1))
)
mycourse.add_child(Node.s32("music_id_4", mycoursedict.get_int("music_id_4", -1)))
mycourse.add_child(Node.s16("note_grade_4", mycoursedict.get_int("note_grade_4", -1)))
mycourse.add_child(Node.s32("score_4", mycoursedict.get_int("score_4", -1)))
mycourse.add_child(
Node.s32("insert_time", mycoursedict.get_int("insert_time", -1))
)
mycourse.add_child(Node.s32("insert_time", mycoursedict.get_int("insert_time", -1)))
mycourse.add_child(Node.s32("def_music_id_1", -1))
mycourse.add_child(Node.s16("def_note_grade_1", -1))
mycourse.add_child(Node.s32("def_music_id_2", -1))
@ -785,50 +652,28 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
mycourse_f.add_child(rec)
rec.add_child(Node.s32("rival_id", rprofile.extid))
rec.add_child(Node.s16("mycourse_id", 1))
rec.add_child(
Node.s32("music_id_1", mycoursedict.get_int("music_id_1", -1))
)
rec.add_child(
Node.s16("note_grade_1", mycoursedict.get_int("note_grade_1", -1))
)
rec.add_child(Node.s32("music_id_1", mycoursedict.get_int("music_id_1", -1)))
rec.add_child(Node.s16("note_grade_1", mycoursedict.get_int("note_grade_1", -1)))
rec.add_child(Node.s32("score_1", mycoursedict.get_int("score_1", -1)))
rec.add_child(
Node.s32("music_id_2", mycoursedict.get_int("music_id_2", -1))
)
rec.add_child(
Node.s16("note_grade_2", mycoursedict.get_int("note_grade_2", -1))
)
rec.add_child(Node.s32("music_id_2", mycoursedict.get_int("music_id_2", -1)))
rec.add_child(Node.s16("note_grade_2", mycoursedict.get_int("note_grade_2", -1)))
rec.add_child(Node.s32("score_2", mycoursedict.get_int("score_2", -1)))
rec.add_child(
Node.s32("music_id_3", mycoursedict.get_int("music_id_3", -1))
)
rec.add_child(
Node.s16("note_grade_3", mycoursedict.get_int("note_grade_3", -1))
)
rec.add_child(Node.s32("music_id_3", mycoursedict.get_int("music_id_3", -1)))
rec.add_child(Node.s16("note_grade_3", mycoursedict.get_int("note_grade_3", -1)))
rec.add_child(Node.s32("score_3", mycoursedict.get_int("score_3", -1)))
rec.add_child(
Node.s32("music_id_4", mycoursedict.get_int("music_id_4", -1))
)
rec.add_child(
Node.s16("note_grade_4", mycoursedict.get_int("note_grade_4", -1))
)
rec.add_child(Node.s32("music_id_4", mycoursedict.get_int("music_id_4", -1)))
rec.add_child(Node.s16("note_grade_4", mycoursedict.get_int("note_grade_4", -1)))
rec.add_child(Node.s32("score_4", mycoursedict.get_int("score_4", -1)))
rec.add_child(
Node.s32("insert_time", mycoursedict.get_int("insert_time", -1))
)
rec.add_child(Node.s32("insert_time", mycoursedict.get_int("insert_time", -1)))
return root
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = oldprofile.clone()
# Save base player profile info
newprofile.replace_int(
"lid", ID.parse_machine_id(request.child_value("pdata/account/lid"))
)
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("mg", request.child_value("pdata/base/mg"))
newprofile.replace_int("ap", request.child_value("pdata/base/ap"))
@ -836,60 +681,36 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
newprofile.replace_int("money", request.child_value("pdata/base/money"))
newprofile.replace_int("class", request.child_value("pdata/base/class"))
newprofile.replace_int("class_ar", request.child_value("pdata/base/class_ar"))
newprofile.replace_int(
"skill_point", request.child_value("pdata/base/skill_point")
)
newprofile.replace_int("skill_point", request.child_value("pdata/base/skill_point"))
newprofile.replace_int("mgid", request.child_value("pdata/minigame/mgid"))
newprofile.replace_int("mgsc", request.child_value("pdata/minigame/sc"))
newprofile.replace_int_array(
"favorites", 30, request.child_value("pdata/mylist/list/mlst")
)
newprofile.replace_int_array("favorites", 30, request.child_value("pdata/mylist/list/mlst"))
# Save player config
configdict = newprofile.get_dict("config")
config = request.child("pdata/config")
if config:
configdict.replace_int("msel_bgm", config.child_value("msel_bgm"))
configdict.replace_int(
"narrowdown_type", config.child_value("narrowdown_type")
)
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_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("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("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(
"custom_folder_work", config.child_value("custom_folder_work")
)
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("custom_folder_work", config.child_value("custom_folder_work"))
configdict.replace_int("folder_type", config.child_value("folder_type"))
configdict.replace_int(
"folder_lamp_type", config.child_value("folder_lamp_type")
)
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")
)
configdict.replace_bool("is_link_twitter", config.child_value("is_link_twitter"))
newprofile.replace_dict("config", configdict)
# Save player custom settings
@ -905,31 +726,17 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
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_gr_gauge_type", custom.child_value("st_gr_gauge_type")
)
customdict.replace_int(
"voice_message_set", custom.child_value("voice_message_set")
)
customdict.replace_int(
"same_time_note_disp", custom.child_value("same_time_note_disp")
)
customdict.replace_int(
"st_score_disp_type", custom.child_value("st_score_disp_type")
)
customdict.replace_int("st_gr_gauge_type", custom.child_value("st_gr_gauge_type"))
customdict.replace_int("voice_message_set", custom.child_value("voice_message_set"))
customdict.replace_int("same_time_note_disp", custom.child_value("same_time_note_disp"))
customdict.replace_int("st_score_disp_type", custom.child_value("st_score_disp_type"))
customdict.replace_int("st_bonus_type", custom.child_value("st_bonus_type"))
customdict.replace_int(
"st_rivalnote_type", custom.child_value("st_rivalnote_type")
)
customdict.replace_int(
"st_topassist_type", custom.child_value("st_topassist_type")
)
customdict.replace_int("st_rivalnote_type", custom.child_value("st_rivalnote_type"))
customdict.replace_int("st_topassist_type", custom.child_value("st_topassist_type"))
customdict.replace_int("high_speed", custom.child_value("high_speed"))
customdict.replace_int("st_hazard", custom.child_value("st_hazard"))
customdict.replace_int("st_clr_cond", custom.child_value("st_clr_cond"))
customdict.replace_int(
"voice_message_volume", custom.child_value("voice_message_volume")
)
customdict.replace_int("voice_message_volume", custom.child_value("voice_message_volume"))
newprofile.replace_dict("custom", customdict)
# Save player parameter info
@ -965,9 +772,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
# I assume this is copypasta, but I want to be sure
extid = child.child_value("user_id")
if extid != newprofile.extid:
raise Exception(
f"Unexpected user ID, got {extid} expecting {newprofile.extid}"
)
raise Exception(f"Unexpected user ID, got {extid} expecting {newprofile.extid}")
episode_type = child.child_value("type")
episode_value0 = child.child_value("value0")
@ -1085,9 +890,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
continue
extid = child.child_value("id")
other_userid = self.data.remote.user.from_extid(
self.game, self.version, extid
)
other_userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if other_userid is None:
continue
@ -1189,33 +992,17 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
)
if total >= oldtotal:
mycoursedict.replace_int(
"music_id_1", mycourse.child_value("music_id_1")
)
mycoursedict.replace_int(
"note_grade_1", mycourse.child_value("note_grade_1")
)
mycoursedict.replace_int("music_id_1", mycourse.child_value("music_id_1"))
mycoursedict.replace_int("note_grade_1", mycourse.child_value("note_grade_1"))
mycoursedict.replace_int("score_1", score_1)
mycoursedict.replace_int(
"music_id_2", mycourse.child_value("music_id_2")
)
mycoursedict.replace_int(
"note_grade_2", mycourse.child_value("note_grade_2")
)
mycoursedict.replace_int("music_id_2", mycourse.child_value("music_id_2"))
mycoursedict.replace_int("note_grade_2", mycourse.child_value("note_grade_2"))
mycoursedict.replace_int("score_2", score_2)
mycoursedict.replace_int(
"music_id_3", mycourse.child_value("music_id_3")
)
mycoursedict.replace_int(
"note_grade_3", mycourse.child_value("note_grade_3")
)
mycoursedict.replace_int("music_id_3", mycourse.child_value("music_id_3"))
mycoursedict.replace_int("note_grade_3", mycourse.child_value("note_grade_3"))
mycoursedict.replace_int("score_3", score_3)
mycoursedict.replace_int(
"music_id_4", mycourse.child_value("music_id_4")
)
mycoursedict.replace_int(
"note_grade_4", mycourse.child_value("note_grade_4")
)
mycoursedict.replace_int("music_id_4", mycourse.child_value("music_id_4"))
mycoursedict.replace_int("note_grade_4", mycourse.child_value("note_grade_4"))
mycoursedict.replace_int("score_4", score_4)
mycoursedict.replace_int("insert_time", Time.now())
newprofile.replace_dict("mycourse", mycoursedict)

View File

@ -87,16 +87,11 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
)
machine = self.data.local.machine.get_machine(self.config.machine.pcbid)
if machine.arcade is not None:
lids = [
machine.id
for machine in self.data.local.machine.get_all_machines(machine.arcade)
]
lids = [machine.id for machine in self.data.local.machine.get_all_machines(machine.arcade)]
else:
lids = [machine.id]
relevant_profiles = [
profile for profile in all_profiles if profile[1].get_int("lid", -1) in lids
]
relevant_profiles = [profile for profile in all_profiles if profile[1].get_int("lid", -1) in lids]
for rootnode, timeoffset in [
(today, 0),
@ -124,10 +119,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
scores_by_user[userid][attempt.id][attempt.chart] = attempt
else:
# If this attempt is better than the stored one, replace it
if (
scores_by_user[userid][attempt.id][attempt.chart].points
< attempt.points
):
if scores_by_user[userid][attempt.id][attempt.chart].points < attempt.points:
scores_by_user[userid][attempt.id][attempt.chart] = attempt
# Calculate points earned by user in the day
@ -136,27 +128,16 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
points_by_user[userid] = 0
for mid in scores_by_user[userid]:
for chart in scores_by_user[userid][mid]:
points_by_user[userid] = (
points_by_user[userid]
+ scores_by_user[userid][mid][chart].points
)
points_by_user[userid] = points_by_user[userid] + scores_by_user[userid][mid][chart].points
# Output that day's earned points
for userid, profile in relevant_profiles:
data = Node.void("data")
rootnode.add_child(data)
data.add_child(
Node.s16(
"day_id", int((Time.now() - timeoffset) / Time.SECONDS_IN_DAY)
)
)
data.add_child(Node.s16("day_id", int((Time.now() - timeoffset) / Time.SECONDS_IN_DAY)))
data.add_child(Node.s32("user_id", profile.extid))
data.add_child(
Node.s16("icon_id", profile.get_dict("config").get_int("icon_id"))
)
data.add_child(
Node.s16("point", min(points_by_user.get(userid, 0), 32767))
)
data.add_child(Node.s16("icon_id", profile.get_dict("config").get_int("icon_id")))
data.add_child(Node.s16("point", min(points_by_user.get(userid, 0), 32767)))
data.add_child(Node.s32("update_time", Time.now()))
data.add_child(Node.string("name", profile.get_str("name")))
@ -176,9 +157,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
ranking = Node.void("ranking")
root.add_child(ranking)
def add_hitchart(
name: str, start: int, end: int, hitchart: List[Tuple[int, int]]
) -> None:
def add_hitchart(name: str, start: int, end: int, hitchart: List[Tuple[int, int]]) -> None:
base = Node.void(name)
ranking.add_child(base)
base.add_child(Node.s32("bt", start))
@ -261,17 +240,11 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
data.add_child(
Node.s8(
"clear_type",
self._db_to_game_clear_type(
score.data.get_int("clear_type")
),
self._db_to_game_clear_type(score.data.get_int("clear_type")),
)
)
data.add_child(Node.s32("user_id", profile.extid))
data.add_child(
Node.s16(
"icon_id", profile.get_dict("config").get_int("icon_id")
)
)
data.add_child(Node.s16("icon_id", profile.get_dict("config").get_int("icon_id")))
data.add_child(Node.s32("score", score.points))
data.add_child(Node.s32("time", score.timestamp))
data.add_child(Node.string("name", profile.get_str("name")))
@ -288,9 +261,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
if userid is not None:
profile = self.get_profile(userid)
info = self.data.local.lobby.get_play_session_info(
self.game, self.version, userid
)
info = self.data.local.lobby.get_play_session_info(self.game, self.version, userid)
if profile is None or info is None:
return root
@ -369,9 +340,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
continue
profile = self.get_profile(user)
info = self.data.local.lobby.get_play_session_info(
self.game, self.version, userid
)
info = self.data.local.lobby.get_play_session_info(self.game, self.version, userid)
if profile is None or info is None:
# No profile info, don't return this lobby
return root
@ -502,9 +471,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
)
if lobby is not None:
self.data.local.lobby.destroy_lobby(lobby.get_int("id"))
self.data.local.lobby.destroy_play_session_info(
self.game, self.version, userid
)
self.data.local.lobby.destroy_play_session_info(self.game, self.version, userid)
return Node.void("player")

View File

@ -21,9 +21,7 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
CLEAR_TYPE_CLEAR: Final[int] = DBConstants.SDVX_CLEAR_TYPE_CLEAR
CLEAR_TYPE_HARD_CLEAR: Final[int] = DBConstants.SDVX_CLEAR_TYPE_HARD_CLEAR
CLEAR_TYPE_ULTIMATE_CHAIN: Final[int] = DBConstants.SDVX_CLEAR_TYPE_ULTIMATE_CHAIN
CLEAR_TYPE_PERFECT_ULTIMATE_CHAIN: Final[
int
] = DBConstants.SDVX_CLEAR_TYPE_PERFECT_ULTIMATE_CHAIN
CLEAR_TYPE_PERFECT_ULTIMATE_CHAIN: Final[int] = DBConstants.SDVX_CLEAR_TYPE_PERFECT_ULTIMATE_CHAIN
GRADE_NO_PLAY: Final[int] = DBConstants.SDVX_GRADE_NO_PLAY
GRADE_D: Final[int] = DBConstants.SDVX_GRADE_D
@ -68,9 +66,7 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Now, return it
return self.format_profile(userid, profile)
def new_profile_by_refid(
self, refid: Optional[str], name: Optional[str], locid: Optional[int]
) -> Node:
def new_profile_by_refid(self, refid: Optional[str], name: Optional[str], locid: Optional[int]) -> Node:
"""
Given a RefID and an optional name, create a profile and then return
a formatted profile node. Similar rationale to get_profile_by_refid.
@ -103,9 +99,7 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void("game")
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -154,10 +148,7 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# We saw an attempt, keep the total attempts in sync.
attempts[attempt.id][attempt.chart]["average"] = int(
(
(
attempts[attempt.id][attempt.chart]["average"]
* attempts[attempt.id][attempt.chart]["total"]
)
(attempts[attempt.id][attempt.chart]["average"] * attempts[attempt.id][attempt.chart]["total"])
+ attempt.points
)
/ (attempts[attempt.id][attempt.chart]["total"] + 1)
@ -187,12 +178,8 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"average": 0,
}
attempts[songid][songchart]["total"] += remote_attempts[songid][
songchart
]["plays"]
attempts[songid][songchart]["clears"] += remote_attempts[songid][
songchart
]["clears"]
attempts[songid][songchart]["total"] += remote_attempts[songid][songchart]["plays"]
attempts[songid][songchart]["clears"] += remote_attempts[songid][songchart]["clears"]
return attempts
@ -267,9 +254,7 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
scoredata = oldscore.data
# Replace clear type and grade
scoredata.replace_int(
"clear_type", max(scoredata.get_int("clear_type"), clear_type)
)
scoredata.replace_int("clear_type", max(scoredata.get_int("clear_type"), clear_type))
history.replace_int("clear_type", clear_type)
scoredata.replace_int("grade", max(scoredata.get_int("grade"), grade))
history.replace_int("grade", grade)

View File

@ -227,10 +227,7 @@ class SoundVoltexBooth(
records_by_id[score.id][score.chart] = record
missing_users.append(userid)
users = {
userid: profile
for (userid, profile) in self.get_any_profiles(missing_users)
}
users = {userid: profile for (userid, profile) in self.get_any_profiles(missing_users)}
# Output records
for songid in records_by_id:
@ -492,22 +489,16 @@ class SoundVoltexBooth(
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update experience and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
gain_exp = request.child_value("gain_exp")
if gain_exp is not None:
newprofile.replace_int("exp", newprofile.get_int("exp") + gain_exp)
@ -520,15 +511,11 @@ class SoundVoltexBooth(
if not game_config.get_bool("force_unlock_cards"):
have_item = request.child_value("have_item")
if have_item is not None:
newprofile.replace_int_array(
"have_item", 512, [1 if x else 0 for x in have_item]
)
newprofile.replace_int_array("have_item", 512, [1 if x else 0 for x in have_item])
if not game_config.get_bool("force_unlock_songs"):
have_note = request.child_value("have_note")
if have_note is not None:
newprofile.replace_int_array(
"have_note", 512, [1 if x else 0 for x in have_note]
)
newprofile.replace_int_array("have_note", 512, [1 if x else 0 for x in have_note])
# Grab last information.
lastdict = newprofile.get_dict("last")

View File

@ -204,9 +204,7 @@ class SoundVoltexGravityWars(
courses = self._get_skill_analyzer_courses()
max_level: Dict[int, int] = {}
for course in courses:
max_level[course["level"]] = max(
course["season_id"], max_level.get(course["level"], -1)
)
max_level[course["level"]] = max(course["season_id"], max_level.get(course["level"], -1))
for course in courses:
info = Node.void("info")
skill_course.add_child(info)
@ -214,11 +212,7 @@ class SoundVoltexGravityWars(
info.add_child(Node.s16("level", course["level"]))
info.add_child(Node.s32("season_id", course["season_id"]))
info.add_child(Node.string("season_name", seasons[course["season_id"]]))
info.add_child(
Node.bool(
"season_new_flg", max_level[course["level"]] == course["season_id"]
)
)
info.add_child(Node.bool("season_new_flg", max_level[course["level"]] == course["season_id"]))
info.add_child(
Node.string(
"course_name",
@ -226,14 +220,8 @@ class SoundVoltexGravityWars(
)
)
info.add_child(Node.s16("course_type", 0))
info.add_child(
Node.s16("skill_name_id", course.get("skill_name_id", course["level"]))
)
info.add_child(
Node.bool(
"matching_assist", course["level"] >= 0 and course["level"] <= 6
)
)
info.add_child(Node.s16("skill_name_id", course.get("skill_name_id", course["level"])))
info.add_child(Node.bool("matching_assist", course["level"] >= 0 and course["level"] <= 6))
info.add_child(Node.s16("gauge_type", self.GAME_GAUGE_TYPE_SKILL))
info.add_child(Node.s16("paseli_type", 0))
@ -464,11 +452,7 @@ class SoundVoltexGravityWars(
self.__db_to_game_clear_type(score.data.get_int("clear_type")),
)
)
music.add_child(
Node.u32(
"score_grade", self.__db_to_game_grade(score.data.get_int("grade"))
)
)
music.add_child(Node.u32("score_grade", self.__db_to_game_grade(score.data.get_int("grade"))))
stats = score.data.get_dict("stats")
music.add_child(Node.u32("btn_rate", stats.get_int("btn_rate")))
music.add_child(Node.u32("long_rate", stats.get_int("long_rate")))

View File

@ -3063,10 +3063,7 @@ class SoundVoltexGravityWarsSeason1(
# Now, grab user records
records = self.data.remote.music.get_all_records(self.game, self.version)
missing_users = [userid for (userid, _) in records]
users = {
userid: profile
for (userid, profile) in self.get_any_profiles(missing_users)
}
users = {userid: profile for (userid, profile) in self.get_any_profiles(missing_users)}
hiscore_allover = Node.void("hiscore_allover")
game.add_child(hiscore_allover)
@ -3091,14 +3088,10 @@ class SoundVoltexGravityWarsSeason1(
# Now, grab local records
area_users = [
uid
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)
if prof.get_int("loc", -1) == locid
]
records = self.data.local.music.get_all_records(
self.game, self.version, userlist=area_users
)
records = self.data.local.music.get_all_records(self.game, self.version, userlist=area_users)
missing_users = [userid for (userid, _) in records if userid not in users]
for userid, profile in self.get_any_profiles(missing_users):
users[userid] = profile
@ -3131,9 +3124,7 @@ class SoundVoltexGravityWarsSeason1(
for songid in clears:
for chart in clears[songid]:
if clears[songid][chart]["total"] > 0:
rate = float(clears[songid][chart]["clears"]) / float(
clears[songid][chart]["total"]
)
rate = float(clears[songid][chart]["clears"]) / float(clears[songid][chart]["total"])
dnode = Node.void("d")
clear_rate.add_child(dnode)
dnode.add_child(Node.u32("id", songid))
@ -3151,9 +3142,7 @@ class SoundVoltexGravityWarsSeason1(
game.add_child(Node.u32("gamecoin_packet", profile.get_int("packet")))
game.add_child(Node.u32("gamecoin_block", profile.get_int("block")))
game.add_child(Node.s16("skill_name_id", profile.get_int("skill_name_id", -1)))
game.add_child(
Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20))
)
game.add_child(Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20)))
game.add_child(Node.u32("blaster_energy", profile.get_int("blaster_energy")))
game.add_child(Node.u32("blaster_count", profile.get_int("blaster_count")))
@ -3182,25 +3171,17 @@ class SoundVoltexGravityWarsSeason1(
game.add_child(itemnode)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for item in achievements:
if item.type[:5] != "item_":
continue
itemtype = int(item.type[5:])
if (
game_config.get_bool("force_unlock_songs")
and itemtype == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and itemtype == self.GAME_CATALOG_TYPE_SONG:
# Don't echo unlocked songs, we will add all of them later
continue
if (
game_config.get_bool("force_unlock_cards")
and itemtype == self.GAME_CATALOG_TYPE_APPEAL_CARD
):
if game_config.get_bool("force_unlock_cards") and itemtype == self.GAME_CATALOG_TYPE_APPEAL_CARD:
# Don't echo unlocked appeal cards, we will add all of them later
continue
@ -3274,30 +3255,22 @@ class SoundVoltexGravityWarsSeason1(
storynode.add_child(info)
info.add_child(Node.s32("story_id", story.id))
info.add_child(Node.s32("progress_id", story.data.get_int("progress_id")))
info.add_child(
Node.s32("progress_param", story.data.get_int("progress_param"))
)
info.add_child(Node.s32("progress_param", story.data.get_int("progress_param")))
info.add_child(Node.s32("clear_cnt", story.data.get_int("clear_cnt")))
info.add_child(Node.u32("route_flg", story.data.get_int("route_flg")))
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update blaster energy and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
earned_blaster_energy = request.child_value("earned_blaster_energy")
if earned_blaster_energy is not None:
newprofile.replace_int(
@ -3308,9 +3281,7 @@ class SoundVoltexGravityWarsSeason1(
# Miscelaneous stuff
newprofile.replace_int("blaster_count", request.child_value("blaster_count"))
newprofile.replace_int("skill_name_id", request.child_value("skill_name_id"))
newprofile.replace_int_array(
"hidden_param", 20, request.child_value("hidden_param")
)
newprofile.replace_int_array("hidden_param", 20, request.child_value("hidden_param"))
# Update user's unlock status if we aren't force unlocked
game_config = self.get_game_config()
@ -3324,22 +3295,13 @@ class SoundVoltexGravityWarsSeason1(
item_type = child.child_value("type")
param = child.child_value("param")
if (
game_config.get_bool("force_unlock_cards")
and item_type == self.GAME_CATALOG_TYPE_APPEAL_CARD
):
if game_config.get_bool("force_unlock_cards") and item_type == self.GAME_CATALOG_TYPE_APPEAL_CARD:
# Don't save back appeal cards because they were force unlocked
continue
if (
game_config.get_bool("force_unlock_songs")
and item_type == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and item_type == self.GAME_CATALOG_TYPE_SONG:
# Don't save back songs, because they were force unlocked
continue
if (
game_config.get_bool("force_unlock_crew")
and item_type == self.GAME_CATALOG_TYPE_CREW
):
if game_config.get_bool("force_unlock_crew") and item_type == self.GAME_CATALOG_TYPE_CREW:
# Don't save back crew, because they were force unlocked
continue

View File

@ -3850,22 +3850,15 @@ class SoundVoltexGravityWarsSeason2(
# Now, grab global and local scores as well as clear rates
global_records = self.data.remote.music.get_all_records(self.game, self.version)
users = {
uid: prof
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
}
users = {uid: prof for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)}
area_users = [uid for uid in users if users[uid].get_int("loc", -1) == locid]
area_records = self.data.local.music.get_all_records(
self.game, self.version, userlist=area_users
)
area_records = self.data.local.music.get_all_records(self.game, self.version, userlist=area_users)
clears = self.get_clear_rates()
records: Dict[int, Dict[int, Dict[str, Tuple[UserID, Score]]]] = {}
missing_users = [
userid for (userid, _) in global_records if userid not in users
] + [userid for (userid, _) in area_records if userid not in users]
missing_users = [userid for (userid, _) in global_records if userid not in users] + [
userid for (userid, _) in area_records if userid not in users
]
for userid, profile in self.get_any_profiles(missing_users):
users[userid] = profile
@ -3896,9 +3889,7 @@ class SoundVoltexGravityWarsSeason2(
global_profile = users[globaluserid]
if clears[musicid][chart]["total"] > 0:
clear_rate = float(clears[musicid][chart]["clears"]) / float(
clears[musicid][chart]["total"]
)
clear_rate = float(clears[musicid][chart]["clears"]) / float(clears[musicid][chart]["total"])
else:
clear_rate = 0.0
@ -3906,9 +3897,7 @@ class SoundVoltexGravityWarsSeason2(
highscores.add_child(info)
info.add_child(Node.u32("id", musicid))
info.add_child(Node.u32("ty", chart))
info.add_child(
Node.string("a_sq", ID.format_extid(global_profile.extid))
)
info.add_child(Node.string("a_sq", ID.format_extid(global_profile.extid)))
info.add_child(Node.string("a_nm", global_profile.get_str("name")))
info.add_child(Node.u32("a_sc", globalscore.points))
info.add_child(Node.s32("cr", int(clear_rate * 10000)))
@ -3916,9 +3905,7 @@ class SoundVoltexGravityWarsSeason2(
if "area" in records[musicid][chart]:
(localuserid, localscore) = records[musicid][chart]["area"]
local_profile = users[localuserid]
info.add_child(
Node.string("l_sq", ID.format_extid(local_profile.extid))
)
info.add_child(Node.string("l_sq", ID.format_extid(local_profile.extid)))
info.add_child(Node.string("l_nm", local_profile.get_str("name")))
info.add_child(Node.u32("l_sc", localscore.points))
@ -3946,15 +3933,11 @@ class SoundVoltexGravityWarsSeason2(
rival = Node.void("rival")
game.add_child(rival)
rival.add_child(Node.s16("no", index))
rival.add_child(
Node.string("seq", ID.format_extid(other_profile.extid))
)
rival.add_child(Node.string("seq", ID.format_extid(other_profile.extid)))
rival.add_child(Node.string("name", other_profile.get_str("name")))
# Return scores for this user on random charts
scores = self.data.remote.music.get_scores(
self.game, self.version, link.other_userid
)
scores = self.data.remote.music.get_scores(self.game, self.version, link.other_userid)
for score in scores:
music = Node.void("music")
rival.add_child(music)
@ -3975,14 +3958,10 @@ class SoundVoltexGravityWarsSeason2(
game.add_child(
Node.s16(
"skill_name_id",
profile.get_int(
"chosen_skill_id", profile.get_int("skill_name_id", -1)
),
profile.get_int("chosen_skill_id", profile.get_int("skill_name_id", -1)),
)
)
game.add_child(
Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20))
)
game.add_child(Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20)))
game.add_child(Node.u32("blaster_energy", profile.get_int("blaster_energy")))
game.add_child(Node.u32("blaster_count", profile.get_int("blaster_count")))
@ -4011,31 +3990,20 @@ class SoundVoltexGravityWarsSeason2(
game.add_child(itemnode)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for item in achievements:
if item.type[:5] != "item_":
continue
itemtype = int(item.type[5:])
if (
game_config.get_bool("force_unlock_songs")
and itemtype == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and itemtype == self.GAME_CATALOG_TYPE_SONG:
# Don't echo unlocked songs, we will add all of them later
continue
if (
game_config.get_bool("force_unlock_cards")
and itemtype == self.GAME_CATALOG_TYPE_APPEAL_CARD
):
if game_config.get_bool("force_unlock_cards") and itemtype == self.GAME_CATALOG_TYPE_APPEAL_CARD:
# Don't echo unlocked appeal cards, we will add all of them later
continue
if (
game_config.get_bool("force_unlock_crew")
and itemtype == self.GAME_CATALOG_TYPE_CREW
):
if game_config.get_bool("force_unlock_crew") and itemtype == self.GAME_CATALOG_TYPE_CREW:
# Don't echo unlocked crew, we will add all of them later
continue
@ -4104,8 +4072,7 @@ class SoundVoltexGravityWarsSeason2(
courselist = [
c
for c in self._get_skill_analyzer_courses()
if c.get("id", c["level"]) == course_id
and c["season_id"] == season_id
if c.get("id", c["level"]) == course_id and c["season_id"] == season_id
]
if len(courselist) > 0:
skill_level = max(skill_level, courselist[0]["level"])
@ -4132,9 +4099,7 @@ class SoundVoltexGravityWarsSeason2(
storynode.add_child(info)
info.add_child(Node.s32("story_id", story.id))
info.add_child(Node.s32("progress_id", story.data.get_int("progress_id")))
info.add_child(
Node.s32("progress_param", story.data.get_int("progress_param"))
)
info.add_child(Node.s32("progress_param", story.data.get_int("progress_param")))
info.add_child(Node.s32("clear_cnt", story.data.get_int("clear_cnt")))
info.add_child(Node.u32("route_flg", story.data.get_int("route_flg")))
@ -4157,22 +4122,16 @@ class SoundVoltexGravityWarsSeason2(
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update blaster energy and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
earned_blaster_energy = request.child_value("earned_blaster_energy")
if earned_blaster_energy is not None:
newprofile.replace_int(
@ -4183,9 +4142,7 @@ class SoundVoltexGravityWarsSeason2(
# Miscelaneous stuff
newprofile.replace_int("blaster_count", request.child_value("blaster_count"))
newprofile.replace_int("chosen_skill_id", request.child_value("skill_name_id"))
newprofile.replace_int_array(
"hidden_param", 20, request.child_value("hidden_param")
)
newprofile.replace_int_array("hidden_param", 20, request.child_value("hidden_param"))
# Update user's unlock status if we aren't force unlocked
game_config = self.get_game_config()
@ -4199,22 +4156,13 @@ class SoundVoltexGravityWarsSeason2(
item_type = child.child_value("type")
param = child.child_value("param")
if (
game_config.get_bool("force_unlock_cards")
and item_type == self.GAME_CATALOG_TYPE_APPEAL_CARD
):
if game_config.get_bool("force_unlock_cards") and item_type == self.GAME_CATALOG_TYPE_APPEAL_CARD:
# Don't save back appeal cards because they were force unlocked
continue
if (
game_config.get_bool("force_unlock_songs")
and item_type == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and item_type == self.GAME_CATALOG_TYPE_SONG:
# Don't save back songs, because they were force unlocked
continue
if (
game_config.get_bool("force_unlock_crew")
and item_type == self.GAME_CATALOG_TYPE_CREW
):
if game_config.get_bool("force_unlock_crew") and item_type == self.GAME_CATALOG_TYPE_CREW:
# Don't save back crew, because they were force unlocked
continue

View File

@ -68,9 +68,7 @@ class SoundVoltexHeavenlyHaven(
GAME_SKILL_NAME_ID_BMK2017: Final[int] = 19
GAME_SKILL_NAME_ID_KAC_7TH_TIGER: Final[int] = 20
GAME_SKILL_NAME_ID_KAC_7TH_WOLF: Final[int] = 21
GAME_SKILL_NAME_ID_RIKKA: Final[
int
] = 22 # For the course that ran from 1/18/2018-2/18/2018
GAME_SKILL_NAME_ID_RIKKA: Final[int] = 22 # For the course that ran from 1/18/2018-2/18/2018
GAME_SKILL_NAME_ID_KAC_8TH: Final[int] = 23
# Return the local2 service so that SDVX 4 and above will send certain packets.
@ -3336,9 +3334,7 @@ class SoundVoltexHeavenlyHaven(
skill_course = Node.void("skill_course")
game.add_child(skill_course)
achievements = self.data.local.user.get_all_achievements(
self.game, self.version, achievementtype="course"
)
achievements = self.data.local.user.get_all_achievements(self.game, self.version, achievementtype="course")
courserates: Dict[Tuple[int, int], Dict[str, int]] = {}
def getrates(season_id: int, course_id: int) -> Dict[str, int]:
@ -3372,14 +3368,8 @@ class SoundVoltexHeavenlyHaven(
info.add_child(Node.s32("season_id", course["season_id"]))
info.add_child(Node.string("season_name", seasons[course["season_id"]]))
info.add_child(
Node.bool("season_new_flg", course["season_id"] in {10, 11, 12, 22, 23})
)
info.add_child(
Node.s16(
"course_id", course.get("course_id", course.get("skill_level", -1))
)
)
info.add_child(Node.bool("season_new_flg", course["season_id"] in {10, 11, 12, 22, 23}))
info.add_child(Node.s16("course_id", course.get("course_id", course.get("skill_level", -1))))
info.add_child(
Node.string(
"course_name",
@ -3409,8 +3399,7 @@ class SoundVoltexHeavenlyHaven(
info.add_child(
Node.bool(
"matching_assist",
course.get("skill_level", -1) >= 1
and course.get("skill_level", -1) <= 7,
course.get("skill_level", -1) >= 1 and course.get("skill_level", -1) <= 7,
)
)
@ -3420,14 +3409,8 @@ class SoundVoltexHeavenlyHaven(
course.get("course_id", course.get("skill_level", -1)),
)
if rate["attempts"] > 0:
info.add_child(
Node.s32(
"clear_rate", int(100.0 * (rate["clears"] / rate["attempts"]))
)
)
info.add_child(
Node.u32("avg_score", rate["total_score"] // rate["attempts"])
)
info.add_child(Node.s32("clear_rate", int(100.0 * (rate["clears"] / rate["attempts"]))))
info.add_child(Node.u32("avg_score", rate["total_score"] // rate["attempts"]))
else:
info.add_child(Node.s32("clear_rate", 0))
info.add_child(Node.u32("avg_score", 0))
@ -3461,22 +3444,15 @@ class SoundVoltexHeavenlyHaven(
# Now, grab global and local scores as well as clear rates
global_records = self.data.remote.music.get_all_records(self.game, self.version)
users = {
uid: prof
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
}
users = {uid: prof for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)}
area_users = [uid for uid in users if users[uid].get_int("loc", -1) == locid]
area_records = self.data.local.music.get_all_records(
self.game, self.version, userlist=area_users
)
area_records = self.data.local.music.get_all_records(self.game, self.version, userlist=area_users)
clears = self.get_clear_rates()
records: Dict[int, Dict[int, Dict[str, Tuple[UserID, Score]]]] = {}
missing_users = [
userid for (userid, _) in global_records if userid not in users
] + [userid for (userid, _) in area_records if userid not in users]
missing_users = [userid for (userid, _) in global_records if userid not in users] + [
userid for (userid, _) in area_records if userid not in users
]
for userid, profile in self.get_any_profiles(missing_users):
users[userid] = profile
@ -3507,9 +3483,7 @@ class SoundVoltexHeavenlyHaven(
global_profile = users[globaluserid]
if clears[musicid][chart]["total"] > 0:
clear_rate = float(clears[musicid][chart]["clears"]) / float(
clears[musicid][chart]["total"]
)
clear_rate = float(clears[musicid][chart]["clears"]) / float(clears[musicid][chart]["total"])
else:
clear_rate = 0.0
@ -3517,9 +3491,7 @@ class SoundVoltexHeavenlyHaven(
highscores.add_child(info)
info.add_child(Node.u32("id", musicid))
info.add_child(Node.u32("ty", chart))
info.add_child(
Node.string("a_sq", ID.format_extid(global_profile.extid))
)
info.add_child(Node.string("a_sq", ID.format_extid(global_profile.extid)))
info.add_child(Node.string("a_nm", global_profile.get_str("name")))
info.add_child(Node.u32("a_sc", globalscore.points))
info.add_child(Node.s32("cr", int(clear_rate * 10000)))
@ -3528,9 +3500,7 @@ class SoundVoltexHeavenlyHaven(
if "area" in records[musicid][chart]:
(localuserid, localscore) = records[musicid][chart]["area"]
local_profile = users[localuserid]
info.add_child(
Node.string("l_sq", ID.format_extid(local_profile.extid))
)
info.add_child(Node.string("l_sq", ID.format_extid(local_profile.extid)))
info.add_child(Node.string("l_nm", local_profile.get_str("name")))
info.add_child(Node.u32("l_sc", localscore.points))
@ -3655,18 +3625,14 @@ class SoundVoltexHeavenlyHaven(
rival = Node.void("rival")
game.add_child(rival)
rival.add_child(Node.s16("no", index))
rival.add_child(
Node.string("seq", ID.format_extid(other_profile.extid))
)
rival.add_child(Node.string("seq", ID.format_extid(other_profile.extid)))
rival.add_child(Node.string("name", other_profile.get_str("name")))
# Keep track of index
index = index + 1
# Return scores for this user on random charts
scores = self.data.remote.music.get_scores(
self.game, self.version, link.other_userid
)
scores = self.data.remote.music.get_scores(self.game, self.version, link.other_userid)
for score in scores:
music = Node.void("music")
rival.add_child(music)
@ -3677,9 +3643,7 @@ class SoundVoltexHeavenlyHaven(
score.id,
score.chart,
score.points,
self.__db_to_game_clear_type(
score.data.get_int("clear_type")
),
self.__db_to_game_clear_type(score.data.get_int("clear_type")),
self.__db_to_game_grade(score.data.get_int("grade")),
],
)
@ -3956,31 +3920,20 @@ class SoundVoltexHeavenlyHaven(
game.add_child(itemnode)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for item in achievements:
if item.type[:5] != "item_":
continue
itemtype = int(item.type[5:])
if (
game_config.get_bool("force_unlock_songs")
and itemtype == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and itemtype == self.GAME_CATALOG_TYPE_SONG:
# Don't echo unlocked songs, we will add all of them later
continue
if (
game_config.get_bool("force_unlock_cards")
and itemtype == self.GAME_CATALOG_TYPE_APPEAL_CARD
):
if game_config.get_bool("force_unlock_cards") and itemtype == self.GAME_CATALOG_TYPE_APPEAL_CARD:
# Don't echo unlocked appeal cards, we will add all of them later
continue
if (
game_config.get_bool("force_unlock_crew")
and itemtype == self.GAME_CATALOG_TYPE_CREW
):
if game_config.get_bool("force_unlock_crew") and itemtype == self.GAME_CATALOG_TYPE_CREW:
# Don't echo unlocked crew, we will add all of them later
continue
@ -4047,8 +4000,7 @@ class SoundVoltexHeavenlyHaven(
courselist = [
c
for c in self.__get_skill_analyzer_courses()
if c.get("course_id", c.get("skill_level", -1)) == course_id
and c["season_id"] == season_id
if c.get("course_id", c.get("skill_level", -1)) == course_id and c["season_id"] == season_id
]
if len(courselist) > 0:
skill_level = max(skill_level, courselist[0]["skill_level"])
@ -4060,9 +4012,7 @@ class SoundVoltexHeavenlyHaven(
course_node.add_child(Node.s32("sc", course.data.get_int("score")))
course_node.add_child(Node.s16("ct", course.data.get_int("clear_type")))
course_node.add_child(Node.s16("gr", course.data.get_int("grade")))
course_node.add_child(
Node.s16("ar", course.data.get_int("achievement_rate"))
)
course_node.add_child(Node.s16("ar", course.data.get_int("achievement_rate")))
course_node.add_child(Node.s16("cnt", 1))
# Calculated skill level
@ -4104,22 +4054,16 @@ class SoundVoltexHeavenlyHaven(
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update blaster energy and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
earned_blaster_energy = request.child_value("earned_blaster_energy")
if earned_blaster_energy is not None:
newprofile.replace_int(
@ -4146,22 +4090,13 @@ class SoundVoltexHeavenlyHaven(
item_type = child.child_value("type")
param = child.child_value("param")
if (
game_config.get_bool("force_unlock_cards")
and item_type == self.GAME_CATALOG_TYPE_APPEAL_CARD
):
if game_config.get_bool("force_unlock_cards") and item_type == self.GAME_CATALOG_TYPE_APPEAL_CARD:
# Don't save back appeal cards because they were force unlocked
continue
if (
game_config.get_bool("force_unlock_songs")
and item_type == self.GAME_CATALOG_TYPE_SONG
):
if game_config.get_bool("force_unlock_songs") and item_type == self.GAME_CATALOG_TYPE_SONG:
# Don't save back songs, because they were force unlocked
continue
if (
game_config.get_bool("force_unlock_crew")
and item_type == self.GAME_CATALOG_TYPE_CREW
):
if game_config.get_bool("force_unlock_crew") and item_type == self.GAME_CATALOG_TYPE_CREW:
# Don't save back crew, because they were force unlocked
continue

View File

@ -1920,9 +1920,7 @@ class SoundVoltexInfiniteInfection(
elif unlock.type == "special_unlock":
info = Node.void("info")
catalog.add_child(info)
info.add_child(
Node.u8("catalog_type", self.GAME_CATALOG_TYPE_SPECIAL_SONG)
)
info.add_child(Node.u8("catalog_type", self.GAME_CATALOG_TYPE_SPECIAL_SONG))
info.add_child(Node.u32("catalog_id", unlock.id))
info.add_child(Node.u32("currency_type", self.GAME_CURRENCY_BLOCKS))
info.add_child(Node.u32("price", unlock.data.get_int("blocks")))
@ -1941,9 +1939,7 @@ class SoundVoltexInfiniteInfection(
info.add_child(Node.s16("level", course["level"]))
info.add_child(Node.s32("season_id", course["season_id"]))
info.add_child(Node.string("season_name", seasons[course["season_id"]]))
info.add_child(
Node.bool("season_new_flg", course["season_id"] == last_season)
)
info.add_child(Node.bool("season_new_flg", course["season_id"] == last_season))
info.add_child(Node.string("course_name", skillnames[course["level"]]))
info.add_child(Node.s16("course_type", 0))
info.add_child(Node.s16("skill_name_id", course["level"]))
@ -1983,10 +1979,7 @@ class SoundVoltexInfiniteInfection(
# Now, grab user records
records = self.data.remote.music.get_all_records(self.game, self.version)
missing_users = [userid for (userid, _) in records]
users = {
userid: profile
for (userid, profile) in self.get_any_profiles(missing_users)
}
users = {userid: profile for (userid, profile) in self.get_any_profiles(missing_users)}
hiscore_allover = Node.void("hiscore_allover")
game.add_child(hiscore_allover)
@ -2011,14 +2004,10 @@ class SoundVoltexInfiniteInfection(
# Now, grab local records
area_users = [
uid
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)
if prof.get_int("loc", -1) == locid
]
records = self.data.local.music.get_all_records(
self.game, self.version, userlist=area_users
)
records = self.data.local.music.get_all_records(self.game, self.version, userlist=area_users)
missing_users = [userid for (userid, _) in records if userid not in users]
for userid, profile in self.get_any_profiles(missing_users):
users[userid] = profile
@ -2051,9 +2040,7 @@ class SoundVoltexInfiniteInfection(
for songid in clears:
for chart in clears[songid]:
if clears[songid][chart]["total"] > 0:
rate = float(clears[songid][chart]["clears"]) / float(
clears[songid][chart]["total"]
)
rate = float(clears[songid][chart]["clears"]) / float(clears[songid][chart]["total"])
dnode = Node.void("d")
clear_rate.add_child(dnode)
dnode.add_child(Node.u32("id", songid))
@ -2155,11 +2142,7 @@ class SoundVoltexInfiniteInfection(
self.__db_to_game_clear_type(score.data.get_int("clear_type")),
)
)
music.add_child(
Node.u32(
"score_grade", self.__db_to_game_grade(score.data.get_int("grade"))
)
)
music.add_child(Node.u32("score_grade", self.__db_to_game_grade(score.data.get_int("grade"))))
stats = score.data.get_dict("stats")
music.add_child(Node.u32("btn_rate", stats.get_int("btn_rate")))
music.add_child(Node.u32("long_rate", stats.get_int("long_rate")))
@ -2330,9 +2313,7 @@ class SoundVoltexInfiniteInfection(
game.add_child(Node.u32("gamecoin_packet", profile.get_int("packet")))
game.add_child(Node.u32("gamecoin_block", profile.get_int("block")))
game.add_child(Node.s16("skill_name_id", profile.get_int("skill_name_id", -1)))
game.add_child(
Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20))
)
game.add_child(Node.s32_array("hidden_param", profile.get_int_array("hidden_param", 20)))
game.add_child(Node.u32("blaster_energy", profile.get_int("blaster_energy")))
game.add_child(Node.u32("blaster_count", profile.get_int("blaster_count")))
@ -2362,9 +2343,7 @@ class SoundVoltexInfiniteInfection(
game.add_child(itemnode)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(
self.game, self.version, userid
)
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for item in achievements:
if item.type[:5] != "item_":
@ -2375,9 +2354,7 @@ class SoundVoltexInfiniteInfection(
# Type 1 is appeal cards, and the game saves this for non-default cards but
# we take care of this below.
continue
if itemtype == self.GAME_CATALOG_TYPE_SONG and game_config.get_bool(
"force_unlock_songs"
):
if itemtype == self.GAME_CATALOG_TYPE_SONG and game_config.get_bool("force_unlock_songs"):
# We will echo this below in the force unlock song section
continue
@ -2452,22 +2429,16 @@ class SoundVoltexInfiniteInfection(
return game
def unformat_profile(
self, userid: UserID, request: Node, oldprofile: Profile
) -> Profile:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = oldprofile.clone()
# Update blaster energy and in-game currencies
earned_gamecoin_packet = request.child_value("earned_gamecoin_packet")
if earned_gamecoin_packet is not None:
newprofile.replace_int(
"packet", newprofile.get_int("packet") + earned_gamecoin_packet
)
newprofile.replace_int("packet", newprofile.get_int("packet") + earned_gamecoin_packet)
earned_gamecoin_block = request.child_value("earned_gamecoin_block")
if earned_gamecoin_block is not None:
newprofile.replace_int(
"block", newprofile.get_int("block") + earned_gamecoin_block
)
newprofile.replace_int("block", newprofile.get_int("block") + earned_gamecoin_block)
earned_blaster_energy = request.child_value("earned_blaster_energy")
if earned_blaster_energy is not None:
newprofile.replace_int(
@ -2478,9 +2449,7 @@ class SoundVoltexInfiniteInfection(
# Miscelaneous stuff
newprofile.replace_int("blaster_count", request.child_value("blaster_count"))
newprofile.replace_int("skill_name_id", request.child_value("skill_name_id"))
newprofile.replace_int_array(
"hidden_param", 20, request.child_value("hidden_param")
)
newprofile.replace_int_array("hidden_param", 20, request.child_value("hidden_param"))
# Update user's unlock status if we aren't force unlocked
game_config = self.get_game_config()

View File

@ -22,9 +22,7 @@ class BaseClient:
CORRECT_PASSWORD: Final[str] = "1234"
WRONG_PASSWORD: Final[str] = "4321"
def __init__(
self, proto: ClientProtocol, pcbid: str, config: Dict[str, Any]
) -> None:
def __init__(self, proto: ClientProtocol, pcbid: str, config: Dict[str, Any]) -> None:
self.__proto = proto
self.pcbid = pcbid
self.config = config
@ -92,9 +90,7 @@ class BaseClient:
if not self.__assert_path(root, path):
raise Exception(f"Path '{path}' not found in root node:\n{root}")
def verify_services_get(
self, expected_services: List[str] = [], include_net: bool = False
) -> None:
def verify_services_get(self, expected_services: List[str] = [], include_net: bool = False) -> None:
call = self.call_node()
# Construct node
@ -254,9 +250,7 @@ class BaseClient:
# Verify that response is correct
self.assert_path(resp, "response/pcbevent")
def verify_cardmng_inquire(
self, card_id: str, msg_type: str, paseli_enabled: bool
) -> Optional[str]:
def verify_cardmng_inquire(self, card_id: str, msg_type: str, paseli_enabled: bool) -> Optional[str]:
call = self.call_node()
# Construct node
@ -295,17 +289,11 @@ class BaseClient:
ecflag = int(resp.child("cardmng").attribute("ecflag"))
if binded != 0:
raise Exception(
f"Card '{card_id}' returned invalid binded value '{binded}'"
)
raise Exception(f"Card '{card_id}' returned invalid binded value '{binded}'")
if newflag != 1:
raise Exception(
f"Card '{card_id}' returned invalid newflag value '{newflag}'"
)
raise Exception(f"Card '{card_id}' returned invalid newflag value '{newflag}'")
if ecflag != (1 if paseli_enabled else 0):
raise Exception(
f"Card '{card_id}' returned invalid ecflag value '{newflag}'"
)
raise Exception(f"Card '{card_id}' returned invalid ecflag value '{newflag}'")
# Return the refid
return resp.child("cardmng").attribute("refid")
@ -321,17 +309,11 @@ class BaseClient:
ecflag = int(resp.child("cardmng").attribute("ecflag"))
if binded != 1:
raise Exception(
f"Card '{card_id}' returned invalid binded value '{binded}'"
)
raise Exception(f"Card '{card_id}' returned invalid binded value '{binded}'")
if newflag != 0:
raise Exception(
f"Card '{card_id}' returned invalid newflag value '{newflag}'"
)
raise Exception(f"Card '{card_id}' returned invalid newflag value '{newflag}'")
if ecflag != (1 if paseli_enabled else 0):
raise Exception(
f"Card '{card_id}' returned invalid ecflag value '{newflag}'"
)
raise Exception(f"Card '{card_id}' returned invalid ecflag value '{newflag}'")
# Return the refid
return resp.child("cardmng").attribute("refid")
@ -365,9 +347,7 @@ class BaseClient:
cardmng = Node.void("cardmng")
call.add_child(cardmng)
cardmng.set_attribute("method", "authpass")
cardmng.set_attribute(
"pass", self.CORRECT_PASSWORD if correct else self.CORRECT_PASSWORD[::-1]
)
cardmng.set_attribute("pass", self.CORRECT_PASSWORD if correct else self.CORRECT_PASSWORD[::-1])
cardmng.set_attribute("refid", ref_id)
# Swap with server
@ -426,9 +406,7 @@ class BaseClient:
newbalance = resp.child("eacoin").child_value("balance")
if balance - amount != newbalance:
raise Exception(
f"Expected to get back balance {balance - amount} but got {newbalance}"
)
raise Exception(f"Expected to get back balance {balance - amount} but got {newbalance}")
def verify_eacoin_checkout(self, session: str) -> None:
call = self.call_node()

View File

@ -190,32 +190,22 @@ class TheStarBishiBashiClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Bishi doesn't read a new profile, it just writes out CSV for a blank one
self.verify_usergamedata_send(ref_id, msg_type="new")
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -403,9 +403,7 @@ class DDR2013Client(BaseClient):
scores[reclink][chart] = vals
return scores
def verify_game_save(
self, ref_id: str, style: int, gauge: Optional[List[int]] = None
) -> None:
def verify_game_save(self, ref_id: str, style: int, gauge: Optional[List[int]] = None) -> None:
gauge = gauge or [0, 0, 0, 0, 0]
call = self.call_node()
@ -460,9 +458,7 @@ class DDR2013Client(BaseClient):
int(resp.child("game").attribute("sc5")),
]
def verify_game_save_m(
self, ref_id: str, ext_id: str, score: Dict[str, Any]
) -> None:
def verify_game_save_m(self, ref_id: str, ext_id: str, score: Dict[str, Any]) -> None:
call = self.call_node()
game = Node.void("game")
call.add_child(game)
@ -544,33 +540,23 @@ class DDR2013Client(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Bishi doesn't read a new profile, it just writes out CSV for a blank one
self.verify_game_load(ref_id, msg_type="new")
self.verify_game_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify locking and unlocking profile ability
@ -703,22 +689,16 @@ class DDR2013Client(BaseClient):
# Verify empty scores for starters
if phase == 1:
for score in dummyscores:
last_five = self.verify_game_score(
ref_id, score["id"], score["chart"]
)
last_five = self.verify_game_score(ref_id, score["id"], score["chart"])
if any([s != 0 for s in last_five]):
raise Exception(
"Score already found on song not played yet!"
)
raise Exception("Score already found on song not played yet!")
for score in dummyscores:
self.verify_game_save_m(ref_id, ext_id, score)
scores = self.verify_game_load_m(ref_id)
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
# Verify the attributes of the score
expected_score = score.get("expected_score", score["score"])
@ -739,9 +719,7 @@ class DDR2013Client(BaseClient):
)
# Verify that the last score is our score
last_five = self.verify_game_score(
ref_id, score["id"], score["chart"]
)
last_five = self.verify_game_score(ref_id, score["id"], score["chart"])
if last_five[0] != score["score"]:
raise Exception(
f'Invalid score returned for last five scores on song {score["id"]} chart {score["chart"]}!'

View File

@ -423,9 +423,7 @@ class DDR2014Client(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/game")
def verify_game_save(
self, ref_id: str, style: int, gauge: Optional[List[int]] = None
) -> None:
def verify_game_save(self, ref_id: str, style: int, gauge: Optional[List[int]] = None) -> None:
gauge = gauge or [0, 0, 0, 0, 0]
call = self.call_node()
@ -453,9 +451,7 @@ class DDR2014Client(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/game")
def verify_game_save_m(
self, ref_id: str, ext_id: str, score: Dict[str, Any]
) -> None:
def verify_game_save_m(self, ref_id: str, ext_id: str, score: Dict[str, Any]) -> None:
call = self.call_node()
game = Node.void("game")
call.add_child(game)
@ -546,33 +542,23 @@ class DDR2014Client(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Bishi doesn't read a new profile, it just writes out CSV for a blank one
self.verify_game_load(ref_id, msg_type="new")
self.verify_game_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify locking and unlocking profile ability
@ -709,9 +695,7 @@ class DDR2014Client(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
# Verify the attributes of the score
expected_score = score.get("expected_score", score["score"])

View File

@ -99,9 +99,7 @@ class DDRAceClient(BaseClient):
return resp.child_value("playerdata/code")
def verify_playerdata_usergamedata_advanced_ghostload(
self, refid: str, ghostid: int
) -> Dict[str, Any]:
def verify_playerdata_usergamedata_advanced_ghostload(self, refid: str, ghostid: int) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -140,9 +138,7 @@ class DDRAceClient(BaseClient):
"ghost": resp.child_value("playerdata/ghostdata/ghost"),
}
def verify_playerdata_usergamedata_advanced_rivalload(
self, refid: str, loadflag: int
) -> None:
def verify_playerdata_usergamedata_advanced_rivalload(self, refid: str, loadflag: int) -> None:
call = self.call_node()
# Construct node
@ -191,9 +187,7 @@ class DDRAceClient(BaseClient):
if resp.child_value("playerdata/data/recordtype") != loadflag:
raise Exception("Invalid record type returned!")
def verify_playerdata_usergamedata_advanced_userload(
self, refid: str
) -> Tuple[bool, List[Dict[str, Any]]]:
def verify_playerdata_usergamedata_advanced_userload(self, refid: str) -> Tuple[bool, List[Dict[str, Any]]]:
call = self.call_node()
# Construct node
@ -252,9 +246,7 @@ class DDRAceClient(BaseClient):
music,
)
def verify_playerdata_usergamedata_advanced_inheritance(
self, refid: str, locid: str
) -> None:
def verify_playerdata_usergamedata_advanced_inheritance(self, refid: str, locid: str) -> None:
call = self.call_node()
# Construct node
@ -454,9 +446,7 @@ class DDRAceClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/playerdata/result")
def verify_usergamedata_send(
self, ref_id: str, ext_id: int, msg_type: str, send_only_common: bool = False
) -> None:
def verify_usergamedata_send(self, ref_id: str, ext_id: int, msg_type: str, send_only_common: bool = False) -> None:
call = self.call_node()
# Set up profile write
@ -720,9 +710,7 @@ class DDRAceClient(BaseClient):
self.verify_eventlog_write(location)
# Verify the game-wide packets Ace insists on sending before profile load
is_new, music = self.verify_playerdata_usergamedata_advanced_userload(
"X0000000000000000000000000123456"
)
is_new, music = self.verify_playerdata_usergamedata_advanced_userload("X0000000000000000000000000123456")
if not is_new:
raise Exception("Fake profiles should be new!")
if len(music) > 0:
@ -736,18 +724,12 @@ class DDRAceClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
self.verify_system_convcardnumber(card)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
extid = self.verify_playerdata_usergamedata_advanced_usernew(ref_id)
self.verify_usergamedata_send(ref_id, extid, "new")
@ -755,30 +737,22 @@ class DDRAceClient(BaseClient):
name = self.verify_usergamedata_recv(ref_id)
if name != "":
raise Exception("Name stored on profile we just created!")
self.verify_usergamedata_send(
ref_id, extid, "existing", send_only_common=True
)
self.verify_usergamedata_send(ref_id, extid, "existing", send_only_common=True)
name = self.verify_usergamedata_recv(ref_id)
if name != self.NAME:
raise Exception("Name stored on profile is incorrect!")
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
is_new, music = self.verify_playerdata_usergamedata_advanced_userload(
ref_id
)
is_new, music = self.verify_playerdata_usergamedata_advanced_userload(ref_id)
if is_new:
raise Exception("Profile should not be new!")
if len(music) > 0:
@ -862,9 +836,7 @@ class DDRAceClient(BaseClient):
)
pos = pos + 1
is_new, scores = self.verify_playerdata_usergamedata_advanced_userload(
ref_id
)
is_new, scores = self.verify_playerdata_usergamedata_advanced_userload(ref_id)
if is_new:
raise Exception("Profile should not be new!")
if len(scores) == 0:
@ -873,17 +845,12 @@ class DDRAceClient(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
@ -912,9 +879,7 @@ class DDRAceClient(BaseClient):
)
# Now verify that the ghost for this score is what we saved
ghost = self.verify_playerdata_usergamedata_advanced_ghostload(
ref_id, received["ghostid"]
)
ghost = self.verify_playerdata_usergamedata_advanced_ghostload(ref_id, received["ghostid"])
if "expected_ghost" in expected:
expected_ghost = expected["expected_ghost"]
else:
@ -933,9 +898,7 @@ class DDRAceClient(BaseClient):
f'Wrong ghost data \'{ghost["ghost"]}\' returned for ghost, expected \'{expected_ghost}\''
)
if ghost["extid"] != extid:
raise Exception(
f'Wrong extid \'{ghost["extid"]}\' returned for ghost, expected \'{extid}\''
)
raise Exception(f'Wrong extid \'{ghost["extid"]}\' returned for ghost, expected \'{extid}\'')
# Sleep so we don't end up putting in score history on the same second
time.sleep(1)
@ -952,15 +915,9 @@ class DDRAceClient(BaseClient):
print("Skipping score checks for existing card")
# Verify global scores now that we've inserted some
self.verify_playerdata_usergamedata_advanced_rivalload(
"X0000000000000000000000000123456", 1
)
self.verify_playerdata_usergamedata_advanced_rivalload(
"X0000000000000000000000000123456", 2
)
self.verify_playerdata_usergamedata_advanced_rivalload(
"X0000000000000000000000000123456", 4
)
self.verify_playerdata_usergamedata_advanced_rivalload("X0000000000000000000000000123456", 1)
self.verify_playerdata_usergamedata_advanced_rivalload("X0000000000000000000000000123456", 2)
self.verify_playerdata_usergamedata_advanced_rivalload("X0000000000000000000000000123456", 4)
# Verify paseli handling
if paseli_enabled:

View File

@ -347,9 +347,7 @@ class DDRX2Client(BaseClient):
index = index + 1
return courses
def verify_game_save(
self, ref_id: str, style: int, gauge: Optional[List[int]] = None
) -> None:
def verify_game_save(self, ref_id: str, style: int, gauge: Optional[List[int]] = None) -> None:
gauge = gauge or [0, 0, 0, 0, 0]
call = self.call_node()
@ -502,33 +500,23 @@ class DDRX2Client(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Bishi doesn't read a new profile, it just writes out CSV for a blank one
self.verify_game_load(ref_id, msg_type="new")
self.verify_game_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify locking and unlocking profile ability
@ -655,22 +643,16 @@ class DDRX2Client(BaseClient):
# Verify empty scores for starters
if phase == 1:
for score in dummyscores:
last_five = self.verify_game_score(
ref_id, score["id"], score["chart"]
)
last_five = self.verify_game_score(ref_id, score["id"], score["chart"])
if any([s != 0 for s in last_five]):
raise Exception(
"Score already found on song not played yet!"
)
raise Exception("Score already found on song not played yet!")
for score in dummyscores:
self.verify_game_save_m(ref_id, score)
scores = self.verify_game_load_m(ref_id)
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
# Verify the attributes of the score
expected_score = score.get("expected_score", score["score"])
@ -691,9 +673,7 @@ class DDRX2Client(BaseClient):
)
# Verify that the last score is our score
last_five = self.verify_game_score(
ref_id, score["id"], score["chart"]
)
last_five = self.verify_game_score(ref_id, score["id"], score["chart"])
if last_five[0] != score["score"]:
raise Exception(
f'Invalid score returned for last five scores on song {score["id"]} chart {score["chart"]}!'
@ -769,9 +749,7 @@ class DDRX2Client(BaseClient):
expected_combo = course.get("expected_combo", course["combo"])
expected_rank = course.get("expected_rank", course["rank"])
expected_stage = course.get("expected_stage", course["stage"])
expected_combo_type = course.get(
"expected_combo_type", course["combo_type"]
)
expected_combo_type = course.get("expected_combo_type", course["combo_type"])
if data["score"] != expected_score:
raise Exception(

View File

@ -414,9 +414,7 @@ class DDRX3Client(BaseClient):
index = index + 1
return courses
def verify_game_save(
self, ref_id: str, style: int, gauge: Optional[List[int]] = None
) -> None:
def verify_game_save(self, ref_id: str, style: int, gauge: Optional[List[int]] = None) -> None:
gauge = gauge or [0, 0, 0, 0, 0]
call = self.call_node()
@ -579,33 +577,23 @@ class DDRX3Client(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Bishi doesn't read a new profile, it just writes out CSV for a blank one
self.verify_game_load(ref_id, msg_type="new")
self.verify_game_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify locking and unlocking profile ability
@ -778,33 +766,23 @@ class DDRX3Client(BaseClient):
# Verify empty scores for starters
if phase == 1:
for score in dummyscores:
last_five = self.verify_game_score(
ref_id, score["id"], score["chart"]
)
last_five = self.verify_game_score(ref_id, score["id"], score["chart"])
if any([s != 0 for s in last_five]):
raise Exception(
"Score already found on song not played yet!"
)
raise Exception("Score already found on song not played yet!")
for score in dummyscores:
self.verify_game_save_m(ref_id, score)
scores = self.verify_game_load_m(ref_id)
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
# Verify the attributes of the score
expected_score = score.get("expected_score", score["score"])
expected_rank = score.get("expected_rank", score["rank"])
expected_halo = score.get("expected_halo", score["halo"])
expected_score_2nd = score.get(
"expected_score_2nd", score["score_2nd"]
)
expected_rank_2nd = score.get(
"expected_rank_2nd", score["rank_2nd"]
)
expected_score_2nd = score.get("expected_score_2nd", score["score_2nd"])
expected_rank_2nd = score.get("expected_rank_2nd", score["rank_2nd"])
if score["score"] != 0:
if data["score"] != expected_score:
@ -821,9 +799,7 @@ class DDRX3Client(BaseClient):
)
# Verify that the last score is our score
last_five = self.verify_game_score(
ref_id, score["id"], score["chart"]
)
last_five = self.verify_game_score(ref_id, score["id"], score["chart"])
if last_five[0] != score["score"]:
raise Exception(
f'Invalid score returned for last five scores on song {score["id"]} chart {score["chart"]}!'
@ -908,9 +884,7 @@ class DDRX3Client(BaseClient):
expected_combo = course.get("expected_combo", course["combo"])
expected_rank = course.get("expected_rank", course["rank"])
expected_stage = course.get("expected_stage", course["stage"])
expected_combo_type = course.get(
"expected_combo_type", course["combo_type"]
)
expected_combo_type = course.get("expected_combo_type", course["combo_type"])
if data["score"] != expected_score:
raise Exception(

View File

@ -91,9 +91,7 @@ class IIDXCannonBallersClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 1001:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_iidx25shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -175,9 +173,7 @@ class IIDXCannonBallersClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/IIDX25shop")
def verify_iidx25pc_get(
self, ref_id: str, card_id: str, lid: str
) -> Dict[str, Any]:
def verify_iidx25pc_get(self, ref_id: str, card_id: str, lid: str) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -297,9 +293,7 @@ class IIDXCannonBallersClient(BaseClient):
"expert_point": expert_point,
}
def verify_iidx25music_getrank(
self, extid: int
) -> Dict[int, Dict[int, Dict[str, int]]]:
def verify_iidx25music_getrank(self, extid: int) -> Dict[int, Dict[int, Dict[str, int]]]:
scores: Dict[int, Dict[int, Dict[str, int]]] = {}
for cltype in [0, 1]: # singles, doubles
call = self.call_node()
@ -321,9 +315,7 @@ class IIDXCannonBallersClient(BaseClient):
for child in resp.child("IIDX25music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -461,9 +453,7 @@ class IIDXCannonBallersClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX25pc")
def verify_iidx25music_reg(
self, extid: int, lid: str, score: Dict[str, Any]
) -> None:
def verify_iidx25music_reg(self, extid: int, lid: str, score: Dict[str, Any]) -> None:
call = self.call_node()
# Construct node
@ -491,9 +481,7 @@ class IIDXCannonBallersClient(BaseClient):
self.assert_path(resp, "response/IIDX25music/shopdata/@rank")
self.assert_path(resp, "response/IIDX25music/ranklist/data")
def verify_iidx25music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_iidx25music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -618,9 +606,7 @@ class IIDXCannonBallersClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX25music")
def verify_iidx25grade_raised(
self, iidxid: int, shop_name: str, dantype: str
) -> None:
def verify_iidx25grade_raised(self, iidxid: int, shop_name: str, dantype: str) -> None:
call = self.call_node()
# Construct node
@ -644,9 +630,7 @@ class IIDXCannonBallersClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX25grade/@pnum")
def verify_iidx25ranking_entry(
self, iidxid: int, shop_name: str, coursetype: str
) -> None:
def verify_iidx25ranking_entry(self, iidxid: int, shop_name: str, coursetype: str) -> None:
call = self.call_node()
# Construct node
@ -757,13 +741,9 @@ class IIDXCannonBallersClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX25music/cpu_score_list/score_list/score")
self.assert_path(
resp, "response/IIDX25music/cpu_score_list/score_list/enable_score"
)
self.assert_path(resp, "response/IIDX25music/cpu_score_list/score_list/enable_score")
self.assert_path(resp, "response/IIDX25music/cpu_score_list/score_list/ghost")
self.assert_path(
resp, "response/IIDX25music/cpu_score_list/score_list/enable_ghost"
)
self.assert_path(resp, "response/IIDX25music/cpu_score_list/score_list/enable_ghost")
def verify_iidx25gamesystem_systeminfo(self, lid: str) -> None:
call = self.call_node()
@ -820,32 +800,22 @@ class IIDXCannonBallersClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_iidx25pc_reg(ref_id, card, lid)
self.verify_iidx25pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -940,9 +910,7 @@ class IIDXCannonBallersClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -971,9 +939,7 @@ class IIDXCannonBallersClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_iidx25music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_iidx25music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -1078,9 +1044,7 @@ class IIDXCannonBallersClient(BaseClient):
)
scores = self.verify_iidx25music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:
@ -1101,12 +1065,8 @@ class IIDXCannonBallersClient(BaseClient):
self.verify_iidx25ranking_classicentry(profile["extid"])
profile = self.verify_iidx25pc_get(ref_id, card, lid)
for ptype in ["ir_data", "secret_course_data", "classic_course_data"]:
if profile[ptype] != {
2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}
}:
raise Exception(
f"Invalid data {profile[ptype]} returned on profile load for {ptype}!"
)
if profile[ptype] != {2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}}:
raise Exception(f"Invalid data {profile[ptype]} returned on profile load for {ptype}!")
else:
print("Skipping score checks for existing card")

View File

@ -90,9 +90,7 @@ class IIDXCopulaClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 101:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_iidx23shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -171,9 +169,7 @@ class IIDXCopulaClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/IIDX23shop")
def verify_iidx23pc_get(
self, ref_id: str, card_id: str, lid: str
) -> Dict[str, Any]:
def verify_iidx23pc_get(self, ref_id: str, card_id: str, lid: str) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -269,9 +265,7 @@ class IIDXCopulaClient(BaseClient):
"expert_point": expert_point,
}
def verify_iidx23music_getrank(
self, extid: int
) -> Dict[int, Dict[int, Dict[str, int]]]:
def verify_iidx23music_getrank(self, extid: int) -> Dict[int, Dict[int, Dict[str, int]]]:
scores: Dict[int, Dict[int, Dict[str, int]]] = {}
for cltype in [0, 1]: # singles, doubles
call = self.call_node()
@ -293,9 +287,7 @@ class IIDXCopulaClient(BaseClient):
for child in resp.child("IIDX23music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -434,9 +426,7 @@ class IIDXCopulaClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX23pc")
def verify_iidx23music_reg(
self, extid: int, lid: str, score: Dict[str, Any]
) -> None:
def verify_iidx23music_reg(self, extid: int, lid: str, score: Dict[str, Any]) -> None:
call = self.call_node()
# Construct node
@ -464,9 +454,7 @@ class IIDXCopulaClient(BaseClient):
self.assert_path(resp, "response/IIDX23music/shopdata/@rank")
self.assert_path(resp, "response/IIDX23music/ranklist/data")
def verify_iidx23music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_iidx23music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -586,9 +574,7 @@ class IIDXCopulaClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX23music")
def verify_iidx23grade_raised(
self, iidxid: int, shop_name: str, dantype: str
) -> None:
def verify_iidx23grade_raised(self, iidxid: int, shop_name: str, dantype: str) -> None:
call = self.call_node()
# Construct node
@ -612,9 +598,7 @@ class IIDXCopulaClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX23grade/@pnum")
def verify_iidx23ranking_entry(
self, iidxid: int, shop_name: str, coursetype: str
) -> None:
def verify_iidx23ranking_entry(self, iidxid: int, shop_name: str, coursetype: str) -> None:
call = self.call_node()
# Construct node
@ -682,32 +666,22 @@ class IIDXCopulaClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_iidx23pc_reg(ref_id, card, lid)
self.verify_iidx23pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -802,9 +776,7 @@ class IIDXCopulaClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -833,9 +805,7 @@ class IIDXCopulaClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_iidx23music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_iidx23music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -940,9 +910,7 @@ class IIDXCopulaClient(BaseClient):
)
scores = self.verify_iidx23music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:
@ -962,12 +930,8 @@ class IIDXCopulaClient(BaseClient):
self.verify_iidx23ranking_entry(profile["extid"], newname, "secret")
profile = self.verify_iidx23pc_get(ref_id, card, lid)
for ptype in ["ir_data", "secret_course_data"]:
if profile[ptype] != {
2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}
}:
raise Exception(
f"Invalid data {profile[ptype]} returned on profile load for {ptype}!"
)
if profile[ptype] != {2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}}:
raise Exception(f"Invalid data {profile[ptype]} returned on profile load for {ptype}!")
else:
print("Skipping score checks for existing card")

View File

@ -90,9 +90,7 @@ class IIDXPendualClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 101:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_iidx22shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -171,9 +169,7 @@ class IIDXPendualClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/IIDX22shop")
def verify_iidx22pc_get(
self, ref_id: str, card_id: str, lid: str
) -> Dict[str, Any]:
def verify_iidx22pc_get(self, ref_id: str, card_id: str, lid: str) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -270,9 +266,7 @@ class IIDXPendualClient(BaseClient):
"expert_point": expert_point,
}
def verify_iidx22music_getrank(
self, extid: int
) -> Dict[int, Dict[int, Dict[str, int]]]:
def verify_iidx22music_getrank(self, extid: int) -> Dict[int, Dict[int, Dict[str, int]]]:
scores: Dict[int, Dict[int, Dict[str, int]]] = {}
for cltype in [0, 1]: # singles, doubles
call = self.call_node()
@ -294,9 +288,7 @@ class IIDXPendualClient(BaseClient):
for child in resp.child("IIDX22music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -435,9 +427,7 @@ class IIDXPendualClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX22pc")
def verify_iidx22music_reg(
self, extid: int, lid: str, score: Dict[str, Any]
) -> None:
def verify_iidx22music_reg(self, extid: int, lid: str, score: Dict[str, Any]) -> None:
call = self.call_node()
# Construct node
@ -465,9 +455,7 @@ class IIDXPendualClient(BaseClient):
self.assert_path(resp, "response/IIDX22music/shopdata/@rank")
self.assert_path(resp, "response/IIDX22music/ranklist/data")
def verify_iidx22music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_iidx22music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -587,9 +575,7 @@ class IIDXPendualClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX22music")
def verify_iidx22grade_raised(
self, iidxid: int, shop_name: str, dantype: str
) -> None:
def verify_iidx22grade_raised(self, iidxid: int, shop_name: str, dantype: str) -> None:
call = self.call_node()
# Construct node
@ -613,9 +599,7 @@ class IIDXPendualClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX22grade/@pnum")
def verify_iidx22ranking_entry(
self, iidxid: int, shop_name: str, coursetype: str
) -> None:
def verify_iidx22ranking_entry(self, iidxid: int, shop_name: str, coursetype: str) -> None:
call = self.call_node()
# Construct node
@ -683,32 +667,22 @@ class IIDXPendualClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_iidx22pc_reg(ref_id, card, lid)
self.verify_iidx22pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -803,9 +777,7 @@ class IIDXPendualClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -834,9 +806,7 @@ class IIDXPendualClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_iidx22music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_iidx22music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -941,9 +911,7 @@ class IIDXPendualClient(BaseClient):
)
scores = self.verify_iidx22music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:
@ -963,12 +931,8 @@ class IIDXPendualClient(BaseClient):
self.verify_iidx22ranking_entry(profile["extid"], newname, "secret")
profile = self.verify_iidx22pc_get(ref_id, card, lid)
for ptype in ["ir_data", "secret_course_data"]:
if profile[ptype] != {
2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}
}:
raise Exception(
f"Invalid data {profile[ptype]} returned on profile load for {ptype}!"
)
if profile[ptype] != {2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}}:
raise Exception(f"Invalid data {profile[ptype]} returned on profile load for {ptype}!")
else:
print("Skipping score checks for existing card")

View File

@ -90,9 +90,7 @@ class IIDXRootageClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 1001:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_iidx26shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -174,9 +172,7 @@ class IIDXRootageClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/IIDX26shop")
def verify_iidx26pc_get(
self, ref_id: str, card_id: str, lid: str
) -> Dict[str, Any]:
def verify_iidx26pc_get(self, ref_id: str, card_id: str, lid: str) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -238,9 +234,7 @@ class IIDXRootageClient(BaseClient):
"expert_point": expert_point,
}
def verify_iidx26music_getrank(
self, extid: int
) -> Dict[int, Dict[int, Dict[str, int]]]:
def verify_iidx26music_getrank(self, extid: int) -> Dict[int, Dict[int, Dict[str, int]]]:
scores: Dict[int, Dict[int, Dict[str, int]]] = {}
for cltype in [0, 1]: # singles, doubles
call = self.call_node()
@ -262,9 +256,7 @@ class IIDXRootageClient(BaseClient):
for child in resp.child("IIDX26music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -406,9 +398,7 @@ class IIDXRootageClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX26pc")
def verify_iidx26music_reg(
self, extid: int, lid: str, score: Dict[str, Any]
) -> None:
def verify_iidx26music_reg(self, extid: int, lid: str, score: Dict[str, Any]) -> None:
call = self.call_node()
# Construct node
@ -436,9 +426,7 @@ class IIDXRootageClient(BaseClient):
self.assert_path(resp, "response/IIDX26music/shopdata/@rank")
self.assert_path(resp, "response/IIDX26music/ranklist/data")
def verify_iidx26music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_iidx26music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -563,9 +551,7 @@ class IIDXRootageClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX26music")
def verify_iidx26grade_raised(
self, iidxid: int, shop_name: str, dantype: str
) -> None:
def verify_iidx26grade_raised(self, iidxid: int, shop_name: str, dantype: str) -> None:
call = self.call_node()
# Construct node
@ -650,13 +636,9 @@ class IIDXRootageClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX26music/cpu_score_list/score_list/score")
self.assert_path(
resp, "response/IIDX26music/cpu_score_list/score_list/enable_score"
)
self.assert_path(resp, "response/IIDX26music/cpu_score_list/score_list/enable_score")
self.assert_path(resp, "response/IIDX26music/cpu_score_list/score_list/ghost")
self.assert_path(
resp, "response/IIDX26music/cpu_score_list/score_list/enable_ghost"
)
self.assert_path(resp, "response/IIDX26music/cpu_score_list/score_list/enable_ghost")
def verify_iidx26gamesystem_systeminfo(self, lid: str) -> None:
call = self.call_node()
@ -713,32 +695,22 @@ class IIDXRootageClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_iidx26pc_reg(ref_id, card, lid)
self.verify_iidx26pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -829,9 +801,7 @@ class IIDXRootageClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -860,9 +830,7 @@ class IIDXRootageClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_iidx26music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_iidx26music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -967,9 +935,7 @@ class IIDXRootageClient(BaseClient):
)
scores = self.verify_iidx26music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:

View File

@ -92,9 +92,7 @@ class IIDXSinobuzClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 1001:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_iidx24shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -176,9 +174,7 @@ class IIDXSinobuzClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/IIDX24shop")
def verify_iidx24pc_get(
self, ref_id: str, card_id: str, lid: str
) -> Dict[str, Any]:
def verify_iidx24pc_get(self, ref_id: str, card_id: str, lid: str) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -298,9 +294,7 @@ class IIDXSinobuzClient(BaseClient):
"expert_point": expert_point,
}
def verify_iidx24music_getrank(
self, extid: int
) -> Dict[int, Dict[int, Dict[str, int]]]:
def verify_iidx24music_getrank(self, extid: int) -> Dict[int, Dict[int, Dict[str, int]]]:
scores: Dict[int, Dict[int, Dict[str, int]]] = {}
for cltype in [0, 1]: # singles, doubles
call = self.call_node()
@ -322,9 +316,7 @@ class IIDXSinobuzClient(BaseClient):
for child in resp.child("IIDX24music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -454,9 +446,7 @@ class IIDXSinobuzClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX24pc")
def verify_iidx24music_reg(
self, extid: int, lid: str, score: Dict[str, Any]
) -> None:
def verify_iidx24music_reg(self, extid: int, lid: str, score: Dict[str, Any]) -> None:
call = self.call_node()
# Construct node
@ -485,9 +475,7 @@ class IIDXSinobuzClient(BaseClient):
self.assert_path(resp, "response/IIDX24music/shopdata/@rank")
self.assert_path(resp, "response/IIDX24music/ranklist/data")
def verify_iidx24music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_iidx24music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -612,9 +600,7 @@ class IIDXSinobuzClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX24music")
def verify_iidx24grade_raised(
self, iidxid: int, shop_name: str, dantype: str
) -> None:
def verify_iidx24grade_raised(self, iidxid: int, shop_name: str, dantype: str) -> None:
call = self.call_node()
# Construct node
@ -638,9 +624,7 @@ class IIDXSinobuzClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX24grade/@pnum")
def verify_iidx24ranking_entry(
self, iidxid: int, shop_name: str, coursetype: str
) -> None:
def verify_iidx24ranking_entry(self, iidxid: int, shop_name: str, coursetype: str) -> None:
call = self.call_node()
# Construct node
@ -730,32 +714,22 @@ class IIDXSinobuzClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_iidx24pc_reg(ref_id, card, lid)
self.verify_iidx24pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -850,9 +824,7 @@ class IIDXSinobuzClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -881,9 +853,7 @@ class IIDXSinobuzClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_iidx24music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_iidx24music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -988,9 +958,7 @@ class IIDXSinobuzClient(BaseClient):
)
scores = self.verify_iidx24music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:
@ -1011,12 +979,8 @@ class IIDXSinobuzClient(BaseClient):
self.verify_iidx24ranking_classicentry(profile["extid"])
profile = self.verify_iidx24pc_get(ref_id, card, lid)
for ptype in ["ir_data", "secret_course_data", "classic_course_data"]:
if profile[ptype] != {
2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}
}:
raise Exception(
f"Invalid data {profile[ptype]} returned on profile load for {ptype}!"
)
if profile[ptype] != {2: {1: {"clear_status": 4, "pgnum": 1771, "gnum": 967}}}:
raise Exception(f"Invalid data {profile[ptype]} returned on profile load for {ptype}!")
else:
print("Skipping score checks for existing card")

View File

@ -92,9 +92,7 @@ class IIDXSpadaClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 101:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_iidx21shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -173,9 +171,7 @@ class IIDXSpadaClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/IIDX21shop")
def verify_iidx21pc_get(
self, ref_id: str, card_id: str, lid: str
) -> Dict[str, Any]:
def verify_iidx21pc_get(self, ref_id: str, card_id: str, lid: str) -> Dict[str, Any]:
call = self.call_node()
# Construct node
@ -223,9 +219,7 @@ class IIDXSpadaClient(BaseClient):
"deller": int(resp.child("IIDX21pc/deller").attribute("deller")),
}
def verify_iidx21music_getrank(
self, extid: int
) -> Dict[int, Dict[int, Dict[str, int]]]:
def verify_iidx21music_getrank(self, extid: int) -> Dict[int, Dict[int, Dict[str, int]]]:
scores: Dict[int, Dict[int, Dict[str, int]]] = {}
for cltype in [0, 1]: # singles, doubles
call = self.call_node()
@ -247,9 +241,7 @@ class IIDXSpadaClient(BaseClient):
for child in resp.child("IIDX21music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -374,9 +366,7 @@ class IIDXSpadaClient(BaseClient):
resp = self.exchange("", call)
self.assert_path(resp, "response/IIDX21pc")
def verify_iidx21music_reg(
self, extid: int, lid: str, score: Dict[str, Any]
) -> None:
def verify_iidx21music_reg(self, extid: int, lid: str, score: Dict[str, Any]) -> None:
call = self.call_node()
# Construct node
@ -404,9 +394,7 @@ class IIDXSpadaClient(BaseClient):
self.assert_path(resp, "response/IIDX21music/shopdata/@rank")
self.assert_path(resp, "response/IIDX21music/ranklist/data")
def verify_iidx21music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_iidx21music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -526,9 +514,7 @@ class IIDXSpadaClient(BaseClient):
# Verify nodes that cause crashes if they don't exist
self.assert_path(resp, "response/IIDX21music")
def verify_iidx21grade_raised(
self, iidxid: int, shop_name: str, dantype: str
) -> None:
def verify_iidx21grade_raised(self, iidxid: int, shop_name: str, dantype: str) -> None:
call = self.call_node()
# Construct node
@ -592,32 +578,22 @@ class IIDXSpadaClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_iidx21pc_reg(ref_id, card, lid)
self.verify_iidx21pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -706,9 +682,7 @@ class IIDXSpadaClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -737,9 +711,7 @@ class IIDXSpadaClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_iidx21music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_iidx21music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -791,9 +763,7 @@ class IIDXSpadaClient(BaseClient):
)
scores = self.verify_iidx21music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:

View File

@ -89,9 +89,7 @@ class IIDXTricoroClient(BaseClient):
raise Exception(f"Invalid node data {child} in clear rate response!")
for v in child.value:
if v < 0 or v > 101:
raise Exception(
f"Invalid clear percent {child} in clear rate response!"
)
raise Exception(f"Invalid clear percent {child} in clear rate response!")
def verify_shop_getconvention(self, lid: str) -> None:
call = self.call_node()
@ -238,9 +236,7 @@ class IIDXTricoroClient(BaseClient):
for child in resp.child("music").children:
if child.name == "m":
if child.value[0] != -1:
raise Exception(
"Got non-self score back when requesting only our scores!"
)
raise Exception("Got non-self score back when requesting only our scores!")
music_id = child.value[1]
normal_clear_status = child.value[2]
@ -368,9 +364,7 @@ class IIDXTricoroClient(BaseClient):
self.assert_path(resp, "response/music/shopdata/@rank")
self.assert_path(resp, "response/music/ranklist/data")
def verify_music_appoint(
self, extid: int, musicid: int, chart: int
) -> Tuple[int, bytes]:
def verify_music_appoint(self, extid: int, musicid: int, chart: int) -> Tuple[int, bytes]:
call = self.call_node()
# Construct node
@ -554,32 +548,22 @@ class IIDXTricoroClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_pc_reg(ref_id, card, lid)
self.verify_pc_get(ref_id, card, lid)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -668,9 +652,7 @@ class IIDXTricoroClient(BaseClient):
for score in dummyscores:
data = scores.get(score["id"], {}).get(score["chart"], None)
if data is None:
raise Exception(
f'Expected to get score back for song {score["id"]} chart {score["chart"]}!'
)
raise Exception(f'Expected to get score back for song {score["id"]} chart {score["chart"]}!')
if "expected_ex_score" in score:
expected_score = score["expected_ex_score"]
@ -699,9 +681,7 @@ class IIDXTricoroClient(BaseClient):
)
# Verify we can fetch our own ghost
ex_score, ghost = self.verify_music_appoint(
profile["extid"], score["id"], score["chart"]
)
ex_score, ghost = self.verify_music_appoint(profile["extid"], score["id"], score["chart"])
if ex_score != expected_score:
raise Exception(
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{score["chart"]}\' but got score \'{data["ex_score"]}\''
@ -753,9 +733,7 @@ class IIDXTricoroClient(BaseClient):
)
scores = self.verify_music_getrank(profile["extid"])
if 1000 not in scores:
raise Exception(
f"Didn't get expected scores back for song {1000} beginner chart!"
)
raise Exception(f"Didn't get expected scores back for song {1000} beginner chart!")
if 6 not in scores[1000]:
raise Exception(f"Didn't get beginner score back for song {1000}!")
if scores[1000][6] != {"clear_status": 4, "ex_score": -1, "miss_count": -1}:

View File

@ -53,24 +53,12 @@ class JubeatClanClient(BaseClient):
self.assert_path(resp, "response/shopinfo/data/info/born/year")
self.assert_path(resp, "response/shopinfo/data/info/collection/rating_s")
self.assert_path(resp, "response/shopinfo/data/info/expert_option/is_available")
self.assert_path(
resp, "response/shopinfo/data/info/all_music_matching/is_available"
)
self.assert_path(
resp, "response/shopinfo/data/info/all_music_matching/team/default_flag"
)
self.assert_path(
resp, "response/shopinfo/data/info/all_music_matching/team/redbelk_flag"
)
self.assert_path(
resp, "response/shopinfo/data/info/all_music_matching/team/cyanttle_flag"
)
self.assert_path(
resp, "response/shopinfo/data/info/all_music_matching/team/greenesia_flag"
)
self.assert_path(
resp, "response/shopinfo/data/info/all_music_matching/team/plumpark_flag"
)
self.assert_path(resp, "response/shopinfo/data/info/all_music_matching/is_available")
self.assert_path(resp, "response/shopinfo/data/info/all_music_matching/team/default_flag")
self.assert_path(resp, "response/shopinfo/data/info/all_music_matching/team/redbelk_flag")
self.assert_path(resp, "response/shopinfo/data/info/all_music_matching/team/cyanttle_flag")
self.assert_path(resp, "response/shopinfo/data/info/all_music_matching/team/greenesia_flag")
self.assert_path(resp, "response/shopinfo/data/info/all_music_matching/team/plumpark_flag")
self.assert_path(resp, "response/shopinfo/data/info/question_list")
self.assert_path(resp, "response/shopinfo/data/info/drop_list")
self.assert_path(resp, "response/shopinfo/data/info/daily_bonus_list")
@ -138,24 +126,12 @@ class JubeatClanClient(BaseClient):
self.assert_path(resp, "response/gametop/data/info/born/year")
self.assert_path(resp, "response/gametop/data/info/collection/rating_s")
self.assert_path(resp, "response/gametop/data/info/expert_option/is_available")
self.assert_path(
resp, "response/gametop/data/info/all_music_matching/is_available"
)
self.assert_path(
resp, "response/gametop/data/info/all_music_matching/team/default_flag"
)
self.assert_path(
resp, "response/gametop/data/info/all_music_matching/team/redbelk_flag"
)
self.assert_path(
resp, "response/gametop/data/info/all_music_matching/team/cyanttle_flag"
)
self.assert_path(
resp, "response/gametop/data/info/all_music_matching/team/greenesia_flag"
)
self.assert_path(
resp, "response/gametop/data/info/all_music_matching/team/plumpark_flag"
)
self.assert_path(resp, "response/gametop/data/info/all_music_matching/is_available")
self.assert_path(resp, "response/gametop/data/info/all_music_matching/team/default_flag")
self.assert_path(resp, "response/gametop/data/info/all_music_matching/team/redbelk_flag")
self.assert_path(resp, "response/gametop/data/info/all_music_matching/team/cyanttle_flag")
self.assert_path(resp, "response/gametop/data/info/all_music_matching/team/greenesia_flag")
self.assert_path(resp, "response/gametop/data/info/all_music_matching/team/plumpark_flag")
self.assert_path(resp, "response/gametop/data/info/question_list")
self.assert_path(resp, "response/gametop/data/info/drop_list")
self.assert_path(resp, "response/gametop/data/info/daily_bonus_list")
@ -234,19 +210,13 @@ class JubeatClanClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/lab_edit_seq")
self.assert_path(resp, "response/gametop/data/player/event_info")
self.assert_path(resp, "response/gametop/data/player/navi/flag")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/today/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/state")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/whim/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/state")
self.assert_path(resp, "response/gametop/data/player/official_news/news_list")
self.assert_path(resp, "response/gametop/data/player/rivallist")
self.assert_path(
resp, "response/gametop/data/player/free_first_play/is_available"
)
self.assert_path(resp, "response/gametop/data/player/free_first_play/is_available")
self.assert_path(resp, "response/gametop/data/player/jbox/point")
self.assert_path(resp, "response/gametop/data/player/jbox/emblem/normal/index")
self.assert_path(resp, "response/gametop/data/player/jbox/emblem/premium/index")
@ -255,9 +225,7 @@ class JubeatClanClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/born/status")
self.assert_path(resp, "response/gametop/data/player/question_list")
self.assert_path(resp, "response/gametop/data/player/jubility/@param")
self.assert_path(
resp, "response/gametop/data/player/jubility/target_music_list"
)
self.assert_path(resp, "response/gametop/data/player/jubility/target_music_list")
self.assert_path(resp, "response/gametop/data/player/team/@id")
self.assert_path(resp, "response/gametop/data/player/team/section")
self.assert_path(resp, "response/gametop/data/player/team/street")
@ -277,24 +245,12 @@ class JubeatClanClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/drop_list/drop/@id")
self.assert_path(resp, "response/gametop/data/player/drop_list/drop/exp")
self.assert_path(resp, "response/gametop/data/player/drop_list/drop/flag")
self.assert_path(
resp, "response/gametop/data/player/drop_list/drop/item_list/item/@id"
)
self.assert_path(
resp, "response/gametop/data/player/drop_list/drop/item_list/item/num"
)
self.assert_path(
resp, "response/gametop/data/player/fill_in_category/no_gray_flag_list"
)
self.assert_path(
resp, "response/gametop/data/player/fill_in_category/all_yellow_flag_list"
)
self.assert_path(
resp, "response/gametop/data/player/fill_in_category/full_combo_flag_list"
)
self.assert_path(
resp, "response/gametop/data/player/fill_in_category/excellent_flag_list"
)
self.assert_path(resp, "response/gametop/data/player/drop_list/drop/item_list/item/@id")
self.assert_path(resp, "response/gametop/data/player/drop_list/drop/item_list/item/num")
self.assert_path(resp, "response/gametop/data/player/fill_in_category/no_gray_flag_list")
self.assert_path(resp, "response/gametop/data/player/fill_in_category/all_yellow_flag_list")
self.assert_path(resp, "response/gametop/data/player/fill_in_category/full_combo_flag_list")
self.assert_path(resp, "response/gametop/data/player/fill_in_category/excellent_flag_list")
self.assert_path(resp, "response/gametop/data/player/daily_bonus_list")
self.assert_path(resp, "response/gametop/data/player/ticket_list")
@ -661,31 +617,21 @@ class JubeatClanClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_gametop_regist(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -26,13 +26,9 @@ class JubeatFestoClient(BaseClient):
self.assert_path(resp, f"response/{base}/data/info/jbox/emblem/premium/index")
self.assert_path(resp, f"response/{base}/data/info/born/status")
self.assert_path(resp, f"response/{base}/data/info/born/year")
self.assert_path(
resp, f"response/{base}/data/info/konami_logo_50th/is_available"
)
self.assert_path(resp, f"response/{base}/data/info/konami_logo_50th/is_available")
self.assert_path(resp, f"response/{base}/data/info/expert_option/is_available")
self.assert_path(
resp, f"response/{base}/data/info/all_music_matching/is_available"
)
self.assert_path(resp, f"response/{base}/data/info/all_music_matching/is_available")
self.assert_path(resp, f"response/{base}/data/info/department/shop_list")
self.assert_path(resp, f"response/{base}/data/info/question_list")
# Don't bother asserting on actual courses, this is highly specific.
@ -171,9 +167,7 @@ class JubeatFestoClient(BaseClient):
data = Node.void("data")
logger.add_child(data)
data.add_child(Node.string("code", "pcbinfo_01"))
data.add_child(
Node.string("information", "u can literally put anything here lmao")
)
data.add_child(Node.string("information", "u can literally put anything here lmao"))
# Swap with server
resp = self.exchange("", call)
@ -326,19 +320,13 @@ class JubeatFestoClient(BaseClient):
# Required nodes for events and stuff
self.assert_path(resp, "response/gametop/data/player/rivallist")
self.assert_path(resp, "response/gametop/data/player/lab_edit_seq")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/today/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/state")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/whim/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/state")
self.assert_path(resp, "response/gametop/data/player/official_news/news_list")
self.assert_path(resp, "response/gametop/data/player/history/@count")
self.assert_path(
resp, "response/gametop/data/player/free_first_play/is_available"
)
self.assert_path(resp, "response/gametop/data/player/free_first_play/is_available")
self.assert_path(resp, "response/gametop/data/player/event_info")
self.assert_path(resp, "response/gametop/data/player/jbox/point")
self.assert_path(resp, "response/gametop/data/player/jbox/emblem/normal/index")
@ -369,9 +357,7 @@ class JubeatFestoClient(BaseClient):
resp,
"response/gametop/data/player/fill_in_category/normal/excellent_flag_list",
)
self.assert_path(
resp, "response/gametop/data/player/fill_in_category/hard/no_gray_flag_list"
)
self.assert_path(resp, "response/gametop/data/player/fill_in_category/hard/no_gray_flag_list")
self.assert_path(
resp,
"response/gametop/data/player/fill_in_category/hard/all_yellow_flag_list",
@ -783,31 +769,21 @@ class JubeatFestoClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_gametop_regist(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -41,16 +41,12 @@ class JubeatPropClient(BaseClient):
self.assert_path(resp, "response/shopinfo/data/info/share_music")
self.assert_path(resp, "response/shopinfo/data/info/bonus_music")
self.assert_path(resp, "response/shopinfo/data/info/only_now_music")
self.assert_path(
resp, "response/shopinfo/data/info/fc_challenge/today/music_id"
)
self.assert_path(resp, "response/shopinfo/data/info/fc_challenge/today/music_id")
self.assert_path(resp, "response/shopinfo/data/info/white_music_list")
self.assert_path(resp, "response/shopinfo/data/info/open_music_list")
self.assert_path(resp, "response/shopinfo/data/info/cabinet_survey/id")
self.assert_path(resp, "response/shopinfo/data/info/cabinet_survey/status")
self.assert_path(
resp, "response/shopinfo/data/info/kaitou_bisco/remaining_days"
)
self.assert_path(resp, "response/shopinfo/data/info/kaitou_bisco/remaining_days")
self.assert_path(resp, "response/shopinfo/data/info/league/status")
self.assert_path(resp, "response/shopinfo/data/info/bistro/bistro_id")
self.assert_path(resp, "response/shopinfo/data/info/jbox/point")
@ -165,27 +161,17 @@ class JubeatPropClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/cabinet_survey/read_flag")
self.assert_path(resp, "response/gametop/data/player/kaitou_bisco/read_flag")
self.assert_path(resp, "response/gametop/data/player/navi/flag")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/today/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/state")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/whim/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/state")
self.assert_path(resp, "response/gametop/data/player/news/checked")
self.assert_path(resp, "response/gametop/data/player/news/checked_flag")
self.assert_path(resp, "response/gametop/data/player/rivallist")
self.assert_path(
resp, "response/gametop/data/player/free_first_play/is_available"
)
self.assert_path(resp, "response/gametop/data/player/free_first_play/is_available")
self.assert_path(resp, "response/gametop/data/player/free_first_play/point")
self.assert_path(
resp, "response/gametop/data/player/free_first_play/point_used"
)
self.assert_path(
resp, "response/gametop/data/player/free_first_play/come_come_jbox/is_valid"
)
self.assert_path(resp, "response/gametop/data/player/free_first_play/point_used")
self.assert_path(resp, "response/gametop/data/player/free_first_play/come_come_jbox/is_valid")
self.assert_path(
resp,
"response/gametop/data/player/free_first_play/come_come_jbox/end_time_if_paired",
@ -201,17 +187,13 @@ class JubeatPropClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/league/class")
self.assert_path(resp, "response/gametop/data/player/league/subclass")
self.assert_path(resp, "response/gametop/data/player/new_music")
self.assert_path(
resp, "response/gametop/data/player/eapass_privilege/emblem_list"
)
self.assert_path(resp, "response/gametop/data/player/eapass_privilege/emblem_list")
self.assert_path(resp, "response/gametop/data/player/bonus_music/music")
self.assert_path(resp, "response/gametop/data/player/bonus_music/event_id")
self.assert_path(resp, "response/gametop/data/player/bonus_music/till_time")
self.assert_path(resp, "response/gametop/data/player/bistro/chef/id")
self.assert_path(resp, "response/gametop/data/player/bistro/carry_over")
self.assert_path(
resp, "response/gametop/data/player/bistro/route_list/route_count"
)
self.assert_path(resp, "response/gametop/data/player/bistro/route_list/route_count")
self.assert_path(resp, "response/gametop/data/player/bistro/extension")
self.assert_path(resp, "response/gametop/data/player/gift_list")
@ -507,9 +489,7 @@ class JubeatPropClient(BaseClient):
leagueid = resp.child_value("gametop/data/league_list/league/id")
playernode = None
for player in resp.child(
"gametop/data/league_list/league/player_list"
).children:
for player in resp.child("gametop/data/league_list/league/player_list").children:
if player.child_value("jid") == jid:
playernode = player
break
@ -599,31 +579,21 @@ class JubeatPropClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_gametop_regist(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -731,13 +701,9 @@ class JubeatPropClient(BaseClient):
courses = self.verify_gametop_get_course(jid)
league = self.verify_gametop_get_league(jid)
if len(courses) > 0:
raise Exception(
"Got nonzero course count without playing any courses!"
)
raise Exception("Got nonzero course count without playing any courses!")
if league[1][0] != 0 or league[1][1] != 0 or league[1][2] != 0:
raise Exception(
"Got nonzero league count without playing any league!"
)
raise Exception("Got nonzero league count without playing any league!")
for score in dummyscores:
newscore = scores[str(score["id"])][score["chart"]]
@ -808,14 +774,10 @@ class JubeatPropClient(BaseClient):
for course in dummycourses:
# Find the course
foundcourses = [
c for c in courses if c["course_id"] == course["course_id"]
]
foundcourses = [c for c in courses if c["course_id"] == course["course_id"]]
if len(foundcourses) == 0:
raise Exception(
f"Didn't find course by ID {course['course_id']}"
)
raise Exception(f"Didn't find course by ID {course['course_id']}")
foundcourse = foundcourses[0]
if "expected_rating" in course:
@ -846,33 +808,21 @@ class JubeatPropClient(BaseClient):
time.sleep(1)
# Play a league course, save the score
self.verify_gameend_regist(
ref_id, jid, [], {}, (league[0], (123456, 234567, 345678))
)
self.verify_gameend_regist(ref_id, jid, [], {}, (league[0], (123456, 234567, 345678)))
jid = self.verify_gametop_get_pdata(card, ref_id)
league = self.verify_gametop_get_league(jid)
if (
league[1][0] != 123456
or league[1][1] != 234567
or league[1][2] != 345678
):
if league[1][0] != 123456 or league[1][1] != 234567 or league[1][2] != 345678:
raise Exception(
f"League score didn\t save! Got wrong values {league[1][0]}, {league[1][1]}, {league[1][2]} back!"
)
# Play a league course, do worse, make sure it doesn't overwrite
self.verify_gameend_regist(
ref_id, jid, [], {}, (league[0], (12345, 23456, 34567))
)
self.verify_gameend_regist(ref_id, jid, [], {}, (league[0], (12345, 23456, 34567)))
jid = self.verify_gametop_get_pdata(card, ref_id)
league = self.verify_gametop_get_league(jid)
if (
league[1][0] != 123456
or league[1][1] != 234567
or league[1][2] != 345678
):
if league[1][0] != 123456 or league[1][1] != 234567 or league[1][2] != 345678:
raise Exception(
f"League score got overwritten! Got wrong values {league[1][0]}, {league[1][1]}, {league[1][2]} back!"
)

View File

@ -160,20 +160,14 @@ class JubeatQubellClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/lab_edit_seq")
self.assert_path(resp, "response/gametop/data/player/event_info")
self.assert_path(resp, "response/gametop/data/player/navi/flag")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/today/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/state")
self.assert_path(
resp, "response/gametop/data/player/fc_challenge/whim/music_id"
)
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/music_id")
self.assert_path(resp, "response/gametop/data/player/fc_challenge/whim/state")
self.assert_path(resp, "response/gametop/data/player/news/checked")
self.assert_path(resp, "response/gametop/data/player/news/checked_flag")
self.assert_path(resp, "response/gametop/data/player/rivallist")
self.assert_path(
resp, "response/gametop/data/player/free_first_play/is_available"
)
self.assert_path(resp, "response/gametop/data/player/free_first_play/is_available")
self.assert_path(resp, "response/gametop/data/player/jbox/point")
self.assert_path(resp, "response/gametop/data/player/jbox/emblem/normal/index")
self.assert_path(resp, "response/gametop/data/player/jbox/emblem/premium/index")
@ -189,28 +183,14 @@ class JubeatQubellClient(BaseClient):
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/ratio")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/used_point")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/point")
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/excavated_point"
)
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/excavated_point")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/state")
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/cube/item/kind"
)
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/cube/item/value"
)
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/cube/norma/till_time"
)
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/cube/norma/kind"
)
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/cube/norma/value"
)
self.assert_path(
resp, "response/gametop/data/player/digdig/eternal/cube/norma/param"
)
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/item/kind")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/item/value")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/norma/till_time")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/norma/kind")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/norma/value")
self.assert_path(resp, "response/gametop/data/player/digdig/eternal/cube/norma/param")
# Return the jid
return resp.child_value("gametop/data/player/jid")
@ -497,31 +477,21 @@ class JubeatQubellClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_gametop_regist(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -134,9 +134,7 @@ class JubeatSaucerClient(BaseClient):
# Return the jid
return resp.child_value("gametop/data/player/jid")
def verify_gameend_regist(
self, ref_id: str, jid: int, scores: List[Dict[str, Any]]
) -> None:
def verify_gameend_regist(self, ref_id: str, jid: int, scores: List[Dict[str, Any]]) -> None:
call = self.call_node()
# Construct node
@ -378,31 +376,21 @@ class JubeatSaucerClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_gametop_regist(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -457,31 +457,21 @@ class JubeatSaucerFulfillClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_gametop_regist(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:
@ -583,9 +573,7 @@ class JubeatSaucerFulfillClient(BaseClient):
scores = self.verify_gametop_get_mdata(jid)
courses = self.verify_gametop_get_course(jid)
if len(courses) > 0:
raise Exception(
"Got nonzero course count without playing any courses!"
)
raise Exception("Got nonzero course count without playing any courses!")
for score in dummyscores:
newscore = scores[str(score["id"])][score["chart"]]
@ -656,14 +644,10 @@ class JubeatSaucerFulfillClient(BaseClient):
for course in dummycourses:
# Find the course
foundcourses = [
c for c in courses if c["course_id"] == course["course_id"]
]
foundcourses = [c for c in courses if c["course_id"] == course["course_id"]]
if len(foundcourses) == 0:
raise Exception(
f"Didn't find course by ID {course['course_id']}"
)
raise Exception(f"Didn't find course by ID {course['course_id']}")
foundcourse = foundcourses[0]
if "expected_rating" in course:

View File

@ -318,32 +318,22 @@ class MetalGearArcadeClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# MGA doesn't read a new profile, it just writes out CSV for a blank one
self.verify_usergamedata_send(ref_id, msg_type="new")
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -165,9 +165,7 @@ class Museca1Client(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/game_3/result")
def verify_game_save(
self, location: str, refid: str, packet: int, block: int, blaster_energy: int
) -> None:
def verify_game_save(self, location: str, refid: str, packet: int, block: int, blaster_energy: int) -> None:
call = self.call_node()
game = Node.void("game_3")
@ -230,9 +228,7 @@ class Museca1Client(BaseClient):
self.assert_path(resp, "response/game_3/music_limited")
self.assert_path(resp, "response/game_3/event")
def verify_game_load(
self, cardid: str, refid: str, msg_type: str
) -> Dict[str, Any]:
def verify_game_load(self, cardid: str, refid: str, msg_type: str) -> Dict[str, Any]:
call = self.call_node()
game = Node.void("game_3")
@ -354,9 +350,7 @@ class Museca1Client(BaseClient):
return scores
def verify_game_save_m(
self, location: str, refid: str, score: Dict[str, int]
) -> None:
def verify_game_save_m(self, location: str, refid: str, score: Dict[str, int]) -> None:
call = self.call_node()
game = Node.void("game_3")
@ -428,17 +422,11 @@ class Museca1Client(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Museca doesn't read the new profile, it asks for the profile itself after calling new
self.verify_game_load(card, ref_id, msg_type="new")
@ -446,16 +434,12 @@ class Museca1Client(BaseClient):
self.verify_game_load(card, ref_id, msg_type="existing")
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify account freezing
@ -467,34 +451,24 @@ class Museca1Client(BaseClient):
# Verify profile loading and saving
profile = self.verify_game_load(card, ref_id, msg_type="existing")
if profile["name"] != self.NAME:
raise Exception(
f'Profile has incorrect name {profile["name"]} associated with it!'
)
raise Exception(f'Profile has incorrect name {profile["name"]} associated with it!')
if profile["packet"] != 0:
raise Exception("Profile has nonzero blocks associated with it!")
if profile["block"] != 0:
raise Exception("Profile has nonzero packets associated with it!")
if profile["blaster_energy"] != 0:
raise Exception(
"Profile has nonzero blaster energy associated with it!"
)
raise Exception("Profile has nonzero blaster energy associated with it!")
self.verify_game_save(
location, ref_id, packet=123, block=234, blaster_energy=42
)
self.verify_game_save(location, ref_id, packet=123, block=234, blaster_energy=42)
profile = self.verify_game_load(card, ref_id, msg_type="existing")
if profile["name"] != self.NAME:
raise Exception(
f'Profile has incorrect name {profile["name"]} associated with it!'
)
raise Exception(f'Profile has incorrect name {profile["name"]} associated with it!')
if profile["packet"] != 123:
raise Exception("Profile has invalid blocks associated with it!")
if profile["block"] != 234:
raise Exception("Profile has invalid packets associated with it!")
if profile["blaster_energy"] != 42:
raise Exception(
"Profile has invalid blaster energy associated with it!"
)
raise Exception("Profile has invalid blaster energy associated with it!")
# Verify empty profile has no scores on it
scores = self.verify_game_load_m(ref_id)
@ -567,17 +541,12 @@ class Museca1Client(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]

View File

@ -165,9 +165,7 @@ class Museca1PlusClient(BaseClient):
# Verify that response is correct
self.assert_path(resp, "response/game_3/result")
def verify_game_save(
self, location: str, refid: str, packet: int, block: int, blaster_energy: int
) -> None:
def verify_game_save(self, location: str, refid: str, packet: int, block: int, blaster_energy: int) -> None:
call = self.call_node()
game = Node.void("game_3")
@ -230,9 +228,7 @@ class Museca1PlusClient(BaseClient):
self.assert_path(resp, "response/game_3/music_limited")
self.assert_path(resp, "response/game_3/event")
def verify_game_load(
self, cardid: str, refid: str, msg_type: str
) -> Dict[str, Any]:
def verify_game_load(self, cardid: str, refid: str, msg_type: str) -> Dict[str, Any]:
call = self.call_node()
game = Node.void("game_3")
@ -369,9 +365,7 @@ class Museca1PlusClient(BaseClient):
return scores
def verify_game_save_m(
self, location: str, refid: str, score: Dict[str, int]
) -> None:
def verify_game_save_m(self, location: str, refid: str, score: Dict[str, int]) -> None:
call = self.call_node()
game = Node.void("game_3")
@ -443,17 +437,11 @@ class Museca1PlusClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Museca doesn't read the new profile, it asks for the profile itself after calling new
self.verify_game_load(card, ref_id, msg_type="new")
@ -461,16 +449,12 @@ class Museca1PlusClient(BaseClient):
self.verify_game_load(card, ref_id, msg_type="existing")
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify account freezing
@ -485,34 +469,24 @@ class Museca1PlusClient(BaseClient):
# Verify profile loading and saving
profile = self.verify_game_load(card, ref_id, msg_type="existing")
if profile["name"] != self.NAME:
raise Exception(
f'Profile has incorrect name {profile["name"]} associated with it!'
)
raise Exception(f'Profile has incorrect name {profile["name"]} associated with it!')
if profile["packet"] != 0:
raise Exception("Profile has nonzero blocks associated with it!")
if profile["block"] != 0:
raise Exception("Profile has nonzero packets associated with it!")
if profile["blaster_energy"] != 0:
raise Exception(
"Profile has nonzero blaster energy associated with it!"
)
raise Exception("Profile has nonzero blaster energy associated with it!")
self.verify_game_save(
location, ref_id, packet=123, block=234, blaster_energy=42
)
self.verify_game_save(location, ref_id, packet=123, block=234, blaster_energy=42)
profile = self.verify_game_load(card, ref_id, msg_type="existing")
if profile["name"] != self.NAME:
raise Exception(
f'Profile has incorrect name {profile["name"]} associated with it!'
)
raise Exception(f'Profile has incorrect name {profile["name"]} associated with it!')
if profile["packet"] != 123:
raise Exception("Profile has invalid blocks associated with it!")
if profile["block"] != 234:
raise Exception("Profile has invalid packets associated with it!")
if profile["blaster_energy"] != 42:
raise Exception(
"Profile has invalid blaster energy associated with it!"
)
raise Exception("Profile has invalid blaster energy associated with it!")
# Verify empty profile has no scores on it
scores = self.verify_game_load_m(ref_id)
@ -585,17 +559,12 @@ class Museca1PlusClient(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]

View File

@ -118,9 +118,7 @@ class PopnMusicEclaleClient(BaseClient):
self.assert_path(resp, "response/player23/stamp/stamp_id")
self.assert_path(resp, "response/player23/stamp/cnt")
def verify_player23_read(
self, ref_id: str, msg_type: str
) -> Dict[str, Dict[int, Dict[str, int]]]:
def verify_player23_read(self, ref_id: str, msg_type: str) -> Dict[str, Dict[int, Dict[str, int]]]:
call = self.call_node()
# Construct node
@ -139,9 +137,7 @@ class PopnMusicEclaleClient(BaseClient):
self.assert_path(resp, "response/player23/result")
status = resp.child_value("player23/result")
if status != 2:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
return {
"medals": {},
@ -156,9 +152,7 @@ class PopnMusicEclaleClient(BaseClient):
self.assert_path(resp, "response/player23/result")
status = resp.child_value("player23/result")
if status != 0:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
name = resp.child_value("player23/account/name")
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for Ref ID '{ref_id}'")
@ -192,9 +186,7 @@ class PopnMusicEclaleClient(BaseClient):
else:
raise Exception(f"Unrecognized message type '{msg_type}'")
def verify_player23_read_score(
self, ref_id: str
) -> Dict[str, Dict[int, Dict[int, int]]]:
def verify_player23_read_score(self, ref_id: str) -> Dict[str, Dict[int, Dict[int, int]]]:
call = self.call_node()
# Construct node
@ -418,32 +410,22 @@ class PopnMusicEclaleClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_player23_read(ref_id, msg_type="new")
self.verify_player23_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify proper handling of basic stuff
@ -489,9 +471,7 @@ class PopnMusicEclaleClient(BaseClient):
raise Exception("Expecting to see chara ID 5 to have type 2 in characters!")
# Verify purchases work
self.verify_player23_buy(
ref_id, item={"id": 6, "type": 7, "param": 8, "lumina": 400, "price": 250}
)
self.verify_player23_buy(ref_id, item={"id": 6, "type": 7, "param": 8, "lumina": 400, "price": 250})
unlocks = self.verify_player23_read(ref_id, msg_type="query")
if 6 not in unlocks["items"]:
raise Exception("Expecting to see item ID 6 in items!")
@ -500,9 +480,7 @@ class PopnMusicEclaleClient(BaseClient):
if unlocks["items"][6]["param"] != 8:
raise Exception("Expecting to see item ID 6 to have param 8 in items!")
if unlocks["lumina"][0]["lumina"] != 150:
raise Exception(
f'Got wrong value for lumina {unlocks["lumina"][0]["lumina"]} after purchase!'
)
raise Exception(f'Got wrong value for lumina {unlocks["lumina"][0]["lumina"]} after purchase!')
if cardid is None:
# Verify score handling

View File

@ -115,9 +115,7 @@ class PopnMusicFantasiaClient(BaseClient):
if len(node.value) != length:
raise Exception(f"Node '{name}' is wrong array length!")
def verify_playerdata_get(
self, ref_id: str, msg_type: str
) -> Optional[Dict[str, Any]]:
def verify_playerdata_get(self, ref_id: str, msg_type: str) -> Optional[Dict[str, Any]]:
call = self.call_node()
# Construct node
@ -125,9 +123,7 @@ class PopnMusicFantasiaClient(BaseClient):
call.add_child(playerdata)
playerdata.set_attribute("method", "get")
if msg_type == "new":
playerdata.set_attribute(
"model", self.config["old_profile_model"].split(":")[0]
)
playerdata.set_attribute("model", self.config["old_profile_model"].split(":")[0])
playerdata.add_child(Node.string("ref_id", ref_id))
playerdata.add_child(Node.string("shop_name", ""))
@ -143,9 +139,7 @@ class PopnMusicFantasiaClient(BaseClient):
status = int(resp.child("playerdata").attribute("status"))
if status != 109:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
# No score data
return None
@ -181,11 +175,7 @@ class PopnMusicFantasiaClient(BaseClient):
)
medals = [
transform_medals(medal)
for medal in resp.child("playerdata")
.child("base")
.child("clear_medal")
.value
transform_medals(medal) for medal in resp.child("playerdata").child("base").child("clear_medal").value
]
hiscore = resp.child("playerdata").child("hiscore").value
@ -202,8 +192,7 @@ class PopnMusicFantasiaClient(BaseClient):
hiscores.append(value & 0x1FFFF)
scores = [
(hiscores[x], hiscores[x + 1], hiscores[x + 2], hiscores[x + 3])
for x in range(0, len(hiscores), 4)
(hiscores[x], hiscores[x + 1], hiscores[x + 2], hiscores[x + 3]) for x in range(0, len(hiscores), 4)
]
return {"medals": medals, "scores": scores}
@ -240,9 +229,7 @@ class PopnMusicFantasiaClient(BaseClient):
}[score["chart"]],
)
)
stage.add_child(
Node.u16("n_data", (score["medal"] << (4 * score["chart"])))
)
stage.add_child(Node.u16("n_data", (score["medal"] << (4 * score["chart"]))))
stage.add_child(Node.u8("e_data", 0))
stage.add_child(Node.s32("score", score["score"]))
stage.add_child(Node.u8("ojama_1", 0))
@ -325,32 +312,22 @@ class PopnMusicFantasiaClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_playerdata_get(ref_id, msg_type="new")
self.verify_playerdata_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -136,9 +136,7 @@ class PopnMusicKaimeiClient(BaseClient):
self.assert_path(resp, "response/player24/stamp/stamp_id")
self.assert_path(resp, "response/player24/stamp/cnt")
def verify_player24_read(
self, ref_id: str, msg_type: str
) -> Dict[str, Dict[int, Dict[str, int]]]:
def verify_player24_read(self, ref_id: str, msg_type: str) -> Dict[str, Dict[int, Dict[str, int]]]:
call = self.call_node()
# Construct node
@ -157,9 +155,7 @@ class PopnMusicKaimeiClient(BaseClient):
self.assert_path(resp, "response/player24/result")
status = resp.child_value("player24/result")
if status != 2:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
return {
"items": {},
@ -173,9 +169,7 @@ class PopnMusicKaimeiClient(BaseClient):
self.assert_path(resp, "response/player24/result")
status = resp.child_value("player24/result")
if status != 0:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
name = resp.child_value("player24/account/name")
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for Ref ID '{ref_id}'")
@ -207,16 +201,12 @@ class PopnMusicKaimeiClient(BaseClient):
"items": items,
"characters": charas,
"courses": courses,
"points": {
0: {"points": resp.child_value("player24/account/player_point")}
},
"points": {0: {"points": resp.child_value("player24/account/player_point")}},
}
else:
raise Exception(f"Unrecognized message type '{msg_type}'")
def verify_player24_read_score(
self, ref_id: str
) -> Dict[str, Dict[int, Dict[int, int]]]:
def verify_player24_read_score(self, ref_id: str) -> Dict[str, Dict[int, Dict[int, int]]]:
call = self.call_node()
# Construct node
@ -468,32 +458,22 @@ class PopnMusicKaimeiClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_player24_read(ref_id, msg_type="new")
self.verify_player24_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify proper handling of basic stuff
@ -531,9 +511,7 @@ class PopnMusicKaimeiClient(BaseClient):
if 5 not in unlocks["characters"]:
raise Exception("Expecting to see chara ID 5 in characters!")
if unlocks["characters"][5]["friendship"] != 420:
raise Exception(
"Expecting to see chara ID 5 to have type 2 in characters!"
)
raise Exception("Expecting to see chara ID 5 to have type 2 in characters!")
# Verify purchases work
self.verify_player24_buy(
@ -548,9 +526,7 @@ class PopnMusicKaimeiClient(BaseClient):
if unlocks["items"][6]["param"] != 8:
raise Exception("Expecting to see item ID 6 to have param 8 in items!")
if unlocks["points"][0]["points"] != 150:
raise Exception(
f'Got wrong value for points {unlocks["points"][0]["points"]} after purchase!'
)
raise Exception(f'Got wrong value for points {unlocks["points"][0]["points"]} after purchase!')
# Verify course handling
self.verify_player24_update_ranking(ref_id, location)
@ -558,25 +534,15 @@ class PopnMusicKaimeiClient(BaseClient):
if 12345 not in unlocks["courses"]:
raise Exception("Expecting to see course ID 12345 in courses!")
if unlocks["courses"][12345]["clear_type"] != 7:
raise Exception(
"Expecting to see item ID 12345 to have clear_type 7 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have clear_type 7 in courses!")
if unlocks["courses"][12345]["clear_rank"] != 5:
raise Exception(
"Expecting to see item ID 12345 to have clear_rank 5 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have clear_rank 5 in courses!")
if unlocks["courses"][12345]["total_score"] != 86000:
raise Exception(
"Expecting to see item ID 12345 to have total_score 86000 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have total_score 86000 in courses!")
if unlocks["courses"][12345]["count"] != 1:
raise Exception(
"Expecting to see item ID 12345 to have count 1 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have count 1 in courses!")
if unlocks["courses"][12345]["sheet_num"] != 2:
raise Exception(
"Expecting to see item ID 12345 to have sheet_num 2 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have sheet_num 2 in courses!")
# Verify score handling
scores = self.verify_player24_read_score(ref_id)

View File

@ -49,9 +49,7 @@ class PopnMusicLapistoriaClient(BaseClient):
if node.data_type != "void":
raise Exception(f"Node '{name}' has wrong data type!")
def verify_player22_read(
self, ref_id: str, msg_type: str
) -> Optional[Dict[str, Any]]:
def verify_player22_read(self, ref_id: str, msg_type: str) -> Optional[Dict[str, Any]]:
call = self.call_node()
# Construct node
@ -72,9 +70,7 @@ class PopnMusicLapistoriaClient(BaseClient):
status = int(resp.child("player22").attribute("status"))
if status != 109:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
# No score data
return None
@ -287,32 +283,22 @@ class PopnMusicLapistoriaClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_player22_read(ref_id, msg_type="new")
self.verify_player22_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -136,9 +136,7 @@ class PopnMusicPeaceClient(BaseClient):
self.assert_path(resp, "response/player24/stamp/stamp_id")
self.assert_path(resp, "response/player24/stamp/cnt")
def verify_player24_read(
self, ref_id: str, msg_type: str
) -> Dict[str, Dict[int, Dict[str, int]]]:
def verify_player24_read(self, ref_id: str, msg_type: str) -> Dict[str, Dict[int, Dict[str, int]]]:
call = self.call_node()
# Construct node
@ -157,9 +155,7 @@ class PopnMusicPeaceClient(BaseClient):
self.assert_path(resp, "response/player24/result")
status = resp.child_value("player24/result")
if status != 2:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
return {
"items": {},
@ -173,9 +169,7 @@ class PopnMusicPeaceClient(BaseClient):
self.assert_path(resp, "response/player24/result")
status = resp.child_value("player24/result")
if status != 0:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
name = resp.child_value("player24/account/name")
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for Ref ID '{ref_id}'")
@ -207,16 +201,12 @@ class PopnMusicPeaceClient(BaseClient):
"items": items,
"characters": charas,
"courses": courses,
"points": {
0: {"points": resp.child_value("player24/account/player_point")}
},
"points": {0: {"points": resp.child_value("player24/account/player_point")}},
}
else:
raise Exception(f"Unrecognized message type '{msg_type}'")
def verify_player24_read_score(
self, ref_id: str
) -> Dict[str, Dict[int, Dict[int, int]]]:
def verify_player24_read_score(self, ref_id: str) -> Dict[str, Dict[int, Dict[int, int]]]:
call = self.call_node()
# Construct node
@ -468,32 +458,22 @@ class PopnMusicPeaceClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_player24_read(ref_id, msg_type="new")
self.verify_player24_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify proper handling of basic stuff
@ -531,9 +511,7 @@ class PopnMusicPeaceClient(BaseClient):
if 5 not in unlocks["characters"]:
raise Exception("Expecting to see chara ID 5 in characters!")
if unlocks["characters"][5]["friendship"] != 420:
raise Exception(
"Expecting to see chara ID 5 to have type 2 in characters!"
)
raise Exception("Expecting to see chara ID 5 to have type 2 in characters!")
# Verify purchases work
self.verify_player24_buy(
@ -548,9 +526,7 @@ class PopnMusicPeaceClient(BaseClient):
if unlocks["items"][6]["param"] != 8:
raise Exception("Expecting to see item ID 6 to have param 8 in items!")
if unlocks["points"][0]["points"] != 150:
raise Exception(
f'Got wrong value for points {unlocks["points"][0]["points"]} after purchase!'
)
raise Exception(f'Got wrong value for points {unlocks["points"][0]["points"]} after purchase!')
# Verify course handling
self.verify_player24_update_ranking(ref_id, location)
@ -558,25 +534,15 @@ class PopnMusicPeaceClient(BaseClient):
if 12345 not in unlocks["courses"]:
raise Exception("Expecting to see course ID 12345 in courses!")
if unlocks["courses"][12345]["clear_type"] != 7:
raise Exception(
"Expecting to see item ID 12345 to have clear_type 7 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have clear_type 7 in courses!")
if unlocks["courses"][12345]["clear_rank"] != 5:
raise Exception(
"Expecting to see item ID 12345 to have clear_rank 5 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have clear_rank 5 in courses!")
if unlocks["courses"][12345]["total_score"] != 86000:
raise Exception(
"Expecting to see item ID 12345 to have total_score 86000 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have total_score 86000 in courses!")
if unlocks["courses"][12345]["count"] != 1:
raise Exception(
"Expecting to see item ID 12345 to have count 1 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have count 1 in courses!")
if unlocks["courses"][12345]["sheet_num"] != 2:
raise Exception(
"Expecting to see item ID 12345 to have sheet_num 2 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have sheet_num 2 in courses!")
# Verify score handling
scores = self.verify_player24_read_score(ref_id)

View File

@ -80,9 +80,7 @@ class PopnMusicSunnyParkClient(BaseClient):
if len(node.value) != 5:
raise Exception(f"Node '{name}' is wrong array length!")
def verify_playerdata_get(
self, ref_id: str, msg_type: str
) -> Optional[Dict[str, Any]]:
def verify_playerdata_get(self, ref_id: str, msg_type: str) -> Optional[Dict[str, Any]]:
call = self.call_node()
# Construct node
@ -90,9 +88,7 @@ class PopnMusicSunnyParkClient(BaseClient):
call.add_child(playerdata)
playerdata.set_attribute("method", "get")
if msg_type == "new":
playerdata.set_attribute(
"model", self.config["old_profile_model"].split(":")[0]
)
playerdata.set_attribute("model", self.config["old_profile_model"].split(":")[0])
playerdata.add_child(Node.string("ref_id", ref_id))
playerdata.add_child(Node.string("shop_name", ""))
@ -115,9 +111,7 @@ class PopnMusicSunnyParkClient(BaseClient):
status = int(resp.child("playerdata").attribute("status"))
if status != 109:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
# No score data
return None
@ -149,11 +143,7 @@ class PopnMusicSunnyParkClient(BaseClient):
)
medals = [
transform_medals(medal)
for medal in resp.child("playerdata")
.child("base")
.child("clear_medal")
.value
transform_medals(medal) for medal in resp.child("playerdata").child("base").child("clear_medal").value
]
hiscore = resp.child("playerdata").child("hiscore").value
@ -170,8 +160,7 @@ class PopnMusicSunnyParkClient(BaseClient):
hiscores.append(value & 0x1FFFF)
scores = [
(hiscores[x], hiscores[x + 1], hiscores[x + 2], hiscores[x + 3])
for x in range(0, len(hiscores), 4)
(hiscores[x], hiscores[x + 1], hiscores[x + 2], hiscores[x + 3]) for x in range(0, len(hiscores), 4)
]
return {"medals": medals, "scores": scores}
@ -198,9 +187,7 @@ class PopnMusicSunnyParkClient(BaseClient):
playerdata.add_child(stage)
stage.add_child(Node.s16("no", score["id"]))
stage.add_child(Node.u8("sheet", score["chart"]))
stage.add_child(
Node.u16("n_data", (score["medal"] << (4 * score["chart"])))
)
stage.add_child(Node.u16("n_data", (score["medal"] << (4 * score["chart"]))))
stage.add_child(Node.s32("score", score["score"]))
# Swap with server
@ -273,32 +260,22 @@ class PopnMusicSunnyParkClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_playerdata_get(ref_id, msg_type="new")
self.verify_playerdata_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -66,9 +66,7 @@ class PopnMusicTuneStreetClient(BaseClient):
if name not in resp.child("game").attributes:
raise Exception(f"Missing attribute '{name}' in response!")
def verify_playerdata_get(
self, ref_id: str, msg_type: str
) -> Optional[Dict[str, Any]]:
def verify_playerdata_get(self, ref_id: str, msg_type: str) -> Optional[Dict[str, Any]]:
call = self.call_node()
# Construct node
@ -80,9 +78,7 @@ class PopnMusicTuneStreetClient(BaseClient):
playerdata.set_attribute("ref_id", ref_id)
if msg_type == "new":
playerdata.set_attribute(
"model", self.config["old_profile_model"].split(":")[0]
)
playerdata.set_attribute("model", self.config["old_profile_model"].split(":")[0])
# Swap with server
resp = self.exchange("pnm/playerdata", call)
@ -93,9 +89,7 @@ class PopnMusicTuneStreetClient(BaseClient):
status = int(resp.child("playerdata").attribute("status"))
if status != 109:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
# No score data
return None
@ -105,20 +99,12 @@ class PopnMusicTuneStreetClient(BaseClient):
self.assert_path(resp, "response/playerdata/hiscore")
self.assert_path(resp, "response/playerdata/town")
name = (
resp.child("playerdata")
.child("b")
.value[0:12]
.decode("SHIFT_JIS")
.replace("\x00", "")
)
name = resp.child("playerdata").child("b").value[0:12].decode("SHIFT_JIS").replace("\x00", "")
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for Ref ID '{ref_id}'")
medals = resp.child("playerdata").child("b").value[108:]
medals = [
(medals[x] + (medals[x + 1] << 8)) for x in range(0, len(medals), 2)
]
medals = [(medals[x] + (medals[x + 1] << 8)) for x in range(0, len(medals), 2)]
# Extract and return score data
def transform_medals(medal: int) -> Tuple[int, int, int, int]:
@ -273,32 +259,22 @@ class PopnMusicTuneStreetClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_playerdata_get(ref_id, msg_type="new")
self.verify_playerdata_new(card, ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
if cardid is None:

View File

@ -136,9 +136,7 @@ class PopnMusicUsaNekoClient(BaseClient):
self.assert_path(resp, "response/player24/stamp/stamp_id")
self.assert_path(resp, "response/player24/stamp/cnt")
def verify_player24_read(
self, ref_id: str, msg_type: str
) -> Dict[str, Dict[int, Dict[str, int]]]:
def verify_player24_read(self, ref_id: str, msg_type: str) -> Dict[str, Dict[int, Dict[str, int]]]:
call = self.call_node()
# Construct node
@ -157,9 +155,7 @@ class PopnMusicUsaNekoClient(BaseClient):
self.assert_path(resp, "response/player24/result")
status = resp.child_value("player24/result")
if status != 2:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
return {
"items": {},
@ -173,9 +169,7 @@ class PopnMusicUsaNekoClient(BaseClient):
self.assert_path(resp, "response/player24/result")
status = resp.child_value("player24/result")
if status != 0:
raise Exception(
f"Reference ID '{ref_id}' returned invalid status '{status}'"
)
raise Exception(f"Reference ID '{ref_id}' returned invalid status '{status}'")
name = resp.child_value("player24/account/name")
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for Ref ID '{ref_id}'")
@ -207,16 +201,12 @@ class PopnMusicUsaNekoClient(BaseClient):
"items": items,
"characters": charas,
"courses": courses,
"points": {
0: {"points": resp.child_value("player24/account/player_point")}
},
"points": {0: {"points": resp.child_value("player24/account/player_point")}},
}
else:
raise Exception(f"Unrecognized message type '{msg_type}'")
def verify_player24_read_score(
self, ref_id: str
) -> Dict[str, Dict[int, Dict[int, int]]]:
def verify_player24_read_score(self, ref_id: str) -> Dict[str, Dict[int, Dict[int, int]]]:
call = self.call_node()
# Construct node
@ -468,32 +458,22 @@ class PopnMusicUsaNekoClient(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
self.verify_player24_read(ref_id, msg_type="new")
self.verify_player24_new(ref_id)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify proper handling of basic stuff
@ -531,9 +511,7 @@ class PopnMusicUsaNekoClient(BaseClient):
if 5 not in unlocks["characters"]:
raise Exception("Expecting to see chara ID 5 in characters!")
if unlocks["characters"][5]["friendship"] != 420:
raise Exception(
"Expecting to see chara ID 5 to have type 2 in characters!"
)
raise Exception("Expecting to see chara ID 5 to have type 2 in characters!")
# Verify purchases work
self.verify_player24_buy(
@ -548,9 +526,7 @@ class PopnMusicUsaNekoClient(BaseClient):
if unlocks["items"][6]["param"] != 8:
raise Exception("Expecting to see item ID 6 to have param 8 in items!")
if unlocks["points"][0]["points"] != 150:
raise Exception(
f'Got wrong value for points {unlocks["points"][0]["points"]} after purchase!'
)
raise Exception(f'Got wrong value for points {unlocks["points"][0]["points"]} after purchase!')
# Verify course handling
self.verify_player24_update_ranking(ref_id, location)
@ -558,25 +534,15 @@ class PopnMusicUsaNekoClient(BaseClient):
if 12345 not in unlocks["courses"]:
raise Exception("Expecting to see course ID 12345 in courses!")
if unlocks["courses"][12345]["clear_type"] != 7:
raise Exception(
"Expecting to see item ID 12345 to have clear_type 7 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have clear_type 7 in courses!")
if unlocks["courses"][12345]["clear_rank"] != 5:
raise Exception(
"Expecting to see item ID 12345 to have clear_rank 5 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have clear_rank 5 in courses!")
if unlocks["courses"][12345]["total_score"] != 86000:
raise Exception(
"Expecting to see item ID 12345 to have total_score 86000 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have total_score 86000 in courses!")
if unlocks["courses"][12345]["count"] != 1:
raise Exception(
"Expecting to see item ID 12345 to have count 1 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have count 1 in courses!")
if unlocks["courses"][12345]["sheet_num"] != 2:
raise Exception(
"Expecting to see item ID 12345 to have sheet_num 2 in courses!"
)
raise Exception("Expecting to see item ID 12345 to have sheet_num 2 in courses!")
# Verify score handling
scores = self.verify_player24_read_score(ref_id)

View File

@ -182,9 +182,7 @@ class ReflecBeatColette(BaseClient):
self.assert_path(resp, "response/player/pdata/record")
if resp.child_value("player/pdata/base/name") != self.NAME:
raise Exception(
f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!'
)
raise Exception(f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!')
scores = []
for child in resp.child("player/pdata/record").children:
@ -203,9 +201,7 @@ class ReflecBeatColette(BaseClient):
scores.append(score)
return scores
def verify_player_write(
self, refid: str, loc: str, scores: List[Dict[str, int]]
) -> int:
def verify_player_write(self, refid: str, loc: str, scores: List[Dict[str, int]]) -> int:
call = self.call_node()
player = Node.void("player")
@ -471,9 +467,7 @@ class ReflecBeatColette(BaseClient):
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for comment!")
if comment != "アメ〜〜!":
raise Exception(
f"Invalid comment '{comment}' returned for comment!"
)
raise Exception(f"Invalid comment '{comment}' returned for comment!")
found = True
if not found:
@ -553,17 +547,11 @@ class ReflecBeatColette(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Always get a player start, regardless of new profile or not
self.verify_player_start(ref_id)
@ -586,16 +574,12 @@ class ReflecBeatColette(BaseClient):
)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify lobby functionality
@ -690,26 +674,19 @@ class ReflecBeatColette(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
else:
expected_score = expected["score"]
if "expected_achievement_rate" in expected:
expected_achievement_rate = expected[
"expected_achievement_rate"
]
expected_achievement_rate = expected["expected_achievement_rate"]
else:
expected_achievement_rate = expected["achievement_rate"]
if "expected_clear_type" in expected:

View File

@ -123,11 +123,7 @@ class ReflecBeatGroovinUpper(BaseClient):
player.add_child(Node.u8_array("ga", [127, 0, 0, 1]))
player.add_child(Node.u16("gp", 10573))
player.add_child(Node.u8_array("la", [16, 0, 0, 0]))
player.add_child(
Node.u8_array(
"pnid", [39, 16, 0, 0, 0, 23, 62, 60, 39, 127, 0, 0, 1, 23, 62, 60]
)
)
player.add_child(Node.u8_array("pnid", [39, 16, 0, 0, 0, 23, 62, 60, 39, 127, 0, 0, 1, 23, 62, 60]))
call.add_child(player)
@ -293,13 +289,9 @@ class ReflecBeatGroovinUpper(BaseClient):
self.assert_path(resp, "response/player/pdata/pue")
if resp.child_value("player/pdata/base/name") != self.NAME:
raise Exception(
f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!'
)
raise Exception(f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!')
def verify_player_rb4readscore(
self, refid: str, location: str
) -> List[Dict[str, int]]:
def verify_player_rb4readscore(self, refid: str, location: str) -> List[Dict[str, int]]:
call = self.call_node()
player = Node.void("player")
@ -347,9 +339,7 @@ class ReflecBeatGroovinUpper(BaseClient):
continue
if child.child_value("user_id") != extid:
raise Exception(
f'Invalid user ID returned {child.child_value("user_id")}'
)
raise Exception(f'Invalid user ID returned {child.child_value("user_id")}')
episode = {
"id": child.child_value("type"),
@ -598,9 +588,7 @@ class ReflecBeatGroovinUpper(BaseClient):
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for comment!")
if comment != "アメ〜〜!":
raise Exception(
f"Invalid comment '{comment}' returned for comment!"
)
raise Exception(f"Invalid comment '{comment}' returned for comment!")
found = True
if not found:
@ -683,17 +671,11 @@ class ReflecBeatGroovinUpper(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Always get a player start, regardless of new profile or not
@ -706,16 +688,12 @@ class ReflecBeatGroovinUpper(BaseClient):
)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify lobby functionality
@ -853,26 +831,19 @@ class ReflecBeatGroovinUpper(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
else:
expected_score = expected["score"]
if "expected_achievement_rate" in expected:
expected_achievement_rate = expected[
"expected_achievement_rate"
]
expected_achievement_rate = expected["expected_achievement_rate"]
else:
expected_achievement_rate = expected["achievement_rate"]
if "expected_clear_type" in expected:

View File

@ -213,9 +213,7 @@ class ReflecBeatLimelight(BaseClient):
self.assert_path(resp, "response/player/pdata/narrow_down/adv_param")
if resp.child_value("player/pdata/base/name") != self.NAME:
raise Exception(
f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!'
)
raise Exception(f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!')
scores = []
for child in resp.child("player/pdata/record").children:
@ -343,9 +341,7 @@ class ReflecBeatLimelight(BaseClient):
return f'{thing["id"]}-{thing["chart"]}'
updates = [key(score) for score in scores]
sortedrecords = {
key(record): record for record in records if key(record) in updates
}
sortedrecords = {key(record): record for record in records if key(record) in updates}
# Now, see what records need updating and update them
for score in scores:
@ -366,9 +362,7 @@ class ReflecBeatLimelight(BaseClient):
"id": score["id"],
"chart": score["chart"],
"clear_type": max(record["clear_type"], score["clear_type"]),
"achievement_rate": max(
record["achievement_rate"], score["achievement_rate"]
),
"achievement_rate": max(record["achievement_rate"], score["achievement_rate"]),
"score": max(record["score"], score["score"]),
"combo": max(record["combo"], score["combo"]),
"miss_count": min(record["miss_count"], score["miss_count"]),
@ -443,9 +437,7 @@ class ReflecBeatLimelight(BaseClient):
self.assert_path(resp, "response/player/time")
return resp.child_value("player/uid")
def verify_log_play(
self, extid: int, loc: str, scores: List[Dict[str, int]]
) -> None:
def verify_log_play(self, extid: int, loc: str, scores: List[Dict[str, int]]) -> None:
call = self.call_node()
log = Node.void("log")
@ -683,9 +675,7 @@ class ReflecBeatLimelight(BaseClient):
if name != self.NAME:
raise Exception(f"Invalid name '{name}' returned for comment!")
if comment != "アメ〜〜!":
raise Exception(
f"Invalid comment '{comment}' returned for comment!"
)
raise Exception(f"Invalid comment '{comment}' returned for comment!")
found = True
if not found:
@ -745,17 +735,11 @@ class ReflecBeatLimelight(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Always get a player start, regardless of new profile or not
self.verify_player_start(ref_id)
@ -769,16 +753,12 @@ class ReflecBeatLimelight(BaseClient):
)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify lobby functionality
@ -875,26 +855,19 @@ class ReflecBeatLimelight(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
else:
expected_score = expected["score"]
if "expected_achievement_rate" in expected:
expected_achievement_rate = expected[
"expected_achievement_rate"
]
expected_achievement_rate = expected["expected_achievement_rate"]
else:
expected_achievement_rate = expected["achievement_rate"]
if "expected_clear_type" in expected:

View File

@ -155,9 +155,7 @@ class ReflecBeat(BaseClient):
self.assert_path(resp, "response/player/pdata/cmnt")
if resp.child_value("player/pdata/base/name") != self.NAME:
raise Exception(
f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!'
)
raise Exception(f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!')
scores = []
for child in resp.child("player/pdata/record").children:
@ -224,9 +222,7 @@ class ReflecBeat(BaseClient):
return f'{thing["id"]}-{thing["chart"]}'
updates = [key(score) for score in scores]
sortedrecords = {
key(record): record for record in records if key(record) in updates
}
sortedrecords = {key(record): record for record in records if key(record) in updates}
# Now, see what records need updating and update them
for score in scores:
@ -247,9 +243,7 @@ class ReflecBeat(BaseClient):
"id": score["id"],
"chart": score["chart"],
"clear_type": max(record["clear_type"], score["clear_type"]),
"achievement_rate": max(
record["achievement_rate"], score["achievement_rate"]
),
"achievement_rate": max(record["achievement_rate"], score["achievement_rate"]),
"score": max(record["score"], score["score"]),
"combo": max(record["combo"], score["combo"]),
"miss_count": min(record["miss_count"], score["miss_count"]),
@ -310,9 +304,7 @@ class ReflecBeat(BaseClient):
self.assert_path(resp, "response/player/time")
return resp.child_value("player/uid")
def verify_log_play(
self, extid: int, loc: str, scores: List[Dict[str, int]]
) -> None:
def verify_log_play(self, extid: int, loc: str, scores: List[Dict[str, int]]) -> None:
call = self.call_node()
log = Node.void("log")
@ -468,17 +460,11 @@ class ReflecBeat(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Always get a player start, regardless of new profile or not
self.verify_player_start(ref_id)
@ -492,16 +478,12 @@ class ReflecBeat(BaseClient):
)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify lobby functionality
@ -593,26 +575,19 @@ class ReflecBeat(BaseClient):
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
else:
expected_score = expected["score"]
if "expected_achievement_rate" in expected:
expected_achievement_rate = expected[
"expected_achievement_rate"
]
expected_achievement_rate = expected["expected_achievement_rate"]
else:
expected_achievement_rate = expected["achievement_rate"]
if "expected_clear_type" in expected:

View File

@ -121,11 +121,7 @@ class ReflecBeatVolzza(BaseClient):
player.add_child(Node.u8_array("ga", [127, 0, 0, 1]))
player.add_child(Node.u16("gp", 10573))
player.add_child(Node.u8_array("la", [16, 0, 0, 0]))
player.add_child(
Node.u8_array(
"pnid", [39, 16, 0, 0, 0, 23, 62, 60, 39, 127, 0, 0, 1, 23, 62, 60]
)
)
player.add_child(Node.u8_array("pnid", [39, 16, 0, 0, 0, 23, 62, 60, 39, 127, 0, 0, 1, 23, 62, 60]))
call.add_child(player)
@ -246,9 +242,7 @@ class ReflecBeatVolzza(BaseClient):
self.assert_path(resp, "response/player/ap")
self.assert_path(resp, "response/player/uattr")
def verify_player_rb5_player_read(
self, refid: str, cardid: str, location: str
) -> None:
def verify_player_rb5_player_read(self, refid: str, cardid: str, location: str) -> None:
call = self.call_node()
player = Node.void("player")
@ -303,13 +297,9 @@ class ReflecBeatVolzza(BaseClient):
self.assert_path(resp, "response/player/pdata/mylist/list/mlst")
if resp.child_value("player/pdata/base/name") != self.NAME:
raise Exception(
f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!'
)
raise Exception(f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!')
def verify_player_rb5_player_read_score(
self, refid: str, location: str
) -> List[Dict[str, int]]:
def verify_player_rb5_player_read_score(self, refid: str, location: str) -> List[Dict[str, int]]:
call = self.call_node()
player = Node.void("player")
@ -581,17 +571,11 @@ class ReflecBeatVolzza(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Always get a player start, regardless of new profile or not
@ -603,16 +587,12 @@ class ReflecBeatVolzza(BaseClient):
)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify lobby functionality
@ -699,35 +679,26 @@ class ReflecBeatVolzza(BaseClient):
"expected_miss_count": 0,
},
]
self.verify_player_rb5_player_write(
ref_id, location, scores=dummyscores
)
self.verify_player_rb5_player_write(ref_id, location, scores=dummyscores)
self.verify_player_rb5_player_read(ref_id, card, location)
scores = self.verify_player_rb5_player_read_score(ref_id, location)
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
else:
expected_score = expected["score"]
if "expected_achievement_rate" in expected:
expected_achievement_rate = expected[
"expected_achievement_rate"
]
expected_achievement_rate = expected["expected_achievement_rate"]
else:
expected_achievement_rate = expected["achievement_rate"]
if "expected_clear_type" in expected:

View File

@ -122,11 +122,7 @@ class ReflecBeatVolzza2(BaseClient):
player.add_child(Node.u8_array("ga", [127, 0, 0, 1]))
player.add_child(Node.u16("gp", 10573))
player.add_child(Node.u8_array("la", [16, 0, 0, 0]))
player.add_child(
Node.u8_array(
"pnid", [39, 16, 0, 0, 0, 23, 62, 60, 39, 127, 0, 0, 1, 23, 62, 60]
)
)
player.add_child(Node.u8_array("pnid", [39, 16, 0, 0, 0, 23, 62, 60, 39, 127, 0, 0, 1, 23, 62, 60]))
call.add_child(player)
@ -248,9 +244,7 @@ class ReflecBeatVolzza2(BaseClient):
self.assert_path(resp, "response/player/ap")
self.assert_path(resp, "response/player/uattr")
def verify_player_rb5_player_read(
self, refid: str, cardid: str, location: str
) -> Dict[str, Any]:
def verify_player_rb5_player_read(self, refid: str, cardid: str, location: str) -> Dict[str, Any]:
call = self.call_node()
player = Node.void("player")
@ -310,9 +304,7 @@ class ReflecBeatVolzza2(BaseClient):
self.assert_path(resp, "response/player/pdata/mycourse_f")
if resp.child_value("player/pdata/base/name") != self.NAME:
raise Exception(
f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!'
)
raise Exception(f'Invalid name {resp.child_value("player/pdata/base/name")} returned on profile read!')
mycourse = [
{
@ -340,9 +332,7 @@ class ReflecBeatVolzza2(BaseClient):
"mycourse": mycourse,
}
def verify_player_rb5_player_read_score_5(
self, refid: str, location: str
) -> List[Dict[str, int]]:
def verify_player_rb5_player_read_score_5(self, refid: str, location: str) -> List[Dict[str, int]]:
call = self.call_node()
player = Node.void("player")
@ -386,9 +376,7 @@ class ReflecBeatVolzza2(BaseClient):
scores.append(score)
return scores
def verify_player_rb5_player_read_score_old_5(
self, refid: str, location: str
) -> List[Dict[str, int]]:
def verify_player_rb5_player_read_score_old_5(self, refid: str, location: str) -> List[Dict[str, int]]:
call = self.call_node()
player = Node.void("player")
@ -688,17 +676,11 @@ class ReflecBeatVolzza2(BaseClient):
print(f"Generated random card ID {card} for use.")
if cardid is None:
self.verify_cardmng_inquire(
card, msg_type="unregistered", paseli_enabled=paseli_enabled
)
self.verify_cardmng_inquire(card, msg_type="unregistered", paseli_enabled=paseli_enabled)
ref_id = self.verify_cardmng_getrefid(card)
if len(ref_id) != 16:
raise Exception(
f"Invalid refid '{ref_id}' returned when registering card"
)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="new", paseli_enabled=paseli_enabled
):
raise Exception(f"Invalid refid '{ref_id}' returned when registering card")
if ref_id != self.verify_cardmng_inquire(card, msg_type="new", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Always get a player start, regardless of new profile or not
@ -710,16 +692,12 @@ class ReflecBeatVolzza2(BaseClient):
)
else:
print("Skipping new card checks for existing card")
ref_id = self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
)
ref_id = self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled)
# Verify pin handling and return card handling
self.verify_cardmng_authpass(ref_id, correct=True)
self.verify_cardmng_authpass(ref_id, correct=False)
if ref_id != self.verify_cardmng_inquire(
card, msg_type="query", paseli_enabled=paseli_enabled
):
if ref_id != self.verify_cardmng_inquire(card, msg_type="query", paseli_enabled=paseli_enabled):
raise Exception(f"Invalid refid '{ref_id}' returned when querying card")
# Verify lobby functionality
@ -815,35 +793,26 @@ class ReflecBeatVolzza2(BaseClient):
"expected_miss_count": 0,
},
]
self.verify_player_rb5_player_write_5(
ref_id, location, scores=dummyscores
)
self.verify_player_rb5_player_write_5(ref_id, location, scores=dummyscores)
self.verify_player_rb5_player_read(ref_id, card, location)
scores = self.verify_player_rb5_player_read_score_5(ref_id, location)
for expected in dummyscores:
actual = None
for received in scores:
if (
received["id"] == expected["id"]
and received["chart"] == expected["chart"]
):
if received["id"] == expected["id"] and received["chart"] == expected["chart"]:
actual = received
break
if actual is None:
raise Exception(
f"Didn't find song {expected['id']} chart {expected['chart']} in response!"
)
raise Exception(f"Didn't find song {expected['id']} chart {expected['chart']} in response!")
if "expected_score" in expected:
expected_score = expected["expected_score"]
else:
expected_score = expected["score"]
if "expected_achievement_rate" in expected:
expected_achievement_rate = expected[
"expected_achievement_rate"
]
expected_achievement_rate = expected["expected_achievement_rate"]
else:
expected_achievement_rate = expected["achievement_rate"]
if "expected_clear_type" in expected:

Some files were not shown because too many files have changed in this diff Show More