2022-10-03 04:10:43 +02:00
|
|
|
import random
|
|
|
|
import time
|
|
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
|
|
|
|
from bemani.client.base import BaseClient
|
|
|
|
from bemani.common import CardCipher, Time
|
|
|
|
from bemani.protocol import Node
|
|
|
|
|
|
|
|
|
|
|
|
class JubeatFestoClient(BaseClient):
|
2022-10-15 20:56:30 +02:00
|
|
|
NAME = "TEST"
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
def __verify_info(self, resp: Node, base: str) -> None:
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/event_info")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/genre_def_music")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/black_jacket_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/white_music_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/white_marker_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/white_theme_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/open_music_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/shareable_music_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/hot_music_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/jbox/point")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/jbox/emblem/normal/index")
|
|
|
|
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")
|
2022-10-15 20:56:30 +02:00
|
|
|
self.assert_path(
|
|
|
|
resp, f"response/{base}/data/info/konami_logo_50th/is_available"
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
self.assert_path(resp, f"response/{base}/data/info/expert_option/is_available")
|
2022-10-15 20:56:30 +02:00
|
|
|
self.assert_path(
|
|
|
|
resp, f"response/{base}/data/info/all_music_matching/is_available"
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
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.
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/course_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/share_music")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/weekly_music/value")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/weekly_music/music_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/add_default_music_list")
|
|
|
|
|
|
|
|
# These below I'm not sure are needed, and I think some of them mess with stone tablet.
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/team_battle")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/emo_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/hike_event")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/tip_list")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/travel")
|
|
|
|
self.assert_path(resp, f"response/{base}/data/info/stamp")
|
|
|
|
|
|
|
|
def verify_shopinfo_regist(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
shopinfo = Node.void("shopinfo")
|
|
|
|
shopinfo.set_attribute("method", "regist")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(shopinfo)
|
2022-10-15 20:56:30 +02:00
|
|
|
shop = Node.void("shop")
|
2022-10-03 04:10:43 +02:00
|
|
|
shopinfo.add_child(shop)
|
2022-10-15 20:56:30 +02:00
|
|
|
shop.add_child(Node.string("name", ""))
|
|
|
|
shop.add_child(Node.string("pref", "JP-14"))
|
|
|
|
shop.add_child(Node.string("softwareid", ""))
|
|
|
|
shop.add_child(Node.string("systemid", self.pcbid))
|
|
|
|
shop.add_child(Node.string("hardwareid", "01020304050607080900"))
|
|
|
|
shop.add_child(Node.string("locationid", "US-1"))
|
|
|
|
shop.add_child(Node.string("monitor", "D26L155 6252 151"))
|
|
|
|
testmode = Node.void("testmode")
|
2022-10-03 04:10:43 +02:00
|
|
|
shop.add_child(testmode)
|
2022-10-15 20:56:30 +02:00
|
|
|
sound = Node.void("sound")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(sound)
|
2022-10-15 20:56:30 +02:00
|
|
|
sound.add_child(Node.u8("volume_in_attract", 0))
|
|
|
|
game = Node.void("game")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(game)
|
2022-10-15 20:56:30 +02:00
|
|
|
play_settings = Node.void("play_settings")
|
2022-10-03 04:10:43 +02:00
|
|
|
game.add_child(play_settings)
|
2022-10-15 20:56:30 +02:00
|
|
|
play_settings.add_child(Node.u8("max_member", 1))
|
|
|
|
game_settings = Node.void("game_settings")
|
2022-10-03 04:10:43 +02:00
|
|
|
game.add_child(game_settings)
|
2022-10-15 20:56:30 +02:00
|
|
|
game_settings.add_child(Node.u8("close_set", 0))
|
|
|
|
game_settings.add_child(Node.s32("close_time", 0))
|
|
|
|
display_type_settings = Node.void("display_type_settings")
|
2022-10-03 04:10:43 +02:00
|
|
|
game.add_child(display_type_settings)
|
2022-10-15 20:56:30 +02:00
|
|
|
display_type_settings.add_child(Node.u8("display_type", 2))
|
|
|
|
coin = Node.void("coin")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(coin)
|
2022-10-15 20:56:30 +02:00
|
|
|
coin.add_child(Node.u8("free_play", 0))
|
|
|
|
coin.add_child(Node.u8("free_first_play", 1))
|
|
|
|
coin.add_child(Node.u8("coin_slot", 8))
|
|
|
|
coin.add_child(Node.u8("start", 1))
|
|
|
|
network = Node.void("network")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(network)
|
2022-10-15 20:56:30 +02:00
|
|
|
network.add_child(Node.u8("cabinet_id", 1))
|
|
|
|
bookkeeping = Node.void("bookkeeping")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(bookkeeping)
|
2022-10-15 20:56:30 +02:00
|
|
|
bookkeeping.add_child(Node.u8("enable", 0))
|
|
|
|
clock = Node.void("clock")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(clock)
|
2022-10-15 20:56:30 +02:00
|
|
|
clock.add_child(Node.u8("enable", 1))
|
|
|
|
clock.add_child(Node.s32("offset", 0))
|
|
|
|
virtual_coin = Node.void("virtual_coin")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(virtual_coin)
|
2022-10-15 20:56:30 +02:00
|
|
|
pattern1 = Node.void("pattern1")
|
2022-10-03 04:10:43 +02:00
|
|
|
virtual_coin.add_child(pattern1)
|
2022-10-15 20:56:30 +02:00
|
|
|
pattern1.add_child(Node.u16("basic_rate", 1000))
|
|
|
|
pattern1.add_child(Node.u8("balance_of_credit", 0))
|
|
|
|
pattern1.add_child(Node.u8("is_premium_start", 0))
|
|
|
|
pattern1.add_child(Node.u8("service_value", 10))
|
|
|
|
pattern1.add_child(Node.u8("service_limit", 10))
|
|
|
|
pattern1.add_child(Node.u8("service_time_start_h", 7))
|
|
|
|
pattern1.add_child(Node.u8("service_time_start_m", 0))
|
|
|
|
pattern1.add_child(Node.u8("service_time_end_h", 11))
|
|
|
|
pattern1.add_child(Node.u8("service_time_end_m", 0))
|
|
|
|
pattern2 = Node.void("pattern2")
|
2022-10-03 04:10:43 +02:00
|
|
|
virtual_coin.add_child(pattern2)
|
2022-10-15 20:56:30 +02:00
|
|
|
pattern2.add_child(Node.u16("basic_rate", 1000))
|
|
|
|
pattern2.add_child(Node.u8("balance_of_credit", 0))
|
|
|
|
pattern2.add_child(Node.u8("is_premium_start", 0))
|
|
|
|
pattern2.add_child(Node.u8("service_value", 10))
|
|
|
|
pattern2.add_child(Node.u8("service_limit", 10))
|
|
|
|
pattern2.add_child(Node.u8("service_time_start_h", 7))
|
|
|
|
pattern2.add_child(Node.u8("service_time_start_m", 0))
|
|
|
|
pattern2.add_child(Node.u8("service_time_end_h", 11))
|
|
|
|
pattern2.add_child(Node.u8("service_time_end_m", 0))
|
|
|
|
pattern3 = Node.void("pattern3")
|
2022-10-03 04:10:43 +02:00
|
|
|
virtual_coin.add_child(pattern3)
|
2022-10-15 20:56:30 +02:00
|
|
|
pattern3.add_child(Node.u16("basic_rate", 1000))
|
|
|
|
pattern3.add_child(Node.u8("balance_of_credit", 0))
|
|
|
|
pattern3.add_child(Node.u8("is_premium_start", 0))
|
|
|
|
pattern3.add_child(Node.u8("service_value", 10))
|
|
|
|
pattern3.add_child(Node.u8("service_limit", 10))
|
|
|
|
pattern3.add_child(Node.u8("service_time_start_h", 7))
|
|
|
|
pattern3.add_child(Node.u8("service_time_start_m", 0))
|
|
|
|
pattern3.add_child(Node.u8("service_time_end_h", 11))
|
|
|
|
pattern3.add_child(Node.u8("service_time_end_m", 0))
|
|
|
|
schedule = Node.void("schedule")
|
2022-10-03 04:10:43 +02:00
|
|
|
virtual_coin.add_child(schedule)
|
2022-10-15 20:56:30 +02:00
|
|
|
schedule.add_child(Node.u8("mon", 0))
|
|
|
|
schedule.add_child(Node.u8("tue", 0))
|
|
|
|
schedule.add_child(Node.u8("wed", 0))
|
|
|
|
schedule.add_child(Node.u8("thu", 0))
|
|
|
|
schedule.add_child(Node.u8("fri", 0))
|
|
|
|
schedule.add_child(Node.u8("sat", 0))
|
|
|
|
schedule.add_child(Node.u8("sun", 0))
|
|
|
|
schedule.add_child(Node.u8("holi", 0))
|
|
|
|
tax = Node.void("tax")
|
2022-10-03 04:10:43 +02:00
|
|
|
testmode.add_child(tax)
|
2022-10-15 20:56:30 +02:00
|
|
|
tax.add_child(Node.u8("tax_phase", 0))
|
|
|
|
tax.add_child(Node.u8("tax_mode", 0))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
self.assert_path(resp, "response/shopinfo/data/cabid")
|
|
|
|
self.assert_path(resp, "response/shopinfo/data/locationid")
|
|
|
|
self.assert_path(resp, "response/shopinfo/data/tax_phase")
|
|
|
|
self.assert_path(resp, "response/shopinfo/data/facility/exist")
|
|
|
|
|
|
|
|
# Verify server flags for events and stuff.
|
2022-10-15 20:56:30 +02:00
|
|
|
self.__verify_info(resp, "shopinfo")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
def verify_logger_report(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
logger = Node.void("logger")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(logger)
|
2022-10-15 20:56:30 +02:00
|
|
|
logger.set_attribute("method", "report")
|
|
|
|
logger.add_child(Node.s32("retry", 0))
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
logger.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
data.add_child(Node.string("code", "pcbinfo_01"))
|
|
|
|
data.add_child(
|
|
|
|
Node.string("information", "u can literally put anything here lmao")
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/logger/@status")
|
|
|
|
|
|
|
|
def verify_demodata_get_info(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
demodata = Node.void("demodata")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(demodata)
|
2022-10-15 20:56:30 +02:00
|
|
|
demodata.set_attribute("method", "get_info")
|
|
|
|
pcbinfo = Node.void("pcbinfo")
|
2022-10-03 04:10:43 +02:00
|
|
|
demodata.add_child(pcbinfo)
|
2022-10-15 20:56:30 +02:00
|
|
|
pcbinfo.set_attribute("client_data_version", "0")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/demodata/data/info/black_jacket_list")
|
|
|
|
|
|
|
|
def verify_demodata_get_news(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
demodata = Node.void("demodata")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(demodata)
|
2022-10-15 20:56:30 +02:00
|
|
|
demodata.set_attribute("method", "get_news")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/demodata/data/officialnews/@count")
|
|
|
|
|
|
|
|
def verify_demodata_get_jbox_list(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
demodata = Node.void("demodata")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(demodata)
|
2022-10-15 20:56:30 +02:00
|
|
|
demodata.set_attribute("method", "get_jbox_list")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/demodata/@status")
|
|
|
|
|
|
|
|
def verify_lab_get_ranking(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
lab = Node.void("lab")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(lab)
|
2022-10-15 20:56:30 +02:00
|
|
|
lab.set_attribute("method", "get_ranking")
|
|
|
|
lab.add_child(Node.s32("retry", 0))
|
|
|
|
lab.add_child(Node.s8("category", 1))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/lab/category")
|
|
|
|
self.assert_path(resp, "response/lab/entries/@count")
|
|
|
|
|
|
|
|
# Category should be the same as when we requested it.
|
|
|
|
if resp.child_value("lab/category") != 1:
|
|
|
|
raise Exception("Lab category did not get round-tripped!")
|
|
|
|
|
|
|
|
def __verify_profile(self, resp: Node, should_inherit: bool) -> int:
|
|
|
|
for item in [
|
2022-10-15 20:56:30 +02:00
|
|
|
"tune_cnt",
|
|
|
|
"save_cnt",
|
|
|
|
"saved_cnt",
|
|
|
|
"fc_cnt",
|
|
|
|
"ex_cnt",
|
|
|
|
"clear_cnt",
|
|
|
|
"match_cnt",
|
|
|
|
"beat_cnt",
|
|
|
|
"mynews_cnt",
|
|
|
|
"bonus_tune_points",
|
|
|
|
"is_bonus_tune_played",
|
|
|
|
"inherit",
|
|
|
|
"mtg_entry_cnt",
|
|
|
|
"mtg_hold_cnt",
|
|
|
|
"mtg_result",
|
2022-10-03 04:10:43 +02:00
|
|
|
]:
|
|
|
|
self.assert_path(resp, f"response/gametop/data/player/info/{item}")
|
|
|
|
|
|
|
|
# Technically we could use this to check profile succession doesn't show the
|
|
|
|
# tutorial, but we don't go that far yet.
|
|
|
|
if resp.child_value("gametop/data/player/info/inherit") != should_inherit:
|
|
|
|
raise Exception("Inherit flag wrong for profile!")
|
|
|
|
|
|
|
|
for item in [
|
2022-10-15 20:56:30 +02:00
|
|
|
"music_list",
|
|
|
|
"secret_list",
|
|
|
|
"theme_list",
|
|
|
|
"marker_list",
|
|
|
|
"title_list",
|
|
|
|
"parts_list",
|
|
|
|
"emblem_list",
|
|
|
|
"commu_list",
|
|
|
|
"new/secret_list",
|
|
|
|
"new/theme_list",
|
|
|
|
"new/marker_list",
|
2022-10-03 04:10:43 +02:00
|
|
|
]:
|
|
|
|
self.assert_path(resp, f"response/gametop/data/player/item/{item}")
|
|
|
|
|
|
|
|
for item in [
|
2022-10-15 20:56:30 +02:00
|
|
|
"play_time",
|
|
|
|
"shopname",
|
|
|
|
"areaname",
|
|
|
|
"music_id",
|
|
|
|
"seq_id",
|
|
|
|
"sort",
|
|
|
|
"category",
|
|
|
|
"expert_option",
|
2022-10-03 04:10:43 +02:00
|
|
|
]:
|
|
|
|
self.assert_path(resp, f"response/gametop/data/player/last/{item}")
|
|
|
|
|
|
|
|
for item in [
|
2022-10-15 20:56:30 +02:00
|
|
|
"marker",
|
|
|
|
"theme",
|
|
|
|
"title",
|
|
|
|
"parts",
|
|
|
|
"rank_sort",
|
|
|
|
"combo_disp",
|
|
|
|
"emblem",
|
|
|
|
"matching",
|
|
|
|
"hard",
|
|
|
|
"hazard",
|
2022-10-03 04:10:43 +02:00
|
|
|
]:
|
|
|
|
self.assert_path(resp, f"response/gametop/data/player/last/settings/{item}")
|
|
|
|
|
|
|
|
# Misc stuff
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/session_id")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/event_flag")
|
|
|
|
|
|
|
|
# Profile settings
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/name")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/jid")
|
2022-10-15 20:56:30 +02:00
|
|
|
if resp.child_value("gametop/data/player/name") != self.NAME:
|
2022-10-03 04:10:43 +02:00
|
|
|
raise Exception("Unexpected name received from server!")
|
|
|
|
|
|
|
|
# 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")
|
2022-10-15 20:56:30 +02:00
|
|
|
self.assert_path(
|
|
|
|
resp, "response/gametop/data/player/fc_challenge/today/music_id"
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
self.assert_path(resp, "response/gametop/data/player/fc_challenge/today/state")
|
2022-10-15 20:56:30 +02:00
|
|
|
self.assert_path(
|
|
|
|
resp, "response/gametop/data/player/fc_challenge/whim/music_id"
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
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")
|
2022-10-15 20:56:30 +02:00
|
|
|
self.assert_path(
|
|
|
|
resp, "response/gametop/data/player/free_first_play/is_available"
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
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")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/jbox/emblem/premium/index")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/new_music")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/navi/flag")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/gift_list")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/born/status")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/born/year")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/question_list")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/emo_list")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/server")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/course_list")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/course_list/category_list")
|
2022-10-15 20:56:30 +02:00
|
|
|
self.assert_path(
|
|
|
|
resp,
|
|
|
|
"response/gametop/data/player/fill_in_category/normal/no_gray_flag_list",
|
|
|
|
)
|
|
|
|
self.assert_path(
|
|
|
|
resp,
|
|
|
|
"response/gametop/data/player/fill_in_category/normal/all_yellow_flag_list",
|
|
|
|
)
|
|
|
|
self.assert_path(
|
|
|
|
resp,
|
|
|
|
"response/gametop/data/player/fill_in_category/normal/full_combo_flag_list",
|
|
|
|
)
|
|
|
|
self.assert_path(
|
|
|
|
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/all_yellow_flag_list",
|
|
|
|
)
|
|
|
|
self.assert_path(
|
|
|
|
resp,
|
|
|
|
"response/gametop/data/player/fill_in_category/hard/full_combo_flag_list",
|
|
|
|
)
|
|
|
|
self.assert_path(
|
|
|
|
resp,
|
|
|
|
"response/gametop/data/player/fill_in_category/hard/excellent_flag_list",
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
self.assert_path(resp, "response/gametop/data/player/department/shop_list")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/stamp/sheet_list")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/festo_dungeon/phase")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/festo_dungeon/clear_flag")
|
|
|
|
|
|
|
|
# Return the jid
|
2022-10-15 20:56:30 +02:00
|
|
|
return resp.child_value("gametop/data/player/jid")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
def verify_gameend_regist(
|
|
|
|
self,
|
|
|
|
ref_id: str,
|
|
|
|
jid: int,
|
|
|
|
scores: List[Dict[str, Any]],
|
|
|
|
) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
gameend = Node.void("gameend")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(gameend)
|
2022-10-15 20:56:30 +02:00
|
|
|
gameend.set_attribute("method", "regist")
|
|
|
|
gameend.add_child(Node.s32("retry", 0))
|
|
|
|
pcbinfo = Node.void("pcbinfo")
|
2022-10-03 04:10:43 +02:00
|
|
|
gameend.add_child(pcbinfo)
|
2022-10-15 20:56:30 +02:00
|
|
|
pcbinfo.set_attribute("client_data_version", "0")
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
gameend.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.string("refid", ref_id))
|
|
|
|
player.add_child(Node.s32("jid", jid))
|
|
|
|
player.add_child(Node.string("name", self.NAME))
|
|
|
|
result = Node.void("result")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(result)
|
2022-10-15 20:56:30 +02:00
|
|
|
result.set_attribute("count", str(len(scores)))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Send scores
|
|
|
|
scoreid = 0
|
|
|
|
for score in scores:
|
|
|
|
# Always played
|
|
|
|
bits = 0x1
|
2022-10-15 20:56:30 +02:00
|
|
|
if score["clear"]:
|
2022-10-03 04:10:43 +02:00
|
|
|
bits |= 0x2
|
2022-10-15 20:56:30 +02:00
|
|
|
if score["fc"]:
|
2022-10-03 04:10:43 +02:00
|
|
|
bits |= 0x4
|
2022-10-15 20:56:30 +02:00
|
|
|
if score["ex"]:
|
2022-10-03 04:10:43 +02:00
|
|
|
bits |= 0x8
|
|
|
|
|
|
|
|
# Intentionally starting at 1 because that's what the game does
|
|
|
|
scoreid = scoreid + 1
|
2022-10-15 20:56:30 +02:00
|
|
|
tune = Node.void("tune")
|
2022-10-03 04:10:43 +02:00
|
|
|
result.add_child(tune)
|
2022-10-15 20:56:30 +02:00
|
|
|
tune.set_attribute("id", str(scoreid))
|
|
|
|
tune.add_child(Node.s32("music", score["id"]))
|
|
|
|
tune.add_child(Node.s64("timestamp", Time.now() * 1000))
|
|
|
|
player_1 = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
tune.add_child(player_1)
|
2022-10-15 20:56:30 +02:00
|
|
|
player_1.set_attribute("rank", "1")
|
|
|
|
scorenode = Node.s32("score", score["score"])
|
2022-10-03 04:10:43 +02:00
|
|
|
player_1.add_child(scorenode)
|
2022-10-15 20:56:30 +02:00
|
|
|
scorenode.set_attribute("seq", str(score["chart"]))
|
|
|
|
scorenode.set_attribute("clear", str(bits))
|
|
|
|
scorenode.set_attribute("combo", "69")
|
|
|
|
player_1.add_child(
|
|
|
|
Node.u8_array(
|
|
|
|
"mbar",
|
|
|
|
[
|
|
|
|
239,
|
|
|
|
175,
|
|
|
|
170,
|
|
|
|
170,
|
|
|
|
190,
|
|
|
|
234,
|
|
|
|
187,
|
|
|
|
158,
|
|
|
|
153,
|
|
|
|
230,
|
|
|
|
170,
|
|
|
|
90,
|
|
|
|
102,
|
|
|
|
170,
|
|
|
|
85,
|
|
|
|
150,
|
|
|
|
150,
|
|
|
|
102,
|
|
|
|
85,
|
|
|
|
234,
|
|
|
|
171,
|
|
|
|
169,
|
|
|
|
157,
|
|
|
|
150,
|
|
|
|
170,
|
|
|
|
101,
|
|
|
|
230,
|
|
|
|
90,
|
|
|
|
214,
|
|
|
|
255,
|
|
|
|
],
|
|
|
|
)
|
|
|
|
)
|
|
|
|
player_1.add_child(Node.bool("is_hard_mode", score["hard"]))
|
|
|
|
player_1.add_child(Node.s32("music_rate", score["rate"]))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
self.assert_path(resp, "response/gameend/data/player/session_id")
|
|
|
|
self.assert_path(resp, "response/gameend/data/player/end_final_session_id")
|
|
|
|
|
|
|
|
def verify_gameend_final(
|
|
|
|
self,
|
|
|
|
ref_id: str,
|
|
|
|
jid: int,
|
|
|
|
) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
gameend = Node.void("gameend")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(gameend)
|
2022-10-15 20:56:30 +02:00
|
|
|
gameend.set_attribute("method", "final")
|
|
|
|
gameend.add_child(Node.s32("retry", 0))
|
|
|
|
pcbinfo = Node.void("pcbinfo")
|
2022-10-03 04:10:43 +02:00
|
|
|
gameend.add_child(pcbinfo)
|
2022-10-15 20:56:30 +02:00
|
|
|
pcbinfo.set_attribute("client_data_version", "0")
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
gameend.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
info = Node.void("info")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(info)
|
2022-10-15 20:56:30 +02:00
|
|
|
born = Node.void("born")
|
2022-10-03 04:10:43 +02:00
|
|
|
info.add_child(born)
|
2022-10-15 20:56:30 +02:00
|
|
|
born.add_child(Node.s8("status", 3))
|
|
|
|
born.add_child(Node.s16("year", 0))
|
|
|
|
info.add_child(Node.void("question_list"))
|
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.string("refid", ref_id))
|
|
|
|
player.add_child(Node.s32("jid", jid))
|
|
|
|
jbox = Node.void("jbox")
|
2022-10-03 04:10:43 +02:00
|
|
|
player.add_child(jbox)
|
2022-10-15 20:56:30 +02:00
|
|
|
jbox.add_child(Node.s32("point", 0))
|
|
|
|
emblem = Node.void("emblem")
|
2022-10-03 04:10:43 +02:00
|
|
|
jbox.add_child(emblem)
|
2022-10-15 20:56:30 +02:00
|
|
|
emblem.add_child(Node.u8("type", 0))
|
|
|
|
emblem.add_child(Node.s16("index", 0))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
self.assert_path(resp, "response/gameend/@status")
|
|
|
|
|
|
|
|
def verify_gametop_regist(self, card_id: str, ref_id: str) -> int:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop = Node.void("gametop")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(gametop)
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop.set_attribute("method", "regist")
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
gametop.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.string("refid", ref_id))
|
|
|
|
player.add_child(Node.string("datid", ref_id))
|
|
|
|
player.add_child(Node.string("uid", card_id))
|
|
|
|
player.add_child(Node.bool("inherit", True))
|
|
|
|
player.add_child(Node.string("name", self.NAME))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify server flags for events and stuff.
|
2022-10-15 20:56:30 +02:00
|
|
|
self.__verify_info(resp, "gametop")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify nodes that cause crashes or failed card-ins if they don't exist
|
|
|
|
return self.__verify_profile(resp, False)
|
|
|
|
|
|
|
|
def verify_gametop_get_pdata(self, card_id: str, ref_id: str) -> int:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop = Node.void("gametop")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(gametop)
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop.set_attribute("method", "get_pdata")
|
|
|
|
retry = Node.s32("retry", 0)
|
2022-10-03 04:10:43 +02:00
|
|
|
gametop.add_child(retry)
|
2022-10-15 20:56:30 +02:00
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
gametop.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.string("refid", ref_id))
|
|
|
|
player.add_child(Node.string("datid", ref_id))
|
|
|
|
player.add_child(Node.string("uid", card_id))
|
|
|
|
player.add_child(Node.string("card_no", CardCipher.encode(card_id)))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify nodes that cause crashes if they don't exist
|
|
|
|
return self.__verify_profile(resp, False)
|
|
|
|
|
|
|
|
def verify_gametop_get_mdata(self, jid: int) -> Dict[str, List[Dict[str, Any]]]:
|
|
|
|
ret = {}
|
2023-08-19 22:08:35 +02:00
|
|
|
for ver in [1, 2, 3]:
|
|
|
|
# Construct node
|
|
|
|
call = self.call_node()
|
|
|
|
gametop = Node.void("gametop")
|
|
|
|
call.add_child(gametop)
|
|
|
|
gametop.set_attribute("method", "get_mdata")
|
|
|
|
retry = Node.s32("retry", 0)
|
|
|
|
gametop.add_child(retry)
|
|
|
|
data = Node.void("data")
|
|
|
|
gametop.add_child(data)
|
|
|
|
player = Node.void("player")
|
|
|
|
data.add_child(player)
|
|
|
|
player.add_child(Node.s32("jid", jid))
|
|
|
|
player.add_child(Node.s8("mdata_ver", ver))
|
|
|
|
player.add_child(Node.bool("rival", False))
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
resp = self.exchange("", call)
|
|
|
|
|
|
|
|
# Parse out scores
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/jid")
|
|
|
|
self.assert_path(resp, "response/gametop/data/player/mdata_list")
|
|
|
|
if resp.child_value("gametop/data/player/jid") != jid:
|
|
|
|
raise Exception("Unexpected jid received from server!")
|
|
|
|
|
|
|
|
for musicdata in resp.child("gametop/data/player/mdata_list").children:
|
|
|
|
if musicdata.name != "musicdata":
|
|
|
|
raise Exception("Unexpected node in playdata!")
|
|
|
|
|
|
|
|
music_id = musicdata.attribute("music_id")
|
|
|
|
scores_by_chart: List[Dict[str, int]] = [{}, {}, {}, {}, {}, {}]
|
|
|
|
|
|
|
|
def extract_cnts(name: str, offset: int, val: List[int]) -> None:
|
|
|
|
scores_by_chart[offset + 0][name] = val[0]
|
|
|
|
scores_by_chart[offset + 1][name] = val[1]
|
|
|
|
scores_by_chart[offset + 2][name] = val[2]
|
|
|
|
|
|
|
|
for subdata in musicdata.children:
|
|
|
|
if subdata.name == "normal":
|
|
|
|
offset = 0
|
|
|
|
elif subdata.name == "hard":
|
|
|
|
offset = 3
|
|
|
|
else:
|
|
|
|
raise Exception(f"Unexpected chart type {subdata.name}!")
|
|
|
|
|
|
|
|
extract_cnts("plays", offset, subdata.child_value("play_cnt"))
|
|
|
|
extract_cnts("clears", offset, subdata.child_value("clear_cnt"))
|
|
|
|
extract_cnts("full_combos", offset, subdata.child_value("fc_cnt"))
|
|
|
|
extract_cnts("excellents", offset, subdata.child_value("ex_cnt"))
|
|
|
|
extract_cnts("score", offset, subdata.child_value("score"))
|
|
|
|
extract_cnts("medal", offset, subdata.child_value("clear"))
|
|
|
|
extract_cnts("rate", offset, subdata.child_value("music_rate"))
|
|
|
|
|
|
|
|
ret[music_id] = scores_by_chart
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def verify_gametop_get_meeting(self, jid: int) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop = Node.void("gametop")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(gametop)
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop.set_attribute("method", "get_meeting")
|
|
|
|
gametop.add_child(Node.s32("retry", 0))
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
gametop.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.s32("jid", jid))
|
|
|
|
pcbinfo = Node.void("pcbinfo")
|
2022-10-03 04:10:43 +02:00
|
|
|
gametop.add_child(pcbinfo)
|
2022-10-15 20:56:30 +02:00
|
|
|
pcbinfo.set_attribute("client_data_version", "0")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify expected nodes
|
|
|
|
self.assert_path(resp, "response/gametop/data/meeting/single/@count")
|
|
|
|
self.assert_path(resp, "response/gametop/data/meeting/tag/@count")
|
|
|
|
self.assert_path(resp, "response/gametop/data/reward/total")
|
|
|
|
self.assert_path(resp, "response/gametop/data/reward/point")
|
|
|
|
|
|
|
|
def verify_recommend_get_recommend(self, jid: int) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
recommend = Node.void("recommend")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(recommend)
|
2022-10-15 20:56:30 +02:00
|
|
|
recommend.set_attribute("method", "get_recommend")
|
|
|
|
recommend.add_child(Node.s32("retry", 0))
|
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
recommend.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.s32("jid", jid))
|
|
|
|
player.add_child(Node.void("music_list"))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify expected nodes
|
|
|
|
self.assert_path(resp, "response/recommend/data/player/music_list")
|
|
|
|
|
|
|
|
def verify_demodata_get_hitchart(self) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop = Node.void("demodata")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(gametop)
|
2022-10-15 20:56:30 +02:00
|
|
|
gametop.set_attribute("method", "get_hitchart")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify expected nodes
|
|
|
|
self.assert_path(resp, "response/demodata/data/update")
|
|
|
|
self.assert_path(resp, "response/demodata/data/hitchart_lic/@count")
|
|
|
|
self.assert_path(resp, "response/demodata/data/hitchart_org/@count")
|
|
|
|
|
|
|
|
def verify_jbox_get_list(self, jid: int) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
jbox = Node.void("jbox")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(jbox)
|
2022-10-15 20:56:30 +02:00
|
|
|
jbox.set_attribute("method", "get_list")
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
jbox.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.s32("jid", jid))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/jbox/selection_list")
|
|
|
|
|
|
|
|
def verify_jbox_get_agreement(self, jid: int) -> None:
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
# Construct node
|
2022-10-15 20:56:30 +02:00
|
|
|
jbox = Node.void("jbox")
|
2022-10-03 04:10:43 +02:00
|
|
|
call.add_child(jbox)
|
2022-10-15 20:56:30 +02:00
|
|
|
jbox.set_attribute("method", "get_agreement")
|
|
|
|
data = Node.void("data")
|
2022-10-03 04:10:43 +02:00
|
|
|
jbox.add_child(data)
|
2022-10-15 20:56:30 +02:00
|
|
|
player = Node.void("player")
|
2022-10-03 04:10:43 +02:00
|
|
|
data.add_child(player)
|
2022-10-15 20:56:30 +02:00
|
|
|
player.add_child(Node.s32("jid", jid))
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Swap with server
|
2022-10-15 20:56:30 +02:00
|
|
|
resp = self.exchange("", call)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
self.assert_path(resp, "response/jbox/is_agreement")
|
|
|
|
|
|
|
|
def verify(self, cardid: Optional[str]) -> None:
|
|
|
|
# Verify boot sequence is okay
|
|
|
|
self.verify_services_get(
|
|
|
|
expected_services=[
|
2022-10-15 20:56:30 +02:00
|
|
|
"pcbtracker",
|
|
|
|
"pcbevent",
|
|
|
|
"local",
|
|
|
|
"message",
|
|
|
|
"facility",
|
|
|
|
"cardmng",
|
|
|
|
"package",
|
|
|
|
"posevent",
|
|
|
|
"pkglist",
|
|
|
|
"dlstatus",
|
|
|
|
"eacoin",
|
|
|
|
"lobby",
|
|
|
|
"netlog",
|
|
|
|
"slocal",
|
|
|
|
"ntp",
|
|
|
|
"keepalive",
|
2022-10-03 04:10:43 +02:00
|
|
|
],
|
|
|
|
include_net=True,
|
|
|
|
)
|
|
|
|
paseli_enabled = self.verify_pcbtracker_alive(ecflag=3)
|
|
|
|
self.verify_package_list()
|
|
|
|
self.verify_message_get()
|
2022-10-15 20:56:30 +02:00
|
|
|
self.verify_facility_get(encoding="Shift-JIS")
|
2022-10-03 04:10:43 +02:00
|
|
|
self.verify_pcbevent_put()
|
|
|
|
self.verify_logger_report()
|
|
|
|
self.verify_shopinfo_regist()
|
|
|
|
self.verify_demodata_get_info()
|
|
|
|
self.verify_demodata_get_jbox_list()
|
|
|
|
self.verify_demodata_get_news()
|
|
|
|
self.verify_demodata_get_hitchart()
|
|
|
|
self.verify_lab_get_ranking()
|
|
|
|
|
|
|
|
# Verify card registration and profile lookup
|
|
|
|
if cardid is not None:
|
|
|
|
card = cardid
|
|
|
|
else:
|
|
|
|
card = self.random_card()
|
|
|
|
print(f"Generated random card ID {card} for use.")
|
|
|
|
|
|
|
|
if cardid is None:
|
2022-10-15 20:56:30 +02:00
|
|
|
self.verify_cardmng_inquire(
|
|
|
|
card, msg_type="unregistered", paseli_enabled=paseli_enabled
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
ref_id = self.verify_cardmng_getrefid(card)
|
|
|
|
if len(ref_id) != 16:
|
2022-10-15 20:56:30 +02:00
|
|
|
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")
|
2022-10-03 04:10:43 +02:00
|
|
|
self.verify_gametop_regist(card, ref_id)
|
|
|
|
else:
|
|
|
|
print("Skipping new card checks for existing card")
|
2022-10-15 20:56:30 +02:00
|
|
|
ref_id = self.verify_cardmng_inquire(
|
|
|
|
card, msg_type="query", paseli_enabled=paseli_enabled
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify pin handling and return card handling
|
|
|
|
self.verify_cardmng_authpass(ref_id, correct=True)
|
|
|
|
self.verify_cardmng_authpass(ref_id, correct=False)
|
2022-10-15 20:56:30 +02:00
|
|
|
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")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
if cardid is None:
|
|
|
|
# Verify score handling
|
|
|
|
jid = self.verify_gametop_get_pdata(card, ref_id)
|
|
|
|
self.verify_recommend_get_recommend(jid)
|
|
|
|
scores = self.verify_gametop_get_mdata(jid)
|
|
|
|
self.verify_gametop_get_meeting(jid)
|
|
|
|
if scores is None:
|
2022-10-15 20:56:30 +02:00
|
|
|
raise Exception("Expected to get scores back, didn't get anything!")
|
2022-10-03 04:10:43 +02:00
|
|
|
if len(scores) > 0:
|
2022-10-15 20:56:30 +02:00
|
|
|
raise Exception("Got nonzero score count on a new card!")
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Verify end of game behavior
|
|
|
|
self.verify_jbox_get_list(jid)
|
|
|
|
self.verify_jbox_get_agreement(jid)
|
|
|
|
self.verify_gameend_final(ref_id, jid)
|
|
|
|
|
|
|
|
for phase in [1, 2]:
|
|
|
|
if phase == 1:
|
|
|
|
dummyscores = [
|
|
|
|
# An okay score on a chart
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 40000059,
|
|
|
|
"chart": 2,
|
|
|
|
"hard": False,
|
|
|
|
"clear": True,
|
|
|
|
"fc": False,
|
|
|
|
"ex": False,
|
|
|
|
"score": 800000,
|
|
|
|
"rate": 567,
|
|
|
|
"expected_medal": 0x3,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
# A good score on an easier chart of the same song
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 40000059,
|
|
|
|
"chart": 1,
|
|
|
|
"hard": False,
|
|
|
|
"clear": True,
|
|
|
|
"fc": True,
|
|
|
|
"ex": False,
|
|
|
|
"score": 990000,
|
|
|
|
"rate": 456,
|
|
|
|
"expected_medal": 0x5,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
# A perfect score on an easiest chart of the same song
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 40000059,
|
|
|
|
"chart": 0,
|
|
|
|
"hard": False,
|
|
|
|
"clear": True,
|
|
|
|
"fc": True,
|
|
|
|
"ex": True,
|
|
|
|
"score": 1000000,
|
|
|
|
"rate": 678,
|
|
|
|
"expected_medal": 0x9,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
# A bad score on a hard chart
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 30000027,
|
|
|
|
"chart": 2,
|
|
|
|
"hard": False,
|
|
|
|
"clear": False,
|
|
|
|
"fc": False,
|
|
|
|
"ex": False,
|
|
|
|
"score": 400000,
|
|
|
|
"rate": 123,
|
|
|
|
"expected_medal": 0x1,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
# A terrible score on an easy chart
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 50000045,
|
|
|
|
"chart": 0,
|
|
|
|
"hard": False,
|
|
|
|
"clear": False,
|
|
|
|
"fc": False,
|
|
|
|
"ex": False,
|
|
|
|
"score": 100000,
|
|
|
|
"rate": 69,
|
|
|
|
"expected_medal": 0x1,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
# A good score on a hard chart to make sure
|
|
|
|
# it doesn't pollute regular charts.
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 40000059,
|
|
|
|
"chart": 2,
|
|
|
|
"hard": True,
|
|
|
|
"clear": True,
|
|
|
|
"fc": False,
|
|
|
|
"ex": False,
|
|
|
|
"score": 812300,
|
|
|
|
"rate": 666,
|
|
|
|
"expected_medal": 0x3,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
]
|
|
|
|
if phase == 2:
|
|
|
|
dummyscores = [
|
|
|
|
# A better score on the same chart
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 50000045,
|
|
|
|
"chart": 0,
|
|
|
|
"hard": False,
|
|
|
|
"clear": True,
|
|
|
|
"fc": False,
|
|
|
|
"ex": False,
|
|
|
|
"score": 850000,
|
|
|
|
"rate": 555,
|
|
|
|
"expected_medal": 0x3,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
# A worse score on another same chart
|
|
|
|
{
|
2022-10-15 20:56:30 +02:00
|
|
|
"id": 40000059,
|
|
|
|
"chart": 1,
|
|
|
|
"hard": False,
|
|
|
|
"clear": True,
|
|
|
|
"fc": False,
|
|
|
|
"ex": False,
|
|
|
|
"score": 925000,
|
|
|
|
"rate": 432,
|
|
|
|
"expected_score": 990000,
|
|
|
|
"expected_rate": 456,
|
|
|
|
"expected_medal": 0x7,
|
2022-10-03 04:10:43 +02:00
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
self.verify_gameend_regist(ref_id, jid, dummyscores)
|
|
|
|
jid = self.verify_gametop_get_pdata(card, ref_id)
|
|
|
|
scores = self.verify_gametop_get_mdata(jid)
|
|
|
|
|
|
|
|
for score in dummyscores:
|
2022-10-15 20:56:30 +02:00
|
|
|
chart = score["chart"] + (3 if score["hard"] else 0)
|
|
|
|
newscore = scores[str(score["id"])][chart]
|
2022-10-03 04:10:43 +02:00
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
if "expected_score" in score:
|
|
|
|
expected_score = score["expected_score"]
|
2022-10-03 04:10:43 +02:00
|
|
|
else:
|
2022-10-15 20:56:30 +02:00
|
|
|
expected_score = score["score"]
|
2022-10-03 04:10:43 +02:00
|
|
|
|
2022-10-15 20:56:30 +02:00
|
|
|
if "expected_rate" in score:
|
|
|
|
expected_rate = score["expected_rate"]
|
2022-10-03 04:10:43 +02:00
|
|
|
else:
|
2022-10-15 20:56:30 +02:00
|
|
|
expected_rate = score["rate"]
|
|
|
|
|
|
|
|
if newscore["score"] != expected_score:
|
|
|
|
raise Exception(
|
|
|
|
f'Expected a score of \'{expected_score}\' for song \'{score["id"]}\' chart \'{chart}\' but got score \'{newscore["score"]}\''
|
|
|
|
)
|
|
|
|
|
|
|
|
if newscore["rate"] != expected_rate:
|
|
|
|
raise Exception(
|
|
|
|
f'Expected a rate of \'{expected_rate}\' for song \'{score["id"]}\' chart \'{chart}\' but got rate \'{newscore["rate"]}\''
|
|
|
|
)
|
|
|
|
|
|
|
|
if newscore["medal"] != score["expected_medal"]:
|
|
|
|
raise Exception(
|
|
|
|
f'Expected a medal of \'{score["expected_medal"]}\' for song \'{score["id"]}\' chart \'{chart}\' but got medal \'{newscore["medal"]}\''
|
|
|
|
)
|
2022-10-03 04:10:43 +02:00
|
|
|
|
|
|
|
# Sleep so we don't end up putting in score history on the same second
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
else:
|
|
|
|
print("Skipping score checks for existing card")
|
|
|
|
|
|
|
|
# Verify paseli handling
|
|
|
|
if paseli_enabled:
|
|
|
|
print("PASELI enabled for this PCBID, executing PASELI checks")
|
|
|
|
else:
|
|
|
|
print("PASELI disabled for this PCBID, skipping PASELI checks")
|
|
|
|
return
|
|
|
|
|
|
|
|
sessid, balance = self.verify_eacoin_checkin(card)
|
|
|
|
if balance == 0:
|
|
|
|
print("Skipping PASELI consume check because card has 0 balance")
|
|
|
|
else:
|
|
|
|
self.verify_eacoin_consume(sessid, balance, random.randint(0, balance))
|
|
|
|
self.verify_eacoin_checkout(sessid)
|