Exemplo n.º 1
0
    async def _check_session_key(self):
        Logger.info('[Auth Session Manager]: checking session key')
        session_key = await RedisConnection.create().get('#{}-session-key'.format(self.account_name))
        if not session_key:
            raise Exception('Session key does not exists')

        self.session_key = b64decode(session_key)
Exemplo n.º 2
0
 def run():
     Logger.info('[Web Server]: init')
     app = web.Application()
     app.router.add_routes([web.get('/', WebServer.websocket_handler)])
     web.run_app(app,
                 host=Config.WebServer.Connection.host,
                 port=Config.WebServer.Connection.port)
Exemplo n.º 3
0
    async def process(self) -> tuple:
        data = self._parse_packet()

        try:
            with PlayerManager() as player_mgr:
                player_mgr.new(name=data['name'],
                               race=data['race'],
                               char_class=data['char_class'],
                               gender=data['gender'],
                               skin=data['skin'],
                               face=data['face'],
                               hair_style=data['hair_style'],
                               hair_color=data['hair_color'],
                               facial_hair=data['facial_hair'],
                               account=self.connection.account)

                Logger.notify(f'Character \"{data["name"]}\" created')

                response = pack(
                    '<B', CharCreateResponseCode.CHAR_CREATE_SUCCESS.value)
                return WorldOpCode.SMSG_CHAR_CREATE, [response]

        except IntegrityError:
            response = pack(
                '<B', CharCreateResponseCode.CHAR_CREATE_NAME_IN_USE.value)
            return WorldOpCode.SMSG_CHAR_CREATE, [response]
Exemplo n.º 4
0
    async def authenticate_on_login_server(self):
        while True:
            try:
                request = await asyncio.wait_for(self.reader.read(1024),
                                                 timeout=0.01)
                if request:
                    opcode, packet = request[0], request[1:]
                    try:
                        handler = AuthManager.AUTH_HANDLERS[LoginOpCode(
                            opcode)]
                    except ValueError:
                        Logger.error(
                            '[AuthManager]: Incorrect request, check the opcode'
                        )
                        pass
                    else:
                        response = await handler(
                            packet=packet,
                            srp=self.srp,
                            temp_ref=self.temp_ref).process()

                        if response:
                            self.writer.write(response)
            except TimeoutError:
                pass
            finally:
                await asyncio.sleep(0.01)
Exemplo n.º 5
0
    async def send_update_packet_to_player(self):
        while True:
            try:
                player_name, update_packets = await asyncio.wait_for(
                    QueuesRegistry.update_packets_queue.get(), timeout=0.01)
            except TimeoutError:
                pass
            else:
                try:
                    writer = self.connections[player_name]['writer']
                    header_crypt = self.connections[player_name][
                        'header_crypt']
                except KeyError:
                    # on login step player object not registered in self.connections,
                    # just ignore
                    pass
                else:
                    try:
                        for update_packet in update_packets:
                            response = WorldPacketManager.generate_packet(
                                opcode=WorldOpCode.SMSG_UPDATE_OBJECT,
                                data=update_packet,
                                header_crypt=header_crypt)
                            Logger.test(
                                'Send update packet to {}'.format(player_name))
                            writer.write(response)
                            await writer.drain()
                    except BrokenPipeError:
                        del self.connections[player_name]

                    except ConnectionResetError:
                        del self.connections[player_name]
            finally:
                await asyncio.sleep(0.01)
Exemplo n.º 6
0
    async def process(self):
        Logger.debug('[Login Challenge]: processing')
        self._parse_data()

        try:
            with AccountManager() as account_mgr:
                account = account_mgr.get(name=self.account_name).account

                if account is None:
                    raise Exception('Account \'{}\' is not found'.format(self.account_name))

                account.os = self.os
                account.ip = '.'.join([str(i) for i in self.ip_addr])
                account.platform = self.platform
                account.timezone = self.timezone
                account.locale = self.locale

                account_mgr.update()

                self.account = account
                self.temp_ref.account = account

        # TODO: define account exceptions
        except Exception as e:
            Logger.error('[Login Challenge]: error = {}'.format(e))
            return None
        finally:
            return self._get_response()
