]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
protocol/dp8: Implement parting messages
authorCloudwalk <cloudwalk009@gmail.com>
Thu, 22 Jul 2021 01:31:30 +0000 (21:31 -0400)
committerCloudwalk <cloudwalk009@gmail.com>
Thu, 22 Jul 2021 01:31:30 +0000 (21:31 -0400)
* Extended CL_Disconnect and SV_DropClient for this purpose.
* Add a string parameter to svc_disconnect and clc_disconnect, which
  shall contain the parting message.

19 files changed:
cl_demo.c
cl_input.c
cl_main.c
cl_parse.c
client.h
common.h
csprogs.c
fs.c
host.c
host.h
libcurl.c
netconn.c
server.h
sv_ccmds.c
sv_main.c
sv_save.c
sv_send.c
sv_user.c
svvm_cmds.c

index eb4ab55e933592bbace8c10a2220e6970c9bd93d..4c826c0db6fffa0494df5d3c73126ba9ea90f47c 100644 (file)
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -256,9 +256,8 @@ void CL_ReadDemoMessage(void)
                }
                if (cl_message.cursize > cl_message.maxsize)
                {
-                       Con_Printf("Demo message (%i) > cl_message.maxsize (%i)", cl_message.cursize, cl_message.maxsize);
+                       CL_Disconnect(false, "Demo message (%i) > cl_message.maxsize (%i)", cl_message.cursize, cl_message.maxsize);
                        cl_message.cursize = 0;
-                       CL_Disconnect();
                        return;
                }
                VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
@@ -285,7 +284,7 @@ void CL_ReadDemoMessage(void)
                }
                else
                {
-                       CL_Disconnect();
+                       CL_Disconnect(false, NULL);
                        return;
                }
        }
@@ -364,7 +363,7 @@ void CL_Record_f(cmd_state_t *cmd)
        }
 
        if (cls.state == ca_connected)
-               CL_Disconnect();
+               CL_Disconnect(false, NULL);
 
        // write the forced cd track number, or -1
        if (c == 4)
@@ -422,7 +421,7 @@ void CL_PlayDemo(const char *demo)
        cls.demostarting = true;
 
        // disconnect from server
-       CL_Disconnect();
+       CL_Disconnect(false, NULL);
 
        // update networking ports (this is mainly just needed at startup)
        NetConn_UpdateSockets();
@@ -680,7 +679,7 @@ static void CL_Demos_f(cmd_state_t *cmd)
                return;
        if (cls.demonum == -1)
                cls.demonum = 1;
-       CL_Disconnect();
+       CL_Disconnect(false, NULL);
        CL_NextDemo();
 }
 
@@ -695,7 +694,7 @@ static void CL_Stopdemo_f(cmd_state_t *cmd)
 {
        if (!cls.demoplayback)
                return;
-       CL_Disconnect();
+       CL_Disconnect(false, NULL);
 }
 
 // LadyHavoc: pausedemo command
index ebc508677d81f36c3608f95132fb8654c26be23b..7c5598ca54960ff1666673a5efaeb4ca52060193 100644 (file)
@@ -2167,10 +2167,7 @@ void CL_SendMove(void)
        in_impulse = 0;
 
        if (cls.netcon->message.overflowed)
-       {
-               Con_Print("CL_SendMove: lost server connection\n");
-               CL_Disconnect();
-       }
+               CL_Disconnect(true, "Lost connection to server");
 }
 
 /*
index 6d46bc77046e9c2ed0d74ac8999ce62468ed823e..e4d56733a18ba40c7f93b5ce241f1d1e35b2b46f 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -360,11 +360,25 @@ Sends a disconnect message to the server
 This is also called on Host_Error, so it shouldn't cause any errors
 =====================
 */
