Пример #1
0
    async def process(self, packet: bytes):
        if not self.header_crypt:
            raise Exception('Cannot decrypt packet')

        # this is workaround cause one-time decryption do not works correctly for some opcodes
        # so I need decrypt some packets for multiple times
        def decrypt(packet: bytes):
            result = packet
            for index in range(20):
                enc = self.header_crypt.decrypt(packet)
                try:
                    # TODO: add has_key for Enum
                    WorldOpCode(int.from_bytes(enc[2:6], 'little')).value
                except ValueError:
                    continue
                else:
                    result = enc
                    break

            return result

        packet = decrypt(packet)

        size = unpack('>H', packet[:2])[0]
        opcode = WorldOpCode(unpack('<I', packet[2:6])[0])

        if opcode in HANDLERS:
            Logger.debug(
                '[World Packet]: processing {} opcode ({} bytes)'.format(
                    WorldOpCode(opcode).name, size))
            handlers = HANDLERS[opcode]
            packets = list()

            for handler in handlers:
                opcode, response = await handler(
                    packet,
                    temp_ref=self.temp_ref,
                    reader=self.reader,
                    writer=self.writer,
                    header_crypt=self.header_crypt).process()
                if opcode and response:
                    packets.append(
                        WorldPacketManager.generate_packet(
                            opcode, response, self.header_crypt))

            return packets
        else:
            try:
                Logger.warning(
                    '[World Packet]: no handler for opcode = {} ({} bytes)'.
                    format(WorldOpCode(opcode).name, size))
            except ValueError:
                Logger.error(
                    '[World Packet]: no handler for unknown opcode = {} ({} bytes)'
                    .format(opcode, size))
            finally:
                return None
Пример #2
0
    async def run(self):
        while True:
            self.last_update = Timer.get_ms_time()

            try:
                await asyncio.wait_for(self.update(), timeout=1.0)
            except TimeoutError:
                Logger.warning('[World Manager]: Timeout...')
            finally:
                await asyncio.sleep(self.heartbeat)
Пример #3
0
    async def handle_connection(self, websocket: WebSocketCommonProtocol, path):
        self._register_tasks(websocket=websocket)

        while True:
            try:
                response = {'type': 'REGIONS_FETCH_LIST_RESPONSE', 'payload': self.web_data}
                await websocket.send(json.dumps(response))
            except ConnectionClosedOK:
                Logger.error('[Websocket Server]: Connection was closed')
                return
            except Exception as e:
                Logger.error('[Websocket Server]: {}'.format(e))
                Logger.warning(self.web_data)
                traceback.print_exc()
                continue
            finally:
                await asyncio.sleep(1)
Пример #4
0
    def add(self, field, value, offset=0):
        try:
            field_type = FIELD_TYPE_MAP[field]
        except KeyError:
            Logger.error(
                '[UpdatePacket Block Builder]: no type associated with {}'.
                format(str(field)))
            return
        else:
            field_struct = self.FIELD_BIN_MAP[field_type]
            index = offset and (field.value + offset) or field
            field_index = UpdateBlocksBuilder._get_field_index(index)

            self._set_field_mask_bits(field_index, field_struct)
            try:
                self._set_field_value(field_index, field_struct, value)
            except StructError:
                Logger.warning(
                    'Field with index {} should be set'.format(field_index))
                pass
