コード例 #1
0
ファイル: networker.py プロジェクト: PyGG2/PyGG2
    def recieve(self, server, game):
        # recieve all packets
        while True:
            packet = networking.packet.Packet("client")

            try:
                data, sender = self.socket.recvfrom(constants.MAX_PACKET_SIZE)
            except socket.error:
                # recvfrom throws socket.error if there was no packet to read
                break

            # FIXME: Uncomment these as soon as networking debugging is done. I commented this out because it messed with Traceback.
            #try:
            packet.unpack(data)
            #except:
            #    # parse error, don't throw exception but print it
            #    print("Parse error: %s" % sys.exc_info()[1])
            #    continue # drop packet

            # only handle this packet if we know the player
            if sender in self.players:
                for seq, event in packet.events:
                    if seq <= self.players[sender].server_acksequence:
                        # Event has already been processed before, discard
                        continue
                    try:
                        event_handler.eventhandlers[event.eventid](self, game, game.current_state, self.players[sender], event)
                        if event.eventid == constants.EVENT_PLAYER_DISCONNECT:
                            # Player disconnected, any further events are useless
                            break
                    except KeyError:
                        # Invalid event; ignore
                        print("WARNING: Client sent invalid event:", type(event), event.eventid)

            # or if someone wants to shake hands
            elif (packet.events[0])[1].eventid == constants.EVENT_HELLO:
                event = (packet.events[0])[1]
                if event.password == server.password:
                    newplayer = player.Player(self, game, event.name, sender)
                    newplayer.name = event.name

                    for player_obj in self.players.values():
                        if player_obj == newplayer:
                            self.service_new_player(server, game, newplayer)
                        else:
                            join_event = networking.event_serialize.ServerEventPlayerJoin(newplayer.id, newplayer.name)
                            player_obj.events.append((player_obj.sequence, join_event))
            # otherwise drop the packet
            else:
                continue

            try:
                # ack the packet
                self.players[sender].server_acksequence = packet.sequence
                self.players[sender].client_acksequence = packet.acksequence
            except KeyError:
                # The player has just disconnected, so no-one cares about acksequence
                pass
コード例 #2
0
ファイル: networker.py プロジェクト: Orpheon/PyGG2-1
    def recieve(self, server, game):
        # recieve all packets
        while True:
            packet = networking.packet.Packet("client")

            try:
                data, sender = self.socket.recvfrom(constants.MAX_PACKET_SIZE)
            except socket.error:
                # recvfrom throws socket.error if there was no packet to read
                break

            # FIXME: Uncomment these as soon as networking debugging is done. I commented this out because it messed with Traceback.
            #try:
            packet.unpack(data)
            #except:
            #    # parse error, don't throw exception but print it
            #    print("Parse error: %s" % sys.exc_info()[1])
            #    continue # drop packet

            # only handle this packet if we know the player
            if sender in self.players:
                for seq, event in packet.events:
                    if seq <= self.players[sender].server_acksequence:
                        # Event has already been processed before, discard
                        continue
                    try:
                        event_handler.eventhandlers[event.eventid](self, game, game.current_state, self.players[sender], event)
                        if event.eventid == constants.EVENT_PLAYER_DISCONNECT:
                            # Player disconnected, any further events are useless
                            break
                    except KeyError:
                        # Invalid event; ignore
                        print("WARNING: Client sent invalid event:", type(event), event.eventid)

            # or if someone wants to shake hands
            elif (packet.events[0])[1].eventid == constants.EVENT_HELLO:
                event = (packet.events[0])[1]
                if event.password == server.password:
                    newplayer = player.Player(self, game, event.name, sender)
                    newplayer.name = event.name

                    for player_obj in self.players.values():
                        if player_obj == newplayer:
                            self.service_new_player(server, game, newplayer)
                        else:
                            join_event = networking.event_serialize.ServerEventPlayerJoin(newplayer.id, newplayer.name)
                            player_obj.events.append((player_obj.sequence, join_event))
            # otherwise drop the packet
            else:
                continue

            try:
                # ack the packet
                self.players[sender].server_acksequence = packet.sequence
                self.players[sender].client_acksequence = packet.acksequence
            except KeyError:
                # The player has just disconnected, so no-one cares about acksequence
                pass
