Beispiel #1
0
/**
 * @sa CL_ServerInfoCallback
 */
static void CL_ServerInfo_f (void)
{
	struct net_stream *s;
	const char *host;
	const char *port;

	switch (cgi->Cmd_Argc()) {
	case 2:
		host = cgi->Cmd_Argv(1);
		port = DOUBLEQUOTE(PORT_SERVER);
		break;
	case 3:
		host = cgi->Cmd_Argv(1);
		port = cgi->Cmd_Argv(2);
		break;
	default:
		if (selectedServer) {
			host = selectedServer->node;
			port = selectedServer->service;
		} else {
			host = cgi->Cvar_GetString("mn_server_ip");
			port = DOUBLEQUOTE(PORT_SERVER);
		}
		break;
	}
	s = cgi->NET_Connect(host, port, NULL);
	if (s) {
		cgi->NET_OOB_Printf(s, "status %i", PROTOCOL_VERSION);
		cgi->NET_StreamSetCallback(s, &CL_ServerInfoCallback);
	} else
		cgi->Com_Printf("Could not connect to %s %s\n", host, port);
}
Beispiel #2
0
/**
 * @brief Sends an rcon command to the gameserver that the user is currently connected to,
 * or if this is not the case, the gameserver that is specified in the cvar rcon_address.
 * @return @c true if the command was send, @c false otherwise.
 */
bool GAME_MP_Rcon (const char* password, const char* command)
{
	if (Q_strnull(password)) {
		cgi->Com_Printf("You must set 'rcon_password' before issuing a rcon command.\n");
		return false;
	}

	if (cgi->CL_GetClientState() >= ca_connected) {
		cgi->NET_OOB_Printf2(SV_CMD_RCON " %s %s", password, command);
		return true;
	} else if (rcon_address->string) {
		const char* port;

		if (strstr(rcon_address->string, ":"))
			port = strstr(rcon_address->string, ":") + 1;
		else
			port = DOUBLEQUOTE(PORT_SERVER);

		struct net_stream* s = cgi->NET_Connect(rcon_address->string, port, nullptr);
		if (s) {
			cgi->NET_OOB_Printf(s, SV_CMD_RCON " %s %s", password, command);
			cgi->NET_StreamSetCallback(s, &GAME_MP_RconCallback);
			return true;
		}
	}

	cgi->Com_Printf("You are not connected to any server\n");
	return false;
}
Beispiel #3
0
/**
 * @brief A brand new game has been started
 */
static void SV_InitGame (void)
{
	/* allow next change after map change or restart */
	sv_maxclients->flags |= CVAR_LATCH;

	/* get any latched variable changes (sv_maxclients, etc) */
	Cvar_UpdateLatchedVars();

	if (svs.serverMutex)
		Sys_Error("There is still a server running");

	svs.clients = (client_t *)Mem_PoolAlloc(sizeof(client_t) * sv_maxclients->integer, sv_genericPool, 0);
	svs.serverMutex = TH_MutexCreate("server");

	/* init network stuff */
	if (sv_maxclients->integer > 1) {
		svs.initialized = SV_Start(NULL, port->string, &SV_ReadPacket);
		svs.netDatagramSocket = NET_DatagramSocketNew(NULL, Cvar_Get("port", DOUBLEQUOTE(PORT_SERVER), CVAR_NOSET, NULL)->string, &SV_DiscoveryCallback);
	} else
		svs.initialized = SV_Start(NULL, NULL, &SV_ReadPacket);

	SV_Heartbeat_f();

	/* init game */
	SV_InitGameProgs();

	if (sv_maxclients->integer != 1 && (sv_dedicated->integer || sv_public->integer))
		SV_SetMaster_f();
}
Beispiel #4
0
void R_InitPrograms (void)
{
	if (!qglCreateProgram) {
		Com_Printf("not using GLSL shaders\n");
		Cvar_Set("r_programs", "0");
		r_programs->modified = false;
		return;
	}

	OBJZERO(r_state.shaders);
	OBJZERO(r_state.programs);

	/* Capable of running shaders, but have got them disabled, so do nothing */
	if (!r_programs->integer)
		return;

	r_state.world_program = R_LoadProgram(shaderQualityLevelNames[r_programs->integer - 1][0], R_InitWorldProgram, R_UseWorldProgram);
	r_state.model_program = R_LoadProgram(shaderQualityLevelNames[r_programs->integer - 1][1], R_InitModelProgram, R_UseModelProgram);
	r_state.warp_program = R_LoadProgram("warp", R_InitWarpProgram, R_UseWarpProgram);
	r_state.geoscape_program = R_LoadProgram("geoscape", R_InitGeoscapeProgram, nullptr);
	r_state.combine2_program = R_LoadProgram("combine2", R_InitCombine2Program, nullptr);
	r_state.convolve_program = R_LoadProgram("convolve" DOUBLEQUOTE(FILTER_SIZE), R_InitConvolveProgram, R_UseConvolveProgram);
	r_state.atmosphere_program = R_LoadProgram("atmosphere", R_InitAtmosphereProgram, nullptr);
	r_state.simple_glow_program = R_LoadProgram("simple_glow", R_InitSimpleGlowProgram, nullptr);

	if (!(r_state.world_program && r_state.model_program && r_state.warp_program && r_state.geoscape_program && r_state.combine2_program
		&& r_state.convolve_program && r_state.atmosphere_program && r_state.simple_glow_program)) {
		Com_Printf("disabled shaders because they failed to compile\n");
		Cvar_Set("r_programs", "0");
		r_programs->modified = false;
	}
}
Beispiel #5
0
/**
 * @brief Only called once at startup, not for each game
 */
