EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
EntityList.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24  Rewrite: Allan
25 */
26 
27 #include "eve-server.h"
28 
29 #include "EVE_Mail.h"
30 
31 #include "Client.h"
32 #include "ConsoleCommands.h"
33 #include "EntityList.h"
34 #include "EVEServerConfig.h"
35 #include "ServiceDB.h"
36 #include "agents/Agent.h"
37 #include "exploration/Probes.h"
38 #include "map/MapDB.h"
39 #include "market/MarketMgr.h"
40 //#include "market/MarketBotMgr.h"
42 #include "station/Station.h"
43 #include "system/DestinyManager.h"
44 #include "system/SystemManager.h"
50 
52 : m_services( nullptr ),
53 m_targTimer(0, true),
54 m_stampTimer(0, true),
55 m_minuteTimer(0, true),
56 m_startTime(0),
57 m_npcs(0),
58 m_stamp(1000), /* arbitrary. start at 1k. in seconds. used for destiny and client counters */
59 m_minutes(0),
60 m_connections(0),
61 m_clientSeedID(0)
62 {
63  m_agents.clear();
64  m_probes.clear();
65  m_clients.clear();
66  m_players.clear();
67  m_systems.clear();
68  m_stations.clear();
69  m_targMgrs.clear();
70  m_corpMembers.clear();
71 
72  m_shipTracking = sConfig.debug.UseShipTracking;
73 }
74 
76  sLog.Green(" ServerShutdown", " Complete.");
77 }
78 
81 
82  /* start the timers */
83  m_targTimer.Start(250); // testing targeting and scan probes at 4/sec
84  m_stampTimer.Start(1000); // 1hz tic timer
85  m_minuteTimer.Start(60000); // does this need to be accurate?
86 
88  sLog.Green( " ServerInit", "ClientSeed Initialized." );
89 
90  if (is_log_enabled(SERVER__STACKTRACE))
91  sConfig.debug.StackTrace = true;
92 
93  sLog.Blue(" EntityList", "Entity Manager Initialized.");
94 }
95 
102  for (auto cur : m_clients)
103  SafeDelete(cur);
104 
105  m_clients.clear();
106 }
107 
109 {
110  if (m_clients.size() > 0) {
111  sLog.Yellow(" EntityList", "Cleaning up %u clients, %u systems, %u agents, and %u stations", \
112  m_clients.size(), m_systems.size(), m_agents.size(), m_stations.size());
113  } else {
114  sLog.Green(" EntityList", "Cleaning up %u clients, %u systems, %u agents, and %u stations", \
115  m_clients.size(), m_systems.size(), m_agents.size(), m_stations.size());
116  }
117 
118  for (auto cur : m_clients)
119  SafeDelete(cur);
120 
121  for (auto cur : m_agents)
122  SafeDelete(cur.second);
123 
124  for (auto cur : m_systems) {
125  cur.second->UnloadSystem();
126  SafeDelete(cur.second);
127  }
128 
129  sLog.Warning(" EntityList", "Entity List has been closed." );
130 }
131 
132 /* m_clients is used to search for online players and numerous other things.
133  * the problem here is any searching is done thru iteration, which can get expensive.
134  * however, clients are added before their char is selected, so there is no charID for map placement.
135  * maybe use m_clients for basic Process() calls and use m_players for character/client searching
136  *
137  * update: done and working very well.
138  */
139 
140 void EntityList::Add( Client* pClient ) {
141  ++m_connections;
142  if (pClient != nullptr)
143  m_clients.push_back(pClient);
144 }
145 
146 void EntityList::Remove(Client* pClient) {
147  /* note: will get expensive for many clients */
148  std::vector<Client*>::iterator itr = m_clients.begin();
149  for (; itr != m_clients.end(); ++itr)
150  if ((*itr) == pClient) {
151  m_clients.erase(itr);
152  return;
153  }
154 }
155 
157 {
158  if (pClient != nullptr)
159  if (pClient->IsValidSession()) {
160  m_players.emplace(pClient->GetCharacterID(), pClient);
161  if (IsPlayerCorp(pClient->GetCorporationID())) {
162  corpRole role;
163  role.emplace(pClient, pClient->GetCorpRole());
164  m_corpMembers.emplace(pClient->GetCorporationID(), role);
165  }
166  } else {
167  m_players.emplace(pClient->GetCharID(), pClient);
168  // make note about invalid session and failure to add player to corp roles.
169  // this is nbd if player is in npc corp or in player corp with no roles
170  }
171 }
172 
174 {
175  if (pClient != nullptr)
176  if (pClient->IsValidSession()) {
177  m_players.erase(pClient->GetCharacterID());
178  // remove player from corp map, if applicable
179  std::map<uint32, corpRole>::iterator itr = m_corpMembers.find(pClient->GetCorporationID());
180  if (itr != m_corpMembers.end())
181  itr->second.erase(pClient);
182  } else {
183  m_players.erase(pClient->GetCharID());
184  }
185 }
186 
187 
189  Client* pClient(nullptr);
190  std::vector<Client*>::iterator citr = m_clients.begin();
191  while (citr != m_clients.end()) {
192  if ((*citr)->ProcessNet()) {
193  ++citr;
194  } else {
195  pClient = *citr;
196  citr = m_clients.erase(citr);
197  SafeDelete(pClient);
198  }
199  }
200 
201  if (m_targTimer.Check()) {
202  std::unordered_map<SystemEntity*, TargetManager*>::iterator titr = m_targMgrs.begin();
203  while (titr != m_targMgrs.end()) {
204  if (titr->second->Process()) {
205  ++titr;
206  } else {
207  titr = m_targMgrs.erase(titr);
208  }
209  }
210  std::map<uint32, ProbeSE*>::iterator pitr = m_probes.begin();
211  while (pitr != m_probes.end()) {
212  if (pitr->second->ProcessTic()) {
213  ++pitr;
214  } else {
215  pitr = m_probes.erase(pitr);
216  }
217  }
218  }
219 
220  /* check for 1Hz timer tic */
221  if (m_stampTimer.Check()) {
222  double profileStartTime = GetTimeUSeconds();
223 
224  ++m_stamp;
225 
226  for (auto cur : m_players)
227  if (cur.second->IsValidSession()) // verify client is constructed before calling ProcessClient() on it
228  cur.second->ProcessClient();
229 
231  // this wont work....possibility of removing systems, therefore invalidating the iterator.
232  // bad things can happen if this is running parallel on MP
233  //#pragma omp parallel // starts a new team
234  std::map<uint32, SystemManager*>::iterator itr = m_systems.begin();
235  while (itr != m_systems.end()) {
236  if (itr->second == nullptr) { /* this shouldnt happen. log error to make note */
237  sLog.Error(" EntityList::Proc", "Deleting System %u", itr->first);
238  itr = m_systems.erase(itr);
239  continue;
240  } else if (!itr->second->ProcessTic()) { /* Process each loaded system */
241  itr->second->UnloadSystem();
242  SafeDelete(itr->second);
243  itr = m_systems.erase(itr);
244  continue;
245  }
246  ++itr;
247  }
248 
249  // these need 1Hz tics
250  sCivMgr.Process();
251  sBubbleMgr.Process();
252 
253  // these minute tics do not need to be precise
254  if (m_minuteTimer.Check()) {
255  ++m_minutes;
256  sMissionDataMgr.Process(); // 1m
257 
258  if (m_minutes % 5 == 0) { // ~5m
259  sWHMgr.Process();
260  // write something to tic corps vote cases.
261  for (auto cur : m_systems)
262  cur.second->UpdateData(); // update active system timers and dynamic data every 5m
263  }
264  if (m_minutes % 15 == 0) { // ~15m
265  //sMktBotMgr.Process(); // 15m to 30m
266  sConsole.UpdateStatus();
267  }
268  if (m_minutes % 60 == 0) { // ~1h
270  sMktMgr.Process(); // not used - does nothing at this time
271  }
272  }
273 
274  if (sConfig.debug.UseProfiling)
275  sProfiler.AddTime(Profile::entityS, GetTimeUSeconds() - profileStartTime);
276  }
277 }
278 
280  if (!sDataMgr.IsSolarSystem(systemID)) {
281  _log(SERVER__INIT_ERR, "BootSystem() called with invalid systemID (%u)", systemID);
282  return nullptr;
283  }
284 
285  std::map<uint32, SystemManager*>::iterator itr = m_systems.find(systemID);
286  if (itr != m_systems.end())
287  return itr->second;
288 
289  SystemManager* pSM = new SystemManager(systemID, *m_services);
290  if ((pSM == nullptr) or (!pSM->BootSystem())) {
291  _log(SERVER__INIT_ERR, "BootSystem() - Booting system %u failed", systemID);
292  SafeDelete(pSM);
293  return nullptr;
294  }
295 
296  _log(SERVER__INIT, "BootSystem() - Booted system %u", systemID);
297  m_systems[systemID] = pSM;
298  return pSM;
299 }
300 
301 // cannot put add/remove station in header due to incomplete StationItemRef class
302 void EntityList::AddStation(uint32 stationID, StationItemRef itemRef) {
303  m_stations[stationID] = itemRef;
304 }
305 
307  m_stations.erase(stationID);
308 }
309 
311  std::map<uint32, Agent*>::iterator res = m_agents.find(agentID);
312  if (res != m_agents.end())
313  return res->second;
314 
315  Agent* pAgent = new Agent(agentID);
316  if (!pAgent->Load()) {
317  delete pAgent;
318  return nullptr;
319  }
320  m_agents[agentID] = pAgent;
321  return pAgent;
322 }
323 
324 void EntityList::GetClients(std::vector<Client*> &result) const {
325  for (auto cur : m_players)
326  result.push_back(cur.second);
327 }
328 
329 void EntityList::GetCorpClients(std::vector<Client*> &result, uint32 corpID) const {
330  std::map<uint32, corpRole>::const_iterator cItr = m_corpMembers.find(corpID);
331  if (cItr == m_corpMembers.end())
332  return;
333 
334  corpRole::const_iterator itr = cItr->second.begin(), end = cItr->second.end();
335  while (itr != end) {
336  if (itr->first != nullptr)
337  result.push_back(itr->first);
338  ++itr;
339  }
340 }
341 
342 // this method is corrected, as stations have their own guestlist now.
343 void EntityList::GetStationGuestList(uint32 stationID, std::vector<Client*> &result) const {
344  std::map<uint32, StationItemRef>::const_iterator itr = m_stations.find(stationID);
345  if (itr != m_stations.end())
346  itr->second->GetGuestList(result);
347 }
348 
350 {
351  if (m_players.find(charID) == m_players.end())
352  return false;
353  return true;
354 }
355 
357 {
358  if (m_players.find(charID) == m_players.end())
359  return PyStatic.NewFalse();
360  return PyStatic.NewTrue();
361 }
362 
364 {
365  std::map<uint32, Client*>::const_iterator itr = m_players.find(charID);
366  if (itr != m_players.end())
367  return itr->second;
368  return nullptr;
369 }
370 
372  std::map<uint32, StationItemRef>::iterator res = m_stations.find(stationID);
373  if (res != m_stations.end())
374  return res->second;
375  return StationItemRef(nullptr);
376 }
377 
379 {
380  // these should be totally unique. design a way to enforce this
381  std::string str1 = "", str2 = "";
382  for (uint8 i = 0; i < 3; ++i) {
383  str1 += alphaList[MakeRandomInt(0,25)]; //rand() % sizeof(alphaList) - 1
384  str2 += std::to_string(MakeRandomInt(0,9));
385  }
386 
387  std::string res = str1;
388  res += "-";
389  res += str2;
390  // not sure if we need to keep track of these IDs...
391  //m_anomIDs.push_back(res);
392  return res;
393 }
394 
395 void EntityList::GetUpTime( std::string& time )
396 {
397  float seconds = m_stamp - 1000;
398  float minutes = seconds/60;
399  float hours = minutes/60;
400  float days = hours/24;
401  float weeks = days/7;
402  float months = days/30;
403 
404  int s(fmod(seconds, 60));
405  int m(fmod(minutes, 60));
406  int h(fmod(hours, 24));
407  int d(fmod(days, 7));
408  int w(fmod(weeks, 4));
409  int M(fmod(months, 12));
410 
411  std::ostringstream uptime;
412  if (M) {
413  uptime << M << "M" << w << "w" << d << "d" << h << "h" << m << "m" << s << "s";
414  } else if (w) {
415  uptime << w << "w" << d << "d" << h << "h" << m << "m" << s << "s";
416  } else if (d) {
417  uptime << d << "d" << h << "h" << m << "m" << s << "s";
418  } else if (h) {
419  uptime << h << "h" << m << "m" << s << "s";
420  } else if (m) {
421  uptime << m << "m" << s << "s";
422  } else {
423  uptime << s << "s";
424  }
425 
426  //std::shared_ptr<const char*> ret = uptime.str().c_str();
427  time = uptime.str();
428 }
429 
430 
431 // this is my answer to the crazy looping of Multicast shit...
432 void EntityList::CorpNotify(uint32 corpID, uint8 bCastType, const char* notifyType, const char* idType, PyTuple* payload) const
433 {
434  // make sure this is player corp (which it really should be, but just in case....)
435  if (IsNPCCorp(corpID))
436  return;
437  std::map<uint32, Client*> cMap;
438  std::map<uint32, corpRole>::const_iterator cItr = m_corpMembers.find(corpID);
439  if (cItr == m_corpMembers.end()) {
440  PySafeDecRef(payload);
441  return; // no corp members online now. nothing to do here.
442  }
443 
444  // determine who in corp needs to be notified
445  using namespace Notify::Types;
446  //using namespace Corp::Role;
447  // auto doesnt work here...dunno why yet.
448  corpRole::const_iterator itr = cItr->second.begin(), end = cItr->second.end();
449  switch (bCastType) {
450  case CorpNews:
451  case CorpNewCEO:
452  case CharLeftCorp: {
453  // all members?
454  while (itr != end) {
455  cMap.emplace(itr->first->GetCharacterID(), itr->first);
456  ++itr;
457  }
458  } break;
459  case CorpAppNew:
460  case CorpAppReject:
461  case CorpAppAccept: {
462  // who else wants/needs this?
463  // PersonnelManager is only role that can view corp applications
464  while (itr != end) {
465  //if ((itr->second & Corp::Role::Director) == Corp::Role::Director)
466  // cMap.insert(std::make_pair(std::make_pair(itr->first->GetCharacterID(), itr->first)));
468  cMap.emplace(itr->first->GetCharacterID(), itr->first);
469  ++itr;
470  }
471  } break;
472  case CorpVote: {
473  // any member that can vote (has shares)
474  // damn...dunno if i wanna do this one like this....hit db every loop here?? fukin nuts!
475  // this is another vote for putting "corp shares" in character.corpData
476  // well, then we'd have to hit db for offine chars.....omg
477  CorporationDB mdb;
478  while (itr != end) {
479  // if (itr->first->GetChar()->HasShares()) // not written, no underlying code yet
480  if (mdb.HasShares(itr->first->GetCharacterID(), corpID))
481  cMap.emplace(itr->first->GetCharacterID(), itr->first);
482  ++itr;
483  }
484  } break;
485 
486  // unused yet. (not coded or not understood ...mostly the latter at this point in corp code)
487  case CharMedal:
488  case AllMaintenanceBill:
489  case AllWarDeclared:
490  case AllWarSurrender:
491  case AllWarRetracted:
492  case AllWarInvalidated:
493  case CharBill:
494  case CorpAllBill:
495  case BillOutOfMoney:
496  case BillPaidChar:
497  case BillPaidCorpAll:
498  case CorpTaxChange:
499  case CorpDividend:
500  case CorpVoteCEORevoked:
501  case CorpWarDeclared:
503  case CorpWarSurrender:
504  case CorpWarRetracted:
505  case CorpWarInvalidated:
506  case ContainerPassword:
507  case SovAllClaimFail:
508  case SovCorpClaimFail:
509  case SovAllBillLate:
510  case SovCorpBillLate:
511  case SovAllClaimLost:
512  case SovCorpClaimLost:
513  case SovAllClaimAquired:
514  case SovCorpClaimAquired:
515  case AllAnchoring:
516  case AllStructVulnerable:
518  case SovDisruptor:
519  case CorpStructLost:
521  case FWCorpJoin:
522  case FWCorpLeave:
523  case FWCorpKick:
524  case FWCharKick:
525  case FWCorpWarning:
526  case FWCharWarning:
527  case FWCharRankLoss:
528  case FWCharRankGain:
529  case FWAllianceWarning:
530  case FWAllianceKick:
531  case TransactionReversal:
532  case Reimbursement:
533  case TowerAlert:
534  case TowerResourceAlert:
535  case StationAggression1:
536  case StationStateChange:
537  case StationConquer:
538  case StationAggression2:
543  case CorpLiquidation:
546  case SovereigntyIHDamage:
547  case ContactAdd:
548  case ContactEdit:
549  case CorpKicked:
550  case OrbitalAttacked:
551  case OrbitalReinforced:
553  break;
554 
555  // internal corp notifications
556  case FactoryJob: { // factory job completion added to calendar
557  // who else wants/needs this?
558  // lets start with factory manager, and may have to add later
559  while (itr != end) {
561  cMap.emplace(itr->first->GetCharacterID(), itr->first);
562  ++itr;
563  }
564  } break;
565  case MarketOrder: {
566  // who else wants/needs this?
567  // lets start with traders, and may have to add later
568  while (itr != end) {
569  if ((itr->second & Corp::Role::Trader) == Corp::Role::Trader)
570  cMap.emplace(itr->first->GetCharacterID(), itr->first);
571  ++itr;
572  }
573  } break;
574  case WalletChange: {
575  while (itr != end) {
576  if ((itr->second & Corp::Role::Accountant) == Corp::Role::Accountant)
577  cMap.emplace(itr->first->GetCharacterID(), itr->first);
578  if ((itr->second & Corp::Role::Auditor) == Corp::Role::Auditor)
579  cMap.emplace(itr->first->GetCharacterID(), itr->first);
580  // this may need to check if player has access to division changed - will require a LOT more code
582  cMap.emplace(itr->first->GetCharacterID(), itr->first);
583  ++itr;
584  }
585  } break;
586  case ItemUpdateStation: {
587  // all members?
588  while (itr != end) {
589  cMap.emplace(itr->first->GetCharacterID(), itr->first);
590  ++itr;
591  }
592  } break;
593  case ItemUpdateSystem: {
594  // all members?
595  while (itr != end) {
596  cMap.emplace(itr->first->GetCharacterID(), itr->first);
597  ++itr;
598  }
599  } break;
600  }
601 
602  for (auto cur : cMap) {
603  PyIncRef(payload);
604  cur.second->SendNotification( notifyType, idType, payload, false ); // are any of these sequenced?
605  }
606 
607  PyDecRef(payload);
608 }
609 
610 void EntityList::Broadcast(const char* notifyType, const char* idType, PyTuple** payload) const {
611  //build a little notification out of it.
612  EVENotificationStream notify;
613  notify.remoteObject = 1;
614  notify.args = *payload;
615  payload = nullptr; //consumed
616 
617  //now sent it to the client
618  PyAddress dest;
619  dest.type = PyAddress::Broadcast;
620  dest.service = notifyType;
621  dest.bcast_idtype = idType;
622  Broadcast(dest, notify);
623 }
624 
625 void EntityList::Broadcast(const PyAddress &dest, EVENotificationStream &noti) const {
626  for (auto cur : m_players)
627  cur.second->SendNotification(dest, noti);
628 }
629 
630 void EntityList::Multicast(const character_set &cset, const PyAddress &dest, EVENotificationStream &noti) const {
631  std::map<uint32, Client*>::const_iterator itr = m_players.begin();
632  for (auto cur : cset) {
633  itr = m_players.find(cur);
634  if (itr != m_players.end())
635  itr->second->SendNotification(dest, noti);
636  }
637 }
638 
639 // updated to remove looping thru entire client list for each call....still needs work
640 void EntityList::Multicast( const char* notifyType, const char* idType, PyTuple** in_payload, NotificationDestination target, uint32 targID, bool seq )
641 {
642  PyTuple* payload = *in_payload;
643  in_payload = nullptr;
644 
645  std::vector<Client*> cVec;
646  cVec.clear();
647  switch( target ) {
648  case NOTIF_DEST__LOCATION: {
649  if (sDataMgr.IsStation(targID)) {
650  GetStationGuestList(targID, cVec);
651  } else if (sDataMgr.IsSolarSystem(targID)) {
652  SystemManager* pSysMgr = FindOrBootSystem(targID);
653  if (pSysMgr == nullptr)
654  break;
655  pSysMgr->GetClientList(cVec);
656  } else {
657  sLog.Error("EntityList::Multicast 1", "DEST__LOCATION - location %u is neither station nor system", targID);
658  EvE::traceStack();
659  }
660  } break;
662  std::map<uint32, corpRole>::const_iterator cItr = m_corpMembers.find(targID);
663  if (cItr == m_corpMembers.end())
664  break;
665  corpRole::const_iterator itr = cItr->second.begin();
666  while (itr != cItr->second.end()) {
667  cVec.push_back(itr->first);
668  ++itr;
669  }
670  } break;
671  };
672 
673  for (auto cur : cVec) {
674  PyIncRef(payload);
675  cur->SendNotification( notifyType, idType, &payload, seq );
676  }
677 
678  PyDecRef( payload );
679 }
680 
681 // updated. so much better this way.
682 void EntityList::Multicast(const char* notifyType, const char* idType, PyTuple** in_payload, const MulticastTarget &mcset, bool seq)
683 {
684  // consume payload
685  PyTuple* payload = *in_payload;
686  in_payload = nullptr;
687 
688  if (!mcset.characters.empty())
689  for (auto cur : mcset.characters) {
690  std::map<uint32, Client*>::iterator itr = m_players.find(cur);
691  if ( itr != m_players.end()) {
692  PyIncRef(payload);
693  itr->second->SendNotification( notifyType, idType, &payload, seq );
694  }
695  }
696 
697  if (!mcset.locations.empty()) {
698  SystemManager* pSysMgr(nullptr);
699  std::vector<Client*> cVec;
700  cVec.clear();
701  for (auto cur : mcset.locations) {
702  if (sDataMgr.IsStation(cur)) {
703  GetStationGuestList(cur, cVec);
704  } else if (sDataMgr.IsSolarSystem(cur)) {
705  pSysMgr = FindOrBootSystem(cur);
706  if (pSysMgr == nullptr)
707  continue;
708  pSysMgr->GetClientList(cVec);
709  } else {
710  sLog.Error("EntityList::Multicast 2", "location %u is neither station nor system", cur);
711  EvE::traceStack();
712  }
713  }
714  for (auto cur : cVec) {
715  PyIncRef(payload);
716  cur->SendNotification( notifyType, idType, &payload, seq );
717  }
718  }
719 
720  // this will need list of interested parties from corp. update this call to use CorpNotify() where possible.
721  if (!mcset.corporations.empty()) {
722  sLog.Error("EntityList::Multicast 2", "Corporation MulticastTarget called.");
723  EvE::traceStack();
724  for (auto cur : mcset.corporations) {
725  std::map<uint32, corpRole>::const_iterator cItr = m_corpMembers.find(cur);
726  if (cItr == m_corpMembers.end())
727  continue;
728  corpRole::const_iterator itr = cItr->second.begin();
729  while (itr != cItr->second.end()) {
730  PyIncRef(payload);
731  itr->first->SendNotification( notifyType, idType, &payload, seq );
732  ++itr;
733  }
734  }
735  }
736 
737  PyDecRef( payload );
738 }
739 
740 void EntityList::Multicast(const character_set &cset, const char* notifyType, const char* idType, PyTuple** in_payload, bool seq) const
741 {
742  // consume payload
743  PyTuple* payload = *in_payload;
744  in_payload = nullptr;
745 
746  std::map<uint32, Client*>::const_iterator itr = m_players.begin();
747  for (auto cur : cset) {
748  itr = m_players.find(cur);
749  if (itr != m_players.end()) {
750  PyIncRef(payload);
751  itr->second->SendNotification(notifyType, idType, &payload, seq);
752  }
753  }
754  PyDecRef( payload );
755 }
756 
757 void EntityList::Unicast(uint32 charID, const char* notifyType, const char* idType, PyTuple** payload, bool seq) {
758  Client* pClient = FindClientByCharID(charID);
759  if (pClient != nullptr)
760  pClient->SendNotification( notifyType, idType, payload, seq );
761 }
762 
765 //used by gmCommands....i dont like this one either....but at least it's use will be seldom
766 Client* EntityList::FindClientByName(const char* name) const {
767  for (auto cur : m_players) {
768  CharacterRef cRef = cur.second->GetChar();
769  if (cRef.get() != nullptr)
770  if (strcmp(cRef->name(), name) == 0)
771  return cur.second;
772  }
773  return nullptr;
774 }
775 
777 void EntityList::RegisterSID(int64 &sessionID) {
778  /* this whole method is just made up...eventually it will return a unique long long */
779  /* max for int64 = 9223372036854775807 */
780  std::set<int64>::iterator cur = m_sessions.find(sessionID);
781  std::pair<std::_Rb_tree_const_iterator<int64>, bool > test;
782  if (cur == m_sessions.end())
783  test = m_sessions.insert(sessionID);
784  if (test.second)
785  return;
786 }
787 
788 void EntityList::RemoveSID ( int64 sessionID ) {
789  m_sessions.erase(sessionID);
790 }
Base Python wire object.
Definition: PyRep.h:66
#define sConfig
A macro for easier access to the singleton.
void AddPlayer(Client *pClient)
Definition: EntityList.cpp:156
int64 m_startTime
Definition: EntityList.h:204
unsigned __int8 uint8
Definition: eve-compat.h:46
#define IsNPCCorp(itemID)
Definition: EVE_Defines.h:238
void SendNotification(const PyAddress &dest, EVENotificationStream &noti, bool seq=true)
Definition: Client.cpp:2245
std::set< uint32 > corporations
Definition: EntityList.h:60
std::map< uint32, Agent * > m_agents
Definition: EntityList.h:185
PyRep * PyIsOnline(uint32 charID)
Definition: EntityList.cpp:356
#define _log(type, fmt,...)
Definition: logsys.h:124
std::map< uint32, SystemManager * > m_systems
Definition: EntityList.h:182
#define sConsole
void RemovePlayer(Client *pClient)
Definition: EntityList.cpp:173
void Unicast(uint32 charID, const char *notifyType, const char *idType, PyTuple **payload, bool seq=true)
Definition: EntityList.cpp:757
int64 GetCorpRole() const
Definition: Client.h:129
Agent * GetAgent(uint32 agentID)
Definition: EntityList.cpp:310
uint32 m_minutes
Definition: EntityList.h:200
Client * FindClientByName(const char *name) const
Definition: EntityList.cpp:766
#define sProfiler
Definition: dbcore.cpp:39
StationItemRef GetStationByID(uint32 stationID)
Definition: EntityList.cpp:371
std::unordered_map< SystemEntity *, TargetManager * > m_targMgrs
Definition: EntityList.h:188
void Add(Client *pClient)
Definition: EntityList.cpp:140
int32 GetCharacterID() const
Definition: Client.h:113
NotificationDestination
Definition: EntityList.h:49
int32 GetCorporationID() const
Definition: Client.h:123
void GetCorpClients(std::vector< Client * > &result, uint32 corpID) const
Definition: EntityList.cpp:329
void GetClientList(std::vector< Client * > &cVec)
std::map< Client *, int64 > corpRole
Definition: EntityList.h:193
static uint32 SetClientSeed()
Definition: ServiceDB.cpp:34
const char * name()
Respawn timer checks every u minutes
Python tuple.
Definition: PyRep.h:567
void AddStation(uint32 stationID, StationItemRef itemRef)
Definition: EntityList.cpp:302
std::map< uint32, ProbeSE * > m_probes
Definition: EntityList.h:190
void Broadcast(const char *notifyType, const char *idType, PyTuple **payload) const
Definition: EntityList.cpp:610
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
void RegisterSID(int64 &sessionID)
Definition: EntityList.cpp:777
std::map< uint32, corpRole > m_corpMembers
Definition: EntityList.h:194
void Initialize()
Definition: EntityList.cpp:79
#define is_log_enabled(type)
Definition: logsys.h:78
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
void RemoveSID(int64 sessionID)
Definition: EntityList.cpp:788
uint32 m_stamp
Definition: EntityList.h:199
void Multicast(const char *notifyType, const char *idType, PyTuple **in_payload, NotificationDestination target, uint32 target_id, bool seq=true)
Definition: EntityList.cpp:640
double GetTimeUSeconds()
Definition: utils_time.cpp:116
Timer m_minuteTimer
Definition: EntityList.h:172
AddrType type
Definition: PyPacket.h:88
Definition: Agent.h:21
static void ManipulateTimeData()
Definition: MapDB.cpp:270
uint16 m_clientSeedID
Definition: EntityList.h:202
Timer m_stampTimer
Definition: EntityList.h:171
void Shutdown()
Definition: EntityList.cpp:96
SystemManager * FindOrBootSystem(uint32 systemID)
Definition: EntityList.cpp:279
void GetStationGuestList(uint32 stationID, std::vector< Client * > &result) const
Definition: EntityList.cpp:343
bool Check(bool reset=true)
Definition: timer.cpp:62
#define PyStatic
Definition: PyRep.h:1209
X * get() const
Definition: RefPtr.h:213
#define IsPlayerCorp(itemID)
Definition: EVE_Defines.h:241
#define sMktMgr
Definition: MarketMgr.h:86
#define sMissionDataMgr
uint32 GetCharID()
Definition: Client.h:166
#define PyDecRef(op)
Definition: PyRep.h:57
Definition: Client.h:66
std::string GetAnomalyID()
Definition: EntityList.cpp:378
void RemoveStation(uint32 stationID)
Definition: EntityList.cpp:306
static const char alphaList[]
Definition: EVE_Consts.h:19
std::string bcast_idtype
Definition: PyPacket.h:93
unsigned __int32 uint32
Definition: eve-compat.h:50
#define PyIncRef(op)
Definition: PyRep.h:56
T str2(const char *str)
Generic string conversion template.
Definition: str2conv.h:39
std::set< uint32 > characters
Definition: EntityList.h:58
std::map< uint32, StationItemRef > m_stations
Definition: EntityList.h:183
std::set< uint32 > character_set
Definition: EntityList.h:70
double GetFileTimeNow()
Definition: utils_time.cpp:84
#define sWHMgr
Definition: WormholeMgr.h:59
int64 MakeRandomInt(int64 low, int64 high)
Generates random integer from interval [low; high].
Definition: misc.cpp:109
signed __int64 int64
Definition: eve-compat.h:51
std::map< uint32, Client * > m_players
Definition: EntityList.h:180
void GetClients(std::vector< Client * > &result) const
Definition: EntityList.cpp:324
PyServiceMgr * m_services
Definition: EntityList.h:166
Client * FindClientByCharID(uint32 charID) const
Definition: EntityList.cpp:363
Timer m_targTimer
Definition: EntityList.h:173
void traceStack(void)
Definition: misc.cpp:169
void Remove(Client *pClient)
Definition: EntityList.cpp:146
std::string service
Definition: PyPacket.h:92
#define PySafeDecRef(op)
Definition: PyRep.h:61
void Process()
Definition: EntityList.cpp:188
bool IsOnline(uint32 charID)
Definition: EntityList.cpp:349
uint32 m_connections
Definition: EntityList.h:201
void GetUpTime(std::string &time)
Definition: EntityList.cpp:395
void CorpNotify(uint32 corpID, uint8 bCastType, const char *notifyType, const char *idType, PyTuple *payload) const
Definition: EntityList.cpp:432
std::set< int64 > m_sessions
Definition: EntityList.h:181
#define sCivMgr
Definition: CivilianMgr.h:45
void Close()
Definition: EntityList.cpp:108
#define sBubbleMgr
std::set< uint32 > locations
Definition: EntityList.h:59
bool HasShares(uint32 charID, uint32 corpID)
bool IsValidSession()
Definition: Client.h:103
#define sDataMgr
bool m_shipTracking
Definition: EntityList.h:196
void Start(uint32 setTimerTime=0, bool changeResetTimer=true)
Definition: timer.cpp:81
std::vector< Client * > m_clients
Definition: EntityList.h:177