diff --git a/code/client/cl_input.c b/code/client/cl_input.c index 72056a28..f0147682 100644 --- a/code/client/cl_input.c +++ b/code/client/cl_input.c @@ -863,7 +863,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 ^= MSG_HashKey(clc.serverCommands[ clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS-1) ], 32); // write all the commands, including the predicted command for ( i = 0 ; i < count ; i++ ) { diff --git a/code/qcommon/common.c b/code/qcommon/common.c index 2f4e8438..b8bef851 100644 --- a/code/qcommon/common.c +++ b/code/qcommon/common.c @@ -672,22 +672,6 @@ int Com_FilterPath(char *filter, char *name, int casesensitive) return Com_Filter(new_filter, new_name, casesensitive); } -/* -============ -Com_HashKey -============ -*/ -int Com_HashKey(char *string, int maxlen) { - int register hash, i; - - hash = 0; - for (i = 0; i < maxlen && string[i] != '\0'; i++) { - hash += string[i] * (119 + i); - } - hash = (hash ^ (hash >> 10) ^ (hash >> 20)); - return hash; -} - /* ================ Com_RealTime diff --git a/code/qcommon/msg.c b/code/qcommon/msg.c index b883c83b..04fb424a 100644 --- a/code/qcommon/msg.c +++ b/code/qcommon/msg.c @@ -311,9 +311,9 @@ void MSG_WriteString( msg_t *sb, const char *s ) { } Q_strncpyz( string, s, sizeof( string ) ); - // get rid of 0xff chars, because old clients don't like them + // get rid of 0x80+ and '%' chars, because old clients don't like them for ( i = 0 ; i < l ; i++ ) { - if ( ((byte *)string)[i] > 127 ) { + if ( ((byte *)string)[i] > 127 || string[i] == '%' ) { string[i] = '.'; } } @@ -337,9 +337,9 @@ void MSG_WriteBigString( msg_t *sb, const char *s ) { } Q_strncpyz( string, s, sizeof( string ) ); - // get rid of 0xff chars, because old clients don't like them + // get rid of 0x80+ and '%' chars, because old clients don't like them for ( i = 0 ; i < l ; i++ ) { - if ( ((byte *)string)[i] > 127 ) { + if ( ((byte *)string)[i] > 127 || string[i] == '%' ) { string[i] = '.'; } } @@ -525,6 +525,21 @@ void MSG_ReadData( msg_t *msg, void *data, int len ) { } } +// a string hasher which gives the same hash value even if the +// string is later modified via the legacy MSG read/write code +int MSG_HashKey(const char *string, int maxlen) { + int hash, i; + + hash = 0; + for (i = 0; i < maxlen && string[i] != '\0'; i++) { + if (string[i] & 0x80 || string[i] == '%') + hash += '.' * (119 + i); + else + hash += string[i] * (119 + i); + } + hash = (hash ^ (hash >> 10) ^ (hash >> 20)); + return hash; +} /* ============================================================================= diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index a2d81060..d1cc2fde 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -76,6 +76,7 @@ void MSG_WriteFloat (msg_t *sb, float f); void MSG_WriteString (msg_t *sb, const char *s); void MSG_WriteBigString (msg_t *sb, const char *s); void MSG_WriteAngle16 (msg_t *sb, float f); +int MSG_HashKey(const char *string, int maxlen); void MSG_BeginReading (msg_t *sb); void MSG_BeginReadingOOB(msg_t *sb); @@ -799,7 +800,6 @@ void Com_Quit_f( void ); int Com_Milliseconds( void ); // will be journaled properly unsigned Com_BlockChecksum( const void *buffer, int length ); char *Com_MD5File(const char *filename, int length, const char *prefix, int prefix_len); -int Com_HashKey(char *string, int maxlen); int Com_Filter(char *filter, char *name, int casesensitive); int Com_FilterPath(char *filter, char *name, int casesensitive); int Com_RealTime(qtime_t *qtime); diff --git a/code/server/sv_client.c b/code/server/sv_client.c index 4387d24b..1195c88b 100644 --- a/code/server/sv_client.c +++ b/code/server/sv_client.c @@ -1605,7 +1605,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 ^= MSG_HashKey(cl->reliableCommands[ cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ], 32); Com_Memset( &nullcmd, 0, sizeof(nullcmd) ); oldcmd = &nullcmd;