Пример #1
0
/*
 * @brief
 */
void Cl_ParseConfigString(void) {
	const uint16_t i = (uint16_t) Net_ReadShort(&net_message);

	if (i >= MAX_CONFIG_STRINGS) {
		Com_Error(ERR_DROP, "Invalid index %i\n", i);
	}

	strcpy(cl.config_strings[i], Net_ReadString(&net_message));
	const char *s = cl.config_strings[i];

	if (i > CS_MODELS && i < CS_MODELS + MAX_MODELS) {
		if (cls.state == CL_ACTIVE) {
			cl.model_precache[i - CS_MODELS] = R_LoadModel(s);
			if (cl.config_strings[i][0] == '*') {
				cl.model_clip[i - CS_MODELS] = Cm_Model(s);
			} else {
				cl.model_clip[i - CS_MODELS] = NULL;
			}
		}
	} else if (i >= CS_SOUNDS && i < CS_SOUNDS + MAX_SOUNDS) {
		if (cls.state == CL_ACTIVE) {
			cl.sound_precache[i - CS_SOUNDS] = S_LoadSample(s);
		}
	} else if (i >= CS_IMAGES && i < CS_IMAGES + MAX_IMAGES) {
		if (cls.state == CL_ACTIVE) {
			cl.image_precache[i - CS_IMAGES] = R_LoadImage(s, IT_PIC);
		}
	}

	cls.cgame->UpdateConfigString(i);
}
Пример #2
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);
}
Пример #3
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);
}
Пример #4
0
/**
 * @brief Parses an incoming SVC_PRINT message.
 */
