Esempio n. 1
0
void WEB_InitStartup (void)
{
	Cmd_AddCommand("web_auth", WEB_Auth_f, "Perform the authentication against the UFOAI server");

	web_username = Cvar_Get("web_username", Sys_GetCurrentUser(), CVAR_ARCHIVE, "The username for the UFOAI server.");
	/* if the password is a non-empty string, this means that username and password
	 * are valid, and the authentication was successful */
	web_password = Cvar_Get("web_password", "", CVAR_ARCHIVE, "The encrypted password for the UFOAI server.");
	web_userid = Cvar_Get("web_userid", "0", 0, "Your userid for the UFOAI server");
	web_authurl = Cvar_Get("web_authurl", WEB_API_SERVER "api/auth.php", CVAR_ARCHIVE,
				"The url to perform the authentication against.");

	WEB_CGameCvars();
	WEB_CGameCommands();

	Com_Printf("\n------- web initialization ---------\n");
	if (Q_strvalid(web_password->string)) {
		Com_Printf("... using username '%s'\n", web_username->string);
		if (!WEB_GetURL(web_authurl->string, WEB_AuthResponse)) {
			Cvar_Set("web_password", "");
		}
		if (Q_strvalid(web_password->string)) {
			Com_Printf("... login successful\n");
		} else {
			Com_Printf("... login failed\n");
		}
	} else {
		Com_Printf("... web access not yet configured\n");
	}
}
Esempio n. 2
0
/**
 * @note Think function
 */
static void LET_Projectile (le_t* le)
{
	if (cl.time >= le->endTime) {
		vec3_t impact;
		VectorCopy(le->origin, impact);
		CL_ParticleFree(le->ptl);
		/* don't run the think function again */
		le->inuse = false;
		if (Q_strvalid(le->ref1)) {
			VectorCopy(le->ptl->s, impact);
			le->ptl = CL_ParticleSpawn(le->ref1, 0, impact, bytedirs[le->angle]);
			VecToAngles(bytedirs[le->state], le->ptl->angles);
		}
		if (Q_strvalid(le->ref2)) {
			S_LoadAndPlaySample(le->ref2, impact, le->fd->impactAttenuation, SND_VOLUME_WEAPONS);
		}
		if (le->ref3) {
			/* Spawn blood particles (if defined) if actor(-body) was hit. Even if actor is dead. */
			/** @todo Special particles for stun attack (mind you that there is
			 * electrical and gas/chemical stunning)? */
			if (le->fd->obj->dmgtype != csi.damStunGas)
				LE_ActorBodyHit(le->ref3, impact, le->angle);
			CL_ActorPlaySound(le->ref3, SND_HURT);
		}
	} else if (CL_OutsideMap(le->ptl->s, UNIT_SIZE * 10)) {
		le->endTime = cl.time;
		CL_ParticleFree(le->ptl);
		/* don't run the think function again */
		le->inuse = false;
	}
}
Esempio n. 3
0
/**
 * @brief Executes console commands after a mission
 *
 * @param[in] mission Pointer to the mission to execute the triggers for
 * @param[in] won Int value that is one when you've won the game, and zero when the game was lost
 * Can execute console commands (triggers) on win and lose
 * This can be used for story dependent missions
 */
void CP_ExecuteMissionTrigger (const mission_t* mission, bool won)
{
	Com_DPrintf(DEBUG_CLIENT, "Execute mission triggers\n");

	if (mission == nullptr)
		return;

	/* we add them only here - and remove them afterwards to prevent cheating */
	CP_CampaignTriggerFunctions(true);

	if (won) {
		if (Q_strvalid(mission->onwin)) {
			Com_DPrintf(DEBUG_CLIENT, "...won - executing '%s'\n", mission->onwin);
			cgi->Cmd_ExecuteString("%s", mission->onwin);
		}
		if (mission->mapDef && Q_strvalid(mission->mapDef->onwin)) {
			Com_DPrintf(DEBUG_CLIENT, "...won - executing '%s'\n", mission->mapDef->onwin);
			cgi->Cmd_ExecuteString("%s", mission->mapDef->onwin);
		}
	} else {
		if (Q_strvalid(mission->onlose)) {
			Com_DPrintf(DEBUG_CLIENT, "...lost - executing '%s'\n", mission->onlose);
			cgi->Cmd_ExecuteString("%s", mission->onlose);
		}
		if (mission->mapDef && Q_strvalid(mission->mapDef->onlose)) {
			Com_DPrintf(DEBUG_CLIENT, "...lost - executing '%s'\n", mission->mapDef->onlose);
			cgi->Cmd_ExecuteString("%s", mission->mapDef->onlose);
		}
	}

	CP_CampaignTriggerFunctions(false);
}
Esempio n. 4
0
CGAME_HARD_LINKED_FUNCTIONS

