Пример #1
0
/**
 * @brief Responds with teaminfo such as free team num
 * @sa CL_ParseTeamInfoMessage
 */
static void SVC_TeamInfo (struct net_stream *s)
{
	client_t *cl;
	dbuffer msg;
	char infoGlobal[MAX_INFO_STRING] = "";

	NET_WriteByte(&msg, clc_oob);
	NET_WriteRawString(&msg, "teaminfo\n");

	Info_SetValueForKey(infoGlobal, sizeof(infoGlobal), "sv_teamplay", Cvar_GetString("sv_teamplay"));
	Info_SetValueForKey(infoGlobal, sizeof(infoGlobal), "sv_maxteams", Cvar_GetString("sv_maxteams"));
	Info_SetValueForKey(infoGlobal, sizeof(infoGlobal), "sv_maxplayersperteam", Cvar_GetString("sv_maxplayersperteam"));
	NET_WriteString(&msg, infoGlobal);

	cl = NULL;
	while ((cl = SV_GetNextClient(cl)) != NULL) {
		if (cl->state >= cs_connected) {
			char infoPlayer[MAX_INFO_STRING] = "";
			/* show players that already have a team with their teamnum */
			int teamId = svs.ge->ClientGetTeamNum(cl->player);
			if (!teamId)
				teamId = TEAM_NO_ACTIVE;
			Info_SetValueForKeyAsInteger(infoPlayer, sizeof(infoPlayer), "cl_team", teamId);
			Info_SetValueForKeyAsInteger(infoPlayer, sizeof(infoPlayer), "cl_ready", svs.ge->ClientIsReady(cl->player));
			Info_SetValueForKey(infoPlayer, sizeof(infoPlayer), "cl_name", cl->name);
			NET_WriteString(&msg, infoPlayer);
		}
	}

	NET_WriteByte(&msg, 0);

	NET_WriteMsg(s, msg);
}
Пример #2
0
/**
 * @brief Plays the music file given via commandline parameter
 */
static void M_Play_f (void)
{
	if (Cmd_Argc() == 2)
		Cvar_Set("snd_music", "%s", Cmd_Argv(1));

	M_Start(Cvar_GetString("snd_music"));
}
Пример #3
0
/**
 * @brief Changed the given cvar to the next/prev equipment definition
 */
static void GAME_SK_ChangeEquip_f (void)
{
	const equipDef_t *ed;
	int index;
	const char *cvarName;

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

	cvarName = Cmd_Argv(1);
	ed = INV_GetEquipmentDefinitionByID(Cvar_GetString(cvarName));
	index = ed - csi.eds;

	if (Q_streq(Cmd_Argv(0), "sk_prevequip")) {
		index--;
		if (index < 0)
			index = csi.numEDs - 1;
		Cvar_Set(cvarName, csi.eds[index].name);
	} else {
		index++;
		if (index >= csi.numEDs)
			index = 0;
		Cvar_Set(cvarName, csi.eds[index].name);
	}
}
Пример #4
0
/*
 * Svc_Info
 *
 * Responds with short info for broadcast scans.
 */
static void Svc_Info(void) {
	char string[MAX_MSG_SIZE];
	int i, count;
	int prot;

	if (sv_max_clients->integer == 1)
		return; // ignore in single player

	prot = atoi(Cmd_Argv(1));

	if (prot != PROTOCOL)
		snprintf(string, sizeof(string), "%s: wrong protocol version\n", sv_hostname->string);
	else {
		count = 0;

		for (i = 0; i < sv_max_clients->integer; i++) {
			if (svs.clients[i].state >= SV_CLIENT_CONNECTED)
				count++;
		}

		snprintf(string, sizeof(string), "%-63s\\%-31s\\%-31s\\%d\\%d",
				sv_hostname->string, sv.name, Cvar_GetString("g_gameplay"),
				count, sv_max_clients->integer);
	}

	Netchan_OutOfBandPrint(NS_SERVER, net_from, "info\n%s", string);
}
/**
 * @brief Opens the UFOpedia for the current selected item/aircraft.
 * @note called by market_openpedia
 */
static void BS_MarketInfoClick_f (void)
{
	const technology_t *tech = RS_GetTechByProvided(Cvar_GetString("mn_item"));

	if (tech)
		UP_OpenWith(tech->id);
}
Пример #6
0
/*
 * Sv_New_f
 *
 * Sends the first message from the server to a connected client.
 * This will be sent on the initial connection and upon each server load.
 */
