Beispiel #1
0
    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")
Beispiel #2
0
    def verify_eventlog_write(self, location: str) -> None:
        call = self.call_node()

        # Construct node
        eventlog = Node.void('eventlog')
        call.add_child(eventlog)
        eventlog.set_attribute('method', 'write')
        eventlog.add_child(Node.u32('retrycnt', 0))
        data = Node.void('data')
        eventlog.add_child(data)
        data.add_child(Node.string('eventid', 'S_PWRON'))
        data.add_child(Node.s32('eventorder', 0))
        data.add_child(Node.u64('pcbtime', int(time.time() * 1000)))
        data.add_child(Node.s64('gamesession', -1))
        data.add_child(Node.string('strdata1', '2.3.8'))
        data.add_child(Node.string('strdata2', ''))
        data.add_child(Node.s64('numdata1', 1))
        data.add_child(Node.s64('numdata2', 0))
        data.add_child(Node.string('locationid', location))

        # Swap with server
        resp = self.exchange('', call)

        # Verify that response is correct
        self.assert_path(resp, "response/eventlog/gamesession")
        self.assert_path(resp, "response/eventlog/logsendflg")
        self.assert_path(resp, "response/eventlog/logerrlevel")
        self.assert_path(resp, "response/eventlog/evtidnosendflg")
Beispiel #3
0
    def test_packet1(self) -> Node:
        root = Node.void('test')
        root.set_attribute('test', 'test string value')

        # Regular nodes
        root.add_child(Node.void('void_node'))
        root.add_child(Node.s8('s8_node', -1))
        root.add_child(Node.u8('u8_node', 245))
        root.add_child(Node.s16('s16_node', -8000))
        root.add_child(Node.u16('u16_node', 65000))
        root.add_child(Node.s32('s32_node', -2000000000))
        root.add_child(Node.u32('u32_node', 4000000000))
        root.add_child(Node.s64('s64_node', -1234567890000))
        root.add_child(Node.u64('u64_node', 1234567890000))
        root.add_child(Node.binary('bin_node', b'DEADBEEF'))
        root.add_child(Node.string('str_node', 'this is a string!'))
        root.add_child(Node.ipv4('ip4_node', '192.168.1.24'))
        root.add_child(Node.time('time_node', 1234567890))
        root.add_child(Node.float('float_node', 2.5))
        root.add_child(Node.fouru8('4u8_node', [0x20, 0x21, 0x22, 0x23]))
        root.add_child(Node.bool('bool_true_node', True))
        root.add_child(Node.bool('bool_false_node', False))

        # Array nodes
        root.add_child(Node.s8_array('s8_array_node', [-1, -2, 3, 4, -5]))
        root.add_child(Node.u8_array('u8_array_node', [245, 2, 0, 255, 1]))
        root.add_child(Node.s16_array('s16_array_node', [-8000, 8000]))
        root.add_child(Node.u16_array('u16_array_node', [65000, 1, 2, 65535]))
        root.add_child(Node.s32_array('s32_array_node', [-2000000000, -1]))
        root.add_child(Node.u32_array('u32_array_node', [4000000000, 0, 1, 2]))
        root.add_child(
            Node.s64_array('s64_array_node', [-1234567890000, -1, 1, 1337]))
        root.add_child(
            Node.u64_array('u64_array_node', [1234567890000, 123, 456, 7890]))
        root.add_child(
            Node.time_array('time_array_node', [1234567890, 98765432]))
        root.add_child(
            Node.float_array('float_array_node', [2.5, 0.0, 5.0, 20.5]))
        root.add_child(
            Node.bool_array('bool_array_node', [False, True, True, False]))

        # XML escaping
        escape = Node.string(
            'escape_test',
            '\r\n<testing> & \'thing\' "thing" \r\nthing on new line\r\n    ')
        escape.set_attribute('test',
                             '<testing> & \'thing\' "thing" \r\n thing')
        root.add_child(escape)

        # Unicode
        unicode_node = Node.string('unicode', '今日は')
        unicode_node.set_attribute('unicode_attr', 'わたし')
        root.add_child(unicode_node)

        self.assertLoopback(root)
Beispiel #4
0
    def verify_playerdata_usergamedata_advanced_rivalload(
            self, refid: str, loadflag: int) -> None:
        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', 'rivalload'))
        data.add_child(Node.u64('targettime', Time.now() * 1000))
        data.add_child(Node.string('shoparea', '.'))
        data.add_child(Node.bool('isdouble', False))
        data.add_child(Node.s32('loadflag', loadflag))
        data.add_child(Node.s32('ddrcode', 0))
        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/data/recordtype")
        if loadflag != 2:
            # As implemented, its possible for a machine not in an arcade to have scores.
            # So, if the test PCBID we're using isn't in an arcade, we won't fetch scores
            # for area records (flag 2), so don't check for these in that case.
            self.assert_path(resp, "response/playerdata/data/record/mcode")
            self.assert_path(resp, "response/playerdata/data/record/notetype")
            self.assert_path(resp, "response/playerdata/data/record/rank")
            self.assert_path(resp, "response/playerdata/data/record/clearkind")
            self.assert_path(resp, "response/playerdata/data/record/flagdata")
            self.assert_path(resp, "response/playerdata/data/record/name")
            self.assert_path(resp, "response/playerdata/data/record/area")
            self.assert_path(resp, "response/playerdata/data/record/code")
            self.assert_path(resp, "response/playerdata/data/record/score")
            self.assert_path(resp, "response/playerdata/data/record/ghostid")

        if resp.child_value('playerdata/data/recordtype') != loadflag:
            raise Exception('Invalid record type returned!')
Beispiel #5
0
    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")
Beispiel #6
0
    def handle_player_rb5_player_start_request(self, request: Node) -> Node:
        root = Node.void('player')

        # Create a new play session based on info from the request
        refid = request.child_value('rid')
        userid = self.data.remote.user.from_refid(self.game, self.version,
                                                  refid)
        if userid is not None:
            self.data.local.lobby.put_play_session_info(
                self.game,
                self.version,
                userid,
                {
                    'ga': request.child_value('ga'),
                    'gp': request.child_value('gp'),
                    'la': request.child_value('la'),
                    'pnid': request.child_value('pnid'),
                },
            )
            info = self.data.local.lobby.get_play_session_info(
                self.game,
                self.version,
                userid,
            )
            if info is not None:
                play_id = info.get_int('id')
            else:
                play_id = 0
        else:
            play_id = 0

        # Session stuff, and resend global defaults
        root.add_child(Node.s32('plyid', play_id))
        root.add_child(Node.u64('start_time', Time.now() * 1000))
        self._add_event_info(root)

        return root
Beispiel #7
0
def parse_psmap(data: bytes, offset: str, rootname: str) -> Node:
    pe = pefile.PE(data=data, fast_load=True)
    root = Node.void(rootname)
    base = int(offset, 16)

    def virtual_to_physical(offset: int) -> int:
        for section in pe.sections:
            start = section.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase
            end = start + section.SizeOfRawData

            if offset >= start and offset < end:
                return (offset - start) + section.PointerToRawData
        raise Exception(
            f'Couldn\'t find raw offset for virtual offset 0x{offset:08x}')

    if base >= pe.OPTIONAL_HEADER.ImageBase:
        # Assume this is virtual
        base = virtual_to_physical(base)

    def read_string(offset: int) -> str:
        # First, translate load offset in memory to disk offset
        offset = virtual_to_physical(offset)

        # Now, grab bytes until we're null-terminated
        bytestring = []
        while data[offset] != 0:
            bytestring.append(data[offset])
            offset = offset + 1

        # Its shift-jis encoded, so decode it now
        return bytes(bytestring).decode('shift_jisx0213')

    # For recursing into nodes
    saved_root: List[Node] = []
    saved_loc: List[int] = []

    while True:
        chunk = data[base:(base + 16)]
        base = base + 16

        (nodetype, mandatory, outoffset, width, nameptr,
         defaultptr) = struct.unpack('<BBHIII', chunk)

        if nodetype == 0xFF:
            # End of nodes, see if we should exit
            if len(saved_root) == 0:
                break
            else:
                root = saved_root.pop()
                oldbase = saved_loc.pop()
                if oldbase is not None:
                    base = oldbase
                continue

        # Grab name, get rid of parse numbers
        name = read_string(nameptr)
        try:
            if name.index('#') >= 0:
                name = name[:name.index('#')]
        except ValueError:
            pass

        if nodetype == 0x00:
            raise Exception(f'Invalid node type 0x{nodetype:02x}')
        elif nodetype == 0x01:
            # This is a void node, so we should handle by recursing
            node = Node.void(name)
            root.add_child(node)

            # Recurse here
            saved_root.append(root)

            if defaultptr != 0:
                saved_loc.append(base)
                base = virtual_to_physical(defaultptr)
            else:
                saved_loc.append(None)

            root = node
            continue
        elif nodetype == 0x02 or nodetype == 0x43:
            if nodetype < 0x40:
                elements = int(width / 1)
            else:
                elements = width
            if elements > 1:
                node = Node.s8_array(name, [-1] * elements)
            else:
                node = Node.s8(name, -1)
        elif nodetype == 0x03 or nodetype == 0x44:
            if nodetype < 0x40:
                elements = int(width / 1)
            else:
                elements = width
            if elements > 1:
                node = Node.u8_array(name, [0] * elements)
            else:
                node = Node.u8(name, 0)
        elif nodetype == 0x04 or nodetype == 0x45:
            if nodetype < 0x40:
                elements = int(width / 2)
            else:
                elements = width
            if elements > 1:
                node = Node.s16_array(name, [-1] * elements)
            else:
                node = Node.s16(name, -1)
        elif nodetype == 0x05 or nodetype == 0x46:
            if nodetype < 0x40:
                elements = int(width / 2)
            else:
                elements = width
            if elements > 1:
                node = Node.u16_array(name, [0] * elements)
            else:
                node = Node.u16(name, 0)
        elif nodetype == 0x06 or nodetype == 0x47:
            if nodetype < 0x40:
                elements = int(width / 4)
            else:
                elements = width
            if elements > 1:
                node = Node.s32_array(name, [-1] * elements)
            else:
                node = Node.s32(name, -1)
        elif nodetype == 0x07 or nodetype == 0x48:
            if nodetype < 0x40:
                elements = int(width / 4)
            else:
                elements = width
            if elements > 1:
                node = Node.u32_array(name, [0] * elements)
            else:
                node = Node.u32(name, 0)
        elif nodetype == 0x08 or nodetype == 0x49:
            if nodetype < 0x40:
                elements = int(width / 8)
            else:
                elements = width
            if elements > 1:
                node = Node.s64_array(name, [-1] * elements)
            else:
                node = Node.s64(name, -1)
        elif nodetype == 0x09 or nodetype == 0x4A:
            if nodetype < 0x40:
                elements = int(width / 8)
            else:
                elements = width
            if elements > 1:
                node = Node.u64_array(name, [0] * elements)
            else:
                node = Node.u64(name, 0)
        elif nodetype == 0x0A:
            node = Node.string(name, '')
        elif nodetype == 0x0D:
            node = Node.float(name, 0.0)
        elif nodetype == 0x32 or nodetype == 0x6D:
            if nodetype < 0x40:
                elements = int(width / 1)
            else:
                elements = width
            if elements > 1:
                node = Node.bool_array(name, [False] * elements)
            else:
                node = Node.bool(name, False)
        elif nodetype == 0x2F:
            # Special case, this is an attribute
            if name[-1] != '@':
                raise Exception(
                    f'Attribute name {name} expected to end with @')
            root.set_attribute(name[:-1], '')
            continue
        else:
            raise Exception(f'Unimplemented node type 0x{nodetype:02x}')

        # Append it
        root.add_child(node)

    return root