Пример #5
0
def process():
    parser = argparse.ArgumentParser(prog='cmd')
    commands = parser.add_subparsers(help='Available console commands')

    # database
    db_parser = commands.add_parser('db')

    args = db_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'db':
        if subcommand == 'create':
            create_db()
            Logger.success('All dbs was created')

        elif subcommand == 'create_tables':
            create_tables()
            Logger.success('All required tables was created')

        elif subcommand == 'drop':
            drop_db()
            Logger.warning('All db was dropped')

        elif subcommand == 'recreate':
            drop_db()
            create_db()
            create_tables()
            Logger.notify('DB was successfully re-created')

        elif subcommand == 'load_data':
            load_world_data()

        elif subcommand == 'recreate_with_load':
            drop_db()
            create_db()
            create_tables()
            Logger.notify('DB was successfully re-created')
            load_world_data()

    # accounts
    account_parser = commands.add_parser('account')
    account_parser.add_argument('-n', '--name')
    account_parser.add_argument('-p', '--password')

    args = account_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'account':
        if subcommand == 'create':
            with AccountManager() as account_mgr:
                account_mgr.create(name=args[0].name,
                                   password=args[0].password)
                Logger.success('Account "{}" created successfully!'.format(
                    args[0].name))

    # items
    item_parser = commands.add_parser('item')
    item_parser.add_argument('-d', '--display_id')
    item_parser.add_argument('-i', '--item_type')
    item_parser.add_argument('-e', '--entry')

    args = item_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'item':
        if subcommand == 'create':
            with ItemManager() as item_mgr:
                item_mgr.create(display_id=args[0].display_id,
                                item_type=args[0].item_type,
                                entry=int(args[0].entry)).save()

                Logger.success('Item "{}" created successfully!'.format(
                    args[0].entry))

    # spells
    spell_parser = commands.add_parser('spell')
    spell_parser.add_argument('-e', '--entry')
    spell_parser.add_argument('-n', '--name')
    spell_parser.add_argument('-c', '--cost')
    spell_parser.add_argument('-s', '--school')
    spell_parser.add_argument('-r', '--range')

    args = spell_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'spell':
        if subcommand == 'create':
            SpellManager().create(entry=args[0].entry,
                                  name=args[0].name,
                                  cost=args[0].cost,
                                  school=args[0].school,
                                  range=args[0].range).save()

            Logger.test('Spell "{}" ({}) created successfully!'.format(
                args[0].name, args[0].entry))

    # default spells
    default_spell_parser = commands.add_parser('default_spell')
    default_spell_parser.add_argument('-e', '--entry')
    default_spell_parser.add_argument('-r', '--race')
    default_spell_parser.add_argument('-c', '--char_class')

    args = default_spell_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'default_spell':
        if subcommand == 'create':
            SpellManager().create_default_spell(
                entry=args[0].entry,
                race=args[0].race,
                char_class=args[0].char_class).save()

            Logger.test(
                'Default spell "{}" ({}:{}) created successfully!'.format(
                    args[0].entry, args[0].race, args[0].char_class))

    # skills
    # skill_parser = commands.add_parser('skill')
    # skill_parser.add_argument('-e', '--entry')
    # skill_parser.add_argument('-n', '--name')
    #
    # args = skill_parser.parse_known_args()
    # parser_name = args[1][0]
    # subcommand = args[1].pop()
    #
    # if parser_name == 'skill':
    #     if subcommand == 'create':
    #         SkillManager().create(
    #             entry=args[0].entry,
    #             name=args[0].name
    #         ).save()
    #
    #         Logger.test('Skill "{}" ({}) created successfully!'.format(args[0].name, args[0].entry))

    # skills
    skill_parser = commands.add_parser('skill')
    skill_parser.add_argument('-e', '--entry')
    skill_parser.add_argument('-n', '--name')
    skill_parser.add_argument('--min')
    skill_parser.add_argument('--max')

    args = skill_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'skill':
        if subcommand == 'create':
            SkillManager().create(entry=args[0].entry,
                                  name=args[0].name,
                                  min=args[0].min,
                                  max=args[0].max).save()

            Logger.success('Skill "{}" ({}) created successfully!'.format(
                args[0].name, args[0].entry))

    # default skills
    default_skill_parser = commands.add_parser('default_skill')
    default_skill_parser.add_argument('-e', '--entry')
    default_skill_parser.add_argument('-r', '--race')
    default_skill_parser.add_argument('-c', '--char_class')

    args = default_skill_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'default_skill':
        if subcommand == 'create':
            SkillManager().create_default_skill(
                entry=args[0].entry,
                race=args[0].race,
                char_class=args[0].char_class).save()

            Logger.success(
                'Default skill "{}" ({}:{}) created successfully!'.format(
                    args[0].entry, args[0].race, args[0].char_class))

    # regions
    region_parser = commands.add_parser('region')
    region_parser.add_argument('-i', '--identifier')
    region_parser.add_argument('--y1')
    region_parser.add_argument('--y2')
    region_parser.add_argument('--x1')
    region_parser.add_argument('--x2')
    region_parser.add_argument('-c', '--continent_id')

    # # arguments for default region
    region_parser.add_argument('-r', '--race')
    region_parser.add_argument('-m', '--map_id')

    # # arguments for region unit # #
    region_parser.add_argument('-u', '--unit_entry')

    # # arguments for both default region and region unit
    region_parser.add_argument('-x')
    region_parser.add_argument('-y')
    region_parser.add_argument('-z')

    args = region_parser.parse_known_args()
    parser_name = args[1][0]
    subcommand = args[1].pop()

    if parser_name == 'region':
        if subcommand == 'create':
            with RegionManager() as region_mgr:
                region_mgr.create(
                    identifier=args[0].identifier,
                    y1=args[0].y1,
                    y2=args[0].y2,
                    x1=args[0].x1,
                    x2=args[0].x2,
                    continent_id=args[0].continent_id,
                ).save()

                Logger.notify('Region "{}" created successfully!'.format(
                    args[0].identifier))

        elif subcommand == 'add_default_location':
            with RegionManager() as region_mgr:
                region_mgr.create_default_location(
                    identifier=args[0].identifier,
                    x=args[0].x,
                    y=args[0].y,
                    z=args[0].z,
                    race=args[0].race,
                    map_id=args[0].map_id)

                Logger.success(
                    'Default location ({}) for race "{}" successfully added'.
                    format(args[0].identifier, args[0].race))

        elif subcommand == 'add_unit':
            with UnitManager() as unit_mgr:
                unit_mgr.new(entry=args[0].unit_entry,
                             identifier=args[0].identifier,
                             x=args[0].x,
                             y=args[0].y,
                             z=args[0].z).set_stats().save()

                Logger.notify(
                    'Unit "{}" IN ({} - {} - {}) created successfully!'.format(
                        args[0].unit_entry, args[0].x, args[0].y, args[0].z))