コード例 #3
0
ファイル: networker.py プロジェクト: NukleusGG2/PyGG2
    def recieve(self, game, client):
        # If we haven't received confirmation that we're connected yet, see if we should try again:
        if not self.has_connected:
            self.connection_timeout_timer -= 1

            if self.connection_timeout_timer <= 0:
                self.connection_timeout_timer = constants.CLIENT_TIMEOUT
                # Send a reminder, in case the first packet was lost
                packet = networking.packet.Packet("client")
                packet.sequence = self.sequence
                packet.acksequence = self.client_acksequence

                event = networking.event_serialize.ClientEventHello(client.player_name, client.server_password)
                packet.events.append((self.sequence, event))
                data = packet.pack()

                numbytes = self.socket.sendto(data, self.server_address)
                if len(data) != numbytes:
                    # TODO sane error handling
                    print("SERIOUS ERROR, NUMBER OF BYTES SENT != PACKET SIZE AT HELLO")


        while True:
            packet = networking.packet.Packet("server")

            try:
                data, sender = self.socket.recvfrom(constants.MAX_PACKET_SIZE)
            except socket.error:
                # recvfrom throws socket.error if there was no packet to read
                break

            # FIXME: Uncomment these as soon as networking debugging is done. I commented this out because it messed with Traceback.
            #try:
            packet.unpack(data)
            #except:
            #    # parse error, don't throw exception but print it
            #    print("Parse error: %s" % sys.exc_info()[1])
            #    continue # drop packet

            # only accept the packet if the sender is the server
            if sender == self.server_address:
                for seq, event in packet.events:
                    if seq <= self.client_acksequence:
                        # Event has already been processed before, discard
                        continue
                    event_handler.eventhandlers[event.eventid](client, self, game, event)
            # otherwise drop the packet
            else:
                print("RECEIVED PACKET NOT FROM ACTUAL SERVER ADDRESS:\nActual Server Address:"+str(self.server_address)+"\nPacket Address:"+str(sender))
                continue

            # ack the packet
            self.client_acksequence = packet.sequence
            self.server_acksequence = packet.acksequence

            # Clear the acked stuff from the history
            index = 0
            while index < len(self.events):
                seq, event = self.events[index]
                if seq > self.server_acksequence:
                    # This (and all the following events) weren't acked yet. We're done.
                    break
                else:
                    del self.events[index]
                    index -= 1
                index += 1
