#include "g_local.h"
Include dependency graph for g_client.c:

Go to the source code of this file.
|
|
Definition at line 142 of file g_client.c. |
|
|
Definition at line 142 of file g_client.c. |
|
|
Definition at line 350 of file g_client.c. References gentity_t, level, gentity_s::nextthink, gentity_s::physicsObject, entityState_s::pos, gentity_s::s, level_locals_t::time, gentity_s::timestamp, trap_UnlinkEntity(), and trajectory_t::trBase. 00350 {
00351 if ( level.time - ent->timestamp > 6500 ) {
00352 // the body ques are never actually freed, they are just unlinked
00353 trap_UnlinkEntity( ent );
00354 ent->physicsObject = qfalse;
00355 return;
00356 }
00357 ent->nextthink = level.time + 100;
00358 ent->s.pos.trBase[2] -= 1;
00359 }
|
Here is the call graph for this function:

|
|
Definition at line 993 of file g_client.c. References CalculateRanks(), gentity_s::client, entityState_s::clientNum, level_locals_t::clients, ClientSpawn(), clientPersistant_t::connected, playerState_s::eFlags, clientPersistant_t::enterTime, EV_PLAYER_TELEPORT_IN, g_entities, g_gametype, G_InitGentity(), G_LogPrintf(), G_TempEntity(), gclient_t, gentity_t, level, entityShared_t::linked, memset(), clientPersistant_t::netname, playerState_s::origin, gentity_s::pain, gclient_s::pers, gclient_s::ps, gentity_s::r, gentity_s::s, S_COLOR_WHITE, gclient_s::sess, clientSession_t::sessionTeam, playerTeamState_t::state, clientPersistant_t::teamState, level_locals_t::time, gentity_s::touch, trap_SendServerCommand(), trap_UnlinkEntity(), and va(). Referenced by AddBotToSpawnQueue(), G_AddBot(), G_CheckBotSpawn(), SetTeam(), SpectatorClientEndFrame(), and vmMain(). 00993 {
00994 gentity_t *ent;
00995 gclient_t *client;
00996 gentity_t *tent;
00997 int flags;
00998
00999 ent = g_entities + clientNum;
01000
01001 client = level.clients + clientNum;
01002
01003 if ( ent->r.linked ) {
01004 trap_UnlinkEntity( ent );
01005 }
01006 G_InitGentity( ent );
01007 ent->touch = 0;
01008 ent->pain = 0;
01009 ent->client = client;
01010
01011 client->pers.connected = CON_CONNECTED;
01012 client->pers.enterTime = level.time;
01013 client->pers.teamState.state = TEAM_BEGIN;
01014
01015 // save eflags around this, because changing teams will
01016 // cause this to happen with a valid entity, and we
01017 // want to make sure the teleport bit is set right
01018 // so the viewpoint doesn't interpolate through the
01019 // world to the new position
01020 flags = client->ps.eFlags;
01021 memset( &client->ps, 0, sizeof( client->ps ) );
01022 client->ps.eFlags = flags;
01023
01024 // locate ent at a spawn point
01025 ClientSpawn( ent );
01026
01027 if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
01028 // send event
01029 tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
01030 tent->s.clientNum = ent->s.clientNum;
01031
01032 if ( g_gametype.integer != GT_TOURNAMENT ) {
01033 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname) );
01034 }
01035 }
01036 G_LogPrintf( "ClientBegin: %i\n", clientNum );
01037
01038 // count current clients and rank for scoreboard
01039 CalculateRanks();
01040 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 610 of file g_client.c. References ch, ColorIndex, in, p, and Q_strncpyz(). Referenced by ClientUserinfoChanged(). 00610 {
00611 int len, colorlessLen;
00612 char ch;
00613 char *p;
00614 int spaces;
00615
00616 //save room for trailing null byte
00617 outSize--;
00618
00619 len = 0;
00620 colorlessLen = 0;
00621 p = out;
00622 *p = 0;
00623 spaces = 0;
00624
00625 while( 1 ) {
00626 ch = *in++;
00627 if( !ch ) {
00628 break;
00629 }
00630
00631 // don't allow leading spaces
00632 if( !*p && ch == ' ' ) {
00633 continue;
00634 }
00635
00636 // check colors
00637 if( ch == Q_COLOR_ESCAPE ) {
00638 // solo trailing carat is not a color prefix
00639 if( !*in ) {
00640 break;
00641 }
00642
00643 // don't allow black in a name, period
00644 if( ColorIndex(*in) == 0 ) {
00645 in++;
00646 continue;
00647 }
00648
00649 // make sure room in dest for both chars
00650 if( len > outSize - 2 ) {
00651 break;
00652 }
00653
00654 *out++ = ch;
00655 *out++ = *in++;
00656 len += 2;
00657 continue;
00658 }
00659
00660 // don't allow too many consecutive spaces
00661 if( ch == ' ' ) {
00662 spaces++;
00663 if( spaces > 3 ) {
00664 continue;
00665 }
00666 }
00667 else {
00668 spaces = 0;
00669 }
00670
00671 if( len > outSize - 1 ) {
00672 break;
00673 }
00674
00675 *out++ = ch;
00676 colorlessLen++;
00677 len++;
00678 }
00679 *out = 0;
00680
00681 // don't allow empty names
00682 if( *p == 0 || colorlessLen == 0 ) {
00683 Q_strncpyz( p, "UnnamedPlayer", outSize );
00684 }
00685 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 903 of file g_client.c. References BroadcastTeamChange(), CalculateRanks(), gentity_s::client, level_locals_t::clients, ClientUserinfoChanged(), clientPersistant_t::connected, G_BotConnect(), g_entities, G_FilterPacket(), g_gametype, G_InitSessionData(), G_LogPrintf(), g_password, G_ReadSessionData(), gclient_t, gentity_t, GT_TEAM, Info_ValueForKey(), gentity_s::inuse, level, memset(), level_locals_t::newSession, gclient_s::pers, Q_stricmp(), gentity_s::r, S_COLOR_WHITE, strcmp(), vmCvar_t::string, entityShared_t::svFlags, trap_GetUserinfo(), trap_SendServerCommand(), va(), and value. Referenced by G_AddBot(), and vmMain(). 00903 {
00904 char *value;
00905 // char *areabits;
00906 gclient_t *client;
00907 char userinfo[MAX_INFO_STRING];
00908 gentity_t *ent;
00909
00910 ent = &g_entities[ clientNum ];
00911
00912 trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
00913
00914 // IP filtering
00915 // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
00916 // recommanding PB based IP / GUID banning, the builtin system is pretty limited
00917 // check to see if they are on the banned IP list
00918 value = Info_ValueForKey (userinfo, "ip");
00919 if ( G_FilterPacket( value ) ) {
00920 return "You are banned from this server.";
00921 }
00922
00923 // we don't check password for bots and local client
00924 // NOTE: local client <-> "ip" "localhost"
00925 // this means this client is not running in our current process
00926 if ( !( ent->r.svFlags & SVF_BOT ) && (strcmp(value, "localhost") != 0)) {
00927 // check for a password
00928 value = Info_ValueForKey (userinfo, "password");
00929 if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) &&
00930 strcmp( g_password.string, value) != 0) {
00931 return "Invalid password";
00932 }
00933 }
00934
00935 // they can connect
00936 ent->client = level.clients + clientNum;
00937 client = ent->client;
00938
00939 // areabits = client->areabits;
00940
00941 memset( client, 0, sizeof(*client) );
00942
00943 client->pers.connected = CON_CONNECTING;
00944
00945 // read or initialize the session data
00946 if ( firstTime || level.newSession ) {
00947 G_InitSessionData( client, userinfo );
00948 }
00949 G_ReadSessionData( client );
00950
00951 if( isBot ) {
00952 ent->r.svFlags |= SVF_BOT;
00953 ent->inuse = qtrue;
00954 if( !G_BotConnect( clientNum, !firstTime ) ) {
00955 return "BotConnectfailed";
00956 }
00957 }
00958
00959 // get and distribute relevent paramters
00960 G_LogPrintf( "ClientConnect: %i\n", clientNum );
00961 ClientUserinfoChanged( clientNum );
00962
00963 // don't do the "xxx connected" messages if they were caried over from previous level
00964 if ( firstTime ) {
00965 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " connected\n\"", client->pers.netname) );
00966 }
00967
00968 if ( g_gametype.integer >= GT_TEAM &&
00969 client->sess.sessionTeam != TEAM_SPECTATOR ) {
00970 BroadcastTeamChange( client, -1 );
00971 }
00972
00973 // count current clients and rank for scoreboard
00974 CalculateRanks();
00975
00976 // for statistics
00977 // client->areabits = areabits;
00978 // if ( !client->areabits )
00979 // client->areabits = G_Alloc( (trap_AAS_PointReachabilityAreaIndex( NULL ) + 7) / 8 );
00980
00981 return NULL;
00982 }
|
Here is the call graph for this function:

