コード例 #1
0
ファイル: bg_luaplayer.cpp プロジェクト: Mauii/japp
	static void Player_SetName( lua_State *L, jpluaEntity_t *ent ) {
		const char *name = luaL_checkstring(L, 3);
		char info[MAX_INFO_STRING], oldName[MAX_NETNAME];

		if (!name || !*name || strlen(name) >= MAX_NETNAME)
			return;

		Q_strncpyz(oldName, ent->client->pers.netname, sizeof(oldName));

		ClientCleanName(name, ent->client->pers.netname, sizeof(ent->client->pers.netname));

		if (!strcmp(oldName, ent->client->pers.netname))
			return;

		Q_strncpyz(ent->client->pers.netnameClean, ent->client->pers.netname, sizeof(ent->client->pers.netnameClean));
		Q_CleanString(ent->client->pers.netnameClean, STRIP_COLOUR);

		if (CheckDuplicateName(ent->s.number)) {
			Q_strncpyz(ent->client->pers.netnameClean, ent->client->pers.netname, sizeof(ent->client->pers.netnameClean));
			Q_CleanString(ent->client->pers.netnameClean, STRIP_COLOUR);
		}

		// update clientinfo
		trap->GetConfigstring(CS_PLAYERS + ent->s.number, info, sizeof(info));
		Info_SetValueForKey(info, "n", name);
		trap->SetConfigstring(CS_PLAYERS + ent->s.number, info);

		// update userinfo (in engine)
		trap->GetUserinfo(ent->s.number, info, sizeof(info));
		Info_SetValueForKey(info, "name", name);
		trap->SetUserinfo(ent->s.number, info);
	}
コード例 #2
0
ファイル: g_client.c プロジェクト: zturtleman/swarmedq3
/*
===========
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, team, health;
	char	*s;
	char	model[MAX_QPATH];
	char	headModel[MAX_QPATH];
	char	oldname[MAX_STRING_CHARS];
	gclient_t	*client;
	char	c1[MAX_INFO_STRING];
	char	c2[MAX_INFO_STRING];
	char	redTeam[MAX_INFO_STRING];
	char	blueTeam[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");
	}

	// 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, client->pers.netname, sizeof(client->pers.netname) );

	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_CONNECTED ) {
		if ( strcmp( oldname, client->pers.netname ) ) {
			trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname, 
				client->pers.netname) );
		}
	}

	// set max health
#ifdef MISSIONPACK
	if (client->ps.powerups[PW_GUARD]) {
		client->pers.maxHealth = 200;
	} else {
		health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
		client->pers.maxHealth = health;
		if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
			client->pers.maxHealth = 100;
		}
	}
#else
	health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
	client->pers.maxHealth = health;
	if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
		client->pers.maxHealth = 100;
	}
#endif
	client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;

	// set model
	if( g_gametype.integer >= GT_TEAM ) {
		Q_strncpyz( model, Info_ValueForKey (userinfo, "team_model"), sizeof( model ) );
		Q_strncpyz( headModel, Info_ValueForKey (userinfo, "team_headmodel"), sizeof( headModel ) );
	} else {
		Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) );
		Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) );
	}

	// bots set their team a few frames later
	if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
		s = Info_ValueForKey( userinfo, "team" );
		if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
			team = TEAM_RED;
		} else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
			team = TEAM_BLUE;
		} else {
			// pick the team with the least number of players
			team = PickTeam( clientNum );
		}
	}
	else {
		team = client->sess.sessionTeam;
	}

/*	NOTE: all client side now

	// team
	switch( team ) {
	case TEAM_RED:
		ForceClientSkin(client, model, "red");
//		ForceClientSkin(client, headModel, "red");
		break;
	case TEAM_BLUE:
		ForceClientSkin(client, model, "blue");
//		ForceClientSkin(client, headModel, "blue");
		break;
	}
	// don't ever use a default skin in teamplay, it would just waste memory
	// however bots will always join a team but they spawn in as spectator
	if ( g_gametype.integer >= GT_TEAM && team == TEAM_SPECTATOR) {
		ForceClientSkin(client, model, "red");
//		ForceClientSkin(client, headModel, "red");
	}
*/

#ifdef MISSIONPACK
	if (g_gametype.integer >= GT_TEAM) {
		client->pers.teamInfo = qtrue;
	} else {
		s = Info_ValueForKey( userinfo, "teamoverlay" );
		if ( ! *s || atoi( s ) != 0 ) {
			client->pers.teamInfo = qtrue;
		} else {
			client->pers.teamInfo = qfalse;
		}
	}
#else
	// teamInfo
	s = Info_ValueForKey( userinfo, "teamoverlay" );
	if ( ! *s || atoi( s ) != 0 ) {
		client->pers.teamInfo = qtrue;
	} else {
		client->pers.teamInfo = qfalse;
	}
