Commits

Szymon Wróblewski committed 00ca227

exapnded Peer

Comments (0)

Files changed (2)

 
 
 class OutgoingCommand(object):
-    def __init__(self):
+    def __init__(self, command, data='', offset=0, length=0):
         self.outgoing_command_list = []
         self.reliable_seq_num = 0
         self.unreliable_seq_num = 0
         self.sent_time = 0
         self.round_trip_timeout = 0
         self.round_trip_timeout_limit = 0
-        self.fragment_offset = 0
-        self.fragment_length = 0
+        self.fragment_offset = offset
+        self.fragment_length = length
         self.send_attempts = 0
-        self.command = 0
-        self.packet = 0
+        self.command = command
+        self.data = data
+
+    def push_to_queue(self, peer): #setup_outgoing_command
+        command = self.command
+        channel = peer._get_channel(command.channel_id)
+
+        peer.outgoing_data_total += command.size + self.fragment_length
+        if command.channel_id == 0xff:
+            peer.outgoing_reliable_seq_num += 1
+            self.reliable_seq_num = peer.outgoing_reliable_seq_num
+            self.unreliable_seq_num = 0
+        elif command.command & protocol.Flag.COMMAND_ACKNOWLEDGE:
+            channel.outgoing_reliable_seq_num += 1
+            channel.outgoing_unreliable_seq_num = 0
+            self.reliable_seq_num = channel.outgoing_reliable_seq_num
+            self.unreliable_seq_num = 0
+        elif command.command & protocol.Flag.COMMAND_UNSEQUENCED:
+            peer.outgoing_unsequenced_group += 1
+            self.reliable_seq_num = 0
+            self.unreliable_seq_num = 0
+        else:
+            if self.fragment_offset == 0:
+                channel.outgoing_unreliable_seq_num += 1
+            self.reliable_seq_num = channel.outgoing_reliable_seq_num
+            self.unreliable_seq_num = channel.outgoing_unreliable_seq_num
+        command.reliable_seq_num = self.reliable_seq_num
+
+        command_type = command.command & protocol.COMMAND_MASK
+        if command_type == protocol.Command.SEND_UNRELIABLE:
+            command.unreliable_seq_num = self.unreliable_seq_num
+        elif command_type == protocol.Command.SEND_UNSEQUENCED:
+            command.unsequenced_group = peer.outgoing_unsequenced_group
+
+        if command.command & protocol.Flag.COMMAND_ACKNOWLEDGE:
+            peer.outgoing_reliable_commands.append(self)
+        else:
+            peer.outgoing_unreliable_commands.append(self)
 
 
 class IncomingCommand(object):
         self.fragment_count = 0
         self.fragments_remaining = 0
         self.fragments = 0
-        self.packet = 0
+        self.data = ''
 
 
 class Peer(object):
             self.connect_id,
             self.data
         )
-        self._queue_outgoing_command(connect)
+        self._setup_outgoing_command(OutgoingCommand(connect))
 
     def _get_channel(self, channel_id, by_user=0):
         try:
                 raise ValueError('Wrong channel_id: %d' % channel_id)
         return channel
 
-    def _queue_outgoing_command(self, command, packet=None, offset=0, length=0):
-        outgoing_command = OutgoingCommand()
-        outgoing_command.command = command
-        outgoing_command.fragment_offset = offset
-        outgoing_command.fragment_length = length
-        outgoing_command.packet = packet
-
-        self._setup_outgoing_command(outgoing_command)
-        return outgoing_command
-
     def _setup_outgoing_command(self, outgoing_command):
         command = outgoing_command.command
         channel = self._get_channel(command.channel_id)
         data_len = len(data)
         if data_len > protocol.MAXIMUM_PACKET_SIZE:
             raise ValueError('Data too large')
-        frag_len = self.mtu - protocol.SendFragment.size
+        fragment_len = self.mtu - protocol.SendFragment.size
         if self.host.checksum is not None:
-            frag_len -= 4  # 32bit unsigned int
+            fragment_len -= 4  # 32bit unsigned int
 
