Beispiel #1
0
/**
 * @brief called whenever the player updates a userinfo variable.
 * @note The game can override any of the settings in place (forcing skins or names, etc) before copying it off.
 */
void G_ClientUserinfoChanged (player_t * player, const char *userinfo)
{
	const bool alreadyReady = player->isReady;
	const int oldTeamnum = Info_IntegerForKey(player->pers.userinfo, "cl_teamnum");

	/* check for malformed or illegal info strings */
	if (!Info_Validate(userinfo))
		userinfo = "\\cl_name\\badinfo";

	/* set name */
	Q_strncpyz(player->pers.netname, Info_ValueForKey(userinfo, "cl_name"), sizeof(player->pers.netname));
	Q_strncpyz(player->pers.userinfo, userinfo, sizeof(player->pers.userinfo));
	player->autostand = Info_IntegerForKey(userinfo, "cl_autostand");
	player->reactionLeftover = Info_IntegerForKey(userinfo, "cl_reactionleftover");
	player->isReady = Info_IntegerForKey(userinfo, "cl_ready");

	/* send the updated config string */
	gi.ConfigString(CS_PLAYERNAMES + player->num, "%s", player->pers.netname);

	/* try to update to the preferred team */
	if (!G_MatchIsRunning() && oldTeamnum != Info_IntegerForKey(userinfo, "cl_teamnum")) {
		/* if the player is marked as ready he can't change his team */
		if (!alreadyReady || !player->isReady) {
			player->pers.team = TEAM_NO_ACTIVE;
			G_GetTeam(player);
		} else {
			Com_DPrintf(DEBUG_GAME, "G_ClientUserinfoChanged: player %s is already marked as being ready\n",
					player->pers.netname);
		}
	}
}
Beispiel #2
0
/**
 * @brief Parsed the server ping response.
 * @param[out] server The server data to store the parsed information in
 * @param[in] msg The ping response with the server information to parse
 * @sa CL_PingServerCallback
 * @sa SVC_Info
 * @return @c true if the server is compatible, @c msg is not @c null and the server
 * wasn't pinged already, @c false otherwise
 */
static bool CL_ProcessPingReply (serverList_t *server, const char *msg)
{
	if (!msg)
		return false;

	if (PROTOCOL_VERSION != Info_IntegerForKey(msg, "sv_protocol")) {
		Com_DPrintf(DEBUG_CLIENT, "CL_ProcessPingReply: Protocol mismatch\n");
		return false;
	}
	if (!Q_streq(UFO_VERSION, Info_ValueForKey(msg, "sv_version"))) {
		Com_DPrintf(DEBUG_CLIENT, "CL_ProcessPingReply: Version mismatch\n");
	}

	if (server->pinged)
		return false;

	server->pinged = true;
	Q_strncpyz(server->sv_hostname, Info_ValueForKey(msg, "sv_hostname"),
		sizeof(server->sv_hostname));
	Q_strncpyz(server->version, Info_ValueForKey(msg, "sv_version"),
		sizeof(server->version));
	Q_strncpyz(server->mapname, Info_ValueForKey(msg, "sv_mapname"),
		sizeof(server->mapname));
	Q_strncpyz(server->gametype, Info_ValueForKey(msg, "sv_gametype"),
		sizeof(server->gametype));
	server->clients = Info_IntegerForKey(msg, "clients");
	server->sv_dedicated = Info_IntegerForKey(msg, "sv_dedicated");
	server->sv_maxclients = Info_IntegerForKey(msg, "sv_maxclients");
	return true;
}
Beispiel #3
0
/**
 * @brief Team selection text
 *
 * This function fills the multiplayer_selectteam menu with content
 * @sa NET_OOB_Printf
 * @sa SVC_TeamInfo
 * @sa CL_SelectTeam_Init_f
 */
void CL_ParseTeamInfoMessage (dbuffer *msg)
{
	char str[4096];
	int cnt = 0;
	linkedList_t *userList = NULL;
	linkedList_t *userTeam = NULL;

	if (cgi->NET_ReadString(msg, str, sizeof(str)) == 0) {
		cgi->UI_ResetData(TEXT_MULTIPLAYER_USERLIST);
		cgi->UI_ResetData(TEXT_MULTIPLAYER_USERTEAM);
		cgi->UI_ExecuteConfunc("multiplayer_playerNumber 0");
		cgi->Com_DPrintf(DEBUG_CLIENT, "CL_ParseTeamInfoMessage: No teaminfo string\n");
		return;
	}

	OBJZERO(teamData);

	teamData.maxteams = Info_IntegerForKey(str, "sv_maxteams");
	teamData.maxPlayersPerTeam = Info_IntegerForKey(str, "sv_maxplayersperteam");

	/* for each lines */
	while (cgi->NET_ReadString(msg, str, sizeof(str)) > 0) {
		const int team = Info_IntegerForKey(str, "cl_team");
		const int isReady = Info_IntegerForKey(str, "cl_ready");
		const char *user = Info_ValueForKey(str, "cl_name");

		if (team > 0 && team < MAX_TEAMS)
			teamData.teamCount[team]++;

		/* store data */
		cgi->LIST_AddString(&userList, user);
		if (team != TEAM_NO_ACTIVE)
			cgi->LIST_AddString(&userTeam, va(_("Team %d"), team));
		else
			cgi->LIST_AddString(&userTeam, _("No team"));

		cgi->UI_ExecuteConfunc("multiplayer_playerIsReady %i %i", cnt, isReady);

		cnt++;
	}

	cgi->UI_RegisterLinkedListText(TEXT_MULTIPLAYER_USERLIST, userList);
	cgi->UI_RegisterLinkedListText(TEXT_MULTIPLAYER_USERTEAM, userTeam);
	cgi->UI_ExecuteConfunc("multiplayer_playerNumber %i", cnt);

	/* no players are connected ATM */
	if (!cnt) {
		/** @todo warning must not be into the player list.
		 * if we see this we are the first player that would be connected to the server */
		/* Q_strcat(teamData.teamInfoText, _("No player connected\n"), sizeof(teamData.teamInfoText)); */
	}

	cgi->Cvar_SetValue("mn_maxteams", teamData.maxteams);
	cgi->Cvar_SetValue("mn_maxplayersperteam", teamData.maxPlayersPerTeam);
}
Beispiel #4
0
/**
 * @brief Pull specific info from a newly changed userinfo string into a more C friendly form.
 */
void SV_UserinfoChanged (client_t* cl)
{
    /* call prog code to allow overrides */
    {
        const ScopedMutex scopedMutex(svs.serverMutex);
        svs.ge->ClientUserinfoChanged(*cl->player, cl->userinfo);
    }

    /* name of the player */
    Q_strncpyz(cl->name, Info_ValueForKey(cl->userinfo, "cl_name"), sizeof(cl->name));
    /* mask off high bit */
    for (int i = 0; i < sizeof(cl->name); i++)
        cl->name[i] &= 127;

    /* msg command */
    cl->messagelevel = Info_IntegerForKey(cl->userinfo, "cl_msg");

    Com_DPrintf(DEBUG_SERVER, "SV_UserinfoChanged: Changed userinfo for player %s\n", cl->name);
}
Beispiel #5
0
/**
 * @brief Returns the preferred team number for the player
 */
int G_ClientGetTeamNumPref (const player_t * player)
{
	assert(player);
	return Info_IntegerForKey(player->pers.userinfo, "cl_teamnum");
}