static void GAME_SK_InitMissionBriefing (const char** title, linkedList_t** victoryConditionsMsgIDs, linkedList_t** missionBriefingMsgIDs)
{
	const mapDef_t* md = cgi->GAME_GetCurrentSelectedMap();
	if (Q_strvalid(md->victoryCondition)) {
		cgi->LIST_AddString(victoryConditionsMsgIDs, md->victoryCondition);
	}
	if (Q_strvalid(md->missionBriefing)) {
		cgi->LIST_AddString(missionBriefingMsgIDs, md->missionBriefing);
	}
	if (Q_strvalid(md->description)) {
		*title = _(md->description);
	}
}
Esempio n. 5
0
/**
 * @brief Triggers a campaign event with a special type
 * @param[in] type the event type
 * @param[in] userdata Any userdata that is passed to the bep checker function
 */
void CP_TriggerEvent (campaignTriggerEventType_t type, const void* userdata)
{
	int i;

	for (i = 0; i < ccs.numCampaignTriggerEvents; i++) {
		campaignTriggerEvent_t *event = &ccs.campaignTriggerEvents[i];
		if (event->type != type || (!event->active && event->reactivate == NULL))
			continue;

		if (event->active) {
			if (BEP_Evaluate(event->require, CP_CheckTriggerEvent, userdata)) {
				if (Q_strvalid(event->command)) {
					CP_CampaignTriggerFunctions(true);
					cgi->Cbuf_AddText(event->command);
					cgi->Cbuf_Execute();
					CP_CampaignTriggerFunctions(false);
				}

				if (event->once) {
					event->active = false;
				}
			}
		} else {
			event->active = BEP_Evaluate(event->reactivate, CP_CheckTriggerEvent, userdata);
		}
	}
}
Esempio n. 6
0
void M_Frame (void)
{
	if (snd_music_play && snd_music_play->modified) {
		music.playing = snd_music_play->integer != 0;
		snd_music_play->modified = false;
	}
	if (!music.playing) {
		if (Mix_PlayingMusic())
			M_Stop();
		return;
	}
	if (snd_music->modified) {
		M_Start(snd_music->string);
		snd_music->modified = false;
	}
	if (snd_music_volume->modified) {
		Mix_VolumeMusic(snd_music_volume->integer);
		snd_music_volume->modified = false;
	}

	if (music.playingStream) {
		M_MusicStreamUpdate();
	} else if (!Mix_PlayingMusic()) {
		M_Stop(); /* free the allocated memory */
		if (Q_strvalid(music.nextTrack)) {
			M_Start(music.nextTrack);
			music.nextTrack[0] = '\0';
		} else {
			if (!M_PlayRandomByCategory(music.category))
				M_Start(music.currentTrack);
		}
	}
}
Esempio n. 7
0
/**
 * @brief Run eventhandler script for a building
 * @param[in] buildingTemplate Building type (template) to run event for
 * @param[in] base The base to run it at
 * @param[in] eventType Type of the event to run
 * @return @c true if an event was fired @c false otherwise (the building may not have one)
 */
