stratagus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Stratagus-CVS] stratagus doc/ChangeLog.html src/include/networ...


From: Russell Smith
Subject: [Stratagus-CVS] stratagus doc/ChangeLog.html src/include/networ...
Date: Sun, 02 Nov 2003 16:12:54 -0500

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Russell Smith <address@hidden>  03/11/02 16:12:54

Modified files:
        doc            : ChangeLog.html 
        src/include    : network.h netconnect.h 
        src/network    : network.c 

Log message:
        Upgraded Network Code, Variable packet size and don't send repeat 
commands

Patches:
Index: stratagus/doc/ChangeLog.html
diff -u stratagus/doc/ChangeLog.html:1.565 stratagus/doc/ChangeLog.html:1.566
--- stratagus/doc/ChangeLog.html:1.565  Mon Oct 27 00:56:19 2003
+++ stratagus/doc/ChangeLog.html        Sun Nov  2 16:12:52 2003
@@ -2,7 +2,7 @@
 <html>
 <head>
 <!--
-----   $Id: ChangeLog.html,v 1.565 2003/10/27 05:56:19 mr-russ Exp $
+----   $Id: ChangeLog.html,v 1.566 2003/11/02 21:12:52 mr-russ Exp $
 
 ----   (c) Copyright 1998-2003 by Lutz Sammer
 
@@ -36,6 +36,7 @@
 <li>Future 2.00 Release<p>
     <ul>
     <li>++
+    <li>Upgraded Network Code, Variable packet size and don't send repeat 
commands (from Russell Smith).
     <li>Fixed Bug #6063: Copy and Paste isn't working in boxes (from Russell 
Smith).
     <li>Fixed Bug #6085: Pb in saving spell order action (from Russell Smith).
     <li>Applied patch #2130 (missile flags and area-heal) (from Jarod Dauphin).
Index: stratagus/src/include/netconnect.h
diff -u stratagus/src/include/netconnect.h:1.51 
stratagus/src/include/netconnect.h:1.52
--- stratagus/src/include/netconnect.h:1.51     Fri Jul 11 10:35:30 2003
+++ stratagus/src/include/netconnect.h  Sun Nov  2 16:12:53 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: netconnect.h,v 1.51 2003/07/11 14:35:30 n0body Exp $
+//     $Id: netconnect.h,v 1.52 2003/11/02 21:12:53 mr-russ Exp $
 
 #ifndef __NETCONNECT_H__
 #define __NETCONNECT_H__
@@ -46,9 +46,9 @@
     /// Network protocol major version
 #define NetworkProtocolMajorVersion    0
     /// Network protocol minor version (maximal 99)
-#define NetworkProtocolMinorVersion    4
+#define NetworkProtocolMinorVersion    9
     /// Network protocol patch level (maximal 99)
