This is a fork of Zandronum Beta for TSPG.
Revisión | ff53493bde0d753a8a508e3dd75362a575279878 (tree) |
---|---|
Tiempo | 2021-12-01 13:46:46 |
Autor | Adam Kaminski <kaminskiadam9@gmai...> |
Commiter | Adam Kaminski |
The server no longer ignores commands that arrived too late anymore, but rather only ignores duplicates of commands it already received from a player.
@@ -2137,6 +2137,10 @@ | ||
2137 | 2137 | // should be able to go back is the gametic they connected with. |
2138 | 2138 | g_aClients[lClient].lLastServerGametic = gametic; |
2139 | 2139 | |
2140 | + // [AK] Clear any recent command gametics from the client. | |
2141 | + g_aClients[lClient].recentMoveCMDs.clear(); | |
2142 | + g_aClients[lClient].recentSelectCMDs.clear(); | |
2143 | + | |
2140 | 2144 | // [AK] Reset the client's tic buffer. |
2141 | 2145 | SERVER_ResetClientTicBuffer( lClient ); |
2142 | 2146 |
@@ -5300,13 +5304,27 @@ | ||
5300 | 5304 | const ULONG ulClientTic = cmd->getClientTic( ); |
5301 | 5305 | const bool bIsMoveCMD = cmd->isMoveCmd( ); |
5302 | 5306 | |
5303 | - // [AK] Ignore commands that arrived too late or are duplicates of commands we already processed, | |
5304 | - // neither of which we can account for anymore. This way, we aren't processing the same commands | |
5305 | - // again, or that happened too far into the past. | |
5306 | - if (( ulClientTic != 0 ) && ( ulClientTic <= g_aClients[g_lCurrentClient].ulClientGameTic )) | |
5307 | - { | |
5308 | - delete cmd; | |
5309 | - return false; | |
5307 | + // [AK] Ignore commands that are duplicates of commands we already received and/or processed. | |
5308 | + // This way, we won't process the exact same commands multiple times. | |
5309 | + if ( ulClientTic != 0 ) | |
5310 | + { | |
5311 | + RingBuffer<ULONG, MAX_RECENT_COMMANDS> *recentCMDs; | |
5312 | + | |
5313 | + // [AK] Move commands and weapon select commands each have their own ring buffers, since | |
5314 | + // a movement and weapon select commands with the same gametic can co-exist. | |
5315 | + recentCMDs = bIsMoveCMD ? &g_aClients[g_lCurrentClient].recentMoveCMDs : &g_aClients[g_lCurrentClient].recentSelectCMDs; | |
5316 | + | |
5317 | + for ( unsigned int i = 0; i < MAX_RECENT_COMMANDS; i++ ) | |
5318 | + { | |
5319 | + if ( recentCMDs->getOldestEntry( i ) == ulClientTic ) | |
5320 | + { | |
5321 | + delete cmd; | |
5322 | + return false; | |
5323 | + } | |
5324 | + } | |
5325 | + | |
5326 | + // [AK] Save this gametic into the ring buffer for later use. | |
5327 | + recentCMDs->put( ulClientTic ); | |
5310 | 5328 | } |
5311 | 5329 | |
5312 | 5330 | if ( sv_useticbuffer ) |
@@ -5336,25 +5354,11 @@ | ||
5336 | 5354 | { |
5337 | 5355 | ULONG ulBufferClientTic = (*buffer)[i]->getClientTic( ); |
5338 | 5356 | |
5339 | - if ( ulBufferClientTic != 0 ) | |
5357 | + // [AK] Reorganize the commands in case they arrived in the wrong order. | |
5358 | + if (( ulBufferClientTic != 0 ) && ( ulClientTic < ulBufferClientTic )) | |
5340 | 5359 | { |
5341 | - // [AK] Double-check to make sure we don't already have this command stored anywhere in the buffer. | |
5342 | - // If it's not a late command, we also need to make sure there aren't any newer move commands already | |
5343 | - // in the tic buffer. If any of these conditions fail, we have to ignore this command. | |
5344 | - // Movement and weapon select commands with the same gametic can co-exist in the tic buffer, as | |
5345 | - // they're not the same command, but two movement or weapon select commands cannot. | |
5346 | - if (( ulBufferClientTic == ulClientTic ) && ( bIsMoveCMD == (*buffer)[i]->isMoveCmd( ))) | |
5347 | - { | |
5348 | - delete cmd; | |
5349 | - return false; | |
5350 | - } | |
5351 | - | |
5352 | - // [AK] Reorganize the commands in case they arrived in the wrong order. | |
5353 | - if ( ulClientTic < ulBufferClientTic ) | |
5354 | - { | |
5355 | - buffer->Insert( i, cmd ); | |
5356 | - return false; | |
5357 | - } | |
5360 | + buffer->Insert( i, cmd ); | |
5361 | + return false; | |
5358 | 5362 | } |
5359 | 5363 | } |
5360 | 5364 | } |
@@ -5563,14 +5567,7 @@ | ||
5563 | 5567 | |
5564 | 5568 | // [AK] Clear all stored commands in the tic buffer. |
5565 | 5569 | for ( unsigned int i = 0; i < g_aClients[ulClient].MoveCMDs.Size( ); i++ ) |
5566 | - { | |
5567 | - // [AK] Set the client's gametic to the last command in their tic buffer that has a non-zero | |
5568 | - // gametic. This way, any old and therefore invalid backup commands will be rejected. | |
5569 | - if ( g_aClients[ulClient].MoveCMDs[i]->getClientTic( ) != 0 ) | |
5570 | - g_aClients[ulClient].ulClientGameTic = g_aClients[ulClient].MoveCMDs[i]->getClientTic( ); | |
5571 | - | |
5572 | 5570 | delete g_aClients[ulClient].MoveCMDs[i]; |
5573 | - } | |
5574 | 5571 | |
5575 | 5572 | g_aClients[ulClient].MoveCMDs.Clear( ); |
5576 | 5573 |
@@ -5600,12 +5597,9 @@ | ||
5600 | 5597 | // to the last late command we received from them and update their gametic. |
5601 | 5598 | if ( bUpdatedLastMoveCMD == false ) |
5602 | 5599 | { |
5603 | - ULONG ulNewClientGametic = g_aClients[ulClient].LastMoveCMD->getClientTic( ) + g_aClients[ulClient].ulExtrapolatedTics; | |
5604 | - | |
5605 | 5600 | delete g_aClients[ulClient].LastMoveCMD; |
5606 | 5601 | g_aClients[ulClient].LastMoveCMD = static_cast<ClientMoveCommand *>( g_aClients[ulClient].LateMoveCMDs[i] ); |
5607 | 5602 | |
5608 | - g_aClients[ulClient].LastMoveCMD->setClientTic( ulNewClientGametic ); | |
5609 | 5603 | bUpdatedLastMoveCMD = true; |
5610 | 5604 | continue; |
5611 | 5605 | } |
@@ -82,6 +82,9 @@ | ||
82 | 82 | // Amount of time the client has to report his checksum of the level. |
83 | 83 | #define CLIENT_CHECKSUM_WAITTIME ( 15 * TICRATE ) |
84 | 84 | |
85 | +// [AK] Maximum amount of gametics of recent commands from a client that we can store. | |
86 | +#define MAX_RECENT_COMMANDS 15 | |
87 | + | |
85 | 88 | // This is for the server console, but since we normally can't include that (win32 stuff), |
86 | 89 | // we can just put it here. |
87 | 90 | #define UDF_NAME 0x00000001 |
@@ -392,6 +395,12 @@ | ||
392 | 395 | // [BB] A record of the gametics the client called protected minor commands, e.g. toggleconsole. |
393 | 396 | RingBuffer<LONG, 100> minorCommandInstances; |
394 | 397 | |
398 | + // [AK] A list of gametics of the last few movement commands the client sent us. | |
399 | + RingBuffer<ULONG, MAX_RECENT_COMMANDS> recentMoveCMDs; | |
400 | + | |
401 | + // [AK] A list of (non-zero) gametics of the last few weapon select commands the client sent us. | |
402 | + RingBuffer<ULONG, MAX_RECENT_COMMANDS> recentSelectCMDs; | |
403 | + | |
395 | 404 | // A record of the gametic the client spoke at. We store the last MAX_CHATINSTANCE_STORAGE |
396 | 405 | // times the client chatted. This is used to chat spam protection. |
397 | 406 | LONG lChatInstances[MAX_CHATINSTANCE_STORAGE]; |