|
|
Definition at line 1276 of file g_client.c. References BotAIShutdownClient(), CalculateRanks(), gentity_s::classname, gentity_s::client, entityState_s::clientNum, level_locals_t::clients, ClientUserinfoChanged(), CON_CONNECTED, clientPersistant_t::connected, CS_PLAYERS, EV_PLAYER_TELEPORT_OUT, g_entities, g_gametype, G_LogPrintf(), G_RemoveQueuedBotBegin(), G_TempEntity(), gentity_t, i, level_locals_t::intermissiontime, gentity_s::inuse, level, level_locals_t::maxclients, entityState_s::modelindex, playerState_s::origin, gclient_s::pers, playerState_s::persistant, gclient_s::ps, qfalse, gentity_s::r, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, level_locals_t::sortedClients, SPECTATOR_FOLLOW, clientSession_t::spectatorClient, clientSession_t::spectatorState, StopFollowing(), entityShared_t::svFlags, TEAM_SPECTATOR, TossClientCubes(), TossClientItems(), trap_SetConfigstring(), trap_UnlinkEntity(), level_locals_t::warmupTime, and clientSession_t::wins. Referenced by vmMain(). 01276 {
01277 gentity_t *ent;
01278 gentity_t *tent;
01279 int i;
01280
01281 // cleanup if we are kicking a bot that
01282 // hasn't spawned yet
01283 G_RemoveQueuedBotBegin( clientNum );
01284
01285 ent = g_entities + clientNum;
01286 if ( !ent->client ) {
01287 return;
01288 }
01289
01290 // stop any following clients
01291 for ( i = 0 ; i < level.maxclients ; i++ ) {
01292 if ( level.clients[i].sess.sessionTeam == TEAM_SPECTATOR
01293 && level.clients[i].sess.spectatorState == SPECTATOR_FOLLOW
01294 && level.clients[i].sess.spectatorClient == clientNum ) {
01295 StopFollowing( &g_entities[i] );
01296 }
01297 }
01298
01299 // send effect if they were completely connected
01300 if ( ent->client->pers.connected == CON_CONNECTED
01301 && ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
01302 tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT );
01303 tent->s.clientNum = ent->s.clientNum;
01304
01305 // They don't get to take powerups with them!
01306 // Especially important for stuff like CTF flags
01307 TossClientItems( ent );
01308 #ifdef MISSIONPACK
01309 TossClientPersistantPowerups( ent );
01310 if( g_gametype.integer == GT_HARVESTER ) {
01311 TossClientCubes( ent );
01312 }
01313 #endif
01314
01315 }
01316
01317 G_LogPrintf( "ClientDisconnect: %i\n", clientNum );
01318
01319 // if we are playing in tourney mode and losing, give a win to the other player
01320 if ( (g_gametype.integer == GT_TOURNAMENT )
01321 && !level.intermissiontime
01322 && !level.warmupTime && level.sortedClients[1] == clientNum ) {
01323 level.clients[ level.sortedClients[0] ].sess.wins++;
01324 ClientUserinfoChanged( level.sortedClients[0] );
01325 }
01326
01327 trap_UnlinkEntity (ent);
01328 ent->s.modelindex = 0;
01329 ent->inuse = qfalse;
01330 ent->classname = "disconnected";
01331 ent->client->pers.connected = CON_DISCONNECTED;
01332 ent->client->ps.persistant[PERS_TEAM] = TEAM_FREE;
01333 ent->client->sess.sessionTeam = TEAM_FREE;
01334
01335 trap_SetConfigstring( CS_PLAYERS + clientNum, "");
01336
01337 CalculateRanks();
01338
01339 if ( ent->r.svFlags & SVF_BOT ) {
01340 BotAIShutdownClient( clientNum, qfalse );
01341 }
01342 }
|
Here is the call graph for this function:

