示例#1
0
/*
==============
BotSetUserInfo
==============
*/
void BotSetUserInfo(bot_state_t *bs, char *key, char *value)
{
	char userinfo[MAX_INFO_STRING];

	trap_GetUserinfo(bs->client, userinfo, sizeof(userinfo));
	Info_SetValueForKey(userinfo, key, value);
	trap_SetUserinfo(bs->client, userinfo);
	ClientUserinfoChanged( bs->client );
}
示例#2
0
文件: ai_cast.c 项目: natelo/rtcwPub
//----(SA) modified this for head separation
gentity_t *AICast_AddCastToGame( gentity_t *ent, char *castname, char *model, char *head, char *sex, char *color, char *handicap )
{
	int clientNum;
	gentity_t *bot;
	char	userinfo[MAX_INFO_STRING];
	usercmd_t		cmd;

	// create the bot's userinfo
	userinfo[0] = '\0';

	Info_SetValueForKey( userinfo, "name", castname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "handicap", handicap );
	Info_SetValueForKey( userinfo, "model", model );
	Info_SetValueForKey( userinfo, "head", head );
	Info_SetValueForKey( userinfo, "color", color );

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "BotAllocateClient failed\n" );
		return NULL;
	}
	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->r.svFlags |= SVF_CASTAI;		// flag it for special Cast AI behaviour

	// register the userinfo
	trap_SetUserinfo( bot->s.number, userinfo );

	// have it connect to the game as a normal client
//----(SA) ClientConnect requires a third 'isbot' parameter.  setting to qfalse and noting
	ClientConnect( bot->s.number, qtrue, qfalse );
//----(SA) end

	// copy the origin/angles across
	VectorCopy( ent->s.origin, bot->s.origin );
	VectorCopy( ent->s.angles, bot->s.angles );

	memset( &cmd, 0, sizeof( cmd ) );
	ClientBegin( bot->s.number );

	// set up the ai
	AICast_SetupClient( bot->s.number );

	return bot;
}
示例#3
0
/*
==================
Cmd_TeamTask_f
==================
*/
void Cmd_TeamTask_f( gentity_t *ent ) {
	char userinfo[MAX_INFO_STRING];
	char		arg[MAX_TOKEN_CHARS];
	int task;
	int client = ent->client - level.clients;

	if ( trap_Argc() != 2 ) {
		return;
	}
	trap_Argv( 1, arg, sizeof( arg ) );
	task = atoi( arg );

	trap_GetUserinfo(client, userinfo, sizeof(userinfo));
	Info_SetValueForKey(userinfo, "teamtask", va("%d", task));
	trap_SetUserinfo(client, userinfo);
	ClientUserinfoChanged(client);
}
示例#4
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, const char *pclass, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			userinfo[MAX_INFO_STRING];
	int				preTeam = 0;

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