void SV_Init (void)
{
	Com_Printf("\n------ server initialization -------\n");

	sv_genericPool = Mem_CreatePool("Server: Generic");

	OBJZERO(svs);

	sv = (serverInstanceGame_t *) Mem_PoolAlloc(sizeof(*sv), sv_genericPool, 0);

	SV_InitOperatorCommands();

	rcon_password = Cvar_Get("rcon_password", "", 0, NULL);
	Cvar_Get("sv_cheats", "0", CVAR_SERVERINFO | CVAR_LATCH, NULL);
	Cvar_Get("sv_protocol", DOUBLEQUOTE(PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_NOSET, NULL);
	/* this cvar will become a latched cvar when you start the server */
	sv_maxclients = Cvar_Get("sv_maxclients", "1", CVAR_SERVERINFO, "Max. connected clients");
	sv_hostname = Cvar_Get("sv_hostname", "noname", CVAR_SERVERINFO | CVAR_ARCHIVE, "The name of the server that is displayed in the serverlist");
	sv_http_downloadserver = Cvar_Get("sv_http_downloadserver", "", CVAR_ARCHIVE, "URL to a location where clients can download game content over HTTP");
	sv_enablemorale = Cvar_Get("sv_enablemorale", "1", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_LATCH, "Enable morale changes in multiplayer");
	sv_maxsoldiersperteam = Cvar_Get("sv_maxsoldiersperteam", "4", CVAR_ARCHIVE | CVAR_SERVERINFO, "Max. amount of soldiers per team (see sv_maxsoldiersperplayer and sv_teamplay)");
	sv_maxsoldiersperplayer = Cvar_Get("sv_maxsoldiersperplayer", "8", CVAR_ARCHIVE | CVAR_SERVERINFO, "Max. amount of soldiers each player can controll (see maxsoldiers and sv_teamplay)");
	Cvar_SetCheckFunction("sv_maxsoldiersperplayer", SV_CheckMaxSoldiersPerPlayer);

	sv_dumpmapassembly = Cvar_Get("sv_dumpmapassembly", "0", CVAR_ARCHIVE, "Dump map assembly information to game console");

	sv_threads = Cvar_Get("sv_threads", "1", CVAR_LATCH | CVAR_ARCHIVE, "Run the server threaded");
	sv_public = Cvar_Get("sv_public", "1", 0, "Should heartbeats be send to the masterserver");
	sv_reconnect_limit = Cvar_Get("sv_reconnect_limit", "3", CVAR_ARCHIVE, "Minimum seconds between connect messages");

	SV_MapcycleInit();
}
Beispiel #6
0
void GAME_MP_CallbacksInit (const cgame_import_t* import)
{
	cgi = import;
	rcon_client_password = cgi->Cvar_Get("rcon_password", "", 0, "Remote console password");
	rcon_address = cgi->Cvar_Get("rcon_address", "", 0, "Address of the host you would like to control via rcon");
	info_password = cgi->Cvar_Get("password", "", CVAR_USERINFO, nullptr);
	cl_maxsoldiersperteam = cgi->Cvar_Get("sv_maxsoldiersperteam", "4", CVAR_ARCHIVE | CVAR_SERVERINFO, "How many soldiers may one team have");
	cl_maxsoldiersperplayer = cgi->Cvar_Get("sv_maxsoldiersperplayer", DOUBLEQUOTE(MAX_ACTIVETEAM), CVAR_ARCHIVE | CVAR_SERVERINFO, "How many soldiers one player is able to control in a given team");
	cl_roundtimelimit = cgi->Cvar_Get("sv_roundtimelimit", "90", CVAR_ARCHIVE | CVAR_SERVERINFO, "Timelimit in seconds for multiplayer rounds");
	cgi->Cmd_AddCommand("mp_selectteam_init", GAME_MP_SelectTeam_Init_f, "Function that gets all connected players and let you choose a free team");
	cgi->Cmd_AddCommand("mp_init_ui", GAME_MP_InitUI_f, nullptr);
	cgi->Cmd_AddCommand("teamnum_dec", GAME_MP_TeamNum_f, "Decrease the preferred teamnum");
	cgi->Cmd_AddCommand("teamnum_inc", GAME_MP_TeamNum_f, "Increase the preferred teamnum");
	cgi->Cmd_AddCommand("pingservers", GAME_MP_PingServers_f, "Ping all servers in local network to get the serverlist");
	cgi->Cmd_AddCommand("disconnect", GAME_MP_Disconnect_f, "Disconnect from the current server");
	cgi->Cmd_AddCommand("connect", GAME_MP_Connect_f, "Connect to given ip");
	cgi->Cmd_AddParamCompleteFunction("connect", GAME_MP_CompleteNetworkAddress);
	cgi->Cmd_AddCommand("reconnect", GAME_MP_Reconnect_f, "Reconnect to last server");
	cgi->Cmd_AddCommand("rcon", GAME_MP_Rcon_f, "Execute a rcon command - see rcon_password");
	cgi->Cmd_AddCommand("cl_startgame", GAME_MP_StartGame_f, "Forces a gamestart if you are the admin");
	cgi->Cmd_AddParamCompleteFunction("rcon", GAME_MP_CompleteNetworkAddress);

	cl_maxsoldiersperteam->modified = false;
	cl_maxsoldiersperplayer->modified = false;
}
Beispiel #7
0
	static void SetUpTestCase() {
		TEST_Init();
		/* we need the teamdefs for spawning ai actors */
		Com_ParseScripts(true);
		Cvar_Set("sv_threads", "0");
		sv_maxclients = Cvar_Get("sv_maxclients", "1", CVAR_SERVERINFO, "Max. connected clients for test");
		port = Cvar_Get("port", DOUBLEQUOTE(PORT_SERVER), CVAR_NOSET);
		masterserver_url = Cvar_Get("masterserver_url", MASTER_SERVER, CVAR_ARCHIVE, "URL of UFO:AI masterserver");

		sv_genericPool = Mem_CreatePool("server-gametest");
		com_networkPool = Mem_CreatePool("server-gametest-network");
		r_state.active_texunit = &r_state.texunits[0];
	}
Beispiel #8
0
/**
 * @brief Adds a new entry into string with given value.
 * @note Removed any old version of the key
 * @param[in,out] s The target info string
 * @param[in] size The size of @c s
 * @param[in] key The key to set
 * @param[in] value The value to set for the given key
 * @sa Info_RemoveKey
 * @sa Info_SetValueForKeyAsInteger
 */
void Info_SetValueForKey (char* s, const size_t size, const char* key, const char* value)
{
	char newi[MAX_INFO_STRING];

	if (strstr(key, "\\") || strstr(value, "\\")) {
		Com_Printf("Can't use keys or values with a \\\n");
		return;
	}

	if (strstr(key, ";")) {
		Com_Printf("Can't use keys or values with a semicolon\n");
		return;
	}

	if (strstr(key, "\"") || strstr(value, "\"")) {
		Com_Printf("Can't use keys or values with a \"\n");
		return;
	}

	if (strlen(key) > MAX_INFO_KEY - 1) {
		Com_Printf("Keys must be < " DOUBLEQUOTE(MAX_INFO_KEY) " characters.\n");
		return;
	}

	if (strlen(key) > MAX_INFO_VALUE - 1) {
		Com_Printf("Values must be < " DOUBLEQUOTE(MAX_INFO_VALUE) " characters.\n");
		return;
	}

	Info_RemoveKey(s, key);
	if (Q_strnull(value))
		return;

	Com_sprintf(newi, sizeof(newi), "\\%s\\%s%s", key, value, s);
	Q_strncpyz(s, newi, size);
}
Beispiel #9
0
/**
 * @brief The first function called when entering the multiplayer menu, then CL_Frame takes over
 * @sa CL_ParseServerInfoMessage
 * @note Use a parameter for pingservers to update the current serverlist
 */
void CL_PingServers_f (void)
{
	selectedServer = NULL;

	/* refresh the list */
	if (cgi->Cmd_Argc() == 2) {
		int i;
		/* reset current list */
		serverText[0] = 0;
		serversAlreadyQueried = false;
		for (i = 0; i < serverListLength; i++) {
			cgi->Free(serverList[i].node);
			cgi->Free(serverList[i].service);
		}
		serverListPos = 0;
		serverListLength = 0;
		OBJZERO(serverList);
	} else {
		cgi->UI_RegisterText(TEXT_LIST, serverText);
		return;
	}

	if (!netDatagramSocket)
		netDatagramSocket = cgi->NET_DatagramSocketNew(NULL, DOUBLEQUOTE(PORT_CLIENT), &CL_ServerListDiscoveryCallback);

	/* broadcast search for all the servers int the local network */
	if (netDatagramSocket) {
		const char buf[] = "discover";
		cgi->NET_DatagramBroadcast(netDatagramSocket, buf, sizeof(buf), PORT_SERVER);
	}
	cgi->UI_RegisterText(TEXT_LIST, serverText);

	/* don't query the masterservers with every call */
	if (serversAlreadyQueried) {
		if (lastServerQuery + SERVERQUERYTIMEOUT > cgi->CL_Milliseconds())
			return;
	} else
		serversAlreadyQueried = true;

	lastServerQuery = cgi->CL_Milliseconds();

	/* query master server? */
	if (cgi->Cmd_Argc() == 2 && !Q_streq(cgi->Cmd_Argv(1), "local")) {
		cgi->Com_DPrintf(DEBUG_CLIENT, "Query masterserver\n");
		cgi->CL_QueryMasterServer("query", CL_QueryMasterServerThread);
	}
}
Beispiel #10
0
void GAME_MP_CallbacksInit (const cgame_import_t* import)
{
	cgi = import;
	rcon_client_password = cgi->Cvar_Get("rcon_password", "", 0, "Remote console password");
	rcon_address = cgi->Cvar_Get("rcon_address", "", 0, "Address of the host you would like to control via rcon");
	info_password = cgi->Cvar_Get("password", "", CVAR_USERINFO, nullptr);
	cl_maxsoldiersperteam = cgi->Cvar_Get("sv_maxsoldiersperteam", "4", CVAR_ARCHIVE | CVAR_SERVERINFO, "How many soldiers may one team have");
	cl_maxsoldiersperplayer = cgi->Cvar_Get("sv_maxsoldiersperplayer", DOUBLEQUOTE(MAX_ACTIVETEAM), CVAR_ARCHIVE | CVAR_SERVERINFO, "How many soldiers one player is able to control in a given team");
	cl_roundtimelimit = cgi->Cvar_Get("sv_roundtimelimit", "90", CVAR_ARCHIVE | CVAR_SERVERINFO, "Timelimit in seconds for multiplayer rounds");

	cgi->Cmd_TableAddList(mpCallbacks);
	cgi->Cmd_AddParamCompleteFunction("connect", GAME_MP_CompleteNetworkAddress);
	cgi->Cmd_AddParamCompleteFunction("rcon", GAME_MP_CompleteNetworkAddress);

	cl_maxsoldiersperteam->modified = false;
	cl_maxsoldiersperplayer->modified = false;
}
Beispiel #11
0
/**
 * @brief Responds with short info for broadcast scans
 * @note The second parameter should be the current protocol version number.
 * @note Only a short server description - the user can determine whether he is
 * interested in a full status
 * @sa CL_ParseStatusMessage
 * @sa CL_ProcessPingReply
 */
static void SVC_Info (struct net_stream* s)
{
    if (SVC_RateLimitAddress(*s)) {
        Com_DPrintf(DEBUG_SERVER, "SVC_Info: rate limit from %s exceeded, dropping request\n", NET_StreamToString(s));
        return;
    }

    /* Allow getinfo to be DoSed relatively easily, but prevent excess outbound bandwidth usage when being flooded inbound */
    if (SVC_RateLimit(&outboundLeakyBucket)) {
        Com_DPrintf(DEBUG_SERVER, "SVC_Info: rate limit exceeded, dropping request\n");
        return;
    }

    if (sv_maxclients->integer == 1) {
        Com_DPrintf(DEBUG_SERVER, "Ignore info string in singleplayer mode\n");
        return;	/* ignore in single player */
    }

    const int version = atoi(Cmd_Argv(1));
    if (version != PROTOCOL_VERSION) {
        char string[MAX_VAR];
        Com_sprintf(string, sizeof(string), "%s: wrong version (client: %i, host: %i)\n", sv_hostname->string, version, PROTOCOL_VERSION);
        NET_OOB_Printf(s, SV_CMD_PRINT "\n%s", string);
        return;
    }

    int count = 0;

    client_t* cl = nullptr;
    while ((cl = SV_GetNextClient(cl)) != nullptr)
        if (cl->state >= cs_spawning)
            count++;

    char infostring[MAX_INFO_STRING];
    infostring[0] = '\0';
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_protocol", DOUBLEQUOTE(PROTOCOL_VERSION));
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_hostname", sv_hostname->string);
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_dedicated", sv_dedicated->string);
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_gametype", sv_gametype->string);
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_mapname", sv->name);
    Info_SetValueForKeyAsInteger(infostring, sizeof(infostring), "clients", count);
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_maxclients", sv_maxclients->string);
    Info_SetValueForKey(infostring, sizeof(infostring), "sv_version", UFO_VERSION);
    NET_OOB_Printf(s, SV_CMD_INFO "\n%s", infostring);
}
static void CL_Connect_f (void)
{
	char server[MAX_VAR];
	char serverport[16];

	if (!selectedServer && cgi->Cmd_Argc() != 2 && cgi->Cmd_Argc() != 3) {
		cgi->Com_Printf("Usage: %s <server> [<port>]\n", cgi->Cmd_Argv(0));
		return;
	}

	if (cgi->Cmd_Argc() == 2) {
		Q_strncpyz(server, cgi->Cmd_Argv(1), sizeof(server));
		Q_strncpyz(serverport, DOUBLEQUOTE(PORT_SERVER), sizeof(serverport));
	} else if (cgi->Cmd_Argc() == 3) {
		Q_strncpyz(server, cgi->Cmd_Argv(1), sizeof(server));
		Q_strncpyz(serverport, cgi->Cmd_Argv(2), sizeof(serverport));
	} else {
		assert(selectedServer);
		Q_strncpyz(server, selectedServer->node, sizeof(server));
		Q_strncpyz(serverport, selectedServer->service, sizeof(serverport));
	}

	if (cgi->GAME_IsTeamEmpty() && !cgi->GAME_LoadDefaultTeam(qtrue)) {
		cgi->UI_Popup(_("Error"), "%s", _("Assemble a team first"));
		return;
	}

	if (cgi->Cvar_GetInteger("mn_server_need_password")) {
		cgi->UI_PushWindow("serverpassword", NULL, NULL);
		return;
	}

	/* if running a local server, kill it and reissue */
	cgi->SV_Shutdown("Server quit.", qfalse);
	cgi->CL_Disconnect();

	cgi->GAME_SetServerInfo(server, serverport);

	cgi->CL_SetClientState(ca_connecting);

	cgi->UI_InitStack(NULL, "multiplayerInGame", qfalse, qfalse);
}
Beispiel #13
0
/**
 * @brief Responds with short info for broadcast scans
 * @note The second parameter should be the current protocol version number.
 * @note Only a short server description - the user can determine whether he is
 * interested in a full status
 * @sa CL_ParseStatusMessage
 * @sa CL_ProcessPingReply
 */
static void SVC_Info (struct net_stream *s)
{
	int version;

	if (sv_maxclients->integer == 1) {
		Com_DPrintf(DEBUG_SERVER, "Ignore info string in singleplayer mode\n");
		return;	/* ignore in single player */
	}

	version = atoi(Cmd_Argv(1));

	if (version != PROTOCOL_VERSION) {
		char string[MAX_VAR];
		Com_sprintf(string, sizeof(string), "%s: wrong version (client: %i, host: %i)\n", sv_hostname->string, version, PROTOCOL_VERSION);
		NET_OOB_Printf(s, "print\n%s", string);
	} else {
		client_t *cl;
		char infostring[MAX_INFO_STRING];
		int count = 0;

		cl = NULL;
		while ((cl = SV_GetNextClient(cl)) != NULL)
			if (cl->state >= cs_spawning)
				count++;

		infostring[0] = '\0';

		Info_SetValueForKey(infostring, sizeof(infostring), "sv_protocol", DOUBLEQUOTE(PROTOCOL_VERSION));
		Info_SetValueForKey(infostring, sizeof(infostring), "sv_hostname", sv_hostname->string);
		Info_SetValueForKey(infostring, sizeof(infostring), "sv_dedicated", sv_dedicated->string);
		Info_SetValueForKey(infostring, sizeof(infostring), "sv_gametype", sv_gametype->string);
		Info_SetValueForKey(infostring, sizeof(infostring), "sv_mapname", sv->name);
		Info_SetValueForKeyAsInteger(infostring, sizeof(infostring), "clients", count);
		Info_SetValueForKey(infostring, sizeof(infostring), "sv_maxclients", sv_maxclients->string);
		Info_SetValueForKey(infostring, sizeof(infostring), "sv_version", UFO_VERSION);
		NET_OOB_Printf(s, "info\n%s", infostring);
	}
}
/**
 * Send the rest of the command line over as
 * an unconnected command.
 */
static void CL_Rcon_f (void)
{
	char message[MAX_STRING_CHARS];

	if (cgi->Cmd_Argc() < 2) {
		cgi->Com_Printf("Usage: %s <command>\n", cgi->Cmd_Argv(0));
		return;
	}

	if (!rcon_client_password->string) {
		cgi->Com_Printf("You must set 'rcon_password' before issuing an rcon command.\n");
		return;
	}

	Com_sprintf(message, sizeof(message), "rcon %s %s",
		rcon_client_password->string, cgi->Cmd_Args());

	if (cgi->CL_GetClientState() >= ca_connected) {
		cgi->NET_OOB_Printf2("%s", message);
	} else if (rcon_address->string) {
		const char *port;
		struct net_stream *s;

		if (strstr(rcon_address->string, ":"))
			port = strstr(rcon_address->string, ":") + 1;
		else
			port = DOUBLEQUOTE(PORT_SERVER);

		s = cgi->NET_Connect(rcon_address->string, port, NULL);
		if (s) {
			cgi->NET_OOB_Printf(s, "%s", message);
			cgi->NET_StreamSetCallback(s, &CL_RconCallback);
		}
	} else {
		cgi->Com_Printf("You are not connected to any server\n");
	}
}
Beispiel #15
0
bool Irc_Proto_Connect(const char *host, unsigned short port) {
	const bool status = Irc_Net_Connect(host, port, &irc_sock);
	if (!status) {
		if (!irc_messageBucketSize) {
			irc_messageBucketSize = IRC_IMPORT.Cvar_Get("irc_messageBucketSize", DOUBLEQUOTE(IRC_DEFAULT_MESSAGE_BUCKET_SIZE), CVAR_ARCHIVE);
			irc_messageBucketBurst = IRC_IMPORT.Cvar_Get("irc_messageBucketBurst", DOUBLEQUOTE(IRC_DEFAULT_MESSAGE_BUCKET_BURST), CVAR_ARCHIVE);
			irc_messageBucketRate = IRC_IMPORT.Cvar_Get("irc_messageBucketRate", DOUBLEQUOTE(IRC_DEFAULT_MESSAGE_BUCKET_RATE), CVAR_ARCHIVE);
			irc_characterBucketSize = IRC_IMPORT.Cvar_Get("irc_characterBucketSize", DOUBLEQUOTE(IRC_DEFAULT_CHARACTER_BUCKET_SIZE), CVAR_ARCHIVE);
			irc_characterBucketBurst = IRC_IMPORT.Cvar_Get("irc_characterBucketBurst", DOUBLEQUOTE(IRC_DEFAULT_CHARACTER_BUCKET_BURST), CVAR_ARCHIVE);
			irc_characterBucketRate = IRC_IMPORT.Cvar_Get("irc_characterBucketRate", DOUBLEQUOTE(IRC_DEFAULT_CHARACTER_BUCKET_RATE), CVAR_ARCHIVE);
		}
		irc_bucket.first_msg = NULL;
		irc_bucket.message_size = 0;
		irc_bucket.character_size = 0;
		irc_bucket.last_refill = IRC_IMPORT.Sys_Microseconds();
		irc_bucket.message_token = Cvar_GetFloatValue(irc_messageBucketBurst);
		irc_bucket.character_token = Cvar_GetFloatValue(irc_characterBucketBurst);
	}
	return status;
}
Beispiel #16
0
void GameTest::testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
{
	if (verbose) {
		std::cout << "[          ] adding test parameter: gamemode multiplayer" << std::endl;
		Com_Printf("CountSpawnpoints - adding test parameter: gamemode multiplayer\n");
	}

	if (LIST_IsEmpty(md->gameTypes)) {
		ADD_FAILURE() << "Error: Multiplayer enabled, but no gametypes defined in mapdef " << md->id;
		Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n");
		return;
	}

	if (md->teams < 1) {
		ADD_FAILURE() << "Error: Multiplayer enabled, but number of teams is " << md->teams;
		Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but number of teams is %i.\n", md->teams);
		return;
	}

	/* Set initial values. */
	/* Load map in multiplayer mode. */
	Cvar_Set("sv_maxclients", DOUBLEQUOTE(MAX_CLIENTS));
	/* It seems, because of reaction-fire limitations we cannot spawn more than 128 actors total. */
	Cvar_Set("sv_maxsoldiersperteam", "12");
	Cvar_Set("ai_multiplayeraliens", "64");
	Cvar_Set("ai_numcivilians", "16");

	Com_Printf("CountSpawnpoints - loading map: mode multiplayer mapdef %s map %s assembly %s dropship %s ufo %s\n", md->id, md->mapTheme, asmName, aircraft, ufo);
	long time = Sys_Milliseconds();

	try {
		SV_Map(true, md->mapTheme, asmName, true);
	} catch (comDrop_t&) {
		ADD_FAILURE() << "Error: Failed to load assembly " << asmName << " from mapdef " << md->id << ", map "
			<< md->mapTheme << " aircraft: " << aircraft << ", ufo: " << ufo << " => multiplayer mode.";
			Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n");
		Com_Printf("CountSpawnpoints - error: Failed to load map.\n");
		SV_ShutdownGameProgs();
		return;
	}

	time = Sys_Milliseconds() - time;
	Com_Printf("CountSpawnpoints - result: %li ms\n", time);
	SV_ShutdownGameProgs();
	mapCount++;

	/* Print report to log. */
	Com_Printf("CountSpawnpoints - map: mode multiplayer\n");
	Com_Printf("CountSpawnpoints - map: mapdef %s\n", md->id);
	Com_Printf("CountSpawnpoints - map: map %s\n", md->mapTheme);
	Com_Printf("CountSpawnpoints - map: assembly %s\n", asmName);
	Com_Printf("CountSpawnpoints - map: aircraft %s \n", aircraft);
	Com_Printf("CountSpawnpoints - map: ufo %s\n", ufo);

	/* Check if one of the gametypes available in the mapdef defines a coop mode,
	   in which case we will need aliens on the map. */
	int coop = 0;
	/* The number of alien spawnpoints required on the map. In PvP gamemodes this is zero,
	   while in coop games we check for the number given as 'maxaliens' in the mapdef. */
	int minAliens = 0;
	/* The number of player spawnpoints required for each team is determined
	   by the value of sv_maxsoldiersperteam given in the gametype def. */
	int minMP = 0;

	/* Count spawnpoints for TEAM_CIVILIAN. */
	const int spawnCivs = static_cast<int>(level.num_spawnpoints[TEAM_CIVILIAN]);
	Com_Printf("CountSpawnpoints - count spawnpoints: civilian %i\n", spawnCivs);

	/* Find the highest numbers for alien and player spawnpoints needed in the map. */
	LIST_Foreach(md->gameTypes, const char, gameType) {
		for (int i = 0; i < csi.numGTs; i++) {
			const gametype_t* gt = &csi.gts[i];
			if (!Q_streq(gt->id, gameType))
				continue;
			const cvarlist_t* list = gt->cvars;
			for (int j = 0; j < gt->num_cvars; j++, list++) {
				if (Q_streq(list->name, "ai_multiplayeraliens")) {
					coop = std::max(coop, atoi(list->value));
				} else if (Q_streq(list->name, "sv_maxsoldiersperteam")) {
					minMP = std::max(minMP, atoi(list->value));
				}
			}
		}
	}

	/* If the mapdef does not define a coop mode, we do not need aliens. */
	if (coop)
		minAliens = std::min(md->maxAliens, testCountSpawnpointsGetNumteamValueForUFO(ufo));

	const int startTeam = TEAM_CIVILIAN + 1;
	/* For every single mp team defined in the mapdef - check if there are enough spawnpoints available. */
	for (int currTeamNum = startTeam; currTeamNum < startTeam + md->teams; ++currTeamNum) {
		if (currTeamNum > TEAM_MAX_HUMAN) {
			ADD_FAILURE() << "Error: Mapdef " << md->id << " has too many teams set.";
			Com_Printf("CountSpawnpoints - error: Too many teams set.\n");
			break;
		}
		const int spawnTeam = static_cast<int>(level.num_spawnpoints[currTeamNum]);
		/* Make gtest report back in case there are not enough spawnpoints available for the team. */
		EXPECT_GE(spawnTeam, minMP) << "Error: Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme
			<< "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode: Only " << spawnTeam
			<< " spawnpoints for team " << currTeamNum << " but " << minMP << " expected.";
		/* Log the result. */
		Com_Printf("CountSpawnpoints - count spawnpoints: player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam);
		if (spawnTeam < minMP)
			Com_Printf("CountSpawnpoints - error: missing spawnpoints - player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam);

	}
	if (minAliens) {
		const int spawnAliens = static_cast<int>(level.num_spawnpoints[TEAM_ALIEN]);
		/* Make gtest report back in case there are not enough alien spawnpoints available. */
		EXPECT_GE(spawnAliens, minAliens) << "Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme
			<< "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode defines at least one coop game mode,"
			<< " but does not have enough alien spawn positions for that. We expect at least " << minAliens
			<< " spawn positions for aliens, the map provides " << spawnAliens << ".";
		/* Log the result. */
		Com_Printf("CountSpawnpoints - count spawnpoints: alien needs/found %i/%i\n", minAliens, spawnAliens);
		if (spawnAliens < minAliens)
			Com_Printf("CountSpawnpoints - error: missing spawnpoints - alien needs/found %i/%i\n", minAliens, spawnAliens);
	}

	SV_ShutdownGameProgs();
}
Beispiel #17
0
/**
 * @brief Init function
 * @sa Com_ParseScripts
 * @sa Qcommon_Shutdown
 * @sa Sys_Init
 * @sa CL_Init
 */
void Qcommon_Init (int argc, char** argv)
{
	logfile_active = nullptr;
	developer = nullptr;

	Sys_InitSignals();

	/* random seed */
	Com_SetRandomSeed(time(nullptr));

	com_aliasSysPool = Mem_CreatePool("Common: Alias system for commands and enums");
	com_cmdSysPool = Mem_CreatePool("Common: Command system");
	com_cmodelSysPool = Mem_CreatePool("Common: Collision model");
	com_cvarSysPool = Mem_CreatePool("Common: Cvar system");
	com_fileSysPool = Mem_CreatePool("Common: File system");
	com_genericPool = Mem_CreatePool("Generic");
	com_networkPool = Mem_CreatePool("Network");

	try {
		OBJZERO(csi);

		/* prepare enough of the subsystems to handle
		 * cvar and command buffer management */
		Com_InitArgv(argc, argv);

		Swap_Init();
		Cbuf_Init();

		Cmd_Init();
		Cvar_Init();

		uploadcrashdump = Cvar_Get("uploadcrashdump", "1", 0, "upload crashdumps to the developers");

		Key_Init();

		/* we need to add the early commands twice, because
		 * a basedir needs to be set before executing
		 * config files, but we want other parms to override
		 * the settings of the config files */
		Cbuf_AddEarlyCommands(false);
		Cbuf_Execute();

		FS_InitFilesystem(true);

		Cbuf_AddText("exec default.cfg\n");
#ifdef DEDICATED_ONLY
		Cbuf_AddText("exec dedconfig.cfg\n");
#else
		Cbuf_AddText("exec config.cfg\n");
#endif

		Cbuf_AddEarlyCommands(true);
		Cbuf_Execute();

		Com_SetRenderModified(false);
		Com_SetUserinfoModified(false);

		/* init commands and vars */
		Cmd_AddCommand("saveconfig", Com_WriteConfig_f, "Write the configuration to file");
		Cmd_AddCommand("gametypelist", Com_GameTypeList_f, "List all available multiplayer game types");
#ifdef DEBUG
		Cmd_AddCommand("debug_help", Com_DebugHelp_f, "Show some debugging help");
		Cmd_AddCommand("debug_error", Com_DebugError_f, "Just throw a fatal error to test error shutdown procedures");
#endif
		Cmd_AddCommand("setdeveloper", Com_DeveloperSet_f, "Set the developer cvar to only get the debug output you want");

		developer = Cvar_Get("developer", "0", 0, "Activate developer output to logfile and gameconsole");
#ifdef DEBUG
		logfile_active = Cvar_Get("logfile", "2", 0, "0 = deactivate logfile, 1 = write normal logfile, 2 = flush on every new line, 3 = always append to existing file");
#else
		logfile_active = Cvar_Get("logfile", "1", 0, "0 = deactivate logfile, 1 = write normal logfile, 2 = flush on every new line, 3 = always append to existing file");
#endif
		sv_gametype = Cvar_Get("sv_gametype", "fight1on1", CVAR_ARCHIVE | CVAR_SERVERINFO, "Sets the multiplayer gametype - see gametypelist command for a list of all gametypes");
		http_proxy = Cvar_Get("http_proxy", "", CVAR_ARCHIVE, "Use this proxy for http transfers");
		http_timeout = Cvar_Get("http_timeout", "3", CVAR_ARCHIVE, "Http connection and read timeout");
		port = Cvar_Get("port", DOUBLEQUOTE(PORT_SERVER), CVAR_NOSET);
		masterserver_url = Cvar_Get("masterserver_url", MASTER_SERVER, CVAR_ARCHIVE, "URL of UFO:AI masterserver");
#ifdef DEDICATED_ONLY
		sv_dedicated = Cvar_Get("sv_dedicated", "1", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
		/* don't allow to override this from commandline of config */
		Cvar_ForceSet("sv_dedicated", "1");
#else
		sv_dedicated = Cvar_Get("sv_dedicated", "0", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");

		/* set this to false for client - otherwise Qcommon_Frame would set the initial values to multiplayer */
		sv_gametype->modified = false;

		s_language = Cvar_Get("s_language", "", CVAR_ARCHIVE, "Game language - full language string e.g. en_EN.UTF-8");
		s_language->modified = false;
		cl_maxfps = Cvar_Get("cl_maxfps", "50", CVAR_ARCHIVE);
		Cvar_SetCheckFunction("cl_maxfps", Com_CvarCheckMaxFPS);
#endif

		// 5 is an i7 with a medium gfx-card
		// 3 dual core with 2 GB
		// 2 EeePc with 1 GB
		// 1 smartphone
		const char* hwclassVal = "5";
#ifdef __ANDROID__
		/** get the hardware class of the machine we are running on. */
		hwclassVal = "1";
#endif
		hwclass = Cvar_Get("hwclass", hwclassVal, 0, "Defines the hardware class of this machine. 1 is the lowest, 5 is the highest.");

		const char* s = va("UFO: Alien Invasion %s %s %s %s", UFO_VERSION, CPUSTRING, __DATE__, BUILDSTRING);
		Cvar_Get("version", s, CVAR_NOSET, "Full version string");
		Cvar_Get("ver", UFO_VERSION, CVAR_SERVERINFO | CVAR_NOSET, "Version number");

		if (sv_dedicated->integer)
			Cmd_AddCommand("quit", Com_Quit, "Quits the game");

		Mem_Init();
		Sys_Init();

		NET_Init();

#ifndef NO_HTTP
		curl_global_init(CURL_GLOBAL_NOTHING);
		Com_Printf("%s initialized.\n", curl_version());
#endif

		SV_Init();

		/* e.g. init the client hunk that is used in script parsing */
		CL_Init();

		Com_ParseScripts(sv_dedicated->integer);
#ifndef DEDICATED_ONLY
		Cbuf_AddText("exec keys.cfg\n");
#endif

		if (!sv_dedicated->integer)
			Cbuf_AddText("init\n");
		else
			Cbuf_AddText("dedicated_start\n");
		Cbuf_Execute();

		FS_ExecAutoexec();

		/* add + commands from command line
		 * if the user didn't give any commands, run default action */
		if (Cbuf_AddLateCommands()) {
			/* the user asked for something explicit
			 * so drop the loading plaque */
			SCR_EndLoadingPlaque();
		}

		const cvar_t* com_pipefile = Cvar_Get("com_pipefile", "", CVAR_ARCHIVE, "Filename of the pipe that is used to send commands to the game");
		if (com_pipefile->string[0] != '\0') {
			FS_CreateOpenPipeFile(com_pipefile->string, &pipefile);
		}

		CL_InitAfter();

		/* Check memory integrity */
		Mem_CheckGlobalIntegrity();

#ifndef DEDICATED_ONLY
		if (!sv_dedicated->integer) {
			Schedule_Timer(cl_maxfps, &CL_Frame, nullptr, nullptr);
			Schedule_Timer(Cvar_Get("cl_slowfreq", "10", 0, nullptr), &CL_SlowFrame, nullptr, nullptr);

			/* now hide the console */
			Sys_ShowConsole(false);
		}
#endif

		Schedule_Timer(Cvar_Get("sv_freq", "10", CVAR_NOSET, nullptr), &SV_Frame, nullptr, nullptr);

		/** @todo This line wants to be removed */
		Schedule_Timer(Cvar_Get("cbuf_freq", "10", 0, nullptr), &Cbuf_Execute_timer, nullptr, nullptr);

		Com_Printf("====== UFO Initialized ======\n");
		Com_Printf("=============================\n");
	} catch (comDrop_t const&) {
		Sys_Error("Error during initialization");
	}
}
Beispiel #18
0
/**
 * @brief This will be called when the game library is first loaded
 * @note only happens when a new game/map is started
 */
static void G_Init (void)
{
	gi.DPrintf("==== InitGame ====\n");

	/* noset vars */
	sv_dedicated = gi.Cvar_Get("sv_dedicated", "0", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");

	/* latched vars */
	sv_cheats = gi.Cvar_Get("sv_cheats", "0", CVAR_SERVERINFO | CVAR_LATCH, "Activate cheats");
	gi.Cvar_Get("gamename", GAMEVERSION, CVAR_SERVERINFO | CVAR_LATCH, nullptr);
	gi.Cvar_Get("gamedate", __DATE__, CVAR_SERVERINFO | CVAR_LATCH, nullptr);
	developer = gi.Cvar_Get("developer", "0", 0, "Print out a lot of developer debug messages - useful to track down bugs");
	logstats = gi.Cvar_Get("logstats", "1", CVAR_ARCHIVE, "Server logfile output for kills");

	/* max. players per team (original quake) */
	sv_maxplayersperteam = gi.Cvar_Get("sv_maxplayersperteam", "8", CVAR_SERVERINFO | CVAR_LATCH, "How many players (humans) may a team have");
	/* max. soldiers per team */
	sv_maxsoldiersperteam = gi.Cvar_Get("sv_maxsoldiersperteam", "4", CVAR_ARCHIVE | CVAR_SERVERINFO, "How many soldiers may one team have");
	/* max soldiers per player */
	sv_maxsoldiersperplayer = gi.Cvar_Get("sv_maxsoldiersperplayer", DOUBLEQUOTE(MAX_ACTIVETEAM), CVAR_ARCHIVE | CVAR_SERVERINFO, "How many soldiers one player is able to control in a given team");
	/* enable moralestates in multiplayer */
	sv_enablemorale = gi.Cvar_Get("sv_enablemorale", "1", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_LATCH, "Enable morale behaviour for actors");
	sv_roundtimelimit = gi.Cvar_Get("sv_roundtimelimit", "90", CVAR_ARCHIVE | CVAR_SERVERINFO, "Timelimit in seconds for multiplayer rounds");
	sv_roundtimelimit->modified = false;
	sv_maxentities = gi.Cvar_Get("sv_maxentities", "1024", CVAR_LATCH, nullptr);

	sv_maxteams = gi.Cvar_Get("sv_maxteams", "2", CVAR_SERVERINFO, "How many teams for current running map");
	sv_maxteams->modified = false;

	/* change anytime vars */
	password = gi.Cvar_Get("password", "", CVAR_USERINFO, nullptr);
	sv_needpass = gi.Cvar_Get("sv_needpass", "0", CVAR_SERVERINFO, nullptr);
	sv_filterban = gi.Cvar_Get("sv_filterban", "1", 0, nullptr);
	sv_ai = gi.Cvar_Get("sv_ai", "1", 0, "Activate or deativate the ai");
	sv_teamplay = gi.Cvar_Get("sv_teamplay", "0", CVAR_ARCHIVE | CVAR_LATCH | CVAR_SERVERINFO, "Is teamplay activated? see sv_maxclients, sv_maxplayersperteam, sv_maxsoldiersperteam and sv_maxsoldiersperplayer");
	/* how many connected clients */
	sv_maxclients = gi.Cvar_Get("sv_maxclients", "1", CVAR_SERVERINFO, "If sv_maxclients is 1 we are in singleplayer - otherwise we are mutliplayer mode (see sv_teamplay)");
	sv_shot_origin = gi.Cvar_Get("sv_shot_origin", "8", 0, "Assumed distance of muzzle from model");
	sv_send_edicts = gi.Cvar_Get("sv_send_edicts", "0", CVAR_ARCHIVE | CVAR_CHEAT, "Send server side edicts for client display like triggers");
	sv_hurtaliens = gi.Cvar_Get("sv_hurtaliens", "0", CVAR_SERVERINFO, "Spawn hurt aliens");

	ai_alienteam = gi.Cvar_Get("ai_alienteam", "ortnok", 0, "Alien team");
	ai_civilianteam = gi.Cvar_Get("ai_civilianteam", "europe", 0, "Civilian team");
	/* this cvar is set in singleplayer via campaign definition */
	ai_equipment = gi.Cvar_Get("ai_equipment", "multiplayer_alien", 0, "Initial equipment definition for aliens");
	/* aliens in singleplayer (can differ each mission) */
	ai_singleplayeraliens = gi.Cvar_Get("ai_singleplayeraliens", "30", 0, "How many aliens in this battle (singleplayer)");
	/* civilians for singleplayer */
	ai_numcivilians = gi.Cvar_Get("ai_numcivilians", "10", 0, "How many civilians in this battle");
	/* aliens in multiplayer */
	ai_multiplayeraliens = gi.Cvar_Get("ai_multiplayeraliens", "8", CVAR_ARCHIVE, "How many (ai controlled) actors in this battle (multiplayer)");

	mob_death = gi.Cvar_Get("mob_death", "10", CVAR_LATCH|CVAR_NOSET, nullptr);
	mob_wound = gi.Cvar_Get("mob_wound", "0.1", CVAR_LATCH|CVAR_NOSET, nullptr);
	mob_shoot = gi.Cvar_Get("mob_shoot", "0.1", CVAR_LATCH|CVAR_NOSET, nullptr);
	mof_watching = gi.Cvar_Get("mof_watching", "1.7", CVAR_LATCH|CVAR_NOSET, nullptr);
	mof_teamkill = gi.Cvar_Get("mof_teamkill", "2.0", CVAR_LATCH|CVAR_NOSET, nullptr);
	mof_civilian = gi.Cvar_Get("mof_civilian", "0.3", CVAR_LATCH|CVAR_NOSET, nullptr);
	mof_enemy = gi.Cvar_Get("mof_ememy", "0.5", CVAR_LATCH|CVAR_NOSET, nullptr);
	mor_pain = gi.Cvar_Get("mof_pain", "3.6", CVAR_LATCH|CVAR_NOSET, nullptr);
	/* everyone gets this times morale damage */
	mor_default = gi.Cvar_Get("mor_default", "0.3", CVAR_LATCH|CVAR_NOSET, "Everyone gets this times morale damage");
	/* at this distance the following two get halved (exponential scale) */
	mor_distance = gi.Cvar_Get("mor_distance", "120", CVAR_LATCH|CVAR_NOSET, "At this distance the following two get halved (exponential scale)");
	/* at this distance the following two get halved (exponential scale) */
	mor_victim = gi.Cvar_Get("mor_victim", "0.7", CVAR_LATCH|CVAR_NOSET, "At this distance the following two get halved (exponential scale)");
	/* at this distance the following two get halved (exponential scale) */
	mor_attacker = gi.Cvar_Get("mor_attacker", "0.3", CVAR_LATCH|CVAR_NOSET, "At this distance the following two get halved (exponential scale)");
	/* how much the morale depends on the size of the damaged team */
	mon_teamfactor = gi.Cvar_Get("mon_teamfactor", "0.6", CVAR_LATCH|CVAR_NOSET, "How much the morale depends on the size of the damaged team");

	mor_regeneration = gi.Cvar_Get("mor_regeneration", "15", CVAR_LATCH|CVAR_NOSET, nullptr);
	mor_shaken = gi.Cvar_Get("mor_shaken", "50", CVAR_LATCH|CVAR_NOSET, nullptr);
	mor_panic = gi.Cvar_Get("mor_panic", "30", CVAR_LATCH|CVAR_NOSET, nullptr);
	mor_brave = gi.Cvar_Get("mor_brave", "85", CVAR_LATCH|CVAR_NOSET, nullptr);

	m_sanity = gi.Cvar_Get("m_sanity", "1.0", CVAR_LATCH|CVAR_NOSET, nullptr);
	m_rage = gi.Cvar_Get("m_rage", "0.6", CVAR_LATCH|CVAR_NOSET, nullptr);
	m_rage_stop = gi.Cvar_Get("m_rage_stop", "2.0", CVAR_LATCH|CVAR_NOSET, nullptr);
	m_panic_stop = gi.Cvar_Get("m_panic_stop", "1.0", CVAR_LATCH|CVAR_NOSET, nullptr);

	g_endlessaliens = gi.Cvar_Get("g_endlessaliens", "0", CVAR_LATCH|CVAR_SERVERINFO, "Spawn endless aliens");
	g_ailua = gi.Cvar_Get("g_ailua", "0", 0, "Activate or deactivate the LUA AI");
	g_aihumans = gi.Cvar_Get("g_aihumans", "0", CVAR_DEVELOPER, "Activate or deactivate the ai for human actors");
	g_aidebug = gi.Cvar_Get("g_aidebug", "0", CVAR_DEVELOPER|CVAR_CHEAT, "All AI actors are visible");
	g_drawtraces = gi.Cvar_Get("g_drawtraces", "0", CVAR_DEVELOPER, "All traces will be rendered");
	g_nodamage = gi.Cvar_Get("g_nodamage", "0", CVAR_DEVELOPER|CVAR_CHEAT, "No damage in developer mode");
	g_notu = gi.Cvar_Get("g_notu", "0", CVAR_DEVELOPER|CVAR_CHEAT, "No TU costs while performing any action");
	g_actorspeed = gi.Cvar_Get("g_actorspeed", "1.0", CVAR_ARCHIVE|CVAR_SERVERINFO, "Moving speed of the actor");
	g_lastseen = gi.Cvar_Get("g_lastseen", "20", CVAR_ARCHIVE|CVAR_SERVERINFO, "Quit the match if no player was seen in this amount of rounds");
	g_nospawn = gi.Cvar_Get("g_nospawn", "0", CVAR_DEVELOPER|CVAR_CHEAT, "Do not spawn a soldier");

	/* flood control */
	flood_msgs = gi.Cvar_Get("flood_msgs", "4", 0, nullptr);
	flood_persecond = gi.Cvar_Get("flood_persecond", "4", 0, nullptr);
	flood_waitdelay = gi.Cvar_Get("flood_waitdelay", "10", 0, "Delay until someone is unlocked from talking again");

	g_difficulty = gi.Cvar_Get("g_difficulty", "0", CVAR_NOSET, "Singleplayer difficulty level");

	game.sv_maxentities = sv_maxentities->integer;
	game.sv_maxplayersperteam = sv_maxplayersperteam->integer;

	/* initialize the entity storage */
	globals.edicts = G_EdictsConstruct();
	globals.max_edicts = game.sv_maxentities;
	globals.num_edicts = game.sv_maxplayersperteam;

	/* initialize all players for this game */
	/* game.sv_maxplayersperteam for human controlled players
	 * + game.sv_maxplayer for ai */
	game.players = static_cast<player_t*>(G_TagMalloc(game.sv_maxplayersperteam * 2 * sizeof(game.players[0]), TAG_GAME));
	globals.players = game.players;
	globals.maxplayersperteam = game.sv_maxplayersperteam;

	/* init csi and inventory */
	INVSH_InitCSI(gi.csi);
	game.invi.initInventory("game", gi.csi, &inventoryImport);

	if (logstats->integer)
		logstatsfile = gi.Sys_Fopen(va("%s/stats.log", gi.FS_Gamedir()), "a");
	else
		logstatsfile = nullptr;

	AI_Init();
	AIL_Init();
}