コード例 #4
0
ファイル: networker.py プロジェクト: PyGG2/PyGG2
    def recieve(self, game, client):
        # If we haven't received confirmation that we're connected yet, see if we should try again:
        if not self.has_connected:
            self.connection_timeout_timer -= 1

            if self.connection_timeout_timer <= 0:
                self.connection_timeout_timer = constants.CLIENT_TIMEOUT
                # Send a reminder, in case the first packet was lost
                packet = networking.packet.Packet("client")
                packet.sequence = self.sequence
                packet.acksequence = self.client_acksequence

                event = networking.event_serialize.ClientEventHello(client.player_name, client.server_password)
                packet.events.append((self.sequence, event))
                data = packet.pack()

                self.socket.sendto(data, self.server_address)


        while True:
            packet = networking.packet.Packet("server")

            try:
                data, sender = self.socket.recvfrom(constants.MAX_PACKET_SIZE)
            except socket.error:
                # recvfrom throws socket.error if there was no packet to read
                break

            # FIXME: Uncomment these as soon as networking debugging is done. I commented this out because it messed with Traceback.
            #try:
            packet.unpack(data)
            #except:
            #    # parse error, don't throw exception but print it
            #    print("Parse error: %s" % sys.exc_info()[1])
            #    continue # drop packet
            
            # Check whether the packet is even new enough
            if packet.sequence <= self.client_acksequence:
                print("Old packet:", packet.time, game.current_state.time)
                # No need to even consider this packet
                return

            # First check whether it's a hello packet, if yes handle it differently
            if (packet.events[0])[1].eventid == constants.EVENT_HELLO:
                # Hello event, full update and snapshot update
                for time, event in packet.events:
                    event_handler.eventhandlers[event.eventid](client, self, game, game.current_state, event)
            else:
                # Try to get a template state that's as close to the received one as possible.
                state = None
                if len(game.old_client_states) > 0 and game.current_state.time > packet.time:
                    if packet.time < game.old_client_states[0].time:
                        # This packet is extremely old
                        # This shouldn't actually ever happen
                        print("Packet received that is not in game.old_client_states!\nPacket time: {0}\ngame.old_client_states: {1}".format(packet.time, [i.time for i in game.old_client_states]))
                        state = game.old_client_states[0].copy()
                        state.update_all_objects(game, packet.time - state.time)
    
                    # "states" just contains all the states that we can interpolate from
                    # That includes the old_client_states and current_state
                    states = game.old_client_states[:]
                    states.append(game.current_state.copy())
    
                    # Now we sort it as a function of it's closeness to time
                    states.sort(key=lambda x: abs(packet.time - x.time))
    
                    # The two first elements of this list will necessarily be those around time
                    # So now we cut off everything except the first two
                    states = states[:2]
                    # And then we sort those normally
                    states.sort(key=lambda x: x.time)
                    # And then we interpolate
                    d_time = (packet.time - states[0].time) * (states[1].time - states[0].time)
                    if not(0 <= d_time <= 1):
                        if abs(d_time) > 0.001:
                            print("This should not happen!\nd_time:{0}\ntime:{1}\nstates[0].time:{2}\nstates[1].time:{3}\n\nold_client_states:{4}\n\n\n".format(d_time, packet.time, states[0].time, states[1].time, [i.time for i in game.old_client_states]))
                        if d_time < 0:
                            d_time = 0
                        if d_time > 1:
                            d_time = 1
                    states[0].interpolate(states[0], states[1], d_time)
                    state = states[0].copy()
    
                else:
                    # We don't even have any old states, just take current_state
                    state = game.current_state.copy()
    
                # All old states before this packet are now useless, and all old states after it are wrong
                game.old_client_states = []
    
                # only accept the packet if the sender is the server
                if sender == self.server_address:
                    for seq, event in packet.events:
                        if seq <= self.client_acksequence:
                            # Event has already been processed before, discard
                            continue
                        # First modify state to correspond to the time of the event
                        state.update_all_objects(game, event.time - state.time)
                        # process the event
                        event_handler.eventhandlers[event.eventid](client, self, game, state, event)
    
                    # Calculate current latency
                    self.latency = game.current_state.time - packet.time
                    # Set the state to the actual packet time and add it to the buffer for rendering
                    state.update_all_objects(game, packet.time - state.time)
                    game.old_server_states.append(state.copy())
                    game.old_client_states.append(state.copy())
                    if (abs(self.latency) <= constants.MAX_TIME_DESYNC):
                        # Update it to the current state time and then set it
                        state.update_all_objects(game, game.current_state.time - state.time)
                    else:
                        # Otherwise just let the client jump and correct itself
                        pass
                    game.current_state = state.copy()
                # otherwise drop the packet
                else:
                    print("RECEIVED PACKET NOT FROM ACTUAL SERVER ADDRESS:\nActual Server Address:"+str(self.server_address)+"\nPacket Address:"+str(sender))
                    continue

            # ack the packet
            self.client_acksequence = packet.sequence
            self.server_acksequence = packet.acksequence

            # Clear the acked stuff from the history
            index = 0
            while index < len(self.events):
                seq, event = self.events[index]
                if seq > self.server_acksequence:
                    # This (and all the following events) weren't acked yet. We're done.
                    break
                else:
                    del self.events[index]
                    index -= 1
                index += 1
