// 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;
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;
}
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);
}
}
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 ();
//
*/
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:
int signon;
// network connection
netconn_t *netcon;
- // writing buffer to send to server
- sizebuf_t message;
- unsigned char message_buf[1024];
}
client_static_t;
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);
}
/*
}
}
+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
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
*/
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);
+ }
}
/*
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);
}
}
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);
}
/*
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);
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
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)
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
{
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);
}
/*
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;
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;
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;
}
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);
}
/*
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;
// 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;
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);
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
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
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);
}
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;
}
}
- 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;
}
}
}
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);
}
}
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);
}
/*
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);
}
}
}
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");