void G_namelog_update_name( gclient_t *client ) { char n1[ MAX_NAME_LENGTH ], n2[ MAX_NAME_LENGTH ]; namelog_t *n = client->pers.namelog; if( n->name[ n->nameOffset ][ 0 ] ) { G_SanitiseString( client->pers.netname, n1, sizeof( n1 ) ); G_SanitiseString( n->name[ n->nameOffset ], n2, sizeof( n2 ) ); if( strcmp( n1, n2 ) != 0 ) n->nameOffset = ( n->nameOffset + 1 ) % MAX_NAMELOG_NAMES; } strcpy( n->name[ n->nameOffset ], client->pers.netname ); }
void G_namelog_update_name( gclient_t *client ) { int i; char n1[ MAX_NAME_LENGTH ], n2[ MAX_NAME_LENGTH ]; namelog_t *n = client->pers.namelog; G_SanitiseString( client->pers.netname, n1, sizeof( n1 ) ); for( i = 0; i < MAX_NAMELOG_NAMES && n->name[ i ][ 0 ]; i++ ) { G_SanitiseString( n->name[ i ], n2, sizeof( n2 ) ); if( !strcmp( n1, n2 ) ) return; } strcpy( n->name[ n->nameChanges % MAX_NAMELOG_NAMES ], client->pers.netname ); }
/* ================== G_ClientNumbersFromString Sets plist to an array of integers that represent client numbers that have names that are a partial match for s. Returns number of matching clientids up to max. ================== */ int G_ClientNumbersFromString( char *s, int *plist, int max ) { gclient_t *p; int i, found = 0; char n2[ MAX_NAME_LENGTH ] = {""}; char s2[ MAX_NAME_LENGTH ] = {""}; if( max == 0 ) return 0; // if a number is provided, it is a clientnum for( i = 0; s[ i ] && isdigit( s[ i ] ); i++ ); if( !s[ i ] ) { i = atoi( s ); if( i >= 0 && i < level.maxclients ) { p = &level.clients[ i ]; if( p->pers.connected != CON_DISCONNECTED ) { *plist = i; return 1; } } // we must assume that if only a number is provided, it is a clientNum return 0; } // now look for name matches G_SanitiseString( s, s2, sizeof( s2 ) ); if( strlen( s2 ) < 1 ) return 0; for( i = 0; i < level.maxclients && found < max; i++ ) { p = &level.clients[ i ]; if( p->pers.connected == CON_DISCONNECTED ) { continue; } G_SanitiseString( p->pers.netname, n2, sizeof( n2 ) ); if( strstr( n2, s2 ) ) { *plist++ = i; found++; } } return found; }
/* ================== G_ClientNumberFromString Returns a player number for either a number or name string Returns -1 if invalid ================== */ int G_ClientNumberFromString( char *s ) { gclient_t *cl; int i; char s2[ MAX_NAME_LENGTH ]; char n2[ MAX_NAME_LENGTH ]; // numeric values are just slot numbers for( i = 0; s[ i ] && isdigit( s[ i ] ); i++ ); if( !s[ i ] ) { i = atoi( s ); if( i < 0 || i >= level.maxclients ) return -1; cl = &level.clients[ i ]; if( cl->pers.connected == CON_DISCONNECTED ) return -1; return i; } // check for a name match G_SanitiseString( s, s2, sizeof( s2 ) ); for( i = 0, cl = level.clients; i < level.maxclients; i++, cl++ ) { if( cl->pers.connected == CON_DISCONNECTED ) continue; G_SanitiseString( cl->pers.netname, n2, sizeof( n2 ) ); if( !strcmp( n2, s2 ) ) return i; } return -1; }
void G_adminGlobalSetWho(char *who, int skiparg) { G_SayArgv(1 + skiparg, who, MAX_STRING_CHARS); G_SanitiseString(who, who, MAX_STRING_CHARS); }
/** * 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; }