コード例 #5
0
ファイル: networker.py プロジェクト: Orpheon/PyGG2-1
    def recieve(self, game, client):
        # If we haven't received confirmation that we're connected yet, see if we should try again:
        if not self.has_connected:
            self.connection_timeout_timer -= 1

            if self.connection_timeout_timer <= 0:
                self.connection_timeout_timer = constants.CLIENT_TIMEOUT
                # Send a reminder, in case the first packet was lost
                packet = networking.packet.Packet("client")
                packet.sequence = self.sequence
                packet.acksequence = self.client_acksequence

                event = networking.event_serialize.ClientEventHello(client.player_name, client.server_password)
                packet.events.append((self.sequence, event))
                data = packet.pack()

                numbytes = self.socket.sendto(data, self.server_address)
                if len(data) != numbytes:
                    # TODO sane error handling
                    print("SERIOUS ERROR, NUMBER OF BYTES SENT != PACKET SIZE AT HELLO")


        while True:
            packet = networking.packet.Packet("server")

            try:
                data, sender = self.socket.recvfrom(constants.MAX_PACKET_SIZE)
            except socket.error:
                # recvfrom throws socket.error if there was no packet to read
                break

            # FIXME: Uncomment these as soon as networking debugging is done. I commented this out because it messed with Traceback.
            #try:
            packet.unpack(data)
            #except:
            #    # parse error, don't throw exception but print it
            #    print("Parse error: %s" % sys.exc_info()[1])
            #    continue # drop packet
            
            # Check whether the packet is even new enough
            if packet.sequence <= self.client_acksequence:
                print("Old packet:", packet.time, game.current_state.time)
                # No need to even consider this packet
                return

            # First check whether it's a hello packet, if yes handle it differently
            if (packet.events[0])[1].eventid == constants.EVENT_HELLO:
                # Hello event, full update and snapshot update
                for time, event in packet.events:
                    event_handler.eventhandlers[event.eventid](client, self, game, game.current_state, event)
            else:
                # Try to get a template state that's as close to the received one as possible.
                state = None
                if len(game.old_client_states) > 0 and game.current_state.time > packet.time:
                    if packet.time < game.old_client_states[0].time:
                        # This packet is extremely old
                        # This shouldn't actually ever happen
                        print("Packet received that is not in game.old_client_states!\nPacket time: {0}\ngame.old_client_states: {1}".format(packet.time, [i.time for i in game.old_client_states]))
                        state = game.old_client_states[0].copy()
                        state.update_all_objects(game, packet.time - state.time)
    
                    # "states" just contains all the states that we can interpolate from
                    # That includes the old_client_states and current_state
                    states = game.old_client_states[:]
                    states.append(game.current_state.copy())
    
                    # Now we sort it as a function of it's closeness to time
                    states.sort(key=lambda x: abs(packet.time - x.time))
    
                    # The two first elements of this list will necessarily be those around time
                    # So now we cut off everything except the first two
                    states = states[:2]
                    # And then we sort those normally
                    states.sort(key=lambda x: x.time)
                    # And then we interpolate
                    d_time = (packet.time - states[0].time) * (states[1].time - states[0].time)
                    if not(0 <= d_time <= 1):
                        if abs(d_time) > 0.001:
                            print("This should not happen!\nd_time:{0}\ntime:{1}\nstates[0].time:{2}\nstates[1].time:{3}\n\nold_client_states:{4}\n\n\n".format(d_time, packet.time, states[0].time, states[1].time, [i.time for i in game.old_client_states]))
                        if d_time < 0:
                            d_time = 0
                        if d_time > 1:
                            d_time = 1
                    states[0].interpolate(states[0], states[1], d_time)
                    state = states[0].copy()
    
                else:
                    # We don't even have any old states, just take current_state
                    state = game.current_state.copy()
    
                # All old states before this packet are now useless, and all old states after it are wrong
                game.old_client_states = []
    
                # only accept the packet if the sender is the server
                if sender == self.server_address:
                    for seq, event in packet.events:
                        if seq <= self.client_acksequence:
                            # Event has already been processed before, discard
                            continue
                        # First modify state to correspond to the time of the event
                        state.update_all_objects(game, event.time - state.time)
                        # process the event
                        event_handler.eventhandlers[event.eventid](client, self, game, state, event)
    
                    # Calculate current latency
                    self.latency = game.current_state.time - packet.time
                    print(abs(self.latency)*1000, "<", constants.MAX_TIME_DESYNC*1000, "Rendering delta: ", game.rendering_time - game.current_state.time)
                    # Set the state to the actual packet time and add it to the buffer for rendering
                    state.update_all_objects(game, packet.time - state.time)
                    game.old_server_states.append(state.copy())
                    game.old_client_states.append(state.copy())
                    if (abs(self.latency) <= constants.MAX_TIME_DESYNC):
                        # Update it to the current state time and then set it
                        state.update_all_objects(game, game.current_state.time - state.time)
                    else:
                        # Otherwise just let the client jump and correct itself
                        pass
                    game.current_state = state.copy()
                # otherwise drop the packet
                else:
                    print("RECEIVED PACKET NOT FROM ACTUAL SERVER ADDRESS:\nActual Server Address:"+str(self.server_address)+"\nPacket Address:"+str(sender))
                    continue

            # ack the packet
            self.client_acksequence = packet.sequence
            self.server_acksequence = packet.acksequence

            # Clear the acked stuff from the history
            index = 0
            while index < len(self.events):
                seq, event = self.events[index]
                if seq > self.server_acksequence:
                    # This (and all the following events) weren't acked yet. We're done.
                    break
                else:
                    del self.events[index]
                    index -= 1
                index += 1