bool B_FireEvent (const building_t* buildingTemplate, const base_t* base, buildingEvent_t eventType)
{
	const char* command = nullptr;

	assert(buildingTemplate);
	assert(base);

	switch (eventType) {
		case B_ONCONSTRUCT:
			command = buildingTemplate->onConstruct;
			break;
		case B_ONENABLE:
			command = buildingTemplate->onEnable;
			break;
		case B_ONDISABLE:
			command = buildingTemplate->onDisable;
			break;
		case B_ONDESTROY:
			command = buildingTemplate->onDestroy;
			break;
		default:
			cgi->Com_Error(ERR_DROP, "B_FireEvent: Invalid Event\n");
	}

	if (Q_strvalid(command)) {
		cgi->Cmd_ExecuteString("%s %i %i", command, base->idx, buildingTemplate->buildingType);
		return true;
	}

	return false;
}
 /**
 * @brief Sets the title of the installation to a cvar to prepare the rename menu.
 * @note it also assigns description text
 */
static void INS_SetInstallationTitle (installationType_t type)
{
	const installationTemplate_t* insTemp = INS_GetInstallationTemplateByType(type);
	cgi->Cvar_Set("mn_installation_title", "%s #%i", (insTemp) ? _(insTemp->name) : _("Installation"), ccs.campaignStats.installationsBuilt + 1);
	if (!insTemp || !Q_strvalid(insTemp->description))
		cgi->UI_ResetData(TEXT_BUILDING_INFO);
	else
		cgi->UI_RegisterText(TEXT_BUILDING_INFO, _(insTemp->description));
}
Esempio n. 9
0
/**
 * @brief If password has changed, update sv_needpass cvar as needed
 */
static void CheckNeedPass (void)
{
	if (password->modified) {
		password->modified = false;

		const int need = Q_strvalid(password->string) && Q_strcasecmp(password->string, "none") ? 1 : 0;
		gi.Cvar_Set("sv_needpass", "%i", need);
	}
}
Esempio n. 10
0
static inline void CLMN_AddBindings (keyBindSpace_t scope, char** bindings, int offset = 0)
{
	for (int i = K_FIRST_KEY; i < K_LAST_KEY; i++) {
		if (Q_strnull(bindings[i]))
			continue;
		const char* binding = Cmd_GetCommandDesc(bindings[i]);
		if (Q_strvalid(binding))
			binding = _(binding);
		UI_ExecuteConfunc("keybinding_add %i %i \"%s\" \"%s\"", i + offset, scope, Key_KeynumToString(i), binding);
	}
}
Esempio n. 11
0
/**
 * @brief Checks whether the given input string is allowed to be used as a user-given name string
 * for aircraft, soldiers, bases and so on
 * @param[in] input The input string to check
 * @return @c true if the string is valid and can be used as a name, @c false otherwise
 */
bool Com_IsValidName (const char* input)
{
	/* empty strings are not allowed */
	if (!Q_strvalid(input))
		return false;
	/* names with only _ are not allowed - they would get translated with as empty msgid for gettext */
	if (Q_streq(input, "_"))
		return false;
	/* there may be no quotes in the names - as they are given very often as parameter in the scripts */
	if (strchr(input, '"') != nullptr)
		return false;
	return true;
}
Esempio n. 12
0
/**
 * @brief Adds UI Keybindings to the list for the Keylist UI
 * @param[in,out] list Linked list of strings to add to
 */
static inline void CLMN_AddUIBindings (linkedList_t **list)
{
	int i;

	for (i = 0; i < UI_GetKeyBindingCount(); i++) {
		const uiKeyBinding_t* binding = UI_GetKeyBindingByIndex(i);

		if (binding == NULL)
			continue;
		if (binding->inherited)
			continue;
		if (!Q_strvalid(binding->description))
			continue;

		LIST_AddString(list, va("%s\t%s", Key_KeynumToString(binding->key), _(binding->description)));
	}
}
Esempio n. 13
0
/**
 * @brief Adds UI Keybindings to the list for the Keylist UI
 */