/*	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	} */

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "munro/main/default"; //RPG-X MODEL SYSTEM
	}
	Info_SetValueForKey( userinfo, key, model );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	if (g_gametype.integer >= GT_TEAM)
	{
		if (team && Q_stricmp(team, "red") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_RED;
		}
		else if (team && Q_stricmp(team, "blue") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_BLUE;
		}
		else
		{
			bot->client->sess.sessionTeam = PickTeam( -1 );
		}
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if (bot->client->sess.sessionTeam != preTeam)
	{
		trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

		if (bot->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			bot->client->sess.sessionTeam = preTeam;
		}

		if (bot->client->sess.sessionTeam == TEAM_RED)
		{
			team = "Red";
		}
		else
		{
			team = "Blue";
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap_SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		ClientUserinfoChanged( clientNum );
	}

	if( delay == 0 ) {
		ClientBegin( clientNum, qfalse, qfalse, qfalse );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
示例#5
0
/*
=============
BotInitialize

Initialize all internal data in the bot state
=============
*/
void BotInitialize(bot_state_t *bs)
{
	int i;
	char gender[MAX_CHARACTERISTIC_PATH];
	char userinfo[MAX_INFO_STRING];

	// No valid last command time exists, but make the bot do its AI as if nothing
	// special has happened recently
	bs->last_command_time_ms = server_time_ms;

	// Set the team (red, blue, or free) when not in tournament mode
	if (g_gametype.integer != GT_TOURNAMENT)
		trap_EA_Command(bs->client, va("team %s", bs->settings.team));

	// Set the bot gender
	trap_Characteristic_String(bs->character, CHARACTERISTIC_GENDER, gender, sizeof(gender));
	trap_GetUserinfo(bs->client, userinfo, sizeof(userinfo));
	Info_SetValueForKey(userinfo, "sex", gender);
	trap_SetUserinfo(bs->client, userinfo);

	// Set the chat gender
	if (gender[0] == 'm' || gender[0] == 'M')
		trap_BotSetChatGender(bs->cs, CHAT_GENDERMALE);
	else if (gender[0] == 'f' || gender[0] == 'F')
		trap_BotSetChatGender(bs->cs, CHAT_GENDERFEMALE);
	else
		trap_BotSetChatGender(bs->cs, CHAT_GENDERLESS);

	// Set the chat name
	trap_BotSetChatName(bs->cs, EntityNameFast(bs->ent), bs->client);

#ifdef DEBUG_AI
	// Initialize debug settings
	bs->debug_flags = 0x00000000;
	bs->use_weapon = WP_NONE;
#endif

	// Load the skill and accuracy characteristics for each weapon
	for (i = 0; i < WP_NUM_WEAPONS; i++)
		BotWeaponCharsLoad(bs, i);

	// Load the bot's reaction times
	BotReactionLoad(bs);

	// Cache the chat attack characteristic, since it's used a lot
	bs->chat_attack = (.5 <= trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_EASY_FRAGGER, 0, 1));

	// Initialize enemies
	BotAimEnemySet(bs, NULL, NULL);
	bs->goal_enemy = NULL;

	// Initialize the awareness engine
	BotAwarenessReset(bs);

	// Initialize the main goal
	BotGoalReset(bs);

	// Item tracking, timing, and statistics
	BotItemReset(bs);

	// Accuracy data for different aim zones
	BotAccuracyReset(bs);
}
示例#6
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
//	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];
	int				preTeam = 0;

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "kyle/default";
	}
	Info_SetValueForKey( userinfo, key, model );

/*	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );
*/
	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "single_1";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "personality");
	if (!*s )
	{
		Info_SetValueForKey( userinfo, "personality", "botfiles/default.jkb" );
	}
	else
	{
		Info_SetValueForKey( userinfo, "personality", s );
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
//		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
//		G_Printf( S_COLOR_RED "Start server with more 'open' slots.\n" );
		trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "UNABLE_TO_ADD_BOT")));
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
//	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	if (g_gametype.integer >= GT_TEAM)
	{
		if (team && Q_stricmp(team, "red") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_RED;
		}
		else if (team && Q_stricmp(team, "blue") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_BLUE;
		}
		else
		{
			bot->client->sess.sessionTeam = PickTeam( -1 );
		}
	}

	if (g_gametype.integer == GT_SIEGE)
	{
		bot->client->sess.siegeDesiredTeam = bot->client->sess.sessionTeam;
		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if (bot->client->sess.sessionTeam != preTeam)
	{
		trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

		if (bot->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			bot->client->sess.sessionTeam = preTeam;
		}

		if (bot->client->sess.sessionTeam == TEAM_RED)
		{
			team = "Red";
		}
		else
		{
			if (g_gametype.integer == GT_SIEGE)
			{
				if (bot->client->sess.sessionTeam == TEAM_BLUE)
				{
					team = "Blue";
				}
				else
				{
					team = "s";
				}
			}
			else
			{
				team = "Blue";
			}
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap_SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		ClientUserinfoChanged( clientNum );
	}

	if (g_gametype.integer == GT_DUEL ||
		g_gametype.integer == GT_POWERDUEL)
	{
		int loners = 0;
		int doubles = 0;

		bot->client->sess.duelTeam = 0;
		G_PowerDuelCount(&loners, &doubles, qtrue);

		if (!doubles || loners > (doubles/2))
		{
            bot->client->sess.duelTeam = DUELTEAM_DOUBLE;
		}
		else
		{
            bot->client->sess.duelTeam = DUELTEAM_LONE;
		}

		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
		SetTeam(bot, "s");
	}
	else
	{
		if( delay == 0 ) {
			ClientBegin( clientNum, qfalse );
			return;
		}		
		AddBotToSpawnQueue( clientNum, delay );
	}
}
示例#7
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				value;
	int				connectionNum;
	int				clientNum;
	int				t;
	char			*botinfo;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];
	qboolean		modelSet;

	// have the server allocate a client slot
	value = trap_BotAllocateClient();
	if ( value == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// get connection and client numbers
	connectionNum = value & 0xFFFF;
	clientNum = value >> 16;

	// set default team
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "free";
		}
	}

	// get the botinfo from bots.txt
	if (Q_stricmp(name, "random") == 0) {
		if (Q_stricmp(team, "blue") == 0)
			t = TEAM_BLUE;
		else if (Q_stricmp(team, "red") == 0)
			t = TEAM_RED;
		else
			t = TEAM_FREE;

		// get info of a randomly selected bot
		botinfo = G_GetBotInfoByNumber( G_SelectRandomBotForAdd( t ) );
	}
	else {
		// get info of the bot
		botinfo = G_GetBotInfoByName( name );
	}

	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		trap_BotFreeClient(clientNum);
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );
	Info_SetValueForKey( userinfo, "teampref", team );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	modelSet = ( *model );
	if ( !modelSet ) {
		model = DEFAULT_MODEL;
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		if (!modelSet) {
			headmodel = DEFAULT_HEAD;
		} else {
			headmodel = model;
		}
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = va("%d", DEFAULT_CLIENT_COLOR1);
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = va("%d", DEFAULT_CLIENT_COLOR2);
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Print( S_COLOR_RED "Error: bot has no aifile specified\n" );
		trap_BotFreeClient(clientNum);
		return;
	}
	Info_SetValueForKey( userinfo, "characterfile", s );

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue, connectionNum, 0 ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
示例#8
0
文件: g_client.c 项目: Exosum/ETrun
/*
===========
ClientUserInfoChanged

Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
void ClientUserinfoChanged(int clientNum) {
	gentity_t *ent;
	char      *s;
	char      oldname[MAX_STRING_CHARS];
	char      userinfo[MAX_INFO_STRING];
	gclient_t *client;
	char      *ip   = NULL; // Nico, used to store client ip
	char      *rate   = NULL; // Nico, used to store client rate
	char      *snaps   = NULL; // Nico, used to store client snaps
	char      *name = NULL; // Nico, used to store client name
	char      oldAuthToken[MAX_QPATH]; // Nico, used to see if auth token was changed

	ent    = g_entities + clientNum;
	client = ent->client;

	client->ps.clientNum = clientNum;

	// Nico, flood protection
	if (ClientIsFlooding(ent)) {
		G_LogPrintf("Dropping client %d: flooded userinfo\n", clientNum);
		trap_DropClient(clientNum, "^1You were kicked because of flooded userinfo", 0);
		return;
	}

	trap_GetUserinfo(clientNum, userinfo, sizeof (userinfo));

	// Nico, perform security checks on userinfo string
	if (!checkUserinfoString(clientNum, userinfo)) {
		return;
	}

	if (g_developer.integer || *g_log.string || g_dedicated.integer) {
		G_Printf("Userinfo: %s\n", userinfo);
	}

	// check for local client
	ip = Info_ValueForKey(userinfo, "ip");
	Q_strncpyz(client->pers.ip, ip, IP_MAX_LENGTH);
	if (ip && !strcmp(ip, "localhost")) {
		client->pers.localClient = qtrue;
		level.fLocalHost         = qtrue;
		client->sess.referee     = RL_REFEREE;
	}

	// Nico, store rate and snaps
	rate = Info_ValueForKey(userinfo, "rate");
	client->pers.rate = atoi(rate);
	snaps = Info_ValueForKey(userinfo, "snaps");
	client->pers.snaps = atoi(snaps);

	// Nico, backup old auth token
	Q_strncpyz(oldAuthToken, client->pers.authToken, sizeof (oldAuthToken));

	s = Info_ValueForKey(userinfo, "cg_uinfo");
	sscanf(s, "%i %i %i %i %s %i %i %i %i %i %i %i %i %i",
	       &client->pers.clientFlags,
	       &client->pers.clientTimeNudge,
	       &client->pers.clientMaxPackets,

	       // Nico, max FPS
	       &client->pers.maxFPS,

	       // Nico, auth Token
	       (char *)&client->pers.authToken,

	       // Nico, load view angles on load
	       &client->pers.loadViewAngles,

		   // Nico, load weapon on load
	       &client->pers.loadWeapon,

	       // Nico, load position when player dies
	       &client->pers.autoLoad,

	       // Nico, cgaz
	       &client->pers.cgaz,

	       // Nico, hideme
	       &client->pers.hideme,

	       // Nico, client auto demo record setting
	       &client->pers.autoDemo,

	       // Nico, automatically load checkpoints
	       &client->pers.autoLoadCheckpoints,

	       // Nico, persistant specLock
	       (int *)&client->sess.specLocked,

	       // Nico, keep all demos
	       &client->pers.keepAllDemos

	       );

	// Nico, check if auth token was changed
	if (oldAuthToken[0] != '\0' &&
		Q_stricmp(oldAuthToken, client->pers.authToken) &&
		client->sess.logged) {
		// Nico, auth token was changed => logout player if he was logged in
		CP("cp \"You are no longer logged in!\n\"");
		G_LogPrintf("ClientUserinfoChanged: authToken changed for client %d, forcing logout\n", clientNum);
		ent->client->sess.logged = qfalse;
	}

	client->pers.autoActivate      = (client->pers.clientFlags & CGF_AUTOACTIVATE) ? PICKUP_TOUCH : PICKUP_ACTIVATE;
	client->pers.predictItemPickup = ((client->pers.clientFlags & CGF_PREDICTITEMS) != 0);

	if (client->pers.clientFlags & CGF_AUTORELOAD) {
		client->pers.bAutoReloadAux = qtrue;
		client->pmext.bAutoReload   = qtrue;
	} else {
		client->pers.bAutoReloadAux = qfalse;
		client->pmext.bAutoReload   = qfalse;
	}

	// Nico, pmove_fixed
	client->pers.pmoveFixed = client->pers.clientFlags & CGF_PMOVEFIXED;

	// Nico, autologin
	client->pers.autoLogin = client->pers.clientFlags & CGF_AUTOLOGIN;

	//
	// Nico, name handling
	//

	// Backup old name
	Q_strncpyz(oldname, client->pers.netname, sizeof (oldname));

	// Get new name from userinfo string
	name = Info_ValueForKey(userinfo, "name");

	// Clean the new name
	ClientCleanName(name, client->pers.netname, sizeof (client->pers.netname));

	// Check it's valid
	if (CheckName(client->pers.netname) != qtrue) {
		// Invalid name, restore old name
		Q_strncpyz(client->pers.netname, oldname, sizeof (client->pers.netname));
		Info_SetValueForKey(userinfo, "name", oldname);
		trap_SetUserinfo(clientNum, userinfo);
		CPx(clientNum, "print \"^1Invalid name, name change refused\n\"");
		G_LogPrintf("Client %d name change refused\n", clientNum);
	} else {
		// Name is valid
		// Now, check if name was changed or not
		if (client->pers.connected == CON_CONNECTED && strcmp(oldname, client->pers.netname) != 0) {
			// Name was changed
			// Now, check name changes limit
			if (g_maxNameChanges.integer > -1 && client->pers.nameChanges >= g_maxNameChanges.integer) {
				// Nico, limit reached, forbid name change
				Q_strncpyz(client->pers.netname, oldname, sizeof (client->pers.netname));
				Info_SetValueForKey(userinfo, "name", oldname);
				trap_SetUserinfo(clientNum, userinfo);
				CPx(clientNum, "print \"^1You had too many namechanges\n\"");
				G_LogPrintf("Client %d name change refused\n", clientNum);
				return;
			}
			client->pers.nameChanges++;
			trap_SendServerCommand(-1, va("print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname, client->pers.netname));
		}
	}

	//
	// Nico, end of name handling
	//

	client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;

	// To communicate it to cgame
	client->ps.stats[STAT_PLAYER_CLASS] = client->sess.playerType;
	// Gordon: Not needed any more as it's in clientinfo?

	// send over a subset of the userinfo keys so other clients can
	// print scoreboards, display models, and play custom sounds

	s = va("n\\%s\\t\\%i\\c\\%i\\w\\%i\\lw\\%i\\sw\\%i\\mu\\%i\\ref\\%i\\pm\\%i\\l\\%i\\h\\%i\\cc\\%i",
	       client->pers.netname,
	       client->sess.sessionTeam,
	       client->sess.playerType,
	       client->sess.playerWeapon,
	       client->sess.latchPlayerWeapon,
	       client->sess.latchPlayerWeapon2,
	       client->sess.muted ? 1 : 0,
	       client->sess.referee,
	       client->pers.pmoveFixed ? 1 : 0, // Nico, pmove_fixed
	       client->sess.logged ? 1 : 0, // Nico, login status
	       client->pers.hideme, // Nico, hideme
		   client->sess.countryCode// Nico, country code (GeoIP)
	       );

	trap_GetConfigstring(CS_PLAYERS + clientNum, oldname, sizeof (oldname));

	trap_SetConfigstring(CS_PLAYERS + clientNum, s);

	if (!Q_stricmp(oldname, s)) {
		return;
	}

	G_LogPrintf("ClientUserinfoChanged: %i %s\n", clientNum, s);
	G_DPrintf("ClientUserinfoChanged: %i :: %s\n", clientNum, s);
}
/*
===========
ClientUserInfoChanged

Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
void ClientUserinfoChanged( int clientNum )
{
  gentity_t *ent;
  int       health;
  char      *s;
  char      model[ MAX_QPATH ];
  char      buffer[ MAX_QPATH ];
  char      filename[ MAX_QPATH ];
  char      oldname[ MAX_NAME_LENGTH ];
  char      newname[ MAX_NAME_LENGTH ];
  char      err[ MAX_STRING_CHARS ];
  qboolean  revertName = qfalse;
  gclient_t *client;
  char      c1[ MAX_INFO_STRING ];
  char      c2[ MAX_INFO_STRING ];
  char      userinfo[ MAX_INFO_STRING ];

  ent = g_entities + clientNum;
  client = ent->client;

  trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

  // check for malformed or illegal info strings
  if( !Info_Validate(userinfo) )
    strcpy( userinfo, "\\name\\badinfo" );

  // set name
  Q_strncpyz( oldname, client->pers.netname, sizeof( oldname ) );
  s = Info_ValueForKey( userinfo, "name" );
  G_ClientCleanName( s, newname, sizeof( newname ) );

  if( strcmp( oldname, newname ) )
  {
    // in case we need to revert and there's no oldname
    if( client->pers.connected != CON_CONNECTED )
        Q_strncpyz( oldname, "UnnamedPlayer", sizeof( oldname ) );

    if( client->pers.nameChangeTime &&
      ( level.time - client->pers.nameChangeTime )
      <= ( g_minNameChangePeriod.value * 1000 ) )
    {
      trap_SendServerCommand( ent - g_entities, va(
        "print \"Name change spam protection (g_minNameChangePeriod = %d)\n\"",
         g_minNameChangePeriod.integer ) );
      revertName = qtrue;
    }
    else if( g_maxNameChanges.integer > 0
      && client->pers.nameChanges >= g_maxNameChanges.integer  )
    {
      trap_SendServerCommand( ent - g_entities, va(
        "print \"Maximum name changes reached (g_maxNameChanges = %d)\n\"",
         g_maxNameChanges.integer ) );
      revertName = qtrue;
    }
    else if( !G_admin_name_check( ent, newname, err, sizeof( err ) ) )
    {
      trap_SendServerCommand( ent - g_entities, va( "print \"%s\n\"", err ) );
      revertName = qtrue;
    }

    if( revertName )
    {
      Q_strncpyz( client->pers.netname, oldname,
        sizeof( client->pers.netname ) );
      Info_SetValueForKey( userinfo, "name", oldname );
      trap_SetUserinfo( clientNum, userinfo );
    }
    else
    {
      Q_strncpyz( client->pers.netname, newname,
        sizeof( client->pers.netname ) );
      if( client->pers.connected == CON_CONNECTED )
      {
        client->pers.nameChangeTime = level.time;
        client->pers.nameChanges++;
      }
    }
  }

  if( client->sess.spectatorState == SPECTATOR_SCOREBOARD )
    Q_strncpyz( client->pers.netname, "scoreboard", sizeof( client->pers.netname ) );

  if( client->pers.connected == CON_CONNECTED )
  {
    if( strcmp( oldname, client->pers.netname ) )
    {
      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE
        " renamed to %s\n\"", oldname, client->pers.netname ) );
      G_LogPrintf( "ClientRename: %i [%s] (%s) \"%s\" -> \"%s\"\n", clientNum,
         client->pers.ip, client->pers.guid, oldname, client->pers.netname );
      G_admin_namelog_update( client, qfalse );
    }
  }

  // set max health
  health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
  client->pers.maxHealth = health;

  if( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 )
    client->pers.maxHealth = 100;

  if( client->pers.classSelection == PCL_NONE )
  {
    //This looks hacky and frankly it is. The clientInfo string needs to hold different
    //model details to that of the spawning class or the info change will not be
    //registered and an axis appears instead of the player model. There is zero chance
    //the player can spawn with the battlesuit, hence this choice.
    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_ClassConfig( PCL_HUMAN_BSUIT )->modelName,
                                              BG_ClassConfig( PCL_HUMAN_BSUIT )->skinName );
  }
  else
  {
    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_ClassConfig( client->pers.classSelection )->modelName,
                                              BG_ClassConfig( client->pers.classSelection )->skinName );

    //model segmentation
    Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg",
                 BG_ClassConfig( client->pers.classSelection )->modelName );

    if( G_NonSegModel( filename ) )
      client->ps.persistant[ PERS_STATE ] |= PS_NONSEGMODEL;
    else
      client->ps.persistant[ PERS_STATE ] &= ~PS_NONSEGMODEL;
  }
  Q_strncpyz( model, buffer, sizeof( model ) );

  // wallwalk follow
  s = Info_ValueForKey( userinfo, "cg_wwFollow" );

  if( atoi( s ) )
    client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGFOLLOW;
  else
    client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGFOLLOW;

  // wallwalk toggle
  s = Info_ValueForKey( userinfo, "cg_wwToggle" );

  if( atoi( s ) )
    client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGTOGGLE;
  else
    client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGTOGGLE;

  // teamInfo
  s = Info_ValueForKey( userinfo, "teamoverlay" );

  if( !*s || atoi( s ) != 0 )
    client->pers.teamInfo = qtrue;
  else
    client->pers.teamInfo = qfalse;

  // colors
  strcpy( c1, Info_ValueForKey( userinfo, "color1" ) );
  strcpy( c2, Info_ValueForKey( userinfo, "color2" ) );

  Q_strncpyz( client->pers.voice, Info_ValueForKey( userinfo, "voice" ),
    sizeof( client->pers.voice ) );

  // send over a subset of the userinfo keys so other clients can
  // print scoreboards, display models, and play custom sounds

  Com_sprintf( userinfo, sizeof( userinfo ),
    "n\\%s\\t\\%i\\model\\%s\\c1\\%s\\c2\\%s\\"
    "hc\\%i\\ig\\%16s\\v\\%s",
    client->pers.netname, client->pers.teamSelection, model, c1, c2,
    client->pers.maxHealth, BG_ClientListString( &client->sess.ignoreList ),
    client->pers.voice );

  trap_SetConfigstring( CS_PLAYERS + clientNum, userinfo );

  /*G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, userinfo );*/
}
示例#10
0
文件: g_bot.c 项目: ForcePush/OJPRPFZ
//[TABBot]
//added bot type varible
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname, int bottype) {
//static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
//[/TABBot]
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
//	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];
	int				preTeam = 0;
	//[DuelGuns][EnhancedImpliment]
	/*
	char			*firearm; // ** change gun model	
	qboolean		bot_dualguns = qfalse;
	int				gunoption=0;
	*/
	//[/DuelGuns][EnhancedImpliment]

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "kyle/default";
	}
	Info_SetValueForKey( userinfo, key, model );