static void Sv_New_f(void) {
	int player_num;

	Com_Debug("New() from %s\n", Sv_NetaddrToString(sv_client));

	if (sv_client->state != SV_CLIENT_CONNECTED) {
		Com_Warn("Sv_New_f: %s already spawned\n",
				Sv_NetaddrToString(sv_client));
		return;
	}

	// demo servers will send the demo file's server info packet
	if (sv.state == SV_ACTIVE_DEMO) {
		return;
	}

	// send the server data
	Msg_WriteByte(&sv_client->netchan.message, SV_CMD_SERVER_DATA);
	Msg_WriteLong(&sv_client->netchan.message, PROTOCOL);
	Msg_WriteLong(&sv_client->netchan.message, svs.spawn_count);
	Msg_WriteLong(&sv_client->netchan.message, svs.frame_rate);
	Msg_WriteByte(&sv_client->netchan.message, 0);
	Msg_WriteString(&sv_client->netchan.message, Cvar_GetString("game"));

	player_num = sv_client - svs.clients;
	Msg_WriteShort(&sv_client->netchan.message, player_num);

	// send full level name
	Msg_WriteString(&sv_client->netchan.message, sv.config_strings[CS_NAME]);

	// begin fetching config_strings
	Msg_WriteByte(&sv_client->netchan.message, SV_CMD_CBUF_TEXT);
	Msg_WriteString(&sv_client->netchan.message,
			va("config_strings %i 0\n", svs.spawn_count));
}
Пример #7
0
/**
 * @brief Add a new command to the script interface
 * @param[in] cmd_name The name the command is available via script interface
 * @param[in] function The function pointer
 * @param[in] desc A usually(?) one-line description of what the cmd does
 * @sa Cmd_RemoveCommand
 */
