Example #1
0
    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()
Example #2
0
    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()
Example #3
0
    async def broadcast_packets(self):
        while True:
            try:
                player_name, opcode, data = await wait_for(
                    QueuesRegistry.packets_queue.get(),
                    timeout=Config.Realm.Settings.min_timeout
                )
            except TimeoutError:
                pass
            else:
                connection: Connection = self.connections.get(player_name, None)
                if connection:
                    writer: StreamWriter = connection.writer

                    response: bytes = WorldPacketManager(
                        connection=connection
                    ).generate_packet(
                        opcode=opcode,
                        data=data,
                    )

                    writer.write(response)
                    await writer.drain()
            finally:
                await sleep(Config.Realm.Settings.min_timeout)
Example #4
0
    async def send_name_query_packet_to_player(self):
        while True:
            try:
                player_name, name_query_packet = await asyncio.wait_for(
                    QueuesRegistry.name_query_packets_queue.get(),
                    timeout=0.01)
            # except asyncio.QueueEmpty:
            #     pass
            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:
                        response = WorldPacketManager.generate_packet(
                            opcode=WorldOpCode.SMSG_NAME_QUERY_RESPONSE,
                            data=name_query_packet,
                            header_crypt=header_crypt)
                        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)
Example #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)
Example #6
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)
Example #7
0
 def _send_addon_info(self):
     # TODO parse actual addon list from CMSG_AUTH_SESSION and check
     response = b'\x02\x01\x00\x00\x00\x00\x00\x00' * 16
     response = WorldPacketManager.generate_packet(
         opcode=WorldOpCode.SMSG_ADDON_INFO,
         data=response,
         header_crypt=self.world_packet_manager.header_crypt)
     # send this packet to show 'addons' button on Characters screen
     self.writer.write(response)
Example #8
0
    async def handle_connection(self, reader: StreamReader, writer: StreamWriter):
        self._register_tasks()

        connection = Connection(reader=reader, writer=writer, session_keys=self.session_keys)
        world_packet_mgr = WorldPacketManager(connection=connection)

        # send auth challenge
        auth_seed: bytes = urandom(4)
        writer.write(
            world_packet_mgr.generate_packet(
                WorldOpCode.SMSG_AUTH_CHALLENGE,
                auth_seed
            )
        )

        connection.auth_seed = auth_seed

        while True:
            try:
                await WorldServer.process_request(reader, writer, world_packet_mgr)
            except TimeoutError:
                continue
            finally:
                await sleep(Config.Realm.Settings.min_timeout)
Example #9
0
    def _send_auth_response(self):
        # updating session request
        response = pack(
            '<BIBIB',
            ResponseCodes.AUTH_OK.value,
            0x00,  # BillingTimeRemaining
            0x00,  # BillingPlanFlags
            0x00,  # BillingTimeRested
            0x01  # Expansion, 0 - normal, 1 - TBC, must be set manually for each account
        )

        response = WorldPacketManager.generate_packet(
            opcode=WorldOpCode.SMSG_AUTH_RESPONSE,
            data=response,
            header_crypt=self.world_packet_manager.header_crypt)
        self.writer.write(response)
Example #10
0
    async def process_request(reader: StreamReader, writer: StreamWriter,
                              world_packet_mgr: WorldPacketManager):
        request = await asyncio.wait_for(
            reader.read(4096), timeout=Config.Realm.Settings.min_timeout)
        if request:
            opcode, data = request[:1], request[1:]

            if data:
                response = await asyncio.wait_for(
                    world_packet_mgr.process(opcode=opcode, data=data),
                    timeout=Config.Realm.Settings.min_timeout)

                if response:
                    for packet in response:
                        writer.write(packet)
                        await writer.drain()
Example #11
0
    async def send_update_packet_to_player(self):
        while True:
            try:
                player_name, update_packets = await asyncio.wait_for(
                    update_packets_queue.get(), timeout=1.0)
            except TimeoutError:
                pass
            else:
                try:
                    writer = self.connections[player_name]['writer']
                    header_crypt = self.connections[player_name][
                        'header_crypt']
                except KeyError:
                    # do nothing for this because on login step player not saved in self.connections
                    pass
                else:

                    responses = []

                    while update_packets:
                        # batches with chained with this packet
                        head_update_packet_builder = update_packets.pop(0)

                        for index in range(
                                0, WorldServer.MAX_UPDATE_PACKETS_INCLUDED):

                            if not update_packets:
                                break

                            batch = update_packets.pop(0).get_update_packet()
                            head_update_packet_builder.add_batch(batch)

                        update_packet = head_update_packet_builder.get_update_packet(
                            build=True)

                        responses.append(update_packet)

                    for update_packet in responses:
                        response = WorldPacketManager.generate_packet(
                            opcode=WorldOpCode.SMSG_UPDATE_OBJECT,
                            data=update_packet,
                            header_crypt=header_crypt)
                        writer.write(response)
                        await writer.drain()

                finally:
                    await asyncio.sleep(1)
Example #12
0
    async def process_request(reader: StreamReader, writer: StreamWriter, world_packet_mgr: WorldPacketManager):
        request: bytes = await wait_for(reader.read(4096), timeout=Config.Realm.Settings.min_timeout)
        if request:
            size, opcode, data = request[:2], request[2:6], request[6:]

            response: List[bytes] = await wait_for(
                world_packet_mgr.process(
                    size=size,
                    opcode=opcode,
                    data=data
                ),
                timeout=Config.Realm.Settings.min_timeout
            )

            if response:
                for packet in response:
                    writer.write(packet)
                    await writer.drain()
Example #13
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=1.0
                )
            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:

                    responses = []

                    while update_packets:
                        head_update_packet_builder = update_packets.pop(0)

                        for index in range(0, WorldServer.MAX_UPDATE_PACKETS_INCLUDED):

                            if not update_packets:
                                break

                            batch = update_packets.pop(0).get_update_packet()
                            head_update_packet_builder.add_batch(batch)

                        update_packet = head_update_packet_builder.get_update_packet(build=True)

                        responses.append(update_packet)

                    for update_packet in responses:
                        response = WorldPacketManager.generate_packet(
                            opcode=WorldOpCode.SMSG_UPDATE_OBJECT,
                            data=update_packet,
                            header_crypt=header_crypt
                        )
                        writer.write(response)
                        await writer.drain()
Example #14
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))

        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)