|
|
Definition at line 1051 of file g_client.c. References gclient_s::accuracy_hits, gclient_s::accuracy_shots, atoi, BG_PlayerStateToEntityState(), gentity_s::classname, gentity_s::client, ClientEndFrame(), level_locals_t::clients, ClientThink(), gentity_s::clipmask, clientPersistant_t::cmd, entityShared_t::contents, entityShared_t::currentOrigin, gentity_s::die, EF_TELEPORT_BIT, EF_VOTED, entityState_s::eFlags, playerState_s::eFlags, playerState_s::eventSequence, gentity_s::flags, g_entities, g_gametype, g_inactivity, G_KillBox(), G_SetOrigin(), G_UseTargets(), gclient_t, gentity_t, entityState_s::groundEntityNum, gentity_s::health, i, Info_ValueForKey(), clientPersistant_t::initialSpawn, vmCvar_t::integer, level_locals_t::intermissiontime, gentity_s::inuse, level, clientPersistant_t::localClient, entityShared_t::maxs, memset(), entityShared_t::mins, MoveClientToIntermission(), playerState_s::origin, gclient_s::pers, playerState_s::persistant, playerState_s::ping, playerMaxs, playerMins, gclient_s::ps, qtrue, gentity_s::r, gentity_s::s, SelectCTFSpawnPoint(), SelectInitialSpawnPoint(), SelectSpawnPoint(), SelectSpectatorSpawnPoint(), usercmd_s::serverTime, gclient_s::sess, clientSession_t::sessionTeam, SetClientViewAngle(), playerTeamState_t::state, entityShared_t::svFlags, gentity_s::takedamage, clientPersistant_t::teamState, level_locals_t::time, trap_GetUsercmd(), trap_GetUserinfo(), trap_LinkEntity(), vec3_t, VectorCopy, gentity_s::waterlevel, gentity_s::watertype, and WP_NUM_WEAPONS. Referenced by ClientBegin(), G_RankRunFrame(), and respawn(). 01051 {
01052 int index;
01053 vec3_t spawn_origin, spawn_angles;
01054 gclient_t *client;
01055 int i;
01056 clientPersistant_t saved;
01057 clientSession_t savedSess;
01058 int persistant[MAX_PERSISTANT];
01059 gentity_t *spawnPoint;
01060 int flags;
01061 int savedPing;
01062 // char *savedAreaBits;
01063 int accuracy_hits, accuracy_shots;
01064 int eventSequence;
01065 char userinfo[MAX_INFO_STRING];
01066
01067 index = ent - g_entities;
01068 client = ent->client;
01069
01070 // find a spawn point
01071 // do it before setting health back up, so farthest
01072 // ranging doesn't count this client
01073 if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
01074 spawnPoint = SelectSpectatorSpawnPoint (
01075 spawn_origin, spawn_angles);
01076 } else if (g_gametype.integer >= GT_CTF ) {
01077 // all base oriented team games use the CTF spawn points
01078 spawnPoint = SelectCTFSpawnPoint (
01079 client->sess.sessionTeam,
01080 client->pers.teamState.state,
01081 spawn_origin, spawn_angles);
01082 } else {
01083 do {
01084 // the first spawn should be at a good looking spot
01085 if ( !client->pers.initialSpawn && client->pers.localClient ) {
01086 client->pers.initialSpawn = qtrue;
01087 spawnPoint = SelectInitialSpawnPoint( spawn_origin, spawn_angles );
01088 } else {
01089 // don't spawn near existing origin if possible
01090 spawnPoint = SelectSpawnPoint (
01091 client->ps.origin,
01092 spawn_origin, spawn_angles);
01093 }
01094
01095 // Tim needs to prevent bots from spawning at the initial point
01096 // on q3dm0...
01097 if ( ( spawnPoint->flags & FL_NO_BOTS ) && ( ent->r.svFlags & SVF_BOT ) ) {
01098 continue; // try again
01099 }
01100 // just to be symetric, we have a nohumans option...
01101 if ( ( spawnPoint->flags & FL_NO_HUMANS ) && !( ent->r.svFlags & SVF_BOT ) ) {
01102 continue; // try again
01103 }
01104
01105 break;
01106
01107 } while ( 1 );
01108 }
01109 client->pers.teamState.state = TEAM_ACTIVE;
01110
01111 // always clear the kamikaze flag
01112 ent->s.eFlags &= ~EF_KAMIKAZE;
01113
01114 // toggle the teleport bit so the client knows to not lerp
01115 // and never clear the voted flag
01116 flags = ent->client->ps.eFlags & (EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED);
01117 flags ^= EF_TELEPORT_BIT;
01118
01119 // clear everything but the persistant data
01120
01121 saved = client->pers;
01122 savedSess = client->sess;
01123 savedPing = client->ps.ping;
01124 // savedAreaBits = client->areabits;
01125 accuracy_hits = client->accuracy_hits;
01126 accuracy_shots = client->accuracy_shots;
01127 for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
01128 persistant[i] = client->ps.persistant[i];
01129 }
01130 eventSequence = client->ps.eventSequence;
01131
01132 memset (client, 0, sizeof(*client)); // bk FIXME: Com_Memset?
01133
01134 client->pers = saved;
01135 client->sess = savedSess;
01136 client->ps.ping = savedPing;
01137 // client->areabits = savedAreaBits;
01138 client->accuracy_hits = accuracy_hits;
01139 client->accuracy_shots = accuracy_shots;
01140 client->lastkilled_client = -1;
01141
01142 for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
01143 client->ps.persistant[i] = persistant[i];
01144 }
01145 client->ps.eventSequence = eventSequence;
01146 // increment the spawncount so the client will detect the respawn
01147 client->ps.persistant[PERS_SPAWN_COUNT]++;
01148 client->ps.persistant[PERS_TEAM] = client->sess.sessionTeam;
01149
01150 client->airOutTime = level.time + 12000;
01151
01152 trap_GetUserinfo( index, userinfo, sizeof(userinfo) );
01153 // set max health
01154 client->pers.maxHealth = atoi( Info_ValueForKey( userinfo, "handicap" ) );
01155 if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
01156 client->pers.maxHealth = 100;
01157 }
01158 // clear entity values
01159 client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
01160 client->ps.eFlags = flags;
01161
01162 ent->s.groundEntityNum = ENTITYNUM_NONE;
01163 ent->client = &level.clients[index];
01164 ent->takedamage = qtrue;
01165 ent->inuse = qtrue;
01166 ent->classname = "player";
01167 ent->r.contents = CONTENTS_BODY;
01168 ent->clipmask = MASK_PLAYERSOLID;
01169 ent->die = player_die;
01170 ent->waterlevel = 0;
01171 ent->watertype = 0;
01172 ent->flags = 0;
01173
01174 VectorCopy (playerMins, ent->r.mins);
01175 VectorCopy (playerMaxs, ent->r.maxs);
01176
01177 client->ps.clientNum = index;
01178
01179 client->ps.stats[STAT_WEAPONS] = ( 1 << WP_MACHINEGUN );
01180 if ( g_gametype.integer == GT_TEAM ) {
01181 client->ps.ammo[WP_MACHINEGUN] = 50;
01182 } else {
01183 client->ps.ammo[WP_MACHINEGUN] = 100;
01184 }
01185
01186 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GAUNTLET );
01187 client->ps.ammo[WP_GAUNTLET] = -1;
01188 client->ps.ammo[WP_GRAPPLING_HOOK] = -1;
01189
01190 // health will count down towards max_health
01191 ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] + 25;
01192
01193 G_SetOrigin( ent, spawn_origin );
01194 VectorCopy( spawn_origin, client->ps.origin );
01195
01196 // the respawned flag will be cleared after the attack and jump keys come up
01197 client->ps.pm_flags |= PMF_RESPAWNED;
01198
01199 trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd );
01200 SetClientViewAngle( ent, spawn_angles );
01201
01202 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
01203
01204 } else {
01205 G_KillBox( ent );
01206 trap_LinkEntity (ent);
01207
01208 // force the base weapon up
01209 client->ps.weapon = WP_MACHINEGUN;
01210 client->ps.weaponstate = WEAPON_READY;
01211
01212 }
01213
01214 // don't allow full run speed for a bit
01215 client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
01216 client->ps.pm_time = 100;
01217
01218 client->respawnTime = level.time;
01219 client->inactivityTime = level.time + g_inactivity.integer * 1000;
01220 client->latched_buttons = 0;
01221
01222 // set default animations
01223 client->ps.torsoAnim = TORSO_STAND;
01224 client->ps.legsAnim = LEGS_IDLE;
01225
01226 if ( level.intermissiontime ) {
01227 MoveClientToIntermission( ent );
01228 } else {
01229 // fire the targets of the spawn point
01230 G_UseTargets( spawnPoint, ent );
01231
01232 // select the highest weapon number available, after any
01233 // spawn given items have fired
01234 client->ps.weapon = 1;
01235 for ( i = WP_NUM_WEAPONS - 1 ; i > 0 ; i-- ) {
01236 if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) {
01237 client->ps.weapon = i;
01238 break;
01239 }
01240 }
01241 }
01242
01243 // run a client frame to drop exactly to the floor,
01244 // initialize animations and other things
01245 client->ps.commandTime = level.time - 100;
01246 ent->client->pers.cmd.serverTime = level.time;
01247 ClientThink( ent-g_entities );
01248
01249 // positively link the client, even if the command times are weird
01250 if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
01251 BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
01252 VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
01253 trap_LinkEntity( ent );
01254 }
01255
01256 // run the presend to set anything else
01257 ClientEndFrame( ent );
01258
01259 // clear entity state values
01260 BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
01261 }
|
Here is the call graph for this function:

