57typedef struct leakyBucket_s {
65 struct leakyBucket_s*
prev;
66 struct leakyBucket_s*
next;
70#define MAX_BUCKETS 16384
71#define MAX_HASHES 1024
82 return sv->configstrings[
index];
128 value =
va(
"%i", va_arg(ap,
int));
131 value = va_arg(ap,
char*);
145 return sv->configstrings[
index];
162 assert(lastClient >=
svs.clients);
163 assert(lastClient < endOfClients);
168 if (client >= endOfClients)
187 dbuffer msg(2 + strlen(message));
214 svs.killserver =
true;
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) {
254 if (bucket->
next !=
nullptr) {
273 bucket->
prev =
nullptr;
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;
302 if (bucket->
burst < burst) {
352 int teamId =
svs.ge->ClientGetTeamNum(*
cl->player);
396 Com_sprintf(player,
sizeof(player),
"%i \"%s\"\n",
svs.ge->ClientGetTeamNum(*
cl->player),
cl->name);
429 const int version = atoi(
Cmd_Argv(1));
445 infostring[0] =
'\0';
466 if (
sv->started ||
sv->spawned) {
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");
523 cl->player->setNum(playernum);
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);
545 cl->player->setInUse(
true);
546 cl->lastmessage =
svs.realtime;
610 static char sv_outputbuf[1024];
617 char remaining[1024] =
"";
690#define HEARTBEAT_SECONDS 30
723 if (
svs.lastHeartbeat >
svs.realtime)
724 svs.lastHeartbeat =
svs.realtime;
729 svs.lastHeartbeat =
svs.realtime;
768 if (!
sv->spawned ||
sv->started)
791#define PING_SECONDS 5
796 if (
svs.lastPing >
svs.realtime)
797 svs.lastPing =
svs.realtime;
802 svs.lastPing =
svs.realtime;
815 const int droppoint =
svs.realtime - 1000 *
sv_timeout->integer;
826 if (
cl->lastmessage >
svs.realtime)
827 cl->lastmessage =
svs.realtime;
829 if (
cl->lastmessage > 0 &&
cl->lastmessage < droppoint)
857 if (!
svs.initialized) {
859 Com_Printf(
"Starting next map from the mapcycle\n");
871 if (
svs.realtime > 0x70000000) {
887 SDL_CondSignal(
svs.gameFrameCond);
899 if (
svs.abandon &&
svs.killserver)
926 svs.ge->ClientUserinfoChanged(*
cl->player,
cl->userinfo);
932 for (
int i = 0;
i <
sizeof(
cl->name);
i++)
954 return &
sv->mapTiles;
962 Com_Printf(
"\n------ server initialization -------\n");
987 sv_rma =
Cvar_Get(
"sv_rma",
"2", 0,
"1 = old algorithm, 2 = new algorithm");
989 sv_public =
Cvar_Get(
"sv_public",
"1", 0,
"Should heartbeats be send to the masterserver");
1005 dbuffer msg(2 + strlen(message));
1018 cl->stream =
nullptr;
1044 if (!
svs.initialized)
1050 Com_Printf(
"Shutdown server: %s\n", finalmsg);
1058 for (
int i = 0;
i <
sv->numSVModels;
i++) {
1069 SDL_DestroyMutex(
svs.serverMutex);
1101 if (!
svs.initialized)
const char * Sys_ConsoleInput(void)
void setInUse(bool inuse)
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
const char * Cmd_Argv(int arg)
Returns a given argument.
void Cmd_TokenizeString(const char *text, bool macroExpand, bool replaceWhitespaces)
Parses the given string into command line tokens.
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
void Cbuf_AddText(const char *format,...)
Adds command text at the end of the buffer.
void Com_SetServerState(int state)
void Com_ReadFromPipe(void)
Read whatever is in com_pipefile, if anything, and execute it.
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
void Com_Error(int code, const char *fmt,...)
void Com_SetGameType(void)
void Com_Printf(const char *const fmt,...)
cvar_t * masterserver_url
void Com_BeginRedirect(struct net_stream *stream, char *buffer, int buffersize)
Redirect packets/output from server to client.
bool Com_CheckConfigStringIndex(int index)
void Com_EndRedirect(void)
End the redirection of packets/output.
bool Cvar_SetCheckFunction(const char *varName, bool(*check)(cvar_t *cvar))
Set a checker function for cvar values.
bool Cvar_AssertValue(cvar_t *cvar, float minVal, float maxVal, bool shouldBeIntegral)
Checks cvar values.
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
const char * Cvar_GetString(const char *varName)
Returns the value of cvar as string.
const char * Cvar_Serverinfo(char *info, size_t infoSize)
Returns an info string containing all the CVAR_SERVERINFO cvars.
cvar_t * sv_maxsoldiersperplayer
cvar_t * sv_maxsoldiersperteam
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).
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.
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 Info_SetValueForKeyAsInteger(char *s, const size_t size, const char *key, const int value)
int Info_IntegerForKey(const char *s, const char *key)
#define Mem_CreatePool(name)
#define Mem_PoolAllocType(type, pool)
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 NET_StreamSetData(struct net_stream *s, void *data)
void * NET_StreamGetData(struct net_stream *s)
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 NET_StreamFree(struct net_stream *s)
Call NET_StreamFree to dump the whole thing right now.
const char * NET_StreamToString(struct net_stream *s)
Returns the numerical representation of a net_stream.
void NET_Wait(int timeout)
void NET_DatagramSocketClose(struct datagram_socket *s)
const char * NET_StreamPeerToName(struct net_stream *s, char *dst, int len, bool appendPort)
int NET_ReadStringLine(dbuffer *buf, char *string, size_t length)
void NET_WriteRawString(dbuffer *buf, const char *str)
Skip the zero string terminal character. If you need it, use NET_WriteString.
void NET_WriteMsg(struct net_stream *s, dbuffer &buf)
Enqueue the buffer in the net stream for ONE client.
int NET_ReadByte(dbuffer *buf)
Reads a byte from the netchannel.
void NET_WriteByte(dbuffer *buf, byte c)
void NET_WriteConstMsg(struct net_stream *s, const dbuffer &buf)
Enqueue the buffer in the net stream for MULTIPLE clients.
void NET_OOB_Printf(struct net_stream *s, const char *format,...)
Out of band print.
void NET_WriteString(dbuffer *buf, const char *str)
#define CL_CMD_CLIENT_CONNECT
#define MAX_ENTITYSTRINGS
#define REJ_CONNECTION_REFUSED
#define BAD_RCON_PASSWORD
#define REJ_SERVER_VERSION_MISMATCH
#define REJ_GAME_ALREADY_STARTED
static wrapCache_t * hash[MAX_WRAP_HASH]
QGL_EXTERN GLsizei const GLvoid * data
Main server include file.
memPool_t * sv_genericPool
void SV_MapcycleClear(void)
Empty the mapcycle list.
cvar_t * sv_rmadisplaythemap
display a character graphic of the tiles placed when RMA2 reaches a dead end.
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.
void SV_MapcycleInit(void)
void SV_ShutdownGameProgs(void)
Called when either the entire server is being killed, or it is changing to a different game directory...
void SV_InitOperatorCommands(void)
void SV_NextMapcycle(void)
Start the next map in the cycle.
void SV_RunGameFrame(void)
Calls the G_RunFrame function from game api let everything in the world think and move.
serverInstanceGame_t * sv
void SV_SetClientState(client_t *client, client_state_t state)
Set the client state.
void void void SV_BroadcastPrintf(int level, const char *fmt,...) __attribute__((format(__printf__
#define SV_SetConfigString(index, value)
serverInstanceStatic_t svs
void SV_ClientCommand(client_t *client, const char *fmt,...) __attribute__((format(__printf__
void void void void SV_ExecuteClientMessage(client_t *cl, int cmd, dbuffer *msg)
The current net_message is parsed for the given client.
cvar_t * sv_dumpmapassembly
bool Q_strnull(const char *string)
unsigned int Com_HashKey(const char *name, int hashsize)
returns hash key for a string
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
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...
struct net_stream * stream
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
struct leakyBucket_s * next
struct leakyBucket_s * prev
Struct that is only valid for one map. It's deleted on every map load.
static mesh models (none-animated) can have a server side flag set to be clipped for pathfinding
void SV_LogShutdown(void)
void SV_LogHandleOutput(void)
Handle the log output from the main thread by reading the strings from the dbuffer the game lib threa...
game lib logging handling
char * SV_GetConfigString(int index)
static leakyBucket_t * SVC_BucketForAddress(struct net_stream &address, int burst, int period)
Find or allocate a bucket for an address.
static leakyBucket_t * bucketHashes[MAX_HASHES]
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.
static void Master_Shutdown(void)
Informs all masters that this server is going down.
static bool Rcon_Validate(const char *password)
Checks whether the remote connection is allowed (rcon_password must be set on the server) - and verif...
static cvar_t * sv_http_downloadserver
client_t * SV_GetClient(int index)
static void SVC_TeamInfo(struct net_stream *s)
Responds with teaminfo such as free team num.
static void SVC_RemoteCommand(struct net_stream *stream)
A client issued an rcon command. Shift down the remaining args. Redirect all printfs.
static leakyBucket_t buckets[MAX_BUCKETS]
static cvar_t * rcon_password
static void SVC_Info(struct net_stream *s)
Responds with short info for broadcast scans.
void SV_ReadPacket(struct net_stream *s)
static bool SVC_RateLimit(leakyBucket_t *bucket, int burst=10, int period=100)
static void SV_PingPlayers(void)
static void SVC_DirectConnect(struct net_stream *stream)
A connection request that did not come from the master.
static void SV_ConnectionlessPacket(struct net_stream *stream, dbuffer *msg)
Handles a connectionless message from a client.
int SV_GetConfigStringLength(int index)
static cvar_t * sv_timeout
int SV_GetConfigStringInteger(int index)
mapData_t * SV_GetMapData(void)
static void SV_CheckSpawnSoldiers(void)
If all connected clients have set their ready flag the server will spawn the clients and that change ...
void SV_ShutdownWhenEmpty(void)
Will eventually shutdown the server once all clients have disconnected.
mapTiles_t * SV_GetMapTiles(void)
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.
static void SV_CheckStartMatch(void)
void SV_Shutdown(const char *finalmsg, bool reconnect)
Called when each game quits, before Sys_Quit or Sys_Error.
int SV_CountPlayers(void)
Returns the number of spawned players.
static void SV_CheckTimeouts(void)
static bool SVC_RateLimitAddress(struct net_stream &from, int burst=10, int period=1000)
Rate limit for a particular address.
client_t * SV_GetNextClient(client_t *lastClient)
Iterates through clients.
void SV_Frame(int now, void *data)
static bool SV_CheckMaxSoldiersPerPlayer(cvar_t *cvar)
void SV_Clear(void)
Cleanup when the whole game process is shutting down.
void SV_DropClient(client_t *drop, const char *message)
Called when the player is totally leaving the server, either willingly or unwillingly....
void SV_Init(void)
Only called once at startup, not for each game.
static void SVC_Status(struct net_stream *s)
Responds with all the info that the server browser can see.
#define HEARTBEAT_SECONDS
void SV_UserinfoChanged(client_t *cl)
Pull specific info from a newly changed userinfo string into a more C friendly form.
static SDL_Thread * masterServerHeartBeatThread
static cvar_t * sv_reconnect_limit
static cvar_t * sv_hostname
static void Master_Heartbeat(void)
static leakyBucket_t outboundLeakyBucket
int Sys_Milliseconds(void)
SDL_Thread * Com_CreateThread(int(*fn)(void *), const char *name, void *data=nullptr)