movement packet loss tracking
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 21 Dec 2009 12:31:10 +0000 (12:31 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 21 Dec 2009 12:31:10 +0000 (12:31 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9630 d7cf8633-e32d-0410-b094-e92efae38249

client.h
clvm_cmds.c
host_cmd.c
server.h
sv_main.c
sv_user.c

index 607c539..38cf7b8 100644 (file)
--- a/client.h
+++ b/client.h
@@ -478,6 +478,7 @@ typedef struct scoreboard_s
        float   qw_entertime;
        int             qw_ping;
        int             qw_packetloss;
+       int             qw_movementloss;
        int             qw_spectator;
        char    qw_team[8];
        char    qw_skin[MAX_QPATH];
index 9815a9d..43413c7 100644 (file)
@@ -1246,6 +1246,9 @@ static void VM_CL_getplayerkey (void)
        else
                if(!strcasecmp(c, "pl"))
                        dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_packetloss);
+       else
+               if(!strcasecmp(c, "movementloss"))
+                       dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_movementloss);
        else
                if(!strcasecmp(c, "entertime"))
                        dpsnprintf(t, sizeof(t), "%f", cl.scores[i].qw_entertime);
index 7cbfe00..635882d 100644 (file)
@@ -142,7 +142,7 @@ void Host_Status_f (void)
                                for (j = 0;j < NETGRAPH_PACKETS;j++)
                                        if (client->netconnection->incoming_netgraph[j].unreliablebytes == NETGRAPH_LOSTPACKET)
                                                packetloss++;
-                       packetloss = packetloss * 100 / NETGRAPH_PACKETS;
+                       packetloss = (packetloss * 100 + NETGRAPH_PACKETS - 1) / NETGRAPH_PACKETS;
                        ping = bound(0, (int)floor(client->ping*1000+0.5), 9999);
                }
 
@@ -2712,7 +2712,7 @@ Send back ping and packet loss update for all current players to this player
 */
 void Host_Pings_f (void)
 {
-       int             i, j, ping, packetloss;
+       int             i, j, ping, packetloss, movementloss;
        char temp[128];
 
        if (!host_client->netconnection)
@@ -2726,11 +2726,18 @@ void Host_Pings_f (void)
        for (i = 0;i < svs.maxclients;i++)
        {
                packetloss = 0;
+               movementloss = 0;
                if (svs.clients[i].netconnection)
+               {
                        for (j = 0;j < NETGRAPH_PACKETS;j++)
                                if (svs.clients[i].netconnection->incoming_netgraph[j].unreliablebytes == NETGRAPH_LOSTPACKET)
                                        packetloss++;
-               packetloss = packetloss * 100 / NETGRAPH_PACKETS;
+                       for (j = 0;j < NETGRAPH_PACKETS;j++)
+                               if (svs.clients[i].movement_count[j] < 0)
+                                       movementloss++;
+               }
+               packetloss = (packetloss * 100 + NETGRAPH_PACKETS - 1) / NETGRAPH_PACKETS;
+               movementloss = (movementloss * 100 + NETGRAPH_PACKETS - 1) / NETGRAPH_PACKETS;
                ping = (int)floor(svs.clients[i].ping*1000+0.5);
                ping = bound(0, ping, 9999);
                if (sv.protocol == PROTOCOL_QUAKEWORLD)
@@ -2744,7 +2751,10 @@ void Host_Pings_f (void)
                else
                {
                        // write the string into the packet as multiple unterminated strings to avoid needing a local buffer
-                       dpsnprintf(temp, sizeof(temp), " %d %d", ping, packetloss);
+                       if(movementloss)
+                               dpsnprintf(temp, sizeof(temp), " %d %d,%d", ping, packetloss, movementloss);
+                       else
+                               dpsnprintf(temp, sizeof(temp), " %d %d", ping, packetloss);
                        MSG_WriteUnterminatedString(&host_client->netconnection->message, temp);
                }
        }
@@ -2754,6 +2764,7 @@ void Host_Pings_f (void)
 
 void Host_PingPLReport_f(void)
 {
+       char **errbyte;
        int i;
        int l = Cmd_Argc();
        if (l > cl.maxclients)
@@ -2761,7 +2772,11 @@ void Host_PingPLReport_f(void)
        for (i = 0;i < l;i++)
        {
                cl.scores[i].qw_ping = atoi(Cmd_Argv(1+i*2));
-               cl.scores[i].qw_packetloss = atoi(Cmd_Argv(1+i*2+1));
+               cl.scores[i].qw_packetloss = strtol(Cmd_Argv(1+i*2+1), &errbyte, 0);
+               if(errbyte && *errbyte == ',')
+                       cl.scores[i].qw_movementloss = atoi(errbyte + 1);
+               else
+                       cl.scores[i].qw_movementloss = 0;
        }
 }
 
index 1c370d4..72ea9de 100644 (file)
--- a/server.h
+++ b/server.h
@@ -199,6 +199,8 @@ typedef struct client_s
        netconn_t *netconnection;
 
        int movesequence;
+       signed char movement_count[NETGRAPH_PACKETS];
+       int movement_highestsequence_seen; // not the same as movesequence if prediction is off
        /// movement
        usercmd_t cmd;
        /// intended motion calced from cmd
index a45dfc7..160fb56 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -938,6 +938,8 @@ void SV_SendServerinfo (client_t *client)
        // clear movement info until client enters the new level properly
        memset(&client->cmd, 0, sizeof(client->cmd));
        client->movesequence = 0;
+       client->movement_highestsequence_seen = 0;
+       memset(&client->movement_count, 0, sizeof(client->movement_count));
 #ifdef NUM_PING_TIMES
        for (i = 0;i < NUM_PING_TIMES;i++)
                client->ping_times[i] = 0;
index 6d9a39d..b545b8b 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -544,6 +544,35 @@ void SV_ReadClientMove (void)
        // (we have to buffer the moves because of old ones being repeated)
        if (sv_numreadmoves < CL_MAX_USERCMDS)
                sv_readmoves[sv_numreadmoves++] = *move;
+
+       // movement packet loss tracking
+       if(move->sequence)
+       {
+               if(move->sequence > host_client->movement_highestsequence_seen)
+               {
+                       if(host_client->movement_highestsequence_seen)
+                       {
+                               // mark moves in between as lost
+                               if(move->sequence - host_client->movement_highestsequence_seen < NETGRAPH_PACKETS)
+                                       for(i = host_client->movement_highestsequence_seen; i < move->sequence; ++i)
+                                               host_client->movement_count[i % NETGRAPH_PACKETS] = -1;
+                               else
+                                       memset(host_client->movement_count, -1, sizeof(host_client->movement_count));
+                       }
+                       // mark THIS move as seen for the first time
+                       host_client->movement_count[move->sequence % NETGRAPH_PACKETS] = 1;
+                       // update highest sequence seen
+                       host_client->movement_highestsequence_seen = move->sequence;
+               }
+               else
+                       if(host_client->movement_count[move->sequence % NETGRAPH_PACKETS] >= 0)
+                               ++host_client->movement_count[move->sequence % NETGRAPH_PACKETS];
+       }
+       else
+       {
+               host_client->movement_highestsequence_seen = 0;
+               memset(host_client->movement_count, 0, sizeof(host_client->movement_count));
+       }
 }
 
 void SV_ExecuteClientMoves(void)