/*	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );
*/
	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "single_1";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "personality");
	if (!*s )
	{
		Info_SetValueForKey( userinfo, "personality", "botfiles/default.jkb" );
	}
	else
	{
		Info_SetValueForKey( userinfo, "personality", s );
	}

	//[DuelGuns][EnhancedImpliment]
	/*
//	if(1)//f_dualguns.integer)
//	{
		key = "dualgun";
		s = Info_ValueForKey(botinfo, key);
		if (*s)
		{
			gunoption = atoi(s);
		}
		if(gunoption>0)
			bot_dualguns = qtrue;
//	}

	firearm = Info_ValueForKey( botinfo, "firearm");
	if (!*firearm)
	{
		Info_SetValueForKey( userinfo, "firearm", botname );
	}
	else
	{
		Info_SetValueForKey( userinfo, "firearm", firearm);
	}
	*/
	//[/DuelGuns][EnhancedImpliment]

	//[RGBSabers]
	key = "rgb_saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "255,0,0";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "rgb_saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "0,255,255";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "rgb_script1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "rgb_script2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );
	//[/RGBSabers]

	//[ClientPlugInDetect]
	//set it so that the bots are assumed to have the OJP client plugin
	//this should be CURRENT_OJPENHANCED_CLIENTVERSION
	Info_SetValueForKey( userinfo, "ojp_clientplugin", CURRENT_OJPENHANCED_CLIENTVERSION );
	//[/ClientPlugInDetect]

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
//		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
//		G_Printf( S_COLOR_RED "Start server with more 'open' slots.\n" );
		trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "UNABLE_TO_ADD_BOT")));
		return;
	}

	//[DuelGuns][EnhancedImpliment]
	/*
	if(bot_dualguns)
	{
		g_entities[clientNum].client->ps.dualguns = 1;		
	}
	*/
	//[/DuelGuns][EnhancedImpliment]

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			//[AdminSys]
			if( PickTeam(clientNum, qtrue) == TEAM_RED) {
			//if( PickTeam(clientNum) == TEAM_RED) {
			//[/AdminSys]
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
//	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );
	//[TABBot]
	Info_SetValueForKey( userinfo, "bottype", va( "%i", bottype) );
	//[/TABBot]

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	//[NewGameTypes][EnhancedImpliment]
	//if (g_gametype.integer >= GT_TEAM && g_gametype.integer != GT_RPG)
	if (g_gametype.integer >= GT_TEAM)
	//[/NewGameTypes][EnhancedImpliment]
	{
		if (team && Q_stricmp(team, "red") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_RED;
		}
		else if (team && Q_stricmp(team, "blue") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_BLUE;
		}
		else
		{
			//[AdminSys]
			bot->client->sess.sessionTeam = PickTeam( -1, qtrue );
			//bot->client->sess.sessionTeam = PickTeam( -1 );
			//[/AdminSys]
		}
	}

	if (g_gametype.integer == GT_SIEGE)
	{
		bot->client->sess.siegeDesiredTeam = bot->client->sess.sessionTeam;
		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if (bot->client->sess.sessionTeam != preTeam)
	{
		trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

		if (bot->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			bot->client->sess.sessionTeam = preTeam;
		}

		if (bot->client->sess.sessionTeam == TEAM_RED)
		{
			team = "Red";
		}
		else
		{
			if (g_gametype.integer == GT_SIEGE)
			{
				if (bot->client->sess.sessionTeam == TEAM_BLUE)
				{
					team = "Blue";
				}
				else
				{
					team = "s";
				}
			}
			else
			{
				team = "Blue";
			}
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap_SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		ClientUserinfoChanged( clientNum );
	}

	if (g_gametype.integer == GT_DUEL ||
		g_gametype.integer == GT_POWERDUEL)
	{
		int loners = 0;
		int doubles = 0;

		bot->client->sess.duelTeam = 0;
		G_PowerDuelCount(&loners, &doubles, qtrue);

		if (!doubles || loners > (doubles/2))
		{
            bot->client->sess.duelTeam = DUELTEAM_DOUBLE;
		}
		else
		{
            bot->client->sess.duelTeam = DUELTEAM_LONE;
		}

		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
		SetTeam(bot, "s");
	}
	else
	{
		if( delay == 0 ) {
			ClientBegin( clientNum, qfalse );
			//UNIQUEFIX - what's the purpose of this?
			//ClientUserinfoChanged( clientNum );
			return;
		}

		AddBotToSpawnQueue( clientNum, delay );
		//UNIQUEFIX - what's the purpose of this?
		//ClientUserinfoChanged( clientNum );
	}
}
示例#11
0
bool G_BotAdd( const char *name, team_t team, int skill, const char *behavior, bool filler )
{
	int clientNum;
	char userinfo[MAX_INFO_STRING];
	const char* s = 0;
	gentity_t *bot;
	bool autoname = false;
	bool okay;

	if ( !navMeshLoaded )
	{
		Log::Warn( "No Navigation Mesh file is available for this map" );
		return false;
	}

	// find what clientNum to use for bot
	clientNum = trap_BotAllocateClient();

	if ( clientNum < 0 )
	{
		Log::Warn( "no more slots for bot" );
		return false;
	}
	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = true;

	if ( !Q_stricmp( name, BOT_NAME_FROM_LIST ) )
	{
		name = G_BotSelectName( team );
		autoname = name != nullptr;
	}

	//default bot data
	okay = G_BotSetDefaults( clientNum, team, skill, behavior );

	// register user information
	userinfo[0] = '\0';
	Info_SetValueForKey( userinfo, "name", name ? name : "", false ); // allow defaulting
	Info_SetValueForKey( userinfo, "rate", "25000", false );
	Info_SetValueForKey( userinfo, "snaps", "20", false );
	if ( autoname )
	{
		Info_SetValueForKey( userinfo, "autoname", name, false );
	}

	//so we can connect if server is password protected
	if ( g_needpass.integer == 1 )
	{
		Info_SetValueForKey( userinfo, "password", g_password.string, false );
	}

	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ( s = ClientBotConnect( clientNum, true, team ) ) )
	{
		// won't let us join
		Log::Warn( s );
		okay = false;
	}

	if ( !okay )
	{
		G_BotDel( clientNum );
		return false;
	}

	if ( autoname )
	{
		G_BotNameUsed( team, name, true );
	}

	ClientBegin( clientNum );
	bot->pain = BotPain; // ClientBegin resets the pain function
	level.clients[clientNum].pers.isFillerBot = filler;
	G_ChangeTeam( bot, team );
	return true;
}
示例#12
0
void JMP_AdminExecuteCommand( gentity_t *pEntity, sAdminData_t *am, int trueTarget )
{
	char		zUserInfo[MAX_TOKEN_CHARS];

	char		par1[MAX_TOKEN_CHARS]; // Used
	char		par2[MAX_TOKEN_CHARS];
	char		par3[MAX_TOKEN_CHARS];
	char		par4[MAX_TOKEN_CHARS];
	char		par5[MAX_TOKEN_CHARS];

	int			clientNum = pEntity->s.number;
	int			targetNum = trueTarget;
	int			i = 0;

	trap_Argv( 1, par1, sizeof( par1 ));
	trap_Argv( 2, par2, sizeof( par2 ));
	trap_Argv( 3, par3, sizeof( par3 ));
	trap_Argv( 4, par4, sizeof( par4 ));
	trap_Argv( 5, par5, sizeof( par5 ));

	if ( targetNum == -1 )
	{
		if ( JMP_AdminNoAccess( clientNum, am->iCmdFlag ))
		{
			return;
		}

		targetNum = JMP_GetTarget( pEntity, par1 );

		if ( targetNum == -1 && !am->bAllowAll )
		{
			JMP_AdminMessage( clientNum, "You are not allowed to use this command on multiple persons" );
			return;
		}
		else if ( targetNum == -2 )
		{
			JMP_AdminMessage( clientNum, "No target has been found in your crosshair" );
			return;
		}
		else if ( targetNum == -3 )
		{
			JMP_AdminMessage( clientNum, "No target matching your specifications has been found" );
			return;
		}
		else if ( targetNum == -4 )
		{
			JMP_AdminMessage( clientNum, "Multiple matches have been found, only one is allowed" );
			return;
		}
		else if ( targetNum == clientNum && !am->bAllowSelf )
		{
#ifndef _DEBUG
			JMP_AdminMessage( clientNum, "This command may not be executed upon yourself" );
			return;
#endif
		}
		else if ( targetNum != -1 && targetNum != clientNum && sPlayerData[targetNum]->iAdminLogged && sPlayerData[targetNum]->iAdminLogged <= sPlayerData[clientNum]->iAdminLogged && JMP_AdminEvilCommand( am->iCmdFlag ))
		{
			JMP_AdminMessage( clientNum, "This command may not be executed upon an equal/higher ranked admin" );
			return;
		}
	}

	if ( targetNum == -1 )
	{
		for ( i = 0; i < MAX_CLIENTS; i++ )
		{
			if ( !sPlayerData[i]->iInUse
				|| ( i == clientNum && !am->bAllowSelf )
				|| ( i != clientNum && sPlayerData[i]->iAdminLogged && sPlayerData[i]->iAdminLogged <= sPlayerData[clientNum]->iAdminLogged && JMP_AdminEvilCommand( am->iCmdFlag )))
			{
				continue;
			}

			JMP_AdminExecuteCommand( pEntity, am, i );
		}

		return;
	}

	if ( !sPlayerData[targetNum]->iInUse )
	{
		return;
	}

	switch( am->iCmdFlag )
	{
		case DS_KICK:
		{
			if ( !strlen( par2 ))
			{
				JMP_DropPlayer( g_entities[targetNum], "has been kicked." );
			}
			else
			{
				JMP_DropPlayer( g_entities[targetNum], va( "has been kicked. (^3 Reason^7: ^1%s ^7)", ConcatArgs( 2 )));
			}

			break;
		}

		case DS_KICKBAN:
		case DS_BANRANGE:
		{
			// Initialize the ban for each type of command.
			if ( am->iCmdFlag == DS_KICKBAN )
			{
				trap_SendConsoleCommand( EXEC_APPEND, va("addip %i.%i.%i.%i", sPlayerData[targetNum]->iPlayerIP[0], sPlayerData[targetNum]->iPlayerIP[1], sPlayerData[targetNum]->iPlayerIP[2], sPlayerData[targetNum]->iPlayerIP[3] ));
			}
			else
			{
				trap_SendConsoleCommand( EXEC_APPEND, va("addip %i.%i.0.0", sPlayerData[targetNum]->iPlayerIP[0], sPlayerData[targetNum]->iPlayerIP[1] ));
			}

			// Give the message for the ban, good bye player!
			if ( !strlen( par2 ))
			{
				JMP_DropPlayer( g_entities[targetNum], "has been banned." );
			}
			else
			{
				JMP_DropPlayer( g_entities[targetNum], va( "has been banned. (^3 Reason^7: ^1%s ^7)", ConcatArgs( 2 )));
			}

			break;
		}

		case DS_SLAP:
		{
			if ( g_clients[targetNum]->stats[STAT_HEALTH] <= 0 )
			{
				JMP_AdminMessage( clientNum, "This player is not alive!" );
				break;
			}

			if ( !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_SLEEP )) && !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_PUNISH )))
			{
				int				iAngle;
				vec3_t			vDir;

				if ( g_clients[targetNum]->saberHolstered != 2 )
				{
					g_clients[targetNum]->saberHolstered = 2;
				}

				VectorNormalize2( g_clients[clientNum]->velocity, vDir );
				VectorScale( vDir, -1, vDir );
				iAngle = g_clients[clientNum]->viewangles[YAW] * ( M_PI * 2 / 360 );
				
				vDir[1] = ( sin( iAngle ) * 500 );
				vDir[0] = ( cos( iAngle ) * 500 );

				g_clients[targetNum]->velocity[0] = vDir[0];
				g_clients[targetNum]->velocity[1] = vDir[1];
				g_clients[targetNum]->velocity[2] = 500;

				g_clients[targetNum]->forceHandExtend = HANDEXTEND_KNOCKDOWN + bMovieBattles;
				g_clients[targetNum]->forceHandExtendTime = sWorldData->iTime + 3000;
				g_clients[targetNum]->forceDodgeAnim = 0;
			}

			break;
		}

		case DS_SLEEP:
		{
			if ( !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_SLEEP )) && !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_PUNISH )))
			{
				if ( g_clients[targetNum]->saberHolstered != 2 )
				{
					g_clients[targetNum]->saberHolstered = 2;
				}

				sPlayerData[targetNum]->iClientEffect |= ( 1 << F_SLEEP );
				g_clients[targetNum]->forceHandExtend = HANDEXTEND_KNOCKDOWN + bMovieBattles;
				g_clients[targetNum]->forceHandExtendTime = sWorldData->iTime + INFINITE;
				g_clients[targetNum]->forceDodgeAnim = 0;
			}

			break;
		}

		case DS_WAKE:
		{
			if ( sPlayerData[targetNum]->iClientEffect & ( 1 << F_SLEEP ))
			{
				sPlayerData[targetNum]->iClientEffect &= ~( 1 << F_SLEEP );
				g_clients[targetNum]->forceHandExtendTime = sWorldData->iTime + 500;
			}

			break;
		}

		case DS_PUNISH:
		{
			if ( !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_SLEEP )) && !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_PUNISH )))
			{
				if ( g_clients[targetNum]->saberHolstered != 2 )
				{
					g_clients[targetNum]->saberHolstered = 2;
				}

				sPlayerData[targetNum]->iClientEffect |= ( 1 << F_PUNISH );

				g_clients[targetNum]->forceHandExtend = HANDEXTEND_CHOKE + bMovieBattles;
				g_clients[targetNum]->forceHandExtendTime = sWorldData->iTime + INFINITE;
				g_clients[targetNum]->forceGripChangeMovetype = PM_FLOAT;
			}

			break;
		}

		case DS_UNPUNISH:
		{
			if ( sPlayerData[targetNum]->iClientEffect & ( 1 << F_PUNISH ))
			{
				sPlayerData[targetNum]->iClientEffect &= ~( 1 << F_PUNISH );

				g_clients[targetNum]->forceHandExtend = HANDEXTEND_NONE + bMovieBattles;
				g_clients[targetNum]->forceHandExtendTime = sWorldData->iTime;
				g_clients[targetNum]->forceGripChangeMovetype = PM_NORMAL;
			}

			break;
		}

		case DS_SILENCE:
		{
			if ( !( sPlayerData[targetNum]->iClientEffect & ( 1 << F_SILENCE )))
			{
				sPlayerData[targetNum]->iClientEffect |= ( 1 << F_SILENCE );
			}

			break;
		}

		case DS_UNSILENCE:
		{
			if ( sPlayerData[targetNum]->iClientEffect & ( 1 << F_SILENCE ))
			{
				sPlayerData[targetNum]->iClientEffect &= ~( 1 << F_SILENCE );
			}

			break;
		}

		case DS_PSAY:
		{
			if ( trap_Argc() < 2 )
			{
				JMP_AdminMessage( clientNum, "Enter a message to broadcast" );
				return;
			}

			JMP_StringEscape( ConcatArgs( 2 ), zUserInfo );
			JMP_SendCommand( targetNum, "cp", zUserInfo );
			break;
		}

		case DS_RENAME:
		{
			if ( trap_Argc() < 3 )
			{
				JMP_AdminMessage( clientNum, "Please enter a new name to set for the player" );
				return;
			}

			JMP_SendCommand( -1, "print", va( "%s ^7has been renamed to %s ^7by %s^7.\n", sPlayerData[targetNum]->zPlayerName, ConcatArgs( 2 ), sPlayerData[clientNum]->zPlayerName ));
				
			trap_GetUserinfo( targetNum, zUserInfo, MAX_INFO_STRING );
			Info_SetValueForKey( zUserInfo, "name", ConcatArgs( 2 ));
			trap_SetUserinfo( targetNum, zUserInfo );

			( *pVmMain )( GAME_CLIENT_USERINFO_CHANGED, targetNum, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
			break;
		}

		case DS_EXPLODE:
		{
			if ( g_clients[targetNum]->stats[STAT_HEALTH] <= 0 )
			{
				JMP_AdminMessage( clientNum, "This player is not alive!" );
				break;
			}

			if ( g_clients[targetNum]->clientNum == targetNum )
			{
				void ( *pCmd_Kill_f )( gentity_t * ) = ( void ( * )( gentity_t * )) dlsym( hHandle, "Cmd_Kill_f" );

				if ( pCmd_Kill_f == NULL )
				{
					JMP_AdminMessage( clientNum, "This function is not supported on this modification or operating system!" );
					return;
				}

				pCmd_Kill_f( g_entities[targetNum] );
			}

			break;
		}

		case DS_FORCETEAM:
		{
			if ( par2[0] == 'R' || par2[0] == 'r' || Q_stricmpn( par2, "red", 3 )
				|| par2[0] == 'B' || par2[0] == 'b' || Q_stricmpn( par2, "blue", 4 )
				|| par2[0] == 'S' || par2[0] == 's' || Q_stricmpn( par2, "spec", 4 ))
			{
				trap_SendConsoleCommand( EXEC_APPEND, va( "forceteam %i %s", targetNum, par2 ));
			}
			else
			{
				JMP_AdminMessage( clientNum, "The specified team is not recognized!" );
			}

			break;
		}

		case DS_CONTROLHUMAN:
		{
			if ( sPlayerData[clientNum]->bControlMaster )
			{
				if ( sPlayerData[clientNum]->iControlMaster == targetNum )
				{
					// Release him from your control.
					sPlayerData[sPlayerData[clientNum]->iControlMaster]->bControlSlave = qfalse;
					sPlayerData[sPlayerData[clientNum]->iControlMaster]->iControlMaster = 0;

					// Release self from underpression.
					sPlayerData[clientNum]->bControlMaster = qfalse;
					sPlayerData[clientNum]->iControlMaster = 0;
				}
				else
				{
					// Release previous target from your control.
					sPlayerData[sPlayerData[clientNum]->iControlMaster]->bControlSlave = qfalse;
					sPlayerData[sPlayerData[clientNum]->iControlMaster]->iControlMaster = 0;

					// Put the new target under your juristiction!
					sPlayerData[targetNum]->bControlSlave = qtrue;
					sPlayerData[targetNum]->iControlMaster = clientNum;

					// Set self to static mode.
					sPlayerData[clientNum]->bControlMaster = qtrue;
					sPlayerData[clientNum]->iControlMaster = targetNum;
				}
			}
			else
			{
				// Put the new target under your juristiction!
				sPlayerData[targetNum]->bControlSlave = qtrue;
				sPlayerData[targetNum]->iControlMaster = clientNum;

				// Set self to static mode.
				sPlayerData[clientNum]->bControlMaster = qtrue;
				sPlayerData[clientNum]->iControlMaster = targetNum;
			}

			break;
		}

		case DS_IGNORE:
		{
			if ( sPlayerData[clientNum]->iIgnoreList & ( 1 << targetNum ))
			{
				sPlayerData[clientNum]->iIgnoreList &= ~( 1 << targetNum );
				JMP_AdminMessage( clientNum, va( "%s ^7is now unignored", sPlayerData[targetNum]->zPlayerName ));
			}
			else
			{
				sPlayerData[clientNum]->iIgnoreList |= ( 1 <<  targetNum );
				JMP_AdminMessage( clientNum, va( "%s ^7is now ignored", sPlayerData[targetNum]->zPlayerName ));
			}

			break;
		}
	}
}
示例#13
0
文件: g_bot.c 项目: GenaSG/ET
static void G_AddBot( const char *name, int skill, const char *team, const char *spawnPoint, int playerClass, int playerWeapon, int characerIndex, const char *respawn, const char *scriptName, int rank, int skills[], qboolean pow ) {
#define	MAX_BOTNAMES 1024
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
//	char			*model;
	char			userinfo[MAX_INFO_STRING];

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( "wolfbot" );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%i", skill) );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient( 0 );	// Arnout: 0 means no prefered clientslot
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( PickTeam(clientNum) == TEAM_AXIS) {
			team = "red";
		} else {
			team = "blue";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	//Info_SetValueForKey( userinfo, "skill", va( "%i", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	if( spawnPoint && spawnPoint[0] ) {
		Info_SetValueForKey( userinfo, "spawnPoint", spawnPoint );
	}

	if (scriptName && scriptName[0]) {
		Info_SetValueForKey( userinfo, "scriptName", scriptName );
	}

/*	if (playerClass > 0) {
		Info_SetValueForKey( userinfo, "pClass", va("%i", playerClass) );
	}

	if (playerWeapon) {
		Info_SetValueForKey( userinfo, "pWeapon", va("%i", playerWeapon) );
	}*/
	// END Mad Doc - TDF

	key = "wolfbot";
	if (!Q_stricmp( (char *)name, key )) {
		// read the botnames file, and pick a name that doesnt exist
		fileHandle_t f;
		int len, i, j, k;
		qboolean setname = qfalse;
		char botnames[8192], *pbotnames, *listbotnames[MAX_BOTNAMES], *token, *oldpbotnames;
		int	lengthbotnames[MAX_BOTNAMES];

		len = trap_FS_FOpenFile( "botfiles/botnames.txt", &f, FS_READ );

		if (len >= 0) {
			if (len > sizeof(botnames)) {
				G_Error( "botfiles/botnames.txt is too big (max = %i)", (int)sizeof(botnames) );
			}
			memset( botnames, 0, sizeof(botnames) );
			trap_FS_Read( botnames, len, f );
			pbotnames = botnames;
			// read them in
			i = 0;
			oldpbotnames = pbotnames;
			while ((token = COM_Parse( &pbotnames ))) {
				if (!token[0]) break;
				listbotnames[i] = strstr( oldpbotnames, token );
				lengthbotnames[i] = strlen(token);
				listbotnames[i][lengthbotnames[i]] = 0;
				oldpbotnames = pbotnames;
				if (++i == MAX_BOTNAMES) break;
			}
			//
			if (i > 2) {
				j = rand() % (i-1);	// start at a random spot inthe list
				for( k = j + 1; k != j; k++ ) {
					if( k == i ) {
						k = -1;	// gets increased on next loop
						continue;
					}
					if (ClientFromName( listbotnames[k] ) == -1) {
						// found an unused name
						Info_SetValueForKey( userinfo, "name", listbotnames[k]  );
						setname = qtrue;
						break;
					}
				}
			}
			//
			trap_FS_FCloseFile( f );
		}

		if (!setname) {
			Info_SetValueForKey( userinfo, "name", va("wolfbot_%i", clientNum+1)  );
		}
	} else {
		Info_SetValueForKey( userinfo, "name", name );
	}

	// if a character was specified, put the index of that character filename in the CS_CHARACTERS table in the userinfo
	if( characerIndex != -1 ) {
		Info_SetValueForKey( userinfo, "ch", va( "%i", characerIndex ) );
	}

	// if a rank was specified, use that
/*	if (rank != -1) {
		Info_SetValueForKey(userinfo, "rank", va("%i", rank));
	}*/

	// END Mad Doc - TDF
	
	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	if( pow ) {
		bot->r.svFlags |= SVF_POW;
	}
	bot->inuse = qtrue;
	bot->aiName = bot->client->pers.netname;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ((s = ClientConnect( clientNum, qtrue, qtrue ))) {
		G_Printf( S_COLOR_RED "Unable to add bot: %s\n", s );
		return;
	}

	SetTeam( bot, (char *)team, qtrue, -1, -1, qfalse );

/*	if( skills ) {
		int i;
		
		for( i = 0; i < SK_NUM_SKILLS; i++ ) {
			bot->client->sess.skill[i] = skills[i];
		}
	}*/
	return;
}
示例#14
0
/*
===========
ClientUserInfoChanged

Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
char *ClientUserinfoChanged( int clientNum, qboolean forceName )
{
    gentity_t *ent;
    char      *s;
    char      model[ MAX_QPATH ];
    char      buffer[ MAX_QPATH ];
    char      filename[ MAX_QPATH ];
    char      oldname[ MAX_NAME_LENGTH ];
    char      newname[ MAX_NAME_LENGTH ];
    char      err[ MAX_STRING_CHARS ];
    qboolean  revertName = qfalse;
    gclient_t *client;
    char      userinfo[ MAX_INFO_STRING ];

    ent = g_entities + clientNum;
    client = ent->client;

    trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

    // check for malformed or illegal info strings
    if( !Info_Validate(userinfo) )
    {
        trap_SendServerCommand( ent - g_entities,
                                "disconnect \"illegal or malformed userinfo\n\"" );
        trap_DropClient( ent - g_entities,
                         "dropped: illegal or malformed userinfo");
        return "Illegal or malformed userinfo";
    }
    // If their userinfo overflowed, tremded is in the process of disconnecting them.
    // If we send our own disconnect, it won't work, so just return to prevent crashes later
    //  in this function. This check must come after the Info_Validate call.
    else if( !userinfo[ 0 ] )
        return "Empty (overflowed) userinfo";

    // stickyspec toggle
    s = Info_ValueForKey( userinfo, "cg_stickySpec" );
    client->pers.stickySpec = atoi( s ) != 0;

    // set name
    Q_strncpyz( oldname, client->pers.netname, sizeof( oldname ) );
    s = Info_ValueForKey( userinfo, "name" );
    G_ClientCleanName( s, newname, sizeof( newname ) );

    if( strcmp( oldname, newname ) )
    {
        if( !forceName && client->pers.namelog->nameChangeTime &&
                level.time - client->pers.namelog->nameChangeTime <=
                g_minNameChangePeriod.value * 1000 )
        {
            trap_SendServerCommand( ent - g_entities, va(
                                        "print \"Name change spam protection (g_minNameChangePeriod = %d)\n\"",
                                        g_minNameChangePeriod.integer ) );
            revertName = qtrue;
        }
        else if( !forceName && g_maxNameChanges.integer > 0 &&
                 client->pers.namelog->nameChanges >= g_maxNameChanges.integer  )
        {
            trap_SendServerCommand( ent - g_entities, va(
                                        "print \"Maximum name changes reached (g_maxNameChanges = %d)\n\"",
                                        g_maxNameChanges.integer ) );
            revertName = qtrue;
        }
        else if( !forceName && client->pers.namelog->muted )
        {
            trap_SendServerCommand( ent - g_entities,
                                    "print \"You cannot change your name while you are muted\n\"" );
            revertName = qtrue;
        }
        else if( !G_admin_name_check( ent, newname, err, sizeof( err ) ) )
        {
            trap_SendServerCommand( ent - g_entities, va( "print \"%s\n\"", err ) );
            revertName = qtrue;
        }

        if( revertName )
        {
            Q_strncpyz( client->pers.netname, *oldname ? oldname : "UnnamedPlayer",
                        sizeof( client->pers.netname ) );
            Info_SetValueForKey( userinfo, "name", oldname );
            trap_SetUserinfo( clientNum, userinfo );
        }
        else
        {
            G_CensorString( client->pers.netname, newname,
                            sizeof( client->pers.netname ), ent );
            if( !forceName && client->pers.connected == CON_CONNECTED )
            {
                client->pers.namelog->nameChangeTime = level.time;
                client->pers.namelog->nameChanges++;
            }
            if( *oldname )
            {
                G_LogPrintf( "ClientRename: %i [%s] (%s) \"%s^7\" -> \"%s^7\" \"%c%s%c^7\"\n",
                             clientNum, client->pers.ip.str, client->pers.guid,
                             oldname, client->pers.netname,
                             DECOLOR_OFF, client->pers.netname, DECOLOR_ON );
            }
        }
        G_namelog_update_name( client );
    }

    if( client->pers.classSelection == PCL_NONE )
    {
        //This looks hacky and frankly it is. The clientInfo string needs to hold different
        //model details to that of the spawning class or the info change will not be
        //registered and an axis appears instead of the player model. There is zero chance
        //the player can spawn with the battlesuit, hence this choice.
        Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_ClassConfig( PCL_HUMAN_BSUIT )->modelName,
                     BG_ClassConfig( PCL_HUMAN_BSUIT )->skinName );
    }
    else
    {
        Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_ClassConfig( client->pers.classSelection )->modelName,
                     BG_ClassConfig( client->pers.classSelection )->skinName );

        //model segmentation
        Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg",
                     BG_ClassConfig( client->pers.classSelection )->modelName );

        if( G_NonSegModel( filename ) )
            client->ps.persistant[ PERS_STATE ] |= PS_NONSEGMODEL;
        else
            client->ps.persistant[ PERS_STATE ] &= ~PS_NONSEGMODEL;
    }
    Q_strncpyz( model, buffer, sizeof( model ) );

    // wallwalk follow
    s = Info_ValueForKey( userinfo, "cg_wwFollow" );

    if( atoi( s ) )
        client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGFOLLOW;
    else
        client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGFOLLOW;

    // wallwalk toggle
    s = Info_ValueForKey( userinfo, "cg_wwToggle" );

    if( atoi( s ) )
        client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGTOGGLE;
    else
        client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGTOGGLE;

    // always sprint
    s = Info_ValueForKey( userinfo, "cg_sprintToggle" );

    if( atoi( s ) )
        client->ps.persistant[ PERS_STATE ] |= PS_SPRINTTOGGLE;
    else
        client->ps.persistant[ PERS_STATE ] &= ~PS_SPRINTTOGGLE;

    // fly speed
    s = Info_ValueForKey( userinfo, "cg_flySpeed" );

    if( *s )
        client->pers.flySpeed = atoi( s );
    else
        client->pers.flySpeed = BG_Class( PCL_NONE )->speed;

    // disable blueprint errors
    s = Info_ValueForKey( userinfo, "cg_disableBlueprintErrors" );

    if( atoi( s ) )
        client->pers.disableBlueprintErrors = qtrue;
    else
        client->pers.disableBlueprintErrors = qfalse;

    // teamInfo
    s = Info_ValueForKey( userinfo, "teamoverlay" );

    if( atoi( s ) != 0 )
    {
        // teamoverlay was enabled so we need an update
        if( client->pers.teamInfo == 0 )
            client->pers.teamInfo = 1;
    }
    else
        client->pers.teamInfo = 0;

    s = Info_ValueForKey( userinfo, "cg_unlagged" );
    if( !s[0] || atoi( s ) != 0 )
        client->pers.useUnlagged = qtrue;
    else
        client->pers.useUnlagged = qfalse;

    Q_strncpyz( client->pers.voice, Info_ValueForKey( userinfo, "voice" ),
                sizeof( client->pers.voice ) );

    // send over a subset of the userinfo keys so other clients can
    // print scoreboards, display models, and play custom sounds

    Com_sprintf( userinfo, sizeof( userinfo ),
                 "n\\%s\\t\\%i\\model\\%s\\ig\\%16s\\v\\%s",
                 client->pers.netname, client->pers.teamSelection, model,
                 Com_ClientListString( &client->sess.ignoreList ),
                 client->pers.voice );

    trap_SetConfigstring( CS_PLAYERS + clientNum, userinfo );

    /*G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, userinfo );*/

    return NULL;
}
示例#15
0
/*
===========
ClientBegin

called when a client has finished connecting, and is ready
to be placed into the level.  This will happen every level load,
and on transition between teams, but doesn't happen on respawns
============
*/
void ClientBegin( int clientNum, qboolean allowTeamReset ) {
	gentity_t	*ent;
	gclient_t	*client;
	gentity_t	*tent;
	int			flags, i;
	char		userinfo[MAX_INFO_VALUE], *modelname;

	ent = g_entities + clientNum;

	if ((ent->r.svFlags & SVF_BOT) && g_gametype.integer >= GT_TEAM)
	{
		if (allowTeamReset)
		{
			const char *team = "Red";
			int preSess;

			//SetTeam(ent, "");
			ent->client->sess.sessionTeam = PickTeam(-1);
			trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

			if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
			{
				ent->client->sess.sessionTeam = TEAM_RED;
			}

			if (ent->client->sess.sessionTeam == TEAM_RED)
			{
				team = "Red";
			}
			else
			{
				team = "Blue";
			}

			Info_SetValueForKey( userinfo, "team", team );

			trap_SetUserinfo( clientNum, userinfo );

			ent->client->ps.persistant[ PERS_TEAM ] = ent->client->sess.sessionTeam;

			preSess = ent->client->sess.sessionTeam;
			G_ReadSessionData( ent->client );
			ent->client->sess.sessionTeam = preSess;
			G_WriteClientSessionData(ent->client);
			ClientUserinfoChanged( clientNum );
			ClientBegin(clientNum, qfalse);
			return;
		}
	}

	client = level.clients + clientNum;

	if ( ent->r.linked ) {
		trap_UnlinkEntity( ent );
	}
	G_InitGentity( ent );
	ent->touch = 0;
	ent->pain = 0;
	ent->client = client;

	client->pers.connected = CON_CONNECTED;
	client->pers.enterTime = level.time;
	client->pers.teamState.state = TEAM_BEGIN;

	// save eflags around this, because changing teams will
	// cause this to happen with a valid entity, and we
	// want to make sure the teleport bit is set right
	// so the viewpoint doesn't interpolate through the
	// world to the new position
	flags = client->ps.eFlags;

	i = 0;

	while (i < NUM_FORCE_POWERS)
	{
		if (ent->client->ps.fd.forcePowersActive & (1 << i))
		{
			WP_ForcePowerStop(ent, i);
		}
		i++;
	}

	i = TRACK_CHANNEL_1;

	while (i < NUM_TRACK_CHANNELS)
	{
		if (ent->client->ps.fd.killSoundEntIndex[i-50] && ent->client->ps.fd.killSoundEntIndex[i-50] < MAX_GENTITIES && ent->client->ps.fd.killSoundEntIndex[i-50] > 0)
		{
			G_MuteSound(ent->client->ps.fd.killSoundEntIndex[i-50], CHAN_VOICE);
		}
		i++;
	}
	i = 0;

	memset( &client->ps, 0, sizeof( client->ps ) );
	client->ps.eFlags = flags;

	client->ps.hasDetPackPlanted = qfalse;

	//first-time force power initialization
	WP_InitForcePowers( ent );

	//init saber ent
	WP_SaberInitBladeData( ent );

	// First time model setup for that player.
	trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
	modelname = Info_ValueForKey (userinfo, "model");
	SetupGameGhoul2Model(client, modelname);

	if (ent->client->ghoul2)
	{
		ent->bolt_Head = trap_G2API_AddBolt(ent->client->ghoul2, 0, "cranium");
		ent->bolt_Waist = trap_G2API_AddBolt(ent->client->ghoul2, 0, "thoracic");
		ent->bolt_LArm = trap_G2API_AddBolt(ent->client->ghoul2, 0, "lradius");
		ent->bolt_RArm = trap_G2API_AddBolt(ent->client->ghoul2, 0, "rradius");
		ent->bolt_LLeg = trap_G2API_AddBolt(ent->client->ghoul2, 0, "ltibia");
		ent->bolt_RLeg = trap_G2API_AddBolt(ent->client->ghoul2, 0, "rtibia");
		ent->bolt_Motion = trap_G2API_AddBolt(ent->client->ghoul2, 0, "Motion");
	}

	// locate ent at a spawn point
	ClientSpawn( ent );

	if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
		// send event
		tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
		tent->s.clientNum = ent->s.clientNum;

		if ( g_gametype.integer != GT_TOURNAMENT  ) {
			trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStripEdString("SVINGAME", "PLENTER")) );
		}
	}
	G_LogPrintf( "ClientBegin: %i\n", clientNum );

	// count current clients and rank for scoreboard
	CalculateRanks();

	G_ClearClientLog(clientNum);
}
示例#16
0
/*
===========
ClientUserInfoChanged

Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
void ClientUserinfoChanged( int clientNum )
{
  gentity_t *ent;
  int       teamTask, teamLeader, health;
  char      *s;
  char      model[ MAX_QPATH ];
  char      buffer[ MAX_QPATH ];
  char      filename[ MAX_QPATH ];
  char      oldname[ MAX_NAME_LENGTH ];
  char      newname[ MAX_NAME_LENGTH ];
  char      err[ MAX_STRING_CHARS ];
  qboolean  revertName = qfalse;
  qboolean  showRenameMsg = qtrue;
  gclient_t *client;
  char      c1[ MAX_INFO_STRING ];
  char      c2[ MAX_INFO_STRING ];
  char      userinfo[ MAX_INFO_STRING ];
  team_t    team;

  ent = g_entities + clientNum;
  client = ent->client;

  trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

  // check for malformed or illegal info strings
  if( !Info_Validate(userinfo) )
    strcpy( userinfo, "\\name\\badinfo" );

  // check for local client
  s = Info_ValueForKey( userinfo, "ip" );

  if( !strcmp( s, "localhost" ) )
    client->pers.localClient = qtrue;

  // check the item prediction
  s = Info_ValueForKey( userinfo, "cg_predictItems" );

  if( !atoi( s ) )
    client->pers.predictItemPickup = qfalse;
  else
    client->pers.predictItemPickup = qtrue;

  // set name
  Q_strncpyz( oldname, client->pers.netname, sizeof( oldname ) );
  s = Info_ValueForKey( userinfo, "name" );
  ClientCleanName( s, newname, sizeof( newname ) );

  if( strcmp( oldname, newname ) )
  {
    if( !strlen( oldname ) && client->pers.connected != CON_CONNECTED )
      showRenameMsg = qfalse;

    // in case we need to revert and there's no oldname
    ClientCleanName( va( "%s", client->pers.netname ), oldname, sizeof( oldname ) );
 
    if( g_newbieNumbering.integer )
    {
      if( !strcmp( newname, "UnnamedPlayer" ) )
        Q_strncpyz( newname, G_NextNewbieName( ent ), sizeof( newname ) );
      if( !strcmp( oldname, "UnnamedPlayer" ) )
        Q_strncpyz( oldname, G_NextNewbieName( ent ), sizeof( oldname ) );
    }


    if( client->pers.muted )
    {
      trap_SendServerCommand( ent - g_entities,
        "print \"You cannot change your name while you are muted\n\"" );
      revertName = qtrue;
    }
    else if( client->pers.nameChangeTime &&
      ( level.time - client->pers.nameChangeTime )
      <= ( g_minNameChangePeriod.value * 1000 ) )
    {
      trap_SendServerCommand( ent - g_entities, va(
        "print \"Name change spam protection (g_minNameChangePeriod = %d)\n\"",
         g_minNameChangePeriod.integer ) );
      revertName = qtrue;
    }
    else if( g_maxNameChanges.integer > 0
      && client->pers.nameChanges >= g_maxNameChanges.integer  )
    {
      trap_SendServerCommand( ent - g_entities, va(
        "print \"Maximum name changes reached (g_maxNameChanges = %d)\n\"",
         g_maxNameChanges.integer ) );
      revertName = qtrue;
    }
    else if( !G_admin_name_check( ent, newname, err, sizeof( err ) ) )
    {
      trap_SendServerCommand( ent - g_entities, va( "print \"%s\n\"", err ) );
      revertName = qtrue;
    }
    else if( client->pers.nlocked )
    {
		trap_SendServerCommand( ent - g_entities,
			"print \"Your name is locked, you can no longer rename.\n\"" );
		revertName = qtrue;
    }
	  
    if( revertName )
    {
      Q_strncpyz( client->pers.netname, oldname,
        sizeof( client->pers.netname ) );
      Info_SetValueForKey( userinfo, "name", oldname );
      trap_SetUserinfo( clientNum, userinfo );
    }
    else
    {
      Q_strncpyz( client->pers.netname, newname,
        sizeof( client->pers.netname ) );
      Info_SetValueForKey( userinfo, "name", newname );
      trap_SetUserinfo( clientNum, userinfo );
      if( client->pers.connected == CON_CONNECTED )
      {
        client->pers.nameChangeTime = level.time;
        client->pers.nameChanges++;
      }
    }
  }

  if( client->sess.sessionTeam == TEAM_SPECTATOR )
  {
    if( client->sess.spectatorState == SPECTATOR_SCOREBOARD )
      Q_strncpyz( client->pers.netname, "scoreboard", sizeof( client->pers.netname ) );
  }

  if( client->pers.connected >= CON_CONNECTING && showRenameMsg )
  {
    if( strcmp( oldname, client->pers.netname ) )
    {
      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE
        " renamed to %s^7\n\"", oldname, client->pers.netname ) );
      if( g_decolourLogfiles.integer)
      {
        char    decoloured[ MAX_STRING_CHARS ] = "";   
        if( g_decolourLogfiles.integer == 1 )
    {
      Com_sprintf( decoloured, sizeof(decoloured), " (\"%s^7\" -> \"%s^7\")", oldname, client->pers.netname );
      G_DecolorString( decoloured, decoloured );
          G_LogPrintfColoured( "ClientRename: %i [%s] (%s) \"%s^7\" -> \"%s^7\"%s\n", clientNum,
             client->pers.ip, client->pers.guid, oldname, client->pers.netname, decoloured );
    }
    else
    {
          G_LogPrintf( "ClientRename: %i [%s] (%s) \"%s^7\" -> \"%s^7\"%s\n", clientNum,
             client->pers.ip, client->pers.guid, oldname, client->pers.netname, decoloured );
    }

      }
      else
      {
      G_LogPrintf( "ClientRename: %i [%s] (%s) \"%s^7\" -> \"%s^7\"\n", clientNum,
         client->pers.ip, client->pers.guid, oldname, client->pers.netname );
      }
      G_admin_namelog_update( client, qfalse );
    }
  }

  // set max health
  health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
  client->pers.maxHealth = health;

  if( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 )
    client->pers.maxHealth = 100;

  //hack to force a client update if the config string does not change between spawning
  if( client->pers.classSelection == PCL_NONE )
    client->pers.maxHealth = 0;

  // set model
  if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN && BG_InventoryContainsUpgrade( UP_BATTLESUIT, client->ps.stats ) )
  {
    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_HUMAN_BSUIT ),
                                              BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) );
  }
  else if( client->pers.classSelection == PCL_NONE )
  {
    //This looks hacky and frankly it is. The clientInfo string needs to hold different
    //model details to that of the spawning class or the info change will not be
    //registered and an axis appears instead of the player model. There is zero chance
    //the player can spawn with the battlesuit, hence this choice.
    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_HUMAN_BSUIT ),
                                              BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) );
  }
  else
  {
    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( client->pers.classSelection ),
                                              BG_FindSkinNameForClass( client->pers.classSelection ) );
  }
  Q_strncpyz( model, buffer, sizeof( model ) );

  //don't bother setting model type if spectating
  if( client->pers.classSelection != PCL_NONE )
  {
    //model segmentation
    Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg",
                 BG_FindModelNameForClass( client->pers.classSelection ) );

    if( G_NonSegModel( filename ) )
      client->ps.persistant[ PERS_STATE ] |= PS_NONSEGMODEL;
    else
      client->ps.persistant[ PERS_STATE ] &= ~PS_NONSEGMODEL;
  }

  // wallwalk follow
  s = Info_ValueForKey( userinfo, "cg_wwFollow" );

  if( atoi( s ) )
    client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGFOLLOW;
  else
    client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGFOLLOW;

  // wallwalk toggle
  s = Info_ValueForKey( userinfo, "cg_wwToggle" );

  if( atoi( s ) )
    client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGTOGGLE;
  else
    client->ps.persistant[ PERS_STATE ] &= ~PS_WALLCLIMBINGTOGGLE;

  // teamInfo
  s = Info_ValueForKey( userinfo, "teamoverlay" );

  if( ! *s || atoi( s ) != 0 )
    client->pers.teamInfo = qtrue;
  else
    client->pers.teamInfo = qfalse;

  s = Info_ValueForKey( userinfo, "cg_unlagged" );
  if( !s[0] || atoi( s ) != 0 )
    client->pers.useUnlagged = qtrue;
  else
    client->pers.useUnlagged = qfalse;

  // team task (0 = none, 1 = offence, 2 = defence)
  teamTask = atoi( Info_ValueForKey( userinfo, "teamtask" ) );
  // team Leader (1 = leader, 0 is normal player)
  teamLeader = client->sess.teamLeader;

  // colors
  strcpy( c1, Info_ValueForKey( userinfo, "color1" ) );
  strcpy( c2, Info_ValueForKey( userinfo, "color2" ) );

  team = client->pers.teamSelection;

  // send over a subset of the userinfo keys so other clients can
  // print scoreboards, display models, and play custom sounds

  Com_sprintf( userinfo, sizeof( userinfo ),
    "n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\"
    "hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\"
    "tl\\%d\\ig\\%16s",
    client->pers.netname, team, model, model, c1, c2,
    client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask,
    teamLeader, BG_ClientListString( &client->sess.ignoreList ) );

  trap_SetConfigstring( CS_PLAYERS + clientNum, userinfo );

  /*G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, userinfo );*/
}
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
    int				clientNum;
    char			*botinfo;
    gentity_t		*bot;
    char			*key;
    char			*s;
    char			*botname;
    char			*model;
    char			*headmodel;
    char			*logo;
    char			userinfo[MAX_INFO_STRING];

    // get the botinfo from bots.txt
    botinfo = G_GetBotInfoByName( name );
    if ( !botinfo ) {
        G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
        return;
    }

    // create the bot's userinfo
    userinfo[0] = '\0';

    botname = Info_ValueForKey( botinfo, "funname" );
    if( !botname[0] ) {
        botname = Info_ValueForKey( botinfo, "name" );
    }
    // check for an alternative name
    if (altname && altname[0]) {
        botname = altname;
    }
    Info_SetValueForKey( userinfo, "name", botname );
    Info_SetValueForKey( userinfo, "rate", "25000" );
    Info_SetValueForKey( userinfo, "snaps", "20" );
    Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

    if ( skill >= 1 && skill < 2 ) {
        Info_SetValueForKey( userinfo, "handicap", "50" );
    }
    else if ( skill >= 2 && skill < 3 ) {
        Info_SetValueForKey( userinfo, "handicap", "70" );
    }
    else if ( skill >= 3 && skill < 4 ) {
        Info_SetValueForKey( userinfo, "handicap", "90" );
    }

    key = "spraylogo";
    logo = Info_ValueForKey( botinfo, key);
    if ( !*logo ) {
        logo = "15_padlogo";
    }
    Info_SetValueForKey( userinfo, key, logo );

    key = "model";
    model = Info_ValueForKey( botinfo, key );
    if ( !*model ) {
        model = "padman/default";
    }
    else if ( g_gametype.integer < GT_TEAM ) {
        // If a team is given, but we're not in a team-gametype
        // this is caused by the ui, so we're forcing a skin.
        // This is rather nasty..

        // TODO: Check whether the resulting model exists

        if ( *team ) {
            char *color = NULL;
            if ( !Q_stricmp( team, "red" )
                    || !Q_stricmp( team, "r" )
                    || !Q_stricmp( team, "0" ) ) {
                color = "red";
            }
            else if ( !Q_stricmp( team, "blue" )
                      || !Q_stricmp( team, "b" )
                      || !Q_stricmp( team, "1" ) ) {
                color = "blue";
            }

            // user decided to add a skin and specify a team
            // use skin color (way easier to implement)
            // FIXME: Explicitly search for color after ('/' or) '_'
            if ( strstr( model, "_red" ) || strstr( model, "_blue" ) ) {
                color = NULL;
            }

            if ( color ) {
                if ( strrchr( model, '/' ) ) {
                    // model is a skin already, append colorname to skin
                    // fatpad/fatty _red
                    model = va( "%s_%s", model, color );
                }
                else {
                    // model is a "basemodel", append skin
                    // fatpad /red
                    model = va( "%s/%s", model, color );
                }
            }
        }
    }

    Info_SetValueForKey( userinfo, key, model );
    key = "team_model";
    Info_SetValueForKey( userinfo, key, model );

    key = "headmodel";
    headmodel = Info_ValueForKey( botinfo, key );
    if ( !*headmodel ) {
        headmodel = model;
    }
    Info_SetValueForKey( userinfo, key, headmodel );
    key = "team_headmodel";
    Info_SetValueForKey( userinfo, key, headmodel );

    key = "gender";
    s = Info_ValueForKey( botinfo, key );
    if ( !*s ) {
        s = "male";
    }
    Info_SetValueForKey( userinfo, "sex", s );

    key = "color1";
    s = Info_ValueForKey( botinfo, key );
    if ( !*s ) {
        s = "4";
    }
    Info_SetValueForKey( userinfo, key, s );

    key = "color2";
    s = Info_ValueForKey( botinfo, key );
    if ( !*s ) {
        s = "5";
    }
    Info_SetValueForKey( userinfo, key, s );

    s = Info_ValueForKey(botinfo, "aifile");
    if (!*s ) {
        trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
        return;
    }

    // have the server allocate a client slot
    clientNum = trap_BotAllocateClient();
    if ( clientNum == -1 ) {
        G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
        G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
        return;
    }

    // initialize the bot settings
    if( !team || !*team ) {
        if( g_gametype.integer >= GT_TEAM ) {
            if( PickTeam(clientNum) == TEAM_RED) {
                team = "red";
            }
            else {
                team = "blue";
            }
        }
        else {
            team = "red";
        }
    }
    Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
    Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
    Info_SetValueForKey( userinfo, "team", team );

    bot = &g_entities[ clientNum ];
    bot->r.svFlags |= SVF_BOT;
    bot->inuse = qtrue;

    // register the userinfo
    trap_SetUserinfo( clientNum, userinfo );

    // have it connect to the game as a normal client
    if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
        return;
    }

    if( delay == 0 ) {
        ClientBegin( clientNum );
        return;
    }

    AddBotToSpawnQueue( clientNum, delay );
}
示例#18
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay ) {
	int clientNum;
	char            *botinfo;
	char            *key;
	char            *s;
	char            *botname;
	char            *model;
	char userinfo[MAX_INFO_STRING];

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		trap_BotFreeClient( clientNum );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if ( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );

	if ( skill == 1 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	} else if ( skill == 2 )   {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	} else if ( skill == 3 )   {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "visor/default";
	}
	Info_SetValueForKey( userinfo, key, model );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey( botinfo, "aifile" );
	if ( !*s ) {
		trap_Print( S_COLOR_RED "Error: bot has no aifile specified\n" );
		trap_BotFreeClient( clientNum );
		return;
	}
	Info_SetValueForKey( userinfo, "characterfile", s );

	if ( !team || !*team ) {
		if ( g_gametype.integer == GT_TEAM || g_gametype.integer == GT_CTF ) {
			if ( PickTeam( clientNum ) == TEAM_RED ) {
				team = "red";
			} else {
				team = "blue";
			}
		} else {
			team = "red";
		}
	}
	Info_SetValueForKey( userinfo, "team", team );

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if ( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
示例#19
0
文件: g_bot.c 项目: aufau/SaberMod
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
//	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	/*
	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}
	*/

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "visor/default";
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

/*	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );
*/
	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "5";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "personality");
	if (!*s )
	{
		Info_SetValueForKey( userinfo, "personality", "botfiles/default.jkb" );
	}
	else
	{
		Info_SetValueForKey( userinfo, "personality", s );
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
//		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
//		G_Printf( S_COLOR_RED "Start server with more 'open' slots.\n" );
		trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "UNABLE_TO_ADD_BOT")));
		return;
	}

	// initialize the bot settings
	if( !team || !*team	|| ( Q_stricmp(team, "red") && Q_stricmp(team, "blue") ) ) {
		team = "";
	}


