mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-10 08:00:05 +00:00
(svn r20553) -Feature: allow rate limiting of incoming commands
This commit is contained in:
parent
cfc0df152b
commit
a4c6d07edc
@ -1757,6 +1757,7 @@ STR_NETWORK_ERROR_SERVER_FULL :{WHITE}The serv
|
||||
STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}You are banned from this server
|
||||
STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game
|
||||
STR_NETWORK_ERROR_CHEATER :{WHITE}Cheating is not allowed on this server
|
||||
STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}You were sending too many commands to the server
|
||||
|
||||
############ Leave those lines in this order!!
|
||||
STR_NETWORK_ERROR_CLIENT_GENERAL :general error
|
||||
@ -1774,6 +1775,7 @@ STR_NETWORK_ERROR_CLIENT_COMPANY_MISMATCH :wrong company i
|
||||
STR_NETWORK_ERROR_CLIENT_KICKED :kicked by server
|
||||
STR_NETWORK_ERROR_CLIENT_CHEATER :was trying to use a cheat
|
||||
STR_NETWORK_ERROR_CLIENT_SERVER_FULL :server full
|
||||
STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS :was sending too many commands
|
||||
############ End of leave-in-this-order
|
||||
|
||||
# Network related errors
|
||||
|
@ -78,6 +78,7 @@ struct CommandPacket;
|
||||
class CommandQueue {
|
||||
CommandPacket *first; ///< The first packet in the queue.
|
||||
CommandPacket *last; ///< The last packet in the queue; only valid when first != NULL.
|
||||
uint count; ///< The number of items in the queue.
|
||||
|
||||
public:
|
||||
/** Initialise the command queue. */
|
||||
@ -88,6 +89,8 @@ public:
|
||||
CommandPacket *Pop();
|
||||
CommandPacket *Peek();
|
||||
void Free();
|
||||
/** Get the number of items in the queue. */
|
||||
uint Count() const { return this->count; }
|
||||
};
|
||||
|
||||
/** Status of a client */
|
||||
|
@ -344,7 +344,8 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err)
|
||||
STR_NETWORK_ERROR_CLIENT_COMPANY_MISMATCH,
|
||||
STR_NETWORK_ERROR_CLIENT_KICKED,
|
||||
STR_NETWORK_ERROR_CLIENT_CHEATER,
|
||||
STR_NETWORK_ERROR_CLIENT_SERVER_FULL
|
||||
STR_NETWORK_ERROR_CLIENT_SERVER_FULL,
|
||||
STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS
|
||||
};
|
||||
|
||||
if (err >= (ptrdiff_t)lengthof(network_error_strings)) err = NETWORK_ERROR_GENERAL;
|
||||
@ -1181,14 +1182,13 @@ void NetworkGameLoop()
|
||||
f = NULL;
|
||||
}
|
||||
#endif /* DEBUG_DUMP_COMMANDS */
|
||||
NetworkDistributeCommands();
|
||||
|
||||
if (_frame_counter >= _frame_counter_max) {
|
||||
/* Only check for active clients just before we're going to send out
|
||||
* the commands so we don't send multiple pause/unpause commands when
|
||||
* the frame_freq is more than 1 tick. */
|
||||
* the frame_freq is more than 1 tick. Same with distributing commands. */
|
||||
CheckPauseOnJoin();
|
||||
CheckMinActiveClients();
|
||||
NetworkDistributeCommands();
|
||||
}
|
||||
|
||||
bool send_frame = false;
|
||||
|
@ -515,6 +515,9 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
|
||||
case NETWORK_ERROR_CHEATER:
|
||||
_switch_mode_errorstr = STR_NETWORK_ERROR_CHEATER;
|
||||
break;
|
||||
case NETWORK_ERROR_TOO_MANY_COMMANDS:
|
||||
_switch_mode_errorstr = STR_NETWORK_ERROR_TOO_MANY_COMMANDS;
|
||||
break;
|
||||
default:
|
||||
_switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "network.h"
|
||||
#include "../command_func.h"
|
||||
#include "../company_func.h"
|
||||
#include "../settings_type.h"
|
||||
|
||||
/** Table with all the callbacks we'll use for conversion*/
|
||||
static CommandCallback * const _callback_table[] = {
|
||||
@ -68,6 +69,7 @@ void CommandQueue::Append(CommandPacket *p)
|
||||
this->last->next = add;
|
||||
}
|
||||
this->last = add;
|
||||
this->count++;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +79,10 @@ void CommandQueue::Append(CommandPacket *p)
|
||||
CommandPacket *CommandQueue::Pop()
|
||||
{
|
||||
CommandPacket *ret = this->first;
|
||||
if (ret != NULL) this->first = this->first->next;
|
||||
if (ret != NULL) {
|
||||
this->first = this->first->next;
|
||||
this->count--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -97,6 +102,7 @@ void CommandQueue::Free()
|
||||
while ((cp = this->Pop()) != NULL) {
|
||||
free(cp);
|
||||
}
|
||||
assert(this->count == 0);
|
||||
}
|
||||
|
||||
/** Local queue of packets waiting for handling. */
|
||||
@ -241,8 +247,10 @@ static void DistributeCommandPacket(CommandPacket cp, const NetworkClientSocket
|
||||
*/
|
||||
static void DistributeQueue(CommandQueue *queue, const NetworkClientSocket *owner)
|
||||
{
|
||||
int to_go = _settings_client.network.commands_per_frame;
|
||||
|
||||
CommandPacket *cp;
|
||||
while ((cp = queue->Pop()) != NULL) {
|
||||
while (--to_go >= 0 && (cp = queue->Pop()) != NULL) {
|
||||
DistributeCommandPacket(*cp, owner);
|
||||
free(cp);
|
||||
}
|
||||
|
@ -897,6 +897,10 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
|
||||
return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
|
||||
}
|
||||
|
||||
if (cs->incoming_queue.Count() >= _settings_client.network.max_commands_in_queue) {
|
||||
return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_TOO_MANY_COMMANDS);
|
||||
}
|
||||
|
||||
CommandPacket cp;
|
||||
const char *err = cs->Recv_Command(p, &cp);
|
||||
|
||||
|
@ -110,6 +110,7 @@ enum NetworkErrorCode {
|
||||
NETWORK_ERROR_KICKED,
|
||||
NETWORK_ERROR_CHEATER,
|
||||
NETWORK_ERROR_FULL,
|
||||
NETWORK_ERROR_TOO_MANY_COMMANDS,
|
||||
};
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
@ -128,6 +128,8 @@ struct NetworkSettings {
|
||||
#ifdef ENABLE_NETWORK
|
||||
uint16 sync_freq; ///< how often do we check whether we are still in-sync
|
||||
uint8 frame_freq; ///< how often do we send commands to the clients
|
||||
uint16 commands_per_frame; ///< how many commands may be sent each frame_freq frames?
|
||||
uint16 max_commands_in_queue; ///< how many commands may there be in the incoming queue before dropping the connection?
|
||||
uint16 max_join_time; ///< maximum amount of time, in game ticks, a client may take to join
|
||||
bool pause_on_join; ///< pause the game when people join
|
||||
uint16 server_port; ///< port the server listens on
|
||||
|
@ -622,6 +622,8 @@ const SettingDesc _settings[] = {
|
||||
|
||||
SDTC_VAR(network.sync_freq, SLE_UINT16,C|S,NO, 100, 0, 100, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.frame_freq, SLE_UINT8,C|S,NO, 0, 0, 100, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.commands_per_frame, SLE_UINT16, S, NO, 4, 1, 65535, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.max_commands_in_queue,SLE_UINT16, S, NO, 32, 1, 65535, 0, STR_NULL, NULL),
|
||||
SDTC_VAR(network.max_join_time, SLE_UINT16, S, NO, 500, 0, 32000, 0, STR_NULL, NULL),
|
||||
SDTC_BOOL(network.pause_on_join, S, NO, true, STR_NULL, NULL),
|
||||
SDTC_VAR(network.server_port, SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL, NULL),
|
||||
|
Loading…
Reference in New Issue
Block a user