31 #include "../ports/system.h"
32 #include "../shared/scopedmutex.h"
33 #include "../shared/thread.h"
70 #define MAX_BUCKETS 16384
71 #define MAX_HASHES 1024
128 value =
va(
"%i", va_arg(ap,
int));
131 value = va_arg(ap,
char*);
163 assert(lastClient < endOfClients);
168 if (client >= endOfClients)
187 dbuffer msg(2 + strlen(message));
235 for (
leakyBucket_t* bucket = bucketHashes[hash]; bucket; bucket = bucket->
next) {
236 if (!
Q_streq(bucket->node, node))
244 const int interval = now - bucket->
lastTime;
247 if (bucket->
lastTime > 0 && (interval > (burst * period) || interval < 0)) {
248 if (bucket->
prev !=
nullptr) {
251 bucketHashes[bucket->
hash] = bucket->
next;
254 if (bucket->
next !=
nullptr) {
269 if (bucketHashes[hash] !=
nullptr) {
273 bucket->
prev =
nullptr;
274 bucketHashes[
hash] = bucket;
286 if (bucket ==
nullptr)
290 const int interval = now - bucket->
lastTime;
291 const int expired = interval / period;
292 const int expiredRemainder = interval % period;
294 if (expired > bucket->
burst) {
298 bucket->
burst -= expired;
299 bucket->
lastTime = now - expiredRemainder;
352 int teamId =
svs.
ge->ClientGetTeamNum(*cl->
player);
424 if (sv_maxclients->
integer == 1) {
429 const int version = atoi(
Cmd_Argv(1));
445 infostring[0] =
'\0';
467 Com_Printf(
"rejected connect because match is already running\n");
475 const int version = atoi(
Cmd_Argv(1));
477 Com_Printf(
"rejected connect from version %i - %s\n", version, peername);
486 Com_Printf(
"Empty userinfo from %s\n", peername);
491 if (strchr(userinfo,
'\xFF')) {
492 Com_Printf(
"Illegal userinfo contained xFF from %s\n", peername);
498 Com_Printf(
"Illegal userinfo contained ip from %s\n", peername);
513 Com_Printf(
"Rejected a connection - server is full.\n");
528 connected =
svs.
ge->ClientConnect(player, userinfo,
sizeof(userinfo));
534 if (rejmsg[0] !=
'\0') {
536 Com_Printf(
"Game rejected a connection from %s. Reason: %s\n", peername, rejmsg);
539 Com_Printf(
"Game rejected a connection from %s.\n", peername);
553 if (sv_http_downloadserver->
string[0])
610 static char sv_outputbuf[1024];
617 char remaining[1024] =
"";
690 #define HEARTBEAT_SECONDS 30
719 if (!sv_public || !sv_public->
integer)
771 if (sv_maxclients->
integer > 1) {
791 #define PING_SECONDS 5
817 if (sv_maxclients->
integer == 1)
858 #ifdef DEDICATED_ONLY
859 Com_Printf(
"Starting next map from the mapcycle\n");
911 if (!sv_public || !sv_public->
integer)
932 for (
int i = 0;
i <
sizeof(cl->
name);
i++)
962 Com_Printf(
"\n------ server initialization -------\n");
978 sv_http_downloadserver =
Cvar_Get(
"sv_http_downloadserver",
"",
CVAR_ARCHIVE,
"URL to a location where clients can download game content over HTTP");
980 sv_maxsoldiersperteam =
Cvar_Get(
"sv_maxsoldiersperteam",
"4",
CVAR_ARCHIVE |
CVAR_SERVERINFO,
"Max. amount of soldiers per team (see sv_maxsoldiersperplayer and sv_teamplay)");
984 sv_dumpmapassembly =
Cvar_Get(
"sv_dumpmapassembly",
"0",
CVAR_ARCHIVE,
"Dump map assembly information to game console");
987 sv_rma =
Cvar_Get(
"sv_rma",
"2", 0,
"1 = old algorithm, 2 = new algorithm");
988 sv_rmadisplaythemap =
Cvar_Get(
"sv_rmadisplaythemap",
"0", 0,
"Activate rma problem output");
989 sv_public =
Cvar_Get(
"sv_public",
"1", 0,
"Should heartbeats be send to the masterserver");
990 sv_reconnect_limit =
Cvar_Get(
"sv_reconnect_limit",
"3",
CVAR_ARCHIVE,
"Minimum seconds between connect messages");
1005 dbuffer msg(2 + strlen(message));
1050 Com_Printf(
"Shutdown server: %s\n", finalmsg);
sv_model_t svModels[MAX_MOD_KNOWN]
bool Q_strnull(const char *string)
void SV_ShutdownWhenEmpty(void)
Will eventually shutdown the server once all clients have disconnected.
static void SVC_Status(struct net_stream *s)
Responds with all the info that the server browser can see.
const char * Cmd_Argv(int arg)
Returns a given argument.
static bool SVC_RateLimit(leakyBucket_t *bucket, int burst=10, int period=100)
void NET_StreamFinished(struct net_stream *s)
Call NET_StreamFinished to mark the stream as uninteresting, but to finish sending any data in the bu...
void Info_SetValueForKeyAsInteger(char *s, const size_t size, const char *key, const int value)
void SV_DropClient(client_t *drop, const char *message)
Called when the player is totally leaving the server, either willingly or unwillingly. This is NOT called if the entire server is quitting or crashing.
void void void SV_BroadcastPrintf(int level, const char *fmt,...) __attribute__((format(__printf__
#define HEARTBEAT_SECONDS
memPool_t * sv_genericPool
void setInUse(bool inuse)
static void Master_Shutdown(void)
Informs all masters that this server is going down.
void SV_Init(void)
Only called once at startup, not for each game.
static SDL_Thread * masterServerHeartBeatThread
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
#define CL_CMD_CLIENT_CONNECT
static cvar_t * sv_http_downloadserver
bool Cvar_AssertValue(cvar_t *cvar, float minVal, float maxVal, bool shouldBeIntegral)
Checks cvar values.
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
#define BAD_RCON_PASSWORD
void NET_WriteRawString(dbuffer *buf, const char *str)
Skip the zero string terminal character. If you need it, use NET_WriteString.
static cvar_t * sv_hostname
void NET_Wait(int timeout)
const char * Cvar_Serverinfo(char *info, size_t infoSize)
Returns an info string containing all the CVAR_SERVERINFO cvars.
struct leakyBucket_s * next
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
#define REJ_CONNECTION_REFUSED
char userinfo[MAX_INFO_STRING]
static void SVC_TeamInfo(struct net_stream *s)
Responds with teaminfo such as free team num.
static leakyBucket_t buckets[MAX_BUCKETS]
void Cbuf_AddText(const char *format,...)
Adds command text at the end of the buffer.
static cvar_t * sv_timeout
void NET_WriteString(dbuffer *buf, const char *str)
static void SV_PingPlayers(void)
static void SV_CheckStartMatch(void)
void SV_ReadPacket(struct net_stream *s)
void SV_Map(bool day, const char *levelstring, const char *assembly, bool verbose=true)
Change the server to a new map, taking all connected clients along with it.
client_t * SV_GetClient(int index)
#define MAX_ENTITYSTRINGS
void Cmd_TokenizeString(const char *text, bool macroExpand, bool replaceWhitespaces)
Parses the given string into command line tokens.
void NET_StreamFree(struct net_stream *s)
Call NET_StreamFree to dump the whole thing right now.
void Com_Printf(const char *const fmt,...)
SDL_Thread * Com_CreateThread(int(*fn)(void *), const char *name, void *data=nullptr)
const char * NET_StreamToString(struct net_stream *s)
Returns the numerical representation of a net_stream.
void SV_SetClientState(client_t *client, client_state_t state)
Set the client state.
char * SV_GetConfigString(int index)
void SV_Frame(int now, void *data)
void Com_SetServerState(int state)
static leakyBucket_t * SVC_BucketForAddress(struct net_stream &address, int burst, int period)
Find or allocate a bucket for an address.
void SV_MapcycleClear(void)
Empty the mapcycle list.
void SV_LogShutdown(void)
static cvar_t * sv_reconnect_limit
cvar_t * masterserver_url
static bool Rcon_Validate(const char *password)
Checks whether the remote connection is allowed (rcon_password must be set on the server) - and verif...
void SV_InitOperatorCommands(void)
static bool SVC_RateLimitAddress(struct net_stream &from, int burst=10, int period=1000)
Rate limit for a particular address.
void * NET_StreamGetData(struct net_stream *s)
void Com_Error(int code, const char *fmt,...)
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
Struct that is only valid for one map. It's deleted on every map load.
static leakyBucket_t outboundLeakyBucket
#define REJ_GAME_ALREADY_STARTED
const char * Info_ValueForKey(const char *s, const char *key)
Searches the string for the given key and returns the associated value, or an empty string...
serverInstanceGame_t * sv
cvar_t * sv_rmadisplaythemap
display a character graphic of the tiles placed when RMA2 reaches a dead end.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
static cvar_t * sv_maxsoldiersperteam
void NET_OOB_Printf(struct net_stream *s, const char *format,...)
Out of band print.
void SV_LogHandleOutput(void)
Handle the log output from the main thread by reading the strings from the dbuffer the game lib threa...
client_t * SV_GetNextClient(client_t *lastClient)
Iterates through clients.
void SV_Shutdown(const char *finalmsg, bool reconnect)
Called when each game quits, before Sys_Quit or Sys_Error.
const char * Sys_ConsoleInput(void)
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
game lib logging handling
static void SV_CheckSpawnSoldiers(void)
If all connected clients have set their ready flag the server will spawn the clients and that change ...
static wrapCache_t * hash[MAX_WRAP_HASH]
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
void SV_MapcycleInit(void)
static void SVC_Info(struct net_stream *s)
Responds with short info for broadcast scans.
void Com_EndRedirect(void)
End the redirection of packets/output.
Main server include file.
struct leakyBucket_s * prev
#define Mem_CreatePool(name)
struct leakyBucket_s leakyBucket_t
int SV_GetConfigStringInteger(int index)
void SV_RunGameFrame(void)
Calls the G_RunFrame function from game api let everything in the world think and move...
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
static void SVC_RemoteCommand(struct net_stream *stream)
A client issued an rcon command. Shift down the remaining args. Redirect all printfs.
static void SV_ConnectionlessPacket(struct net_stream *stream, dbuffer *msg)
Handles a connectionless message from a client.
static cvar_t * sv_maxsoldiersperplayer
int SV_GetConfigStringLength(int index)
bool Com_CheckConfigStringIndex(int index)
static void SV_FinalMessage(const char *message, bool reconnect)
Used by SV_Shutdown to send a final message to all connected clients before the server goes down...
void Info_SetValueForKey(char *s, const size_t size, const char *key, const char *value)
Adds a new entry into string with given value.
void Com_BeginRedirect(struct net_stream *stream, char *buffer, int buffersize)
Redirect packets/output from server to client.
void SV_UserinfoChanged(client_t *cl)
Pull specific info from a newly changed userinfo string into a more C friendly form.
void NET_StreamSetData(struct net_stream *s, void *data)
static void Master_Heartbeat(void)
void SV_ClientCommand(client_t *client, const char *fmt,...) __attribute__((format(__printf__
#define REJ_SERVER_VERSION_MISMATCH
cvar_t * sv_dumpmapassembly
mapData_t * SV_GetMapData(void)
struct net_stream * stream
void NET_DatagramSocketClose(struct datagram_socket *s)
struct client_s * clients
void NET_WriteByte(dbuffer *buf, byte c)
static cvar_t * sv_enablemorale
unsigned int Com_HashKey(const char *name, int hashsize)
returns hash key for a string
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
static void SV_CheckTimeouts(void)
void Com_SetGameType(void)
void Com_ReadFromPipe(void)
Read whatever is in com_pipefile, if anything, and execute it.
static cvar_t * rcon_password
void SV_Clear(void)
Cleanup when the whole game process is shutting down.
dbuffer * NET_ReadMsg(struct net_stream *s)
Reads messages from the network channel and adds them to the dbuffer where you can use the NET_Read* ...
void void void void SV_ExecuteClientMessage(client_t *cl, int cmd, dbuffer *msg)
The current net_message is parsed for the given client.
bool HTTP_GetURL(const char *url, http_callback_t callback, void *userdata, const char *postfields)
Downloads the given url and return the data to the callback (optional)
GLsizei const GLvoid * data
const char * NET_StreamPeerToName(struct net_stream *s, char *dst, int len, bool appendPort)
const char * Cvar_GetString(const char *varName)
Returns the value of cvar as string.
#define Mem_PoolAllocType(type, pool)
char configstrings[MAX_CONFIGSTRINGS][MAX_TOKEN_CHARS]
void SV_NextMapcycle(void)
Start the next map in the cycle.
void SV_ShutdownGameProgs(void)
Called when either the entire server is being killed, or it is changing to a different game directory...
static leakyBucket_t * bucketHashes[MAX_HASHES]
static mesh models (none-animated) can have a server side flag set to be clipped for pathfinding ...
static void SVC_DirectConnect(struct net_stream *stream)
A connection request that did not come from the master.
mapTiles_t * SV_GetMapTiles(void)
serverInstanceStatic_t svs
char * SV_SetConfigString(int index,...)
int NET_ReadByte(dbuffer *buf)
Reads a byte from the netchannel.
static bool SV_CheckMaxSoldiersPerPlayer(cvar_t *cvar)
bool Cvar_SetCheckFunction(const char *varName, bool(*check)(cvar_t *cvar))
Set a checker function for cvar values.
int NET_ReadStringLine(dbuffer *buf, char *string, size_t length)
int Info_IntegerForKey(const char *s, const char *key)
static int Master_HeartbeatThread(void *data)
Send a message to the master every few minutes to let it know we are alive, and log information...
int SV_CountPlayers(void)
Returns the number of spawned players.
struct datagram_socket * netDatagramSocket
void NET_WriteConstMsg(struct net_stream *s, const dbuffer &buf)
Enqueue the buffer in the net stream for MULTIPLE clients.
int Sys_Milliseconds(void)
void NET_WriteMsg(struct net_stream *s, dbuffer &buf)
Enqueue the buffer in the net stream for ONE client.