-#define NetworkProtocolPatchLevel      19
+#define NetworkProtocolPatchLevel      0
     /// Network protocol version (1,2,3) -> 10203
 #define NetworkProtocolVersion \
        (NetworkProtocolMajorVersion*10000+NetworkProtocolMinorVersion*100 \
Index: stratagus/src/include/network.h
diff -u stratagus/src/include/network.h:1.43 
stratagus/src/include/network.h:1.44
--- stratagus/src/include/network.h:1.43        Tue Oct 28 15:20:44 2003
+++ stratagus/src/include/network.h     Sun Nov  2 16:12:53 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: network.h,v 1.43 2003/10/28 20:20:44 n0body Exp $
+//     $Id: network.h,v 1.44 2003/11/02 21:12:53 mr-russ Exp $
 
 #ifndef __NETWORK_H__
 #define __NETWORK_H__
@@ -48,7 +48,7 @@
 
 #define NetworkMaxLag  250             /// Debuging network lag (# game cycles)
 
-#define NetworkDups    1               /// Repeat old commands
+#define MaxNetworkCommands     9               /// Max Commands In A Packet
 
 /*----------------------------------------------------------------------------
 --     Declarations
@@ -60,6 +60,7 @@
 **     @todo cleanup the message types.
 */
 enum _message_type_ {
+    MessageNone,                       /// When Nothing Is Happening
     MessageInitHello,                  /// Start connection
     MessageInitReply,                  /// Connection reply
     MessageInitConfig,                 /// Setup message configure clients
@@ -119,8 +120,6 @@
 **     Network command message.
 */
 typedef struct _network_command_ {
-    unsigned char      Type;           /// Network command type
-    unsigned char      Cycle;          /// Destination game cycle
     UnitRef            Unit;           /// Command for unit
     unsigned short     X;              /// Map position X
     unsigned short     Y;              /// Map position Y
@@ -131,8 +130,6 @@
 **     Extended network command message.
 */
 typedef struct _network_extended_command_ {
-    unsigned char      Type;           /// Network command type
-    unsigned char      Cycle;          /// Destination game cycle
     unsigned char      ExtendedType;   /// Extended network command type
     unsigned char      Arg1;           /// Argument 1
     unsigned short     Arg2;           /// Argument 2
@@ -144,20 +141,30 @@
 **     Network chat message.
 */
 typedef struct _network_chat_ {
-    unsigned char      Cycle;          /// Destination game cycle
-    unsigned char      Type;           /// Network command type
     unsigned char      Player;         /// Sending player
     char               Text[7];        /// Message bytes
 } NetworkChat;
 
 /**
+**     Network packet header.
+**
+**     Header for the packet.
+*/
+typedef struct _network_packet_header_ {
+    unsigned char      Cycle;          /// Destination game cycle
+    unsigned char      Type[MaxNetworkCommands];       /// Command
+                                       /// Commands in packet
+} NetworkPacketHeader;
+
+/**
 **     Network packet.
 **
 **     This is sent over the network.
+**     
 */
 typedef struct _network_packet_ {
-                                       /// Commands in packet
-    NetworkCommand     Commands[NetworkDups];
+    NetworkPacketHeader        Header;         /// Packet Header Info
+    NetworkCommand     Command[MaxNetworkCommands];
 } NetworkPacket;
 
 /*----------------------------------------------------------------------------
Index: stratagus/src/network/network.c
diff -u stratagus/src/network/network.c:1.121 
stratagus/src/network/network.c:1.122
--- stratagus/src/network/network.c:1.121       Sat Oct 11 23:21:37 2003
+++ stratagus/src/network/network.c     Sun Nov  2 16:12:54 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: network.c,v 1.121 2003/10/12 03:21:37 mr-russ Exp $
+//     $Id: network.c,v 1.122 2003/11/02 21:12:54 mr-russ Exp $
 
 //@{
 
@@ -138,16 +138,11 @@
 **     together with the local command. Each ::NetworkUpdates game cycles there
 **     must a package send, to keep the clients in sync, if there is no user
 **     command, a dummy sync package is send.
-**     To avoid too much trouble with lost packages, a package contains 
-**     ::NetworkDups commands, the latest and ::NetworkDups-1 old.
 **     If there are missing packages, the game is paused and old commands
 **     are resend to all clients.
 **
 **     @section missing What features are missing
 **
-**     @li A possible improvement is to compress the sync message, this allows
-**         to lose more packets.
-**
 **     @li The recover from lost packets can be improved, if the server knows
 **         which packets the clients have received.
 **
@@ -170,15 +165,6 @@
 **      @li Proxy and relays should be supported, to improve the playable
 **         over the internet.
 **
-**     @li Currently the 4 slots are filled with package in sequence, but
-**         dropouts are normal short and then hits the same package. If we
-**         interleave the package, we are more resistent against short
-**         dropouts.
-**
-**     @li If we move groups, the commands are send for each unit separated.
-**         It would be better to transfer the group first and than only a
-**         single command for the complete group.
-**
 **     @li The game cycles is transfered for each slot, this is not needed. We
 **         can save some bytes if we compress this.
 **
@@ -225,8 +211,6 @@
 // FIXME: should split the next into small modules!
 // FIXME: I (Johns) leave this for other people (this means you!)
 
-#define __COMPRESS_SYNC
-
 //----------------------------------------------------------------------------
 //     Includes
 //----------------------------------------------------------------------------
@@ -264,6 +248,7 @@
 typedef struct _network_command_queue_ {
     struct dl_node     List[1];        /// double linked list
     unsigned long      Time;           /// time to execute
+    unsigned char      Type;           /// Command Type
     NetworkCommand     Data;           /// command content
 } NetworkCommandQueue;
 
@@ -289,9 +274,8 @@
 local unsigned long NetworkDelay;      /// Delay counter for recover.
 local int NetworkSyncSeeds[256];       /// Network sync seeds.
 local int NetworkSyncHashs[256];       /// Network sync hashs.
-local NetworkCommandQueue NetworkIn[256][PlayerMax]; /// Per-player network 
packet input queue
+local NetworkCommandQueue NetworkIn[256][PlayerMax][MaxNetworkCommands]; /// 
Per-player network packet input queue
 local DL_LIST(CommandsIn);             /// Network command input queue
-local DL_LIST(CommandsOut);            /// Network command output queue
 local DL_LIST(MsgCommandsIn);          /// Network message input queue
 
 #ifdef DEBUG
@@ -325,28 +309,13 @@
 global void NetworkBroadcast(const void* buf, int len)
 {
     int i;
-#if 0
-    //
-    // Can be enabled to simulate network delays.
-    //
-#define DELAY 5
-    static char delay_buf[DELAY][1024];
-    static int delay_len[DELAY];
-    static int index;
 
-    if (index >= DELAY) {
-       // Send to all clients.
-       for (i = 0; i < HostsCount; ++i) {
-           NetSendUDP(NetworkFildes, Hosts[i].Host, Hosts[i].Port,
-               delay_buf[index % DELAY], delay_len[index % DELAY]);
-       }
-    }
-    memcpy(delay_buf[index % DELAY], buf, len);
-    delay_len[index % DELAY] = len;
-    ++index;
-#else
+#undef PACKET_LOSS
 
     // Send to all clients.
+#ifdef PACKET_LOSS
+    if ((MyRand() & PACKET_LOSS)) {
+#endif
     for (i = 0; i < HostsCount; ++i) {
        int n;
 
@@ -354,6 +323,8 @@
        DebugLevel3Fn("Sending %d to %d.%d.%d.%d:%d\n" _C_
            n _C_ NIPQUAD(ntohl(Hosts[i].Host)) _C_ ntohs(Hosts[i].Port));
     }
+#ifdef PACKET_LOSS
+    }
 #endif
 }
 
@@ -366,6 +337,7 @@
 {
     NetworkPacket packet;
     int i;
+    int numcommands;
 
 #ifdef DEBUG
     ++NetworkSendPackets;
@@ -374,24 +346,31 @@
     DebugLevel3Fn("In cycle %lu sending: " _C_ GameCycle);
 
     //
-    // Build packet of 4 messages.
+    // Build packet of Up to MaxNetworkCommands messages.
     //
-    for (i = 0; i < NetworkDups; ++i) {
-       DebugLevel3("%d %d," _C_ ncq->Data.Type _C_ ncq->Time);
-       packet.Commands[i] = ncq->Data;
-       if (ncq->List->next->next) {
-           ncq = (NetworkCommandQueue*)(ncq->List->next);
-       }
+    numcommands = 0;
+    packet.Header.Cycle = ncq[0].Time & 0xFF;
+    DebugLevel3("Time: %lu " _C_ ncq[0].Time);
+    for (i = 0; i < MaxNetworkCommands && ncq[i].Type != MessageNone; ++i) {
+       DebugLevel3("T:%d, Com: %d " _C_ ncq[i].Type _C_ i);
+       packet.Header.Type[i] = ncq[i].Type;
+       packet.Command[i] = ncq[i].Data;
+       ++numcommands;
     }
     DebugLevel3("\n");
 
+    for (; i < MaxNetworkCommands; ++i) {
+       packet.Header.Type[i] = MessageNone;
+    }
+ 
     // if (0 || !(rand() & 15))
-        NetworkBroadcast(&packet, sizeof(packet));
+    
+    NetworkBroadcast(&packet, sizeof(NetworkPacketHeader) + 
sizeof(NetworkCommand) * numcommands);
 
 #if 0
     // Disabled for testing network speed
     if (HostsCount < 3) {              // enough bandwidth to send twice :)
-        NetworkBroadcast(&packet, sizeof(packet));
+       NetworkBroadcast(&packet, sizeof(NetworkPacketHeader) + 
sizeof(NetworkCommand) * numcommands);
     }
 #endif
 }
@@ -476,7 +455,6 @@
 #endif
 
     dl_init(CommandsIn);
-    dl_init(CommandsOut);
     dl_init(MsgCommandsIn);
 }
 
@@ -511,6 +489,7 @@
 {
     int i;
     int n;
+    int c;
 
     NetworkConnectSetupGame();
 
@@ -523,9 +502,10 @@
     memset(NetworkIn, 0, sizeof(NetworkIn));
     for (i = 0; i <= NetworkLag; i += NetworkUpdates) {
        for (n = 0; n < HostsCount; ++n) {
-           NetworkIn[i][Hosts[n].PlyNr].Time = i;
-           NetworkIn[i][Hosts[n].PlyNr].Data.Cycle = i;
-           NetworkIn[i][Hosts[n].PlyNr].Data.Type = MessageSync;
+           for (c = 0; c < MaxNetworkCommands; ++c) {
+               NetworkIn[i][Hosts[n].PlyNr][c].Time = i;
+               NetworkIn[i][Hosts[n].PlyNr][c].Type = MessageSync;
+           }
        }
     }
 
@@ -560,22 +540,40 @@
     const Unit* dest, const UnitType* type, int status)
 {
     NetworkCommandQueue* ncq;
+    NetworkCommandQueue* check;
 
     DebugLevel3Fn("%d,%d,(%d,%d),%d,%s,%s\n" _C_
        command _C_ unit->Slot _C_ x _C_ y _C_ dest ? dest->Slot : -1 _C_
        type ? type->Ident : "-" _C_ status ? "flush" : "append");
 
-    //
-    // FIXME: look if we can ignore this command.
-    //         Duplicate commands can be ignored.
-    //
+    // Check for duplicate command in queue
+    check = (NetworkCommandQueue*)CommandsIn->first->next;
+    while (check) {
+       if ((check->Type & 0x7F) == command &&
+           check->Data.Unit == htons(unit->Slot) &&
+           check->Data.X == htons(x) &&
+           check->Data.Y == htons(y)) {
+           if (dest && check->Data.Dest == htons(dest->Slot)) {
+               DebugLevel3Fn("Removed Repeat Command\n");
+               return;
+           } else if (type && check->Data.Dest == htons(type->Type)) {
+               DebugLevel3Fn("Removed Repeat Command\n");
+               return;
+           } else if (check->Data.Dest == htons(-1)) {
+               DebugLevel3Fn("Removed Repeat Command\n");
+               return;
+           }
+       }
+       check = (NetworkCommandQueue*)check->List->next;
+    }
+
     ncq = malloc(sizeof(NetworkCommandQueue));
     dl_insert_first(CommandsIn, ncq->List);
 
     ncq->Time = GameCycle;
-    ncq->Data.Type = command;
+    ncq->Type = command;
     if (status) {
-       ncq->Data.Type |= 0x80;
+       ncq->Type |= 0x80;
     }
     ncq->Data.Unit = htons(unit->Slot);
     ncq->Data.X = htons(x);
@@ -588,6 +586,7 @@
     } else {
        ncq->Data.Dest = htons(-1);
     }
+
 }
 
 /**
@@ -618,9 +617,9 @@
     ncq->Time = GameCycle;
     nec=(NetworkExtendedCommand*)&ncq->Data;
 
-    nec->Type = MessageExtendedCommand;
+    ncq->Type = MessageExtendedCommand;
     if (status) {
-       nec->Type |= 0x80;
+       ncq->Type |= 0x80;
     }
     nec->ExtendedType = command;
     nec->Arg1 = arg1;
@@ -637,6 +636,7 @@
 local void NetworkRemovePlayer(int player)
 {
     int i;
+    int c;
 
     // Remove player from Hosts and clear NetworkIn
     for (i = 0; i < HostsCount; ++i) {
@@ -647,7 +647,9 @@
        }
     }
     for (i = 0; i < 256; ++i) {
-       NetworkIn[i][player].Time = 0;
+       for (c = 0; c < MaxNetworkCommands; ++c) {
+           NetworkIn[i][player][c].Time = 0;
+       }
     }
 }
 
@@ -665,6 +667,7 @@
     NetworkPacket* packet;
     int player;
     int i;
+    int commands;
     unsigned long n;
 
     if (NetworkFildes == (Socket)-1) {
@@ -701,8 +704,14 @@
     //
     // Minimal checks for good/correct packet.
     //
-    if (i != sizeof(NetworkPacket) && packet->Commands[0].Type != MessageQuit) 
{
-       DebugLevel0Fn("Bad packet\n");
+    commands = 0;
+    while (commands < MaxNetworkCommands && packet->Header.Type[commands] != 
MessageNone ) {
+       ++commands;
+    }
+    // Typecast to fix Broken GCC!! AH
+    if (i != (int)(sizeof(NetworkPacketHeader) + sizeof(NetworkCommand) * 
commands)) {
+       DebugLevel0Fn("Bad packet read:%d, expected:%d\n" _C_
+           i _C_ (int)(sizeof(NetworkPacketHeader) + sizeof(NetworkCommand) * 
commands));
        return;
     }
     
@@ -722,24 +731,24 @@
     //
     // Parse the packet commands.
     //
-    for (i = 0; i < NetworkDups; ++i) {
+    for (i = 0; i < commands; ++i) {
        const NetworkCommand* nc;
 
-       nc = &packet->Commands[i];
+       nc = &packet->Command[i];
 
        //
        //      Handle some messages.
        //
-       if (nc->Type == MessageQuit) {
+       if (packet->Header.Type[i] == MessageQuit) {
            PlayerQuit[nc->X] = 1;
        }
 
-       if (nc->Type == MessageResend) {
-           const NetworkCommandQueue* ncq;
+       if (packet->Header.Type[i] == MessageResend) {
            int j;
+           int c;
 
            // Destination cycle (time to execute).
-           n = ((GameCycle + 128) & ~0xFF) | nc->Cycle;
+           n = ((GameCycle + 128) & ~0xFF) | packet->Header.Cycle;
            if (n > GameCycle + 128) {
                DebugLevel3Fn("+128 needed!\n");
                n -= 0x100;
@@ -749,57 +758,47 @@
            //  other side sends re-send until it gets an answer.
 
            DebugLevel2Fn("Resend for %lu got\n" _C_ n);
-           //
-           //  Find the commands to resend
-           //
-           ncq = (NetworkCommandQueue*)(CommandsOut->first);
-           while (ncq->List->next) {
-               DebugLevel3Fn("resend %d? %d\n" _C_ ncq->Time _C_ n);
-               if (ncq->Time == n) {
-                   // FIXME: don't need to broadcast to everyone
-                   NetworkSendPacket(ncq);
-                   break;
-               }
-
-               ncq = (NetworkCommandQueue*)(ncq->List->next);
-           }
-           if (!ncq->List->next) {
-               DebugLevel3Fn("no packets for resend\n");
+           if (n != NetworkIn[n & 0xFF][ThisPlayer->Player][0].Time) {
+               // Asking for a cycle we haven't gotten to yet, ignore for now
+               return;
            }
 
+           NetworkSendPacket(NetworkIn[n & 0xFF][ThisPlayer->Player]);
+
            // Check if a player quit this cycle
            for (j = 0; j < HostsCount; ++j) {
-               ncq = &NetworkIn[n & 0xFF][Hosts[j].PlyNr];
-               if (ncq->Time && ncq->Data.Type == MessageQuit) {
-                   NetworkPacket np;
+               for (c = 0; c < MaxNetworkCommands; ++c) {
+                   NetworkCommandQueue* ncq;
                    int k;
+                   ncq = &NetworkIn[n & 0xFF][Hosts[j].PlyNr][c];
+                   if (ncq->Time && ncq->Type == MessageQuit) {
+                       NetworkPacket np;
+                       np.Header.Cycle = ncq->Time & 0xFF;
+                       np.Header.Type[0] = ncq->Type;
+                       np.Command[0] = ncq->Data;
+                       for (k = 1; k < MaxNetworkCommands; ++k) {
+                           np.Header.Type[k] = MessageNone;
+                       }
 
-                   for (k = 0; k < NetworkDups; ++k) {
-                       np.Commands[k] = ncq->Data;
+                       NetworkBroadcast(&np, sizeof(NetworkPacketHeader) + 
sizeof(NetworkCommand));
                    }
-
-                   // FIXME: don't need to broadcast to everyone
-                   NetworkBroadcast(&np, sizeof(np));
                }
            }
 
-           continue;
+           return;
        }
 
        // Destination cycle (time to execute).
-       n = ((GameCycle + 128) & ~0xFF) | nc->Cycle;
+       n = ((GameCycle + 128) & ~0xFF) | packet->Header.Cycle;
        if (n > GameCycle + 128) {
            DebugLevel3Fn("+128 needed!\n");
            n -= 0x100;
        }
 
-       if (nc->Type == MessageSync) {
-           // FIXME: must support compressed sync slots.
-       }
-
-       if (NetworkIn[nc->Cycle][player].Time != n) {
+       if (NetworkIn[packet->Header.Cycle][player][0].Time != n) {
            DebugLevel3Fn("Command %3d for %8d(%02X) got\n" _C_
-               nc->Type _C_ n _C_ nc->Cycle);
+               packet->Header.Type[i] _C_ n _C_ 
+               packet->Header.Cycle);
        }
 
        // Receive statistic
@@ -808,24 +807,14 @@
        }
        NetworkLastFrame[player] = FrameCounter;
 
-#ifdef DEBUG
-       if (i) {
-           // Not in first slot and not got packet lost!
-           // FIXME: if more than 1 in sequence is lost, I count one to much!
-           if (NetworkIn[nc->Cycle][player].Time != n) {
-               ++NetworkReceivedLost;
-           }
-       } else {
-           // FIXME: more network statistic
-           if (NetworkIn[nc->Cycle][player].Time == n) {
-               ++NetworkReceivedDups;
-           }
-       }
-#endif
-
        // Place in network in
-       NetworkIn[nc->Cycle][player].Time = n;
-       NetworkIn[nc->Cycle][player].Data = *nc;
+       NetworkIn[packet->Header.Cycle][player][i].Time = n;
+       NetworkIn[packet->Header.Cycle][player][i].Type = 
packet->Header.Type[i];
+       NetworkIn[packet->Header.Cycle][player][i].Data = *nc;
+    }
+
+    for ( ; i < MaxNetworkCommands; ++i) {
+       NetworkIn[packet->Header.Cycle][player][i].Time = 0;
     }
 
     //
@@ -836,7 +825,7 @@
        n = (GameCycle / NetworkUpdates) * NetworkUpdates + NetworkUpdates;
        DebugLevel3Fn("wait for %d - " _C_ n);
        for (player = 0; player < HostsCount; ++player) {
-           if (NetworkIn[n & 0xFF][Hosts[player].PlyNr].Time != n) {
+           if (NetworkIn[n & 0xFF][Hosts[player].PlyNr][0].Time != n) {
                NetworkInSync = 0;
                break;
            }
@@ -850,21 +839,23 @@
 */
 global void NetworkQuit(void)
 {
-    NetworkCommandQueue* ncq;
+    int n;
+    int i;
 
     if (!ThisPlayer) {
        return;
     }
 
-    ncq = malloc(sizeof(NetworkCommandQueue));
-    dl_insert_first(CommandsOut, ncq->List);
+    n = (GameCycle + NetworkUpdates) / NetworkUpdates * NetworkUpdates + 
NetworkLag;
+    NetworkIn[n & 0xFF][ThisPlayer->Player][0].Type = MessageQuit;
+    NetworkIn[n & 0xFF][ThisPlayer->Player][0].Time = n;
+    NetworkIn[n & 0xFF][ThisPlayer->Player][0].Data.X = ThisPlayer->Player;
 
-    ncq->Time = (GameCycle + NetworkUpdates) / NetworkUpdates * NetworkUpdates 
+ NetworkLag;
-    ncq->Data.Cycle = ncq->Time & 0xFF;
-    ncq->Data.Type = MessageQuit;
-    ncq->Data.X = ThisPlayer->Player;
+    for (i = 1; i < MaxNetworkCommands; ++i) {
+       NetworkIn[n & 0xFF][ThisPlayer->Player][i].Type = MessageNone;
+    }
 
-    NetworkSendPacket(ncq);
+    NetworkSendPacket(NetworkIn[n & 0xFF][ThisPlayer->Player]);
 }
 
 /**
@@ -885,7 +876,7 @@
        while (n >= (int)sizeof(ncm->Text)) {
            ncq = malloc(sizeof(NetworkCommandQueue));
            dl_insert_first(MsgCommandsIn, ncq->List);
-           ncq->Data.Type = MessageChat;
+           ncq->Type = MessageChat;
            ncm = (NetworkChat *)(&ncq->Data);
            ncm->Player = ThisPlayer->Player;
            memcpy(ncm->Text, cp, sizeof(ncm->Text));
@@ -894,7 +885,7 @@
        }
        ncq = malloc(sizeof(NetworkCommandQueue));
        dl_insert_first(MsgCommandsIn, ncq->List);
-       ncq->Data.Type = MessageChatTerm;
+       ncq->Type = MessageChatTerm;
        ncm = (NetworkChat*)(&ncq->Data);
        ncm->Player = ThisPlayer->Player;
        memcpy(ncm->Text, cp, n + 1);           // see >= above :)
@@ -910,7 +901,7 @@
 {
     int ply;
 
-    switch (ncq->Data.Type & 0x7F) {
+    switch (ncq->Type & 0x7F) {
        case MessageSync:
            ply = ntohs(ncq->Data.X) << 16;
            ply |= ntohs(ncq->Data.Y);
@@ -918,9 +909,10 @@
                    ntohs(ncq->Data.Unit) != NetworkSyncHashs[GameCycle & 
0xFF]) {
 
                SetMessage("Network out of sync");
-               DebugLevel0Fn("\nNetwork out of sync %x!=%x!\n\n" _C_ 
-                   ply _C_ NetworkSyncSeeds[GameCycle & 0xFF]);
-           }
+               DebugLevel0Fn("\nNetwork out of sync %x!=%x! %d!=%d!\n\n" _C_ 
+                   ply _C_ NetworkSyncSeeds[GameCycle & 0xFF] _C_ 
+                   ntohs(ncq->Data.Unit) _C_ NetworkSyncHashs[GameCycle & 
0xFF]);
+           } 
            return;
        case MessageChat:
        case MessageChatTerm: {
@@ -933,7 +925,7 @@
                        sizeof(ncm->Text));
            }
            NetMsgBufLen[ply] += sizeof(ncm->Text);
-           if (ncq->Data.Type == MessageChatTerm) {
+           if (ncq->Type == MessageChatTerm) {
                NetMsgBuf[ply][127] = '\0';
                SetMessage("%s", NetMsgBuf[ply]);
                NetMsgBufLen[ply] = 0;
@@ -949,12 +941,16 @@
            const NetworkExtendedCommand *nec;
 
            nec = (NetworkExtendedCommand *)(&ncq->Data);
-           ParseExtendedCommand(nec->ExtendedType, (nec->Type & 0x80) >> 7,
+           ParseExtendedCommand(nec->ExtendedType, (ncq->Type & 0x80) >> 7,
                nec->Arg1, ntohs(nec->Arg2), ntohs(nec->Arg3), 
ntohs(nec->Arg4));
            }
            break;
+       case MessageNone:
+           // Nothing to Do, This Message Should Never be Executed
+           DebugCheck(1);
+           break;
        default:
-           ParseCommand(ncq->Data.Type, ntohs(ncq->Data.Unit),
+           ParseCommand(ncq->Type, ntohs(ncq->Data.Unit),
                ntohs(ncq->Data.X), ntohs(ncq->Data.Y), ntohs(ncq->Data.Dest));
            break;
     }
@@ -972,8 +968,6 @@
 local void NetworkResendCommands(void)
 {
     NetworkPacket packet;
-    const NetworkCommandQueue* ncq;
-    int i;
 
 #ifdef DEBUG
     ++NetworkSendResend;
@@ -982,27 +976,17 @@
     //
     // Build packet of 4 messages.
     //
-    packet.Commands[0].Type = MessageResend;
-    packet.Commands[0].Cycle =
+    packet.Header.Type[0] = MessageResend;
+    packet.Header.Type[1] = MessageNone;
+    packet.Header.Cycle =
        (GameCycle / NetworkUpdates) * NetworkUpdates + NetworkUpdates;
 
-    DebugLevel2Fn("In cycle %lu for cycle %lu(%x):" _C_ GameCycle _C_
+    DebugLevel3Fn("In cycle %lu for cycle %lu(%x):" _C_ GameCycle _C_
        (GameCycle / NetworkUpdates) * NetworkUpdates + NetworkUpdates _C_
-       packet.Commands[0].Cycle);
-
-    ncq = (NetworkCommandQueue*)(CommandsOut->last);
-
-    for (i = 1; i < NetworkDups; ++i) {
-       DebugLevel2("%d %lu," _C_ ncq->Data.Type _C_ ncq->Time);
-       packet.Commands[i] = ncq->Data;
-       if (ncq->List->prev->prev) {
-           ncq = (NetworkCommandQueue*)(ncq->List->prev);
-       }
-    }
-    DebugLevel2("<%d %lu\n" _C_ ncq->Data.Type _C_ ncq->Time);
+       packet.Header.Cycle);
 
     // if (0 || !(rand() & 15))
-       NetworkBroadcast(&packet, sizeof(packet));
+    NetworkBroadcast(&packet, sizeof(NetworkPacketHeader) + 
sizeof(NetworkCommand));
 }
 
 /**
@@ -1010,50 +994,61 @@
 */
 local void NetworkSendCommands(void)
 {
+    NetworkCommandQueue* incommand;
     NetworkCommandQueue* ncq;
+    int numcommands;
 
     //
     // No command available, send sync.
     //
+    numcommands = 0;
+    incommand = NULL;
+    ncq = NetworkIn[(GameCycle + NetworkLag) & 0xFF][ThisPlayer->Player];
+    memset(ncq, 0, sizeof(NetworkCommandQueue) * MaxNetworkCommands);
     if (dl_empty(CommandsIn) && dl_empty(MsgCommandsIn)) {
-       ncq = malloc(sizeof(NetworkCommandQueue));
-       ncq->Data.Type = MessageSync;
-       ncq->Data.Unit = htons(SyncHash&0xFFFF);
-       ncq->Data.X = htons(SyncRandSeed>>16);
-       ncq->Data.Y = htons(SyncRandSeed&0xFFFF);
-       // FIXME: can compress sync-messages.
+       ncq[0].Type = MessageSync;
+       ncq[0].Data.Unit = htons(SyncHash&0xFFFF);
+       ncq[0].Data.X = htons(SyncRandSeed>>16);
+       ncq[0].Data.Y = htons(SyncRandSeed&0xFFFF);
+       ncq[0].Time = GameCycle + NetworkLag;
+       numcommands = 1;
+       DebugLevel3Fn("Empty Commands\n");
     } else {
-       DebugLevel3Fn("command in remove\n");
-       if (!dl_empty(CommandsIn)) {
-           ncq = (NetworkCommandQueue*)CommandsIn->last;
+       while( (!dl_empty(CommandsIn) || !dl_empty(MsgCommandsIn)) &&
+               numcommands < MaxNetworkCommands) {
+           DebugLevel3Fn("command in remove\n");
+           if (!dl_empty(CommandsIn)) {
+               incommand = (NetworkCommandQueue*)CommandsIn->last;
+               DebugLevel3Fn("Send Command: %lu T:%d\n" _C_ incommand->Time 
_C_ incommand->Type);
 #ifdef DEBUG
-           if (ncq->Data.Type != MessageExtendedCommand) {
-               // FIXME: we can send destoyed units over network :(
-               if (UnitSlots[ntohs(ncq->Data.Unit)]->Destroyed) {
-                   DebugLevel0Fn("Sending destroyed unit %d over 
network!!!!!!\n" _C_
-                       ntohs(ncq->Data.Unit));
-               }
-           }
+               if (incommand->Type != MessageExtendedCommand) {
+                   // FIXME: we can send destoyed units over network :(
+                   if (UnitSlots[ntohs(ncq->Data.Unit)]->Destroyed) {
+                       DebugLevel0Fn("Sending destroyed unit %d over 
network!!!!!!\n" _C_
+                           ntohs(incommand->Data.Unit));
+                   }
+               }
 #endif
-           dl_remove_last(CommandsIn);
-       } else {
-           ncq = (NetworkCommandQueue*)MsgCommandsIn->last;
-           dl_remove_last(MsgCommandsIn);
+               dl_remove_last(CommandsIn);
+           } else {
+               incommand = (NetworkCommandQueue*)MsgCommandsIn->last;
+               dl_remove_last(MsgCommandsIn);
+           }
+           memcpy(&ncq[numcommands],incommand,sizeof(NetworkCommandQueue));
+           ncq[numcommands].Time = GameCycle + NetworkLag;
+           ++numcommands;
        }
     }
 
-    // Insert in output queue.
-    dl_insert_first(CommandsOut, ncq->List);
-
-    // Fill in the time
-    ncq->Time = GameCycle + NetworkLag;
-    ncq->Data.Cycle = ncq->Time & 0xFF;
-    DebugLevel3Fn("sending for %d\n" _C_ ncq->Time);
+    if (numcommands != MaxNetworkCommands) {
+       ncq[numcommands].Type = MessageNone;
+    }
 
+    DebugLevel3Fn("sending for %lu \n" _C_ ncq[0]->Time);
     NetworkSendPacket(ncq);
 
-    NetworkSyncSeeds[ncq->Time & 0xFF] = SyncRandSeed;
-    NetworkSyncHashs[ncq->Time & 0xFF] = SyncHash & 0xFFFF;    // FIXME: 32bit 
later
+    NetworkSyncSeeds[(GameCycle + NetworkLag) & 0xFF] = SyncRandSeed;
+    NetworkSyncHashs[(GameCycle + NetworkLag) & 0xFF] = SyncHash & 0xFFFF;     
// FIXME: 32bit later
 }
 
 /**
@@ -1063,52 +1058,32 @@
 {
     NetworkCommandQueue* ncq;
     int i;
+    int c;
 
     //
     // Must execute commands on all computers in the same order.
     //
     for (i = 0; i < NumPlayers; ++i) {
-       if (i == ThisPlayer->Player) {
-           //
-           //  Remove outdated commands from queue
-           //
-           while (!dl_empty(CommandsOut)) {
-               ncq = (NetworkCommandQueue*)(CommandsOut->last);
-               // FIXME: how many packets must be kept exactly?
-               // if (ncq->Time + NetworkLag + NetworkUpdates >= GameCycle)
-               // THIS is too much if (ncq->Time >= GameCycle)
-               if (ncq->Time + NetworkLag > GameCycle) {
-                   break;
-               }
-               DebugLevel3Fn("remove %lu,%d\n" _C_ GameCycle _C_ ncq->Time);
-               dl_remove_last(CommandsOut);
-               free(ncq);
-           }
-           //
-           //  Execute local commands from queue
-           //
-           ncq = (NetworkCommandQueue*)(CommandsOut->last);
-           while (ncq->List->prev) {
-               if (ncq->Time == GameCycle) {
-                   DebugLevel3Fn("execute loc %lu,%d\n" _C_ GameCycle _C_ 
ncq->Time);
-                   ParseNetworkCommand(ncq);
-                   break;
-               }
-               ncq = (NetworkCommandQueue*)(ncq->List->prev);
+       //
+       // Remove commands.
+       //
+       for (c = 0; c < MaxNetworkCommands; ++c) {
+           ncq = &NetworkIn[GameCycle & 0xFF][i][c];
+           if (ncq->Type == MessageNone) {
+               break;
            }
-       } else {
-           //
-           //  Remove external commands.
-           //
-           ncq = &NetworkIn[GameCycle & 0xFF][i];
            if (ncq->Time) {
-               DebugLevel3Fn("execute net %lu,%d(%lx),%d\n" _C_
-                   GameCycle _C_ i _C_ GameCycle & 0xFF _C_ ncq->Time);
+#ifdef DEBUG
+               if (ncq->Type != MessageSync) {
+                   DebugLevel3Fn("execute net C:%lu,P:%d,T:%d\n" _C_
+                       ncq->Time _C_ i _C_ ncq->Type);
+               }
                if (ncq->Time != GameCycle) {
-                   DebugLevel2Fn("cycle %lu idx %lu time %lu\n" _C_
+                   DebugLevel1Fn("cycle %lu idx %lu time %lu\n" _C_
                        GameCycle _C_ GameCycle & 0xFF _C_ ncq->Time);
                    DebugCheck(ncq->Time != GameCycle);
                }
+#endif
                ParseNetworkCommand(ncq);
            }
        }
@@ -1131,9 +1106,9 @@
     n = GameCycle + NetworkUpdates;
     for (i = 0; i < HostsCount; ++i) {
        DebugLevel3Fn("sync %d\n" _C_ Hosts[i].PlyNr);
-       ncq = &NetworkIn[n & 0xFF][Hosts[i].PlyNr];
-       DebugLevel3Fn("sync %d==%d\n" _C_ ncq->Time _C_ n);
-       if (ncq->Time != n) {
+       ncq = NetworkIn[n & 0xFF][Hosts[i].PlyNr];
+       DebugLevel3Fn("sync %d==%d\n" _C_ ncq[0].Time _C_ n);
+       if (ncq[0].Time != n) {
            NetworkInSync = 0;
            NetworkDelay = FrameCounter + NetworkUpdates;
            // FIXME: should send a resend request.
@@ -1162,6 +1137,7 @@
     }
 }
 
+
 /**
 **     Recover network.
 */
@@ -1194,32 +1170,28 @@
                const NetworkCommandQueue* ncq;
                unsigned long n;
                NetworkPacket np;
-               int j;
 
                n = GameCycle + NetworkUpdates;
-               nc.Cycle = n & 0xFF;
-               nc.Type = MessageQuit;
                nc.X = Hosts[i].PlyNr;
-               NetworkIn[n & 0xFF][Hosts[i].PlyNr].Time = n;
-               NetworkIn[n & 0xFF][Hosts[i].PlyNr].Data = nc;
+               NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Time = n;
+               NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Type = MessageQuit;
+               NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Data = nc;
                PlayerQuit[Hosts[i].PlyNr] = 1;
                SetMessage("Timed out");
 
-               ncq = &NetworkIn[n & 0xFF][Hosts[i].PlyNr];
-               for (j = 0; j < NetworkDups; ++j) {
-                   np.Commands[j] = ncq->Data;
-               }
-               NetworkBroadcast(&np, sizeof(np));
+               ncq = &NetworkIn[n & 0xFF][Hosts[i].PlyNr][0];
+               np.Header.Cycle = ncq->Time & 0xFF;
+               np.Header.Type[0] = ncq->Type;
+               np.Header.Type[1] = MessageNone;
+
+               NetworkBroadcast(&np, sizeof(NetworkPacketHeader) + 
sizeof(NetworkCommand));
 
                NetworkSyncCommands();
            }
        }
 
        // Resend old commands
-       if (!dl_empty(CommandsOut)) {
-           DebugLevel3Fn("cycle %lu vi %d\n" _C_ GameCycle _C_ 
VideoInterrupts);
-           NetworkResendCommands();
-       }
+       NetworkResendCommands();
     }
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]