2012-05-29 13:31:11 +00:00
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Includes
//
# include "stdmisc.h"
# include "nel/misc/algo.h"
# include "nel/misc/file.h"
# include "nel/misc/path.h"
# include "nel/misc/command.h"
# include "nel/misc/types_nl.h"
# include "nel/misc/entity_id.h"
# include "nel/misc/eid_translator.h"
# include "nel/misc/hierarchical_timer.h"
using namespace std ;
2012-12-05 09:26:01 +00:00
# ifdef DEBUG_NEW
# define new DEBUG_NEW
# endif
2012-05-29 13:31:11 +00:00
namespace NLMISC {
//
// Variables
//
//CEntityIdTranslator *CEntityIdTranslator::Instance = NULL;
NLMISC_SAFE_SINGLETON_IMPL ( CEntityIdTranslator ) ;
// don't forget to increment the number when you change the file format
const uint CEntityIdTranslator : : Version = 1 ;
//
// Functions
//
void CEntityIdTranslator : : CEntity : : serial ( NLMISC : : IStream & s )
{
H_AUTO ( EIdTrans_serial ) ;
s . serial ( EntityName ) ;
if ( CEntityIdTranslator : : getInstance ( ) - > FileVersion > = 1 )
s . serial ( EntitySlot ) ;
else
{
if ( s . isReading ( ) )
{
EntitySlot = - 1 ;
}
else
{
sint8 slot = - 1 ;
s . serial ( slot ) ;
}
}
s . serial ( UId ) ;
s . serial ( UserName ) ;
}
//CEntityIdTranslator *CEntityIdTranslator::getInstance ()
//{
// if(Instance == NULL)
// {
// Instance = new CEntityIdTranslator;
// }
// return Instance;
//}
void CEntityIdTranslator : : getByUser ( uint32 uid , vector < CEntityId > & res )
{
H_AUTO ( EIdTrans_getByUser ) ;
for ( TEntityCont : : iterator it = RegisteredEntities . begin ( ) ; it ! = RegisteredEntities . end ( ) ; it + + )
{
CEntity & entity = it - > second ;
if ( entity . UId = = uid )
{
res . push_back ( it - > first ) ;
}
}
}
void CEntityIdTranslator : : getByUser ( const string & userName , vector < CEntityId > & res , bool exact )
{
H_AUTO ( EIdTrans_getByUser2 ) ;
string lowerName = toLower ( userName ) ;
for ( TEntityCont : : iterator it = RegisteredEntities . begin ( ) ; it ! = RegisteredEntities . end ( ) ; it + + )
{
if ( exact )
{
CEntity & entity = it - > second ;
if ( toLower ( entity . UserName ) = = lowerName )
{
res . push_back ( it - > first ) ;
}
}
else
{
CEntity & entity = it - > second ;
if ( toLower ( entity . UserName ) . find ( lowerName ) ! = string : : npos )
{
res . push_back ( it - > first ) ;
}
}
}
}
const ucstring & CEntityIdTranslator : : getByEntity ( const CEntityId & eid )
{
H_AUTO ( EIdTrans_getByEntity ) ;
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
static ucstring emptyString ;
return emptyString ;
}
else
{
CEntity & entity = it - > second ;
return entity . EntityName ;
}
}
CEntityId CEntityIdTranslator : : getByEntity ( const ucstring & entityName )
{
H_AUTO ( EIdTrans_getByEntity2 ) ;
vector < CEntityId > res ;
getByEntity ( entityName , res , true ) ;
if ( res . empty ( ) )
return CEntityId : : Unknown ;
else
return res [ 0 ] ;
}
void CEntityIdTranslator : : getByEntity ( const ucstring & entityName , vector < CEntityId > & res , bool exact )
{
H_AUTO ( EIdTrans_getByEntity3 ) ;
string lowerName = toLower ( entityName . toString ( ) ) ;
if ( exact )
{
// use the reverse index to speed up search
TNameIndexCont : : iterator it ( NameIndex . find ( lowerName ) ) ;
if ( it ! = NameIndex . end ( ) )
res . push_back ( it - > second ) ;
return ;
}
// parse the entire container to match all entities
for ( TEntityCont : : iterator it = RegisteredEntities . begin ( ) ; it ! = RegisteredEntities . end ( ) ; + + it )
{
CEntity & entity = it - > second ;
if ( toLower ( entity . EntityName . toString ( ) ) . find ( lowerName ) ! = string : : npos )
{
res . push_back ( it - > first ) ;
}
}
}
bool CEntityIdTranslator : : isValidEntityName ( const ucstring & entityName , CLog * log )
{
H_AUTO ( EIdTrans_isValidEntityName ) ;
// 3 char at least
if ( entityName . size ( ) < 3 )
{
log - > displayNL ( " Bad entity name '%s' (less than 3 char) " , entityName . toString ( ) . c_str ( ) ) ;
return false ;
}
if ( entityName . size ( ) > 15 )
{
// if a parenthesis is found before 15 chars, the name is valid
if ( entityName . find ( ucstring ( " ( " ) ) > 15 | | entityName [ entityName . size ( ) - 1 ] ! = ucchar ( ' ) ' ) )
{
log - > displayNL ( " EIT: Bad entity name '%s' (more than 15 char) " , entityName . toString ( ) . c_str ( ) ) ;
return false ;
}
}
bool allowNumeric = false ;
for ( uint i = 0 ; i < entityName . size ( ) ; i + + )
{
if ( entityName [ i ] = = ' ( ' )
{
// starting from shard name, allow alphanumeric character
allowNumeric = true ;
}
// only accept name with alphabetic and numeric value [a-zA-Z] and parenthesis
if ( ! allowNumeric & & ! isalpha ( entityName [ i ] ) & & entityName [ i ] ! = ' ( ' & & entityName [ i ] ! = ' ) ' )
{
log - > displayNL ( " Bad entity name '%s' (only char and num) " , entityName . toString ( ) . c_str ( ) ) ;
return false ;
}
}
// now check with the invalid name list
string en = getRegisterableString ( entityName ) ;
for ( uint i = 0 ; i < InvalidEntityNames . size ( ) ; i + + )
{
if ( testWildCard ( en , InvalidEntityNames [ i ] ) )
{
log - > displayNL ( " Bad entity name '%s' (match the invalid entity name pattern '%s') " , entityName . toString ( ) . c_str ( ) , InvalidEntityNames [ i ] . c_str ( ) ) ;
return false ;
}
}
return true ;
}
void CEntityIdTranslator : : clear ( )
{
NameIndex . clear ( ) ;
RegisteredEntities . clear ( ) ;
}
bool CEntityIdTranslator : : checkEntityName ( const ucstring & entityName )
{
H_AUTO ( EIdTrans_entityNameExists ) ;
// if bad name, don't accept it
if ( ! isValidEntityName ( entityName , NLMISC : : InfoLog ) ) return false ;
return ! entityNameExists ( entityName ) ;
}
bool CEntityIdTranslator : : entityNameExists ( const ucstring & entityName )
{
// Names are stored in case dependant, so we have to test them without case.
ucstring registerable = getRegisterableString ( entityName ) ;
return NameIndex . find ( registerable ) ! = NameIndex . end ( ) ;
/* for (TEntityCont::iterator it = RegisteredEntities.begin(); it != RegisteredEntities.end(); it++)
{
if ( getRegisterableString ( ( * it ) . second . EntityName ) = = registerable )
{
return true ;
}
}
return false ;
*/
}
void CEntityIdTranslator : : registerEntity ( const CEntityId & eid , const ucstring & entityName , sint8 entitySlot , uint32 uid , const string & userName , uint32 shardId )
{
H_AUTO ( EIdTrans_registerEntity ) ;
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
if ( RegisteredEntities . find ( reid ) ! = RegisteredEntities . end ( ) )
{
nlwarning ( " EIT: Can't register EId %s EntityName '%s' UId %d UserName '%s' because EId is already in the map " , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
return ;
}
if ( ! checkEntityName ( entityName ) )
{
if ( isValidEntityName ( entityName ) )
nlwarning ( " EIT: Can't register EId %s EntityName '%s' UId %d UserName '%s' because EntityName is already in the map " , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
else
nlwarning ( " EIT: Can't register EId %s EntityName '%s' UId %d UserName '%s' because EntityName is invalid " , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
return ;
}
nlinfo ( " EIT: Register EId %s EntityName '%s' UId %d UserName '%s' " , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
RegisteredEntities . insert ( make_pair ( reid , CEntityIdTranslator : : CEntity ( entityName , uid , userName , entitySlot , shardId ) ) ) ;
NameIndex . insert ( make_pair ( toLower ( entityName ) , reid ) ) ;
}
void CEntityIdTranslator : : updateEntity ( const CEntityId & eid , const ucstring & entityName , sint8 entitySlot , uint32 uid , const std : : string & userName , uint32 shardId )
{
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
// just register
registerEntity ( eid , entityName , entitySlot , uid , userName , shardId ) ;
}
else
{
// update entity entry and name index
CEntity & entity = it - > second ;
if ( entity . EntityName ! = entityName )
{
if ( ! checkEntityName ( entityName ) )
{
nlwarning ( " EIT: Can't update EId %s EntityName '%s' UId %d UserName '%s' with new name '%s' because EntityName is already in the map " ,
reid . toString ( ) . c_str ( ) ,
entity . EntityName . toString ( ) . c_str ( ) ,
uid ,
userName . c_str ( ) ,
entityName . toString ( ) . c_str ( ) ) ;
return ;
}
// update the name and name index
NameIndex . erase ( toLower ( entity . EntityName ) ) ;
NameIndex . insert ( make_pair ( toLower ( entityName ) , reid ) ) ;
entity . EntityName = entityName ;
entity . EntityNameStringId = 0 ;
}
entity . EntitySlot = entitySlot ;
entity . UId = uid ;
entity . UserName = userName ;
entity . ShardId = shardId ;
}
}
void CEntityIdTranslator : : unregisterEntity ( const CEntityId & eid )
{
H_AUTO ( EIdTrans_unregisterEntity ) ;
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
nlwarning ( " EIT: Can't unregister EId %s because EId is not in the map " , reid . toString ( ) . c_str ( ) ) ;
return ;
}
CEntity & entity = it - > second ;
nldebug ( " EIT: Unregister EId %s EntityName '%s' UId %d UserName '%s' " , reid . toString ( ) . c_str ( ) , entity . EntityName . toString ( ) . c_str ( ) , entity . UId , entity . UserName . c_str ( ) ) ;
NameIndex . erase ( toLower ( entity . EntityName ) ) ;
RegisteredEntities . erase ( reid ) ;
}
bool CEntityIdTranslator : : isEntityRegistered ( const CEntityId & eid )
{
H_AUTO ( EIdTrans_unregisterEntity ) ;
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
return it ! = RegisteredEntities . end ( ) ;
}
void CEntityIdTranslator : : checkEntity ( const CEntityId & eid , const ucstring & entityName , uint32 uid , const string & userName )
{
H_AUTO ( EIdTrans_checkEntity ) ;
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
map < CEntityId , CEntityIdTranslator : : CEntity > : : iterator it = RegisteredEntities . find ( reid ) ;
nlinfo ( " EIT: Checking EId %s EntityName '%s' UId %d UserName '%s' " , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
if ( it = = RegisteredEntities . end ( ) )
{
nlwarning ( " EIT: Check failed because EId is not in the CEntityIdTranslator map for EId %s EntityName '%s' UId %d UserName '%s' " , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
if ( checkEntityName ( entityName ) )
{
nlwarning ( " EIT: Check failed because entity name already exist '%s' for EId %s EntityName '%s' UId %d UserName '%s' " , getByEntity ( entityName ) . toString ( ) . c_str ( ) , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
}
}
else
{
CEntity & entity = it - > second ;
if ( entity . EntityName ! = entityName )
{
nlwarning ( " EIT: Check failed because entity name not identical '%s' in the CEntityIdTranslator map for EId %s EntityName '%s' UId %d UserName '%s' " , entity . EntityName . toString ( ) . c_str ( ) , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
if ( ! entityName . empty ( ) )
{
entity . EntityName = entityName ;
}
}
if ( entity . UId ! = uid )
{
nlwarning ( " EIT: Check failed because uid not identical (%d) in the CEntityIdTranslator map for EId %s EntityName '%s' UId %d UserName '%s' " , entity . UId , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
if ( uid ! = 0 )
{
entity . UId = uid ;
}
}
if ( entity . UserName ! = userName )
{
nlwarning ( " EIT: Check failed because user name not identical '%s' in the CEntityIdTranslator map for EId %s EntityName '%s' UId %d UserName '%s' " , entity . UserName . c_str ( ) , reid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , uid , userName . c_str ( ) ) ;
if ( ! userName . empty ( ) )
{
entity . UserName = userName ;
}
}
}
}
void CEntityIdTranslator : : removeShardFromName ( ucstring & name )
{
// The string must contain a '(' and a ')'
ucstring : : size_type p0 = name . find ( ' ( ' ) ;
ucstring : : size_type p1 = name . find ( ' ) ' ) ;
if ( p0 = = ucstring : : npos | | p1 = = ucstring : : npos | | p1 < = p0 )
return ;
name = name . substr ( 0 , p0 ) + name . substr ( p1 + 1 ) ;
}
// this callback is call when the file is changed
void cbInvalidEntityNamesFilename ( const std : : string & invalidEntityNamesFilename )
{
CEntityIdTranslator : : getInstance ( ) - > InvalidEntityNames . clear ( ) ;
string fn = CPath : : lookup ( invalidEntityNamesFilename , false ) ;
if ( fn . empty ( ) )
{
nlwarning ( " EIT: Can't load filename '%s' for invalid entity names filename (not found) " , invalidEntityNamesFilename . c_str ( ) ) ;
return ;
}
FILE * fp = fopen ( fn . c_str ( ) , " r " ) ;
if ( fp = = NULL )
{
nlwarning ( " EIT: Can't load filename '%s' for invalid entity names filename " , fn . c_str ( ) ) ;
return ;
}
for ( ; ; )
{
char str [ 512 ] ;
if ( ! fgets ( str , 511 , fp ) )
break ;
if ( feof ( fp ) )
break ;
if ( strlen ( str ) > 0 )
{
str [ strlen ( str ) - 1 ] = ' \0 ' ;
CEntityIdTranslator : : getInstance ( ) - > InvalidEntityNames . push_back ( str ) ;
}
}
fclose ( fp ) ;
}
void CEntityIdTranslator : : load ( const string & fileName , const string & invalidEntityNamesFilename )
{
H_AUTO ( EIdTrans_load ) ;
if ( fileName . empty ( ) )
{
nlwarning ( " EIT: Can't load empty filename for EntityIdTranslator " ) ;
return ;
}
if ( ! FileName . empty ( ) )
{
nlwarning ( " EIT: Can't load file '%s' for EntityIdTranslator because we already load the file '%s' " , fileName . c_str ( ) , FileName . c_str ( ) ) ;
return ;
}
nlinfo ( " EIT: CEntityIdTranslator: load '%s' " , fileName . c_str ( ) ) ;
FileName = fileName ;
if ( CFile : : fileExists ( FileName ) )
{
CIFile ifile ;
if ( ifile . open ( FileName ) )
{
FileVersion = Version ;
ifile . serialVersion ( FileVersion ) ;
ifile . serialCont ( RegisteredEntities ) ;
ifile . close ( ) ;
// fill the entity name index container
NameIndex . clear ( ) ;
TEntityCont : : iterator first ( RegisteredEntities . begin ( ) ) , last ( RegisteredEntities . end ( ) ) ;
for ( ; first ! = last ; + + first )
{
NameIndex . insert ( make_pair ( toLower ( first - > second . EntityName ) , first - > first ) ) ;
}
}
else
{
nlwarning ( " EIT: Can't load filename '%s' for EntityIdTranslator " , FileName . c_str ( ) ) ;
}
}
cbInvalidEntityNamesFilename ( invalidEntityNamesFilename ) ;
NLMISC : : CFile : : addFileChangeCallback ( invalidEntityNamesFilename , cbInvalidEntityNamesFilename ) ;
}
void CEntityIdTranslator : : save ( )
{
H_AUTO ( EIdTrans_save ) ;
if ( FileName . empty ( ) )
{
nlwarning ( " EIT: Can't save empty filename for EntityIdTranslator (you forgot to load() it before?) " ) ;
return ;
}
nlinfo ( " EIT: CEntityIdTranslator: save " ) ;
COFile ofile ;
if ( ofile . open ( FileName ) )
{
ofile . serialVersion ( Version ) ;
FileVersion = Version ;
ofile . serialCont ( RegisteredEntities ) ;
ofile . close ( ) ;
}
else
{
nlwarning ( " EIT: Can't save filename '%s' for EntityIdTranslator " , FileName . c_str ( ) ) ;
}
}
uint32 CEntityIdTranslator : : getUId ( const string & userName )
{
const TEntityCont : : iterator itEnd = RegisteredEntities . end ( ) ;
for ( TEntityCont : : iterator it = RegisteredEntities . begin ( ) ; it ! = itEnd ; + + it )
{
CEntity & entity = it - > second ;
if ( entity . UserName = = userName )
{
return entity . UId ;
}
}
return 0 ;
}
string CEntityIdTranslator : : getUserName ( uint32 uid )
{
const TEntityCont : : iterator itEnd = RegisteredEntities . end ( ) ;
for ( TEntityCont : : iterator it = RegisteredEntities . begin ( ) ; it ! = itEnd ; + + it )
{
CEntity & entity = it - > second ;
if ( entity . UId = = uid )
{
return entity . UserName ;
}
}
return 0 ;
}
void CEntityIdTranslator : : getEntityIdInfo ( const CEntityId & eid , ucstring & entityName , sint8 & entitySlot , uint32 & uid , string & userName , bool & online , std : : string * additional )
{
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
if ( additional ! = NULL )
additional - > clear ( ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
nlwarning ( " EIT: %s is not registered in CEntityIdTranslator " , reid . toString ( ) . c_str ( ) ) ;
entityName = " " ;
entitySlot = - 1 ;
uid = std : : numeric_limits < uint32 > : : max ( ) ;
userName = " " ;
online = false ;
}
else
{
CEntity & entity = it - > second ;
entityName = entity . EntityName ;
entitySlot = entity . EntitySlot ;
uid = entity . UId ;
userName = entity . UserName ;
online = entity . Online ;
if ( EntityInfoCallback ! = NULL & & additional ! = NULL )
* additional = EntityInfoCallback ( eid ) ;
}
}
bool CEntityIdTranslator : : setEntityNameStringId ( const ucstring & entityName , uint32 stringId )
{
const TEntityCont : : iterator itEnd = RegisteredEntities . end ( ) ;
for ( TEntityCont : : iterator it = RegisteredEntities . begin ( ) ; it ! = itEnd ; + + it )
{
CEntity & entity = it - > second ;
if ( entity . EntityName = = entityName )
{
entity . EntityNameStringId = stringId ;
return true ;
}
}
return false ;
}
bool CEntityIdTranslator : : setEntityNameStringId ( const CEntityId & eid , uint32 stringId )
{
TEntityCont : : iterator it ( RegisteredEntities . find ( eid ) ) ;
if ( it = = RegisteredEntities . end ( ) )
{
// there is nothing we can do !
return false ;
}
CEntity & entity = it - > second ;
entity . EntityNameStringId = stringId ;
return true ;
}
uint32 CEntityIdTranslator : : getEntityNameStringId ( const CEntityId & eid )
{
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
const TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
return 0 ;
}
else
{
CEntity & entity = it - > second ;
return entity . EntityNameStringId ;
}
}
// get the shard id of an entity
uint32 CEntityIdTranslator : : getEntityShardId ( const CEntityId & eid )
{
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
const TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
return 0 ;
}
else
{
CEntity & entity = it - > second ;
return entity . ShardId ;
}
}
void CEntityIdTranslator : : setEntityOnline ( const CEntityId & eid , bool online )
{
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
nlwarning ( " EIT: %s is not registered in CEntityIdTranslator " , reid . toString ( ) . c_str ( ) ) ;
}
else
{
CEntity & entity = it - > second ;
entity . Online = online ;
}
}
bool CEntityIdTranslator : : isEntityOnline ( const CEntityId & eid )
{
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
CEntityId reid ( eid ) ;
reid . setCreatorId ( 0 ) ;
reid . setDynamicId ( 0 ) ;
TEntityCont : : iterator it = RegisteredEntities . find ( reid ) ;
if ( it = = RegisteredEntities . end ( ) )
{
nlwarning ( " EIT: %s is not registered in CEntityIdTranslator " , reid . toString ( ) . c_str ( ) ) ;
return false ;
}
else
{
CEntity & entity = it - > second ;
return entity . Online ;
}
}
std : : string CEntityIdTranslator : : getRegisterableString ( const ucstring & entityName )
{
string ret = toLower ( entityName . toString ( ) ) ;
string : : size_type pos = ret . find ( 0x20 ) ;
while ( pos ! = string : : npos )
{
ret . erase ( pos , 1 ) ;
pos = ret . find ( 0x20 ) ;
}
return ret ;
}
NLMISC_CATEGORISED_COMMAND ( nel , findEIdByUser , " Find entity ids using the user name " , " <username>|<uid> " )
{
if ( args . size ( ) ! = 1 )
return false ;
vector < CEntityId > res ;
string userName = args [ 0 ] ;
uint32 uid = atoi ( userName . c_str ( ) ) ;
if ( uid ! = 0 )
{
CEntityIdTranslator : : getInstance ( ) - > getByUser ( uid , res ) ;
userName = CEntityIdTranslator : : getInstance ( ) - > getUserName ( uid ) ;
}
else
{
CEntityIdTranslator : : getInstance ( ) - > getByUser ( userName , res ) ;
CEntityIdTranslator : : getInstance ( ) - > getUId ( userName ) ;
}
log . displayNL ( " User Name '%s' (uid=%d) has %d entities: " , userName . c_str ( ) , uid , res . size ( ) ) ;
for ( uint i = 0 ; i < res . size ( ) ; i + + )
{
log . displayNL ( " > %s '%s' " , res [ i ] . toString ( ) . c_str ( ) , CEntityIdTranslator : : getInstance ( ) - > getByEntity ( res [ i ] ) . c_str ( ) ) ;
}
return true ;
}
NLMISC_CATEGORISED_COMMAND ( nel , findEIdByEntity , " Find entity id using the entity name " , " <entityname>|<eid> " )
{
if ( args . size ( ) ! = 1 )
return false ;
CEntityId eid ( args [ 0 ] . c_str ( ) ) ;
if ( eid = = CEntityId : : Unknown )
{
eid = CEntityIdTranslator : : getInstance ( ) - > getByEntity ( args [ 0 ] ) ;
}
if ( eid = = CEntityId : : Unknown )
{
log . displayNL ( " '%s' is not an eid or an entity name " , args [ 0 ] . c_str ( ) ) ;
return false ;
}
ucstring entityName ;
sint8 entitySlot ;
uint32 uid ;
string userName ;
bool online ;
std : : string extinf ;
CEntityIdTranslator : : getInstance ( ) - > getEntityIdInfo ( eid , entityName , entitySlot , uid , userName , online , & extinf ) ;
log . displayNL ( " UId %d UserName '%s' EId %s EntityName '%s' EntitySlot %hd %s%s%s " , uid , userName . c_str ( ) , eid . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , ( sint16 ) entitySlot , ( extinf . c_str ( ) ) , ( extinf . empty ( ) ? " " : " " ) , ( online ? " Online " : " Offline " ) ) ;
return true ;
}
NLMISC_CATEGORISED_COMMAND ( nel , entityNameValid , " Tell if an entity name is valid or not using CEntityIdTranslator validation rulez " , " <entityname> " )
{
if ( args . size ( ) ! = 1 ) return false ;
if ( ! CEntityIdTranslator : : getInstance ( ) - > isValidEntityName ( args [ 0 ] , & log ) )
{
log . displayNL ( " Entity name '%s' is not valid " , args [ 0 ] . c_str ( ) ) ;
}
else
{
if ( CEntityIdTranslator : : getInstance ( ) - > checkEntityName ( args [ 0 ] ) )
{
log . displayNL ( " Entity name '%s' is already used by another player " , args [ 0 ] . c_str ( ) ) ;
}
else
{
log . displayNL ( " Entity name '%s' is available " , args [ 0 ] . c_str ( ) ) ;
}
}
return true ;
}
NLMISC_CATEGORISED_COMMAND ( nel , playerInfo , " Get information about a player or all players in CEntityIdTranslator " , " [<entityname>|<eid>|<username>|<uid>] " )
{
if ( args . size ( ) = = 0 )
{
const map < CEntityId , CEntityIdTranslator : : CEntity > & res = CEntityIdTranslator : : getInstance ( ) - > getRegisteredEntities ( ) ;
log . displayNL ( " %d result(s) for 'all players information' " , res . size ( ) ) ;
for ( map < CEntityId , CEntityIdTranslator : : CEntity > : : const_iterator it = res . begin ( ) ; it ! = res . end ( ) ; it + + )
{
const CEntityIdTranslator : : CEntity & entity = it - > second ;
log . displayNL ( " UId %d UserName '%s' EId %s EntityName '%s' EntitySlot %hd %s " , entity . UId , entity . UserName . c_str ( ) , it - > first . toString ( ) . c_str ( ) , entity . EntityName . toString ( ) . c_str ( ) , ( sint16 ) ( entity . EntitySlot ) , ( entity . Online ? " Online " : " Offline " ) ) ;
}
return true ;
}
else if ( args . size ( ) = = 1 )
{
vector < CEntityId > res ;
CEntityId eid ( args [ 0 ] . c_str ( ) ) ;
uint32 uid = atoi ( args [ 0 ] . c_str ( ) ) ;
if ( eid ! = CEntityId : : Unknown )
{
// we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
eid . setCreatorId ( 0 ) ;
eid . setDynamicId ( 0 ) ;
res . push_back ( eid ) ;
}
else if ( uid ! = 0 )
{
// the parameter is an uid
CEntityIdTranslator : : getInstance ( ) - > getByUser ( uid , res ) ;
}
else
{
CEntityIdTranslator : : getInstance ( ) - > getByUser ( args [ 0 ] , res , false ) ;
CEntityIdTranslator : : getInstance ( ) - > getByEntity ( args [ 0 ] , res , false ) ;
}
log . displayNL ( " %d result(s) for '%s' " , res . size ( ) , args [ 0 ] . c_str ( ) ) ;
for ( uint i = 0 ; i < res . size ( ) ; i + + )
{
ucstring entityName ;
sint8 entitySlot ;
uint32 uid2 ;
string userName ;
bool online ;
std : : string extinf ;
CEntityIdTranslator : : getInstance ( ) - > getEntityIdInfo ( res [ i ] , entityName , entitySlot , uid2 , userName , online , & extinf ) ;
log . displayNL ( " UId %d UserName '%s' EId %s EntityName '%s' EntitySlot %hd %s%s%s " , uid2 , userName . c_str ( ) , res [ i ] . toString ( ) . c_str ( ) , entityName . toString ( ) . c_str ( ) , ( sint16 ) entitySlot , ( extinf . c_str ( ) ) , ( extinf . empty ( ) ? " " : " " ) , ( online ? " Online " : " Offline " ) ) ;
}
return true ;
}
return false ;
}
}