async def handle_command(self, command_message: Command): command = command_message.command future = command_message.result log.info(f'{self.server_name} command received: {command}') if command == 'commands': future.set_result(VALID_COMMANDS) elif not self.rcon_protocol.logged_in: log.warning( f'{self.server_name} not logged in, cancelling command: {command}' ) future.cancel() elif command.split()[0] in VALID_COMMANDS: seq_number = await self.rcon_registrar.get_next_sequence_number() packet = protocol.Packet( protocol.Command(seq_number, command=command)) command_future = asyncio.get_running_loop().create_future() await self.rcon_registrar.register(packet.payload.sequence_number, command_future) self.rcon_protocol.send_rcon_datagram(packet.generate()) try: await command_future future.set_result(command_future.result().payload.data) except asyncio.CancelledError: log.warning(f'{self.server_name} command cancelled: {command}') future.cancel() else: future.set_result('invalid command')
async def keep_alive(self): seq_number = await self.rcon_registrar.get_next_sequence_number() packet = protocol.Packet(protocol.Command(seq_number)) future = asyncio.get_running_loop().create_future() await self.rcon_registrar.register(packet.payload.sequence_number, future) self.rcon_protocol.send_rcon_datagram(packet.generate()) await future if config.get_server(self.server_name).log_rcon_keep_alive: await self.discord_log('keep alive')
def datagram_received(self, data: Union[bytes, Text], addr: Tuple[str, int]) -> None: packet = protocol.Packet.parse(data) if isinstance(packet.payload, protocol.Login): packet.payload = \ CustomPayload(protocol.LOGIN, struct.pack(FORMAT_PREFIX + SEQUENCE_NUMBER_FORMAT, protocol.SUCCESS if self.login_success else 0x00)) self.transport.sendto(packet.generate(), addr) elif isinstance(packet.payload, protocol.Command): packet.payload = protocol.Command(packet.payload.sequence_number, command='random command data') if self.login_success: self.transport.sendto(packet.generate(), addr)
async def process_futures(future_queue, rcon_protocol): while True: future, command = await future_queue.get() log.info(f'command received: {command}') if command == 'commands': future.set_result(VALID_COMMANDS) elif command.split()[0] in VALID_COMMANDS: packet = protocol.Packet(protocol.Command(manager.get_next_sequence_number(), command=command)) command_future = asyncio.get_running_loop().create_future() await manager.register(packet.payload.sequence_number, command_future) rcon_protocol.send_rcon_datagram(packet.generate()) try: await command_future future.set_result(command_future.result().payload.data) except asyncio.CancelledError: future.cancel() else: future.set_result('invalid command')
async def incoming(self, key, packet): log.debug( f'{self.server_name} incoming key {key} and type {type(packet.payload)}' ) if not packet.payload.is_split(): future = self.tasks.pop(key) future.set_result(packet) else: split = self.splits.get(key, [''] * packet.payload.count) split[packet.payload.index] = packet.payload.data if all(split): data = ''.join(split) new_packet = protocol.Packet(protocol.Command(key, data=data)) future = self.tasks.pop(key) future.set_result(new_packet) self.splits.pop(key) else: self.splits[key] = split
def generate_keep_alive(): return protocol.Packet(protocol.Command(manager.get_next_sequence_number()))
def test_non_ascii_outgoing_message(): command = 'say -1 кто на кумырне сейчас?' p = protocol.Command(4, command=command) expected = b'\x01\x04say -1 \xd0\xba\xd1\x82\xd0\xbe \xd0\xbd\xd0\xb0 \xd0\xba\xd1\x83\xd0\xbc\xd1\x8b\xd1\x80\xd0\xbd\xd0\xb5 \xd1\x81\xd0\xb5\xd0\xb9\xd1\x87\xd0\xb0\xd1\x81?' assert expected == p.generate()