-void CL_Disconnect(void)
+void CL_Disconnect(qbool kicked, const char *fmt, ... )
 {
+       va_list argptr;
+       char reason[512];
+
        if (cls.state == ca_dedicated)
                return;
 
+       if(fmt)
+       {
+               va_start(argptr,fmt);
+               dpvsnprintf(reason,sizeof(reason),fmt,argptr);
+               va_end(argptr);
+       }
+       else
+       {
+               dpsnprintf(reason, sizeof(reason), "Disconnect by user");
+       }
+
        if (Sys_CheckParm("-profilegameonly"))
                Sys_AllowProfiling(false);
 
@@ -395,32 +409,41 @@ void CL_Disconnect(void)
        else if (cls.netcon)
        {
                sizebuf_t buf;
-               unsigned char bufdata[8];
+               unsigned char bufdata[520];
                if (cls.demorecording)
                        CL_Stop_f(cmd_local);
 
-               // send disconnect message 3 times to improve chances of server
-               // receiving it (but it still fails sometimes)
-               memset(&buf, 0, sizeof(buf));
-               buf.data = bufdata;
-               buf.maxsize = sizeof(bufdata);
-               if (cls.protocol == PROTOCOL_QUAKEWORLD)
-               {
-                       Con_DPrint("Sending drop command\n");
-                       MSG_WriteByte(&buf, qw_clc_stringcmd);
-                       MSG_WriteString(&buf, "drop");
-               }
-               else
+               if(!kicked)
                {
-                       Con_DPrint("Sending clc_disconnect\n");
-                       MSG_WriteByte(&buf, clc_disconnect);
+                       // send disconnect message 3 times to improve chances of server
+                       // receiving it (but it still fails sometimes)
+                       memset(&buf, 0, sizeof(buf));
+                       buf.data = bufdata;
+                       buf.maxsize = sizeof(bufdata);
+                       if (cls.protocol == PROTOCOL_QUAKEWORLD)
+                       {
+                               Con_DPrint("Sending drop command\n");
+                               MSG_WriteByte(&buf, qw_clc_stringcmd);
+                               MSG_WriteString(&buf, "drop");
+                       }
+                       else
+                       {
+                               Con_DPrint("Sending clc_disconnect\n");
+                               MSG_WriteByte(&buf, clc_disconnect);
+                               if(cls.protocol == PROTOCOL_DARKPLACES8)
+                                       MSG_WriteString(&buf, reason);
+                       }
+                       NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000, 0, false);
+                       NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000, 0, false);
+                       NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000, 0, false);
                }
-               NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000, 0, false);
-               NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000, 0, false);
-               NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000, 0, false);
+
                NetConn_Close(cls.netcon);
                cls.netcon = NULL;
-               Con_Printf("Disconnected\n");
+               if(fmt)
+                       Con_Printf("Disconnect: %s\n", reason);
+               else
+                       Con_Printf("Disconnected\n");
        }
        cls.state = ca_disconnected;
        cl.islocalgame = false;
@@ -515,7 +538,7 @@ static void CL_Connect_f(cmd_state_t *cmd)
 
 void CL_Disconnect_f(cmd_state_t *cmd)
 {
-       CL_Disconnect();
+       CL_Disconnect(false, Cmd_Argc(cmd) > 1 ? Cmd_Argv(cmd, 1) : NULL);
 }
 
 
@@ -2909,7 +2932,7 @@ void CL_Shutdown (void)
        S_StopAllSounds();
        
        // disconnect client from server if active
-       CL_Disconnect();
+       CL_Disconnect(false, NULL);
        
        CL_Video_Shutdown();
 
index 7dfd3a953b81be633bf108bc7a107da958a78d49..5cbcb8b269c27b7d4563d3f3ac3138d61f5ec04e 100644 (file)
@@ -35,7 +35,7 @@ const char *svc_strings[128] =
 {
        "svc_bad",
        "svc_nop",
-       "svc_disconnect",
+       "svc_disconnect",       // (DP8) [string] null terminated parting message
        "svc_updatestat",
        "svc_version",          // [int] server version
        "svc_setview",          // [short] entity number
@@ -3531,7 +3531,7 @@ void CL_ParseServerMessage(void)
                                if (cls.demonum != -1)
                                        CL_NextDemo();
                                else
-                                       CL_Disconnect();
+                                       CL_Disconnect(true, NULL);
                                break;
 
                        case qw_svc_print:
@@ -3911,7 +3911,7 @@ void CL_ParseServerMessage(void)
                                if (cls.demonum != -1)
                                        CL_NextDemo();
                                else
-                                       CL_Disconnect();
+                                       CL_Disconnect(true, cls.protocol == PROTOCOL_DARKPLACES8 ? MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)) : NULL);
                                break;
 
                        case svc_print:
