async def handle_connection(self, reader: StreamReader, writer: StreamWriter): temp_ref = TempRef() world_packet_manager = WorldPacketManager(temp_ref=temp_ref, reader=reader, writer=writer) peername = writer.get_extra_info('peername') Logger.debug('[World Server]: Accept connection from {}'.format(peername)) Logger.info('[World Server]: trying to process auth session') auth = AuthManager(reader, writer, temp_ref=temp_ref, world_packet_manager=world_packet_manager) await auth.process(step=AuthStep.SECOND) self._register_tasks() while True: try: request = await asyncio.wait_for(reader.read(4096), timeout=1.0) if request: response = await asyncio.wait_for(world_packet_manager.process(request), timeout=1.0) if response: for packet in response: writer.write(packet) await writer.drain() except TimeoutError: continue except Exception as e: Logger.error('[World Server]: exception, {}'.format(e)) traceback.print_exc() break writer.close()
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)
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)
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)
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)
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()
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()
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')
async def handle_connection(self, reader: StreamReader, writer: StreamWriter): self._register_tasks() temp_ref = TempRef() world_packet_manager = WorldPacketManager(temp_ref=temp_ref, reader=reader, writer=writer) Logger.info('[World Server]: trying to process auth session') auth = AuthManager(reader, writer, temp_ref=temp_ref, world_packet_manager=world_packet_manager, session_keys=self.session_keys) is_authenticated = await auth.process(step=AuthStep.SECOND) if is_authenticated: peer_name = writer.get_extra_info('peername') Logger.success( '[World Server]: Accept connection from {}'.format(peer_name)) while True: try: request = await asyncio.wait_for(reader.read(4096), timeout=0.01) if request: response = await asyncio.wait_for( world_packet_manager.process(request), timeout=0.01) if response: for packet in response: writer.write(packet) await writer.drain() except TimeoutError: pass except BrokenPipeError: pass except Exception as e: Logger.error('[World Server]: exception, {}'.format(e)) traceback.print_exc() break finally: await asyncio.sleep(0.01) writer.close()
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)
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)
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))
def _parse_account_name(self, buffer: BytesIO): Logger.info('[Auth Session Manager]: parsing account name') result = bytes() while True: char = buffer.read(1) if char and char != b'\x00': result += char else: break try: result = result.decode('utf-8') except UnicodeDecodeError: Logger.error('[Auth Session Manager]: decode error, wrong name = {}'.format(result)) else: return result
async def add_connection(self): while True: try: player_name, reader, writer, header_crypt = QueuesRegistry.connections_queue.get_nowait( ) except asyncio.QueueEmpty: pass else: self.connections[player_name] = { 'reader': reader, 'writer': writer, 'header_crypt': header_crypt } Logger.info( '[World Server]: added connection for player "{}"'.format( player_name)) finally: await asyncio.sleep(0.01)
async def handle_connection(self, reader: StreamReader, writer: StreamWriter): peername = writer.get_extra_info('peername') Logger.info( '[Login Server]: Accepted connection from {}'.format(peername)) connection = Connection(reader=reader, writer=writer, peername=peername) world_packet_mgr = WorldPacketManager(connection=connection) while True: try: await LoginServer.process_request(reader, writer, world_packet_mgr) except TimeoutError: continue finally: await asyncio.sleep(Config.Realm.Settings.min_timeout)
def create(): Logger.info('[Login Server]: init') return LoginServer(Config.Realm.Connection.LoginServer.host, Config.Realm.Connection.LoginServer.port)
def create(): Logger.info('[World Server]: init') return WorldServer(Config.Realm.Connection.WorldServer.host, Config.Realm.Connection.WorldServer.port)
def create(): Logger.info('[Websocket Server]: init') return WebsocketServer( Config.WebsocketServer.Connection.host, Config.WebsocketServer.Connection.port )
async def remove_connection(self): while True: player_name: AnyStr = await QueuesRegistry.disconnect_queue.get() if self.connections.get(player_name): del self.connections[player_name] Logger.info('[World Server]: player "{}" disconnected'.format(player_name))
async def add_connection(self): while True: connection: Connection = await QueuesRegistry.connections_queue.get() self.connections[connection.player.name] = connection Logger.info('[World Server]: added connection for player "{}"'.format(connection.player.name)) await sleep(Config.Realm.Settings.min_timeout)