Beispiel #8
0
    def verify_player_rb5_player_write_5(
        self,
        refid: str,
        loc: str,
        scores: List[Dict[str, int]] = [],
        rivals: List[int] = [],
        mycourse: Optional[List[Dict[str, int]]] = None,
    ) -> int:
        call = self.call_node()

        player = Node.void('player')
        call.add_child(player)
        player.set_attribute('method', 'rb5_player_write_5')
        pdata = Node.void('pdata')
        player.add_child(pdata)
        account = Node.void('account')
        pdata.add_child(account)
        account.add_child(Node.s32('usrid', 0))
        account.add_child(Node.s32('plyid', 0))
        account.add_child(Node.s32('tpc', 1))
        account.add_child(Node.s32('dpc', 1))
        account.add_child(Node.s32('crd', 1))
        account.add_child(Node.s32('brd', 1))
        account.add_child(Node.s32('tdc', 1))
        account.add_child(Node.string('rid', refid))
        account.add_child(Node.string('lid', loc))
        account.add_child(Node.u8('wmode', 0))
        account.add_child(Node.u8('gmode', 0))
        account.add_child(Node.s16('ver', 0))
        account.add_child(Node.bool('pp', False))
        account.add_child(Node.bool('ps', False))
        account.add_child(Node.bool('continue', False))
        account.add_child(Node.bool('firstfree', False))
        account.add_child(Node.s16('pay', 0))
        account.add_child(Node.s16('pay_pc', 0))
        account.add_child(Node.u64('st', int(time.time() * 1000)))
        base = Node.void('base')
        pdata.add_child(base)
        base.add_child(Node.string('name', self.NAME))
        base.add_child(Node.s32('mg', 0))
        base.add_child(Node.s32('ap', 0))
        base.add_child(Node.s32('uattr', 0))
        base.add_child(Node.s32('money', 0))
        base.add_child(Node.bool('is_tut', False))
        base.add_child(Node.s32('class', -1))
        base.add_child(Node.s32('class_ar', 0))
        base.add_child(Node.s32('skill_point', 0))
        stglog = Node.void('stglog')
        pdata.add_child(stglog)

        index = 0
        for score in scores:
            log = Node.void('log')
            stglog.add_child(log)
            log.add_child(Node.s8('stg', index))
            log.add_child(Node.s16('mid', score['id']))
            log.add_child(Node.s8('ng', score['chart']))
            log.add_child(Node.s8('col', 1))
            log.add_child(Node.s8('mt', 0))
            log.add_child(Node.s8('rt', 0))
            log.add_child(Node.s8('ct', score['clear_type']))
            log.add_child(Node.s16('param', score['combo_type']))
            log.add_child(Node.s16('grd', 0))
            log.add_child(Node.s16('ar', score['achievement_rate']))
            log.add_child(Node.s16('sc', score['score']))
            log.add_child(Node.s16('jt_jst', 0))
            log.add_child(Node.s16('jt_grt', 0))
            log.add_child(Node.s16('jt_gd', 0))
            log.add_child(Node.s16('jt_ms', score['miss_count']))
            log.add_child(Node.s16('jt_jr', 0))
            log.add_child(Node.s32('r_uid', 0))
            log.add_child(Node.s32('r_plyid', 0))
            log.add_child(Node.s8('r_stg', 0))
            log.add_child(Node.s8('r_ct', -1))
            log.add_child(Node.s16('r_sc', 0))
            log.add_child(Node.s16('r_grd', 0))
            log.add_child(Node.s16('r_ar', 0))
            log.add_child(Node.s8('r_cpuid', -1))
            log.add_child(Node.s32('time', int(time.time())))
            log.add_child(Node.s8('decide', 0))
            log.add_child(Node.s16('g_gauge', 5000))
            log.add_child(Node.s32('k_flag', 0))
            index = index + 1

        rivalnode = Node.void('rival')
        pdata.add_child(rivalnode)
        for rival in rivals:
            r = Node.void('r')
            rivalnode.add_child(r)
            r.add_child(Node.s32('id', rival))
            r.add_child(Node.s8('regist_type', 3))

        if mycourse is not None:
            mycoursenode = Node.void('mycourse')
            pdata.add_child(mycoursenode)
            mycoursenode.add_child(Node.s16('mycourse_id', 1))
            mycoursenode.add_child(
                Node.s32('music_id_1', mycourse[0]['music_id']))
            mycoursenode.add_child(
                Node.s16('note_grade_1', mycourse[0]['note_grade']))
            mycoursenode.add_child(Node.s32('score_1', mycourse[0]['score']))
            mycoursenode.add_child(
                Node.s32('music_id_2', mycourse[1]['music_id']))
            mycoursenode.add_child(
                Node.s16('note_grade_2', mycourse[1]['note_grade']))
            mycoursenode.add_child(Node.s32('score_2', mycourse[1]['score']))
            mycoursenode.add_child(
                Node.s32('music_id_3', mycourse[2]['music_id']))
            mycoursenode.add_child(
                Node.s16('note_grade_3', mycourse[2]['note_grade']))
            mycoursenode.add_child(Node.s32('score_3', mycourse[2]['score']))
            mycoursenode.add_child(
                Node.s32('music_id_4', mycourse[3]['music_id']))
            mycoursenode.add_child(
                Node.s16('note_grade_4', mycourse[3]['note_grade']))
            mycoursenode.add_child(Node.s32('score_4', mycourse[3]['score']))
            mycoursenode.add_child(Node.s32('insert_time', -1))
            mycoursenode.add_child(Node.s32('def_music_id_1', -1))
            mycoursenode.add_child(Node.s16('def_note_grade_1', -1))
            mycoursenode.add_child(Node.s32('def_music_id_2', -1))
            mycoursenode.add_child(Node.s16('def_note_grade_2', -1))
            mycoursenode.add_child(Node.s32('def_music_id_3', -1))
            mycoursenode.add_child(Node.s16('def_note_grade_3', -1))
            mycoursenode.add_child(Node.s32('def_music_id_4', -1))
            mycoursenode.add_child(Node.s16('def_note_grade_4', -1))

        # Swap with server
        resp = self.exchange('', call)

        # Verify that response is correct
        self.assert_path(resp, "response/player/uid")
        return resp.child_value('player/uid')
Beispiel #9
0
    def handle_info22_request(self, request: Node) -> Optional[Node]:
        method = request.attribute('method')

        if method == 'common':
            # TODO: Hook these up to config so we can change this
            phases = {
                # Unknown event
                0: 0,
                # Unknown event
                1: 0,
                # Pop'n Aura, max 10 (remov all aura requirements)
                2: 10,
                # Story
                3: 1,
                # BEMANI ruins Discovery!
                4: 0,
                # Unknown event
                5: 0,
                # Unknown event
                6: 0,
                # Unknown event
                7: 0,
                # Unknown event
                8: 0,
                # Unknown event
                9: 0,
                # Unknown event
                10: 0,
                # Unknown event
                11: 0,
                # Unknown event
                12: 0,
                # Unknown event
                13: 0,
                # Unknown event
                14: 0,
                # Unknown event
                15: 0,
                # Unknown event
                16: 0,
                # Unknown event
                17: 0,
                # Unknown event
                18: 0,
                # Unknown event
                19: 0,
            }
            stories = list(range(173))

            root = Node.void('info22')
            for phaseid in phases:
                phase = Node.void('phase')
                root.add_child(phase)
                phase.add_child(Node.s16('event_id', phaseid))
                phase.add_child(Node.s16('phase', phases[phaseid]))

            for storyid in stories:
                story = Node.void('story')
                root.add_child(story)
                story.add_child(Node.u32('story_id', storyid))
                story.add_child(Node.bool('is_limited', False))
                story.add_child(Node.u64('limit_date', 0))

            return root

        # Invalid method
        return None