index 8e6d0f50dba4625435d23164ce20accc2242c33d..3e007c70bde34b181c6f6739917f2a2e4def9d21 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1223,7 +1223,7 @@ void CL_StartVideo(void);
 
 void CL_EstablishConnection(const char *host, int firstarg);
 
-void CL_Disconnect (void);
+void CL_Disconnect (qbool kicked, const char *reason, ... );
 void CL_Disconnect_f(cmd_state_t *cmd);
 
 void CL_UpdateRenderEntity(entity_render_t *ent);
index 95a12ab3b98c081c04573ab7e9531df8262a8e79..169d989bd257a82c12b0eab8a7673e2565b29526 100644 (file)
--- a/common.h
+++ b/common.h
@@ -131,7 +131,7 @@ void StoreLittleShort (unsigned char *buffer, unsigned short i);
 typedef enum protocolversion_e
 {
        PROTOCOL_UNKNOWN,
-       PROTOCOL_DARKPLACES8, ///< wip
+       PROTOCOL_DARKPLACES8, ///< added parting messages. WIP
        PROTOCOL_DARKPLACES7, ///< added QuakeWorld-style movement protocol to allow more consistent prediction
        PROTOCOL_DARKPLACES6, ///< various changes
        PROTOCOL_DARKPLACES5, ///< uses EntityFrame5 entity snapshot encoder/decoder which is based on a Tribes networking article at http://www.garagegames.com/articles/networking1/
index 9800fe0a907fecff8507ee1ed21e4ad84d502f2d..47ac1ef22a4b77b627fb85ce47de3523e9326943 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -1043,8 +1043,7 @@ void CL_VM_Init (void)
                        else
                        {
                                Mem_Free(csprogsdata);
-                               Con_Printf(CON_ERROR "Your %s is not the same version as the server (CRC is %i/%i but should be %i/%i)\n", csqc_progname.string, csprogsdatacrc, (int)csprogsdatasize, requiredcrc, requiredsize);
-                               CL_Disconnect();
+                               CL_Disconnect(false, "Your %s is not the same version as the server (CRC is %i/%i but should be %i/%i)\n", csqc_progname.string, csprogsdatacrc, (int)csprogsdatasize, requiredcrc, requiredsize);
                                return;
                        }
                }
@@ -1052,13 +1051,7 @@ void CL_VM_Init (void)
        else
        {
                if (requiredcrc >= 0)
-               {
-                       if (cls.demoplayback)
-                               Con_Printf(CON_ERROR "CL_VM_Init: demo requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string);
-                       else
-                               Con_Printf(CON_ERROR "CL_VM_Init: server requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string);
-                       CL_Disconnect();
-               }
+                       CL_Disconnect(false, CON_ERROR "CL_VM_Init: %s requires CSQC, but \"%s\" wasn't found\n", cls.demoplayback ? "demo" : "server", csqc_progname.string);
                return;
        }
 
@@ -1094,11 +1087,8 @@ void CL_VM_Init (void)
 
        if (!prog->loaded)
        {
-               Host_Error("CSQC %s failed to load\n", csprogsfn);
-               if(!sv.active)
-                       CL_Disconnect();
                Mem_Free(csprogsdata);
-               return;
+               Host_Error("CSQC %s failed to load\n", csprogsfn);
        }
 
        if(cls.demorecording)
diff --git a/fs.c b/fs.c
index f5e67b36519bb7d39cfcc472a2a681162ef166e9..97259f722eb73534781b23c7e3d835cc3733ec06 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -1577,7 +1577,7 @@ qbool FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qbool compl
 
        if (cls.demoplayback)
        {
-               CL_Disconnect();
+               CL_Disconnect(false, NULL);
                cls.demonum = 0;
        }
 
@@ -1628,7 +1628,7 @@ static void FS_GameDir_f(cmd_state_t *cmd)
        }
 
        // halt demo playback to close the file
-       CL_Disconnect();
+       CL_Disconnect(false, NULL);
 
        FS_ChangeGameDirs(numgamedirs, gamedirs, true, true);
 }
