示例#1
0
    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')
示例#2
0
    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'),
        }
示例#3
0
    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")
示例#4
0
    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")
示例#5
0
    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))
示例#6
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)
示例#7
0
    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")
示例#8
0
    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")
示例#9
0
    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', ''))
示例#10
0
    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')))
示例#11
0
    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')
示例#12
0
    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
示例#13
0
    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")
示例#14
0
    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
示例#15
0
    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
示例#16
0
    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")
示例#17
0
    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")
示例#18
0
    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
示例#19
0
    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
示例#20
0
    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")
示例#21
0
    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
示例#22
0
    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")
示例#23
0
    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")
示例#24
0
 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
示例#25
0
    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")
示例#26
0
    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
示例#27
0
    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
示例#28
0
    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
示例#29
0
    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
示例#30
0
    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