//	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum, qfalse );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
示例#20
0
文件: g_bot.c 项目: titityy/reaction
/*
===============
G_AddBot
===============
*/
static void G_AddBot(const char *name, float skill, const char *team, int delay, char *altname)
{
	int clientNum;
	char *botinfo;
	gentity_t *bot;
	char *s;
	char *botname;
	char *model;
	char *headmodel;
	char userinfo[MAX_INFO_STRING];
	weapon_t tpWeapon = WP_M4;
	holdable_t tpItem = HI_LASER;

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName(name);
	if (!botinfo) {
		G_Printf(S_COLOR_RED "Error: Bot '%s' not defined\n", name);
		return;
	}
	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey(botinfo, "funname");
	if (!botname[0]) {
		botname = Info_ValueForKey(botinfo, "name");
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey(userinfo, "name", botname);
	Info_SetValueForKey(userinfo, "rate", "25000");
	Info_SetValueForKey(userinfo, "snaps", "20");
	Info_SetValueForKey(userinfo, "skill", va("%1.2f", skill));

	if (skill >= 1 && skill < 2) {
		Info_SetValueForKey(userinfo, "handicap", "50");
	} else if (skill >= 2 && skill < 3) {
		Info_SetValueForKey(userinfo, "handicap", "70");
	} else if (skill >= 3 && skill < 4) {
		Info_SetValueForKey(userinfo, "handicap", "90");
	}

	model = Info_ValueForKey(botinfo, "model");
	if (!*model) {
		// Elder: changed to our default
		model = "reactionmale/default";
	}

	Info_SetValueForKey(userinfo, "model", model);

	Info_SetValueForKey(userinfo, "team_model", model);

	headmodel = Info_ValueForKey(botinfo, "headmodel");
	if (!*headmodel) {
		headmodel = model;
	}
	Info_SetValueForKey(userinfo, "headmodel", headmodel);

	Info_SetValueForKey(userinfo, "team_headmodel", headmodel);

	s = Info_ValueForKey(botinfo, "gender");
	if (!*s) {
		s = "male";
	}
	Info_SetValueForKey(userinfo, "sex", s);

	s = Info_ValueForKey(botinfo, "color1");
	if (!*s) {
		s = "4";
	}
	Info_SetValueForKey(userinfo, "color1", s);

	s = Info_ValueForKey(botinfo, "color2");
	if (!*s) {
		s = "5";
	}
	Info_SetValueForKey(userinfo, "color2", s);

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s) {
		trap_Printf(S_COLOR_RED "Error: bot has no aifile specified\n");
		return;
	}
	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if (clientNum == -1) {
		G_Printf(S_COLOR_RED "Unable to add bot.  All player slots are in use.\n");
		G_Printf(S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n");
		return;
	}
	// initialize the bot settings
	if (!team || !*team) {
		if (g_gametype.integer >= GT_TEAM) {
			if (PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			} else {
				team = "blue";
			}
		} else {
			team = "red";
		}
	}
	Info_SetValueForKey(userinfo, "characterfile", Info_ValueForKey(botinfo, "aifile"));
	Info_SetValueForKey(userinfo, "skill", va("%5.2f", skill));
	Info_SetValueForKey(userinfo, "team", team);

	if (g_gametype.integer == GT_TEAMPLAY) {
		//Makro - load custom weapon/item from bot file
		tpWeapon = CharToWeapon(Info_ValueForKey(botinfo, "weapon"), WP_M4);
		tpItem = CharToItem(Info_ValueForKey(botinfo, "item"), HI_LASER);
	}
	Info_SetValueForKey(userinfo, "tpw", va("%i", tpWeapon - WP_NONE));
	Info_SetValueForKey(userinfo, "tpi", va("%i", tpItem - HI_NONE));

	bot = &g_entities[clientNum];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo(clientNum, userinfo);

	// have it connect to the game as a normal client
	if (ClientConnect(clientNum, qtrue, qtrue)) {
		return;
	}

	if (delay == 0) {
		ClientBegin(clientNum);
		//Makro - load custom weapon/item from bot file
		if (g_gametype.integer == GT_TEAMPLAY) {
			bot->client->teamplayWeapon = tpWeapon;
			bot->client->teamplayItem = tpItem;
		}
		return;
	}

	AddBotToSpawnQueue(clientNum, delay);

	//Makro - load custom weapon/item from bot file
	if (g_gametype.integer == GT_TEAMPLAY) {
		bot->client->teamplayWeapon = tpWeapon;
		bot->client->teamplayItem = tpItem;
	}
}
示例#21
0
文件: g_bot.c 项目: eserozvataf/q3now
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	int				teamNum;
	int				botinfoNum;
	char			*botinfo;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// set default team
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "free";
		}
	}

	// get the botinfo from bots.txt
	if ( Q_stricmp( name, "random" ) == 0 ) {
		if ( Q_stricmp( team, "red" ) == 0 || Q_stricmp( team, "r" ) == 0 ) {
			teamNum = TEAM_RED;
		}
		else if ( Q_stricmp( team, "blue" ) == 0 || Q_stricmp( team, "b" ) == 0 ) {
			teamNum = TEAM_BLUE;
		}
		else if ( !Q_stricmp( team, "spectator" ) || !Q_stricmp( team, "s" ) ) {
			teamNum = TEAM_SPECTATOR;
		}
		else {
			teamNum = TEAM_FREE;
		}

		botinfoNum = G_SelectRandomBotInfo( teamNum );

		if ( botinfoNum < 0 ) {
			G_Printf( S_COLOR_RED "Error: Cannot add random bot, no bot info available.\n" );
			trap_BotFreeClient( clientNum );
			return;
		}

		botinfo = G_GetBotInfoByNumber( botinfoNum );
	}
	else {
		botinfo = G_GetBotInfoByName( name );
	}

	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		trap_BotFreeClient( clientNum );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );
	Info_SetValueForKey( userinfo, "teampref", team );

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "visor/default";
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "5";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Print( S_COLOR_RED "Error: bot has no aifile specified\n" );
		trap_BotFreeClient( clientNum );
		return;
	}
	Info_SetValueForKey( userinfo, "characterfile", s );

	// don't send tinfo to bots, they don't parse it
	Info_SetValueForKey( userinfo, "teamoverlay", "0" );

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
示例#22
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
                G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "sarge/default";
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "5";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
                G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
                G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
                return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM && g_ffa_gt!=1) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
