def verify_iidx25gamesystem_systeminfo(self, lid: str) -> None: call = self.call_node() IIDX25gameSystem = Node.void('IIDX25gameSystem') call.add_child(IIDX25gameSystem) IIDX25gameSystem.set_attribute('method', 'systemInfo') IIDX25gameSystem.add_child(Node.s32('ver', 7)) IIDX25gameSystem.add_child(Node.string('location_id', lid)) # Swap with server resp = self.exchange('', call) self.assert_path(resp, 'response/IIDX25gameSystem/arena_schedule/phase')
def verify_playerdata_usergamedata_advanced_ghostload( self, refid: str, ghostid: int) -> Dict[str, Any]: call = self.call_node() # Construct node playerdata = Node.void('playerdata') call.add_child(playerdata) playerdata.set_attribute('method', 'usergamedata_advanced') playerdata.add_child(Node.u32('retrycnt', 0)) info = Node.void('info') playerdata.add_child(info) info.add_child(Node.s32('version', 1)) data = Node.void('data') playerdata.add_child(data) data.add_child(Node.string('mode', 'ghostload')) data.add_child(Node.s32('ghostid', ghostid)) data.add_child(Node.s64('gamesession', 123456)) data.add_child(Node.string('refid', refid)) data.add_child(Node.string('dataid', refid)) data.add_child(Node.string('gamekind', 'MDX')) data.add_child(Node.string('pcbid', self.pcbid)) data.add_child(Node.void('record')) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/playerdata/ghostdata/code") self.assert_path(resp, "response/playerdata/ghostdata/mcode") self.assert_path(resp, "response/playerdata/ghostdata/notetype") self.assert_path(resp, "response/playerdata/ghostdata/ghostsize") self.assert_path(resp, "response/playerdata/ghostdata/ghost") return { 'extid': resp.child_value('playerdata/ghostdata/code'), 'id': resp.child_value('playerdata/ghostdata/mcode'), 'chart': resp.child_value('playerdata/ghostdata/notetype'), 'ghost': resp.child_value('playerdata/ghostdata/ghost'), }
def verify_lobby_rb4delete(self, eid: int) -> None: call = self.call_node() lobby = Node.void('lobby') lobby.set_attribute('method', 'rb4delete') lobby.add_child(Node.s32('eid', eid)) call.add_child(lobby) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/lobby")
def verify_log_play(self, extid: int, loc: str, scores: List[Dict[str, int]]) -> None: call = self.call_node() log = Node.void('log') call.add_child(log) log.set_attribute('method', 'play') log.add_child(Node.s32('uid', extid)) log.add_child(Node.string('lid', loc)) play = Node.void('play') log.add_child(play) play.add_child(Node.s16('stage', len(scores))) play.add_child(Node.s32('sec', 700)) scoreid = 0 for score in scores: rec = Node.void('rec') log.add_child(rec) rec.add_child(Node.s16('idx', scoreid)) rec.add_child(Node.s16('mid', score['id'])) rec.add_child(Node.s16('grade', score['chart'])) rec.add_child(Node.s16('color', 0)) rec.add_child(Node.s16('match', 0)) rec.add_child(Node.s16('res', 0)) rec.add_child(Node.s16('score', score['score'])) rec.add_child(Node.s16('mc', score['combo'])) rec.add_child(Node.s16('jt_jr', 0)) rec.add_child(Node.s16('jt_ju', 0)) rec.add_child(Node.s16('jt_gr', 0)) rec.add_child(Node.s16('jt_gd', 0)) rec.add_child(Node.s16('jt_ms', score['miss_count'])) rec.add_child(Node.s32('sec', 200)) scoreid = scoreid + 1 # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/log/@status")
def verify_gametop_get_league(self, jid: int) -> Tuple[int, Tuple[int, int, int]]: call = self.call_node() # Construct node gametop = Node.void('gametop') call.add_child(gametop) gametop.set_attribute('method', 'get_league') gametop.add_child(Node.s32('retry', 0)) 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.s32_array('rival_jid', [0] * 3)) # Swap with server resp = self.exchange('', call) # Verify expected nodes self.assert_path(resp, "response/gametop/data/league_list/league/player_list") self.assert_path(resp, "response/gametop/data/last_class") self.assert_path(resp, "response/gametop/data/last_subclass") self.assert_path(resp, "response/gametop/data/is_checked") 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: if player.child_value('jid') == jid: playernode = player break if playernode is None: raise Exception(f"Didn't find any scores for ExtID {jid}") result = playernode.child_value('result/score') if result is not None: return (leagueid, (result[0], result[1], result[2])) else: return (leagueid, (0, 0, 0))
def test_game_packet2(self) -> Node: root = Node.void('call') root.set_attribute('model', 'LDJ:A:A:A:2015060700') root.set_attribute('srcid', '012010000000DEADBEEF') root.set_attribute('tag', '9yU+HH4q') eacoin = Node.void('eacoin') root.add_child(eacoin) eacoin.set_attribute('esdate', '2015-08-01T02:09:23') eacoin.set_attribute( 'esid', '177baae4bdf0085f1f3da9b6fed02223ee9b482f62b83a28af704a9c7893a370') eacoin.set_attribute('method', 'consume') eacoin.add_child(Node.string('sessid', '5666-5524')) eacoin.add_child(Node.s16('sequence', 0)) eacoin.add_child(Node.s32('payment', 420)) eacoin.add_child(Node.s32('service', 0)) eacoin.add_child(Node.string('itemtype', '0')) eacoin.add_child(Node.string('detail', '/eacoin/premium_free_1p_3')) self.assertLoopback(root)
def verify_gametop_get_meeting(self, jid: int) -> None: call = self.call_node() # Construct node gametop = Node.void('gametop') call.add_child(gametop) gametop.set_attribute('method', 'get_meeting') gametop.add_child(Node.s32('retry', 0)) data = Node.void('data') gametop.add_child(data) player = Node.void('player') data.add_child(player) player.add_child(Node.s32('jid', jid)) # Swap with server resp = self.exchange('', call) # Verify expected nodes self.assert_path(resp, "response/gametop/data/meeting/single") self.assert_path(resp, "response/gametop/data/meeting/tag") self.assert_path(resp, "response/gametop/data/reward/total") self.assert_path(resp, "response/gametop/data/reward/point")
def verify_pzlcmt_write(self, extid: int) -> None: call = self.call_node() info = Node.void('info') info.set_attribute('method', 'pzlcmt_write') info.add_child(Node.s32('uid', extid)) info.add_child(Node.string('name', self.NAME)) info.add_child(Node.s16('icon', 0)) info.add_child(Node.s8('bln', 0)) info.add_child(Node.s32('tid', 0)) info.add_child(Node.string('t_name', '')) info.add_child(Node.s8('pref', 51)) info.add_child(Node.s32('time', int(time.time()))) info.add_child(Node.string('comment', 'アメ〜〜!')) info.add_child(Node.bool('is_tweet', True)) call.add_child(info) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/info")
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!') machine = self.data.local.machine.get_machine(self.config['machine']['pcbid']) self.put_profile(userid, ValidatedDict({ 'lid': machine.id, })) profile = self.get_profile(userid) response.add_child(Node.string('seq', ID.format_extid(profile.get_int('extid')))) response.add_child(Node.s32('code', profile.get_int('extid'))) response.add_child(Node.string('shoparea', ''))
def verify_player_rb5_player_read_rival_score(self, extid: int) -> None: call = self.call_node() player = Node.void('player') player.set_attribute('method', 'rb5_player_read_rival_score') player.add_child(Node.s32('uid', extid)) player.add_child(Node.s32('music_id', 6)) player.add_child(Node.s32('note_grade', 0)) call.add_child(player) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/player/@status") # Verify that we got a score if the extid is nonzero if extid != 0: self.assert_path(resp, "response/player/player_select_score/user_id") self.assert_path(resp, "response/player/player_select_score/name") self.assert_path(resp, "response/player/player_select_score/m_score") self.assert_path( resp, "response/player/player_select_score/m_scoreTime") self.assert_path(resp, "response/player/player_select_score/m_iconID") if resp.child_value( 'player/player_select_score/name') != self.NAME: raise Exception( 'Invalid name {} returned on score read!'.format( resp.child_value('player/player_select_score/name'))) if resp.child_value('player/player_select_score/user_id') != extid: raise Exception( 'Invalid name {} returned on score read!'.format( resp.child_value( 'player/player_select_score/user_id')))
def verify_lobby_entry(self, location: str, extid: int) -> int: call = self.call_node() lobby = Node.void('lobby') lobby.set_attribute('method', 'entry') e = Node.void('e') lobby.add_child(e) e.add_child(Node.s32('eid', 0)) e.add_child(Node.u16('mid', 79)) e.add_child(Node.u8('ng', 0)) e.add_child(Node.s32('uid', extid)) e.add_child(Node.s32('uattr', 0)) e.add_child(Node.string('pn', self.NAME)) e.add_child(Node.s16('mg', 0)) e.add_child(Node.s32('mopt', 0)) e.add_child(Node.s32('tid', 0)) e.add_child(Node.string('tn', '')) e.add_child(Node.s32('topt', 0)) e.add_child(Node.string('lid', location)) e.add_child(Node.string('sn', '')) e.add_child(Node.u8('pref', 51)) e.add_child(Node.s8('stg', 0)) e.add_child(Node.s8('pside', 0)) e.add_child(Node.s16('eatime', 30)) e.add_child(Node.u8_array('ga', [127, 0, 0, 1])) e.add_child(Node.u16('gp', 10007)) e.add_child(Node.u8_array('la', [16, 0, 0, 0])) lobby.add_child(Node.s32_array('friend', [])) call.add_child(lobby) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/lobby/eid") self.assert_path(resp, "response/lobby/interval") self.assert_path(resp, "response/lobby/interval_p") self.assert_path(resp, "response/lobby/e/eid") self.assert_path(resp, "response/lobby/e/mid") self.assert_path(resp, "response/lobby/e/ng") self.assert_path(resp, "response/lobby/e/uid") self.assert_path(resp, "response/lobby/e/pn") self.assert_path(resp, "response/lobby/e/uattr") self.assert_path(resp, "response/lobby/e/mopt") self.assert_path(resp, "response/lobby/e/mg") self.assert_path(resp, "response/lobby/e/tid") self.assert_path(resp, "response/lobby/e/tn") self.assert_path(resp, "response/lobby/e/topt") self.assert_path(resp, "response/lobby/e/lid") self.assert_path(resp, "response/lobby/e/sn") self.assert_path(resp, "response/lobby/e/pref") self.assert_path(resp, "response/lobby/e/stg") self.assert_path(resp, "response/lobby/e/pside") self.assert_path(resp, "response/lobby/e/eatime") self.assert_path(resp, "response/lobby/e/ga") self.assert_path(resp, "response/lobby/e/gp") self.assert_path(resp, "response/lobby/e/la") return resp.child_value('lobby/eid')
def handle_player_rb5_player_read_score_5_request(self, request: Node) -> Node: refid = request.child_value('rid') userid = self.data.remote.user.from_refid(self.game, self.version, refid) if userid is None: scores: List[Score] = [] else: scores = self.data.remote.music.get_scores(self.game, self.version, userid) root = Node.void('player') pdata = Node.void('pdata') root.add_child(pdata) record = Node.void('record') pdata.add_child(record) for score in scores: rec = Node.void('rec') record.add_child(rec) 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.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'), )) rec.add_child(Node.s32('bscrt', score.timestamp)) rec.add_child( Node.s32('bart', score.data.get_int('best_achievement_rate_time'))) rec.add_child( Node.s32('bctt', score.data.get_int('best_clear_type_time'))) rec.add_child( Node.s32('bmst', score.data.get_int('best_miss_count_time'))) rec.add_child( Node.s32('time', score.data.get_int('last_played_time'))) rec.add_child(Node.s32('k_flag', score.data.get_int('kflag'))) return root
def verify_dlstatus_progress(self) -> None: call = self.call_node() # Construct node dlstatus = Node.void('dlstatus') call.add_child(dlstatus) dlstatus.set_attribute('method', 'progress') dlstatus.add_child(Node.s32('progress', 0)) # Swap with server resp = self.exchange('core/dlstatus', call) # Verify that response is correct self.assert_path(resp, "response/dlstatus/@status")
def handle_player_rb5_player_read_rival_score_request(self, request: Node) -> Node: extid = request.child_value('uid') songid = request.child_value('music_id') chart = request.child_value('note_grade') userid = self.data.remote.user.from_extid(self.game, self.version, extid) if userid is None: score = None profile = None else: score = self.data.remote.music.get_score(self.game, self.version, userid, songid, chart) profile = self.get_any_profile(userid) root = Node.void('player') if score is not None and profile is not None: player_select_score = Node.void('player_select_score') root.add_child(player_select_score) player_select_score.add_child(Node.s32('user_id', extid)) 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'))) return root
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) root = Node.void('player') rival_data = Node.void('rival_data') root.add_child(rival_data) if userid is not None: links = self.data.local.user.get_links(self.game, self.version, userid) for link in links: if link.type != 'rival': continue rprofile = self.get_profile(link.other_userid) if rprofile is None: continue rl = Node.void('rl') rival_data.add_child(rl) rl.add_child(Node.s32('uid', rprofile.get_int('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'))) 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: scores_by_musicid[score.id] = [None, None, None, None] 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 ] sl = Node.void('sl') rl.add_child(sl) sl.add_child(Node.s16('mid', mid)) # Score, but shifted left 32 bits for no reason sl.add_child(Node.u64_array('m', points)) # Timestamp of the clear sl.add_child(Node.u64_array('t', timestamps)) return root
def verify_player_start(self, refid: str) -> None: call = self.call_node() player = Node.void('player') player.set_attribute('method', 'start') player.add_child(Node.string('rid', refid)) player.add_child(Node.s32('ver', 3)) call.add_child(player) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/player/is_suc")
def verify_log_pcb_status(self, loc: str) -> None: call = self.call_node() pcb = Node.void('log') pcb.set_attribute('method', 'pcb_status') pcb.add_child(Node.string('lid', loc)) pcb.add_child(Node.s32('cnt', 0)) call.add_child(pcb) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/log/@status")
def handle_player23_read_score_request(self, request: Node) -> Node: refid = request.child_value('ref_id') root = Node.void('player23') 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.version, userid) else: scores = [] for score in scores: # Skip any scores for chart types we don't support if score.chart not in [ self.CHART_TYPE_EASY, self.CHART_TYPE_NORMAL, self.CHART_TYPE_HYPER, self.CHART_TYPE_EX, ]: continue points = score.points medal = score.data.get_int('medal') music = Node.void('music') root.add_child(music) music.add_child(Node.s16('music_num', score.id)) music.add_child(Node.u8('sheet_num', { self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY, self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL, self.CHART_TYPE_HYPER: self.GAME_CHART_TYPE_HYPER, self.CHART_TYPE_EX: self.GAME_CHART_TYPE_EX, }[score.chart])) music.add_child(Node.s32('score', points)) music.add_child(Node.u8('clear_type', { self.PLAY_MEDAL_CIRCLE_FAILED: self.GAME_PLAY_MEDAL_CIRCLE_FAILED, self.PLAY_MEDAL_DIAMOND_FAILED: self.GAME_PLAY_MEDAL_DIAMOND_FAILED, self.PLAY_MEDAL_STAR_FAILED: self.GAME_PLAY_MEDAL_STAR_FAILED, self.PLAY_MEDAL_EASY_CLEAR: self.GAME_PLAY_MEDAL_EASY_CLEAR, self.PLAY_MEDAL_CIRCLE_CLEARED: self.GAME_PLAY_MEDAL_CIRCLE_CLEARED, self.PLAY_MEDAL_DIAMOND_CLEARED: self.GAME_PLAY_MEDAL_DIAMOND_CLEARED, self.PLAY_MEDAL_STAR_CLEARED: self.GAME_PLAY_MEDAL_STAR_CLEARED, self.PLAY_MEDAL_CIRCLE_FULL_COMBO: self.GAME_PLAY_MEDAL_CIRCLE_FULL_COMBO, self.PLAY_MEDAL_DIAMOND_FULL_COMBO: self.GAME_PLAY_MEDAL_DIAMOND_FULL_COMBO, self.PLAY_MEDAL_STAR_FULL_COMBO: self.GAME_PLAY_MEDAL_STAR_FULL_COMBO, self.PLAY_MEDAL_PERFECT: self.GAME_PLAY_MEDAL_PERFECT, }[medal])) music.add_child(Node.s16('cnt', score.plays)) return root
def verify_player_rb4readepisode(self, extid: int) -> List[Dict[str, int]]: call = self.call_node() player = Node.void('player') call.add_child(player) player.set_attribute('method', 'rb4readepisode') player.add_child(Node.s32('user_id', extid)) player.add_child(Node.s32('limit', 20)) # Swap with server resp = self.exchange('', call) episodes = [] for child in resp.child('player/pdata/episode').children: if child.name != 'info': continue if child.child_value('user_id') != extid: raise Exception('Invalid user ID returned {}'.format( child.child_value('user_id'))) episode = { 'id': child.child_value('type'), 'user': child.child_value('user_id'), 'values': [ child.child_value('value0'), child.child_value('value1'), ], 'text': child.child_value('text'), 'time': child.child_value('time'), } episodes.append(episode) return episodes
def verify_event_w_add_comment(self, loc: str, extid: int) -> None: call = self.call_node() event_w = Node.void('event_w') call.add_child(event_w) event_w.set_attribute('method', 'add_comment') event_w.add_child(Node.s32('uid', extid)) event_w.add_child(Node.string('p_name', self.NAME)) event_w.add_child(Node.s32('exp', 0)) event_w.add_child(Node.s32('customize', 0)) event_w.add_child(Node.s32('tid', 0)) event_w.add_child(Node.string('t_name', '')) event_w.add_child(Node.string('lid', loc)) event_w.add_child(Node.string('s_name', '')) event_w.add_child(Node.s8('pref', 51)) event_w.add_child(Node.s32('time', Time.now())) event_w.add_child(Node.string('comment', 'アメ〜〜!')) event_w.add_child(Node.bool('is_tweet', False)) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/event_w/@status")
def handle_playerdata_usergamedata_send_request(self, request: Node) -> Node: # Look up user by refid refid = request.child_value('data/eaid') 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. return root # Extract new profile info from old profile oldprofile = self.get_profile(userid) is_new = False if oldprofile is None: oldprofile = ValidatedDict() is_new = True newprofile = self.unformat_profile(userid, request, oldprofile, is_new) # Write new profile self.put_profile(userid, newprofile) # Return success! root = Node.void('playerdata') root.add_child(Node.s32('result', 0)) return root
def verify_game_active(self) -> None: call = self.call_node() # Construct node game = Node.void('game') call.add_child(game) game.set_attribute('method', 'active') # Add what Pop'n 20 would add after full unlock game.set_attribute('method', 'active') game.add_child(Node.s8('event', 0)) game.add_child(Node.s8('card_use', 0)) game.add_child(Node.string('name', '')) game.add_child(Node.string('location_id', 'JP-1')) game.add_child(Node.string('shop_name_facility', '.')) game.add_child(Node.s8('pref', 50)) game.add_child(Node.string('shop_addr', '127.0.0.1 10000')) game.add_child(Node.string('shop_name', '')) game.add_child(Node.string('eacoin_price', '200,260,200,200')) game.add_child(Node.s8('eacoin_available', 1)) game.add_child(Node.s8('dipswitch', 0)) game.add_child(Node.u8('max_stage', 1)) game.add_child(Node.u8('difficult', 4)) game.add_child(Node.s8('free_play', 1)) game.add_child(Node.s8('event_mode', 0)) game.add_child(Node.s8('popn_card', 0)) game.add_child(Node.s16('close_time', -1)) game.add_child(Node.s32('game_phase', 2)) game.add_child(Node.s32('net_phase', 0)) game.add_child(Node.s32('event_phase', 0)) game.add_child(Node.s32('card_phase', 3)) game.add_child(Node.s32('ir_phase', 0)) game.add_child(Node.u8('coin_to_credit', 1)) game.add_child(Node.u8('credit_to_start', 2)) game.add_child(Node.s32('sound_attract', 100)) game.add_child(Node.s8('bookkeeping', 0)) game.add_child(Node.s8('set_clock', 0)) game.add_child(Node.s32('local_clock_sec', 80011)) game.add_child(Node.s32('revision_sec', 0)) game.add_child(Node.string('crash_log', '')) # Swap with server resp = self.exchange('pnm20/game', call) # Verify that response is correct self.assert_path(resp, "response/game/@status")
def verify_player_rb4total_bestallrank_read(self) -> None: call = self.call_node() player = Node.void('player') player.set_attribute('method', 'rb4total_bestallrank_read') player.add_child(Node.s32('uid', 0)) player.add_child(Node.s32_array('score', [897, 897, 0, 0, 0, 284])) call.add_child(player) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/player/score/rank") self.assert_path(resp, "response/player/score/score") self.assert_path(resp, "response/player/score/allrank")
def handle_playerdata_usergamedata_recv_request(self, request: Node) -> Node: # Look up user by refid refid = request.child_value('data/eaid') profiletype = request.child_value('data/recv_csv').split(',')[0] profile = None userid = None if refid is not None: userid = self.data.remote.user.from_refid(self.game, self.version, refid) if userid is not None: profile = self.get_profile(userid) if profile is not None: 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. return root
def verify_player_start(self, refid: str) -> None: call = self.call_node() player = Node.void('player') player.set_attribute('method', 'start') player.add_child(Node.string('rid', refid)) player.add_child(Node.s32('ver', 0)) call.add_child(player) # Swap with server resp = self.exchange('', call) # Verify that response is correct self.assert_path(resp, "response/player/is_suc") self.assert_path(resp, "response/player/unlock_music") self.assert_path(resp, "response/player/unlock_item") self.assert_path(resp, "response/player/item_lock_ctrl") self.assert_path(resp, "response/player/lincle_link_4/qpro") self.assert_path(resp, "response/player/lincle_link_4/glass") self.assert_path(resp, "response/player/lincle_link_4/treasure") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_0") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_1") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_2") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_3") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_4") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_5") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0_6") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_0") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_1") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_2") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_3") self.assert_path(resp, "response/player/lincle_link_4/for_iidx_4") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_0") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_1") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_2") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_3") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_4") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_5") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0_6") self.assert_path(resp, "response/player/lincle_link_4/for_rb_0") self.assert_path(resp, "response/player/lincle_link_4/for_rb_1") self.assert_path(resp, "response/player/lincle_link_4/for_rb_2") self.assert_path(resp, "response/player/lincle_link_4/for_rb_3") self.assert_path(resp, "response/player/lincle_link_4/for_rb_4") self.assert_path(resp, "response/player/lincle_link_4/qproflg") self.assert_path(resp, "response/player/lincle_link_4/glassflg") self.assert_path(resp, "response/player/lincle_link_4/complete")
def handle_game_3_common_request(self, request: Node) -> Node: game = Node.void('game_3') limited = Node.void('music_limited') game.add_child(limited) # Song unlock config game_config = self.get_game_config() if game_config.get_bool('force_unlock_songs'): ids = set() songs = self.data.local.music.get_all_songs( self.game, self.version) for song in songs: if song.data.get_int('limited') in ( self.GAME_LIMITED_LOCKED, self.GAME_LIMITED_UNLOCKABLE): ids.add((song.id, song.chart)) for (songid, chart) in ids: info = Node.void('info') limited.add_child(info) info.add_child(Node.s32('music_id', songid)) info.add_child(Node.u8('music_type', chart)) info.add_child(Node.u8('limited', self.GAME_LIMITED_UNLOCKED)) # Event config event = Node.void('event') game.add_child(event) def enable_event(eid: int) -> None: evt = Node.void('info') event.add_child(evt) evt.add_child(Node.u32('event_id', eid)) if not game_config.get_bool('disable_matching'): enable_event(143) # Matching enabled enable_event(1) # Extended pedal options enable_event(83) # Light start enable_event(130) # Curator rank enable_event(195) # Fictional curator # Event 194 is continuation mode, but it doesn't seem to work on latest data. enable_event(98) # Mission mode for evtid in [145, 146, 147, 148, 149]: enable_event(evtid) # Mission stuff return game
def handle_info_rb5_info_read_hit_chart_request(self, request: Node) -> Node: version = request.child_value('ver') root = Node.void('info') root.add_child(Node.s32('ver', version)) ranking = Node.void('ranking') root.add_child(ranking) 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)) base.add_child(Node.s32('et', end)) new = Node.void('new') base.add_child(new) for (mid, plays) in hitchart: d = Node.void('d') new.add_child(d) d.add_child(Node.s16('mid', mid)) d.add_child(Node.s32('cnt', plays)) # Weekly hit chart add_hitchart( 'weekly', Time.now() - Time.SECONDS_IN_WEEK, Time.now(), self.data.local.music.get_hit_chart(self.game, self.version, 1024, 7), ) # Monthly hit chart add_hitchart( 'monthly', Time.now() - Time.SECONDS_IN_DAY * 30, Time.now(), self.data.local.music.get_hit_chart(self.game, self.version, 1024, 30), ) # All time hit chart add_hitchart( 'total', Time.now() - Time.SECONDS_IN_DAY * 365, Time.now(), self.data.local.music.get_hit_chart(self.game, self.version, 1024, 365), ) return root
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node: root = Node.void('player23') root.add_child(Node.string('name', profile.get_str('name', 'なし'))) root.add_child(Node.s16('chara', profile.get_int('chara', -1))) root.add_child(Node.s8('result', 1)) scores = self.data.remote.music.get_scores(self.game, self.version, userid) for score in scores: # Skip any scores for chart types we don't support if score.chart not in [ self.CHART_TYPE_EASY, self.CHART_TYPE_NORMAL, self.CHART_TYPE_HYPER, self.CHART_TYPE_EX, ]: continue points = score.points medal = score.data.get_int('medal') music = Node.void('music') root.add_child(music) music.add_child(Node.s16('music_num', score.id)) music.add_child(Node.u8('sheet_num', { self.CHART_TYPE_EASY: self.GAME_CHART_TYPE_EASY, self.CHART_TYPE_NORMAL: self.GAME_CHART_TYPE_NORMAL, self.CHART_TYPE_HYPER: self.GAME_CHART_TYPE_HYPER, self.CHART_TYPE_EX: self.GAME_CHART_TYPE_EX, }[score.chart])) music.add_child(Node.s32('score', points)) music.add_child(Node.u8('clear_type', { self.PLAY_MEDAL_CIRCLE_FAILED: self.GAME_PLAY_MEDAL_CIRCLE_FAILED, self.PLAY_MEDAL_DIAMOND_FAILED: self.GAME_PLAY_MEDAL_DIAMOND_FAILED, self.PLAY_MEDAL_STAR_FAILED: self.GAME_PLAY_MEDAL_STAR_FAILED, self.PLAY_MEDAL_EASY_CLEAR: self.GAME_PLAY_MEDAL_EASY_CLEAR, self.PLAY_MEDAL_CIRCLE_CLEARED: self.GAME_PLAY_MEDAL_CIRCLE_CLEARED, self.PLAY_MEDAL_DIAMOND_CLEARED: self.GAME_PLAY_MEDAL_DIAMOND_CLEARED, self.PLAY_MEDAL_STAR_CLEARED: self.GAME_PLAY_MEDAL_STAR_CLEARED, self.PLAY_MEDAL_CIRCLE_FULL_COMBO: self.GAME_PLAY_MEDAL_CIRCLE_FULL_COMBO, self.PLAY_MEDAL_DIAMOND_FULL_COMBO: self.GAME_PLAY_MEDAL_DIAMOND_FULL_COMBO, self.PLAY_MEDAL_STAR_FULL_COMBO: self.GAME_PLAY_MEDAL_STAR_FULL_COMBO, self.PLAY_MEDAL_PERFECT: self.GAME_PLAY_MEDAL_PERFECT, }[medal])) music.add_child(Node.s16('cnt', score.plays)) return root
def verify_usergamedata_recv(self, ref_id: str) -> str: call = self.call_node() # Construct node playerdata = Node.void('playerdata') call.add_child(playerdata) playerdata.set_attribute('method', 'usergamedata_recv') info = Node.void('info') playerdata.add_child(info) info.add_child(Node.s32('version', 1)) data = Node.void('data') playerdata.add_child(data) data.add_child(Node.string('refid', ref_id)) data.add_child(Node.string('dataid', ref_id)) data.add_child(Node.string('gamekind', 'MDX')) data.add_child(Node.u32('recv_num', 4)) data.add_child( Node.string( 'recv_csv', 'COMMON,3fffffffff,OPTION,3fffffffff,LAST,3fffffffff,RIVAL,3fffffffff' )) # Swap with server resp = self.exchange('', call) self.assert_path(resp, "response/playerdata/result") self.assert_path(resp, "response/playerdata/player/record/d/bin1") self.assert_path(resp, "response/playerdata/player/record_num") profiles = 0 name = '' for child in resp.child('playerdata/player/record').children: if child.name != 'd': continue if profiles == 0: bindata = child.value profiledata = base64.b64decode(bindata).split(b',') name = profiledata[25].decode('ascii') profiles = profiles + 1 if profiles != 4: raise Exception( 'Didn\'t receive all four profiles in the right order!') return name
def handle_game_3_common_request(self, request: Node) -> Node: game = Node.void('game_3') limited = Node.void('music_limited') game.add_child(limited) # Song unlock config game_config = self.get_game_config() if game_config.get_bool('force_unlock_songs'): ids = set() songs = self.data.local.music.get_all_songs( self.game, self.music_version) for song in songs: if song.data.get_int('limited') in ( self.GAME_LIMITED_LOCKED, self.GAME_LIMITED_UNLOCKABLE): ids.add((song.id, song.chart)) for (songid, chart) in ids: info = Node.void('info') limited.add_child(info) info.add_child(Node.s32('music_id', songid)) info.add_child(Node.u8('music_type', chart)) info.add_child(Node.u8('limited', self.GAME_LIMITED_UNLOCKED)) # Event config event = Node.void('event') game.add_child(event) def enable_event(eid: int) -> None: evt = Node.void('info') event.add_child(evt) evt.add_child(Node.u32('event_id', eid)) # Allow PASELI light start enable_event(83) # If you want song unlock news to show up, enable one of the following: # 94 - 5/25/2016 unlocks # 95 - 4/27/2016 second unlocks # 89 - 4/27/2016 unlocks # 87 - 4/13/2016 unlocks # 82 - 3/23/2016 second unlocks # 80 - 3/23/2016 unlocks # 76 - 12/22/2016 unlocks return game