Exemplo n.º 7
0
def load_world_data():
    def get_command(db_name):
        return 'mysql -h{host} -u"{username}" -p"{password}" -D"{db_name}"'.format(
            host=Config.Database.Connection.host,
            username=Config.Database.Connection.username,
            password=Config.Database.Connection.password,
            db_name=db_name)

    for key in MAP_DIRNAME_TO_DBNAME.keys():

        files = []

        command = get_command(db_name=MAP_DIRNAME_TO_DBNAME[key]['db_name'])

        fixture_dir = MAP_DIRNAME_TO_DBNAME[key]['dir_name']

        for (dirpath, _,
             filenames) in walk('DB/Fixtures/{}'.format(fixture_dir)):
            filenames.sort()
            for file in filenames:
                files.append(path.join(dirpath, file))

        for file in files:
            Logger.notify('Start loading {}'.format(file))
            subprocess.run('{} < {}'.format(command, file), shell=True)
            Logger.success('{} successfully imported'.format(file))
Exemplo n.º 8
0
 def _setup_encryption(self):
     Logger.info('[Auth Manager]: setup encryption')
     try:
         header_crypt = HeaderCrypt(self.session_key)
     except Exception as e:
         raise Exception('[Auth Manager]: error on setup encryption = {}'.format(e))
     else:
         self.world_packet_manager.set_header_crypt(header_crypt)
Exemplo n.º 9
0
 def send_auth_challenge(self):
     # auth seed need to generate header_crypt
     Logger.info('[Auth Manager]: sending auth challenge')
     self.auth_seed = int.from_bytes(urandom(4), 'little')
     auth_seed_bytes = pack('<I', self.auth_seed)
     # TODO: make it like standard request handler
     response = WorldPacketManager.generate_packet(WorldOpCode.SMSG_AUTH_CHALLENGE, auth_seed_bytes)
     self.writer.write(response)
Exemplo n.º 10
0
 def _get_response(self):
     try:
         response = pack('<2B20sQ2B', LoginOpCode.LOGIN_PROOF.value,
                         LoginResult.SUCCESS.value, self.srp.server_proof,
                         0x00800000, 0x00, 0x00)
     except Exception as e:
         Logger.error('[Login Proof]: {}'.format(e))
     else:
         return response
Exemplo n.º 11
0
 def _parse_data(self):
     try:
         parsed_data = unpack(LoginProof.LOGIN_PROOF_FORMAT, self.packet)
         self.client_ephemeral = int.from_bytes(parsed_data[0], 'little')
         self.client_proof = parsed_data[1]
         self.checksum = parsed_data[2]
         self.unk = parsed_data[3]
     except StructError as e:
         Logger.error('[Login Proof]: on unpacking data(len={}), error={}'.format(len(self.packet), StructError))
Exemplo n.º 12
0
    async def handle_connection(self, reader: StreamReader, writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.info('[Login Server]: Accepted connection from {}'.format(peername))

        temp_ref = TempRef()

        auth = AuthManager(reader, writer, temp_ref=temp_ref)
        await auth.process(step=AuthStep.FIRST)
        writer.close()
Exemplo n.º 13
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)
Exemplo n.º 14
0
    def delete(self, **kwargs):
        if kwargs:
            try:
                self.session.query(Account).filter_by(**kwargs).delete()
            except Exception as e:
                Logger.error(
                    '[AccountManager]: Error has occured on account delete, {}'
                    .format(e))

        return self
Exemplo n.º 15
0
    def get(self, **kwargs):
        if kwargs:
            try:
                self.account = self.session.query(Account).filter_by(
                    **kwargs).first()
            except Exception as e:
                Logger.error(
                    '[AccountManager]: Error has occured, account will be None, error: {}'
                    .format(e))

        return self