diff --git a/host.c b/host.c
index e196fe79ce167f064ccf6bd00be6b6a1edd7b90b..21650a24c9f1f190f0349e80c9b8c93bd0fe56cf 100644 (file)
--- a/host.c
+++ b/host.c
@@ -134,7 +134,7 @@ void Host_Error (const char *error, ...)
        if (cls.state == ca_dedicated)
                Sys_Error ("Host_Error: %s",hosterrorstring2);  // dedicated servers exit
 
-       CL_Disconnect ();
+       CL_Disconnect (false, NULL);
        cls.demonum = -1;
 
        hosterror = false;
diff --git a/host.h b/host.h
index 4521f72b7983a50c57b60b436520613e91222f2e..26465423839b5523830ae599f25370180699f1c6 100644 (file)
--- a/host.h
+++ b/host.h
@@ -31,7 +31,7 @@ typedef struct host_static_s
        struct
        {
                void (*ConnectLocal)(void);
-               void (*Disconnect)(void);
+               void (*Disconnect)(qbool, const char *, ... );
                void (*ToggleMenu)(void);
                qbool (*CL_Intermission)(void); // Quake compatibility
                void (*CL_SendCvar)(struct cmd_state_s *);
index c29a189426b3c3abef143d51e6ac619df817d8d1..f71dfaafc6beef6ebd4673dca9ffbb7aa69681e1 100644 (file)
--- a/libcurl.c
+++ b/libcurl.c
@@ -1494,7 +1494,7 @@ static void Curl_Curl_f(cmd_state_t *cmd)
                                                dpsnprintf(donecommand, sizeof(donecommand), "connect %s", cls.netcon->address);
                                                Curl_CommandWhenDone(donecommand);
                                                noclear = true;
-                                               CL_Disconnect();
+                                               CL_Disconnect(false, NULL);
                                                noclear = false;
                                                Curl_CheckCommandWhenDone();
                                        }
index 1ec19fcdb7d5cc372117b67c83c1673888a6c6ac..ac481ca6df030e6d3d602ce11f0885880ab81b72 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -1529,7 +1529,7 @@ static void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_
 #endif
        // Disconnect from the current server or stop demo playback
        if(cls.state == ca_connected || cls.demoplayback)
-               CL_Disconnect();
+               CL_Disconnect(false, NULL);
        // allocate a net connection to keep track of things
        cls.netcon = NetConn_Open(mysocket, peeraddress);
        crypto = &cls.netcon->crypto;
@@ -2488,10 +2488,7 @@ void NetConn_ClientFrame(void)
        NetConn_QueryQueueFrame();
 #endif
        if (cls.netcon && host.realtime > cls.netcon->timeout && !sv.active)
-       {
-               Con_Print("Connection timed out\n");
-               CL_Disconnect();
-       }
+               CL_Disconnect(true, "Connection timed out");
 }
 
 static void NetConn_BuildChallengeString(char *buffer, int bufferlength)
index 07639e4b5f52c530fa71cc50e974fe12201fc95d..02d3786bb6319ec8450539e9695b7d15f69bb472 100644 (file)
--- a/server.h
+++ b/server.h
@@ -515,7 +515,7 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v
 void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation, float speed);
 
 void SV_ConnectClient (int clientnum, netconn_t *netconnection);
-void SV_DropClient (qbool crash);
+void SV_DropClient (qbool leaving, const char *reason, ... );
 
 void SV_ClientCommands(const char *fmt, ...) DP_FUNC_PRINTF(1);
 