static void Cl_ParsePrint(void) {

	const byte level = Net_ReadByte(&net_message);
	const char *string = Net_ReadString(&net_message);

	// the server shouldn't have sent us anything below our level anyway
	if (level >= message_level->integer) {

		// check to see if we should ignore the message
		if (*cl_ignore->string) {

			char patterns[MAX_STRING_CHARS];
			g_strlcpy(patterns, cl_ignore->string, sizeof(patterns));

			const char *p = patterns;
			while (true) {
				const char *pattern = ParseToken(&p);
				if (pattern == NULL) {
					break;
				}

				if (GlobMatch(pattern, string)) {
					return;
				}
			}
		}

		char *sample = NULL;
		switch (level) {
			case PRINT_CHAT:
			case PRINT_TEAM_CHAT:
				if (level == PRINT_CHAT && *cl_chat_sound->string) {
					sample = cl_chat_sound->string;
				} else if (level == PRINT_TEAM_CHAT && *cl_team_chat_sound->string) {
					sample = cl_team_chat_sound->string;
				}
				break;
			default:
				break;
		}

		if (sample) {
			S_AddSample(&(const s_play_sample_t) {
				.sample = S_LoadSample(sample)
			});
		}

		Con_Append(level, string);
	}
Пример #5
0
/**
 * @brief
 */
void Cl_ParseServerInfo(void) {
	char info[MAX_MSG_SIZE];

	cl_server_info_t *server = Cl_ServerForNetaddr(&net_from);
	if (!server) { // unknown server, assumed response to broadcast

		server = Cl_AddServer(&net_from);

		server->source = SERVER_SOURCE_BCAST;
		server->ping_time = cls.broadcast_time;
	}

	// try to parse the info string
	g_strlcpy(info, Net_ReadString(&net_message), sizeof(info));
	if (sscanf(info, "%63c\\%31c\\%31c\\%hu\\%hu", server->hostname, server->name,
	           server->gameplay, &server->clients, &server->max_clients) != 5) {

		Com_Debug(DEBUG_CLIENT, "Failed to parse info \"%s\" for %s\n", info, Net_NetaddrToString(&server->addr));

		server->hostname[0] = '\0';
		server->name[0] = '\0';
		server->gameplay[0] = '\0';
		server->clients = 0;
		server->max_clients = 0;

		return;
	}

	g_strchomp(server->hostname);
	g_strchomp(server->name);
	g_strchomp(server->gameplay);

	server->hostname[sizeof(server->hostname) - 1] = '\0';
	server->name[sizeof(server->name) - 1] = '\0';
	server->gameplay[sizeof(server->name) - 1] = '\0';

	server->ping = Clamp(quetoo.ticks - server->ping_time, 1u, 999u);

	Ui_UpdateBindings();
}
Пример #6
0
/*
 * @brief
 */
void Cl_ParseServerMessage(void) {
	int32_t cmd, old_cmd;
	char *s;
	int32_t i;

	if (cl_show_net_messages->integer == 1)
		Com_Print("%u ", (uint32_t) net_message.size);
	else if (cl_show_net_messages->integer >= 2)
		Com_Print("------------------\n");

	cl.byte_counter += net_message.size;
	cmd = 0;

	// parse the message
	while (true) {
		if (net_message.read > net_message.size) {
			Com_Error(ERR_DROP, "Bad server message\n");
		}

		old_cmd = cmd;
		cmd = Net_ReadByte(&net_message);

		if (cmd == -1) {
			Cl_ShowNet("END OF MESSAGE");
			break;
		}

		if (cl_show_net_messages->integer >= 2 && sv_cmd_names[cmd])
			Cl_ShowNet(sv_cmd_names[cmd]);

		switch (cmd) {

			case SV_CMD_BASELINE:
				Cl_ParseBaseline();
				break;

			case SV_CMD_CBUF_TEXT:
				s = Net_ReadString(&net_message);
				Cbuf_AddText(s);
				break;

			case SV_CMD_CONFIG_STRING:
				Cl_ParseConfigString();
				break;

			case SV_CMD_DISCONNECT:
				Com_Error(ERR_DROP, "Server disconnected\n");
				break;

			case SV_CMD_DOWNLOAD:
				Cl_ParseDownload();
				break;

			case SV_CMD_FRAME:
				Cl_ParseFrame();
				break;

			case SV_CMD_PRINT:
				i = Net_ReadByte(&net_message);
				s = Net_ReadString(&net_message);
				if (i == PRINT_CHAT) {
					if (Cl_IgnoreChatMessage(s)) // filter /ignore'd chatters
						break;
					if (*cl_chat_sound->string) // trigger chat sound
						S_StartLocalSample(cl_chat_sound->string);
				} else if (i == PRINT_TEAMCHAT) {
					if (Cl_IgnoreChatMessage(s)) // filter /ignore'd chatters
						break;
					if (*cl_team_chat_sound->string) // trigger chat sound
						S_StartLocalSample(cl_team_chat_sound->string);
				}
				Com_Print("%s", s);
				break;

			case SV_CMD_RECONNECT:
				Com_Print("Server disconnected, reconnecting...\n");
				// stop download
				if (cls.download.file) {
					if (cls.download.http) // clean up http downloads
						Cl_HttpDownload_Complete();
					else
						// or just stop legacy ones
						Fs_Close(cls.download.file);
					cls.download.name[0] = '\0';
					cls.download.file = NULL;
				}
				cls.state = CL_CONNECTING;
				cls.connect_time = 0; // fire immediately
				break;

			case SV_CMD_SERVER_DATA:
				Cl_ParseServerData();
				break;

			case SV_CMD_SOUND:
				Cl_ParseSound();
				break;

			default:
				// delegate to the client game module before failing
				if (!cls.cgame->ParseMessage(cmd)) {
					Com_Error(ERR_DROP, "Illegible server message:\n"
							" %d: last command was %s\n", cmd, sv_cmd_names[old_cmd]);
				}
				break;
		}
	}

	Cl_AddNetGraph();

	Cl_WriteDemoMessage();
}
Пример #7
0
/**
 * @brief
 */
static void Cl_ParseCbufText(void) {

	const char *text = Net_ReadString(&net_message);

	Cbuf_AddText(text);
}