Exemplo n.º 16
0
    def set_default_equipment(self):
        self.session.expunge(self.player.region)
        self.session.expunge(self.player.account)
        self.session.expunge(self.player)

        with EquipmentManager() as equipment_mgr:
            try:
                self.equipment = equipment_mgr.set_default_equipment(
                    player=self.player).get_items()
            except Exception as e:
                Logger.error('[PlayerMgr]: equipment error = {}'.format(e))
Exemplo n.º 17
0
    def _generate_server_hash(self):
        Logger.info(
            '[Auth Session Manager]: generating server hash for account "{}"'.
            format(self.account_name))

        to_hash = (self.account_name.encode('ascii') + bytes(4) +
                   self.client_seed +
                   int.to_bytes(self.auth_seed, 4, 'little') +
                   self.session_key)

        self.server_hash = sha1(to_hash).digest()
Exemplo n.º 18
0
    def guid(self):
        _guid = self.id

        if hasattr(self, 'low_guid'):
            Logger.test('has low guid')
            _guid = self.low_guid | (self.high_guid << 48)

            if bool(self.entry):
                _guid = (self.low_guid | (self.entry << 24) |
                         (self.high_guid << 48))

        return _guid
Exemplo n.º 19
0
    def _parse_account_name(buffer: BytesIO):
        Logger.info('[Character Create]: parsing account name')
        result = bytes()

        while True:
            char = buffer.read(1)
            if char and char != b'\x00':
                result += char
            else:
                break

        return result.decode('utf-8')
Exemplo n.º 20
0
    async def process(self):
        region_id = unpack('<I', self.packet[-4:])[0]

        if not self.temp_ref.player.region.region_id == region_id:
            region = RegionManager().get_region(region_id=region_id)
            self.temp_ref.player.region = region

            player_mgr = PlayerManager()
            player_mgr.set(self.temp_ref.player).save()
            Logger.notify('[Zone Update]: saving player')

        return None, None
Exemplo n.º 21
0
    async def process(self):
        self._load_player()

        if not self.temp_ref.player:
            Logger.error('[Player Init]: player not exists')
            raise PlayerNotExists

        await QueuesRegistry.connections_queue.put(
            (self.temp_ref.player.name, self.reader, self.writer,
             self.header_crypt))
        await QueuesRegistry.players_queue.put(self.temp_ref.player)

        return None, None
Exemplo n.º 22
0
    async def process(self) -> tuple:
        # identifier = unpack('<I', self.data[-4:])[0]
        identifier = unpack('<I', self.data[:4])[0]

        if not self.connection.player.region.identifier == identifier:
            region = RegionManager().get_region(identifier=identifier)
            self.connection.player.region = region

            with PlayerManager() as player_mgr:
                player_mgr.set(self.connection.player).save()
                Logger.notify('[Zone Update]: saving player')

        return None, None
Exemplo n.º 23
0
    def _check_session_key(self):
        Logger.info('[Auth Session Manager]: checking session key')
        key = '#{}-session-key'.format(self.account_name)

        try:
            session_key = self.session_keys[key]
        except KeyError:
            Logger.error('[AuthMgr]: session with this key does not exists')
            self.writer.close()
        else:
            if not session_key:
                raise Exception('[AuthMgr]: Session key does not exists')

            self.session_key = b64decode(session_key)
Exemplo n.º 24
0
 async def remove_connection(self):
     while True:
         try:
             player_name = QueuesRegistry.disconnect_queue.get_nowait()
         except asyncio.QueueEmpty:
             pass
         else:
             if player_name and self.connections and player_name in self.connections:
                 del self.connections[player_name]
                 Logger.info(
                     '[World Server]: player "{}" disconnected'.format(
                         player_name))
         finally:
             await asyncio.sleep(0.01)
Exemplo n.º 25
0
 async def accept_connection(self, websocket: WebSocketCommonProtocol):
     while True:
         try:
             request = await asyncio.wait_for(websocket.recv(), timeout=0.01)
         except TimeoutError:
             pass
         except ConnectionClosedOK:
             return
         else:
             parsed_request = json.loads(request)
             if 'type' in parsed_request and parsed_request['type'] == RequestType.SUBSCRIBE.value:
                 Logger.success('[Websocket Server]: new connection was added, {}'.format(websocket.local_address))
                 self.connections.append(websocket)
         finally:
             await asyncio.sleep(1)
