Merge branch '138-toggle-free-look-with-hotkey' into 'main/atys-live'
[ryzomcore.git] / nel / src / misc / eid_translator.cpp
blobd8c7e06ee5aa60bd80297a137239ec2b71742629
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
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/>.
21 // Includes
24 #include "stdmisc.h"
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"
35 using namespace std;
37 #ifdef DEBUG_NEW
38 #define new DEBUG_NEW
39 #endif
41 namespace NLMISC {
44 // Variables
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;
54 // Functions
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);
64 else
66 if(s.isReading())
68 EntitySlot = -1;
70 else
72 sint8 slot = -1;
73 s.serial (slot);
76 s.serial (UId);
77 s.serial (UserName);
80 //CEntityIdTranslator *CEntityIdTranslator::getInstance ()
81 //{
82 // if(Instance == NULL)
83 // {
84 // Instance = new CEntityIdTranslator;
85 // }
86 // return Instance;
87 //}
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++)
109 if (exact)
111 CEntity &entity = it->second;
112 if (toLower(entity.UserName) == lowerName)
114 res.push_back(it->first);
117 else
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
132 CEntityId reid(eid);
133 reid.setCreatorId(0);
134 reid.setDynamicId(0);
136 TEntityCont::iterator it = RegisteredEntities.find (reid);
137 if (it == RegisteredEntities.end ())
139 static ucstring emptyString;
140 return emptyString;
142 else
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);
154 if (res.empty())
155 return CEntityId::Unknown;
156 else
157 return res[0];
160 void CEntityIdTranslator::getByEntity (const ucstring &entityName, vector<CEntityId> &res, bool exact)
162 H_AUTO(EIdTrans_getByEntity3);
163 string lowerName = toLower(entityName.toString());
165 if (exact)
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);
172 return;
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);
188 // 3 char at least
189 if (entityName.size() < 3)
191 log->displayNL("Bad entity name '%s' (less than 3 char)", entityName.toString().c_str());
192 return false;
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());
201 return false;
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
211 allowNumeric = true;
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());
217 return false;
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());
229 return false;
233 return true;
236 void CEntityIdTranslator::clear()
238 NameIndex.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)
261 return true;
264 return false;
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
272 CEntityId reid(eid);
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());
279 return;
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());
286 else
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());
288 return;
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)
298 CEntityId reid(eid);
299 reid.setCreatorId(0);
300 reid.setDynamicId(0);
302 TEntityCont::iterator it = RegisteredEntities.find (reid);
304 if (it == RegisteredEntities.end())
306 // just register
307 registerEntity(eid, entityName, entitySlot, uid, userName, shardId);
309 else
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(),
320 uid,
321 userName.c_str(),
322 entityName.toString().c_str());
323 return;
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;
332 entity.UId = uid;
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
343 CEntityId reid(eid);
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());
352 return;
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
366 CEntityId reid(eid);
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
380 CEntityId reid(eid);
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());
397 else
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());
411 if (uid != 0)
413 entity.UId = uid;
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)
433 return;
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);
445 if (fn.empty())
447 nlwarning ("EIT: Can't load filename '%s' for invalid entity names filename (not found)", invalidEntityNamesFilename.c_str());
448 return;
451 FILE *fp = nlfopen (fn, "r");
452 if (fp == NULL)
454 nlwarning ("EIT: Can't load filename '%s' for invalid entity names filename", fn.c_str());
455 return;
458 for(;;)
460 char str[512];
461 if (!fgets(str, 511, fp))
462 break;
463 if(feof(fp))
464 break;
465 if (strlen(str) > 0)
467 str[strlen(str)-1] = '\0';
468 CEntityIdTranslator::getInstance()->InvalidEntityNames.push_back(str);
472 fclose (fp);
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");
481 return;
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());
487 return;
490 nlinfo ("EIT: CEntityIdTranslator: load '%s'", fileName.c_str());
492 FileName = fileName;
494 if(CFile::fileExists(FileName))
496 CIFile ifile;
497 if( ifile.open(FileName) )
499 FileVersion = Version;
500 ifile.serialVersion (FileVersion);
501 ifile.serialCont (RegisteredEntities);
503 ifile.close ();
505 // fill the entity name index container
506 NameIndex.clear();
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));
513 else
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?)");
531 return;
534 nlinfo ("EIT: CEntityIdTranslator: save");
536 COFile ofile;
537 if( ofile.open(FileName) )
539 ofile.serialVersion (Version);
540 FileVersion = Version;
541 ofile.serialCont (RegisteredEntities);
543 ofile.close ();
545 else
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)
559 return entity.UId;
562 return 0;
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;
576 return string();
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
582 CEntityId reid(eid);
583 reid.setCreatorId(0);
584 reid.setDynamicId(0);
586 if (additional != NULL)
587 additional->clear();
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());
593 entityName.clear();
594 entitySlot = -1;
595 uid = std::numeric_limits<uint32>::max();
596 userName.clear();
597 online = false;
599 else
601 CEntity &entity = it->second;
602 entityName = entity.EntityName;
603 entitySlot = entity.EntitySlot;
604 uid = entity.UId;
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;
622 return true;
626 return false;
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 !
635 return false;
638 CEntity &entity = it->second;
639 entity.EntityNameStringId = stringId;
641 return true;
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
647 CEntityId reid(eid);
648 reid.setCreatorId(0);
649 reid.setDynamicId(0);
651 const TEntityCont::iterator it = RegisteredEntities.find (reid);
652 if (it == RegisteredEntities.end ())
654 return 0;
656 else
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
667 CEntityId reid(eid);
668 reid.setCreatorId(0);
669 reid.setDynamicId(0);
671 const TEntityCont::iterator it = RegisteredEntities.find (reid);
672 if (it == RegisteredEntities.end ())
674 return 0;
676 else
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
687 CEntityId reid(eid);
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());
696 else
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
706 CEntityId reid(eid);
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());
714 return false;
716 else
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 )
729 ret.erase( pos,1 );
730 pos = ret.find( 0x20 );
732 return ret;
736 NLMISC_CATEGORISED_COMMAND(nel,findEIdByUser,"Find entity ids using the user name","<username>|<uid>")
738 if (args.size () != 1)
739 return false;
741 vector<CEntityId> res;
743 string userName = args[0];
744 uint32 uid = atoi (userName.c_str());
746 if (uid != 0)
748 CEntityIdTranslator::getInstance()->getByUser(uid, res);
749 userName = CEntityIdTranslator::getInstance()->getUserName(uid);
751 else
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());
763 return true;
766 NLMISC_CATEGORISED_COMMAND(nel,findEIdByEntity,"Find entity id using the entity name","<entityname>|<eid>")
768 if (args.size () != 1)
769 return false;
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());
781 return false;
784 ucstring entityName;
785 sint8 entitySlot;
786 uint32 uid;
787 string userName;
788 bool online;
789 std::string extinf;
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"));
795 return true;
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());
806 else
808 if (CEntityIdTranslator::getInstance()->checkEntityName(args[0]))
810 log.displayNL("Entity name '%s' is already used by another player", args[0].c_str());
812 else
814 log.displayNL("Entity name '%s' is available", args[0].c_str());
818 return true;
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"));
833 return true;
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
845 eid.setCreatorId(0);
846 eid.setDynamicId(0);
848 res.push_back(eid);
850 else if (uid != 0)
852 // the parameter is an uid
853 CEntityIdTranslator::getInstance()->getByUser (uid, res);
855 else
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++)
865 ucstring entityName;
866 sint8 entitySlot;
867 uint32 uid2;
868 string userName;
869 bool online;
870 std::string extinf;
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"));
876 return true;
879 return false;