Skip to content
Browse files

Rewrote reliable commands

  • Loading branch information...
1 parent 81b2d6a commit b5f0c4cb5af230412a0e9dc06e623902ab031609 @TheDushan committed Sep 7, 2012
View
2 src/engine/client/cl_cgame.cpp
@@ -377,7 +377,7 @@ qboolean CL_GetServerCommand(int serverCommandNumber)
return qfalse;
}
- s = clc.serverCommands[serverCommandNumber & (MAX_RELIABLE_COMMANDS - 1)];
+ s = CL_GetReliableServerCommand( serverCommandNumber );
clc.lastExecutedServerCommand = serverCommandNumber;
if(cl_showServerCommands->integer)
View
4 src/engine/client/cl_input.cpp
@@ -1362,7 +1362,7 @@ void CL_WritePacket(void)
{
MSG_WriteByte(&buf, clc_clientCommand);
MSG_WriteLong(&buf, i);
- MSG_WriteString(&buf, clc.reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
+ MSG_WriteString( &buf, CL_GetReliableCommand( i ) );
}
// we want to send all the usercmds that were generated in the last
@@ -1459,7 +1459,7 @@ void CL_WritePacket(void)
// also use the message acknowledge
key ^= clc.serverMessageSequence;
// also use the last acknowledged server command in the key
- key ^= Com_HashKey(clc.serverCommands[clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS - 1)], 32);
+ key ^= Com_HashKey( CL_GetReliableServerCommand( clc.serverCommandSequence ), 32);
// write all the commands, including the predicted command
for(i = 0; i < count; i++)
View
24 src/engine/client/cl_main.cpp
@@ -683,6 +683,17 @@ CLIENT RELIABLE COMMAND COMMUNICATION
*/
/*
+=====================
+CL_GetReliableCommand
+=====================
+*/
+char * CL_GetReliableCommand( int index )
+{
+ char * cmd = clc.reliableCommands[ index & (MAX_RELIABLE_COMMANDS-1) ];
+ return cmd?cmd:"";
+}
+
+/*
======================
CL_AddReliableCommand
@@ -702,7 +713,18 @@ void CL_AddReliableCommand(const char *cmd)
}
clc.reliableSequence++;
index = clc.reliableSequence & (MAX_RELIABLE_COMMANDS - 1);
- Q_strncpyz(clc.reliableCommands[index], cmd, sizeof(clc.reliableCommands[index]));
+
+ clc.reliableCommands[ index ] = Q_strcpy_ringbuffer( clc.reliableCommandBuffer,
+ sizeof( clc.reliableCommandBuffer ),
+ clc.reliableCommands[ (clc.reliableAcknowledge) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
+ clc.reliableCommands[ (clc.reliableSequence-1) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
+ cmd
+ );
+
+ if ( !clc.reliableCommands[ index ] )
+ {
+ Com_Error( ERR_DROP, "Client command buffer overflow" );
+ }
}
/*
View
4 src/engine/client/cl_net_chan.cpp
@@ -75,7 +75,7 @@ static void CL_Netchan_Encode(msg_t * msg)
msg->bit = sbit;
msg->readcount = srdc;
- string = (byte *) clc.serverCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
+ string = (byte *)CL_GetReliableServerCommand( reliableAcknowledge );
index = 0;
//
key = clc.challenge ^ serverId ^ messageAcknowledge;
@@ -128,7 +128,7 @@ static void CL_Netchan_Decode(msg_t * msg)
msg->bit = sbit;
msg->readcount = srdc;
- string = (byte *) clc.reliableCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
+ string = (byte*)CL_GetReliableCommand( reliableAcknowledge );
index = 0;
// xor the client challenge with the netchan sequence number (need something that changes every message)
key = (clc.challenge ^ LittleLong(*(unsigned *)msg->data)) & 0xFF;
View
30 src/engine/client/cl_parse.cpp
@@ -1109,6 +1109,17 @@ void CL_ParseVoip ( msg_t *msg ) {
/*
=====================
+CL_GetReliableServerCommand
+=====================
+*/
+char * CL_GetReliableServerCommand( int index )
+{
+ char * cmd = clc.serverCommands[ index & (MAX_RELIABLE_COMMANDS-1) ];
+ return cmd?cmd:"";
+}
+
+/*
+=====================
CL_ParseCommandString
Command strings are just saved off until cgame asks for them
@@ -1117,9 +1128,8 @@ when it transitions a snapshot
*/
void CL_ParseCommandString(msg_t * msg)
{
- char *s;
- int seq;
- int index;
+ char *s, *c;
+ int seq, index;
seq = MSG_ReadLong(msg);
s = MSG_ReadString(msg);
@@ -1132,7 +1142,19 @@ void CL_ParseCommandString(msg_t * msg)
clc.serverCommandSequence = seq;
index = seq & (MAX_RELIABLE_COMMANDS - 1);
- Q_strncpyz(clc.serverCommands[index], s, sizeof(clc.serverCommands[index]));
+ c = Q_strcpy_ringbuffer( clc.serverCommandBuffer,
+ sizeof( clc.serverCommandBuffer ),
+ clc.serverCommands[ (clc.lastExecutedServerCommand-1) & (MAX_RELIABLE_COMMANDS-1) ],
+ clc.serverCommands[ (clc.serverCommandSequence-1) & (MAX_RELIABLE_COMMANDS-1) ],
+ s
+ );
+
+ if ( !c )
+ {
+ Com_Error( ERR_DROP, "client command buffer overflow.\n" );
+ }
+
+ clc.serverCommands[ index ] = c;
}
/*
View
9 src/engine/client/client.h
@@ -204,7 +204,8 @@ typedef struct {
int reliableSequence;
int reliableAcknowledge; // the last one the server has executed
// TTimo - NOTE: incidentally, reliableCommands[0] is never used (always start at reliableAcknowledge+1)
- char reliableCommands[MAX_RELIABLE_COMMANDS][MAX_TOKEN_CHARS];
+ char *reliableCommands[MAX_RELIABLE_COMMANDS];
+ char reliableCommandBuffer[ MAX_RELIABLE_BUFFER ];
// unreliable binary data to send to server
int binaryMessageLength;
char binaryMessage[MAX_BINARY_MESSAGE];
@@ -218,7 +219,9 @@ typedef struct {
// reliable messages received from server
int serverCommandSequence;
int lastExecutedServerCommand; // last server command grabbed or executed with CL_GetServerCommand
- char serverCommands[MAX_RELIABLE_COMMANDS][MAX_TOKEN_CHARS];
+ char *serverCommands[MAX_RELIABLE_COMMANDS];
+ char serverCommandBuffer[ MAX_RELIABLE_BUFFER ];
+
// file transfer from server
fileHandle_t download;
int downloadNumber;
@@ -528,6 +531,7 @@ void CL_Init(void);
void CL_FlushMemory(void);
void CL_ShutdownAll(void);
void CL_AddReliableCommand(const char *cmd);
+char *CL_GetReliableCommand( int index );
void CL_StartHunkUsers(void);
@@ -665,6 +669,7 @@ void CL_Voip_f( void );
void CL_SystemInfoChanged(void);
void CL_ParseServerMessage(msg_t * msg);
+char *CL_GetReliableServerCommand( int index );
//====================================================================
View
42 src/engine/qcommon/q_shared.cpp
@@ -1323,6 +1323,48 @@ qboolean Q_strtoi(const char* s, int * outNum) {
return (qboolean) (*p == '\0');
}
+char * Q_strcpy_ringbuffer( char * buffer, int size, char * first, char * last, const char * s ) {
+
+ int i;
+
+ if ( !first ) {
+ first = buffer + size;
+ } else {
+ while ( *first ) first++;
+ first++;
+ }
+
+ if ( !last ) {
+ last = buffer;
+ } else {
+ while ( *last ) last++;
+ last++;
+ }
+
+ if ( last == first ) {
+ first = buffer + ((last-buffer)-1)%size;
+ }
+
+ for ( i=0; ; i++ ) {
+
+ if ( last + i >= buffer + size ) {
+ last = buffer;
+ i = 0;
+ }
+
+ if ( last + i == first ) {
+ return 0;
+ }
+
+ last[ i ] = s[ i ];
+
+ if ( s[ i ] == '\0' )
+ break;
+ }
+
+ return last;
+}
+
/*
=============
Q_strncpyz
View
1 src/engine/qcommon/q_shared.h
@@ -1377,6 +1377,7 @@ int Q_isupper( int c );
int Q_isnumeric( int c );
int Q_isalphanumeric( int c );
qboolean Q_strtoi( const char *s, int* out);
+char * Q_strcpy_ringbuffer( char * buffer, int size, char * first, char * last, const char * s );
// portable case insensitive compare
int Q_stricmp( const char *s1, const char *s2 );
View
1 src/engine/qcommon/qcommon.h
@@ -167,6 +167,7 @@ NET
//#define MAX_RELIABLE_COMMANDS 64 // max string commands buffered for restransmit
//#define MAX_RELIABLE_COMMANDS 128 // max string commands buffered for restransmit
#define MAX_RELIABLE_COMMANDS 256 // bigger!
+#define MAX_RELIABLE_BUFFER 10240
typedef enum {
NA_BOT,
View
4 src/engine/server/server.h
@@ -191,7 +191,8 @@ typedef struct client_s
char userinfo[MAX_INFO_STRING]; // name, etc
char userinfobuffer[MAX_INFO_STRING]; //used for buffering of user info
- char reliableCommands[MAX_RELIABLE_COMMANDS][MAX_STRING_CHARS];
+ char *reliableCommands[MAX_RELIABLE_COMMANDS];
+ char reliableCommandBuffer[ MAX_RELIABLE_BUFFER ];
int reliableSequence; // last added reliable message, not necesarily sent or acknowledged yet
int reliableAcknowledge; // last acknowledged reliable message
int reliableSent; // last sent reliable message, not necesarily acknowledged yet
@@ -559,6 +560,7 @@ void SV_TempBanNetAddress(netadr_t address, int length);
// sv_snapshot.c
//
void SV_AddServerCommand(client_t * client, const char *cmd);
+char *SV_GetServerCommand( client_t * client, int index );
void SV_UpdateServerCommandsToClient(client_t * client, msg_t * msg);
void SV_WriteFrameToClient(client_t * client, msg_t * msg);
void SV_SendMessageToClient(msg_t * msg, client_t * client);
View
9 src/engine/server/sv_bot.cpp
@@ -726,7 +726,7 @@ SV_BotGetConsoleMessage
*/
int SV_BotGetConsoleMessage(int client, char *buf, int size) {
client_t *cl;
- int index;
+ char *cmd;
cl = &svs.clients[client];
cl->lastPacketTime = svs.time;
@@ -736,13 +736,14 @@ int SV_BotGetConsoleMessage(int client, char *buf, int size) {
}
cl->reliableAcknowledge++;
- index = cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1);
- if(!cl->reliableCommands[index][0]) {
+ cmd = SV_GetServerCommand( cl, cl->reliableAcknowledge );
+
+ if ( !cmd[0] ) {
return qfalse;
}
- //Q_strncpyz( buf, cl->reliableCommands[index], size );
+ Q_strncpyz( buf, cmd, size );
return qtrue;
}
View
2 src/engine/server/sv_client.cpp
@@ -1744,7 +1744,7 @@ static void SV_UserMove(client_t * cl, msg_t * msg, qboolean delta) {
// also use the message acknowledge
key ^= cl->messageAcknowledge;
// also use the last acknowledged server command in the key
- key ^= Com_HashKey(cl->reliableCommands[cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)], 32);
+ key ^= Com_HashKey( SV_GetServerCommand( cl, cl->reliableAcknowledge ), 32);
memset(&nullcmd, 0, sizeof(nullcmd));
oldcmd = &nullcmd;
View
25 src/engine/server/sv_main.cpp
@@ -166,6 +166,17 @@ char *SV_ExpandNewlines(char *in) {
}
/*
+=====================
+SV_GetServerCommand
+=====================
+*/
+char * SV_GetServerCommand( client_t * client, int index )
+{
+ char * cmd = client->reliableCommands[ index & (MAX_RELIABLE_COMMANDS-1) ];
+ return cmd?cmd:"";
+}
+
+/*
======================
SV_AddServerCommand
@@ -184,14 +195,24 @@ void SV_AddServerCommand(client_t * client, const char *cmd) {
if(client->reliableSequence - client->reliableAcknowledge == MAX_RELIABLE_COMMANDS + 1) {
Com_Printf("===== pending server commands =====\n");
for(i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++) {
- Com_Printf("cmd %5d: %s\n", i, client->reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
+ Com_Printf("cmd %5d: %s\n", i, SV_GetServerCommand( client, i ) );
}
Com_Printf("cmd %5d: %s\n", i, cmd);
SV_DropClient(client, "Server command overflow");
return;
}
index = client->reliableSequence & (MAX_RELIABLE_COMMANDS - 1);
- Q_strncpyz(client->reliableCommands[index], cmd, sizeof(client->reliableCommands[index]));
+
+ client->reliableCommands[ index ] = Q_strcpy_ringbuffer( client->reliableCommandBuffer,
+ sizeof( client->reliableCommandBuffer ),
+ client->reliableCommands[ (client->reliableAcknowledge) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
+ client->reliableCommands[ (client->reliableSequence - 1) & ( MAX_RELIABLE_COMMANDS - 1 ) ],
+ cmd
+ );
+
+ if ( !client->reliableCommands[ index ] ) {
+ SV_DropClient( client, "Server command buffer overflow" );
+ }
}
View
2 src/engine/server/sv_net_chan.cpp
@@ -117,7 +117,7 @@ static void SV_Netchan_Decode(client_t * client, msg_t * msg) {
msg->bit = sbit;
msg->readcount = srdc;
- string = (byte *) client->reliableCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
+ string = (byte *)SV_GetServerCommand( client, reliableAcknowledge );
index = 0;
//
key = client->challenge ^ serverId ^ messageAcknowledge;
View
2 src/engine/server/sv_snapshot.cpp
@@ -225,7 +225,7 @@ void SV_UpdateServerCommandsToClient(client_t * client, msg_t * msg) {
for(i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++) {
MSG_WriteByte(msg, svc_serverCommand);
MSG_WriteLong(msg, i);
- MSG_WriteString(msg, client->reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
+ MSG_WriteString( msg, SV_GetServerCommand( client, i ) );
}
client->reliableSent = client->reliableSequence;
}

0 comments on commit b5f0c4c

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