Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Rewrote reliable commands

  • Loading branch information...
commit b5f0c4cb5af230412a0e9dc06e623902ab031609 1 parent 81b2d6a
Dusan Jocic authored
2  src/engine/client/cl_cgame.cpp
@@ -377,7 +377,7 @@ qboolean CL_GetServerCommand(int serverCommandNumber)
377 377 return qfalse;
378 378 }
379 379
380   - s = clc.serverCommands[serverCommandNumber & (MAX_RELIABLE_COMMANDS - 1)];
  380 + s = CL_GetReliableServerCommand( serverCommandNumber );
381 381 clc.lastExecutedServerCommand = serverCommandNumber;
382 382
383 383 if(cl_showServerCommands->integer)
4 src/engine/client/cl_input.cpp
@@ -1362,7 +1362,7 @@ void CL_WritePacket(void)
1362 1362 {
1363 1363 MSG_WriteByte(&buf, clc_clientCommand);
1364 1364 MSG_WriteLong(&buf, i);
1365   - MSG_WriteString(&buf, clc.reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
  1365 + MSG_WriteString( &buf, CL_GetReliableCommand( i ) );
1366 1366 }
1367 1367
1368 1368 // we want to send all the usercmds that were generated in the last
@@ -1459,7 +1459,7 @@ void CL_WritePacket(void)
1459 1459 // also use the message acknowledge
1460 1460 key ^= clc.serverMessageSequence;
1461 1461 // also use the last acknowledged server command in the key
1462   - key ^= Com_HashKey(clc.serverCommands[clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS - 1)], 32);
  1462 + key ^= Com_HashKey( CL_GetReliableServerCommand( clc.serverCommandSequence ), 32);