-        # fragmenting
-        if data_len > frag_len:
-            fragment_cnt = (data_len + frag_len - 1) / frag_len
-            if fragment_cnt > protocol.MAXIMUM_FRAGMENT_COUNT:
+        if data_len > fragment_len:
+            # fragmenting
+            fragment_count = (data_len + fragment_len - 1) / fragment_len
+            if fragment_count > protocol.MAXIMUM_FRAGMENT_COUNT:
                 raise ValueError('Data too large')
-            outgoing_cmd = OutgoingCommand()
             if (flags & PacketFlag.RELIABLE | PacketFlag.UNRELIABLE_FRAGMENT) \
                     == PacketFlag.UNRELIABLE_FRAGMENT and \
                     channel.outgoing_unreliable_seq_num < 0xffff:
-                cmd_type = protocol.Command.SEND_UNRELIABLE_FRAGMENT
+                command_type = protocol.Command.SEND_UNRELIABLE_FRAGMENT
                 start_seq_num = channel.outgoing_unreliable_seq_num + 1
             else:
-                cmd_type = protocol.Command.SEND_FRAGMENT | protocol.Flag.COMMAND_ACKNOWLEDGE
+                command_type = protocol.Command.SEND_FRAGMENT | protocol.Flag.COMMAND_ACKNOWLEDGE
                 start_seq_num = channel.outgoing_reliable_seq_num + 1
 
-            fragments = []
-            for frag_num, frag_offset in enumerate(xrange(0, data_len, frag_len)):
-                if data_len - frag_offset < frag_len:
+            for fragment_number, fragment_offset in enumerate(xrange(0, data_len, fragment_len)):
+                if data_len - fragment_offset < fragment_len:
                     # calculate size of last fragment
-                    frag_len = data_len - frag_offset
+                    fragment_len = data_len - fragment_offset
 
-                fragment = OutgoingCommand()
-                fragment.fragment_offset = frag_offset
-                fragment.fragment_length = frag_len
+                fragment = OutgoingCommand(
+                    protocol.SendFragment(
+                        command_type,
+                        channel_id,
+                        0,
+                        start_seq_num,
+                        fragment_len,
+                        fragment_count,
+                        fragment_number,
+                        data_len,
+                        fragment_offset
+                    ),
+                    fragment_offset,
+                    fragment_len
+                )
 
+                self._setup_outgoing_command(fragment)
+        else:
+            if flags & (PacketFlag.RELIABLE | PacketFlag.UNSEQUENCED) == PacketFlag.UNSEQUENCED:
+                command = protocol.SendUnsequenced()
+            elif flags & PacketFlag.RELIABLE or channel.outgoing_unreliable_seq_num >= 0xffff:
+                command = protocol.SendReliable()
+            else:
+                command = protocol.SendUnreliable()
+            command.channel_id = channel_id
+            command.data_length = data_len
+            self._setup_outgoing_command(OutgoingCommand(command, data, 0, data_len))
 

ppenet/protocol.py

 CommandHeader = structtype('CommandHeader', (
     'command',
     'channel_id',
-    'reliable_seq_num',
+    'reliable_seq_num', # no idea why it's here
 ), '!BBH', default=0)
 
 Acknowledge = structtype('Acknowledge', CommandHeader.field_names + (
     'connect_id',
     'data',
 ), CommandHeader.format + 'HBB10I', default=0, field_defaults={
-    'command': Command.CONNECT
+    'command': Command.CONNECT | Flag.COMMAND_ACKNOWLEDGE
 })
 
 VerifyConnect = structtype('VerifyConnect', CommandHeader.field_names + (
 SendReliable = structtype('SendReliable', CommandHeader.field_names + (
     'data_length',
 ), CommandHeader.format + 'H', default=0, field_defaults={
-    'command': Command.SEND_RELIABLE
+    'command': Command.SEND_RELIABLE | Flag.COMMAND_ACKNOWLEDGE
 })
 
 SendUnreliable = structtype('SendUnreliable', CommandHeader.field_names + (
     'unsequenced_group',
     'data_length',
 ), CommandHeader.format + 'HH', default=0, field_defaults={
-    'command': Command.SEND_UNSEQUENCED
+    'command': Command.SEND_UNSEQUENCED | Flag.COMMAND_UNSEQUENCED
 })
 
 SendFragment = structtype('SendFragment', CommandHeader.field_names + (