|
|
Definition at line 699 of file g_client.c. References atoi, gentity_s::client, ClientCleanName(), clientPersistant_t::connected, CS_PLAYERS, g_entities, g_gametype, G_LogPrintf(), gclient_t, gentity_t, GT_TEAM, Info_Validate(), Info_ValueForKey(), clientPersistant_t::localClient, clientSession_t::losses, clientPersistant_t::maxHealth, clientPersistant_t::netname, gclient_s::pers, PickTeam(), playerState_s::powerups, clientPersistant_t::predictItemPickup, gclient_s::ps, Q_stricmp(), Q_strncpyz(), gentity_s::r, s, S_COLOR_WHITE, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::spectatorState, playerState_s::stats, strcmp(), strcpy(), entityShared_t::svFlags, clientPersistant_t::teamInfo, clientSession_t::teamLeader, trap_GetUserinfo(), trap_SendServerCommand(), trap_SetConfigstring(), va(), and clientSession_t::wins. Referenced by AdjustTournamentScores(), BotSetUserInfo(), ClientConnect(), ClientDisconnect(), Cmd_TeamTask_f(), SetLeader(), SetTeam(), and vmMain(). 00699 {
00700 gentity_t *ent;
00701 int teamTask, teamLeader, team, health;
00702 char *s;
00703 char model[MAX_QPATH];
00704 char headModel[MAX_QPATH];
00705 char oldname[MAX_STRING_CHARS];
00706 gclient_t *client;
00707 char c1[MAX_INFO_STRING];
00708 char c2[MAX_INFO_STRING];
00709 char redTeam[MAX_INFO_STRING];
00710 char blueTeam[MAX_INFO_STRING];
00711 char userinfo[MAX_INFO_STRING];
00712
00713 ent = g_entities + clientNum;
00714 client = ent->client;
00715
00716 trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
00717
00718 // check for malformed or illegal info strings
00719 if ( !Info_Validate(userinfo) ) {
00720 strcpy (userinfo, "\\name\\badinfo");
00721 }
00722
00723 // check for local client
00724 s = Info_ValueForKey( userinfo, "ip" );
00725 if ( !strcmp( s, "localhost" ) ) {
00726 client->pers.localClient = qtrue;
00727 }
00728
00729 // check the item prediction
00730 s = Info_ValueForKey( userinfo, "cg_predictItems" );
00731 if ( !atoi( s ) ) {
00732 client->pers.predictItemPickup = qfalse;
00733 } else {
00734 client->pers.predictItemPickup = qtrue;
00735 }
00736
00737 // set name
00738 Q_strncpyz ( oldname, client->pers.netname, sizeof( oldname ) );
00739 s = Info_ValueForKey (userinfo, "name");
00740 ClientCleanName( s, client->pers.netname, sizeof(client->pers.netname) );
00741
00742 if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
00743 if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) {
00744 Q_strncpyz( client->pers.netname, "scoreboard", sizeof(client->pers.netname) );
00745 }
00746 }
00747
00748 if ( client->pers.connected == CON_CONNECTED ) {
00749 if ( strcmp( oldname, client->pers.netname ) ) {
00750 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname,
00751 client->pers.netname) );
00752 }
00753 }
00754
00755 // set max health
00756 #ifdef MISSIONPACK
00757 if (client->ps.powerups[PW_GUARD]) {
00758 client->pers.maxHealth = 200;
00759 } else {
00760 health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
00761 client->pers.maxHealth = health;
00762 if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
00763 client->pers.maxHealth = 100;
00764 }
00765 }
00766 #else
00767 health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
00768 client->pers.maxHealth = health;
00769 if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
00770 client->pers.maxHealth = 100;
00771 }
00772 #endif
00773 client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
00774
00775 // set model
00776 if( g_gametype.integer >= GT_TEAM ) {
00777 Q_strncpyz( model, Info_ValueForKey (userinfo, "team_model"), sizeof( model ) );
00778 Q_strncpyz( headModel, Info_ValueForKey (userinfo, "team_headmodel"), sizeof( headModel ) );
00779 } else {
00780 Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) );
00781 Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) );
00782 }
00783
00784 // bots set their team a few frames later
00785 if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
00786 s = Info_ValueForKey( userinfo, "team" );
00787 if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
00788 team = TEAM_RED;
00789 } else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
00790 team = TEAM_BLUE;
00791 } else {
00792 // pick the team with the least number of players
00793 team = PickTeam( clientNum );
00794 }
00795 }
00796 else {
00797 team = client->sess.sessionTeam;
00798 }
00799
00800 /* NOTE: all client side now
00801
00802 // team
00803 switch( team ) {
00804 case TEAM_RED:
00805 ForceClientSkin(client, model, "red");
00806 // ForceClientSkin(client, headModel, "red");
00807 break;
00808 case TEAM_BLUE:
00809 ForceClientSkin(client, model, "blue");
00810 // ForceClientSkin(client, headModel, "blue");
00811 break;
00812 }
00813 // don't ever use a default skin in teamplay, it would just waste memory
00814 // however bots will always join a team but they spawn in as spectator
00815 if ( g_gametype.integer >= GT_TEAM && team == TEAM_SPECTATOR) {
00816 ForceClientSkin(client, model, "red");
00817 // ForceClientSkin(client, headModel, "red");
00818 }
00819 */
00820
00821 #ifdef MISSIONPACK
00822 if (g_gametype.integer >= GT_TEAM) {
00823 client->pers.teamInfo = qtrue;
00824 } else {
00825 s = Info_ValueForKey( userinfo, "teamoverlay" );
00826 if ( ! *s || atoi( s ) != 0 ) {
00827 client->pers.teamInfo = qtrue;
00828 } else {
00829 client->pers.teamInfo = qfalse;
00830 }
00831 }
00832 #else
00833 // teamInfo
00834 s = Info_ValueForKey( userinfo, "teamoverlay" );
00835 if ( ! *s || atoi( s ) != 0 ) {
00836 client->pers.teamInfo = qtrue;
00837 } else {
00838 client->pers.teamInfo = qfalse;
00839 }
00840 #endif
00841 /*
00842 s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
00843 if ( !*s || atoi( s ) == 0 ) {
00844 client->pers.pmoveFixed = qfalse;
00845 }
00846 else {
00847 client->pers.pmoveFixed = qtrue;
00848 }
00849 */
00850
00851 // team task (0 = none, 1 = offence, 2 = defence)
00852 teamTask = atoi(Info_ValueForKey(userinfo, "teamtask"));
00853 // team Leader (1 = leader, 0 is normal player)
00854 teamLeader = client->sess.teamLeader;
00855
00856 // colors
00857 strcpy(c1, Info_ValueForKey( userinfo, "color1" ));
00858 strcpy(c2, Info_ValueForKey( userinfo, "color2" ));
00859
00860 strcpy(redTeam, Info_ValueForKey( userinfo, "g_redteam" ));
00861 strcpy(blueTeam, Info_ValueForKey( userinfo, "g_blueteam" ));
00862
00863 // send over a subset of the userinfo keys so other clients can
00864 // print scoreboards, display models, and play custom sounds
00865 if ( ent->r.svFlags & SVF_BOT ) {
00866 s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
00867 client->pers.netname, team, model, headModel, c1, c2,
00868 client->pers.maxHealth, client->sess.wins, client->sess.losses,
00869 Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader );
00870 } else {
00871 s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
00872 client->pers.netname, client->sess.sessionTeam, model, headModel, redTeam, blueTeam, c1, c2,
00873 client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader);
00874 }
00875
00876 trap_SetConfigstring( CS_PLAYERS+clientNum, s );
00877
00878 // this is not the userinfo, more like the configstring actually
00879 G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
00880 }
|
Here is the call graph for this function:

|