Ejemplo n.º 1
0
 def _process_connection_request(self, packet: ConnectionPacket,
                                 addr: Address) -> None:
     self._accepted_time[addr] = self.get_current_time()
     res_packet = connection_packet_factory.create(
         ConnectionPacketType.CONNECTION_REQUEST_ACCEPTED,
         to_packet_format(addr), 0, self.INTERNAL_ADDRESSES,
         packet.client_time_since_start, self._accepted_time[addr])
     self.send_connection_packet(res_packet, addr, DEFAULT_CHANEL)
Ejemplo n.º 2
0
    def _process_connection_request_accepted(self, packet: ConnectionPacket,
                                             addr: Address) -> None:
        if packet.client_time_since_start != self._request_time:
            _logger.warning(
                'The packet of connection request accepted has invalid time. (expected:%d, actual: %d)',
                self._request_time, packet.client_time_since_start)
            return

        send_packet = connection_packet_factory.create(
            ConnectionPacketType.NEW_INCOMING_CONNECTION,
            to_packet_format(addr), self.INTERNAL_ADDRESSES,
            packet.server_time_since_start, self.get_current_time())
        self.send_connection_packet(send_packet, addr, RELIABLE)

        self.send_ping(addr)
Ejemplo n.º 3
0
 def _process_open_connection_request2(self, packet: RakNetPacket, addr: Address) -> None:
     res_packet = raknet_packet_factory.create(
         RakNetPacketType.OPEN_CONNECTION_REPLY2, True, self.guid, to_packet_format(addr), packet.mtu_size, False)
     self.send_to_remote(res_packet, addr)
     self._sessions[addr].reset(packet.mtu_size)
Ejemplo n.º 4
0
 def _process_open_connection_reply1(self, packet: RakNetPacket,
                                     addr: Address) -> None:
     send_packet = raknet_packet_factory.create(
         RakNetPacketType.OPEN_CONNECTION_REQUEST2, True,
         to_packet_format(addr), packet.mtu_size, self.guid)
     self.send_to_remote(send_packet, addr)
Ejemplo n.º 5
0
class MCPEDataHandler(GameDataHandler):

    INTERNAL_ADDRESSES = tuple(to_packet_format((get_unspecified_address(), 0)) for _ in range(20))

    def __init__(self) -> None:
        self.__start_time = time.time()
        self.__ping_time = {}  # type: Dict[Address, int]
        self.__protocol_map = {}  # type: Dict[Address, _ProtocolEntry]
        self.__default_protocol = None

    # GameDataHandler interface methods

    @property
    def guid(self) -> int:
        raise NotImplementedError()

    def register_protocol(self, protocol: Protocol, addr: Optional[Address]=None) -> None:
        entry = _ProtocolEntry(protocol, GamePacketQueue(self.send_connection_packet))
        if addr is None:
            self.__default_protocol = entry
        else:
            self.__protocol_map[addr] = entry

    def remove_protocol(self, addr: Address) -> None:
        del self.__protocol_map[addr]

    def data_received(self, data: bytes, addr: Address) -> None:
        packet = connection_packet_codec.decode(data)
        _logger.debug('> %s', LogString(packet))
        getattr(self, '_process_' + packet.type.name.lower())(packet, addr)

    async def update(self) -> None:
        raise NotImplementedError()

    def disconnect(self, addr: Address) -> None:
        raise NotImplementedError()

    def terminate(self) -> None:
        raise NotImplementedError()

    # local methods

    def update_status(self, addr: Address, is_connecting: bool) -> None:
        raise NotImplementedError()

    def _get_protocol(self, addr: Address) -> Protocol:
        return self.__protocol_map.get(addr, self.__default_protocol).protocol

    def _get_queue(self, addr: Address) -> GamePacketQueue:
        return self.__protocol_map.get(addr, self.__default_protocol).queue

    def send_connection_packet(self, packet: ConnectionPacket, addr: Address, reliability: Reliability) -> None:
        """Send connection packet to specified address.

        :param packet: connection packet
        :param addr: destination
        :param reliability: frame reliability
        """
        _logger.debug('< %s', LogString(packet))
        self._get_protocol(addr).game_data_received(
            connection_packet_codec.encode(packet), addr, reliability)

    def send_game_packet(self, packet: GamePacket, addr: Address, immediately=True) -> None:
        if immediately:
            self._get_queue(addr).send_immediately(packet, addr)
        else:
            self._get_queue(addr).append(packet, addr)

    def send_waiting_game_packet(self, addr: Address) -> None:
        self._get_queue(addr).send()

    def send_ping(self, addr: Address) -> None:
        self.__ping_time[addr] = self.get_current_time()
        packet = connection_packet_factory.create(ConnectionPacketType.CONNECTED_PING, self.__ping_time[addr])
        self.send_connection_packet(packet, addr, UNRELIABLE)

    def get_current_time(self) -> int:
        """Get millisecond time since starting handler."""
        return int(1000 * (time.time() - self.__start_time))

    def _process_batch(self, packet: ConnectionPacket, addr: Address) -> None:
        for i, data in enumerate(packet.payloads):
            try:
                packet = game_packet_codec.decode(data)
                _logger.debug('> %s', LogString(packet))
                getattr(self, '_process_' + packet.type.name.lower())(packet, addr)
            except SessionNotFound:
                raise
            except Exception as exc:
                _logger.exception('%s', exc)
        self.send_waiting_game_packet(addr)

    def _process_connected_ping(self, packet: ConnectionPacket, addr: Address) -> None:
        res_packet = connection_packet_factory.create(
            ConnectionPacketType.CONNECTED_PONG,
            packet.ping_time_since_start,
            self.get_current_time())
        self.send_connection_packet(res_packet, addr, UNRELIABLE)

    def _process_connected_pong(self, packet: ConnectionPacket, addr: Address) -> None:
        if packet.ping_time_since_start != self.__ping_time[addr]:
            _logger.warning(
                'Pong time is invalid. (expected: %d, actual: %d)',
                self.__ping_time[addr], packet.ping_time_since_start)
        self.update_status(addr, True)