1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "nel/misc/algo.h"
27 #include "nel/misc/file.h"
28 #include "nel/misc/path.h"
29 #include "nel/misc/command.h"
30 #include "nel/misc/types_nl.h"
31 #include "nel/misc/entity_id.h"
32 #include "nel/misc/eid_translator.h"
33 #include "nel/misc/hierarchical_timer.h"
47 //CEntityIdTranslator *CEntityIdTranslator::Instance = NULL;
48 NLMISC_SAFE_SINGLETON_IMPL(CEntityIdTranslator
);
50 // don't forget to increment the number when you change the file format
51 const uint
CEntityIdTranslator::Version
= 1;
57 void CEntityIdTranslator::CEntity::serial (NLMISC::IStream
&s
)
59 H_AUTO(EIdTrans_serial
);
60 s
.serial (EntityName
);
62 if (CEntityIdTranslator::getInstance()->FileVersion
>= 1)
63 s
.serial (EntitySlot
);
80 //CEntityIdTranslator *CEntityIdTranslator::getInstance ()
82 // if(Instance == NULL)
84 // Instance = new CEntityIdTranslator;
89 void CEntityIdTranslator::getByUser (uint32 uid
, vector
<CEntityId
> &res
)
91 H_AUTO(EIdTrans_getByUser
);
92 for (TEntityCont::iterator it
= RegisteredEntities
.begin(); it
!= RegisteredEntities
.end(); it
++)
94 CEntity
&entity
= it
->second
;
95 if (entity
.UId
== uid
)
97 res
.push_back(it
->first
);
102 void CEntityIdTranslator::getByUser (const string
&userName
, vector
<CEntityId
> &res
, bool exact
)
104 H_AUTO(EIdTrans_getByUser2
);
105 string lowerName
= toLower(userName
);
107 for (TEntityCont::iterator it
= RegisteredEntities
.begin(); it
!= RegisteredEntities
.end(); it
++)
111 CEntity
&entity
= it
->second
;
112 if (toLower(entity
.UserName
) == lowerName
)
114 res
.push_back(it
->first
);
119 CEntity
&entity
= it
->second
;
120 if (toLower(entity
.UserName
).find(lowerName
) != string::npos
)
122 res
.push_back(it
->first
);
128 const ucstring
&CEntityIdTranslator::getByEntity (const CEntityId
&eid
)
130 H_AUTO(EIdTrans_getByEntity
);
131 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
133 reid
.setCreatorId(0);
134 reid
.setDynamicId(0);
136 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
137 if (it
== RegisteredEntities
.end ())
139 static ucstring emptyString
;
144 CEntity
&entity
= it
->second
;
145 return entity
.EntityName
;
149 CEntityId
CEntityIdTranslator::getByEntity (const ucstring
&entityName
)
151 H_AUTO(EIdTrans_getByEntity2
);
152 vector
<CEntityId
> res
;
153 getByEntity (entityName
, res
, true);
155 return CEntityId::Unknown
;
160 void CEntityIdTranslator::getByEntity (const ucstring
&entityName
, vector
<CEntityId
> &res
, bool exact
)
162 H_AUTO(EIdTrans_getByEntity3
);
163 string lowerName
= toLower(entityName
.toString());
167 // use the reverse index to speed up search
168 TNameIndexCont::iterator
it(NameIndex
.find(lowerName
));
169 if (it
!= NameIndex
.end())
170 res
.push_back(it
->second
);
174 // parse the entire container to match all entities
175 for (TEntityCont::iterator it
= RegisteredEntities
.begin(); it
!= RegisteredEntities
.end(); ++it
)
177 CEntity
&entity
= it
->second
;
178 if (toLower(entity
.EntityName
.toString()).find(lowerName
) != string::npos
)
180 res
.push_back(it
->first
);
185 bool CEntityIdTranslator::isValidEntityName (const ucstring
&entityName
,CLog
*log
)
187 H_AUTO(EIdTrans_isValidEntityName
);
189 if (entityName
.size() < 3)
191 log
->displayNL("Bad entity name '%s' (less than 3 char)", entityName
.toString().c_str());
195 if (entityName
.size() > 15)
197 // if a parenthesis is found before 15 chars, the name is valid
198 if (entityName
.find(ucstring("(")) > 15 || entityName
[entityName
.size()-1] != ucchar(')'))
200 log
->displayNL("EIT: Bad entity name '%s' (more than 15 char)", entityName
.toString().c_str());
205 bool allowNumeric
= false;
206 for (uint i
= 0; i
< entityName
.size(); i
++)
208 if (entityName
[i
] == '(')
210 // starting from shard name, allow alphanumeric character
213 // only accept name with alphabetic and numeric value [a-zA-Z] and parenthesis
214 if (!allowNumeric
&& !isalpha (entityName
[i
]) && entityName
[i
] != '(' && entityName
[i
] != ')')
216 log
->displayNL("Bad entity name '%s' (only char and num)", entityName
.toString().c_str());
221 // now check with the invalid name list
222 string en
= getRegisterableString( entityName
);
224 for (uint i
= 0; i
< InvalidEntityNames
.size(); i
++)
226 if(testWildCard(en
, InvalidEntityNames
[i
]))
228 log
->displayNL("Bad entity name '%s' (match the invalid entity name pattern '%s')", entityName
.toString().c_str(), InvalidEntityNames
[i
].c_str());
236 void CEntityIdTranslator::clear()
239 RegisteredEntities
.clear();
243 bool CEntityIdTranslator::checkEntityName (const ucstring
&entityName
)
245 H_AUTO(EIdTrans_entityNameExists
);
246 // if bad name, don't accept it
247 if (!isValidEntityName (entityName
,NLMISC::InfoLog
)) return false;
248 return !entityNameExists( entityName
);
251 bool CEntityIdTranslator::entityNameExists (const ucstring
&entityName
)
253 // Names are stored in case dependant, so we have to test them without case.
254 ucstring registerable
= getRegisterableString (entityName
);
256 return NameIndex
.find(registerable
) !=NameIndex
.end();
257 /* for (TEntityCont::iterator it = RegisteredEntities.begin(); it != RegisteredEntities.end(); it++)
259 if (getRegisterableString ((*it).second.EntityName) == registerable)
268 void CEntityIdTranslator::registerEntity (const CEntityId
&eid
, const ucstring
&entityName
, sint8 entitySlot
, uint32 uid
, const string
&userName
, uint32 shardId
)
270 H_AUTO(EIdTrans_registerEntity
);
271 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
273 reid
.setCreatorId(0);
274 reid
.setDynamicId(0);
276 if (RegisteredEntities
.find (reid
) != RegisteredEntities
.end ())
278 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());
282 if (!checkEntityName(entityName
))
284 if (isValidEntityName(entityName
))
285 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());
287 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());
291 //nlinfo ("EIT: Register EId %s EntityName '%s' UId %d UserName '%s'", reid.toString().c_str(), entityName.toString().c_str(), uid, userName.c_str());
292 RegisteredEntities
.insert (make_pair(reid
, CEntityIdTranslator::CEntity(entityName
, uid
, userName
, entitySlot
, shardId
)));
293 NameIndex
.insert(make_pair(toLower(entityName
), reid
));
296 void CEntityIdTranslator::updateEntity (const CEntityId
&eid
, const ucstring
&entityName
, sint8 entitySlot
, uint32 uid
, const std::string
&userName
, uint32 shardId
)
299 reid
.setCreatorId(0);
300 reid
.setDynamicId(0);
302 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
304 if (it
== RegisteredEntities
.end())
307 registerEntity(eid
, entityName
, entitySlot
, uid
, userName
, shardId
);
311 // update entity entry and name index
312 CEntity
&entity
= it
->second
;
313 if (entity
.EntityName
!= entityName
)
315 if (!checkEntityName(entityName
))
317 nlwarning ("EIT: Can't update EId %s EntityName '%s' UId %d UserName '%s' with new name '%s' because EntityName is already in the map",
318 reid
.toString().c_str(),
319 entity
.EntityName
.toString().c_str(),
322 entityName
.toString().c_str());
325 // update the name and name index
326 NameIndex
.erase(toLower(entity
.EntityName
));
327 NameIndex
.insert(make_pair(toLower(entityName
), reid
));
328 entity
.EntityName
= entityName
;
329 entity
.EntityNameStringId
= 0;
331 entity
.EntitySlot
= entitySlot
;
333 entity
.UserName
= userName
;
334 entity
.ShardId
= shardId
;
339 void CEntityIdTranslator::unregisterEntity (const CEntityId
&eid
)
341 H_AUTO(EIdTrans_unregisterEntity
);
342 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
344 reid
.setCreatorId(0);
345 reid
.setDynamicId(0);
347 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
349 if (it
== RegisteredEntities
.end ())
351 nlwarning ("EIT: Can't unregister EId %s because EId is not in the map", reid
.toString().c_str());
355 CEntity
&entity
= it
->second
;
357 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());
358 NameIndex
.erase(toLower(entity
.EntityName
));
359 RegisteredEntities
.erase (reid
);
362 bool CEntityIdTranslator::isEntityRegistered(const CEntityId
&eid
)
364 H_AUTO(EIdTrans_unregisterEntity
);
365 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
367 reid
.setCreatorId(0);
368 reid
.setDynamicId(0);
370 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
372 return it
!= RegisteredEntities
.end ();
376 void CEntityIdTranslator::checkEntity (const CEntityId
&eid
, const ucstring
&entityName
, uint32 uid
, const string
&userName
)
378 H_AUTO(EIdTrans_checkEntity
);
379 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
381 reid
.setCreatorId(0);
382 reid
.setDynamicId(0);
384 map
<CEntityId
, CEntityIdTranslator::CEntity
>::iterator it
= RegisteredEntities
.find (reid
);
386 nlinfo ("EIT: Checking EId %s EntityName '%s' UId %d UserName '%s'", reid
.toString().c_str(), entityName
.toString().c_str(), uid
, userName
.c_str());
388 if (it
== RegisteredEntities
.end ())
390 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());
392 if (checkEntityName(entityName
))
394 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());
399 CEntity
&entity
= it
->second
;
400 if (entity
.EntityName
!= entityName
)
402 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());
403 if(!entityName
.empty())
405 entity
.EntityName
= entityName
;
408 if (entity
.UId
!= uid
)
410 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());
416 if (entity
.UserName
!= userName
)
418 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());
419 if(!userName
.empty())
421 entity
.UserName
= userName
;
427 void CEntityIdTranslator::removeShardFromName(ucstring
& name
)
429 // The string must contain a '(' and a ')'
430 ucstring::size_type p0
= name
.find('(');
431 ucstring::size_type p1
= name
.find(')');
432 if (p0
== ucstring::npos
|| p1
== ucstring::npos
|| p1
<= p0
)
435 name
= name
.substr(0, p0
) + name
.substr(p1
+ 1);
438 // this callback is call when the file is changed
439 void cbInvalidEntityNamesFilename(const std::string
&invalidEntityNamesFilename
)
441 CEntityIdTranslator::getInstance()->InvalidEntityNames
.clear ();
443 string fn
= CPath::lookup(invalidEntityNamesFilename
, false);
447 nlwarning ("EIT: Can't load filename '%s' for invalid entity names filename (not found)", invalidEntityNamesFilename
.c_str());
451 FILE *fp
= nlfopen (fn
, "r");
454 nlwarning ("EIT: Can't load filename '%s' for invalid entity names filename", fn
.c_str());
461 if (!fgets(str
, 511, fp
))
467 str
[strlen(str
)-1] = '\0';
468 CEntityIdTranslator::getInstance()->InvalidEntityNames
.push_back(str
);
475 void CEntityIdTranslator::load (const string
&fileName
, const string
&invalidEntityNamesFilename
)
477 H_AUTO(EIdTrans_load
);
478 if (fileName
.empty())
480 nlwarning ("EIT: Can't load empty filename for EntityIdTranslator");
484 if (!FileName
.empty())
486 nlwarning ("EIT: Can't load file '%s' for EntityIdTranslator because we already load the file '%s'", fileName
.c_str(), FileName
.c_str());
490 nlinfo ("EIT: CEntityIdTranslator: load '%s'", fileName
.c_str());
494 if(CFile::fileExists(FileName
))
497 if( ifile
.open(FileName
) )
499 FileVersion
= Version
;
500 ifile
.serialVersion (FileVersion
);
501 ifile
.serialCont (RegisteredEntities
);
505 // fill the entity name index container
507 TEntityCont::iterator
first(RegisteredEntities
.begin()), last(RegisteredEntities
.end());
508 for (; first
!= last
; ++first
)
510 NameIndex
.insert(make_pair(toLower(first
->second
.EntityName
), first
->first
));
515 nlwarning ("EIT: Can't load filename '%s' for EntityIdTranslator", FileName
.c_str());
519 cbInvalidEntityNamesFilename (invalidEntityNamesFilename
);
521 NLMISC::CFile::addFileChangeCallback (invalidEntityNamesFilename
, cbInvalidEntityNamesFilename
);
524 void CEntityIdTranslator::save ()
526 H_AUTO(EIdTrans_save
);
528 if (FileName
.empty())
530 nlwarning ("EIT: Can't save empty filename for EntityIdTranslator (you forgot to load() it before?)");
534 nlinfo ("EIT: CEntityIdTranslator: save");
537 if( ofile
.open(FileName
) )
539 ofile
.serialVersion (Version
);
540 FileVersion
= Version
;
541 ofile
.serialCont (RegisteredEntities
);
547 nlwarning ("EIT: Can't save filename '%s' for EntityIdTranslator", FileName
.c_str());
551 uint32
CEntityIdTranslator::getUId (const string
&userName
)
553 const TEntityCont::iterator itEnd
= RegisteredEntities
.end();
554 for (TEntityCont::iterator it
= RegisteredEntities
.begin(); it
!= itEnd
; ++it
)
556 CEntity
&entity
= it
->second
;
557 if (entity
.UserName
== userName
)
565 string
CEntityIdTranslator::getUserName (uint32 uid
)
567 const TEntityCont::iterator itEnd
= RegisteredEntities
.end();
568 for (TEntityCont::iterator it
= RegisteredEntities
.begin(); it
!= itEnd
; ++it
)
570 CEntity
&entity
= it
->second
;
571 if (entity
.UId
== uid
)
573 return entity
.UserName
;
579 void CEntityIdTranslator::getEntityIdInfo (const CEntityId
&eid
, ucstring
&entityName
, sint8
&entitySlot
, uint32
&uid
, string
&userName
, bool &online
, std::string
* additional
)
581 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
583 reid
.setCreatorId(0);
584 reid
.setDynamicId(0);
586 if (additional
!= NULL
)
589 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
590 if (it
== RegisteredEntities
.end ())
592 nlwarning ("EIT: %s is not registered in CEntityIdTranslator", reid
.toString().c_str());
595 uid
= std::numeric_limits
<uint32
>::max();
601 CEntity
&entity
= it
->second
;
602 entityName
= entity
.EntityName
;
603 entitySlot
= entity
.EntitySlot
;
605 userName
= entity
.UserName
;
606 online
= entity
.Online
;
608 if (EntityInfoCallback
!= NULL
&& additional
!= NULL
)
609 *additional
= EntityInfoCallback(eid
);
613 bool CEntityIdTranslator::setEntityNameStringId(const ucstring
&entityName
, uint32 stringId
)
615 const TEntityCont::iterator itEnd
= RegisteredEntities
.end();
616 for (TEntityCont::iterator it
= RegisteredEntities
.begin(); it
!= itEnd
; ++it
)
618 CEntity
&entity
= it
->second
;
619 if (entity
.EntityName
== entityName
)
621 entity
.EntityNameStringId
= stringId
;
629 bool CEntityIdTranslator::setEntityNameStringId(const CEntityId
&eid
, uint32 stringId
)
631 TEntityCont::iterator
it (RegisteredEntities
.find(eid
));
632 if (it
== RegisteredEntities
.end())
634 // there is nothing we can do !
638 CEntity
&entity
= it
->second
;
639 entity
.EntityNameStringId
= stringId
;
644 uint32
CEntityIdTranslator::getEntityNameStringId(const CEntityId
&eid
)
646 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
648 reid
.setCreatorId(0);
649 reid
.setDynamicId(0);
651 const TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
652 if (it
== RegisteredEntities
.end ())
658 CEntity
&entity
= it
->second
;
659 return entity
.EntityNameStringId
;
663 // get the shard id of an entity
664 uint32
CEntityIdTranslator::getEntityShardId(const CEntityId
&eid
)
666 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
668 reid
.setCreatorId(0);
669 reid
.setDynamicId(0);
671 const TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
672 if (it
== RegisteredEntities
.end ())
678 CEntity
&entity
= it
->second
;
679 return entity
.ShardId
;
684 void CEntityIdTranslator::setEntityOnline (const CEntityId
&eid
, bool online
)
686 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
688 reid
.setCreatorId(0);
689 reid
.setDynamicId(0);
691 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
692 if (it
== RegisteredEntities
.end ())
694 nlwarning ("EIT: %s is not registered in CEntityIdTranslator", reid
.toString().c_str());
698 CEntity
&entity
= it
->second
;
699 entity
.Online
= online
;
703 bool CEntityIdTranslator::isEntityOnline (const CEntityId
&eid
)
705 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
707 reid
.setCreatorId(0);
708 reid
.setDynamicId(0);
710 TEntityCont::iterator it
= RegisteredEntities
.find (reid
);
711 if (it
== RegisteredEntities
.end ())
713 nlwarning ("EIT: %s is not registered in CEntityIdTranslator", reid
.toString().c_str());
718 CEntity
&entity
= it
->second
;
719 return entity
.Online
;
723 std::string
CEntityIdTranslator::getRegisterableString( const ucstring
& entityName
)
725 string ret
= toLower( entityName
.toString() );
726 string::size_type pos
= ret
.find( 0x20 );
727 while( pos
!= string::npos
)
730 pos
= ret
.find( 0x20 );
736 NLMISC_CATEGORISED_COMMAND(nel
,findEIdByUser
,"Find entity ids using the user name","<username>|<uid>")
738 if (args
.size () != 1)
741 vector
<CEntityId
> res
;
743 string userName
= args
[0];
744 uint32 uid
= atoi (userName
.c_str());
748 CEntityIdTranslator::getInstance()->getByUser(uid
, res
);
749 userName
= CEntityIdTranslator::getInstance()->getUserName(uid
);
753 CEntityIdTranslator::getInstance()->getByUser(userName
, res
);
754 CEntityIdTranslator::getInstance()->getUId(userName
);
757 log
.displayNL("User Name '%s' (uid=%d) has %d entities:", userName
.c_str(), uid
, res
.size());
758 for (uint i
= 0 ; i
< res
.size(); i
++)
760 log
.displayNL("> %s '%s'", res
[i
].toString().c_str(), CEntityIdTranslator::getInstance()->getByEntity (res
[i
]).c_str());
766 NLMISC_CATEGORISED_COMMAND(nel
,findEIdByEntity
,"Find entity id using the entity name","<entityname>|<eid>")
768 if (args
.size () != 1)
771 CEntityId
eid (args
[0].c_str());
773 if (eid
== CEntityId::Unknown
)
775 eid
= CEntityIdTranslator::getInstance()->getByEntity(args
[0]);
778 if (eid
== CEntityId::Unknown
)
780 log
.displayNL("'%s' is not an eid or an entity name", args
[0].c_str());
791 CEntityIdTranslator::getInstance()->getEntityIdInfo(eid
, entityName
, entitySlot
, uid
, userName
, online
, &extinf
);
793 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"));
798 NLMISC_CATEGORISED_COMMAND(nel
,entityNameValid
,"Tell if an entity name is valid or not using CEntityIdTranslator validation rulez","<entityname>")
800 if (args
.size () != 1) return false;
802 if(!CEntityIdTranslator::getInstance()->isValidEntityName(args
[0], &log
))
804 log
.displayNL("Entity name '%s' is not valid", args
[0].c_str());
808 if (CEntityIdTranslator::getInstance()->checkEntityName(args
[0]))
810 log
.displayNL("Entity name '%s' is already used by another player", args
[0].c_str());
814 log
.displayNL("Entity name '%s' is available", args
[0].c_str());
821 NLMISC_CATEGORISED_COMMAND(nel
,playerInfo
,"Get information about a player or all players in CEntityIdTranslator","[<entityname>|<eid>|<username>|<uid>]")
823 if (args
.size () == 0)
825 const map
<CEntityId
, CEntityIdTranslator::CEntity
> &res
= CEntityIdTranslator::getInstance()->getRegisteredEntities ();
826 log
.displayNL("%d result(s) for 'all players information'", res
.size());
827 for (map
<CEntityId
, CEntityIdTranslator::CEntity
>::const_iterator it
= res
.begin(); it
!= res
.end(); it
++)
829 const CEntityIdTranslator::CEntity
&entity
= it
->second
;
830 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"));
835 else if (args
.size () == 1)
837 vector
<CEntityId
> res
;
839 CEntityId
eid (args
[0].c_str());
840 uint32 uid
= atoi (args
[0].c_str());
842 if (eid
!= CEntityId::Unknown
)
844 // we have to remove the crea and dyna because it can changed dynamically and will not be found in the storage array
852 // the parameter is an uid
853 CEntityIdTranslator::getInstance()->getByUser (uid
, res
);
857 CEntityIdTranslator::getInstance()->getByUser (args
[0], res
, false);
859 CEntityIdTranslator::getInstance()->getByEntity (args
[0], res
, false);
862 log
.displayNL("%d result(s) for '%s'", res
.size(), args
[0].c_str());
863 for (uint i
= 0; i
< res
.size(); i
++)
871 CEntityIdTranslator::getInstance()->getEntityIdInfo (res
[i
], entityName
, entitySlot
, uid2
, userName
, online
, &extinf
);
873 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"));