void Cmd_AddCommand (const char *cmd_name, xcommand_t function, const char *desc)
{
	cmd_function_t *cmd;
	unsigned int hash;

	if (!cmd_name || !cmd_name[0])
		return;

	/* fail if the command is a variable name */
	if (Cvar_GetString(cmd_name)[0]) {
		Com_Printf("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
		return;
	}

	/* fail if the command already exists */
	hash = Com_HashKey(cmd_name, CMD_HASH_SIZE);
	for (cmd = cmd_functions_hash[hash]; cmd; cmd = cmd->hash_next) {
		if (Q_streq(cmd_name, cmd->name)) {
			Com_DPrintf(DEBUG_COMMANDS, "Cmd_AddCommand: %s already defined\n", cmd_name);
			return;
		}
	}

	cmd = (cmd_function_t *)Mem_PoolAlloc(sizeof(*cmd), com_cmdSysPool, 0);
	cmd->name = cmd_name;
	cmd->description = desc;
	cmd->function = function;
	cmd->completeParam = NULL;
	HASH_Add(cmd_functions_hash, cmd, hash);
	cmd->next = cmd_functions;
	cmd_functions = cmd;
}
Пример #8
0
/**
 * @brief Updates needed cvar for loading screens
 * @param[in] mapString The mapstring of the map that is currently loaded
 * @note If @c mapString is NULL the @c sv_mapname cvar is used
 * @return The loading/background pic path
 */
static const image_t* SCR_SetLoadingBackground (const char *mapString)
{
	const char *mapname;
	image_t* image;

	if (!mapString || Com_ServerState())
		mapname = Cvar_GetString("sv_mapname");
	else {
		mapname = mapString;
		Cvar_Set("sv_mapname", mapString);
	}

	/* we will try to load the random map shots by just removing the + from the beginning */
	if (mapname[0] == '+')
		mapname++;

	image = R_FindImage(va("pics/maps/loading/%s", mapname), it_worldrelated);
	if (image == r_noTexture)
		image = R_FindImage("pics/maps/loading/default", it_pic);

	/* strip away the pics/ part */
	Cvar_Set("mn_mappicbig", image->name + 5);

	return image;
}
Пример #9
0
/**
 * @brief Responds with teaminfo such as free team num
 * @sa CL_ParseTeamInfoMessage
 */
static void SVC_TeamInfo (struct net_stream* s)
{
    if (SVC_RateLimitAddress(*s)) {
        Com_DPrintf(DEBUG_SERVER, "SVC_TeamInfo: 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_TeamInfo: rate limit exceeded, dropping request\n");
        return;
    }

    char infoGlobal[MAX_INFO_STRING] = "";
    Info_SetValueForKey(infoGlobal, sizeof(infoGlobal), "sv_teamplay", Cvar_GetString("sv_teamplay"));
    Info_SetValueForKey(infoGlobal, sizeof(infoGlobal), "sv_maxteams", Cvar_GetString("sv_maxteams"));
    Info_SetValueForKey(infoGlobal, sizeof(infoGlobal), "sv_maxplayersperteam", Cvar_GetString("sv_maxplayersperteam"));

    dbuffer msg;
    NET_WriteByte(&msg, svc_oob);
    NET_WriteRawString(&msg, "teaminfo\n");
    NET_WriteString(&msg, infoGlobal);

    client_t* cl = nullptr;
    while ((cl = SV_GetNextClient(cl)) != nullptr) {
        if (cl->state < cs_connected)
            continue;
        char infoPlayer[MAX_INFO_STRING] = "";
        /* show players that already have a team with their teamnum */
        int teamId = svs.ge->ClientGetTeamNum(*cl->player);
        if (!teamId)
            teamId = TEAM_NO_ACTIVE;
        Info_SetValueForKeyAsInteger(infoPlayer, sizeof(infoPlayer), "cl_team", teamId);
        Info_SetValueForKeyAsInteger(infoPlayer, sizeof(infoPlayer), "cl_ready", svs.ge->ClientIsReady(cl->player));
        Info_SetValueForKey(infoPlayer, sizeof(infoPlayer), "cl_name", cl->name);
        NET_WriteString(&msg, infoPlayer);
    }

    NET_WriteByte(&msg, 0);

    NET_WriteMsg(s, msg);
}
Пример #10
0
/**
 * @brief Allows copying variables
 * Available via console command copy
 */
static void Cvar_Copy_f (void)
{
	int c;

	c = Cmd_Argc();
	if (c < 3) {
		Com_Printf("Usage: %s <target> <source>\n", Cmd_Argv(0));
		return;
	}

	Cvar_Set(Cmd_Argv(1), "%s", Cvar_GetString(Cmd_Argv(2)));
}
Пример #11
0
const char* GAME_GetTeamDef (void)
{
	const char *teamDefID;
	const cgame_export_t *list = GAME_GetCurrentType();

	if (list && list->GetTeamDef)
		return list->GetTeamDef();

	teamDefID = Cvar_GetString("cl_teamdef");
	if (teamDefID[0] == '\0')
		teamDefID = "phalanx";
	return teamDefID;
}
Пример #12
0
void LoadPics(void)
{
	char buffer[256];
	char conchars_name[256];

//main bar (add cvars later)
	Cvar_GetString("gl_consolefont", buffer, sizeof(buffer));
	snprintf(conchars_name, sizeof(conchars_name), "textures/charsets/%s", buffer);
	
	if (*buffer)
		con_chars = Draw_LoadImage(conchars_name, false);
	else
		con_chars = Draw_LoadImage("textures/charsets/povo5", false);
}
Пример #13
0
int Plug_ExecuteCommand(int *args)
{
	char cmd[256];
	Cmd_Argv(0, cmd, sizeof(cmd));
	if (!strcmp("namemaker", cmd))
	{
		Menu_Control(1);
		Cvar_GetString("name", (char*)namebuffer, sizeof(namebuffer));
		LoadPics();
		insertpos = strlen(namebuffer);
		return 1;
	}
	return 0;
}
Пример #14
0
/**
 * @brief Take a screen shot of the map with the position of the radar
 *
 * We add 1 pixel into the border to easy check the result:
 * the screen shot must have a border of 1 black pixel
 */
static void CL_BattlescapeRadarGenerate_f (void)
{
	const int border = 0;
	const char* mapName = Cvar_GetString("sv_mapname");

	const int level = Cvar_GetInteger("cl_worldlevel");
	const char* filename = nullptr;
	int x, y, width, height;

	CL_BattlescapeRadarMapInFrameBuffer(&x, &y, &width, &height);
	if (mapName)
		filename = va("%s_%i", mapName, level + 1);
	R_ScreenShot(x - border, y - border, width + border * 2, height + border * 2, filename, nullptr);
}
Пример #15
0
/**
 * @brief Parses the given string into command line tokens.
 * @note @c cmd_argv and @c cmd_argv are filled and set here
 * @note *cvars will be expanded unless they are in a quoted token
 * @sa Com_MacroExpandString
 * @param[in] text The text to parse and tokenize
 * @param[in] macroExpand expand cvar string with their values
 */
void Cmd_TokenizeString (const char *text, qboolean macroExpand)
{
	const char *com_token, *expanded;

	Cmd_BufClear();

	/* macro expand the text */
	if (macroExpand) {
		expanded = Com_MacroExpandString(text);
		if (expanded)
			text = expanded;
	}

	while (1) {
		/* skip whitespace up to a newline */
		while (*text && *text <= ' ' && *text != '\n') {
			text++;
		}

		if (*text == '\n') {	/* a newline seperates commands in the buffer */
			text++;
			break;
		}

		if (!*text)
			return;

		/* set cmd_args to everything after the first arg */
		if (cmd_argc == 1) {
			Q_strncpyz(cmd_args, text, sizeof(cmd_args));
			Com_Chop(cmd_args);
		}

		com_token = Com_Parse(&text);
		if (!text)
			return;

		if (cmd_argc < MAX_STRING_TOKENS) {
			/* check first char of string if it is a variable */
			if (com_token[0] == '*') {
				com_token++;
				com_token = Cvar_GetString(com_token);
			}
			assert(!cmd_argv[cmd_argc]);
			cmd_argv[cmd_argc] = Mem_PoolStrDup(com_token, com_cmdSysPool, 0);
			cmd_argc++;
		}
	}
}
Пример #16
0
/**
 * @brief Starts a new skirmish game
 */
static void GAME_SK_Start_f (void)
{
	char map[MAX_VAR];
	mapDef_t *md;

	if (!chrDisplayList.num) {
		unsigned int i;
		/** @todo make the teamdef configurable */
		const char *ugvTeamDefID = "phalanx_ugv_phoenix";
		const char *name = Cvar_GetString("cl_equip");
		const equipDef_t *ed = INV_GetEquipmentDefinitionByID(name);
		const size_t size = GAME_GetCharacterArraySize();
		uint32_t maxSoldiers = Cvar_GetInteger("sv_maxsoldiersperplayer");
		uint32_t ugvs = Cvar_GetInteger("cl_ugvs");

		if (maxSoldiers <= 0)
			maxSoldiers = size;

		ugvs = min(ugvs, size - maxSoldiers);
		Com_Printf("Starting skirmish with %i soldiers and %i ugvs\n", maxSoldiers, ugvs);
		GAME_AutoTeam(name, maxSoldiers);
		for (i = 0; i < ugvs; i++)
			GAME_AppendTeamMember(i + maxSoldiers, ugvTeamDefID, ed);
	} else {
		Com_Printf("Using already loaded team with %i members\n", chrDisplayList.num);
	}

	assert(cls.currentSelectedMap >= 0);
	assert(cls.currentSelectedMap < MAX_MAPDEFS);

	md = Com_GetMapDefByIDX(cls.currentSelectedMap);
	if (!md)
		return;

	GAME_SK_SetMissionParameters(md);

	assert(md->map);
	Com_sprintf(map, sizeof(map), "map %s %s %s;", Cvar_GetInteger("mn_serverday") ? "day" : "night", md->map, md->param ? md->param : "");

	/* prepare */
	UI_InitStack(NULL, "singleplayermission", qtrue, qfalse);

	Cbuf_AddText(map);
}
Пример #17
0
// handler of ExecuteCommand event
int Plug_ExecuteCommand(int *args)
{
	char cmd[256];
	Cmd_Argv(0, cmd, sizeof(cmd));
	if (!strcmp("dummyplugin_cmd", cmd))
	{
		char buf[100];
		
		Con_Printf("This is dummy plugin talking.\n");
		if (Cvar_GetString("dummyplugin_cvar", buf, sizeof(buf))) {
			Con_Printf("dummyplugin_cvar value is: '%s'", buf);
		}
		else {
			Con_Printf("Something went wrong, cannot find dummyplugin_cvar\n");
		}
		return 1;
	}
	return 0;
}
/**
 * Updates the material editor node for a given image and a given material stage
 * @param image The image to load into the material editor
 * @param materialStage The material stage to display
 */
static void UI_MaterialEditorUpdate (image_t *image, materialStage_t *materialStage)
{
	linkedList_t *materialStagesList = NULL;

	if (image->normalmap == NULL)
		UI_ExecuteConfunc("hideshaders true 0 0 0 0");
	else
		UI_ExecuteConfunc("hideshaders false %f %f %f %f", image->material.bump,
				image->material.hardness, image->material.parallax, image->material.specular);

	if (image->normalmap == NULL)
		Cvar_Set("me_imagename", image->name);
	else
		Cvar_Set("me_imagename", va("%s (nm)", image->name));

	if (!image->material.num_stages) {
		UI_ExecuteConfunc("hidestages true");
	} else {
		int i;
		if (materialStage) {
			const char *stageType = Cvar_GetString("me_stagetype");
			if (stageType[0] == '\0')
				stageType = "stretch";
			UI_ExecuteConfunc("hidestages false %s", stageType);
		} else
			Cvar_Set("me_stage_id", "-1");
		for (i = 0; i < image->material.num_stages; i++) {
			const materialStage_t *stage = UI_MaterialEditorGetStage(&image->material, i);
			char stageName[MAX_VAR] = "stage ";
			if (stage == materialStage) {
				UI_ExecuteConfunc("updatestagevalues %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
						stage->rotate.hz, stage->rotate.deg,
						stage->stretch.hz, stage->stretch.dhz, stage->stretch.amp, stage->stretch.damp,
						stage->pulse.hz, stage->pulse.dhz,
						stage->scroll.ds, stage->scroll.dt, stage->scroll.s, stage->scroll.t,
						stage->scale.s, stage->scale.t);
			}
			UI_MaterialEditorStagesToName(stage, stageName, sizeof(stageName) - 1);
			LIST_AddString(&materialStagesList, stageName);
		}
	}
	UI_RegisterLinkedListText(TEXT_MATERIAL_STAGES, materialStagesList);
}
Пример #19
0
/*
 * @brief
 */
static void Cl_ParseServerData(void) {
	char *str;
	int32_t i;

	// wipe the cl_client_t struct
	Cl_ClearState();

	cls.state = CL_CONNECTED;
	cls.key_state.dest = KEY_CONSOLE;

	// parse protocol version number
	i = Net_ReadLong(&net_message);

	// ensure protocol matches
	if (i != PROTOCOL) {
		Com_Error(ERR_DROP, "Server is using unknown protocol %d\n", i);
	}

	// retrieve spawn count and packet rate
	cl.server_count = Net_ReadLong(&net_message);
	cl.server_hz = Net_ReadLong(&net_message);

	// determine if we're viewing a demo
	cl.demo_server = Net_ReadByte(&net_message);

	// game directory
	str = Net_ReadString(&net_message);
	if (g_strcmp0(Cvar_GetString("game"), str)) {

		Fs_SetGame(str);

		// reload the client game
		Cl_InitCgame();
	}

	// parse player entity number
	cl.entity_num = Net_ReadShort(&net_message);

	// get the full level name
	str = Net_ReadString(&net_message);
	Com_Print("\n");
	Com_Print("%c%s\n", 2, str);
}
Пример #20
0
/**
 * @brief
 */
static void Cl_ParseServerData(void) {

	// wipe the cl_client_t struct
	Cl_ClearState();

	Cl_SetKeyDest(KEY_CONSOLE);

	// parse protocol version number
	const uint16_t major = Net_ReadShort(&net_message);
	const uint16_t minor = Net_ReadShort(&net_message);

	// ensure protocol major matches
	if (major != PROTOCOL_MAJOR) {
		Com_Error(ERROR_DROP, "Server is using protocol major %d\n", major);
	}

	// determine if we're viewing a demo
	cl.demo_server = Net_ReadByte(&net_message);

	// game directory
	char *str = Net_ReadString(&net_message);
	if (g_strcmp0(Cvar_GetString("game"), str)) {

		Fs_SetGame(str);

		// reload the client game
		Cl_InitCgame();
	}

	// ensure protocol minor matches
	if (minor != cls.cgame->protocol) {
		Com_Error(ERROR_DROP, "Server is using protocol minor %d\n", minor);
	}

	// parse client slot number, which is our entity number + 1
	cl.client_num = Net_ReadShort(&net_message);

	// get the full level name
	str = Net_ReadString(&net_message);
	Com_Print("\n");
	Com_Print("^2%s^7\n", str);
}
Пример #21
0
/**
 * @sa CP_StartMissionMap
 */
static void R_ModLoadTexinfo (const lump_t *l)
{
	const dBspTexinfo_t *in;
	int i, j, count;
	char name[MAX_QPATH];

	in = (const dBspTexinfo_t *) (mod_base + l->fileofs);
	if (l->filelen % sizeof(*in))
		Com_Error(ERR_DROP, "R_ModLoadTexinfo: funny lump size in %s", r_worldmodel->name);
	count = l->filelen / sizeof(*in);
	mBspTexInfo_t* out = Mem_PoolAllocTypeN(mBspTexInfo_t, count, vid_modelPool);
	Com_DPrintf(DEBUG_RENDERER, "...texinfo: %i\n", count);

	r_worldmodel->bsp.texinfo = out;
	r_worldmodel->bsp.numtexinfo = count;

	const char *mapZone = Cvar_GetString("sv_mapzone");
	for (i = 0; i < count; i++, in++, out++) {
		for (j = 0; j < 3; j++) {
			out->uv[j] = LittleFloat(in->vecs[0][j]);
			out->vv[j] = LittleFloat(in->vecs[1][j]);
		}
		out->u_offset = LittleFloat(in->vecs[0][3]);
		out->v_offset = LittleFloat(in->vecs[1][3]);

		out->flags = LittleLong(in->surfaceFlags);

		/* exchange the textures with the ones that are needed for base assembly */
		if (mapZone && strstr(in->texture, "tex_terrain/dummy"))
			Com_sprintf(name, sizeof(name), "textures/tex_terrain/%s", mapZone);
		else
			Com_sprintf(name, sizeof(name), "textures/%s", in->texture);

		out->image = R_FindImage(name, it_world);
	}
}
Пример #22
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);
}
/**
 * @brief Update the item description according to the tech and the slot selected
 */