#endif
	/*
	s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
	if ( !*s || atoi( s ) == 0 ) {
		client->pers.pmoveFixed = qfalse;
	}
	else {
		client->pers.pmoveFixed = qtrue;
	}
	*/

	// 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" ));

	strcpy(redTeam, Info_ValueForKey( userinfo, "g_redteam" ));
	strcpy(blueTeam, Info_ValueForKey( userinfo, "g_blueteam" ));

	// send over a subset of the userinfo keys so other clients can
	// print scoreboards, display models, and play custom sounds
	if ( ent->r.svFlags & SVF_BOT ) {
		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",
			client->pers.netname, team, model, headModel, c1, c2, 
			client->pers.maxHealth, client->sess.wins, client->sess.losses,
			Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader );
	} else {
		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",
			client->pers.netname, client->sess.sessionTeam, model, headModel, redTeam, blueTeam, c1, c2, 
			client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader);
	}

	trap_SetConfigstring( CS_PLAYERS+clientNum, s );

	// this is not the userinfo, more like the configstring actually
	G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
}
コード例 #3
0
ファイル: g_client.c プロジェクト: asker/OmgHaxQVM
/*
===========
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 );*/
}
コード例 #4
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);
}
コード例 #5
0
ファイル: g_client.c プロジェクト: baseas/aftershock
/**
Called when a player begins connecting to the server.
Called again for every map change or tournement restart.

The session information will be valid after exit.

Return NULL if the client should be allowed, otherwise return
a string with the reason for denial.

Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.

firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
*/
char *ClientConnect(int clientNum, qboolean firstTime, qboolean isBot)
{
	char		name[MAX_NETNAME];
	char		*value, *nameError;
	gclient_t	*client;
	char		userinfo[MAX_INFO_STRING];
	gentity_t	*ent;

	ent = &g_entities[ clientNum ];

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

	if (G_BanCheck(userinfo)) {
		return "You are banned from this server.";
	}

	value = Info_ValueForKey(userinfo, "ip");

	nameError = Info_ValueForKey(userinfo, "name");
	nameError = ClientCleanName(nameError, name, sizeof name);

	// we don't check password for bots and local client
	// NOTE: local client <-> "ip" "localhost"
	// this means this client is not running in our current process
	if (!isBot && strcmp(value, "localhost")) {
		// check for invalid player name
		if (nameError) {
			return nameError;
		}

		// check for a password
		value = Info_ValueForKey (userinfo, "password");
		if (g_password.string[0] && Q_stricmp(g_password.string, "none") &&
			strcmp(g_password.string, value) != 0)
		{
			return "Invalid password";
		}
	}
	// if a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
	if (ent->inuse) {
		G_LogPrintf("Forcing disconnect on active client: %i\n", clientNum);
		// so lets just fix up anything that should happen on a disconnect
		ClientDisconnect(clientNum);
	}
	// they can connect
	ent->client = level.clients + clientNum;
	client = ent->client;

	memset(client, 0, sizeof(*client));

	client->pers.connected = CON_CONNECTING;

	// read or initialize the session data
	if (firstTime || level.newSession) {
		G_InitSessionData(client, userinfo);
	}
	G_ReadSessionData(client);

	if (isBot) {
		ent->r.svFlags |= SVF_BOT;
		ent->inuse = qtrue;
		if (!G_BotConnect(clientNum, !firstTime)) {
			return "BotConnectfailed";
		}
	}

	// don't do the "xxx connected" messages if they were caried over from previous level
	if (firstTime) {
		ClientScreenPrint(NULL, "%s ^7connected", name);
	}

	// get and distribute relevent paramters
	G_LogPrintf("ClientConnect: %i\n", clientNum);
	ClientUserinfoChanged(clientNum);

	if (g_gametype.integer >= GT_TEAM && client->sess.sessionTeam != TEAM_SPECTATOR) {
		LogTeamChange(client, -1);
	}

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

	return NULL;
}
コード例 #6
0
ファイル: g_client.c プロジェクト: baseas/aftershock
/**
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, team, health;
	char	*s;
	char	oldname[MAX_STRING_CHARS];
	gclient_t	*client;
	char	userinfo[MAX_INFO_STRING];
	char	*nameError;

	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");
		// don't keep those clients and userinfo
		trap_DropClient(clientNum, "Invalid userinfo");
	}

	// 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");
	nameError = ClientCleanName(s, client->pers.netname, sizeof client->pers.netname);

	if (client->pers.connected == CON_CONNECTED && strcmp(oldname, s)) {
		if (client->pers.muted) {
			ClientPrint(ent, "You cannot change your name while you are muted.");
		} else if (nameError) {
			ClientPrint(ent, "%s", nameError);
		} else {
			G_LogPrintf("%s ^7renamed to %s\n", oldname, client->pers.netname);
		}

		if (nameError || client->pers.muted) {
			Q_strncpyz(client->pers.netname, oldname, sizeof client->pers.netname);
		}
	}

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

	// 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;
	}
	client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;

	// bots set their team a few frames later
	if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
		s = Info_ValueForKey(userinfo, "team");
		if (!Q_stricmp(s, "red") || !Q_stricmp(s, "r")) {
			team = TEAM_RED;
		} else if (!Q_stricmp(s, "blue") || !Q_stricmp(s, "b")) {
			team = TEAM_BLUE;
		} else {
			// pick the team with the least number of players
			team = PickTeam(clientNum);
		}
	}
	else {
		team = client->sess.sessionTeam;
	}

	// 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;

	// send over a subset of the userinfo keys so other clients can
	// print scoreboards, display models, and play custom sounds
	if (ent->r.svFlags & SVF_BOT) {
		s = va("n\\%s\\t\\%i\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
			client->pers.netname, team, client->pers.maxHealth,
			client->sess.wins, client->sess.losses,
			Info_ValueForKey(userinfo, "skill"), teamTask, teamLeader);
	}
	else {
		s = va("n\\%s\\t\\%i\\s\\%d\\r\\%i\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
			client->pers.netname, team, client->sess.specOnly,
			client->pers.ready, client->pers.maxHealth,
			client->sess.wins, client->sess.losses, teamTask, teamLeader);
	}

	trap_SetConfigstring(CS_PLAYERS+clientNum, s);

	// this is not the userinfo, more like the configstring actually
	G_LogPrintf("ClientUserinfoChanged: %i %s\n", clientNum, s);
}