Beispiel #10
0
    def verify_player_write(self, refid: str, loc: str, scores: List[Dict[str, int]]) -> int:
        call = self.call_node()

        player = Node.void('player')
        call.add_child(player)
        player.set_attribute('method', 'write')
        pdata = Node.void('pdata')
        player.add_child(pdata)
        account = Node.void('account')
        pdata.add_child(account)
        account.add_child(Node.s32('usrid', 0))
        account.add_child(Node.s32('plyid', 0))
        account.add_child(Node.s32('tpc', 1))
        account.add_child(Node.s32('dpc', 1))
        account.add_child(Node.s32('crd', 1))
        account.add_child(Node.s32('brd', 1))
        account.add_child(Node.s32('tdc', 1))
        account.add_child(Node.string('rid', refid))
        account.add_child(Node.string('lid', loc))
        account.add_child(Node.u8('mode', 0))
        account.add_child(Node.s16('ver', 5))
        account.add_child(Node.bool('pp', True))
        account.add_child(Node.bool('ps', True))
        account.add_child(Node.s16('pay', 0))
        account.add_child(Node.s16('pay_pc', 0))
        account.add_child(Node.u64('st', int(time.time() * 1000)))
        base = Node.void('base')
        pdata.add_child(base)
        base.add_child(Node.string('name', self.NAME))
        base.add_child(Node.s32('exp', 0))
        base.add_child(Node.s32('lv', 1))
        base.add_child(Node.s32('mg', -1))
        base.add_child(Node.s32('ap', -1))
        base.add_child(Node.s32_array('hidden_param', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
        base.add_child(Node.bool('is_tut', True))
        stglog = Node.void('stglog')
        pdata.add_child(stglog)
        index = 0
        for score in scores:
            log = Node.void('log')
            stglog.add_child(log)
            log.add_child(Node.s8('stg', index))
            log.add_child(Node.s16('mid', score['id']))
            log.add_child(Node.s8('ng', score['chart']))
            log.add_child(Node.s8('col', 0))
            log.add_child(Node.s8('mt', 7))
            log.add_child(Node.s8('rt', 0))
            log.add_child(Node.s8('ct', score['clear_type']))
            log.add_child(Node.s16('grd', 0))
            log.add_child(Node.s16('ar', score['achievement_rate']))
            log.add_child(Node.s16('sc', score['score']))
            log.add_child(Node.s16('jt_jst', 0))
            log.add_child(Node.s16('jt_grt', 0))
            log.add_child(Node.s16('jt_gd', 0))
            log.add_child(Node.s16('jt_ms', score['miss_count']))
            log.add_child(Node.s16('jt_jr', 0))
            log.add_child(Node.s16('cmb', score['combo']))
            log.add_child(Node.s16('exp', 0))
            log.add_child(Node.s32('r_uid', 0))
            log.add_child(Node.s32('r_plyid', 0))
            log.add_child(Node.s8('r_stg', 0))
            log.add_child(Node.s8('r_ct', -1))
            log.add_child(Node.s16('r_sc', 0))
            log.add_child(Node.s16('r_grd', 0))
            log.add_child(Node.s16('r_ar', 0))
            log.add_child(Node.s8('r_cpuid', -1))
            log.add_child(Node.s32('time', int(time.time())))
            log.add_child(Node.s8('decide', 0))
            index = index + 1

        # Swap with server
        resp = self.exchange('', call)

        # Verify that response is correct
        self.assert_path(resp, "response/player/uid")
        return resp.child_value('player/uid')
Beispiel #11
0
    def __construct_common_info(self, root: Node) -> None:
        # Event phases
        phases = {
            # Unknown event (0-16)
            0: 16,
            # Unknown event (0-3)
            1: 3,
            # Unknown event (0-1)
            2: 1,
            # Unknown event (0-2)
            3: 2,
            # Unknown event (0-1)
            4: 1,
            # Unknown event (0-2)
            5: 2,
            # Unknown event (0-1)
            6: 1,
            # Unknown event (0-4)
            7: 4,
            # Unknown event (0-3)
            8: 3,
            # Unknown event (0-4)
            9: 4,
            # Unknown event (0-4)
            10: 4,
            # Unknown event (0-1)
            11: 1,
            # Possibly global event matching related? (0-1)
            12: 1,
            # Unknown event (0-4)
            13: 4,
        }

        for phaseid in phases:
            phase = Node.void('phase')
            root.add_child(phase)
            phase.add_child(Node.s16('event_id', phaseid))
            phase.add_child(Node.s16('phase', phases[phaseid]))

        for areaid in range(1, 50):
            area = Node.void('area')
            root.add_child(area)
            area.add_child(Node.s16('area_id', areaid))
            area.add_child(Node.u64('end_date', 0))
            area.add_child(Node.s16('medal_id', areaid))
            area.add_child(Node.bool('is_limit', False))

        # Calculate most popular characters
        profiles = self.data.remote.user.get_all_profiles(
            self.game, self.version)
        charas: Dict[int, int] = {}
        for (userid, profile) in profiles:
            chara = profile.get_int('chara', -1)
            if chara <= 0:
                continue
            if chara not in charas:
                charas[chara] = 1
            else:
                charas[chara] = charas[chara] + 1

        # Order a typle by most popular character to least popular character
        charamap = sorted(
            [(c, charas[c]) for c in charas],
            key=lambda c: c[1],
            reverse=True,
        )

        # Output the top 20 of them
        rank = 1
        for (charaid, usecount) in charamap[:20]:
            popular = Node.void('popular')
            root.add_child(popular)
            popular.add_child(Node.s16('rank', rank))
            popular.add_child(Node.s16('chara_num', charaid))
            rank = rank + 1

        # Output the hit chart
        for (songid, plays) in self.data.local.music.get_hit_chart(
                self.game, self.music_version, 500):
            popular_music = Node.void('popular_music')
            root.add_child(popular_music)
            popular_music.add_child(Node.s16('music_num', songid))

        # Output goods prices
        for goodsid in range(1, 421):
            if goodsid >= 1 and goodsid <= 80:
                price = 60
            elif goodsid >= 81 and goodsid <= 120:
                price = 250
            elif goodsid >= 121 and goodsid <= 142:
                price = 500
            elif goodsid >= 143 and goodsid <= 300:
                price = 100
            elif goodsid >= 301 and goodsid <= 420:
                price = 150
            else:
                raise Exception('Invalid goods ID!')
            goods = Node.void('goods')
            root.add_child(goods)
            goods.add_child(Node.s16('goods_id', goodsid))
            goods.add_child(Node.s32('price', price))
            goods.add_child(Node.s16('goods_type', 0))
Beispiel #12
0
    def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
        statistics = self.get_play_statistics(userid)
        game_config = self.get_game_config()
        achievements = self.data.local.user.get_achievements(
            self.game, self.version, userid)
        links = self.data.local.user.get_links(self.game, self.version, userid)
        rprofiles: Dict[UserID, ValidatedDict] = {}
        root = Node.void('player')
        pdata = Node.void('pdata')
        root.add_child(pdata)

        # Account time info
        last_play_date = statistics.get_int_array('last_play_date', 3)
        today_play_date = Time.todays_date()
        if (last_play_date[0] == today_play_date[0]
                and last_play_date[1] == today_play_date[1]
                and last_play_date[2] == today_play_date[2]):
            today_count = statistics.get_int('today_plays', 0)
        else:
            today_count = 0

        # Previous account info
        previous_version = self.previous_version()
        if previous_version:
            succeeded = previous_version.has_profile(userid)
        else:
            succeeded = False

        # Account info
        account = Node.void('account')
        pdata.add_child(account)
        account.add_child(Node.s32('usrid', profile.get_int('extid')))
        account.add_child(Node.s32('tpc', statistics.get_int('total_plays',
                                                             0)))
        account.add_child(Node.s32('dpc', today_count))
        account.add_child(Node.s32('crd', 1))
        account.add_child(Node.s32('brd', 1))
        account.add_child(Node.s32('tdc', statistics.get_int('total_days', 0)))
        account.add_child(Node.s32('intrvld', 0))
        account.add_child(Node.s16('ver', 0))
        account.add_child(Node.bool('succeed', succeeded))
        account.add_child(Node.u64('pst', 0))
        account.add_child(Node.u64('st', Time.now() * 1000))
        account.add_child(Node.s32('opc', 0))
        account.add_child(Node.s32('lpc', 0))
        account.add_child(Node.s32('cpc', 0))
        account.add_child(Node.s32('mpc', 0))

        # Base profile info
        base = Node.void('base')
        pdata.add_child(base)
        base.add_child(Node.string('name', profile.get_str('name')))
        base.add_child(Node.s32('mg', profile.get_int('mg')))
        base.add_child(Node.s32('ap', profile.get_int('ap')))
        base.add_child(Node.string('cmnt', ''))
        base.add_child(Node.s32('uattr', profile.get_int('uattr')))
        base.add_child(Node.s32('money', profile.get_int('money')))
        base.add_child(Node.s32('tbs_5', -1))
        base.add_child(Node.s32_array('tbgs_5', [-1, -1, -1, -1]))
        base.add_child(
            Node.s16_array('mlog', [
                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1
            ]))
        base.add_child(Node.s32('class', profile.get_int('class')))
        base.add_child(Node.s32('class_ar', profile.get_int('class_ar')))
        base.add_child(Node.s32('skill_point', profile.get_int('skill_point')))
        base.add_child(Node.bool('meteor_flg', False))

        # Rivals
        rival = Node.void('rival')
        pdata.add_child(rival)
        slotid = 0
        for link in links:
            if link.type != 'rival':
                continue

            if link.other_userid not in rprofiles:
                rprofile = self.get_profile(link.other_userid)
                if rprofile is None:
                    continue
                rprofiles[link.other_userid] = rprofile
            else:
                rprofile = rprofiles[link.other_userid]
            lobbyinfo = self.data.local.lobby.get_play_session_info(
                self.game, self.version, link.other_userid)
            if lobbyinfo is None:
                lobbyinfo = ValidatedDict()

            r = Node.void('r')
            rival.add_child(r)
            r.add_child(Node.s32('slot_id', slotid))
            r.add_child(Node.s32('id', rprofile.get_int('extid')))
            r.add_child(Node.string('name', rprofile.get_str('name')))
            r.add_child(
                Node.s32('icon',
                         rprofile.get_dict('config').get_int('icon_id')))
            r.add_child(Node.s32('class', rprofile.get_int('class')))
            r.add_child(Node.s32('class_ar', rprofile.get_int('class_ar')))
            r.add_child(Node.bool('friend', True))
            r.add_child(Node.bool('target', False))
            r.add_child(Node.u32('time', lobbyinfo.get_int('time')))
            r.add_child(Node.u8_array('ga', lobbyinfo.get_int_array('ga', 4)))
            r.add_child(Node.u16('gp', lobbyinfo.get_int('gp')))
            r.add_child(Node.u8_array('ipn', lobbyinfo.get_int_array('la', 4)))
            r.add_child(
                Node.u8_array('pnid', lobbyinfo.get_int_array('pnid', 16)))
            slotid = slotid + 1

        # Configuration
        configdict = profile.get_dict('config')
        config = Node.void('config')
        pdata.add_child(config)
        config.add_child(Node.u8('msel_bgm', configdict.get_int('msel_bgm')))
        config.add_child(
            Node.u8('narrowdown_type', configdict.get_int('narrowdown_type')))
        config.add_child(Node.s16('icon_id', configdict.get_int('icon_id')))
        config.add_child(Node.s16('byword_0', configdict.get_int('byword_0')))
        config.add_child(Node.s16('byword_1', configdict.get_int('byword_1')))
        config.add_child(
            Node.bool('is_auto_byword_0',
                      configdict.get_bool('is_auto_byword_0')))
        config.add_child(
            Node.bool('is_auto_byword_1',
                      configdict.get_bool('is_auto_byword_1')))
        config.add_child(Node.u8('mrec_type', configdict.get_int('mrec_type')))
        config.add_child(Node.u8('tab_sel', configdict.get_int('tab_sel')))
        config.add_child(Node.u8('card_disp', configdict.get_int('card_disp')))
        config.add_child(
            Node.u8('score_tab_disp', configdict.get_int('score_tab_disp')))
        config.add_child(
            Node.s16('last_music_id', configdict.get_int('last_music_id', -1)))
        config.add_child(
            Node.u8('last_note_grade', configdict.get_int('last_note_grade')))
        config.add_child(Node.u8('sort_type', configdict.get_int('sort_type')))
        config.add_child(
            Node.u8('rival_panel_type',
                    configdict.get_int('rival_panel_type')))
        config.add_child(
            Node.u64('random_entry_work',
                     configdict.get_int('random_entry_work')))
        config.add_child(
            Node.u64('custom_folder_work',
                     configdict.get_int('custom_folder_work')))
        config.add_child(
            Node.u8('folder_type', configdict.get_int('folder_type')))
        config.add_child(
            Node.u8('folder_lamp_type',
                    configdict.get_int('folder_lamp_type')))
        config.add_child(Node.bool('is_tweet',
                                   configdict.get_bool('is_tweet')))
        config.add_child(
            Node.bool('is_link_twitter',
                      configdict.get_bool('is_link_twitter')))

        # Customizations
        customdict = profile.get_dict('custom')
        custom = Node.void('custom')
        pdata.add_child(custom)
        custom.add_child(Node.u8('st_shot', customdict.get_int('st_shot')))
        custom.add_child(Node.u8('st_frame', customdict.get_int('st_frame')))
        custom.add_child(Node.u8('st_expl', customdict.get_int('st_expl')))
        custom.add_child(Node.u8('st_bg', customdict.get_int('st_bg')))
        custom.add_child(
            Node.u8('st_shot_vol', customdict.get_int('st_shot_vol')))
        custom.add_child(Node.u8('st_bg_bri', customdict.get_int('st_bg_bri')))
        custom.add_child(
            Node.u8('st_obj_size', customdict.get_int('st_obj_size')))
        custom.add_child(
            Node.u8('st_jr_gauge', customdict.get_int('st_jr_gauge')))
        custom.add_child(
            Node.u8('st_clr_gauge', customdict.get_int('st_clr_gauge')))
        custom.add_child(Node.u8('st_rnd', customdict.get_int('st_rnd')))
        custom.add_child(
            Node.u8('st_gr_gauge_type',
                    customdict.get_int('st_gr_gauge_type')))
        custom.add_child(
            Node.s16('voice_message_set',
                     customdict.get_int('voice_message_set', -1)))
        custom.add_child(
            Node.u8('same_time_note_disp',
                    customdict.get_int('same_time_note_disp')))
        custom.add_child(
            Node.u8('st_score_disp_type',
                    customdict.get_int('st_score_disp_type')))
        custom.add_child(
            Node.u8('st_bonus_type', customdict.get_int('st_bonus_type')))
        custom.add_child(
            Node.u8('st_rivalnote_type',
                    customdict.get_int('st_rivalnote_type')))
        custom.add_child(
            Node.u8('st_topassist_type',
                    customdict.get_int('st_topassist_type')))
        custom.add_child(
            Node.u8('high_speed', customdict.get_int('high_speed')))
        custom.add_child(Node.u8('st_hazard', customdict.get_int('st_hazard')))
        custom.add_child(
            Node.u8('st_clr_cond', customdict.get_int('st_clr_cond')))
        custom.add_child(
            Node.u8('voice_message_volume',
                    customdict.get_int('voice_message_volume')))

        # Unlocks
        released = Node.void('released')
        pdata.add_child(released)

        for item in achievements:
            if item.type[:5] != 'item_':
                continue
            itemtype = int(item.type[5:])
            if game_config.get_bool('force_unlock_songs') and itemtype == 0:
                # Don't echo unlocks when we're force unlocking, we'll do it later
                continue

            info = Node.void('info')
            released.add_child(info)
            info.add_child(Node.u8('type', itemtype))
            info.add_child(Node.u16('id', item.id))
            info.add_child(Node.u16('param', item.data.get_int('param')))
            info.add_child(Node.s32('insert_time', item.data.get_int('time')))

        if game_config.get_bool('force_unlock_songs'):
            ids: Dict[int, int] = {}
            songs = self.data.local.music.get_all_songs(
                self.game, self.music_version)
            for song in songs:
                if song.id not in ids:
                    ids[song.id] = 0

                if song.data.get_int('difficulty') > 0:
                    ids[song.id] = ids[song.id] | (1 << song.chart)

            for songid in ids:
                if ids[songid] == 0:
                    continue

                info = Node.void('info')
                released.add_child(info)
                info.add_child(Node.u8('type', 0))
                info.add_child(Node.u16('id', songid))
                info.add_child(Node.u16('param', ids[songid]))
                info.add_child(Node.s32('insert_time', Time.now()))

        # Announcements
        announce = Node.void('announce')
        pdata.add_child(announce)

        for announcement in achievements:
            if announcement.type[:13] != 'announcement_':
                continue
            announcementtype = int(announcement.type[13:])

            info = Node.void('info')
            announce.add_child(info)
            info.add_child(Node.u8('type', announcementtype))
            info.add_child(Node.u16('id', announcement.id))
            info.add_child(
                Node.u16('param', announcement.data.get_int('param')))
            info.add_child(
                Node.bool('bneedannounce', announcement.data.get_bool('need')))

        # Dojo ranking return
        dojo = Node.void('dojo')
        pdata.add_child(dojo)

        for entry in achievements:
            if entry.type != 'dojo':
                continue

            rec = Node.void('rec')
            dojo.add_child(rec)
            rec.add_child(Node.s32('class', entry.id))
            rec.add_child(
                Node.s32('clear_type', entry.data.get_int('clear_type')))
            rec.add_child(Node.s32('total_ar', entry.data.get_int('ar')))
            rec.add_child(Node.s32('total_score', entry.data.get_int('score')))
            rec.add_child(Node.s32('play_count', entry.data.get_int('plays')))
            rec.add_child(
                Node.s32('last_play_time',
                         entry.data.get_int('play_timestamp')))
            rec.add_child(
                Node.s32('record_update_time',
                         entry.data.get_int('record_timestamp')))
            rec.add_child(Node.s32('rank', 0))

        # Player Parameters
        player_param = Node.void('player_param')
        pdata.add_child(player_param)

        for param in achievements:
            if param.type[:13] != 'player_param_':
                continue
            itemtype = int(param.type[13:])

            itemnode = Node.void('item')
            player_param.add_child(itemnode)
            itemnode.add_child(Node.s32('type', itemtype))
            itemnode.add_child(Node.s32('bank', param.id))
            itemnode.add_child(
                Node.s32_array('data', param.data.get_int_array('data', 256)))

        # Shop score for players
        self._add_shop_score(pdata)

        # My List data
        mylist = Node.void('mylist')
        pdata.add_child(mylist)
        listdata = Node.void('list')
        mylist.add_child(listdata)
        listdata.add_child(Node.s16('idx', 0))
        listdata.add_child(
            Node.s16_array('mlst',
                           profile.get_int_array('favorites', 30, [-1] * 30)))

        # Minigame settings
        minigame = Node.void('minigame')
        pdata.add_child(minigame)
        minigame.add_child(Node.s8('mgid', profile.get_int('mgid')))
        minigame.add_child(Node.s32('sc', profile.get_int('mgsc')))

        # Derby settings
        derby = Node.void('derby')
        pdata.add_child(derby)
        derby.add_child(Node.bool('is_open', False))

        # Music rank points
        music_rank_point = Node.void('music_rank_point')
        pdata.add_child(music_rank_point)

        # yurukome list stuff
        yurukome_list = Node.void('yurukome_list')
        pdata.add_child(yurukome_list)

        for entry in achievements:
            if entry.type != 'yurukome':
                continue

            yurukome = Node.void('yurukome')
            yurukome_list.add_child(yurukome)
            yurukome.add_child(Node.s32('yurukome_id', entry.id))

        # My course mode
        mycourse = Node.void('mycourse')
        mycoursedict = profile.get_dict('mycourse')
        pdata.add_child(mycourse)
        mycourse.add_child(Node.s16('mycourse_id', 1))
        mycourse.add_child(
            Node.s32('music_id_1', mycoursedict.get_int('music_id_1', -1)))
        mycourse.add_child(
            Node.s16('note_grade_1', mycoursedict.get_int('note_grade_1', -1)))
        mycourse.add_child(
            Node.s32('score_1', mycoursedict.get_int('score_1', -1)))
        mycourse.add_child(
            Node.s32('music_id_2', mycoursedict.get_int('music_id_2', -1)))
        mycourse.add_child(
            Node.s16('note_grade_2', mycoursedict.get_int('note_grade_2', -1)))
        mycourse.add_child(
            Node.s32('score_2', mycoursedict.get_int('score_2', -1)))
        mycourse.add_child(
            Node.s32('music_id_3', mycoursedict.get_int('music_id_3', -1)))
        mycourse.add_child(
            Node.s16('note_grade_3', mycoursedict.get_int('note_grade_3', -1)))
        mycourse.add_child(
            Node.s32('score_3', mycoursedict.get_int('score_3', -1)))
        mycourse.add_child(
            Node.s32('music_id_4', mycoursedict.get_int('music_id_4', -1)))
        mycourse.add_child(
            Node.s16('note_grade_4', mycoursedict.get_int('note_grade_4', -1)))
        mycourse.add_child(
            Node.s32('score_4', mycoursedict.get_int('score_4', -1)))
        mycourse.add_child(
            Node.s32('insert_time', mycoursedict.get_int('insert_time', -1)))
        mycourse.add_child(Node.s32('def_music_id_1', -1))
        mycourse.add_child(Node.s16('def_note_grade_1', -1))
        mycourse.add_child(Node.s32('def_music_id_2', -1))
        mycourse.add_child(Node.s16('def_note_grade_2', -1))
        mycourse.add_child(Node.s32('def_music_id_3', -1))
        mycourse.add_child(Node.s16('def_note_grade_3', -1))
        mycourse.add_child(Node.s32('def_music_id_4', -1))
        mycourse.add_child(Node.s16('def_note_grade_4', -1))

        # Friend course scores
        mycourse_f = Node.void('mycourse_f')
        pdata.add_child(mycourse_f)

        for link in links:
            if link.type != 'rival':
                continue

            if link.other_userid not in rprofiles:
                rprofile = self.get_profile(link.other_userid)
                if rprofile is None:
                    continue
                rprofiles[link.other_userid] = rprofile
            else:
                rprofile = rprofiles[link.other_userid]
            mycoursedict = rprofile.get_dict('mycourse')

            rec = Node.void('rec')
            mycourse_f.add_child(rec)
            rec.add_child(Node.s32('rival_id', rprofile.get_int('extid')))
            rec.add_child(Node.s16('mycourse_id', 1))
            rec.add_child(
                Node.s32('music_id_1', mycoursedict.get_int('music_id_1', -1)))
            rec.add_child(
                Node.s16('note_grade_1',
                         mycoursedict.get_int('note_grade_1', -1)))
            rec.add_child(
                Node.s32('score_1', mycoursedict.get_int('score_1', -1)))
            rec.add_child(
                Node.s32('music_id_2', mycoursedict.get_int('music_id_2', -1)))
            rec.add_child(
                Node.s16('note_grade_2',
                         mycoursedict.get_int('note_grade_2', -1)))
            rec.add_child(
                Node.s32('score_2', mycoursedict.get_int('score_2', -1)))
            rec.add_child(
                Node.s32('music_id_3', mycoursedict.get_int('music_id_3', -1)))
            rec.add_child(
                Node.s16('note_grade_3',
                         mycoursedict.get_int('note_grade_3', -1)))
            rec.add_child(
                Node.s32('score_3', mycoursedict.get_int('score_3', -1)))
            rec.add_child(
                Node.s32('music_id_4', mycoursedict.get_int('music_id_4', -1)))
            rec.add_child(
                Node.s16('note_grade_4',
                         mycoursedict.get_int('note_grade_4', -1)))
            rec.add_child(
                Node.s32('score_4', mycoursedict.get_int('score_4', -1)))
            rec.add_child(
                Node.s32('insert_time',
                         mycoursedict.get_int('insert_time', -1)))

        return root
Beispiel #13
0
    def verify_playerdata_usergamedata_advanced_usersave(
            self,
            refid: str,
            extid: int,
            locid: str,
            score: Dict[str, Any],
            scorepos: int = 0) -> None:
        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', 'usersave'))
        data.add_child(Node.string('name', self.NAME))
        data.add_child(Node.s32('ddrcode', extid))
        data.add_child(Node.s32('playside', 1))
        data.add_child(Node.s32('playstyle', 0))
        data.add_child(Node.s32('area', 58))
        data.add_child(Node.s32('weight100', 0))
        data.add_child(Node.string('shopname', 'gmw='))
        data.add_child(Node.bool('ispremium', False))
        data.add_child(Node.bool('iseapass', True))
        data.add_child(Node.bool('istakeover', False))
        data.add_child(Node.bool('isrepeater', False))
        data.add_child(Node.bool('isgameover', scorepos < 0))
        data.add_child(Node.string('locid', locid))
        data.add_child(Node.string('shoparea', '.'))
        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'))

        for i in range(5):
            if i == scorepos:
                # Fill in score here
                note = Node.void('note')
                data.add_child(note)
                note.add_child(Node.u8('stagenum', i + 1))
                note.add_child(Node.u32('mcode', score['id']))
                note.add_child(Node.u8('notetype', score['chart']))
                note.add_child(Node.u8('rank', score['rank']))
                note.add_child(Node.u8('clearkind', score['halo']))
                note.add_child(Node.s32('score', score['score']))
                note.add_child(Node.s32('exscore', 0))
                note.add_child(Node.s32('maxcombo', 0))
                note.add_child(Node.s32('life', 0))
                note.add_child(Node.s32('fastcount', 0))
                note.add_child(Node.s32('slowcount', 0))
                note.add_child(Node.s32('judge_marvelous', 0))
                note.add_child(Node.s32('judge_perfect', 0))
                note.add_child(Node.s32('judge_great', 0))
                note.add_child(Node.s32('judge_good', 0))
                note.add_child(Node.s32('judge_boo', 0))
                note.add_child(Node.s32('judge_miss', 0))
                note.add_child(Node.s32('judge_ok', 0))
                note.add_child(Node.s32('judge_ng', 0))
                note.add_child(Node.s32('calorie', 0))
                note.add_child(Node.s32('ghostsize', len(score['ghost'])))
                note.add_child(Node.string('ghost', score['ghost']))
                note.add_child(Node.u8('opt_speed', 0))
                note.add_child(Node.u8('opt_boost', 0))
                note.add_child(Node.u8('opt_appearance', 0))
                note.add_child(Node.u8('opt_turn', 0))
                note.add_child(Node.u8('opt_dark', 0))
                note.add_child(Node.u8('opt_scroll', 0))
                note.add_child(Node.u8('opt_arrowcolor', 0))
                note.add_child(Node.u8('opt_cut', 0))
                note.add_child(Node.u8('opt_freeze', 0))
                note.add_child(Node.u8('opt_jump', 0))
                note.add_child(Node.u8('opt_arrowshape', 0))
                note.add_child(Node.u8('opt_filter', 0))
                note.add_child(Node.u8('opt_guideline', 0))
                note.add_child(Node.u8('opt_gauge', 0))
                note.add_child(Node.u8('opt_judgepriority', 0))
                note.add_child(Node.u8('opt_timing', 0))
                note.add_child(Node.string('basename', ''))
                note.add_child(Node.string('title_b64', ''))
                note.add_child(Node.string('artist_b64', ''))
                note.add_child(Node.u16('bpmMax', 0))
                note.add_child(Node.u16('bpmMin', 0))
                note.add_child(Node.u8('level', 0))
                note.add_child(Node.u8('series', 0))
                note.add_child(Node.u32('bemaniFlag', 0))
                note.add_child(Node.u32('genreFlag', 0))
                note.add_child(Node.u8('limited', 0))
                note.add_child(Node.u8('region', 0))
                note.add_child(Node.s32('gr_voltage', 0))
                note.add_child(Node.s32('gr_stream', 0))
                note.add_child(Node.s32('gr_chaos', 0))
                note.add_child(Node.s32('gr_freeze', 0))
                note.add_child(Node.s32('gr_air', 0))
                note.add_child(Node.bool('share', False))
                note.add_child(Node.u64('endtime', 0))
                note.add_child(Node.s32('folder', 0))
            else:
                note = Node.void('note')
                data.add_child(note)
                note.add_child(Node.u8('stagenum', 0))
                note.add_child(Node.u32('mcode', 0))
                note.add_child(Node.u8('notetype', 0))
                note.add_child(Node.u8('rank', 0))
                note.add_child(Node.u8('clearkind', 0))
                note.add_child(Node.s32('score', 0))
                note.add_child(Node.s32('exscore', 0))
                note.add_child(Node.s32('maxcombo', 0))
                note.add_child(Node.s32('life', 0))
                note.add_child(Node.s32('fastcount', 0))
                note.add_child(Node.s32('slowcount', 0))
                note.add_child(Node.s32('judge_marvelous', 0))
                note.add_child(Node.s32('judge_perfect', 0))
                note.add_child(Node.s32('judge_great', 0))
                note.add_child(Node.s32('judge_good', 0))
                note.add_child(Node.s32('judge_boo', 0))
                note.add_child(Node.s32('judge_miss', 0))
                note.add_child(Node.s32('judge_ok', 0))
                note.add_child(Node.s32('judge_ng', 0))
                note.add_child(Node.s32('calorie', 0))
                note.add_child(Node.s32('ghostsize', 0))
                note.add_child(Node.string('ghost', ''))
                note.add_child(Node.u8('opt_speed', 0))
                note.add_child(Node.u8('opt_boost', 0))
                note.add_child(Node.u8('opt_appearance', 0))
                note.add_child(Node.u8('opt_turn', 0))
                note.add_child(Node.u8('opt_dark', 0))
                note.add_child(Node.u8('opt_scroll', 0))
                note.add_child(Node.u8('opt_arrowcolor', 0))
                note.add_child(Node.u8('opt_cut', 0))
                note.add_child(Node.u8('opt_freeze', 0))
                note.add_child(Node.u8('opt_jump', 0))
                note.add_child(Node.u8('opt_arrowshape', 0))
                note.add_child(Node.u8('opt_filter', 0))
                note.add_child(Node.u8('opt_guideline', 0))
                note.add_child(Node.u8('opt_gauge', 0))
                note.add_child(Node.u8('opt_judgepriority', 0))
                note.add_child(Node.u8('opt_timing', 0))
                note.add_child(Node.string('basename', ''))
                note.add_child(Node.string('title_b64', ''))
                note.add_child(Node.string('artist_b64', ''))
                note.add_child(Node.u16('bpmMax', 0))
                note.add_child(Node.u16('bpmMin', 0))
                note.add_child(Node.u8('level', 0))
                note.add_child(Node.u8('series', 0))
                note.add_child(Node.u32('bemaniFlag', 0))
                note.add_child(Node.u32('genreFlag', 0))
                note.add_child(Node.u8('limited', 0))
                note.add_child(Node.u8('region', 0))
                note.add_child(Node.s32('gr_voltage', 0))
                note.add_child(Node.s32('gr_stream', 0))
                note.add_child(Node.s32('gr_chaos', 0))
                note.add_child(Node.s32('gr_freeze', 0))
                note.add_child(Node.s32('gr_air', 0))
                note.add_child(Node.bool('share', False))
                note.add_child(Node.u64('endtime', 0))
                note.add_child(Node.s32('folder', 0))

        # Swap with server
        resp = self.exchange('', call)

        # Verify that response is correct
        self.assert_path(resp, "response/playerdata/result")
Beispiel #14
0
    def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
        root = Node.void('gametop')
        data = Node.void('data')
        root.add_child(data)
        player = Node.void('player')
        data.add_child(player)

        # Player info and statistics
        info = Node.void('info')
        player.add_child(info)
        info.add_child(Node.s16('jubility', profile.get_int('jubility')))
        info.add_child(Node.s16('jubility_yday', profile.get_int('jubility_yday')))
        info.add_child(Node.s32('tune_cnt', profile.get_int('tune_cnt')))
        info.add_child(Node.s32('save_cnt', profile.get_int('save_cnt')))
        info.add_child(Node.s32('saved_cnt', profile.get_int('saved_cnt')))
        info.add_child(Node.s32('fc_cnt', profile.get_int('fc_cnt')))
        info.add_child(Node.s32('ex_cnt', profile.get_int('ex_cnt')))
        info.add_child(Node.s32('pf_cnt', profile.get_int('pf_cnt')))
        info.add_child(Node.s32('clear_cnt', profile.get_int('clear_cnt')))
        info.add_child(Node.s32('match_cnt', profile.get_int('match_cnt')))
        info.add_child(Node.s32('beat_cnt', profile.get_int('beat_cnt')))
        info.add_child(Node.s32('mynews_cnt', profile.get_int('mynews_cnt')))
        info.add_child(Node.s32('extra_point', profile.get_int('extra_point')))
        info.add_child(Node.bool('is_extra_played', profile.get_bool('is_extra_played')))
        if 'total_best_score' in profile:
            info.add_child(Node.s32('total_best_score', profile.get_int('total_best_score')))

        # Looks to be set to true when there's an old profile, stops tutorial from
        # happening on first load.
        info.add_child(Node.bool('inherit', profile.get_bool('has_old_version')))

        # Not saved, but loaded
        info.add_child(Node.s32('mtg_entry_cnt', 123))
        info.add_child(Node.s32('mtg_hold_cnt', 456))
        info.add_child(Node.u8('mtg_result', 10))

        # First play stuff we don't support
        free_first_play = Node.void('free_first_play')
        player.add_child(free_first_play)
        free_first_play.add_child(Node.bool('is_available', False))
        free_first_play.add_child(Node.s32('point', 0))
        free_first_play.add_child(Node.s32('point_used', 0))

        # Secret unlocks
        item = Node.void('item')
        player.add_child(item)
        item.add_child(Node.s32_array(
            'secret_list',
            profile.get_int_array(
                'secret_list',
                32,
                [-1] * 32,
            ),
        ))
        item.add_child(Node.s32_array(
            'title_list',
            profile.get_int_array(
                'title_list',
                96,
                [-1] * 96,
            ),
        ))
        item.add_child(Node.s16('theme_list', profile.get_int('theme_list', -1)))
        item.add_child(Node.s32_array('marker_list', profile.get_int_array('marker_list', 2, [-1] * 2)))
        item.add_child(Node.s32_array('parts_list', profile.get_int_array('parts_list', 96, [-1] * 96)))

        new = Node.void('new')
        item.add_child(new)
        new.add_child(Node.s32_array(
            'secret_list',
            profile.get_int_array(
                'secret_list_new',
                32,
                [-1] * 32,
            ),
        ))
        new.add_child(Node.s32_array(
            'title_list',
            profile.get_int_array(
                'title_list_new',
                96,
                [-1] * 96,
            ),
        ))
        new.add_child(Node.s16('theme_list', profile.get_int('theme_list_new', -1)))
        new.add_child(Node.s32_array('marker_list', profile.get_int_array('marker_list_new', 2, [-1] * 2)))

        # Last played data, for showing cursor and such
        lastdict = profile.get_dict('last')
        last = Node.void('last')
        player.add_child(last)
        last.add_child(Node.s32('music_id', lastdict.get_int('music_id')))
        last.add_child(Node.s8('marker', lastdict.get_int('marker')))
        last.add_child(Node.s16('title', lastdict.get_int('title')))
        last.add_child(Node.s8('theme', lastdict.get_int('theme')))
        last.add_child(Node.s8('sort', lastdict.get_int('sort')))
        last.add_child(Node.s8('rank_sort', lastdict.get_int('rank_sort')))
        last.add_child(Node.s8('combo_disp', lastdict.get_int('combo_disp')))
        last.add_child(Node.s8('seq_id', lastdict.get_int('seq_id')))
        last.add_child(Node.s16('parts', lastdict.get_int('parts')))
        last.add_child(Node.s8('category', lastdict.get_int('category')))
        last.add_child(Node.s64('play_time', lastdict.get_int('play_time')))
        last.add_child(Node.string('shopname', lastdict.get_str('shopname')))
        last.add_child(Node.string('areaname', lastdict.get_str('areaname')))
        last.add_child(Node.s8('expert_option', lastdict.get_int('expert_option')))
        last.add_child(Node.s8('matching', lastdict.get_int('matching')))
        last.add_child(Node.s8('hazard', lastdict.get_int('hazard')))
        last.add_child(Node.s8('hard', lastdict.get_int('hard')))

        # Miscelaneous crap
        player.add_child(Node.s32('session_id', 1))
        player.add_child(Node.u64('event_flag', 0))

        # Macchiato event
        macchiatodict = profile.get_dict('macchiato')
        macchiato = Node.void('macchiato')
        player.add_child(macchiato)
        macchiato.add_child(Node.s32('pack_id', macchiatodict.get_int('pack_id')))
        macchiato.add_child(Node.u16('bean_num', macchiatodict.get_int('bean_num')))
        macchiato.add_child(Node.s32('daily_milk_num', macchiatodict.get_int('daily_milk_num')))
        macchiato.add_child(Node.bool('is_received_daily_milk', macchiatodict.get_bool('is_received_daily_milk')))
        macchiato.add_child(Node.s32('today_tune_cnt', macchiatodict.get_int('today_tune_cnt')))
        macchiato.add_child(Node.s32_array(
            'daily_milk_bonus',
            macchiatodict.get_int_array('daily_milk_bonus', 9, [-1, -1, -1, -1, -1, -1, -1, -1, -1]),
        ))
        macchiato.add_child(Node.s32('daily_play_burst', macchiatodict.get_int('daily_play_burst')))
        macchiato.add_child(Node.bool('sub_menu_is_completed', macchiatodict.get_bool('sub_menu_is_completed')))
        macchiato.add_child(Node.s32('compensation_milk', macchiatodict.get_int('compensation_milk')))
        macchiato.add_child(Node.s32('match_cnt', macchiatodict.get_int('match_cnt')))

        # Probably never will support this
        macchiato_music_list = Node.void('macchiato_music_list')
        macchiato.add_child(macchiato_music_list)
        macchiato_music_list.set_attribute('count', '0')

        # Same with this comment
        macchiato.add_child(Node.s32('sub_pack_id', 0))
        sub_macchiato_music_list = Node.void('sub_macchiato_music_list')
        macchiato.add_child(sub_macchiato_music_list)
        sub_macchiato_music_list.set_attribute('count', '0')

        # And this
        season_music_list = Node.void('season_music_list')
        macchiato.add_child(season_music_list)
        season_music_list.set_attribute('count', '0')

        # Weird, this is sent as a void with a bunch of subnodes, but returned as an int array.
        achievement_list = Node.void('achievement_list')
        macchiato.add_child(achievement_list)
        achievement_list.set_attribute('count', '0')

        # Also probably never supporting this either
        cow_list = Node.void('cow_list')
        macchiato.add_child(cow_list)
        cow_list.set_attribute('count', '0')

        # No news, ever.
        news = Node.void('news')
        player.add_child(news)
        news.add_child(Node.s16('checked', 0))

        # No rival support, yet.
        rivallist = Node.void('rivallist')
        player.add_child(rivallist)
        rivallist.set_attribute('count', '0')

        # Full combo daily challenge.
        entry = self.data.local.game.get_time_sensitive_settings(self.game, self.version, 'fc_challenge')
        if entry is None:
            entry = ValidatedDict()

        # Figure out if we've played these songs
        start_time, end_time = self.data.local.network.get_schedule_duration('daily')
        today_attempts = self.data.local.music.get_all_attempts(self.game, self.version, userid, entry.get_int('today', -1), timelimit=start_time)
        whim_attempts = self.data.local.music.get_all_attempts(self.game, self.version, userid, entry.get_int('whim', -1), timelimit=start_time)

        challenge = Node.void('challenge')
        player.add_child(challenge)
        today = Node.void('today')
        challenge.add_child(today)
        today.add_child(Node.s32('music_id', entry.get_int('today', -1)))
        today.add_child(Node.u8('state', 0x40 if len(today_attempts) > 0 else 0x0))
        whim = Node.void('whim')
        challenge.add_child(whim)
        whim.add_child(Node.s32('music_id', entry.get_int('whim', -1)))
        whim.add_child(Node.u8('state', 0x40 if len(whim_attempts) > 0 else 0x0))

        # Sane defaults for unknown nodes
        only_now_music = Node.void('only_now_music')
        player.add_child(only_now_music)
        only_now_music.set_attribute('count', '0')
        lab_edit_seq = Node.void('lab_edit_seq')
        player.add_child(lab_edit_seq)
        lab_edit_seq.set_attribute('count', '0')
        kac_music = Node.void('kac_music')
        player.add_child(kac_music)
        kac_music.set_attribute('count', '0')
        history = Node.void('history')
        player.add_child(history)
        history.set_attribute('count', '0')
        share_music = Node.void('share_music')
        player.add_child(share_music)
        share_music.set_attribute('count', '0')
        bonus_music = Node.void('bonus_music')
        player.add_child(bonus_music)
        bonus_music.set_attribute('count', '0')

        bingo = Node.void('bingo')
        player.add_child(bingo)
        reward = Node.void('reward')
        bingo.add_child(reward)
        reward.add_child(Node.s32('total', 0))
        reward.add_child(Node.s32('point', 0))
        group = Node.void('group')
        player.add_child(group)
        group.add_child(Node.s32('group_id', 0))

        # Basic profile info
        player.add_child(Node.string('name', profile.get_str('name', 'なし')))
        player.add_child(Node.s32('jid', profile.get_int('extid')))
        player.add_child(Node.string('refid', profile.get_str('refid')))

        # Miscelaneous history stuff
        data.add_child(Node.u8('termver', 16))
        data.add_child(Node.u32('season_etime', 0))
        data.add_child(Node.s32_array(
            'white_music_list',
            [
                -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1,
            ],
        ))
        data.add_child(Node.s32_array(
            'open_music_list',
            [
                -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1,
            ],
        ))

        # Unsupported collaboration events with other games
        collabo_info = Node.void('collabo_info')
        data.add_child(collabo_info)

        # Unsupported policy break stuff
        policy_break = Node.void('policy_break')
        collabo_info.add_child(policy_break)
        policy_break.set_attribute('type', '1')
        policy_break.add_child(Node.u8('state', 1))
        policy_break.add_child(Node.bool('is_report_end', False))

        # Unsupported vocaloid stuff
        vocaloid_event = Node.void('vocaloid_event')
        collabo_info.add_child(vocaloid_event)
        vocaloid_event.set_attribute('type', '1')
        vocaloid_event.add_child(Node.u8('state', 0))
        vocaloid_event.add_child(Node.s32('music_id', 0))

        # Unsupported vocaloid stuff
        vocaloid_event2 = Node.void('vocaloid_event2')
        collabo_info.add_child(vocaloid_event2)
        vocaloid_event2.set_attribute('type', '1')
        vocaloid_event2.add_child(Node.u8('state', 0))
        vocaloid_event2.add_child(Node.s32('music_id', 0))

        # Maybe it is possible to turn off internet matching here?
        lab = Node.void('lab')
        data.add_child(lab)
        lab.add_child(Node.bool('is_open', False))
        matching_off = Node.void('matching_off')
        data.add_child(matching_off)
        matching_off.add_child(Node.bool('is_open', True))

        return root
Beispiel #15
0
    def verify_player_write(self, refid: str, extid: int, loc: str,
                            records: List[Dict[str, int]],
                            scores: List[Dict[str, int]]) -> int:
        call = self.call_node()

        player = Node.void('player')
        call.add_child(player)
        player.set_attribute('method', 'write')
        player.add_child(Node.string('rid', refid))
        player.add_child(Node.string('lid', loc))
        player.add_child(Node.u64('begin_time', Time.now() * 1000))
        player.add_child(Node.u64('end_time', Time.now() * 1000))
        pdata = Node.void('pdata')
        player.add_child(pdata)
        base = Node.void('base')
        pdata.add_child(base)
        base.add_child(Node.s32('uid', extid))
        base.add_child(Node.string('name', self.NAME))
        base.add_child(Node.s16('icon_id', 0))
        base.add_child(Node.s16('lv', 1))
        base.add_child(Node.s32('exp', 0))
        base.add_child(Node.s16('mg', 0))
        base.add_child(Node.s16('ap', 0))
        base.add_child(Node.s32('pc', 0))
        base.add_child(Node.s32('uattr', 0))
        con = Node.void('con')
        pdata.add_child(con)
        con.add_child(Node.s32('day', 0))
        con.add_child(Node.s32('cnt', 0))
        con.add_child(Node.s32('total_cnt', 0))
        con.add_child(Node.s32('last', 0))
        con.add_child(Node.s32('now', 0))
        custom = Node.void('custom')
        pdata.add_child(custom)
        custom.add_child(Node.u8('s_gls', 0))
        custom.add_child(Node.u8('bgm_m', 0))
        custom.add_child(Node.u8('st_f', 0))
        custom.add_child(Node.u8('st_bg', 0))
        custom.add_child(Node.u8('st_bg_b', 100))
        custom.add_child(Node.u8('eff_e', 0))
        custom.add_child(Node.u8('se_s', 0))
        custom.add_child(Node.u8('se_s_v', 100))
        custom.add_child(Node.s16('last_music_id', 85))
        custom.add_child(Node.u8('last_note_grade', 0))
        custom.add_child(Node.u8('sort_type', 0))
        custom.add_child(Node.u8('narrowdown_type', 0))
        custom.add_child(Node.bool('is_begginer', False))
        custom.add_child(Node.bool('is_tut', False))
        custom.add_child(Node.s16_array('symbol_chat_0', [0, 1, 2, 3, 4, 5]))
        custom.add_child(Node.s16_array('symbol_chat_1', [0, 1, 2, 3, 4, 5]))
        custom.add_child(Node.u8('gauge_style', 0))
        custom.add_child(Node.u8('obj_shade', 0))
        custom.add_child(Node.u8('obj_size', 0))
        custom.add_child(Node.s16_array('byword', [0, 0]))
        custom.add_child(Node.bool_array('is_auto_byword', [True, True]))
        custom.add_child(Node.bool('is_tweet', False))
        custom.add_child(Node.bool('is_link_twitter', False))
        custom.add_child(Node.s16('mrec_type', 0))
        custom.add_child(Node.s16('card_disp_type', 0))
        custom.add_child(Node.s16('tab_sel', 0))
        custom.add_child(
            Node.s32_array(
                'hidden_param',
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]))
        pdata.add_child(Node.void('released'))
        pdata.add_child(Node.void('rival'))
        pdata.add_child(Node.void('glass'))
        pdata.add_child(Node.void('fav_music_slot'))
        lincle_link_4 = Node.void('lincle_link_4')
        pdata.add_child(lincle_link_4)
        lincle_link_4.add_child(Node.u32('qpro_add', 0))
        lincle_link_4.add_child(Node.u32('glass_add', 0))
        lincle_link_4.add_child(Node.bool('for_iidx_0_0', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0_1', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0_2', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0_3', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0_4', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0_5', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0_6', False))
        lincle_link_4.add_child(Node.bool('for_iidx_0', False))
        lincle_link_4.add_child(Node.bool('for_iidx_1', False))
        lincle_link_4.add_child(Node.bool('for_iidx_2', False))
        lincle_link_4.add_child(Node.bool('for_iidx_3', False))
        lincle_link_4.add_child(Node.bool('for_iidx_4', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_0', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_1', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_2', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_3', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_4', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_5', False))
        lincle_link_4.add_child(Node.bool('for_rb_0_6', False))
        lincle_link_4.add_child(Node.bool('for_rb_0', False))
        lincle_link_4.add_child(Node.bool('for_rb_1', False))
        lincle_link_4.add_child(Node.bool('for_rb_2', False))
        lincle_link_4.add_child(Node.bool('for_rb_3', False))
        lincle_link_4.add_child(Node.bool('for_rb_4', False))

        # First, filter down to only records that are also in the battle log
        def key(thing: Dict[str, int]) -> str:
            return f'{thing["id"]}-{thing["chart"]}'

        updates = [key(score) for score in scores]
        sortedrecords = {
            key(record): record
            for record in records if key(record) in updates
        }

        # Now, see what records need updating and update them
        for score in scores:
            if key(score) in sortedrecords:
                # Had a record, need to merge
                record = sortedrecords[key(score)]
            else:
                # First time playing
                record = {
                    'clear_type': 0,
                    'achievement_rate': 0,
                    'score': 0,
                    'combo': 0,
                    'miss_count': 999999999,
                }

            sortedrecords[key(score)] = {
                'id':
                score['id'],
                'chart':
                score['chart'],
                'clear_type':
                max(record['clear_type'], score['clear_type']),
                'achievement_rate':
                max(record['achievement_rate'], score['achievement_rate']),
                'score':
                max(record['score'], score['score']),
                'combo':
                max(record['combo'], score['combo']),
                'miss_count':
                min(record['miss_count'], score['miss_count']),
            }

        # Finally, send the records and battle logs
        recordnode = Node.void('record')
        pdata.add_child(recordnode)
        blog = Node.void('blog')
        pdata.add_child(blog)

        for (_, record) in sortedrecords.items():
            rec = Node.void('rec')
            recordnode.add_child(rec)
            rec.add_child(Node.u16('mid', record['id']))
            rec.add_child(Node.u8('ng', record['chart']))
            rec.add_child(Node.s32('point', 2))
            rec.add_child(Node.s32('played_time', Time.now()))
            mrec_0 = Node.void('mrec_0')
            rec.add_child(mrec_0)
            mrec_0.add_child(Node.s32('win', 1))
            mrec_0.add_child(Node.s32('lose', 0))
            mrec_0.add_child(Node.s32('draw', 0))
            mrec_0.add_child(Node.u8('ct', record['clear_type']))
            mrec_0.add_child(Node.s16('ar', record['achievement_rate']))
            mrec_0.add_child(Node.s32('bs', record['score']))
            mrec_0.add_child(Node.s16('mc', record['combo']))
            mrec_0.add_child(Node.s16('bmc', record['miss_count']))
            mrec_1 = Node.void('mrec_1')
            rec.add_child(mrec_1)
            mrec_1.add_child(Node.s32('win', 0))
            mrec_1.add_child(Node.s32('lose', 0))
            mrec_1.add_child(Node.s32('draw', 0))
            mrec_1.add_child(Node.u8('ct', 0))
            mrec_1.add_child(Node.s16('ar', 0))
            mrec_1.add_child(Node.s32('bs', 0))
            mrec_1.add_child(Node.s16('mc', 0))
            mrec_1.add_child(Node.s16('bmc', -1))

        scoreid = 0
        for score in scores:
            log = Node.void('log')
            blog.add_child(log)
            log.add_child(Node.u8('id', scoreid))
            log.add_child(Node.u16('mid', score['id']))
            log.add_child(Node.u8('ng', score['chart']))
            log.add_child(Node.u8('mt', 0))
            log.add_child(Node.u8('rt', 0))
            log.add_child(Node.s32('ruid', 0))
            myself = Node.void('myself')
            log.add_child(myself)
            myself.add_child(Node.s16('mg', 0))
            myself.add_child(Node.s16('ap', 0))
            myself.add_child(Node.u8('ct', score['clear_type']))
            myself.add_child(Node.s32('s', score['score']))
            myself.add_child(Node.s16('ar', score['achievement_rate']))
            rival = Node.void('rival')
            log.add_child(rival)
            rival.add_child(Node.s16('mg', 0))
            rival.add_child(Node.s16('ap', 0))
            rival.add_child(Node.u8('ct', 2))
            rival.add_child(Node.s32('s', 177))
            rival.add_child(Node.s16('ar', 500))
            log.add_child(Node.s32('time', Time.now()))
            scoreid = scoreid + 1

        # Swap with server
        resp = self.exchange('', call)

        # Verify that response is correct
        self.assert_path(resp, "response/player/uid")
        self.assert_path(resp, "response/player/time")
        return resp.child_value('player/uid')
Beispiel #16
0
    def verify_player_rb4write(
        self,
        refid: str,
        loc: str,
        scores: List[Dict[str, int]] = [],
        episodes: List[Dict[str, Any]] = [],
    ) -> int:
        call = self.call_node()

        player = Node.void('player')
        call.add_child(player)
        player.set_attribute('method', 'rb4write')
        pdata = Node.void('pdata')
        player.add_child(pdata)
        account = Node.void('account')
        pdata.add_child(account)
        account.add_child(Node.s32('usrid', 0))
        account.add_child(Node.s32('plyid', 0))
        account.add_child(Node.s32('tpc', 1))
        account.add_child(Node.s32('dpc', 1))
        account.add_child(Node.s32('crd', 1))
        account.add_child(Node.s32('brd', 1))
        account.add_child(Node.s32('tdc', 1))
        account.add_child(Node.string('rid', refid))
        account.add_child(Node.string('lid', loc))
        account.add_child(Node.u8('wmode', 0))
        account.add_child(Node.u8('gmode', 0))
        account.add_child(Node.s16('ver', 1))
        account.add_child(Node.bool('pp', False))
        account.add_child(Node.bool('ps', False))
        account.add_child(Node.s16('pay', 0))
        account.add_child(Node.s16('pay_pc', 0))
        account.add_child(Node.u64('st', int(time.time() * 1000)))
        account.add_child(Node.u8('debutVer', 3))
        account.add_child(Node.s32('upper_pt', 0))
        account.add_child(Node.s32('upper_op', -1))
        base = Node.void('base')
        pdata.add_child(base)
        base.add_child(Node.string('name', self.NAME))
        base.add_child(Node.s32('exp', 0))
        base.add_child(Node.s32('lv', 1))
        base.add_child(Node.s32('mg', -1))
        base.add_child(Node.s32('ap', -1))
        base.add_child(Node.s32('money', 0))
        base.add_child(Node.bool('is_tut', False))
        base.add_child(Node.s32('class', -1))
        base.add_child(Node.s32('class_ar', 0))
        base.add_child(Node.s32('upper_pt', 0))
        stglog = Node.void('stglog')
        pdata.add_child(stglog)

        index = 0
        for score in scores:
            log = Node.void('log')
            stglog.add_child(log)
            log.add_child(Node.s8('stg', index))
            log.add_child(Node.s16('mid', score['id']))
            log.add_child(Node.s8('ng', score['chart']))
            log.add_child(Node.s8('col', 1))
            log.add_child(Node.s8('mt', 0))
            log.add_child(Node.s8('rt', 0))
            log.add_child(Node.s8('ct', score['clear_type']))
            log.add_child(Node.s16('param', score['combo_type']))
            log.add_child(Node.s16('grd', 0))
            log.add_child(Node.s16('ar', score['achievement_rate']))
            log.add_child(Node.s16('sc', score['score']))
            log.add_child(Node.s16('jt_jst', 0))
            log.add_child(Node.s16('jt_grt', 0))
            log.add_child(Node.s16('jt_gd', 0))
            log.add_child(Node.s16('jt_ms', score['miss_count']))
            log.add_child(Node.s16('jt_jr', 0))
            log.add_child(Node.s32('r_uid', 0))
            log.add_child(Node.s32('r_plyid', 0))
            log.add_child(Node.s8('r_stg', 0))
            log.add_child(Node.s8('r_ct', -1))
            log.add_child(Node.s16('r_sc', 0))
            log.add_child(Node.s16('r_grd', 0))
            log.add_child(Node.s16('r_ar', 0))
            log.add_child(Node.s8('r_cpuid', -1))
            log.add_child(Node.s32('time', int(time.time())))
            log.add_child(Node.s8('decide', 0))
            log.add_child(Node.s8('hazard', 0))
            index = index + 1

        episode = Node.void('episode')
        pdata.add_child(episode)
        for ep in episodes:
            info = Node.void('info')
            episode.add_child(info)
            info.add_child(Node.s32('user_id', ep['user']))
            info.add_child(Node.u8('type', ep['id']))
            info.add_child(Node.u16('value0', ep['values'][0]))
            info.add_child(Node.u16('value1', ep['values'][1]))
            info.add_child(Node.string('text', ep['text']))
            info.add_child(Node.s32('time', ep['time']))

        # Swap with server
        resp = self.exchange('', call)

        # Verify that response is correct
        self.assert_path(resp, "response/player/uid")
        return resp.child_value('player/uid')