static inline int CLMN_AddUIBindings (keyBindSpace_t scope)
{
	int cnt = 0;
	const int num = UI_GetKeyBindingCount();
	for (int i = 0; i < num; i++) {
		const uiKeyBinding_t* binding = UI_GetKeyBindingByIndex(i);
		if (binding == nullptr)
			continue;
		if (binding->inherited)
			continue;
		if (!Q_strvalid(binding->description))
			continue;

		UI_ExecuteConfunc("keybinding_add %i %i \"%s\" \"%s\"", cnt++, scope, Key_KeynumToString(binding->key), _(binding->description));
	}
	return cnt;
}
Esempio n. 14
0
/**
 * @brief Fills the options language menu node with the parsed language mappings
 * @sa CL_InitAfter
 * @sa CL_LocaleSet
 */
void CL_LanguageInit (void)
{
	fs_i18ndir = Cvar_Get("fs_i18ndir", "", 0, "System path to language files");

	char systemLanguage[MAX_VAR] = "";
	if (Q_strvalid(s_language->string)) {
		Com_Printf("CL_LanguageInit: language settings are stored in configuration: %s\n", s_language->string);
		Q_strncpyz(systemLanguage, s_language->string, sizeof(systemLanguage));
	} else {
		const char* currentLocale = Sys_GetLocale();
		if (currentLocale) {
			const char* localeID = CL_GetLocaleID(currentLocale);
			if (localeID)
				Q_strncpyz(systemLanguage, localeID, sizeof(systemLanguage));
		}
	}

	Com_DPrintf(DEBUG_CLIENT, "CL_LanguageInit: system language is: '%s'\n", systemLanguage);
}
Esempio n. 15
0
/**
 * @brief Performs a web auth request
 * @param[in] username The (unencoded) username
 * @param[in] password The (ununcoded) password
 * @note the cvars @c web_username and @c web_password are going to become overridden here.
 * If the auth failed, the cvar @c web_password is set to an empty string again.
 * @return @c true if the auth was successful, @c false otherwise.
 */
bool WEB_Auth (const char* username, const char* password)
{
	char digest[41];
	char user[MAX_VAR];
	Q_strncpyz(user, username, sizeof(user));
	Q_strlwr(user);
	char combined[512];
	Com_sprintf(combined, sizeof(combined), "%s%s", user, password);
	Com_SHA1Buffer((const byte*)combined, strlen(combined), digest);
	Cvar_Set("web_username", "%s", username);
	Cvar_Set("web_password", "%s", digest);
	if (!WEB_GetURL(web_authurl->string, WEB_AuthResponse)) {
		Cvar_Set("web_password", "");
		Cvar_Set("web_userid", "0");
		return false;
	}
	/* if the password is still set, the auth was successful */
	return Q_strvalid(web_password->string);
}
Esempio n. 16
0
static void LE_PlayFootStepSound (le_t* le)
{
	if (Q_strvalid(le->teamDef->footstepSound)) {
		S_LoadAndPlaySample(le->teamDef->footstepSound, le->origin, SOUND_ATTN_NORM, SND_VOLUME_FOOTSTEPS);
		return;
	}
	/* walking in water will not play the normal footstep sounds */
	if (!le->pathContents[le->pathPos]) {
		vec3_t from, to;

		/* prepare trace vectors */
		PosToVec(le->pos, from);
		VectorCopy(from, to);
		/* we should really hit the ground with this */
		to[2] -= UNIT_HEIGHT;

		const trace_t trace = CL_Trace(Line(from, to), AABB::EMPTY, nullptr, nullptr, MASK_SOLID, cl_worldlevel->integer);
		if (trace.surface)
			LE_PlaySoundFileAndParticleForSurface(le, trace.surface->name);
	} else
		LE_PlaySoundFileForContents(le, le->pathContents[le->pathPos]);
}
Esempio n. 17
0
/**
 * @brief Responses to broadcasts, etc
 * @sa CL_ReadPackets
 * @sa CL_Frame
 * @sa SVC_DirectConnect
 * @param[in,out] msg The client stream message buffer to read from
 */
