TGB/Networking/Player Names

From TDN

This page is a Work In Progress by Seth Willits, dated May 13, 2008.

TGB Networking >> Player Names

Player Names

Each client connected to a server has a "player name" associated with them. Each client is allowed to choose a name for themselves, but the server enforces that no two clients can have the same name. When a client connects to by calling connectToServer() the player's name contained in $Pref::Player::Name is sent to the server. The server, when accepting the connection, then does a comparison between the connecting client's name and other already-connected clients' names to determine if it is a duplicate, and also checks to make sure there actually is a name (and not simply an empty string).


As of TGB 1.7.2, however, the check for name uniqueness is broken. The function isNameUnique(%name) is responsible for determining the uniqueness of a client's name.

//---------------------------------------------------------------------------------------------
// isNameUnique
// Checks if %name is not used by any clients.
//---------------------------------------------------------------------------------------------
function isNameUnique(%name)
{
   %count = ClientGroup.getCount();
   for (%i = 0; %i < %count; %i++)
   {
      %client = ClientGroup.getObject(%i);

      // This comparison appears invalid as %client.name is not a tag, but the actual string itself
      //%test = detag(getTaggedString(%client.name));
      //if (strcmp(%name, %test) == 0)
      //   return false;
      
      // A string comparison instead, is correct
      if (%name $= %client.name) return false;
   }
   
   // If we get here, the name is unique.
   return true;
}



Additionally, it would only seem logical that the client be told what it's "unique-ified" name is, after the server creates it. To do so requires changing GameConnection::setPlayerName() to send a message to the client via a remote procedure call (RPC) telling it the name as given by the server, and then handling that command on the client. First we send the command to the client by adding a single line to the end of GameConnection.setPlayerName():

//---------------------------------------------------------------------------------------------
// GameConnection.setPlayerName
// Sets %clients name based on %name. If %name is already used, a number is appended or
// incremented until the name is unique.
//---------------------------------------------------------------------------------------------
function GameConnection::setPlayerName(%client, %name)
{
   //echo("name = " @ %name);
   
   // If nothing was passed, set a default name.
   %name = getSubStr(trim(%name), 0, 15);
   if (%name $= "")
      %name = "TGB Gamer";

   // Make sure the name is unique, we'll hit something eventually.
   %nameTest = %name;
   %count = 0;
   while(!isNameUnique(%nameTest))
   {
      %count++;
      %nameTest = %name @ %count;
   }

   // Set the name.
   %client.name = %nameTest;

   // *** Here we add a line to tell the client what its unique name is ***
   commandToClient(%client, 'SetPlayerName', %client.name);
}

The client must then handle the command to accept the name determined by the server:

function clientCmdSetPlayerName(%name)
{
   // Here you can handle the name however you wish.
   // If in other parts of your code you access the player's name by
   // simply referencing $Pref::Player::Name, then simply setting
   // $Pref::Player::Name to %name would be sufficient.
}