Exemplo n.º 26
0
 async def refresh_connections(self):
     while True:
         try:
             player_name, reader, writer, header_crypt = await asyncio.wait_for(
                 QueuesRegistry.connections_queue.get(), timeout=1.0
             )
         except TimeoutError:
             pass
         else:
             self.connections[player_name] = {
                 'reader': reader,
                 'writer': writer,
                 'header_crypt': header_crypt
             }
             Logger.info('[World Server]: new connection for player "{}"'.format(player_name))
Exemplo n.º 27
0
    def _get_verify_login_packet(self):
        player = self.temp_ref.player

        if not player:
            Logger.error('[Login Verify]: player not exists')
            return None

        return pack(
            '<I4f',
            player.map_id,            # map id
            player.x,                 # x
            player.y,                 # y
            player.z,                 # z
            player.orientation        # orientation
        )
Exemplo n.º 28
0
    def load(self):
        current_dir = path.dirname(__file__)
        main_config = 'Config.yml'

        with open(path.join(current_dir, main_config), 'r') as stream:
            try:
                data = yaml.load(stream, Loader=yaml.Loader)
                self.config = json.loads(
                    json.dumps(data),
                    object_hook=lambda d: namedtuple('Configs', d.keys())
                    (*d.values()))
            except yaml.YAMLError as error:
                Logger.error('[Config Manager]: {}'.format(error))
            else:
                return self
Exemplo n.º 29
0
    async def process(self):
        test_item1 = session.player.equipment.get_object_field(CharacterEquipSlot.BODY)
        test_item2 = session.player.equipment.get_object_field(CharacterEquipSlot.CHEST)
        test_item3 = session.player.equipment.get_object_field(CharacterEquipSlot.LEGS)
        test_item4 = session.player.equipment.get_object_field(CharacterEquipSlot.FEET)

        spawned_item = UpdatePacket(test_item1, ObjectUpdateType.CREATE_OBJECT.value, False)

        for field in self.SPAWN_FIELDS:
            spawned_item.add_field(field, test_item1.get_object_field(field))

        response = spawned_item.update(send_packed_guid=True)

        Logger.error('[ItemSpawn]: {}'.format(response))

        return WorldOpCode.SMSG_UPDATE_OBJECT, response
Exemplo n.º 30
0
    async def refresh_creatures(self):
        for region in self.regions:
            try:
                region_units = region.units.copy()
            except DetachedInstanceError as e:
                Logger.error('[Region Manager]: {}'.format(e))
            else:
                units = region_units.copy()

                # finally building packet for player that contains unit list
                movement_flags = (
                    UpdateObjectFlags.UPDATEFLAG_HIGHGUID.value
                    | UpdateObjectFlags.UPDATEFLAG_LIVING.value
                    | UpdateObjectFlags.UPDATEFLAG_HAS_POSITION.value)

                spawn_dist = Config.World.Gameplay.spawn_dist

                online_players = region.get_online_players()

                if not spawn_dist == 0:
                    for player_name in online_players:
                        player = online_players[player_name]

                        # list of unit managers each ready to build the update packet
                        update_packets = []

                        if spawn_dist > 0:
                            units = [
                                unit for unit in units
                                if RegionManager._is_unit_in_spawn_radius(
                                    unit, player)
                            ]

                        for unit in units:
                            with UnitManager() as unit_mgr:
                                unit_mgr.set(unit)
                                unit_mgr.movement.set_update_flags(
                                    movement_flags)

                                batch_builder = unit_mgr.prepare() \
                                    .build_update_packet(RegionManager.UNIT_SPAWN_FIELDS)

                                update_packets.append(batch_builder)

                        asyncio.ensure_future(
                            QueuesRegistry.update_packets_queue.put(
                                (player.name, update_packets)))