static void AIM_UpdateItemDescription (bool fromList, bool fromSlot)
{
	int status;
	aircraft_t *aircraft;
	aircraftSlot_t *slot;
	base_t *base = B_GetCurrentSelectedBase();
	assert(base);

	aircraft = base->aircraftCurrent;
	assert(aircraft);
	slot = AII_SelectAircraftSlot(aircraft, airequipID);

	/* update mini ufopedia */
	/** @todo we should clone the text, and not using the ufopedia text */
	if (fromList)
		UP_AircraftItemDescription(INVSH_GetItemByIDSilent(aimSelectedTechnology ? aimSelectedTechnology->provides : NULL));
	else if (fromSlot) {
		if (airequipID == AC_ITEM_AMMO)
			UP_AircraftItemDescription(slot->ammo);
		else
			UP_AircraftItemDescription(slot->item);
	}

	/* update status */
	status = AIM_CheckTechnologyIntoSlot(slot, aimSelectedTechnology);
	switch (status) {
	case AIM_LOADING_NOSLOTSELECTED:
		Cvar_Set("mn_aircraft_item_warning", _("No slot selected."));
		break;
	case AIM_LOADING_NOTECHNOLOGYSELECTED:
		Cvar_Set("mn_aircraft_item_warning", _("No item selected."));
		break;
	case AIM_LOADING_ALIENTECH:
		Cvar_Set("mn_aircraft_item_warning", _("You can't equip an alien technology."));
		break;
	case AIM_LOADING_TECHNOLOGYNOTRESEARCHED:
		Cvar_Set("mn_aircraft_item_warning", _("Technology requested is not yet completed."));
		break;
	case AIM_LOADING_TOOHEAVY:
		Cvar_Set("mn_aircraft_item_warning", _("This item is too heavy for the selected slot."));
		break;
	case AIM_LOADING_NOWEAPON:
		Cvar_Set("mn_aircraft_item_warning", _("Equip a weapon first."));
		break;
	case AIM_LOADING_NOTUSABLEWITHWEAPON:
		Cvar_Set("mn_aircraft_item_warning", _("Ammo not usable with current weapon."));
		break;
	case AIM_LOADING_UNKNOWNPROBLEM:
		Cvar_Set("mn_aircraft_item_warning", _("Unknown problem."));
		break;
	case AIM_LOADING_OK:
		Cvar_Set("mn_aircraft_item_warning", _("Ok"));
		break;
	}

	if (*Cvar_GetString("mn_item") == '\0') {
		cgi->UI_ExecuteConfunc("airequip_no_item");
	} else {
		if (fromSlot) {
			cgi->UI_ExecuteConfunc("airequip_installed_item");
		} else {
			if (status == AIM_LOADING_OK)
				cgi->UI_ExecuteConfunc("airequip_installable_item");
			else
				cgi->UI_ExecuteConfunc("airequip_noinstallable_item");
		}
	}
}
Пример #24
0
/**
 * @brief Expands strings with cvar values that are dereferenced by a '*cvar'
 * @note There is an overflow check for cvars that also contain a '*cvar'
 * @sa Cmd_TokenizeString
 * @sa UI_GetReferenceString
 */