static void CL_ConnectionlessPacket (dbuffer* msg)
{
	char s[512];
	NET_ReadStringLine(msg, s, sizeof(s));

	Cmd_TokenizeString(s, false);

	const char* c = Cmd_Argv(0);
	Com_DPrintf(DEBUG_CLIENT, "server OOB: %s (%s)\n", c, Cmd_Args());

	/* server connection */
	if (Q_streq(c, CL_CMD_CLIENT_CONNECT)) {
		int i;
		for (i = 1; i < Cmd_Argc(); i++) {
			if (char const* const p = Q_strstart(Cmd_Argv(i), "dlserver=")) {
				Com_sprintf(cls.downloadReferer, sizeof(cls.downloadReferer), "ufo://%s", cls.servername);
				CL_SetHTTPServer(p);
				if (cls.downloadServer[0])
					Com_Printf("HTTP downloading enabled, URL: %s\n", cls.downloadServer);
			}
		}
		if (cls.state == ca_connected) {
			Com_Printf("Dup connect received. Ignored.\n");
			return;
		}
		dbuffer buf(5);
		NET_WriteByte(&buf, clc_stringcmd);
		NET_WriteString(&buf, NET_STATE_NEW "\n");
		NET_WriteMsg(cls.netStream, buf);
		GAME_InitMissionBriefing(_("Loading"));
		return;
	}

	/* remote command from gui front end */
	if (Q_streq(c, CL_CMD_COMMAND)) {
		if (!NET_StreamIsLoopback(cls.netStream)) {
			Com_Printf("Command packet from remote host. Ignored.\n");
			return;
		} else {
			char str[512];
			NET_ReadString(msg, str, sizeof(str));
			Cbuf_AddText("%s\n", str);
		}
		return;
	}

	/* ping from server */
	if (Q_streq(c, CL_CMD_PING)) {
		NET_OOB_Printf(cls.netStream, SV_CMD_ACK);
		return;
	}

	/* echo request from server */
	if (Q_streq(c, CL_CMD_ECHO)) {
		NET_OOB_Printf(cls.netStream, "%s", Cmd_Argv(1));
		return;
	}

	/* print */
	if (Q_streq(c, SV_CMD_PRINT)) {
		NET_ReadString(msg, popupText, sizeof(popupText));
		/* special reject messages needs proper handling */
		if (strstr(popupText, REJ_PASSWORD_REQUIRED_OR_INCORRECT)) {
			UI_PushWindow("serverpassword");
			if (Q_strvalid(Cvar_GetString("password"))) {
				Cvar_Set("password", "");
				CL_Drop();
				UI_Popup(_("Connection failure"), _("The password you specified was wrong."));
			} else {
				CL_Drop();
				UI_Popup(_("Connection failure"), _("This server requires a password."));
			}
		} else if (strstr(popupText, REJ_SERVER_FULL)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("This server is full."));
		} else if (strstr(popupText, REJ_BANNED)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("You are banned on this server."));
		} else if (strstr(popupText, REJ_GAME_ALREADY_STARTED)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("The game has already started."));
		} else if (strstr(popupText, REJ_SERVER_VERSION_MISMATCH)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("The server is running a different version of the game."));
		} else if (strstr(popupText, BAD_RCON_PASSWORD)) {
			Cvar_Set("rcon_password", "");
			UI_Popup(_("Bad rcon password"), _("The rcon password you specified was wrong."));
		} else if (strstr(popupText, REJ_CONNECTION_REFUSED)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("The server refused the connection."));
		} else if (Q_strvalid(popupText)) {
			UI_Popup(_("Notice"), _(popupText));
		}
		return;
	}

	if (!GAME_HandleServerCommand(c, msg))
		Com_Printf("Unknown command received \"%s\"\n", c);
}
Esempio n. 18
0
/**
 * @brief Change the server to a new map, taking all connected clients along with it.
 * @note the full syntax is: @code map [day|night] [+]<map> [<assembly>] @endcode
 * @sa SV_AssembleMap
 * @sa CM_LoadMap
 * @sa Com_SetServerState
 */