1463 1463
1464 1464 // write all the commands, including the predicted command
1465 1465 for(i = 0; i < count; i++)
24 src/engine/client/cl_main.cpp
@@ -683,6 +683,17 @@ CLIENT RELIABLE COMMAND COMMUNICATION
683 683 */
684 684
685 685 /*
  686 +=====================
  687 +CL_GetReliableCommand
  688 +=====================
  689 +*/
  690 +char * CL_GetReliableCommand( int index )
  691 +{
  692 + char * cmd = clc.reliableCommands[ index & (MAX_RELIABLE_COMMANDS-1) ];
  693 + return cmd?cmd:"";
  694 +}
  695 +
  696 +/*
686 697 ======================
687 698 CL_AddReliableCommand
688 699
@@ -702,7 +713,18 @@ void CL_AddReliableCommand(const char *cmd)
702 713 }
703 714 clc.reliableSequence++;
704 715 index = clc.reliableSequence & (MAX_RELIABLE_COMMANDS - 1);
705   - Q_strncpyz(clc.reliableCommands[index], cmd, sizeof(clc.reliableCommands[index]));
  716 +
  717 + clc.reliableCommands[ index ] = Q_strcpy_ringbuffer( clc.reliableCommandBuffer,
  718 + sizeof( clc.reliableCommandBuffer ),
  719 + clc.reliableCommands[ (clc.reliableAcknowledge) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
  720 + clc.reliableCommands[ (clc.reliableSequence-1) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
  721 + cmd
  722 + );
  723 +
  724 + if ( !clc.reliableCommands[ index ] )
  725 + {
  726 + Com_Error( ERR_DROP, "Client command buffer overflow" );
  727 + }
706 728 }
707 729
708 730 /*
4 src/engine/client/cl_net_chan.cpp
@@ -75,7 +75,7 @@ static void CL_Netchan_Encode(msg_t * msg)
75 75 msg->bit = sbit;
76 76 msg->readcount = srdc;
77 77
78   - string = (byte *) clc.serverCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
  78 + string = (byte *)CL_GetReliableServerCommand( reliableAcknowledge );
79 79 index = 0;
80 80 //
81 81 key = clc.challenge ^ serverId ^ messageAcknowledge;
@@ -128,7 +128,7 @@ static void CL_Netchan_Decode(msg_t * msg)
128 128 msg->bit = sbit;
129 129 msg->readcount = srdc;
130 130
131   - string = (byte *) clc.reliableCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
  131 + string = (byte*)CL_GetReliableCommand( reliableAcknowledge );
132 132 index = 0;
133 133 // xor the client challenge with the netchan sequence number (need something that changes every message)
134 134 key = (clc.challenge ^ LittleLong(*(unsigned *)msg->data)) & 0xFF;
30 src/engine/client/cl_parse.cpp
@@ -1109,6 +1109,17 @@ void CL_ParseVoip ( msg_t *msg ) {
1109 1109
1110 1110 /*
1111 1111 =====================
  1112 +CL_GetReliableServerCommand
  1113 +=====================
  1114 +*/
  1115 +char * CL_GetReliableServerCommand( int index )
  1116 +{
  1117 + char * cmd = clc.serverCommands[ index & (MAX_RELIABLE_COMMANDS-1) ];
  1118 + return cmd?cmd:"";
  1119 +}
  1120 +
  1121 +/*
  1122 +=====================
1112 1123 CL_ParseCommandString
1113 1124
1114 1125 Command strings are just saved off until cgame asks for them
@@ -1117,9 +1128,8 @@ when it transitions a snapshot
1117 1128 */
1118 1129 void CL_ParseCommandString(msg_t * msg)
1119 1130 {
1120   - char *s;
1121   - int seq;
1122   - int index;
  1131 + char *s, *c;
  1132 + int seq, index;
1123 1133
1124 1134 seq = MSG_ReadLong(msg);
1125 1135 s = MSG_ReadString(msg);
@@ -1132,7 +1142,19 @@ void CL_ParseCommandString(msg_t * msg)
1132 1142 clc.serverCommandSequence = seq;
1133 1143
1134 1144 index = seq & (MAX_RELIABLE_COMMANDS - 1);
1135   - Q_strncpyz(clc.serverCommands[index], s, sizeof(clc.serverCommands[index]));
  1145 + c = Q_strcpy_ringbuffer( clc.serverCommandBuffer,
  1146 + sizeof( clc.serverCommandBuffer ),
  1147 + clc.serverCommands[ (clc.lastExecutedServerCommand-1) & (MAX_RELIABLE_COMMANDS-1) ],
  1148 + clc.serverCommands[ (clc.serverCommandSequence-1) & (MAX_RELIABLE_COMMANDS-1) ],
  1149 + s
  1150 + );
  1151 +
  1152 + if ( !c )
  1153 + {
  1154 + Com_Error( ERR_DROP, "client command buffer overflow.\n" );
  1155 + }
  1156 +
  1157 + clc.serverCommands[ index ] = c;
1136 1158 }
1137 1159
1138 1160 /*
9 src/engine/client/client.h
@@ -204,7 +204,8 @@ typedef struct {
204 204 int reliableSequence;
205 205 int reliableAcknowledge; // the last one the server has executed
206 206 // TTimo - NOTE: incidentally, reliableCommands[0] is never used (always start at reliableAcknowledge+1)
207   - char reliableCommands[MAX_RELIABLE_COMMANDS][MAX_TOKEN_CHARS];
  207 + char *reliableCommands[MAX_RELIABLE_COMMANDS];
  208 + char reliableCommandBuffer[ MAX_RELIABLE_BUFFER ];
208 209 // unreliable binary data to send to server
209 210 int binaryMessageLength;
210 211 char binaryMessage[MAX_BINARY_MESSAGE];
@@ -218,7 +219,9 @@ typedef struct {
218 219 // reliable messages received from server
219 220 int serverCommandSequence;
220 221 int lastExecutedServerCommand; // last server command grabbed or executed with CL_GetServerCommand
221   - char serverCommands[MAX_RELIABLE_COMMANDS][MAX_TOKEN_CHARS];
  222 + char *serverCommands[MAX_RELIABLE_COMMANDS];
  223 + char serverCommandBuffer[ MAX_RELIABLE_BUFFER ];
  224 +
222 225 // file transfer from server
223 226 fileHandle_t download;
224 227 int downloadNumber;
@@ -528,6 +531,7 @@ void CL_Init(void);
528 531 void CL_FlushMemory(void);
529 532 void CL_ShutdownAll(void);
530 533 void CL_AddReliableCommand(const char *cmd);
  534 +char *CL_GetReliableCommand( int index );
531 535
532 536 void CL_StartHunkUsers(void);
533 537
@@ -665,6 +669,7 @@ void CL_Voip_f( void );
665 669
666 670 void CL_SystemInfoChanged(void);
667 671 void CL_ParseServerMessage(msg_t * msg);
  672 +char *CL_GetReliableServerCommand( int index );
668 673
669 674 //====================================================================
670 675
42 src/engine/qcommon/q_shared.cpp
@@ -1323,6 +1323,48 @@ qboolean Q_strtoi(const char* s, int * outNum) {
1323 1323 return (qboolean) (*p == '\0');
1324 1324 }
1325 1325
  1326 +char * Q_strcpy_ringbuffer( char * buffer, int size, char * first, char * last, const char * s ) {
  1327 +
  1328 + int i;
  1329 +
  1330 + if ( !first ) {
  1331 + first = buffer + size;
  1332 + } else {
  1333 + while ( *first ) first++;
  1334 + first++;
  1335 + }
  1336 +
  1337 + if ( !last ) {
  1338 + last = buffer;
  1339 + } else {
  1340 + while ( *last ) last++;
  1341 + last++;
  1342 + }
  1343 +
  1344 + if ( last == first ) {
  1345 + first = buffer + ((last-buffer)-1)%size;
  1346 + }
  1347 +
  1348 + for ( i=0; ; i++ ) {
  1349 +
  1350 + if ( last + i >= buffer + size ) {
  1351 + last = buffer;
  1352 + i = 0;
  1353 + }
  1354 +
  1355 + if ( last + i == first ) {
  1356 + return 0;
  1357 + }
  1358 +
  1359 + last[ i ] = s[ i ];
  1360 +
  1361 + if ( s[ i ] == '\0' )
  1362 + break;
  1363 + }
  1364 +
  1365 + return last;
  1366 +}
  1367 +
1326 1368 /*
1327 1369 =============
1328 1370 Q_strncpyz
1  src/engine/qcommon/q_shared.h
@@ -1377,6 +1377,7 @@ int Q_isupper( int c );
1377 1377 int Q_isnumeric( int c );
1378 1378 int Q_isalphanumeric( int c );
1379 1379 qboolean Q_strtoi( const char *s, int* out);
  1380 +char * Q_strcpy_ringbuffer( char * buffer, int size, char * first, char * last, const char * s );
1380 1381
1381 1382 // portable case insensitive compare
1382 1383 int Q_stricmp( const char *s1, const char *s2 );
1  src/engine/qcommon/qcommon.h
@@ -167,6 +167,7 @@ NET
167 167 //#define MAX_RELIABLE_COMMANDS 64 // max string commands buffered for restransmit
168 168 //#define MAX_RELIABLE_COMMANDS 128 // max string commands buffered for restransmit
169 169 #define MAX_RELIABLE_COMMANDS 256 // bigger!
  170 +#define MAX_RELIABLE_BUFFER 10240
170 171
171 172 typedef enum {
172 173 NA_BOT,
4 src/engine/server/server.h
@@ -191,7 +191,8 @@ typedef struct client_s
191 191 char userinfo[MAX_INFO_STRING]; // name, etc
192 192 char userinfobuffer[MAX_INFO_STRING]; //used for buffering of user info
193 193
194   - char reliableCommands[MAX_RELIABLE_COMMANDS][MAX_STRING_CHARS];
  194 + char *reliableCommands[MAX_RELIABLE_COMMANDS];
  195 + char reliableCommandBuffer[ MAX_RELIABLE_BUFFER ];
195 196 int reliableSequence; // last added reliable message, not necesarily sent or acknowledged yet
196 197 int reliableAcknowledge; // last acknowledged reliable message
197 198 int reliableSent; // last sent reliable message, not necesarily acknowledged yet
@@ -559,6 +560,7 @@ void SV_TempBanNetAddress(netadr_t address, int length);
559 560 // sv_snapshot.c
560 561 //
561 562 void SV_AddServerCommand(client_t * client, const char *cmd);
  563 +char *SV_GetServerCommand( client_t * client, int index );
562 564 void SV_UpdateServerCommandsToClient(client_t * client, msg_t * msg);
563 565 void SV_WriteFrameToClient(client_t * client, msg_t * msg);
564 566 void SV_SendMessageToClient(msg_t * msg, client_t * client);
9 src/engine/server/sv_bot.cpp
@@ -726,7 +726,7 @@ SV_BotGetConsoleMessage
726 726 */
727 727 int SV_BotGetConsoleMessage(int client, char *buf, int size) {
728 728 client_t *cl;
729   - int index;
  729 + char *cmd;
730 730
731 731 cl = &svs.clients[client];
732 732 cl->lastPacketTime = svs.time;
@@ -736,13 +736,14 @@ int SV_BotGetConsoleMessage(int client, char *buf, int size) {
736 736 }
737 737
738 738 cl->reliableAcknowledge++;
739   - index = cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1);
740 739
741   - if(!cl->reliableCommands[index][0]) {
  740 + cmd = SV_GetServerCommand( cl, cl->reliableAcknowledge );
  741 +
  742 + if ( !cmd[0] ) {
742 743 return qfalse;
743 744 }
744 745
745   - //Q_strncpyz( buf, cl->reliableCommands[index], size );
  746 + Q_strncpyz( buf, cmd, size );
746 747 return qtrue;
747 748 }
748 749
2  src/engine/server/sv_client.cpp
@@ -1744,7 +1744,7 @@ static void SV_UserMove(client_t * cl, msg_t * msg, qboolean delta) {
1744 1744 // also use the message acknowledge
1745 1745 key ^= cl->messageAcknowledge;
1746 1746 // also use the last acknowledged server command in the key
1747   - key ^= Com_HashKey(cl->reliableCommands[cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)], 32);
  1747 + key ^= Com_HashKey( SV_GetServerCommand( cl, cl->reliableAcknowledge ), 32);
