2022-09-19 00:36:42 +02:00
|
|
|
|
import random
|
|
|
|
|
import time
|
|
|
|
|
from typing import Any, Dict, Optional
|
|
|
|
|
|
|
|
|
|
from bemani.client.base import BaseClient
|
|
|
|
|
from bemani.protocol import Node
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PopnMusicKaimeiClient(BaseClient):
|
|
|
|
|
NAME = 'TEST'
|
|
|
|
|
|
|
|
|
|
def verify_pcb24_boot(self, loc: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
pcb24 = Node.void('pcb24')
|
|
|
|
|
call.add_child(pcb24)
|
|
|
|
|
pcb24.set_attribute('method', 'boot')
|
|
|
|
|
pcb24.add_child(Node.string('loc_id', loc))
|
|
|
|
|
pcb24.add_child(Node.u8('loc_type', 0))
|
|
|
|
|
pcb24.add_child(Node.string('loc_name', ''))
|
|
|
|
|
pcb24.add_child(Node.string('country', 'US'))
|
|
|
|
|
pcb24.add_child(Node.string('region', '.'))
|
|
|
|
|
pcb24.add_child(Node.s16('pref', 51))
|
|
|
|
|
pcb24.add_child(Node.string('customer', ''))
|
|
|
|
|
pcb24.add_child(Node.string('company', ''))
|
|
|
|
|
pcb24.add_child(Node.ipv4('gip', '127.0.0.1'))
|
|
|
|
|
pcb24.add_child(Node.u16('gp', 10011))
|
|
|
|
|
pcb24.add_child(Node.string('rom_number', 'M39-JB-G01'))
|
|
|
|
|
pcb24.add_child(Node.u64('c_drive', 10028228608))
|
|
|
|
|
pcb24.add_child(Node.u64('d_drive', 47945170944))
|
|
|
|
|
pcb24.add_child(Node.u64('e_drive', 10394677248))
|
|
|
|
|
pcb24.add_child(Node.string('etc', ''))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
self.assert_path(resp, "response/pcb24/@status")
|
|
|
|
|
|
|
|
|
|
def __verify_common(self, root: str, resp: Node) -> None:
|
|
|
|
|
self.assert_path(resp, f"response/{root}/phase/event_id")
|
|
|
|
|
self.assert_path(resp, f"response/{root}/phase/phase")
|
|
|
|
|
|
|
|
|
|
# Area stuff is not needed unless enabling events.
|
|
|
|
|
# self.assert_path(resp, f"response/{root}/area/area_id")
|
|
|
|
|
# self.assert_path(resp, f"response/{root}/area/end_date")
|
|
|
|
|
# self.assert_path(resp, f"response/{root}/area/medal_id")
|
|
|
|
|
# self.assert_path(resp, f"response/{root}/area/is_limit")
|
|
|
|
|
|
|
|
|
|
self.assert_path(resp, f"response/{root}/choco/choco_id")
|
|
|
|
|
self.assert_path(resp, f"response/{root}/choco/param")
|
|
|
|
|
self.assert_path(resp, f"response/{root}/goods/item_id")
|
|
|
|
|
self.assert_path(resp, f"response/{root}/goods/item_type")
|
|
|
|
|
self.assert_path(resp, f"response/{root}/goods/price")
|
|
|
|
|
self.assert_path(resp, f"response/{root}/goods/goods_type")
|
|
|
|
|
|
|
|
|
|
def verify_info24_common(self, loc: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
info24 = Node.void('info24')
|
|
|
|
|
call.add_child(info24)
|
|
|
|
|
info24.set_attribute('loc_id', loc)
|
|
|
|
|
info24.set_attribute('method', 'common')
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
self.__verify_common('info24', resp)
|
|
|
|
|
|
|
|
|
|
def verify_lobby24_getlist(self, loc: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
lobby24 = Node.void('lobby24')
|
|
|
|
|
call.add_child(lobby24)
|
|
|
|
|
lobby24.set_attribute('method', 'getList')
|
|
|
|
|
lobby24.add_child(Node.string('location_id', loc))
|
|
|
|
|
lobby24.add_child(Node.u8('net_version', 63))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
self.assert_path(resp, "response/lobby24/@status")
|
|
|
|
|
|
|
|
|
|
def __verify_profile(self, resp: Node) -> None:
|
|
|
|
|
self.assert_path(resp, "response/player24/account/name")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/g_pm_id")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/tutorial")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/area_id")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/use_navi")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/read_news")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/nice")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/favorite_chara")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/special_area")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/chocolate_charalist")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/chocolate_sp_chara")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/chocolate_pass_cnt")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/chocolate_hon_cnt")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/teacher_setting")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/welcom_pack")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/ranking_node")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/chara_ranking_kind_id")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/navi_evolution_flg")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/ranking_news_last_no")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/power_point")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/player_point")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/power_point_list")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/staff")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/item_type")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/item_id")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/is_conv")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/license_data")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/my_best")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/latest_music")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/total_play_cnt")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/today_play_cnt")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/consecutive_days")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/total_days")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/interval_day")
|
|
|
|
|
self.assert_path(resp, "response/player24/account/active_fr_num")
|
|
|
|
|
self.assert_path(resp, "response/player24/eaappli/relation")
|
|
|
|
|
self.assert_path(resp, "response/player24/info/ep")
|
|
|
|
|
self.assert_path(resp, "response/player24/config")
|
|
|
|
|
self.assert_path(resp, "response/player24/option")
|
|
|
|
|
self.assert_path(resp, "response/player24/custom_cate")
|
|
|
|
|
self.assert_path(resp, "response/player24/navi_data")
|
|
|
|
|
self.assert_path(resp, "response/player24/mission/mission_id")
|
|
|
|
|
self.assert_path(resp, "response/player24/mission/gauge_point")
|
|
|
|
|
self.assert_path(resp, "response/player24/mission/mission_comp")
|
|
|
|
|
self.assert_path(resp, "response/player24/netvs")
|
|
|
|
|
self.assert_path(resp, "response/player24/customize")
|
|
|
|
|
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]]]:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'read')
|
|
|
|
|
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
player24.add_child(Node.s8('pref', 51))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
if msg_type == 'new':
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
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}\'')
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
'items': {},
|
|
|
|
|
'characters': {},
|
|
|
|
|
'points': {},
|
|
|
|
|
}
|
|
|
|
|
elif msg_type == 'query':
|
|
|
|
|
# Verify that the response is correct
|
|
|
|
|
self.__verify_profile(resp)
|
|
|
|
|
|
|
|
|
|
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}\'')
|
|
|
|
|
name = resp.child_value('player24/account/name')
|
|
|
|
|
if name != self.NAME:
|
|
|
|
|
raise Exception(f'Invalid name \'{name}\' returned for Ref ID \'{ref_id}\'')
|
|
|
|
|
|
|
|
|
|
# Medals and items
|
|
|
|
|
items: Dict[int, Dict[str, int]] = {}
|
|
|
|
|
charas: Dict[int, Dict[str, int]] = {}
|
|
|
|
|
courses: Dict[int, Dict[str, int]] = {}
|
|
|
|
|
for obj in resp.child('player24').children:
|
|
|
|
|
if obj.name == 'item':
|
|
|
|
|
items[obj.child_value('id')] = {
|
|
|
|
|
'type': obj.child_value('type'),
|
|
|
|
|
'param': obj.child_value('param'),
|
|
|
|
|
}
|
|
|
|
|
elif obj.name == 'chara_param':
|
|
|
|
|
charas[obj.child_value('chara_id')] = {
|
|
|
|
|
'friendship': obj.child_value('friendship'),
|
|
|
|
|
}
|
|
|
|
|
elif obj.name == 'course_data':
|
|
|
|
|
courses[obj.child_value('course_id')] = {
|
|
|
|
|
'clear_type': obj.child_value('clear_type'),
|
|
|
|
|
'clear_rank': obj.child_value('clear_rank'),
|
|
|
|
|
'total_score': obj.child_value('total_score'),
|
|
|
|
|
'count': obj.child_value('update_count'),
|
|
|
|
|
'sheet_num': obj.child_value('sheet_num'),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
'items': items,
|
|
|
|
|
'characters': charas,
|
|
|
|
|
'courses': courses,
|
|
|
|
|
'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]]]:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'read_score')
|
|
|
|
|
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
player24.add_child(Node.s8('pref', 51))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify defaults
|
|
|
|
|
self.assert_path(resp, "response/player24/@status")
|
|
|
|
|
|
|
|
|
|
# Grab scores
|
|
|
|
|
scores: Dict[int, Dict[int, int]] = {}
|
|
|
|
|
medals: Dict[int, Dict[int, int]] = {}
|
|
|
|
|
ranks: Dict[int, Dict[int, int]] = {}
|
|
|
|
|
for child in resp.child('player24').children:
|
|
|
|
|
if child.name != 'music':
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
musicid = child.child_value('music_num')
|
|
|
|
|
chart = child.child_value('sheet_num')
|
|
|
|
|
score = child.child_value('score')
|
|
|
|
|
medal = child.child_value('clear_type')
|
|
|
|
|
rank = child.child_value('clear_rank')
|
|
|
|
|
|
|
|
|
|
if musicid not in scores:
|
|
|
|
|
scores[musicid] = {}
|
|
|
|
|
if musicid not in medals:
|
|
|
|
|
medals[musicid] = {}
|
|
|
|
|
if musicid not in ranks:
|
|
|
|
|
ranks[musicid] = {}
|
|
|
|
|
|
|
|
|
|
scores[musicid][chart] = score
|
|
|
|
|
medals[musicid][chart] = medal
|
|
|
|
|
ranks[musicid][chart] = rank
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
'scores': scores,
|
|
|
|
|
'medals': medals,
|
|
|
|
|
'ranks': ranks,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def verify_player24_start(self, ref_id: str, loc: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('loc_id', loc)
|
|
|
|
|
player24.set_attribute('ref_id', ref_id)
|
|
|
|
|
player24.set_attribute('method', 'start')
|
|
|
|
|
player24.set_attribute('start_type', '0')
|
|
|
|
|
pcb_card = Node.void('pcb_card')
|
|
|
|
|
player24.add_child(pcb_card)
|
|
|
|
|
pcb_card.add_child(Node.s8('card_enable', 1))
|
|
|
|
|
pcb_card.add_child(Node.s8('card_soldout', 0))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
self.__verify_common('player24', resp)
|
|
|
|
|
|
|
|
|
|
def verify_player24_update_ranking(self, ref_id: str, loc: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'update_ranking')
|
|
|
|
|
player24.add_child(Node.s16('pref', 51))
|
|
|
|
|
player24.add_child(Node.string('location_id', loc))
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
player24.add_child(Node.string('name', self.NAME))
|
|
|
|
|
player24.add_child(Node.s16('chara_num', 1))
|
|
|
|
|
player24.add_child(Node.s16('course_id', 12345))
|
|
|
|
|
player24.add_child(Node.s32('total_score', 86000))
|
|
|
|
|
player24.add_child(Node.s16('music_num', 1375))
|
|
|
|
|
player24.add_child(Node.u8('sheet_num', 2))
|
|
|
|
|
player24.add_child(Node.u8('clear_type', 7))
|
|
|
|
|
player24.add_child(Node.u8('clear_rank', 5))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/name")
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/chara_num")
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/total_score")
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/clear_type")
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/clear_rank")
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/player_count")
|
|
|
|
|
self.assert_path(resp, "response/player24/all_ranking/player_rank")
|
|
|
|
|
|
|
|
|
|
def verify_player24_logout(self, ref_id: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('ref_id', ref_id)
|
|
|
|
|
player24.set_attribute('method', 'logout')
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify that response is correct
|
|
|
|
|
self.assert_path(resp, "response/player24/@status")
|
|
|
|
|
|
|
|
|
|
def verify_player24_write(
|
|
|
|
|
self,
|
|
|
|
|
ref_id: str,
|
|
|
|
|
item: Optional[Dict[str, int]]=None,
|
|
|
|
|
character: Optional[Dict[str, int]]=None,
|
|
|
|
|
) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'write')
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
|
|
|
|
|
# Add required children
|
|
|
|
|
config = Node.void('config')
|
|
|
|
|
player24.add_child(config)
|
|
|
|
|
config.add_child(Node.s16('chara', 1543))
|
|
|
|
|
|
|
|
|
|
if item is not None:
|
|
|
|
|
itemnode = Node.void('item')
|
|
|
|
|
player24.add_child(itemnode)
|
|
|
|
|
itemnode.add_child(Node.u8('type', item['type']))
|
|
|
|
|
itemnode.add_child(Node.u16('id', item['id']))
|
|
|
|
|
itemnode.add_child(Node.u16('param', item['param']))
|
|
|
|
|
itemnode.add_child(Node.bool('is_new', False))
|
|
|
|
|
itemnode.add_child(Node.u64('get_time', 0))
|
|
|
|
|
|
|
|
|
|
if character is not None:
|
|
|
|
|
chara_param = Node.void('chara_param')
|
|
|
|
|
player24.add_child(chara_param)
|
|
|
|
|
chara_param.add_child(Node.u16('chara_id', character['id']))
|
|
|
|
|
chara_param.add_child(Node.u16('friendship', character['friendship']))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
self.assert_path(resp, "response/player24/@status")
|
|
|
|
|
|
|
|
|
|
def verify_player24_buy(self, ref_id: str, item: Dict[str, int]) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'buy')
|
|
|
|
|
player24.add_child(Node.s32('play_id', 0))
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
player24.add_child(Node.u16('id', item['id']))
|
|
|
|
|
player24.add_child(Node.u8('type', item['type']))
|
|
|
|
|
player24.add_child(Node.u16('param', item['param']))
|
|
|
|
|
player24.add_child(Node.s32('lumina', item['points']))
|
|
|
|
|
player24.add_child(Node.u16('price', item['price']))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
self.assert_path(resp, "response/player24/@status")
|
|
|
|
|
|
|
|
|
|
def verify_player24_write_music(self, ref_id: str, score: Dict[str, Any]) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'write_music')
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
player24.add_child(Node.string('data_id', ref_id))
|
|
|
|
|
player24.add_child(Node.string('name', self.NAME))
|
|
|
|
|
player24.add_child(Node.u8('stage', 0))
|
|
|
|
|
player24.add_child(Node.s16('music_num', score['id']))
|
|
|
|
|
player24.add_child(Node.u8('sheet_num', score['chart']))
|
|
|
|
|
player24.add_child(Node.u8('clear_type', score['medal']))
|
|
|
|
|
player24.add_child(Node.s32('score', score['score']))
|
|
|
|
|
player24.add_child(Node.s16('combo', 0))
|
|
|
|
|
player24.add_child(Node.s16('cool', 0))
|
|
|
|
|
player24.add_child(Node.s16('great', 0))
|
|
|
|
|
player24.add_child(Node.s16('good', 0))
|
|
|
|
|
player24.add_child(Node.s16('bad', 0))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
self.assert_path(resp, "response/player24/@status")
|
|
|
|
|
|
|
|
|
|
def verify_player24_new(self, ref_id: str) -> None:
|
|
|
|
|
call = self.call_node()
|
|
|
|
|
|
|
|
|
|
# Construct node
|
|
|
|
|
player24 = Node.void('player24')
|
|
|
|
|
call.add_child(player24)
|
|
|
|
|
player24.set_attribute('method', 'new')
|
|
|
|
|
|
|
|
|
|
player24.add_child(Node.string('ref_id', ref_id))
|
|
|
|
|
player24.add_child(Node.string('name', self.NAME))
|
|
|
|
|
player24.add_child(Node.s8('pref', 51))
|
|
|
|
|
|
|
|
|
|
# Swap with server
|
|
|
|
|
resp = self.exchange('', call)
|
|
|
|
|
|
|
|
|
|
# Verify nodes
|
|
|
|
|
self.__verify_profile(resp)
|
|
|
|
|
|
|
|
|
|
def verify(self, cardid: Optional[str]) -> None:
|
|
|
|
|
# Verify boot sequence is okay
|
|
|
|
|
self.verify_services_get(
|
|
|
|
|
expected_services=[
|
|
|
|
|
'pcbtracker',
|
|
|
|
|
'pcbevent',
|
|
|
|
|
'local',
|
|
|
|
|
'message',
|
|
|
|
|
'facility',
|
|
|
|
|
'cardmng',
|
|
|
|
|
'package',
|
|
|
|
|
'posevent',
|
|
|
|
|
'pkglist',
|
|
|
|
|
'dlstatus',
|
|
|
|
|
'eacoin',
|
|
|
|
|
'lobby',
|
|
|
|
|
'ntp',
|
|
|
|
|
'keepalive'
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
paseli_enabled = self.verify_pcbtracker_alive()
|
|
|
|
|
self.verify_message_get()
|
|
|
|
|
self.verify_package_list()
|
|
|
|
|
location = self.verify_facility_get()
|
|
|
|
|
self.verify_pcbevent_put()
|
|
|
|
|
self.verify_pcb24_boot(location)
|
|
|
|
|
self.verify_info24_common(location)
|
|
|
|
|
self.verify_lobby24_getlist(location)
|
|
|
|
|
|
|
|
|
|
# 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:
|
|
|
|
|
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 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)
|
|
|
|
|
|
|
|
|
|
# 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):
|
|
|
|
|
raise Exception(f'Invalid refid \'{ref_id}\' returned when querying card')
|
|
|
|
|
|
|
|
|
|
# Verify proper handling of basic stuff
|
|
|
|
|
self.verify_player24_read(ref_id, msg_type='query')
|
|
|
|
|
self.verify_player24_start(ref_id, location)
|
|
|
|
|
self.verify_player24_write(ref_id)
|
|
|
|
|
self.verify_player24_logout(ref_id)
|
|
|
|
|
|
|
|
|
|
if cardid is None:
|
|
|
|
|
# Verify unlocks/story mode work
|
|
|
|
|
unlocks = self.verify_player24_read(ref_id, msg_type='query')
|
|
|
|
|
for item in unlocks['items']:
|
|
|
|
|
if item in [1592, 1608]:
|
|
|
|
|
# Song unlocks after one play
|
|
|
|
|
continue
|
|
|
|
|
raise Exception('Got nonzero items count on a new card!')
|
|
|
|
|
for _ in unlocks['characters']:
|
|
|
|
|
raise Exception('Got nonzero characters count on a new card!')
|
|
|
|
|
for _ in unlocks['courses']:
|
|
|
|
|
raise Exception('Got nonzero course count on a new card!')
|
|
|
|
|
if unlocks['points'][0]['points'] != 300:
|
|
|
|
|
raise Exception('Got wrong default value for points on a new card!')
|
|
|
|
|
|
|
|
|
|
self.verify_player24_write(ref_id, item={'id': 4, 'type': 2, 'param': 69})
|
|
|
|
|
unlocks = self.verify_player24_read(ref_id, msg_type='query')
|
|
|
|
|
if 4 not in unlocks['items']:
|
|
|
|
|
raise Exception('Expecting to see item ID 4 in items!')
|
|
|
|
|
if unlocks['items'][4]['type'] != 2:
|
|
|
|
|
raise Exception('Expecting to see item ID 4 to have type 2 in items!')
|
|
|
|
|
if unlocks['items'][4]['param'] != 69:
|
|
|
|
|
raise Exception('Expecting to see item ID 4 to have param 69 in items!')
|
|
|
|
|
|
|
|
|
|
self.verify_player24_write(ref_id, character={'id': 5, 'friendship': 420})
|
|
|
|
|
unlocks = self.verify_player24_read(ref_id, msg_type='query')
|
|
|
|
|
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!')
|
|
|
|
|
|
|
|
|
|
# Verify purchases work
|
|
|
|
|
self.verify_player24_buy(ref_id, item={'id': 6, 'type': 3, 'param': 8, 'points': 400, 'price': 250})
|
|
|
|
|
unlocks = self.verify_player24_read(ref_id, msg_type='query')
|
|
|
|
|
if 6 not in unlocks['items']:
|
|
|
|
|
raise Exception('Expecting to see item ID 6 in items!')
|
|
|
|
|
if unlocks['items'][6]['type'] != 3:
|
|
|
|
|
raise Exception('Expecting to see item ID 6 to have type 3 in items!')
|
|
|
|
|
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!')
|
|
|
|
|
|
|
|
|
|
# Verify course handling
|
|
|
|
|
self.verify_player24_update_ranking(ref_id, location)
|
|
|
|
|
unlocks = self.verify_player24_read(ref_id, msg_type='query')
|
|
|
|
|
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!')
|
|
|
|
|
if unlocks['courses'][12345]['clear_rank'] != 5:
|
|
|
|
|
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!')
|
|
|
|
|
if unlocks['courses'][12345]['count'] != 1:
|
|
|
|
|
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!')
|
|
|
|
|
|
|
|
|
|
# Verify score handling
|
|
|
|
|
scores = self.verify_player24_read_score(ref_id)
|
|
|
|
|
for _ in scores['medals']:
|
|
|
|
|
raise Exception('Got nonzero medals count on a new card!')
|
|
|
|
|
for _ in scores['scores']:
|
|
|
|
|
raise Exception('Got nonzero scores count on a new card!')
|
|
|
|
|
|
|
|
|
|
for phase in [1, 2]:
|
|
|
|
|
if phase == 1:
|
|
|
|
|
dummyscores = [
|
|
|
|
|
# An okay score on a chart
|
|
|
|
|
{
|
|
|
|
|
'id': 987,
|
|
|
|
|
'chart': 2,
|
|
|
|
|
'medal': 5,
|
|
|
|
|
'score': 76543,
|
|
|
|
|
},
|
|
|
|
|
# A good score on an easier chart of the same song
|
|
|
|
|
{
|
|
|
|
|
'id': 987,
|
|
|
|
|
'chart': 0,
|
|
|
|
|
'medal': 6,
|
|
|
|
|
'score': 99999,
|
|
|
|
|
},
|
|
|
|
|
# A bad score on a hard chart
|
|
|
|
|
{
|
|
|
|
|
'id': 741,
|
|
|
|
|
'chart': 3,
|
|
|
|
|
'medal': 2,
|
|
|
|
|
'score': 45000,
|
|
|
|
|
},
|
|
|
|
|
# A terrible score on an easy chart
|
|
|
|
|
{
|
|
|
|
|
'id': 742,
|
|
|
|
|
'chart': 1,
|
|
|
|
|
'medal': 2,
|
|
|
|
|
'score': 1,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
# Random score to add in
|
2022-10-03 04:10:43 +02:00
|
|
|
|
songid = random.randint(920, 950)
|
2022-09-19 00:36:42 +02:00
|
|
|
|
chartid = random.randint(0, 3)
|
|
|
|
|
score = random.randint(0, 100000)
|
|
|
|
|
medal = random.randint(1, 11)
|
|
|
|
|
dummyscores.append({
|
|
|
|
|
'id': songid,
|
|
|
|
|
'chart': chartid,
|
|
|
|
|
'medal': medal,
|
|
|
|
|
'score': score,
|
|
|
|
|
})
|
|
|
|
|
if phase == 2:
|
|
|
|
|
dummyscores = [
|
|
|
|
|
# A better score on the same chart
|
|
|
|
|
{
|
|
|
|
|
'id': 987,
|
|
|
|
|
'chart': 2,
|
|
|
|
|
'medal': 6,
|
|
|
|
|
'score': 98765,
|
|
|
|
|
},
|
|
|
|
|
# A worse score on another same chart
|
|
|
|
|
{
|
|
|
|
|
'id': 987,
|
|
|
|
|
'chart': 0,
|
|
|
|
|
'medal': 3,
|
|
|
|
|
'score': 12345,
|
|
|
|
|
'expected_score': 99999,
|
|
|
|
|
'expected_medal': 6,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
for dummyscore in dummyscores:
|
|
|
|
|
self.verify_player24_write_music(ref_id, dummyscore)
|
|
|
|
|
scores = self.verify_player24_read_score(ref_id)
|
|
|
|
|
for expected in dummyscores:
|
|
|
|
|
newscore = scores['scores'][expected['id']][expected['chart']]
|
|
|
|
|
newmedal = scores['medals'][expected['id']][expected['chart']]
|
|
|
|
|
newrank = scores['ranks'][expected['id']][expected['chart']]
|
|
|
|
|
|
|
|
|
|
if 'expected_score' in expected:
|
|
|
|
|
expected_score = expected['expected_score']
|
|
|
|
|
else:
|
|
|
|
|
expected_score = expected['score']
|
|
|
|
|
if 'expected_medal' in expected:
|
|
|
|
|
expected_medal = expected['expected_medal']
|
|
|
|
|
else:
|
|
|
|
|
expected_medal = expected['medal']
|
|
|
|
|
|
|
|
|
|
if newscore < 50000:
|
|
|
|
|
expected_rank = 1
|
|
|
|
|
elif newscore < 62000:
|
|
|
|
|
expected_rank = 2
|
|
|
|
|
elif newscore < 72000:
|
|
|
|
|
expected_rank = 3
|
|
|
|
|
elif newscore < 82000:
|
|
|
|
|
expected_rank = 4
|
|
|
|
|
elif newscore < 90000:
|
|
|
|
|
expected_rank = 5
|
|
|
|
|
elif newscore < 95000:
|
|
|
|
|
expected_rank = 6
|
|
|
|
|
elif newscore < 98000:
|
|
|
|
|
expected_rank = 7
|
|
|
|
|
else:
|
|
|
|
|
expected_rank = 8
|
|
|
|
|
|
|
|
|
|
if newscore != expected_score:
|
|
|
|
|
raise Exception(f'Expected a score of \'{expected_score}\' for song \'{expected["id"]}\' chart \'{expected["chart"]}\' but got score \'{newscore}\'')
|
|
|
|
|
if newmedal != expected_medal:
|
|
|
|
|
raise Exception(f'Expected a medal of \'{expected_medal}\' for song \'{expected["id"]}\' chart \'{expected["chart"]}\' but got medal \'{newmedal}\'')
|
|
|
|
|
if newrank != expected_rank:
|
|
|
|
|
raise Exception(f'Expected a rank of \'{expected_rank}\' for song \'{expected["id"]}\' chart \'{expected["chart"]}\' but got rank \'{newrank}\'')
|
|
|
|
|
|
|
|
|
|
# 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)
|