示例#23
0
/**
 * Add one bot into a team
 * @param name [string] bot's name
 * @param team [team_t] alien or human
 */
qboolean G_BotAdd( char *name, team_t team ) {
	int i;
	int clientNum;
	char userinfo[MAX_INFO_STRING];
	int reservedSlots = 0;
	gentity_t *ent;
    namelog_t *namelog;
    char name_s[ MAX_NAME_LENGTH ];
    char name_tmp_s[ MAX_NAME_LENGTH ] = "";
	
	reservedSlots = trap_Cvar_VariableIntegerValue( "sv_privateclients" );

	//If bot name does not contains [BOT], prepend it.
	if(g_bot_tagname.integer == 1) {
		G_DecolorString(name, name_s, MAX_NAME_LENGTH);
		if (! (Com_StringContains(name_s, "[BOT]", 0))) {
			if(team == TEAM_HUMANS) {
				strcat(name_tmp_s, "^4[BOT] ");
			} else if(team == TEAM_ALIENS) {
				strcat(name_tmp_s, "^1[BOT] ");
			}
			strcat(name_tmp_s, name);
			strcpy(name, name_tmp_s);
		}
	}
    // LEPE: check if no player/bot exists with that name	
    G_SanitiseString(name, name_s, sizeof(name_s) );
    for( namelog = level.namelogs; namelog; namelog = namelog->next ) {
        if( namelog->slot >= 0 ) {
            for( i = 0; i < MAX_NAMELOG_NAMES && namelog->name[ i ][ 0 ]; i++ ) {
                G_SanitiseString(namelog->name[ i ], name_tmp_s, sizeof(name_tmp_s) );
                if( i == namelog->nameOffset && namelog->slot > -1 && !strcmp( name_s, name_tmp_s ) ) {
                    trap_Print("Nick already exists\n");
                    return qfalse;
                }
            }
        }
    }
	// find what clientNum to use for bot
	// LEPE: clientNum calculation was modified to prevent player hijacking
        // We will assign slots from maxclients - 1 to maxclients - reservedSlots - 1
	clientNum = -1;
	for( i = level.maxclients - 1; i > level.maxclients - reservedSlots - 1; i-- ) {
		if( !g_entities[i].inuse ) {
			clientNum = i;
			break;
		}
	}
	if(clientNum == -1)
	{
		trap_Print("Error: Bots were not assigned correctly\n"); //LEPE
		return qfalse;
	}
	if(clientNum < level.maxclients - reservedSlots - 1) 
	{
		trap_Print("no more slots for bot\n");
		return qfalse;
	}
	
	ent = &g_entities[ clientNum ];
	ent->inuse = qtrue;
	ent->bot = (bot_t *)BG_Alloc( sizeof(bot_t) );
//	ent->bot->path.crumb = BG_Alloc( sizeof(level.paths) );
	
	ent->r.svFlags |= SVF_BOT;
	// register user information
	userinfo[0] = '\0';
	Info_SetValueForKey( userinfo, "name", name );
	Info_SetValueForKey( userinfo, "rate", "25000" ); //25000
	Info_SetValueForKey( userinfo, "snaps", "40" );
	//so we can connect if server is password protected
	if(g_needpass.integer == 1) {
		  Info_SetValueForKey( userinfo, "password", g_password.string);
	}
	trap_SetUserinfo( clientNum, userinfo );
	
	// have it connect to the game as a normal client
	if(ClientConnect(clientNum, qtrue) != NULL ) {
		G_Printf("Something weird happened. Bot was not added.");
		// won't let us join
		return qfalse;
	}
	ClientBegin( clientNum );
    G_BotDebug(ent, BOT_VERB_IMPORTANT, BOT_DEBUG_GENERAL, "Bot Added\n");
	G_ChangeTeam( ent, team );
	BotInit( ent );
    if(team == TEAM_HUMANS) {
		BotInitHuman( ent );
		level.humanBots++;
    } else if(team == TEAM_ALIENS) {
		BotInitAlien( ent );
		level.alienBots++;
	}
	//TODO: load profile
	return qtrue;
}