From 782901070b01c04dcafcab9b8d27e8c231bccede Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 21 Dec 2009 12:31:10 +0000 Subject: [PATCH] movement packet loss tracking git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9630 d7cf8633-e32d-0410-b094-e92efae38249 --- client.h | 1 + clvm_cmds.c | 3 +++ host_cmd.c | 25 ++++++++++++++++++++----- server.h | 2 ++ sv_main.c | 2 ++ sv_user.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+), 5 deletions(-) diff --git a/client.h b/client.h index 607c539e..38cf7b84 100644 --- 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]; diff --git a/clvm_cmds.c b/clvm_cmds.c index 9815a9d2..43413c77 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -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); diff --git a/host_cmd.c b/host_cmd.c index 7cbfe00f..635882da 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -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; } } diff --git a/server.h b/server.h index 1c370d43..72ea9dee 100644 --- 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 diff --git a/sv_main.c b/sv_main.c index a45dfc7a..160fb56c 100644 --- 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; diff --git a/sv_user.c b/sv_user.c index 6d9a39d1..b545b8b9 100644 --- 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) -- 2.39.2