Пример #1
0
    def connect_to_server(self, server, port, newconn=1):
        """Connect to the server, otherwise raise an exception."""

        self.__total_packets_sent = 0
        self.__total_packets_received = 0
        self.__next_outgoing_ack_id = 0
        self.__next_incoming_ack_id = 0
        self.__last_sync_response_received_tick = get_tick_count_hs()

        self.__event_tick_tick_accumulator = 0
        self.__last_wait_for_event_call_tick = get_tick_count_hs()
        self.__last_core_periodic_event_tick = get_tick_count_hs()

        self.__server = str(server)
        self.__port = int(port)
        self.__socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.__socket.connect((server, port))
        # changed for jython support doesnt seem to affect python
        self.__socket.setblocking(False)
        # self.__socket.settimeout(.01)
        self.__timeout_interval = 0.01

        STATE_NONE = 0
        STATE_CHALLENGE_RECEIVED = 1
        STATE_CONNECTED = 2

        client_key = (-random.randrange(1, sys.maxint))
        server_challenge = 0

        self.fc = FileChecksum()
        self.fc.generate_checksum_array(0)

        state = STATE_NONE
        timeouts = 0
        while state != STATE_CONNECTED:
            if timeouts > 3:
                break

            # send queueing the packets directly is done here because
            # handshake packets are special
            if state == STATE_NONE:
                # send handshake initiation packet
                self.queue_packet(
                    struct.pack("<BBIH", 0x00, 0x01, client_key & 0xFFFFFFFF,
                                0x0001))
            elif state == STATE_CHALLENGE_RECEIVED:
                # respond with server challenge
                self.queue_packet(
                    struct.pack("<BBII", 0x00, 0x06,
                                server_challenge & 0xFFFFFFFF,
                                get_tick_count_hs()))

            # write sent packets to the network
            self.flush_outbound_queues()

            # read raw packet is used here because the packets
            # during handshake are a little bit special (such
            # as the 0x02 type containing key data)
            packet = self.__read_raw_packet(2)
            if packet is None:
                timeouts += 1
                continue

            try:
                game_type, core_type = struct.unpack_from("<BB", packet)

                # default to bad state, unless we get an expected packet
                state = STATE_NONE
                if game_type == 0x00:
                    if core_type == 0x05:  # response to __sendClientKey()
                        server_challenge, = struct.unpack_from("<i", packet, 2)
                        state = STATE_CHALLENGE_RECEIVED
                    elif core_type == 0x02:
                        # success
                        server_key, = struct.unpack_from("<i", packet, 2)
                        self.__crypto = SubspaceEncryption(
                            client_key, server_key)
                        state = STATE_CONNECTED
                        break
            except struct.error:
                pass

        if state != STATE_CONNECTED:
            self.__log(CRITICAL, "Unable to connect to server")
            self.__connected = False
        else:
            self.__connected = True