index 639a3253a42b62b6c580fe80a152b3e3d3b3e4ca..036f4c63f1588cae58155a02479a9ec77f9ae1b7 100644 (file)
@@ -62,7 +62,7 @@ static void SV_Map_f(cmd_state_t *cmd)
                Cvar_Set(&cvars_all, "warpmark", "");
 
        if(host.hook.Disconnect)
-               host.hook.Disconnect();
+               host.hook.Disconnect(false, NULL);
 
        SV_Shutdown();
 
@@ -1026,6 +1026,7 @@ static void SV_Kick_f(cmd_state_t *cmd)
 {
        const char *who;
        const char *message = NULL;
+       char reason[512];
        client_t *save;
        int i;
        qbool byNumber = false;
@@ -1084,10 +1085,11 @@ static void SV_Kick_f(cmd_state_t *cmd)
                                message++;
                }
                if (message)
-                       SV_ClientPrintf("Kicked by %s: %s\n", who, message);
+                       SV_DropClient (false, va(reason, sizeof(reason), "Kicked by %s: %s", who, message)); // kicked
+                       //SV_ClientPrintf("Kicked by %s: %s\n", who, message);
                else
-                       SV_ClientPrintf("Kicked by %s\n", who);
-               SV_DropClient (false); // kicked
+                       //SV_ClientPrintf("Kicked by %s\n", who);
+                       SV_DropClient (false, va(reason, sizeof(reason), "Kicked by %s", who)); // kicked
        }
 
        host_client = save;
index 956b22acad367463cb547de78645fcbe8f1bfb73..777d3e577959ff730fbaa2ce4a53a34f46d1dce6 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -984,14 +984,31 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
 SV_DropClient
 
 Called when the player is getting totally kicked off the host
-if (crash = true), don't bother sending signofs
+if (leaving = true), don't bother sending signofs
 =====================
 */