1748 1748
1749 1749 memset(&nullcmd, 0, sizeof(nullcmd));
1750 1750 oldcmd = &nullcmd;
25 src/engine/server/sv_main.cpp
@@ -166,6 +166,17 @@ char *SV_ExpandNewlines(char *in) {
166 166 }
167 167
168 168 /*
  169 +=====================
  170 +SV_GetServerCommand
  171 +=====================
  172 +*/
  173 +char * SV_GetServerCommand( client_t * client, int index )
  174 +{
  175 + char * cmd = client->reliableCommands[ index & (MAX_RELIABLE_COMMANDS-1) ];
  176 + return cmd?cmd:"";
  177 +}
  178 +
  179 +/*
169 180 ======================
170 181 SV_AddServerCommand
171 182
@@ -184,14 +195,24 @@ void SV_AddServerCommand(client_t * client, const char *cmd) {
184 195 if(client->reliableSequence - client->reliableAcknowledge == MAX_RELIABLE_COMMANDS + 1) {
185 196 Com_Printf("===== pending server commands =====\n");
186 197 for(i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++) {
187   - Com_Printf("cmd %5d: %s\n", i, client->reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
  198 + Com_Printf("cmd %5d: %s\n", i, SV_GetServerCommand( client, i ) );
188 199 }
189 200 Com_Printf("cmd %5d: %s\n", i, cmd);
190 201 SV_DropClient(client, "Server command overflow");
191 202 return;
192 203 }
193 204 index = client->reliableSequence & (MAX_RELIABLE_COMMANDS - 1);
194   - Q_strncpyz(client->reliableCommands[index], cmd, sizeof(client->reliableCommands[index]));
  205 +
  206 + client->reliableCommands[ index ] = Q_strcpy_ringbuffer( client->reliableCommandBuffer,
  207 + sizeof( client->reliableCommandBuffer ),
  208 + client->reliableCommands[ (client->reliableAcknowledge) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
  209 + client->reliableCommands[ (client->reliableSequence - 1) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
  210 + cmd
  211 + );
  212 +
  213 + if ( !client->reliableCommands[ index ] ) {
  214 + SV_DropClient( client, "Server command buffer overflow" );
  215 + }
195 216 }
196 217
197 218
2  src/engine/server/sv_net_chan.cpp
@@ -117,7 +117,7 @@ static void SV_Netchan_Decode(client_t * client, msg_t * msg) {
117 117 msg->bit = sbit;
118 118 msg->readcount = srdc;
119 119
120   - string = (byte *) client->reliableCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
  120 + string = (byte *)SV_GetServerCommand( client, reliableAcknowledge );
121 121 index = 0;
122 122 //
123 123 key = client->challenge ^ serverId ^ messageAcknowledge;
2  src/engine/server/sv_snapshot.cpp
@@ -225,7 +225,7 @@ void SV_UpdateServerCommandsToClient(client_t * client, msg_t * msg) {
225 225 for(i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++) {
226 226 MSG_WriteByte(msg, svc_serverCommand);
227 227 MSG_WriteLong(msg, i);
228   - MSG_WriteString(msg, client->reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
  228 + MSG_WriteString( msg, SV_GetServerCommand( client, i ) );
229 229 }
230 230 client->reliableSent = client->reliableSequence;
231 231 }

0 comments on commit b5f0c4c

Please sign in to comment.
Something went wrong with that request. Please try again.