const char* Com_MacroExpandString (const char* text)
{
	static char expanded[MAX_STRING_CHARS];

	const char* scan = text;
	if (!text || !*text)
		return nullptr;

	int len = strlen(scan);
	if (len >= MAX_STRING_CHARS) {
		Com_Printf("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
		return nullptr;
	}

	bool inquote = false;
	int count = 0;
	OBJZERO(expanded);
	char* pos = expanded;

	/* also the \0 */
	assert(scan[len] == '\0');
	for (int i = 0; i <= len; i++) {
		const char* token, *start, *cvarvalue;
		if (scan[i] == '"')
			inquote ^= 1;
		/* don't expand inside quotes */
		if (inquote || strncmp(&scan[i], "*cvar:", MACRO_CVAR_ID_LENGTH)) {
			*pos++ = scan[i];
			continue;
		}

		/* scan out the complete macro and only parse the cvar name */
		start = &scan[i + MACRO_CVAR_ID_LENGTH];
		token = Com_Parse(&start);
		if (!start)
			continue;

		/* skip the macro and the cvar name in the next loop */
		i += MACRO_CVAR_ID_LENGTH;
		i += strlen(token);
		i--;

		/* get the cvar value */
		cvarvalue = Cvar_GetString(token);
		if (!cvarvalue) {
			Com_Printf("Could not get cvar value for cvar: %s\n", token);
			return nullptr;
		}

		int j = strlen(cvarvalue);
		if (strlen(pos) + j >= MAX_STRING_CHARS) {
			Com_Printf("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
			return nullptr;
		}

		/* copy the cvar value into the target buffer */
		/* check for overflow is already done - so MAX_STRING_CHARS won't hurt here */
		Q_strncpyz(pos, cvarvalue, j + 1);
		pos += j;

		if (++count == 100) {
			Com_Printf("Macro expansion loop, discarded.\n");
			return nullptr;
		}
	}

	if (inquote) {
		Com_Printf("Line has unmatched quote, discarded.\n");
		return nullptr;
	}

	if (count)
		return expanded;

	return nullptr;
}
Пример #25
0
/**
 * @brief Writes server_data, config_strings, and baselines once a non-delta
 * compressed frame arrives from the server.
 */
static void Cl_WriteDemoHeader(void) {
	static entity_state_t null_state;
	mem_buf_t msg;
	byte buffer[MAX_MSG_SIZE];

	// write out messages to hold the startup information
	Mem_InitBuffer(&msg, buffer, sizeof(buffer));

	// write the server data
	Net_WriteByte(&msg, SV_CMD_SERVER_DATA);
	Net_WriteShort(&msg, PROTOCOL_MAJOR);
	Net_WriteShort(&msg, cls.cgame->protocol);
	Net_WriteByte(&msg, 1); // demo_server byte
	Net_WriteString(&msg, Cvar_GetString("game"));
	Net_WriteShort(&msg, cl.client_num);
	Net_WriteString(&msg, cl.config_strings[CS_NAME]);

	// and config_strings
	for (int32_t i = 0; i < MAX_CONFIG_STRINGS; i++) {
		if (*cl.config_strings[i] != '\0') {
			if (msg.size + strlen(cl.config_strings[i]) + 32 > msg.max_size) { // write it out
				const int32_t len = LittleLong((int32_t) msg.size);
				Fs_Write(cls.demo_file, &len, sizeof(len), 1);
				Fs_Write(cls.demo_file, msg.data, msg.size, 1);
				msg.size = 0;
			}

			Net_WriteByte(&msg, SV_CMD_CONFIG_STRING);
			Net_WriteShort(&msg, i);
			Net_WriteString(&msg, cl.config_strings[i]);
		}
	}

	// and baselines
	for (size_t i = 0; i < lengthof(cl.entities); i++) {
		entity_state_t *ent = &cl.entities[i].baseline;
		if (!ent->number) {
			continue;
		}

		if (msg.size + 64 > msg.max_size) { // write it out
			const int32_t len = LittleLong((int32_t) msg.size);
			Fs_Write(cls.demo_file, &len, sizeof(len), 1);
			Fs_Write(cls.demo_file, msg.data, msg.size, 1);
			msg.size = 0;
		}

		Net_WriteByte(&msg, SV_CMD_BASELINE);
		Net_WriteDeltaEntity(&msg, &null_state, &cl.entities[i].baseline, true);
	}

	Net_WriteByte(&msg, SV_CMD_CBUF_TEXT);
	Net_WriteString(&msg, "precache 0\n");

	// write it to the demo file

	const int32_t len = LittleLong((int32_t) msg.size);

	Fs_Write(cls.demo_file, &len, sizeof(len), 1);
	Fs_Write(cls.demo_file, msg.data, msg.size, 1);

	Com_Debug(DEBUG_CLIENT, "Demo started\n");
	// the rest of the demo file will be individual frames
}
Пример #26
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();
}
Пример #27
0
/*
 * Cl_WriteDemoHeader
 *
 * Writes server_data, config_strings, and baselines once a non-delta
 * compressed frame arrives from the server.
 */
static void Cl_WriteDemoHeader(void) {
	byte buffer[MAX_MSG_SIZE];
	size_buf_t msg;
	int i;
	int len;
	entity_state_t null_state;

	// write out messages to hold the startup information
	Sb_Init(&msg, buffer, sizeof(buffer));

	// write the server data
	Msg_WriteByte(&msg, SV_CMD_SERVER_DATA);
	Msg_WriteLong(&msg, PROTOCOL);
	Msg_WriteLong(&msg, cl.server_count);
	Msg_WriteLong(&msg, cl.server_frame_rate);
	Msg_WriteByte(&msg, 1); // demo_server byte
	Msg_WriteString(&msg, Cvar_GetString("game"));
	Msg_WriteShort(&msg, cl.player_num);
	Msg_WriteString(&msg, cl.config_strings[CS_NAME]);

	// and config_strings
	for (i = 0; i < MAX_CONFIG_STRINGS; i++) {
		if (*cl.config_strings[i] != '\0') {
			if (msg.size + strlen(cl.config_strings[i]) + 32 > msg.max_size) { // write it out
				len = LittleLong(msg.size);
				Fs_Write(&len, 4, 1, cls.demo_file);
				Fs_Write(msg.data, msg.size, 1, cls.demo_file);
				msg.size = 0;
			}

			Msg_WriteByte(&msg, SV_CMD_CONFIG_STRING);
			Msg_WriteShort(&msg, i);
			Msg_WriteString(&msg, cl.config_strings[i]);
		}
	}

	// and baselines
	for (i = 0; i < MAX_EDICTS; i++) {
		entity_state_t *ent = &cl.entities[i].baseline;
		if (!ent->number)
			continue;

		if (msg.size + 64 > msg.max_size) { // write it out
			len = LittleLong(msg.size);
			Fs_Write(&len, 4, 1, cls.demo_file);
			Fs_Write(msg.data, msg.size, 1, cls.demo_file);
			msg.size = 0;
		}

		memset(&null_state, 0, sizeof(null_state));

		Msg_WriteByte(&msg, SV_CMD_ENTITY_BASELINE);
		Msg_WriteDeltaEntity(&null_state, &cl.entities[i].baseline, &msg, true,
				true);
	}

	Msg_WriteByte(&msg, SV_CMD_CBUF_TEXT);
	Msg_WriteString(&msg, "precache 0\n");

	// write it to the demo file

	len = LittleLong(msg.size);
	Fs_Write(&len, 4, 1, cls.demo_file);
	Fs_Write(msg.data, msg.size, 1, cls.demo_file);

	Com_Print("Recording to %s.\n", cls.demo_path);
	// the rest of the demo file will be individual frames
}