-void SV_DropClient(qbool crash)
+void SV_DropClient(qbool leaving, const char *fmt, ... )
 {
        prvm_prog_t *prog = SVVM_prog;
        int i;
-       Con_Printf("Client \"%s\" dropped\n", host_client->name);
+
+       va_list argptr;
+       char reason[512] = "";
+
+       Con_Printf("Client \"%s\" dropped", host_client->name);
+
+       if(fmt)
+       {
+               va_start(argptr, fmt);
+               dpvsnprintf(reason, sizeof(reason), fmt, argptr);
+               va_end(argptr);
+
+               Con_Printf(" (%s)\n", reason);
+       }
+       else
+       {
+               Con_Printf(" \n");
+       }
 
        SV_StopDemoRecording(host_client);
 
@@ -1001,15 +1018,22 @@ void SV_DropClient(qbool crash)
        if (host_client->netconnection)
        {
                // tell the client to be gone
-               if (!crash)
+               if (!leaving)
                {
                        // LadyHavoc: no opportunity for resending, so use unreliable 3 times
-                       unsigned char bufdata[8];
+                       unsigned char bufdata[520]; // Disconnect reason string can be 512 characters
                        sizebuf_t buf;
                        memset(&buf, 0, sizeof(buf));
                        buf.data = bufdata;
                        buf.maxsize = sizeof(bufdata);
                        MSG_WriteByte(&buf, svc_disconnect);
+                       if(fmt)
+                       {
+                               if(sv.protocol == PROTOCOL_DARKPLACES8)
+                                       MSG_WriteString(&buf, reason);
+                               else
+                                       SV_ClientPrintf("%s\n", reason);
+                       }
                        NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
                        NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
                        NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
@@ -1037,6 +1061,10 @@ void SV_DropClient(qbool crash)
                NetConn_Close(host_client->netconnection);
                host_client->netconnection = NULL;
        }
+       if(fmt)
+               SV_BroadcastPrintf("\003^3%s left the game (%s)\n", host_client->name, reason);
+       else
+               SV_BroadcastPrintf("\003^3%s left the game\n", host_client->name);
 
        // if a download is active, close it
        if (host_client->download_file)
@@ -2083,7 +2111,7 @@ void SV_Shutdown(void)
        }
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                if (host_client->active)
-                       SV_DropClient(false); // server shutdown
+                       SV_DropClient(false, "Server shutting down"); // server shutdown
 
        NetConn_CloseServerPorts();
 
@@ -2446,17 +2474,8 @@ static void SV_CheckTimeouts(void)
 
        // never timeout loopback connections
        for (i = (host_isclient.integer ? 1 : 0), host_client = &svs.clients[i]; i < svs.maxclients; i++, host_client++)
-       {
                if (host_client->netconnection && host.realtime > host_client->netconnection->timeout)
-               {
-                       if (host_client->begun)
-                               SV_BroadcastPrintf("Client \"%s\" connection timed out\n", host_client->name);
-                       else
-                               Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
-
-                       SV_DropClient(false);
-               }
-       }
+                       SV_DropClient(false, "Timed out");
 }
 
 /*
index 926c90c95da913cef885e920dea6f377c65c697d..814e2db13cdad1f34ce03671438b81c2618516fa 100644 (file)
--- a/sv_save.c
+++ b/sv_save.c
@@ -272,7 +272,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
 
        // stop playing demos
        if (cls.demoplayback)
-               CL_Disconnect ();
+               CL_Disconnect (false, NULL);
 
 #ifdef CONFIG_MENU
        // remove menu
index c42cbc69a237077ce396a62642ad40986891ab3b..a1ee1050ab3cb69b14251c0be1bdc3b7ef165e27 100644 (file)
--- a/sv_send.c
+++ b/sv_send.c
@@ -1712,7 +1712,7 @@ void SV_SendClientMessages(void)
 
                if (host_client->netconnection->message.overflowed)
                {
-                       SV_DropClient (true);   // if the message couldn't send, kick off
+                       SV_DropClient (true, "Buffer overflow in net message"); // if the message couldn't send, kick off
                        continue;
                }
 
index ff1bdbc3b6ab0f8d742e3ffb321266b4a867759b..6a621bac6d293c9ec2a573187e7ee821f1f805c9 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -999,14 +999,14 @@ void SV_ReadClientMessage(void)
                if (!host_client->active)
                {
                        // a command caused an error
-                       SV_DropClient (false);
+                       SV_DropClient (false, "Connection closing");
                        return;
                }
 
                if (sv_message.badread)
                {
                        Con_Print("SV_ReadClientMessage: badread\n");
-                       SV_DropClient (false);
+                       SV_DropClient (false, "An internal server error occurred");
                        return;
                }
 
@@ -1025,7 +1025,7 @@ void SV_ReadClientMessage(void)
                        Con_Printf("SV_ReadClientMessage: unknown command char %i (at offset 0x%x)\n", netcmd, sv_message.readcount);
                        if (developer_networking.integer)
                                Com_HexDumpToConsole(sv_message.data, sv_message.cursize);
-                       SV_DropClient (false);
+                       SV_DropClient (false, "Unknown message sent to the server");
                        return;
 
                case clc_nop:
@@ -1076,7 +1076,9 @@ clc_stringcmd_invalid:
                        break;
 
                case clc_disconnect:
-                       SV_DropClient (false); // client wants to disconnect
+                       SV_DropClient (true, sv.protocol == PROTOCOL_DARKPLACES8
+                                      ? MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring))
+                                      : "Disconnect by user"); // client wants to disconnect
                        return;
 
                case clc_move:
index 249e186d294e2c82a17efeb7be5217311b2f2321..672ff70d1f8e7116237d6f81737fe2b8012a014b 100644 (file)
@@ -2657,7 +2657,7 @@ static void VM_SV_dropclient(prvm_prog_t *prog)
        }
        oldhostclient = host_client;
        host_client = svs.clients + clientnum;
-       SV_DropClient(false);
+       SV_DropClient(false, "Client dropped");
        host_client = oldhostclient;
 }