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_SERVER_BANNED :{WHITE}You are banned from this server
|
||||||
STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game
|
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_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!!
|
############ Leave those lines in this order!!
|
||||||
STR_NETWORK_ERROR_CLIENT_GENERAL :general error
|
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_KICKED :kicked by server
|
||||||
STR_NETWORK_ERROR_CLIENT_CHEATER :was trying to use a cheat
|
STR_NETWORK_ERROR_CLIENT_CHEATER :was trying to use a cheat
|
||||||
STR_NETWORK_ERROR_CLIENT_SERVER_FULL :server full
|
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
|
############ End of leave-in-this-order
|
||||||
|
|
||||||
# Network related errors
|
# Network related errors
|
||||||
|
@ -78,6 +78,7 @@ struct CommandPacket;
|
|||||||
class CommandQueue {
|
class CommandQueue {
|
||||||
CommandPacket *first; ///< The first packet in the queue.
|
CommandPacket *first; ///< The first packet in the queue.
|
||||||
CommandPacket *last; ///< The last packet in the queue; only valid when first != NULL.
|
CommandPacket *last; ///< The last packet in the queue; only valid when first != NULL.
|
||||||
|
uint count; ///< The number of items in the queue.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Initialise the command queue. */
|
/** Initialise the command queue. */
|
||||||
@ -88,6 +89,8 @@ public:
|
|||||||
CommandPacket *Pop();
|
CommandPacket *Pop();
|
||||||
CommandPacket *Peek();
|
CommandPacket *Peek();
|
||||||
void Free();
|
void Free();
|
||||||
|
/** Get the number of items in the queue. */
|
||||||
|
uint Count() const { return this->count; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Status of a client */
|
/** Status of a client */
|
||||||
|
@ -344,7 +344,8 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err)
|
|||||||
STR_NETWORK_ERROR_CLIENT_COMPANY_MISMATCH,
|
STR_NETWORK_ERROR_CLIENT_COMPANY_MISMATCH,
|
||||||
STR_NETWORK_ERROR_CLIENT_KICKED,
|
STR_NETWORK_ERROR_CLIENT_KICKED,
|
||||||
STR_NETWORK_ERROR_CLIENT_CHEATER,
|
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;
|
if (err >= (ptrdiff_t)lengthof(network_error_strings)) err = NETWORK_ERROR_GENERAL;
|
||||||
@ -1181,14 +1182,13 @@ void NetworkGameLoop()
|
|||||||
f = NULL;
|
f = NULL;
|
||||||
}
|
}
|
||||||
#endif /* DEBUG_DUMP_COMMANDS */
|
#endif /* DEBUG_DUMP_COMMANDS */
|
||||||
NetworkDistributeCommands();
|
|
||||||
|
|
||||||
if (_frame_counter >= _frame_counter_max) {
|
if (_frame_counter >= _frame_counter_max) {
|
||||||
/* Only check for active clients just before we're going to send out
|
/* 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 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();
|
CheckPauseOnJoin();
|
||||||
CheckMinActiveClients();
|
CheckMinActiveClients();
|
||||||
|
NetworkDistributeCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool send_frame = false;
|
bool send_frame = false;
|
||||||
|
@ -515,6 +515,9 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
|
|||||||
case NETWORK_ERROR_CHEATER:
|
case NETWORK_ERROR_CHEATER:
|
||||||
_switch_mode_errorstr = STR_NETWORK_ERROR_CHEATER;
|
_switch_mode_errorstr = STR_NETWORK_ERROR_CHEATER;
|
||||||
break;
|
break;
|
||||||
|
case NETWORK_ERROR_TOO_MANY_COMMANDS:
|
||||||
|
_switch_mode_errorstr = STR_NETWORK_ERROR_TOO_MANY_COMMANDS;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION;
|
_switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "../command_func.h"
|
#include "../command_func.h"
|
||||||
#include "../company_func.h"
|
#include "../company_func.h"
|
||||||
|
#include "../settings_type.h"
|
||||||
|
|
||||||
/** Table with all the callbacks we'll use for conversion*/
|
/** Table with all the callbacks we'll use for conversion*/
|
||||||
static CommandCallback * const _callback_table[] = {
|
static CommandCallback * const _callback_table[] = {
|
||||||
@ -68,6 +69,7 @@ void CommandQueue::Append(CommandPacket *p)
|
|||||||
this->last->next = add;
|
this->last->next = add;
|
||||||
}
|
}
|
||||||
this->last = add;
|
this->last = add;
|
||||||
|
this->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +79,10 @@ void CommandQueue::Append(CommandPacket *p)
|
|||||||
CommandPacket *CommandQueue::Pop()
|
CommandPacket *CommandQueue::Pop()
|
||||||
{
|
{
|
||||||
CommandPacket *ret = this->first;
|
CommandPacket *ret = this->first;
|
||||||
if (ret != NULL) this->first = this->first->next;
|
if (ret != NULL) {
|
||||||
|
this->first = this->first->next;
|
||||||
|
this->count--;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +102,7 @@ void CommandQueue::Free()
|
|||||||
while ((cp = this->Pop()) != NULL) {
|
while ((cp = this->Pop()) != NULL) {
|
||||||
free(cp);
|
free(cp);
|
||||||
}
|
}
|
||||||
|
assert(this->count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Local queue of packets waiting for handling. */
|
/** 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)
|
static void DistributeQueue(CommandQueue *queue, const NetworkClientSocket *owner)
|
||||||
{
|
{
|
||||||
|
int to_go = _settings_client.network.commands_per_frame;
|
||||||
|
|
||||||
CommandPacket *cp;
|
CommandPacket *cp;
|
||||||
while ((cp = queue->Pop()) != NULL) {
|
while (--to_go >= 0 && (cp = queue->Pop()) != NULL) {
|
||||||
DistributeCommandPacket(*cp, owner);
|
DistributeCommandPacket(*cp, owner);
|
||||||
free(cp);
|
free(cp);
|
||||||
}
|
}
|
||||||
|
@ -897,6 +897,10 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
|
|||||||
return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
|
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;
|
CommandPacket cp;
|
||||||
const char *err = cs->Recv_Command(p, &cp);
|
const char *err = cs->Recv_Command(p, &cp);
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ enum NetworkErrorCode {
|
|||||||
NETWORK_ERROR_KICKED,
|
NETWORK_ERROR_KICKED,
|
||||||
NETWORK_ERROR_CHEATER,
|
NETWORK_ERROR_CHEATER,
|
||||||
NETWORK_ERROR_FULL,
|
NETWORK_ERROR_FULL,
|
||||||
|
NETWORK_ERROR_TOO_MANY_COMMANDS,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ENABLE_NETWORK */
|
#endif /* ENABLE_NETWORK */
|
||||||
|
@ -128,6 +128,8 @@ struct NetworkSettings {
|
|||||||
#ifdef ENABLE_NETWORK
|
#ifdef ENABLE_NETWORK
|
||||||
uint16 sync_freq; ///< how often do we check whether we are still in-sync
|
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
|
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
|
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
|
bool pause_on_join; ///< pause the game when people join
|
||||||
uint16 server_port; ///< port the server listens on
|
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.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.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_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_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),
|
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