]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host_cmd.c
fix bug with items in a trap door in the ceiling in some usermade maps that made...
[xonotic/darkplaces.git] / host_cmd.c
index ebfd6d49a0a149bf0252c03dc1253a173dfa1dda..f23c658de52405b471309ecf77d2175e4238cba3 100644 (file)
@@ -55,7 +55,8 @@ void Host_Status_f (void)
 
        if (cmd_source == src_command)
        {
-               if (!sv.active)
+               // if running a client, try to send over network so the client's status report parser will see the report
+               if (cls.state == ca_connected)
                {
                        Cmd_ForwardToServer ();
                        return;
@@ -65,6 +66,9 @@ void Host_Status_f (void)
        else
                print = SV_ClientPrintf;
 
+       if (!sv.active)
+               return;
+
        for (players = 0, j = 0;j < svs.maxclients;j++)
                if (svs.clients[j].active)
                        players++;
@@ -88,7 +92,7 @@ void Host_Status_f (void)
                }
                else
                        hours = 0;
-               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->fields.server->frags, hours, minutes, seconds);
+               print ("#%-3u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->fields.server->frags, hours, minutes, seconds);
                print ("   %s\n", client->netconnection ? client->netconnection->address : "botclient");
        }
 }
@@ -213,6 +217,7 @@ Host_Ping_f
 
 ==================
 */
+void Host_Pings_f (void); // called by Host_Ping_f
 void Host_Ping_f (void)
 {
        int i;
@@ -221,7 +226,8 @@ void Host_Ping_f (void)
 
        if (cmd_source == src_command)
        {
-               if (!sv.active)
+               // if running a client, try to send over network so the client's ping report parser will see the report
+               if (cls.state == ca_connected)
                {
                        Cmd_ForwardToServer ();
                        return;
@@ -231,6 +237,9 @@ void Host_Ping_f (void)
        else
                print = SV_ClientPrintf;
 
+       if (!sv.active)
+               return;
+
        print("Client ping times:\n");
        for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
@@ -238,6 +247,9 @@ void Host_Ping_f (void)
                        continue;
                print("%4i %s\n", (int)floor(client->ping*1000+0.5), client->name);
        }
+
+       // now call the Pings command also, which will send a report that contains packet loss for the scoreboard (as well as a simpler ping report)
+       Host_Pings_f();
 }
 
 /*
@@ -2324,6 +2336,71 @@ void Host_Packet_f (void) // credit: taken from QuakeWorld
                NetConn_Write(mysocket, send, out - send, &address);
 }
 
+/*
+====================
+Host_Pings_f
+
+Send back ping and packet loss update for all current players to this player
+====================
+*/
+void Host_Pings_f (void)
+{
+       int             i, j, ping, packetloss;
+       char temp[128];
+
+       if (cmd_source == src_command)
+       {
+               Cmd_ForwardToServer ();
+               return;
+       }
+       if (!host_client->netconnection)
+               return;
+
+       if (sv.protocol != PROTOCOL_QUAKEWORLD)
+       {
+               MSG_WriteByte(&host_client->netconnection->message, svc_stufftext);
+               MSG_WriteUnterminatedString(&host_client->netconnection->message, "pingplreport");
+       }
+       for (i = 0;i < svs.maxclients;i++)
+       {
+               packetloss = 0;
+               if (svs.clients[i].netconnection)
+                       for (j = 0;j < 100;j++)
+                               packetloss += svs.clients[i].netconnection->packetlost[j];
+               ping = (int)floor(svs.clients[i].ping*1000+0.5);
+               ping = bound(0, ping, 9999);
+               if (sv.protocol == PROTOCOL_QUAKEWORLD)
+               {
+                       // send qw_svc_updateping and qw_svc_updatepl messages
+                       MSG_WriteByte(&host_client->netconnection->message, qw_svc_updateping);
+                       MSG_WriteShort(&host_client->netconnection->message, ping);
+                       MSG_WriteByte(&host_client->netconnection->message, qw_svc_updatepl);
+                       MSG_WriteByte(&host_client->netconnection->message, packetloss);
+               }
+               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);
+                       MSG_WriteUnterminatedString(&host_client->netconnection->message, temp);
+               }
+       }
+       if (sv.protocol != PROTOCOL_QUAKEWORLD)
+               MSG_WriteString(&host_client->netconnection->message, "\n");
+}
+
+void Host_PingPLReport_f(void)
+{
+       int i;
+       int l = Cmd_Argc();
+       if (l > cl.maxclients)
+               l = cl.maxclients;
+       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));
+       }
+}
+
 //=============================================================================
 
 /*
@@ -2415,6 +2492,9 @@ void Host_InitCommands (void)
        Cmd_AddCommand ("topcolor", Host_TopColor_f, "QW command to set top color without changing bottom color");
        Cmd_AddCommand ("bottomcolor", Host_BottomColor_f, "QW command to set bottom color without changing top color");
 
+       Cmd_AddCommand ("pings", Host_Pings_f, "command sent by clients to request updated ping and packetloss of players on scoreboard (originally from QW, but also used on NQ servers)");
+       Cmd_AddCommand ("pingplreport", Host_PingPLReport_f, "command sent by server containing client ping and packet loss values for scoreboard, triggered by pings command from client (not used by QW servers)");
+
        Cvar_RegisterVariable (&team);
        Cvar_RegisterVariable (&skin);
        Cvar_RegisterVariable (&noaim);