migrated cls.message and client->message buffers into netconn_t struct
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 11 Feb 2006 02:33:30 +0000 (02:33 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 11 Feb 2006 02:33:30 +0000 (02:33 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5960 d7cf8633-e32d-0410-b094-e92efae38249

15 files changed:
cl_main.c
cl_parse.c
client.h
cmd.c
common.c
common.h
host.c
host_cmd.c
mvm_cmds.c
netconn.c
netconn.h
prvm_cmds.c
server.h
sv_main.c
svvm_cmds.c

index c39741b..346ebdd 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -146,8 +146,6 @@ void CL_ClearState(void)
        // reset the view zoom interpolation
        cl.mviewzoom[0] = cl.mviewzoom[1] = 1;
 
-       SZ_Clear (&cls.message);
-
        cl_num_entities = 0;
        cl_num_csqcentities = 0;        //[515]: csqc
        cl_num_static_entities = 0;
@@ -302,14 +300,21 @@ void CL_Disconnect(void)
                CL_StopPlayback();
        else if (cls.netcon)
        {
+               sizebuf_t buf;
+               unsigned char bufdata[8];
                if (cls.demorecording)
                        CL_Stop_f();
 
+               // send clc_disconnect 3 times to improve chances of server receiving
+               // it (but it still fails sometimes)
                Con_DPrint("Sending clc_disconnect\n");
-               SZ_Clear(&cls.message);
-               MSG_WriteByte(&cls.message, clc_disconnect);
-               NetConn_SendUnreliableMessage(cls.netcon, &cls.message);
-               SZ_Clear(&cls.message);
+               memset(&buf, 0, sizeof(buf));
+               buf.data = bufdata;
+               buf.maxsize = sizeof(bufdata);
+               MSG_WriteByte(&buf, clc_disconnect);
+               NetConn_SendUnreliableMessage(cls.netcon, &buf);
+               NetConn_SendUnreliableMessage(cls.netcon, &buf);
+               NetConn_SendUnreliableMessage(cls.netcon, &buf);
                NetConn_Close(cls.netcon);
                cls.netcon = NULL;
        }
@@ -1528,23 +1533,17 @@ CL_SendCmd
 void CL_UpdatePrydonCursor(void);
 void CL_SendCmd(void)
 {
-       if (cls.demoplayback)
-       {
-               SZ_Clear(&cls.message);
-               return;
-       }
-
        // send the reliable message (forwarded commands) if there is one
-       if (cls.message.cursize && NetConn_CanSendMessage(cls.netcon))
+       if (cls.netcon && cls.netcon->message.cursize && NetConn_CanSendMessage(cls.netcon))
        {
                if (developer.integer)
                {
                        Con_Print("CL_SendCmd: sending reliable message:\n");
-                       SZ_HexDumpToConsole(&cls.message);
+                       SZ_HexDumpToConsole(&cls.netcon->message);
                }
-               if (NetConn_SendReliableMessage(cls.netcon, &cls.message) == -1)
+               if (NetConn_SendReliableMessage(cls.netcon, &cls.netcon->message) == -1)
                        Host_Error("CL_WriteToServer: lost server connection");
-               SZ_Clear(&cls.message);
+               SZ_Clear(&cls.netcon->message);
        }
 }
 
@@ -1636,10 +1635,6 @@ void CL_Init (void)
        r_refdef.maxdrawqueuesize = 256 * 1024;
        r_refdef.drawqueue = (unsigned char *)Mem_Alloc(cl_mempool, r_refdef.maxdrawqueuesize);
 
-       cls.message.data = cls.message_buf;
-       cls.message.maxsize = sizeof(cls.message_buf);
-       cls.message.cursize = 0;
-
        CL_InitInput ();
 
 //
index aa58c51..f1cc56c 100644 (file)
@@ -268,50 +268,57 @@ An svc_signonnum has been received, perform a client side setup
 */
 static void CL_SignonReply (void)
 {
-       //char  str[8192];
-
-Con_DPrintf("CL_SignonReply: %i\n", cls.signon);
+       Con_DPrintf("CL_SignonReply: %i\n", cls.signon);
 
        switch (cls.signon)
        {
        case 1:
-               MSG_WriteByte (&cls.message, clc_stringcmd);
-               MSG_WriteString (&cls.message, "prespawn");
+               if (cls.netcon)
+               {
+                       MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                       MSG_WriteString (&cls.netcon->message, "prespawn");
+               }
                break;
 
        case 2:
-               MSG_WriteByte (&cls.message, clc_stringcmd);
-               MSG_WriteString (&cls.message, va("name \"%s\"", cl_name.string));
+               if (cls.netcon)
+               {
+                       MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                       MSG_WriteString (&cls.netcon->message, va("name \"%s\"", cl_name.string));
 
-               MSG_WriteByte (&cls.message, clc_stringcmd);
-               MSG_WriteString (&cls.message, va("color %i %i", cl_color.integer >> 4, cl_color.integer & 15));
+                       MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                       MSG_WriteString (&cls.netcon->message, va("color %i %i", cl_color.integer >> 4, cl_color.integer & 15));
 
-               if (cl_pmodel.integer)
-               {
-                       MSG_WriteByte (&cls.message, clc_stringcmd);
-                       MSG_WriteString (&cls.message, va("pmodel %i", cl_pmodel.integer));
-               }
-               if (*cl_playermodel.string)
-               {
-                       MSG_WriteByte (&cls.message, clc_stringcmd);
-                       MSG_WriteString (&cls.message, va("playermodel %s", cl_playermodel.string));
-               }
-               if (*cl_playerskin.string)
-               {
-                       MSG_WriteByte (&cls.message, clc_stringcmd);
-                       MSG_WriteString (&cls.message, va("playerskin %s", cl_playerskin.string));
-               }
+                       if (cl_pmodel.integer)
+                       {
+                               MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                               MSG_WriteString (&cls.netcon->message, va("pmodel %i", cl_pmodel.integer));
+                       }
+                       if (*cl_playermodel.string)
+                       {
+                               MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                               MSG_WriteString (&cls.netcon->message, va("playermodel %s", cl_playermodel.string));
+                       }
+                       if (*cl_playerskin.string)
+                       {
+                               MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                               MSG_WriteString (&cls.netcon->message, va("playerskin %s", cl_playerskin.string));
+                       }
 
-               MSG_WriteByte (&cls.message, clc_stringcmd);
-               MSG_WriteString (&cls.message, va("rate %i", cl_rate.integer));
+                       MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                       MSG_WriteString (&cls.netcon->message, va("rate %i", cl_rate.integer));
 
-               MSG_WriteByte (&cls.message, clc_stringcmd);
-               MSG_WriteString (&cls.message, "spawn");
+                       MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                       MSG_WriteString (&cls.netcon->message, "spawn");
+               }
                break;
 
        case 3:
-               MSG_WriteByte (&cls.message, clc_stringcmd);
-               MSG_WriteString (&cls.message, "begin");
+               if (cls.netcon)
+               {
+                       MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
+                       MSG_WriteString (&cls.netcon->message, "begin");
+               }
                break;
 
        case 4:
index 8bc6575..7efd028 100644 (file)
--- a/client.h
+++ b/client.h
@@ -451,9 +451,6 @@ typedef struct client_static_s
        int signon;
        // network connection
        netconn_t *netcon;
-       // writing buffer to send to server
-       sizebuf_t message;
-       unsigned char message_buf[1024];
 }
 client_static_t;
 
diff --git a/cmd.c b/cmd.c
index a9a685f..bc09a50 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -1028,14 +1028,14 @@ void Cmd_ForwardStringToServer (const char *s)
                return;
        }
 
-       if (cls.demoplayback)
-               return;         // not really connected
+       if (!cls.netcon)
+               return;
 
        // LordHavoc: thanks to Fuh for bringing the pure evil of SZ_Print to my
        // attention, it has been eradicated from here, its only (former) use in
        // all of darkplaces.
-       MSG_WriteByte(&cls.message, clc_stringcmd);
-       SZ_Write(&cls.message, (const unsigned char *)s, (int)strlen(s) + 1);
+       MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
+       SZ_Write(&cls.netcon->message, (const unsigned char *)s, (int)strlen(s) + 1);
 }
 
 /*
index 80bd2a4..8bc5a3d 100644 (file)
--- a/common.c
+++ b/common.c
@@ -1254,6 +1254,100 @@ char *SearchInfostring(const char *infostring, const char *key)
        }
 }
 
+void InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength)
+{
+       int pos, j;
+       size_t keylength;
+       if (!key)
+               key = "";
+       if (!value)
+               value = "";
+       keylength = strlen(key);
+       if (valuelength < 1 || !value)
+       {
+               Con_Printf("InfoString_GetValue: no room in value\n");
+               return;
+       }
+       value[0] = 0;
+       if (strchr(key, '\\'))
+       {
+               Con_Printf("InfoString_GetValue: key name \"%s\" contains \\ which is not possible in an infostring\n", key);
+               return;
+       }
+       if (!key[0])
+       {
+               Con_Printf("InfoString_GetValue: can not look up a key with no name\n");
+               return;
+       }
+       while (buffer[pos] == '\\')
+       {
+               if (!memcmp(buffer + pos+1, key, keylength))
+               {
+                       for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
+                       pos++;
+                       for (j = 0;buffer[pos+j] && buffer[pos+j] != '\\' && j < (int)valuelength - 1;j++)
+                               value[j] = buffer[pos+j];
+                       value[j] = 0;
+                       return;
+               }
+               for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
+               for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
+       }
+       // if we reach this point the key was not found
+}
+
+void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value)
+{
+       int pos, pos2;
+       size_t keylength;
+       if (!key)
+               key = "";
+       if (!value)
+               value = "";
+       keylength = strlen(key);
+       if (strchr(key, '\\') || strchr(value, '\\'))
+       {
+               Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \\ which is not possible to store in an infostring\n", key, value);
+               return;
+       }
+       if (!key[0])
+       {
+               Con_Printf("InfoString_SetValue: can not set a key with no name\n");
+               return;
+       }
+       while (buffer[pos] == '\\')
+       {
+               if (!memcmp(buffer + pos+1, key, keylength))
+                       break;
+               for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
+               for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
+       }
+       // if we found the key, find the end of it because we will be replacing it
+       pos2 = pos;
+       if (buffer[pos] == '\\')
+       {
+               for (pos2++;buffer[pos2] && buffer[pos2] != '\\';pos++);
+               for (pos2++;buffer[pos2] && buffer[pos2] != '\\';pos++);
+       }
+       if (bufferlength <= 1 + strlen(key) + 1 + strlen(value) + strlen(buffer + pos2))
+       {
+               Con_Printf("InfoString_SetValue: no room for \"%s\" \"%s\" in infostring\n", key, value);
+               return;
+       }
+       if (value && value[0])
+       {
+               // set the key/value and append the remaining text
+               char tempbuffer[4096];
+               strlcpy(tempbuffer, buffer + pos2, sizeof(tempbuffer));
+               sprintf(buffer + pos, "\\%s\\%s%s", key, value, tempbuffer);
+       }
+       else
+       {
+               // just remove the key from the text
+               strcpy(buffer + pos, buffer + pos2);
+       }
+}
+
 
 //========================================================
 // strlcat and strlcpy, from OpenBSD
index ffbcc8c..b1cba03 100644 (file)
--- a/common.h
+++ b/common.h
@@ -281,6 +281,8 @@ void freedirectory(stringlist_t *list);
 
 char *SearchInfostring(const char *infostring, const char *key);
 
+void InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength);
+void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value);
 
 // strlcat and strlcpy, from OpenBSD
 // Most (all?) BSDs already have them
diff --git a/host.c b/host.c
index 3d52666..180bb66 100644 (file)
--- a/host.c
+++ b/host.c
@@ -294,8 +294,11 @@ FIXME: make this just a stuffed echo?
 */
 void SV_ClientPrint(const char *msg)
 {
-       MSG_WriteByte(&host_client->message, svc_print);
-       MSG_WriteString(&host_client->message, msg);
+       if (host_client->netconnection)
+       {
+               MSG_WriteByte(&host_client->netconnection->message, svc_print);
+               MSG_WriteString(&host_client->netconnection->message, msg);
+       }
 }
 
 /*
@@ -332,10 +335,10 @@ void SV_BroadcastPrint(const char *msg)
 
        for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if (client->spawned)
+               if (client->spawned && client->netconnection)
                {
-                       MSG_WriteByte(&client->message, svc_print);
-                       MSG_WriteString(&client->message, msg);
+                       MSG_WriteByte(&client->netconnection->message, svc_print);
+                       MSG_WriteString(&client->netconnection->message, msg);
                }
        }
 
@@ -374,12 +377,15 @@ void Host_ClientCommands(const char *fmt, ...)
        va_list argptr;
        char string[MAX_INPUTLINE];
 
+       if (!host_client->netconnection)
+               return;
+
        va_start(argptr,fmt);
        dpvsnprintf(string, sizeof(string), fmt, argptr);
        va_end(argptr);
 
-       MSG_WriteByte(&host_client->message, svc_stufftext);
-       MSG_WriteString(&host_client->message, string);
+       MSG_WriteByte(&host_client->netconnection->message, svc_stufftext);
+       MSG_WriteString(&host_client->netconnection->message, string);
 }
 
 /*
@@ -404,10 +410,15 @@ void SV_DropClient(qboolean crash)
                if (!crash)
                {
                        // LordHavoc: no opportunity for resending, so use unreliable 3 times
-                       MSG_WriteByte(&host_client->message, svc_disconnect);
-                       NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
-                       NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
-                       NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
+                       unsigned char bufdata[8];
+                       sizebuf_t buf;
+                       memset(&buf, 0, sizeof(buf));
+                       buf.data = bufdata;
+                       buf.maxsize = sizeof(bufdata);
+                       MSG_WriteByte(&buf, svc_disconnect);
+                       NetConn_SendUnreliableMessage(host_client->netconnection, &buf);
+                       NetConn_SendUnreliableMessage(host_client->netconnection, &buf);
+                       NetConn_SendUnreliableMessage(host_client->netconnection, &buf);
                }
                // break the net connection
                NetConn_Close(host_client->netconnection);
index c14d775..f047ac7 100644 (file)
@@ -1274,9 +1274,12 @@ void Host_PreSpawn_f (void)
                return;
        }
 
-       SZ_Write (&host_client->message, sv.signon.data, sv.signon.cursize);
-       MSG_WriteByte (&host_client->message, svc_signonnum);
-       MSG_WriteByte (&host_client->message, 2);
+       if (host_client->netconnection)
+       {
+               SZ_Write (&host_client->netconnection->message, sv.signon.data, sv.signon.cursize);
+               MSG_WriteByte (&host_client->netconnection->message, svc_signonnum);
+               MSG_WriteByte (&host_client->netconnection->message, 2);
+       }
        host_client->sendsignon = true;
 
        // reset the name change timer because the client will send name soon
@@ -1313,8 +1316,9 @@ void Host_Spawn_f (void)
        host_client->nametime = 0;
 
        // LordHavoc: moved this above the QC calls at FrikaC's request
-       // send all current names, colors, and frag counts
-       SZ_Clear (&host_client->message);
+       // LordHavoc: commented this out
+       //if (host_client->netconnection)
+       //      SZ_Clear (&host_client->netconnection->message);
 
        // run the entrance script
        if (sv.loadgame)
@@ -1352,24 +1356,29 @@ void Host_Spawn_f (void)
                PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
        }
 
+       host_client->sendsignon = true;
+
+       if (!host_client->netconnection)
+               return;
 
        // send time of update
-       MSG_WriteByte (&host_client->message, svc_time);
-       MSG_WriteFloat (&host_client->message, sv.time);
+       MSG_WriteByte (&host_client->netconnection->message, svc_time);
+       MSG_WriteFloat (&host_client->netconnection->message, sv.time);
 
+       // send all current names, colors, and frag counts
        for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
                if (!client->active)
                        continue;
-               MSG_WriteByte (&host_client->message, svc_updatename);
-               MSG_WriteByte (&host_client->message, i);
-               MSG_WriteString (&host_client->message, client->name);
-               MSG_WriteByte (&host_client->message, svc_updatefrags);
-               MSG_WriteByte (&host_client->message, i);
-               MSG_WriteShort (&host_client->message, client->frags);
-               MSG_WriteByte (&host_client->message, svc_updatecolors);
-               MSG_WriteByte (&host_client->message, i);
-               MSG_WriteByte (&host_client->message, client->colors);
+               MSG_WriteByte (&host_client->netconnection->message, svc_updatename);
+               MSG_WriteByte (&host_client->netconnection->message, i);
+               MSG_WriteString (&host_client->netconnection->message, client->name);
+               MSG_WriteByte (&host_client->netconnection->message, svc_updatefrags);
+               MSG_WriteByte (&host_client->netconnection->message, i);
+               MSG_WriteShort (&host_client->netconnection->message, client->frags);
+               MSG_WriteByte (&host_client->netconnection->message, svc_updatecolors);
+               MSG_WriteByte (&host_client->netconnection->message, i);
+               MSG_WriteByte (&host_client->netconnection->message, client->colors);
        }
 
        // send all current light styles
@@ -1377,44 +1386,43 @@ void Host_Spawn_f (void)
        {
                if (sv.lightstyles[i][0])
                {
-                       MSG_WriteByte (&host_client->message, svc_lightstyle);
-                       MSG_WriteByte (&host_client->message, (char)i);
-                       MSG_WriteString (&host_client->message, sv.lightstyles[i]);
+                       MSG_WriteByte (&host_client->netconnection->message, svc_lightstyle);
+                       MSG_WriteByte (&host_client->netconnection->message, (char)i);
+                       MSG_WriteString (&host_client->netconnection->message, sv.lightstyles[i]);
                }
        }
 
        // send some stats
-       MSG_WriteByte (&host_client->message, svc_updatestat);
-       MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS);
-       MSG_WriteLong (&host_client->message, prog->globals.server->total_secrets);
+       MSG_WriteByte (&host_client->netconnection->message, svc_updatestat);
+       MSG_WriteByte (&host_client->netconnection->message, STAT_TOTALSECRETS);
+       MSG_WriteLong (&host_client->netconnection->message, prog->globals.server->total_secrets);
 
-       MSG_WriteByte (&host_client->message, svc_updatestat);
-       MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS);
-       MSG_WriteLong (&host_client->message, prog->globals.server->total_monsters);
+       MSG_WriteByte (&host_client->netconnection->message, svc_updatestat);
+       MSG_WriteByte (&host_client->netconnection->message, STAT_TOTALMONSTERS);
+       MSG_WriteLong (&host_client->netconnection->message, prog->globals.server->total_monsters);
 
-       MSG_WriteByte (&host_client->message, svc_updatestat);
-       MSG_WriteByte (&host_client->message, STAT_SECRETS);
-       MSG_WriteLong (&host_client->message, prog->globals.server->found_secrets);
+       MSG_WriteByte (&host_client->netconnection->message, svc_updatestat);
+       MSG_WriteByte (&host_client->netconnection->message, STAT_SECRETS);
+       MSG_WriteLong (&host_client->netconnection->message, prog->globals.server->found_secrets);
 
-       MSG_WriteByte (&host_client->message, svc_updatestat);
-       MSG_WriteByte (&host_client->message, STAT_MONSTERS);
-       MSG_WriteLong (&host_client->message, prog->globals.server->killed_monsters);
+       MSG_WriteByte (&host_client->netconnection->message, svc_updatestat);
+       MSG_WriteByte (&host_client->netconnection->message, STAT_MONSTERS);
+       MSG_WriteLong (&host_client->netconnection->message, prog->globals.server->killed_monsters);
 
        // send a fixangle
        // Never send a roll angle, because savegames can catch the server
        // in a state where it is expecting the client to correct the angle
        // and it won't happen if the game was just loaded, so you wind up
        // with a permanent head tilt
-       MSG_WriteByte (&host_client->message, svc_setangle);
-       MSG_WriteAngle (&host_client->message, host_client->edict->fields.server->angles[0], sv.protocol);
-       MSG_WriteAngle (&host_client->message, host_client->edict->fields.server->angles[1], sv.protocol);
-       MSG_WriteAngle (&host_client->message, 0, sv.protocol);
+       MSG_WriteByte (&host_client->netconnection->message, svc_setangle);
+       MSG_WriteAngle (&host_client->netconnection->message, host_client->edict->fields.server->angles[0], sv.protocol);
+       MSG_WriteAngle (&host_client->netconnection->message, host_client->edict->fields.server->angles[1], sv.protocol);
+       MSG_WriteAngle (&host_client->netconnection->message, 0, sv.protocol);
 
-       SV_WriteClientdataToMessage (host_client, host_client->edict, &host_client->message, stats);
+       SV_WriteClientdataToMessage (host_client, host_client->edict, &host_client->netconnection->message, stats);
 
-       MSG_WriteByte (&host_client->message, svc_signonnum);
-       MSG_WriteByte (&host_client->message, 3);
-       host_client->sendsignon = true;
+       MSG_WriteByte (&host_client->netconnection->message, svc_signonnum);
+       MSG_WriteByte (&host_client->netconnection->message, 3);
 }
 
 /*
index 92a227c..b9bda85 100644 (file)
@@ -714,10 +714,10 @@ sizebuf_t *VM_WriteDest (void)
 
        case MSG_ONE:
                destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
-               if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
+               if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active || !svs.clients[destclient].netconnection)
                        PRVM_ERROR("VM_clientcommand: %s: invalid client !", PRVM_NAME);
 
-               return &svs.clients[destclient].message;
+               return &svs.clients[destclient].netconnection->message;
 
        case MSG_ALL:
                return &sv.reliable_datagram;
index baa77b6..2f50f4d 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -740,6 +740,9 @@ netconn_t *NetConn_Open(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress)
        conn->peeraddress = *peeraddress;
        conn->canSend = true;
        conn->lastMessageTime = realtime;
+       conn->message.data = conn->messagedata;
+       conn->message.maxsize = sizeof(conn->messagedata);
+       conn->message.cursize = 0;
        // LordHavoc: (inspired by ProQuake) use a short connect timeout to
        // reduce effectiveness of connection request floods
        conn->timeout = realtime + net_connecttimeout.value;
index 1597f89..61d6f57 100755 (executable)
--- a/netconn.h
+++ b/netconn.h
@@ -128,12 +128,22 @@ typedef struct netconn_s
        qboolean canSend;
        qboolean sendNext;
 
+       // writing buffer to send to peer as the next reliable message
+       // can be added to at any time, copied into sendMessage buffer when it is
+       // possible to send a reliable message and then cleared
+       sizebuf_t message;
+       unsigned char messagedata[NET_MAXMESSAGE];
+
+       // reliable message that is currently sending
+       // (for building fragments)
        unsigned int ackSequence;
        unsigned int sendSequence;
        unsigned int unreliableSendSequence;
        int sendMessageLength;
        unsigned char sendMessage[NET_MAXMESSAGE];
 
+       // reliable message that is currently being received
+       // (for putting together fragments)
        unsigned int receiveSequence;
        unsigned int unreliableReceiveSequence;
        int receiveMessageLength;
index db63a14..85af22e 100644 (file)
@@ -219,9 +219,12 @@ void VM_sprint (void)
        }
 
        client = svs.clients + clientnum;
+       if (!client->netconnection)
+               return;
+
        VM_VarString(1, string, sizeof(string));
-       MSG_WriteChar(&client->message,svc_print);
-       MSG_WriteString(&client->message, string);
+       MSG_WriteChar(&client->netconnection->message,svc_print);
+       MSG_WriteString(&client->netconnection->message, string);
 }
 
 /*
index 6db16c4..58e13ac 100644 (file)
--- a/server.h
+++ b/server.h
@@ -107,8 +107,6 @@ typedef struct client_s
        qboolean clientconnectcalled;
        // false = don't send datagrams
        qboolean spawned;
-       // has been told to go to another level
-       qboolean dropasap;
        // only valid before spawned
        qboolean sendsignon;
 
@@ -130,9 +128,6 @@ typedef struct client_s
        // intended motion calced from cmd
        vec3_t wishdir;
 
-       // can be added to at any time, copied and clear once per frame
-       sizebuf_t message;
-       unsigned char msgbuf[NET_MAXMESSAGE];
        // PRVM_EDICT_NUM(clientnum+1)
        prvm_edict_t *edict;
 
index af1a39e..39a9d48 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -296,6 +296,8 @@ void SV_SendServerinfo (client_t *client)
        int i;
        char message[128];
 
+       // we know that this client has a netconnection and thus is not a bot
+
        // edicts get reallocated on level changes, so we need to update it here
        client->edict = PRVM_EDICT_NUM((client - svs.clients) + 1);
 
@@ -323,52 +325,52 @@ void SV_SendServerinfo (client_t *client)
                        client->entitydatabase5 = EntityFrame5_AllocDatabase(sv_mempool);
        }
 
-       SZ_Clear (&client->message);
-       MSG_WriteByte (&client->message, svc_print);
+       SZ_Clear (&client->netconnection->message);
+       MSG_WriteByte (&client->netconnection->message, svc_print);
        dpsnprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, prog->filecrc);
-       MSG_WriteString (&client->message,message);
+       MSG_WriteString (&client->netconnection->message,message);
 
-       // LordHavoc: this does not work on dedicated servers, needs fixing.
+       // FIXME: LordHavoc: this does not work on dedicated servers, needs fixing.
 //[515]: init csprogs according to version of svprogs, check the crc, etc.
        if(csqc_loaded && (cls.state == ca_dedicated || PRVM_NUM_FOR_EDICT(client->edict) != 1))
        {
-               MSG_WriteByte (&client->message, svc_stufftext);
+               MSG_WriteByte (&client->netconnection->message, svc_stufftext);
                if(SV_InitCmd)
-                       MSG_WriteString (&client->message, va("csqc_progcrc %i;%s\n", csqc_progcrc.integer, SV_InitCmd));
+                       MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i;%s\n", csqc_progcrc.integer, SV_InitCmd));
                else
-                       MSG_WriteString (&client->message, va("csqc_progcrc %i\n", csqc_progcrc.integer));
+                       MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n", csqc_progcrc.integer));
        }
 
-       MSG_WriteByte (&client->message, svc_serverinfo);
-       MSG_WriteLong (&client->message, Protocol_NumberForEnum(sv.protocol));
-       MSG_WriteByte (&client->message, svs.maxclients);
+       MSG_WriteByte (&client->netconnection->message, svc_serverinfo);
+       MSG_WriteLong (&client->netconnection->message, Protocol_NumberForEnum(sv.protocol));
+       MSG_WriteByte (&client->netconnection->message, svs.maxclients);
 
        if (!coop.integer && deathmatch.integer)
-               MSG_WriteByte (&client->message, GAME_DEATHMATCH);
+               MSG_WriteByte (&client->netconnection->message, GAME_DEATHMATCH);
        else
-               MSG_WriteByte (&client->message, GAME_COOP);
+               MSG_WriteByte (&client->netconnection->message, GAME_COOP);
 
-       MSG_WriteString (&client->message,PRVM_GetString(prog->edicts->fields.server->message));
+       MSG_WriteString (&client->netconnection->message,PRVM_GetString(prog->edicts->fields.server->message));
 
        for (i = 1;i < MAX_MODELS && sv.model_precache[i][0];i++)
-               MSG_WriteString (&client->message, sv.model_precache[i]);
-       MSG_WriteByte (&client->message, 0);
+               MSG_WriteString (&client->netconnection->message, sv.model_precache[i]);
+       MSG_WriteByte (&client->netconnection->message, 0);
 
        for (i = 1;i < MAX_SOUNDS && sv.sound_precache[i][0];i++)
-               MSG_WriteString (&client->message, sv.sound_precache[i]);
-       MSG_WriteByte (&client->message, 0);
+               MSG_WriteString (&client->netconnection->message, sv.sound_precache[i]);
+       MSG_WriteByte (&client->netconnection->message, 0);
 
 // send music
-       MSG_WriteByte (&client->message, svc_cdtrack);
-       MSG_WriteByte (&client->message, prog->edicts->fields.server->sounds);
-       MSG_WriteByte (&client->message, prog->edicts->fields.server->sounds);
+       MSG_WriteByte (&client->netconnection->message, svc_cdtrack);
+       MSG_WriteByte (&client->netconnection->message, prog->edicts->fields.server->sounds);
+       MSG_WriteByte (&client->netconnection->message, prog->edicts->fields.server->sounds);
 
 // set view
-       MSG_WriteByte (&client->message, svc_setview);
-       MSG_WriteShort (&client->message, PRVM_NUM_FOR_EDICT(client->edict));
+       MSG_WriteByte (&client->netconnection->message, svc_setview);
+       MSG_WriteShort (&client->netconnection->message, PRVM_NUM_FOR_EDICT(client->edict));
 
-       MSG_WriteByte (&client->message, svc_signonnum);
-       MSG_WriteByte (&client->message, 1);
+       MSG_WriteByte (&client->netconnection->message, svc_signonnum);
+       MSG_WriteByte (&client->netconnection->message, 1);
 
        client->sendsignon = true;
        client->spawned = false;                // need prespawn, spawn, etc
@@ -406,9 +408,7 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
        strcpy(client->old_name, "unconnected");
        client->spawned = false;
        client->edict = PRVM_EDICT_NUM(clientnum+1);
-       client->message.data = client->msgbuf;
-       client->message.maxsize = sizeof(client->msgbuf);
-       client->message.allowoverflow = true;           // we can catch it
+       client->netconnection->message.allowoverflow = true;            // we can catch it
        // updated by receiving "rate" command from client
        client->rate = NET_MINRATE;
        // no limits for local player
@@ -1328,7 +1328,7 @@ void SV_UpdateToReliableMessages (void)
 
        for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
                if (client->netconnection)
-                       SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
+                       SZ_Write (&client->netconnection->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
 
        SZ_Clear (&sv.reliable_datagram);
 }
@@ -1376,12 +1376,9 @@ void SV_SendClientMessages (void)
                if (!host_client->active)
                        continue;
                if (!host_client->netconnection)
-               {
-                       SZ_Clear(&host_client->message);
                        continue;
-               }
 
-               if (host_client->message.overflowed)
+               if (host_client->netconnection->message.overflowed)
                {
                        SV_DropClient (true);   // if the message couldn't send, kick off
                        continue;
@@ -1413,21 +1410,16 @@ void SV_SendClientMessages (void)
                        }
                }
 
-               if (host_client->message.cursize || host_client->dropasap)
+               if (host_client->netconnection->message.cursize)
                {
                        if (!NetConn_CanSendMessage (host_client->netconnection))
                                continue;
 
-                       if (host_client->dropasap)
-                               SV_DropClient (false);  // went to another level
-                       else
-                       {
-                               if (NetConn_SendReliableMessage (host_client->netconnection, &host_client->message) == -1)
-                                       SV_DropClient (true);   // if the message couldn't send, kick off
-                               SZ_Clear (&host_client->message);
-                               host_client->last_message = realtime;
-                               host_client->sendsignon = false;
-                       }
+                       if (NetConn_SendReliableMessage (host_client->netconnection, &host_client->netconnection->message) == -1)
+                               SV_DropClient (true);   // if the message couldn't send, kick off
+                       SZ_Clear (&host_client->netconnection->message);
+                       host_client->last_message = realtime;
+                       host_client->sendsignon = false;
                }
        }
 
index 110234b..40d6c17 100644 (file)
@@ -265,9 +265,12 @@ void PF_sprint (void)
        }
 
        client = svs.clients + entnum-1;
+       if (!client->netconnection)
+               return;
+
        VM_VarString(1, string, sizeof(string));
-       MSG_WriteChar(&client->message,svc_print);
-       MSG_WriteString(&client->message, string);
+       MSG_WriteChar(&client->netconnection->message,svc_print);
+       MSG_WriteString(&client->netconnection->message, string);
 }
 
 
@@ -295,9 +298,12 @@ void PF_centerprint (void)
        }
 
        client = svs.clients + entnum-1;
+       if (!client->netconnection)
+               return;
+
        VM_VarString(1, string, sizeof(string));
-       MSG_WriteChar(&client->message,svc_centerprint);
-       MSG_WriteString(&client->message, string);
+       MSG_WriteChar(&client->netconnection->message,svc_centerprint);
+       MSG_WriteString(&client->netconnection->message, string);
 }
 
 /*
@@ -869,11 +875,11 @@ void PF_lightstyle (void)
 
        for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
        {
-               if (client->active)
+               if (client->active && client->netconnection)
                {
-                       MSG_WriteChar (&client->message, svc_lightstyle);
-                       MSG_WriteChar (&client->message,style);
-                       MSG_WriteString (&client->message, val);
+                       MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
+                       MSG_WriteChar (&client->netconnection->message,style);
+                       MSG_WriteString (&client->netconnection->message, val);
                }
        }
 }
@@ -1126,13 +1132,13 @@ sizebuf_t *WriteDest (void)
        case MSG_ONE:
                ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
                entnum = PRVM_NUM_FOR_EDICT(ent);
-               if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+               if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
                {
                        Con_Printf ("WriteDest: tried to write to non-client\n");
                        return &sv.reliable_datagram;
                }
                else
-                       return &svs.clients[entnum-1].message;
+                       return &svs.clients[entnum-1].netconnection->message;
 
        default:
                Con_Printf ("WriteDest: bad destination\n");