void SV_Map (bool day, const char* levelstring, const char* assembly)
{
	int i;
	unsigned checksum = 0;
	char* map = SV_GetConfigString(CS_TILES);
	char* pos = SV_GetConfigString(CS_POSITIONS);
	char* entityString = SV_GetConfigString(CS_ENTITYSTRING);
	MapInfo* randomMap = nullptr;
	client_t* cl;

	/* any partially connected client will be restarted */
	Com_SetServerState(ss_restart);

	/* the game is just starting */
	SV_InitGame();

	if (!svs.initialized) {
		Com_Printf("Could not spawn the server\n");
		return;
	}

	assert(Q_strvalid(levelstring));

	Com_DPrintf(DEBUG_SERVER, "SpawnServer: %s\n", levelstring);

	/* save name for levels that don't set message */
	SV_SetConfigString(CS_NAME, levelstring);
	SV_SetConfigString(CS_LIGHTMAP, day);
	SV_SetConfigString(CS_MAPZONE, Cvar_GetString("sv_mapzone"));

	Q_strncpyz(sv->name, levelstring, sizeof(sv->name));

	/* set serverinfo variable */
	sv_mapname = Cvar_FullSet("sv_mapname", sv->name, CVAR_SERVERINFO | CVAR_NOSET);

	/* notify the client in case of a listening server */
	SCR_BeginLoadingPlaque();

	if (assembly)
		Q_strncpyz(sv->assembly, assembly, sizeof(sv->assembly));
	else
		sv->assembly[0] = '\0';

	/* leave slots at start for clients only */
	cl = nullptr;
	while ((cl = SV_GetNextClient(cl)) != nullptr) {
		/* needs to reconnect */
		if (cl->state >= cs_spawning)
			SV_SetClientState(cl, cs_connected);
	}

	/* assemble and load the map */
	if (levelstring[0] == '+') {
		randomMap = SV_AssembleMap(levelstring + 1, assembly, map, pos, entityString, 0, true);
		if (!randomMap) {
			Com_Printf("Could not load assembly for map '%s'\n", levelstring);
			return;
		}
	} else {
		SV_SetConfigString(CS_TILES, levelstring);
		SV_SetConfigString(CS_POSITIONS, assembly ? assembly : "");
		SV_SetConfigString(CS_ENTITYSTRING, "");
	}

	CM_LoadMap(map, day, pos, entityString, &sv->mapData, &sv->mapTiles);

	Com_Printf("checksum for the map '%s': %u\n", levelstring, sv->mapData.mapChecksum);
	SV_SetConfigString(CS_MAPCHECKSUM, sv->mapData.mapChecksum);

	checksum = Com_GetScriptChecksum();

	Com_Printf("ufo script checksum %u\n", checksum);
	SV_SetConfigString(CS_UFOCHECKSUM, checksum);
	SV_SetConfigString(CS_OBJECTAMOUNT, csi.numODs);
	SV_SetConfigString(CS_VERSION, UFO_VERSION);
	SV_SetConfigString(CS_MAPTITLE, SV_GetMapTitle(randomMap, levelstring));
	if (Q_strstart(SV_GetConfigString(CS_MAPTITLE), "b/")) {
		/* For base attack, CS_MAPTITLE contains too many chars */
		SV_SetConfigString(CS_MAPTITLE, "Base attack");
		SV_SetConfigString(CS_NAME, ".baseattack");
	}

	/* clear random-map assembly data */
	Mem_Free(randomMap);
	randomMap = nullptr;

	/* clear physics interaction links */
	SV_ClearWorld();

	/* fix this! */
	for (i = 1; i <= sv->mapData.numInline; i++)
		sv->models[i] = CM_InlineModel(&sv->mapTiles, va("*%i", i));

	/* precache and static commands can be issued during map initialization */
	Com_SetServerState(ss_loading);

	/* load and spawn all other entities */
	{
		const ScopedMutex scopedMutex(svs.serverMutex);
		svs.ge->SpawnEntities(sv->name, SV_GetConfigStringInteger(CS_LIGHTMAP), sv->mapData.mapEntityString);
	}

	/* all precaches are complete */
	Com_SetServerState(ss_game);

	Com_Printf("-------------------------------------\n");

	Cbuf_CopyToDefer();
}