EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SystemManager.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  This program is distributed in the hope that it will be useful, but WITHOUT
14  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16  You should have received a copy of the GNU Lesser General Public License along with
17  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19  http://www.gnu.org/copyleft/lesser.txt.
20  ------------------------------------------------------------------------------------
21  Author: Zhur
22  Rewrite: Allan
23  Updates: James
24 */
25 
26 #include "eve-server.h"
27 
28 #include "Client.h"
29 #include "EVEServerConfig.h"
30 #include "account/AccountService.h"
31 #include "chat/LSCService.h"
32 #include "exploration/Probes.h"
33 #include "npc/Drone.h"
34 #include "npc/NPC.h"
35 #include "npc/Sentry.h"
36 #include "packets/Destiny.h"
37 #include "planet/Planet.h"
38 #include "planet/Moon.h"
39 #include "planet/CustomsOffice.h"
40 #include "pos/Array.h"
41 #include "pos/Battery.h"
42 #include "pos/Module.h"
43 #include "pos/Structure.h"
44 #include "pos/Tower.h"
45 #include "pos/sovStructures/TCU.h"
46 #include "pos/sovStructures/SBU.h"
47 #include "pos/sovStructures/IHub.h"
48 #include "pos/JumpBridge.h"
49 #include "pos/Weapon.h"
50 #include "ship/Missile.h"
51 #include "ship/Ship.h"
52 #include "station/Station.h"
53 #include "system/Asteroid.h"
54 #include "system/Container.h"
55 #include "system/DestinyManager.h"
56 #include "system/SolarSystem.h"
57 #include "system/SystemBubble.h"
58 #include "system/SystemManager.h"
63 
65 :m_services(svc),
66 m_bountyTimer(0),
67 m_minutetimer(0, true),
68 m_anomMgr(new AnomalyMgr(this, svc)),
69 m_beltMgr(new BeltMgr(this, svc)),
70 m_dungMgr(new DungeonMgr(this, svc)),
71 m_spawnMgr(new SpawnMgr(this, svc)),
72 m_loaded(false),
73 m_entityChanged(false),
74 m_docked(0),
75 m_players(0),
76 m_beltCount(0),
77 m_gateCount(0),
78 m_activityTime(0),
79 m_activeRatSpawns(0),
80 m_activeGateSpawns(0),
81 m_activeRoidSpawns(0),
82 m_secValue(1.1f)
83 {
84  m_minutes = 0;
85 
86  m_npcs.clear();
87  m_clients.clear();
88  m_jumpMap.clear();
89  m_moonMap.clear();
90  m_entities.clear();
91  m_planetMap.clear();
92  m_gateMap.clear();
93  m_ratBubbles.clear();
94  m_beltVector.clear();
95  m_roidBubbles.clear();
96  m_ticEntities.clear();
97  m_staticEntities.clear();
98  m_opStaticEntities.clear();
99 
100  // zero-init our data containers
101  m_data = SystemData();
103 
104  sDataMgr.GetSystemData(systemID, m_data); // system data is now an internal memory (cached) object. db is hit once at system boot.
105  m_secValue -= m_data.securityRating; // range is 0.1 for 1.0 system to 2.0 for -0.9 system
106 
107  _log(COMMON__MESSAGE, "Created SystemManager %p for System %s(%u)", this, m_data.name.c_str(), m_data.systemID);
108 }
109 
111  if (m_players or !m_clients.empty()) {
112  _log(COMMON__ERROR, "D'tor called for System %u with %u players and/or %u clients in mmaps", m_data.systemID, m_players, m_clients.size());
113  for (auto cur : m_clients)
114  sEntityList.Remove(cur.second);
115  }
116 
117  if (m_loaded)
118  UnloadSystem();
119 
124 }
125 
127  // dont fuck with this order...
128 
129  m_solarSystemRef = sItemFactory.GetSolarSystem(m_data.systemID);
130  assert(m_solarSystemRef.get() != nullptr);
131 
132  if (!LoadSystemStatics()) {
133  _log(SERVICE__ERROR, "Unable to load System Statics during boot of system %u.", m_data.systemID);
134  return false;
135  }
136 
137  if (!LoadCosmicMgrs()) {
138  _log(SERVICE__ERROR, "Unable to load Cosmic Managers during boot of system %u.", m_data.systemID);
139  return false;
140  }
141 
142  if (!LoadSystemDynamics()) {
143  _log(SERVICE__ERROR, "Unable to load System Dynamics during boot of system %u.", m_data.systemID);
144  return false;
145  }
146 
147  if (!LoadPlayerDynamics()) {
148  _log(SERVICE__ERROR, "Unable to load System Dynamics during boot of system %u.", m_data.systemID);
149  return false;
150  }
151 
152  // check for operational static entities which need to be initialized (such as sovereignty structures)
153  for (auto cur: m_opStaticEntities)
154  if (cur.second ->IsTCUSE())
155  cur.second->GetTCUSE()->Init();
156  else if (cur.second ->IsSBUSE())
157  cur.second->GetSBUSE()->Init();
158  else if (cur.second ->IsIHubSE())
159  cur.second->GetIHubSE()->Init();
160 
161  // system is loaded. check for items that need initialization
162  for (auto cur : m_ticEntities)
163  if (cur.second->IsPOSSE())
164  cur.second->GetPOSSE()->Init();
165 
166  // check planets for colony/customs office
167  /* does not work as intended
168  for (auto cur : m_planetMap)
169  if (cur.second->GetPlanetSE()->HasColony())
170  if (!cur.second->GetPlanetSE()->HasCOSE())
171  cur.second->GetPlanetSE()->CreateCustomsOffice();
172  */
173 
174  if (sConfig.server.BountyPayoutDelayed)
175  m_bountyTimer.Start(sConfig.server.BountyPayoutTimer * 60 * 1000);
176 
177  //create our chat channels
181 
182  // inform MarketBot of loaded system and stations in this system.
183  //sMktBotMgr.AddSystem();
184 
185  // set system active for system status page
187 
188  // load dynamic map data
190 
191  //start minute timer
192  m_minutetimer.Start(60000);
193 
194  return (m_loaded = true);
195 }
196 
198 {
199  if (!m_spawnMgr->Init()) {
200  _log(SERVICE__ERROR, "Unable to load Spawn Manager during boot of system %u.", m_data.systemID);
201  return false;
202  }
203 
205  _log(SERVICE__ERROR, "Unable to load Dungeon Manager during boot of system %u.", m_data.systemID);
206  return false;
207  }
208 
209  if (m_beltCount)
210  m_beltMgr->Init(m_data.regionID); //nothing to check for in this init.
211 
213  _log(SERVICE__ERROR, "Unable to load Anomaly Manager during boot of system %u.", m_data.systemID);
214  return false;
215  }
216 
217  return true;
218 }
219 
220 //called once per second from EntityList. (1Hz Tic)
222  double profileStartTime = GetTimeUSeconds();
223 
224  /* the idea here is entities map NEVER has invalid items in it, but our iterator may become invalid
225  * when SE->Process() returns because Process() will add/remove from the map as needed
226  * (new objects, destroyed objects, moved objects, etc)
227  * std::map internally orders items by key(itemID here), so use an int var to hold last-processed itemID (mLast).
228  * when iteration starts over, increment until cur > mLast and continue from there to end of list.
229  */
230  std::map<uint32, SystemEntity*>::iterator itr = m_ticEntities.begin();
231  uint32 mLast(0);
232  while (itr != m_ticEntities.end()) {
233  if (mLast >= itr->first) {
234  ++itr;
235  continue;
236  }
237 
238  /* main process call. */
239  mLast = itr->first; // not sure if this will slow this down or not. check profile
240  itr->second->Process();
241 
242  if (m_entityChanged) {
243  m_entityChanged = false;
244  itr = m_ticEntities.begin();
245  continue;
246  }
247  ++itr;
248  }
249 
250  // tic for sov structures (as they aren't in ticEntities)
251  for (auto cur : m_opStaticEntities)
252  if (cur.second->IsTCUSE())
253  cur.second->GetTCUSE()->Process();
254  else if (cur.second ->IsSBUSE())
255  cur.second->GetSBUSE()->Process();
256  else if (cur.second ->IsIHubSE())
257  cur.second->GetIHubSE()->Process();
258 
259  // check bounty timer
260  if (m_bountyTimer.Check(sConfig.server.BountyPayoutDelayed))
261  PayBounties();
262  /* the following are coded for single-tic calls */
263  m_anomMgr->Process();
264  if (m_beltCount)
265  m_beltMgr->Process();
266  m_dungMgr->Process();
267  m_spawnMgr->Process();
268 
269  // process planets for PI
270  if (m_minutetimer.Check()) {
271  //++m_minutes; // not used at this time
272  for (auto cur : m_planetMap)
273  cur.second->Process();
274  }
275 
276  if (sConfig.debug.UseProfiling)
277  sProfiler.AddTime(Profile::system, GetTimeUSeconds() - profileStartTime);
278 
279  return SystemActivity();
280 }
281 
283  if (m_activityTime == 0)
284  return true;
285  if ((sEntityList.GetStamp() - m_activityTime) > 60)
286  return false;
287 
288  return true;
289 }
290 
291 // called from EntityList::Process() and EntityList::Close()
293  if (!m_loaded)
294  return;
295 
296  sLog.Magenta(" SystemManager", "UnloadSystem() called for %s(%u).", m_data.name.c_str(), m_data.systemID);
297 
298  // inform MarketBot of system unloading to remove system stations from proc loop.
299  //sMktBotMgr.RemoveSystem();
300 
301  // system is being unloaded. pay bounties now
302  PayBounties();
303  // unload belts, which saves and removes roids from system
304  m_beltMgr->ClearAll();
305  // close anomaly mgr, which saves and removes sigs from system
306  m_anomMgr->Close();
307 
308  // remove static and dynamic entities
309  std::map<uint32, SystemEntity*>::iterator itr = m_entities.begin();
310  SystemEntity* pSE(nullptr);
311  while (itr != m_entities.end()) {
312  if ((itr->first == 0) or (itr->second == nullptr)) {
313  itr = m_entities.erase(itr);
314  continue;
315  }
316  pSE = itr->second;
317 
318  if (pSE->TargetMgr() != nullptr)
319  pSE->TargetMgr()->Unload();
320 
321  if (pSE->IsStaticEntity() or pSE->isGlobal()) {
322  if (pSE->IsStationSE()) {
323  pSE->GetStationSE()->UnloadStation();
324  sEntityList.RemoveStation(itr->first);
325  }
326  m_staticEntities.erase(m_staticEntities.find(itr->first));
327  } else if (pSE->IsShipSE()) {
328  pSE->GetShipSE()->GetShipItemRef()->LogOut();
329  } else if (pSE->IsNPCSE()) {
330  sEntityList.RemoveNPC(); // this is for loaded npc count.
331  pSE->GetSelf()->Delete();
332  } else if (pSE->IsProbeSE()) {
333  sEntityList.RemoveProbe(itr->first);
334  }
335 
336  if (pSE->IsOperSE()) { //Remove operational statics from list
337  m_opStaticEntities.erase(m_opStaticEntities.find(itr->first));
338  }
339 
340  sItemFactory.RemoveItem(itr->first);
341  itr = m_entities.erase(itr);
342  sBubbleMgr.Remove(pSE);
343  SafeDelete(pSE);
344  }
345 
346  // save items, then remove from system inventory, item factory and decrement item count
348  _log(PHYSICS__MESSAGE, "SystemManager::UnloadSystem() - map count after unload: %u npcs, %u entities, %u statics.", \
349  m_npcs.size(), m_entities.size(), m_staticEntities.size());
350 
351  // this is dupe container. contents unloaded in another call
352  m_npcs.clear();
353  // at this point, system entity list should be clear...but just in case, hit it again
354  m_entities.clear();
355  // this is dupe container. contents unloaded in another call
356  m_ticEntities.clear();
357  // at this point, system static entity list should be clear...but just in case, hit it again
358  m_staticEntities.clear();
359  // clear operational static entity list too
360  m_opStaticEntities.clear();
361 
362  // this still needs some work... seems ok to me. 26Dec18
363  sBubbleMgr.ClearSystemBubbles(m_data.systemID);
364 
365  // remove dungeon shit for this system?
366  // are we saving it for later or is it make-on-boot?
368 
369  // set system inactive for system status page
371 
374 
375  // remove solar system item from ItemFactory
376  sItemFactory.RemoveItem(m_data.systemID);
377  m_loaded = false;
378 }
379 
381  std::vector<DBSystemEntity> entities;
382  entities.clear();
383  m_entities.clear();
384  m_staticEntities.clear();
386  sLog.Error( "SystemManager::LoadSystemStatics()", "Unable to load celestial entities during boot of %s(%u).", m_data.name.c_str(), m_data.systemID);
387  return false;
388  }
389 
390  SystemEntity* pSE(nullptr);
391  for (auto cur : entities) {
392  switch (cur.groupID) {
395  /* types 12242 - 22298 in group 15 are outposts */
396  /* types 29323 - 29390 in group 15 are wrecked stations */
397  StationItemRef itemRef = sItemFactory.GetStationItem(cur.itemID);
398  StationSE *pSSE = new StationSE(itemRef, *(GetServiceMgr()), this);
399  sEntityList.AddStation(cur.itemID, itemRef);
400  pSE = pSSE;
401  } break;
403  CelestialObjectRef itemRef = sItemFactory.GetCelestialObject(cur.itemID);
404  BeltSE *pBSE = new BeltSE(itemRef, *(GetServiceMgr()), this);
405  pBSE->SetBeltMgr(m_beltMgr);
406  ++m_beltCount;
407  pSE = pBSE;
408  } break;
410  CelestialObjectRef itemRef = sItemFactory.GetCelestialObject(cur.itemID);
411  itemRef->SetAttribute(AttrRadius, cur.radius, false);
412  StargateSE *pSSE = new StargateSE(itemRef, *(GetServiceMgr()), this);
413  m_gateMap.insert(std::pair<uint32, SystemEntity*>(cur.itemID, pSSE));
414  ++m_gateCount;
415  pSE = pSSE;
416  } break;
418  CelestialObjectRef itemRef = sItemFactory.GetCelestialObject(cur.itemID);
419  itemRef->SetAttribute(AttrRadius, cur.radius, false);
420  PlanetSE *pPSE = new PlanetSE(itemRef, *(GetServiceMgr()), this);
421  m_planetMap.insert(std::pair<uint32, SystemEntity*>(cur.itemID, pPSE));
422  pSE = pPSE;
423  } break;
424  case EVEDB::invGroups::Moon: {
425  CelestialObjectRef itemRef = sItemFactory.GetCelestialObject(cur.itemID);
426  itemRef->SetAttribute(AttrRadius, cur.radius, false);
427  MoonSE *pMSE = new MoonSE(itemRef, *(GetServiceMgr()), this);
428  m_moonMap.insert(std::pair<uint32, SystemEntity*>(cur.itemID, pMSE));
429  pSE = pMSE;
430  } break;
431  case EVEDB::invGroups::Sun: { // suns dont have anything special, so they are generic SSEs
432  CelestialObjectRef itemRef = sItemFactory.GetCelestialObject(cur.itemID);
433  itemRef->SetAttribute(AttrRadius, cur.radius, false);
434  StaticSystemEntity *pSSE = new StaticSystemEntity(itemRef, *(GetServiceMgr()), this);
435  pSE = pSSE;
436  } break;
437  default: {
438  sLog.Error( "SystemManager::LoadSystemStatics()", "create static entity called for unhandled item %u (grp: %u, type %u)", cur.itemID, cur.groupID, cur.typeID);
439  continue;
440  }
441  }
442  if (pSE == nullptr) {
443  sLog.Error( "SystemManager::LoadSystemStatics()", "Failed to create entity for item %u (grp: %u, type %u)", cur.itemID, cur.groupID, cur.typeID);
444  continue;
445  }
446  if (pSE->IsGateSE() or pSE->IsStationSE())
447  sBubbleMgr.Add(pSE);
448  if (pSE->IsBeltSE()) {
449  sBubbleMgr.Add(pSE);
450  m_beltVector.push_back(cur.itemID);
451  }
452  if (!pSE->LoadExtras())
453  _log(INV__WARNING, "SystemManager::LoadSystemStatics() - Failed to load additional data for entity %u. Continuing.", cur.itemID);
454 
455  m_entities[cur.itemID] = pSE;
456  m_staticEntities[cur.itemID] = pSE;
457  AddItemToInventory(pSE->GetSelf());
458  }
459 
460  _log(SERVER__INIT, "SystemManager::LoadSystemStatics() - %u Static System entities loaded for %s (%u)", entities.size(), m_data.name.c_str(), m_data.systemID);
461  entities.clear();
462  return true;
463 }
464 
466  std::vector<DBSystemDynamicEntity> entities;
467  entities.clear();
469  sLog.Error( "SystemManager::LoadSystemDynamics()", "Unable to load dynamic entities during boot of %s(%u).", m_data.name.c_str(), m_data.systemID);
470  return false;
471  }
472 
473  SystemEntity* pSE(nullptr);
474  for (auto cur : entities) {
475  pSE = DynamicEntityFactory::BuildEntity(*this, cur);
476  if (pSE == nullptr) {
477  sLog.Error( "SystemManager::LoadSystemDynamics()", "Failed to create entity for item %u (grp: %u, type %u)",
478  cur.itemID, cur.groupID, cur.typeID);
479  continue;
480  }
481  _log(ITEM__TRACE, "SystemManager::LoadSystemDynamics() - Loaded dynamic entity %u of type %u for %s(%u)", \
482  cur.itemID, cur.typeID, m_data.name.c_str(), m_data.systemID);
483  if (pSE->GetPosition().isZero())
485  //pSE->SetPosition(mGP.GetRandPointOnMoon(m_data.systemID));
486  AddEntity(pSE);
487  }
488  _log(SERVER__INIT, "SystemManager::LoadSystemDynamics - %u Dynamic System entities loaded for %s(%u)", entities.size(), m_data.name.c_str(),m_data.systemID);
489 
490  return true;
491 }
492 
494  std::vector<DBSystemDynamicEntity> entities;
495  entities.clear();
497  sLog.Error( "SystemManager::LoadPlayerDynamics()", "Unable to load player dynamic entities in %s(%u).", m_data.name.c_str(), m_data.systemID);
498  return false;
499  }
500 
501  SystemEntity* pSE(nullptr);
502  for (auto cur : entities) {
503  pSE = DynamicEntityFactory::BuildEntity(*this, cur);
504  if (pSE == nullptr) {
505  sLog.Error( "SystemManager::LoadPlayerDynamics()", "Failed to create entity for item %u (grp: %u, type %u)", cur.itemID, cur.groupID, cur.typeID);
506  continue;
507  }
508  _log(ITEM__TRACE, "SystemManager::LoadPlayerDynamics() - Loaded dynamic entity %u of type %u for %s(%u)", \
509  cur.itemID, cur.typeID, m_data.name.c_str(),m_data.systemID);
510  if (pSE->GetPosition().isZero())
512  //pSE->SetPosition(mGP.GetRandPointOnPlanet(m_data.systemID));
513  AddEntity(pSE);
514  }
515  _log(SERVER__INIT, "SystemManager::LoadPlayerDynamics() - %u Dynamic Player entities loaded for %s(%u)", \
516  entities.size(), m_data.name.c_str(),m_data.systemID);
517 
518  return true;
519 }
520 
521 bool SystemManager::BuildDynamicEntity(const DBSystemDynamicEntity& entity, uint32 launcherID/*0*/) {
522  SystemEntity* pSE = DynamicEntityFactory::BuildEntity(*this, entity);
523  if (pSE == nullptr) {
524  sLog.Error( "SystemManager::BuildDynamicEntity()", "Failed to create entity for item %u (grp: %u, type %u)", entity.itemID, entity.groupID, entity.typeID);
525  return false;
526  }
527 
528  _log(ITEM__TRACE, "SystemManager::BuildDynamicEntity() - Created dynamic entity %u of type %u for %s(%u)", \
529  entity.itemID, entity.typeID, m_data.name.c_str(),m_data.systemID );
530  AddEntity(pSE);
531 
532  // this is only used for wrecks...
533  if (launcherID) {
534  WreckSE* pWE = pSE->GetWreckSE();
535  pWE->SetLaunchedByID(launcherID);
536  if (IsCharacterID(entity.ownerID)) {
537  Client* pClient = sEntityList.FindClientByCharID(entity.ownerID);
538  if (pClient->InFleet())
539  pWE->SetFleetID(pClient->GetFleetID());
540  }
541  }
542  return true;
543 }
544 
546 {
547  FactionData data = FactionData();
548  data.allianceID = entity.allianceID;
549  data.corporationID = entity.corporationID;
550  data.factionID = entity.factionID;
551  data.ownerID = entity.ownerID;
552 
553  switch (entity.categoryID) {
555  InventoryItemRef asteroid = sItemFactory.GetItem( entity.itemID );
556  if (asteroid.get() == nullptr)
557  ;
558  AsteroidSE* aSE = new AsteroidSE(asteroid, *(sysMgr.GetServiceMgr()), &sysMgr);
559  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making AsteroidSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
560  return aSE;
561  } break;
563  ShipItemRef ship = sItemFactory.GetShip( entity.itemID );
564  if (ship.get() == nullptr)
565  return nullptr;
567  ShipSE* sSE = new ShipSE(ship, *(sysMgr.GetServiceMgr()), &sysMgr, data);
568  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making ShipSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
569  return sSE;
570  } break;
572  InventoryItemRef deployable = sItemFactory.GetItem( entity.itemID );
573  if (deployable.get() == nullptr)
574  return nullptr;
576  deployable->SetAttribute(AttrRadius, deployable->type().radius()); // Can you set this somehow from the type class ?
577  DeployableSE* dSE = new DeployableSE(deployable, *(sysMgr.GetServiceMgr()), &sysMgr, data);
578  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making DeployableSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
579  return dSE;
580  } break;
581  // these should go into m_staticEntities
582  case EVEDB::invCategories::StructureUpgrade: // SOV upgrade structures these may need their own class one day.
583  case EVEDB::invCategories::Structure: { // POS items
584  StructureItemRef structure = sItemFactory.GetStructure( entity.itemID );
585  if (structure.get() == nullptr)
586  return nullptr;
588  StructureSE* pSSE(nullptr);
589  switch(entity.groupID) {
591  TowerSE* tSE = new TowerSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
592  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making TowerSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
593  pSSE = tSE;
594  } break;
599  WeaponSE* wSE = new WeaponSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
600  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making WeaponSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
601  pSSE = wSE;
602  } break;
609  BatterySE* bSE = new BatterySE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
610  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making BatterySE for %s (%u)", entity.itemName.c_str(), entity.itemID);
611  pSSE = bSE;
612  } break;
623  ArraySE* aSE = new ArraySE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
624  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making ArraySE for %s (%u)", entity.itemName.c_str(), entity.itemID);
625  pSSE = aSE;
626  } break;
630  ReactorSE* rSE = new ReactorSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
631  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making ReactorSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
632  pSSE = rSE;
633  } break;
635  JumpBridgeSE* jbSE = new JumpBridgeSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
636  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making JumpBridgeSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
637  pSSE = jbSE;
638  } break;
639  default: {
640  StructureSE* sSE = new StructureSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
641  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making StructureSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
642  pSSE = sSE;
643  } break;
644  }
645  return pSSE;
646  } break;
647  case EVEDB::invCategories::SovereigntyStructure: {// SOV structures
648  //Create item ref
649  StructureItemRef structure = sItemFactory.GetStructure( entity.itemID );
650  if (structure.get() == nullptr)
651  return nullptr;
652  StructureSE* sSSE(nullptr);
653  //Test for different types of sov structures
654  switch(entity.groupID) {
656  TCUSE* sSE = new TCUSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
657  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making TCUSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
658  sSSE = sSE;
659  } break;
661  SBUSE* sSE = new SBUSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
662  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making SBUSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
663  sSSE = sSE;
664  } break;
666  IHubSE* sSE = new IHubSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
667  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making IHubSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
668  sSSE = sSE;
669  } break;
670  default: { //Should never be called, therefore print an error log
671  StructureSE* sSE = new StructureSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
672  _log(POS__ERROR, "DynamicEntityFactory::BuildEntity() Default sovereignty StructureSE created for %s (%u)", entity.itemName.c_str(), entity.itemID);
673  sSSE = sSE;
674  } break;
675  }
676  return sSSE;
677  } break;
678  case EVEDB::invCategories::Orbitals: { // planet orbitals these should go into m_staticEntities
679  StructureItemRef structure = sItemFactory.GetStructure( entity.itemID );
680  if (structure.get() == nullptr)
681  return nullptr;
683  CustomsSE* pCoSE(nullptr);
684  switch(entity.groupID) {
688  pCoSE = new CustomsSE(structure, *(sysMgr.GetServiceMgr()), &sysMgr, data);
689  //structure->GetMyInventory()->LoadContents(); this is called during structureItem creation
690  if ((entity.planetID) and (entity.groupID != EVEDB::invGroups::Test_Orbitals)) {
691  pCoSE->SetPlanet(entity.planetID);
692  SystemEntity* pPE = sysMgr.GetSE(entity.planetID);
693  if ((pPE != nullptr) and pPE->IsPlanetSE())
694  pPE->GetPlanetSE()->SetCustomsOffice(pCoSE);
695  }
696  pCoSE->Init();
697  _log(POS__TRACE, "DynamicEntityFactory::BuildEntity() making CustomsSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
698  } break;
699  }
700  return pCoSE;
701  } break;
703  // TODO: (just use CelestialEntity class for these until their own classes are written)
704  // * WarpGateEntity <-- Warp_Gate
705  // * WormholeEntity <-- Wormhole
706  switch (entity.groupID) {
708  WreckContainerRef wreck = sItemFactory.GetWreckContainer( entity.itemID );
709  if (wreck.get() == nullptr)
710  return nullptr;
712  WreckSE* wSE = new WreckSE(wreck, *(sysMgr.GetServiceMgr()), &sysMgr, data);
713  wreck->GetMyInventory()->LoadContents();
714  wreck->SetMySE(wSE);
715  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making WreckSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
716  return wSE;
717  } break;
723  CargoContainerRef contRef = sItemFactory.GetCargoContainer( entity.itemID );
724  if (contRef.get() == nullptr)
725  return nullptr;
727  ContainerSE* cSE = new ContainerSE(contRef, *(sysMgr.GetServiceMgr()), &sysMgr, data);
728  contRef->GetMyInventory()->LoadContents();
729  contRef->SetMySE(cSE);
730  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making ContainerSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
731  return cSE;
732  } break;
735  case EVEDB::invGroups::Ring:/*wtf*/
739  case EVEDB::invGroups::Large_Collidable_Ship: // this will not hit here. category 11, entity
744  /* test these to see if they are POS types */
749  case EVEDB::invGroups::Force_Field: // <<< this one is POS type but it IS a plain CSE
750  /* these will get their own class eventually */
756  CelestialObjectRef celestial = sItemFactory.GetCelestialObject( entity.itemID );
757  if (celestial.get() == nullptr)
758  return nullptr;
760  CelestialSE* cSE = new CelestialSE(celestial, *(sysMgr.GetServiceMgr()), &sysMgr);
761  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making CelestialSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
762  return cSE;
763  } break;
765  CelestialObjectRef celestial = sItemFactory.GetCelestialObject( entity.itemID );
766  if (celestial.get() == nullptr)
767  return nullptr;
769  WormholeSE* wSE = new WormholeSE(celestial, *(sysMgr.GetServiceMgr()), &sysMgr);
770  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making WormholeSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
771  return wSE;
772  } break;
775  CelestialObjectRef celestial = sItemFactory.GetCelestialObject( entity.itemID );
776  if (celestial.get() == nullptr)
777  return nullptr;
779  AnomalySE* aSE = new AnomalySE(celestial, *(sysMgr.GetServiceMgr()), &sysMgr);
780  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making AnomalySE for %s (%u)", entity.itemName.c_str(), entity.itemID);
781  return aSE;
782  } break;
783  case EVEDB::invGroups::Warp_Gate: { //accel gate
784  // does this need own item, or celestial, or generic or other?
785  InventoryItemRef iRef = sItemFactory.GetItem( entity.itemID );
786  //CelestialObjectRef celestial = sItemFactory.GetCelestialObject( entity.itemID );
787  if (iRef.get() == nullptr)
788  return nullptr;
790  ItemSystemEntity* iSE = new ItemSystemEntity(iRef, *(sysMgr.GetServiceMgr()), &sysMgr);
791  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making ISE for %s (%u)", entity.itemName.c_str(), entity.itemID);
792  return iSE;
793  } break;
794  } break;
795  } break;
796  case EVEDB::invCategories::Entity: { // Entities
797  if (entity.groupID == EVEDB::invGroups::Spawn_Container ) { // these are destructible objects found in dungeons
798  // For category=Entity, group=Spawn Container, create a CargoContainer object:
800  CargoContainerRef contRef = sItemFactory.GetCargoContainer( entity.itemID );
801  if (contRef.get() == nullptr)
802  return nullptr;
804  ContainerSE* cSE = new ContainerSE(contRef, *(sysMgr.GetServiceMgr()), &sysMgr, data);
805  contRef->GetMyInventory()->LoadContents();
806  contRef->SetMySE(cSE);
807  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making ContainerSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
808  return cSE;
811  {
812  InventoryItemRef sentryRef = sItemFactory.GetItem( entity.itemID );
813  if (sentryRef.get() == nullptr)
814  return nullptr;
816  Sentry* SentrySE = new Sentry(sentryRef, *(sysMgr.GetServiceMgr()), &sysMgr, data);
817  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making SentrySE for %s (%u)", entity.itemName.c_str(), entity.itemID);
818  return SentrySE;
819  }
820  // Check for NPC ships/drones here (category 11): NOT player drones (different category [18])
838  or (entity.groupID == EVEDB::invGroups::Large_Collidable_Ship) // this is wreck? abandoned ship?
852  {
853  InventoryItemRef npcRef = sItemFactory.GetItem( entity.itemID );
854  if (npcRef.get() == nullptr)
855  return nullptr;
857  NPC* npcSE = new NPC(npcRef, *(sysMgr.GetServiceMgr()), &sysMgr, data);
858  npcSE->Load();
859  sEntityList.AddNPC();
860  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making NPCSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
861  return npcSE;
862  }
863  // may have to create unique class for Billboard (EVEDB::invGroups::Billboard)
864  else {
865  InventoryItemRef iRef = sItemFactory.GetItem( entity.itemID );
866  if (iRef.get() == nullptr)
867  return nullptr;
869  ItemSystemEntity* cSE = new ItemSystemEntity(iRef, *(sysMgr.GetServiceMgr()), &sysMgr);
870  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making ISE item for %s (%u)", entity.itemName.c_str(), entity.itemID);
871  return cSE;
872  }
873  } break;
874  case EVEDB::invCategories::Drone: { // Player Drones
875  InventoryItemRef drone = sItemFactory.GetItem( entity.itemID );
876  if (drone.get() == nullptr)
877  return nullptr;
879  DroneSE* dSE = new DroneSE(drone, *(sysMgr.GetServiceMgr()), &sysMgr, data);
880  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making DroneSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
881  return dSE;
882  } break;
884  switch (entity.groupID) {
886  ProbeItemRef pRef = sItemFactory.GetProbeItem(entity.itemID);
887  if (pRef.get() == nullptr)
888  return nullptr;
890  // make sure these are owned by eve system
891  pRef->ChangeOwner(1);
892  //these probes are abandoned and offline. give them 5h lifetime
893  ProbeSE* pSE = new ProbeSE(pRef, *(sysMgr.GetServiceMgr()), &sysMgr);
894  _log(ITEM__TRACE, "DynamicEntityFactory::BuildEntity() making ProbeSE for %s (%u)", entity.itemName.c_str(), entity.itemID);
895  return pSE;
896  } break;
898  sLog.Warning("BuildEntity", "Called for Survey_Probe");
899  } break;
901  sLog.Warning("BuildEntity", "Called for Warp_Disruption_Probe");
902  } break;
903  }
904  } break;
905  }
906  sLog.Warning("BuildEntity", "Unhandled dynamic entity category %u for item %u of type %u", entity.categoryID, entity.itemID, entity.typeID);
907  EvE::traceStack();
908  return nullptr;
909 }
910 
911 void SystemManager::AddClient(Client* pClient, bool count/*false*/, bool jump/*false*/) {
912  //called from Client::MoveToLocation() on login and when changing systems
913  if (pClient == nullptr)
914  return;
915  if (m_clients.find(pClient->GetCharacterID()) == m_clients.end()) {
916  m_clients[pClient->GetCharacterID()] = pClient;
917  _log(PLAYER__TRACE, "%s(%u): Added to system manager for %s(%u) - %u clients now in system. count %s", \
918  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID, m_clients.size(), count?"true":"false");
919  } else {
920  // error for player already in client map
921  _log(PLAYER__ERROR, "%s(%u): Already in player map for %s(%u)", \
922  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID);
923  }
924 
925  m_activityTime = 0;
926 
927  if (count) {
928  ++m_players;
929  _log(PLAYER__INFO, "%s(%u): Added to player count for %s(%u) - new count: %u", \
930  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID, m_players);
931  }
932  if (jump) {
933  //add jump in this system
935 
936  _log(PLAYER__INFO, "%s(%u): Add Jump to %s(%u)", \
937  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID);
938 
939  uint16 stamp = sEntityList.GetStamp();
940  std::map<uint32, uint8>::iterator itr = m_jumpMap.find(stamp);
941  if (itr != m_jumpMap.end()) {
942  ++(itr->second);
943  } else {
944  m_jumpMap.emplace(stamp, 1);
945  }
946  }
947 }
948 
949 void SystemManager::RemoveClient(Client* pClient, bool count/*false*/, bool jump/*false*/) {
950  //called from Client::~Client() and Client::MoveToLocation() when changing systems
951  if (pClient == nullptr)
952  return;
953  m_clients.erase(pClient->GetCharacterID());
954  _log(PLAYER__TRACE, "%s(%u): Removed from system manager for %s(%u) - %u clients still in system.", \
955  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID, m_clients.size());
956 
957  if (count) {
958  --m_players;
959  if (m_players < 0) {
960  m_players = 0;
961  m_clients.clear(); // redundant but safe
962  _log(PLAYER__ERROR, "player count for %s(%u) is < 0", m_data.name.c_str(), m_data.systemID);
963  }
964 
965  _log(PLAYER__INFO, "%s(%u): Removed from player count for %s(%u) - new count: %u", \
966  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID, m_players);
967  }
968  if (jump) {
969  //add jump in this system
971 
972  _log(PLAYER__INFO, "%s(%u): Add Jump to %s(%u)", \
973  pClient->GetName(), pClient->GetCharacterID(), m_data.name.c_str(), m_data.systemID);
974 
975  uint16 stamp = sEntityList.GetStamp();
976  std::map<uint32, uint8>::iterator itr = m_jumpMap.find(stamp);
977  if (itr != m_jumpMap.end()) {
978  ++(itr->second);
979  } else {
980  m_jumpMap.emplace(stamp, 1);
981  }
982  }
983 }
984 
985 void SystemManager::SetDockCount(Client* pClient, bool docked/*false*/)
986 {
987  if (docked) {
988  ++m_docked;
989  } else {
990  --m_docked;
991  if (m_docked < 0) {
992  m_docked = 0;
993  _log(PLAYER__ERROR, "docked count for %s(%u) is <0. Setting to 0.", m_data.name.c_str(), m_data.systemID);
994  }
995  }
996 
997  if (m_players > sEntityList.GetPlayerCount())
998  GetPlayerCount();
999  if (m_docked > m_players)
1000  GetDockedCount();
1001 
1003 
1004  _log(PLAYER__INFO, "%s(%u): %s docked count for %s(%u) - new count: %u", \
1005  pClient->GetName(), pClient->GetCharacterID(), docked ? "Added to" : "Removed from", m_data.name.c_str(), m_data.systemID, m_docked);
1006 }
1007 
1009  if ( pNPC == nullptr)
1010  return;
1011  uint32 itemID = pNPC->GetID();
1012  if (m_npcs.find(itemID) != m_npcs.end()) {
1013  _log(ITEM__WARNING, "%s(%u): Called AddNPC(), but they're already in %s(%u). Check bubble.", pNPC->GetName(), itemID, m_data.name.c_str(), m_data.systemID);
1014  } else {
1015  m_npcs[itemID] = pNPC;
1016  }
1017 
1018  _log(NPC__TRACE, "%s(%u): Added to system manager for %s(%u)", pNPC->GetName(), pNPC->GetID(), m_data.name.c_str(), m_data.systemID);
1019  AddEntity(pNPC, false);
1020  sEntityList.AddNPC();
1021 }
1022 
1024  if ( pNPC == nullptr)
1025  return;
1026  auto itr = m_npcs.find(pNPC->GetID());
1027  if (itr != m_npcs.end())
1028  m_npcs.erase(itr);
1029 
1030  _log(NPC__TRACE, "%s(%u): Removed from system manager for %s(%u)", pNPC->GetName(), pNPC->GetID(), m_data.name.c_str(), m_data.systemID);
1031  RemoveEntity(pNPC);
1032  sEntityList.RemoveNPC(); // this is for loaded npc count.
1033  pNPC->RemoveNPC(); // this deletes NPC from DB. NPC's dont jump, so no reason to remove from system unless killed
1034 }
1035 
1036 void SystemManager::AddEntity(SystemEntity* pSE, bool addSignal/*true*/) {
1037  if (pSE == nullptr)
1038  return;
1039  uint32 itemID(pSE->GetID());
1040  if (m_entities.find(itemID) != m_entities.end()) {
1041  _log(ITEM__WARNING, "%s(%u): Called AddEntity(), but they're already in %s(%u). Check bubble.", pSE->GetName(), itemID, m_data.name.c_str(), m_data.systemID);
1042  return;
1043  } else {
1044  _log(ITEM__TRACE, "%s(%u): Added to system manager for %s(%u)", pSE->GetName(), itemID, m_data.name.c_str(), m_data.systemID);
1045  m_entities[itemID] = pSE;
1046 
1047  if ((pSE->IsCOSE())
1048  or (pSE->isGlobal())) {
1049  m_staticEntities[itemID] = pSE;
1050  if (pSE->IsOperSE()) //Entities which need to be acted upon while nobody is in the system
1051  m_opStaticEntities[itemID] = pSE;
1052  if (m_loaded) // only update when system is already loaded
1053  SendStaticBall(pSE);
1054  } else if (pSE->IsProbeSE()) {
1055  // probes are now running sub-hz tics, so dont add to proc list.
1056  addSignal = false; // redundant...called with AddSignal=false
1057  sEntityList.AddProbe(itemID, pSE->GetProbeSE());
1058  } else if (!IsStaticItem(itemID)) {
1059  // *most* dynamic items need proc tics. add to proc list
1060  m_entityChanged = true;
1061  m_ticEntities[itemID] = pSE;
1062  } else {
1063  addSignal = false;
1064  }
1065 
1066  // Add Entity's Item Ref to Solar System Dynamic Inventory:
1068  }
1069  sBubbleMgr.Add(pSE);
1070  // add item to our AnomalyMgr
1071  if (addSignal)
1072  m_anomMgr->AddSignal(pSE);
1073 }
1074 
1077  if (pSE == nullptr)
1078  return;
1079  sBubbleMgr.Remove(pSE);
1080  // Remove Entity's Item Ref from Solar System Dynamic Inventory:
1082  // remove entity from our maps
1083  uint32 itemID(pSE->GetID());
1084  m_entityChanged = true;
1085  m_ticEntities.erase(itemID);
1086  m_staticEntities.erase(itemID);
1087 
1088  // remove from anomaly map, if exists
1090 }
1091 
1092 void SystemManager::AddMarker(SystemEntity* pSE, bool sendBall/*false*/, bool addSignal/*false*/) {
1093  if (pSE == nullptr)
1094  return;
1095 
1096  m_entities[pSE->GetID()] = pSE;
1097  // Add Entity's Item Ref to Solar System Dynamic Inventory:
1098  //m_solarSystemRef->AddItemToInventory(pSE->GetSelf());
1099 
1100  sBubbleMgr.Add(pSE);
1101  if (addSignal)
1102  m_anomMgr->AddSignal(pSE);
1103  if (sendBall) {
1104  // modified from SendStaticBall()
1105  if (m_clients.empty())
1106  return;
1107 
1108  Buffer* destinyBuffer = new Buffer();
1109  //create AddBalls header
1111  head.packet_type = 1; // 0 = full state 1 = balls
1112  head.stamp = sEntityList.GetStamp();
1113  destinyBuffer->Append( head );
1114 
1115  AddBalls2 addballs2;
1116  addballs2.stateStamp = sEntityList.GetStamp();
1117  addballs2.extraBallData = new PyList();
1118 
1119  PyTuple* balls = new PyTuple(2);
1120  balls->SetItem(0, pSE->MakeSlimItem());
1121  balls->SetItem(1, pSE->MakeDamageState());
1122  addballs2.extraBallData->AddItem(balls);
1123 
1124  pSE->EncodeDestiny(*destinyBuffer);
1125 
1126  addballs2.state = new PyBuffer(&destinyBuffer); //consumed
1127  SafeDelete( destinyBuffer );
1128 
1129  if (is_log_enabled(DESTINY__BALL_DUMP))
1130  addballs2.Dump( DESTINY__BALL_DUMP, " " );
1131  //send the update
1132  PyTuple* up = addballs2.Encode();
1133  for (auto cur : m_clients) {
1134  PyIncRef(up);
1135  cur.second->QueueDestinyUpdate(&up, true);
1136  }
1137  }
1138 }
1139 
1140 
1142 {
1143  /*
1144 struct BountyData { // this is comming from rat killed.
1145  uint32 fromID;
1146  uint32 toID;
1147  double amount;
1148  uint8 refTypeID;
1149  uint16 fromKey;
1150  uint16 toKey;
1151  std::string reason; this can stay blank for now. populate during PayBounties
1152 }; */
1153  _log(CLIENT__TEXT, "AddBounty called for charID %u in system %s(%u).", charID, m_data.name.c_str(), m_data.systemID);
1154  std::map<uint32, BountyData>::iterator itr = m_bountyMap.find(charID);
1155  if (itr != m_bountyMap.end()) {
1156  itr->second.amount += data.amount;
1157  std::map<uint32, RatDataMap>::iterator rItr = m_ratMap.find(charID);
1158  if (rItr != m_ratMap.end()) {
1159  RatDataMap::iterator it = rItr->second.begin();
1160  if (it == rItr->second.end()){
1161  RatDataMap vec;
1162  vec.emplace(data.fromID, 1);
1163  rItr->second = vec;
1164  } else {
1165  ++(it->second);
1166  }
1167  } else {
1168  RatDataMap vec;
1169  vec.emplace(data.fromID, 1);
1170  m_ratMap.emplace(charID, vec);
1171  }
1172  } else {
1173  m_bountyMap.emplace(charID, data);
1174  RatDataMap vec;
1175  vec.emplace(data.fromID, 1);
1176  m_ratMap.emplace(charID, vec);
1177  }
1178 }
1179 
1181 {
1182  _log(CLIENT__TEXT, "PayBounties called for system %s(%u).", m_data.name.c_str(), m_data.systemID);
1183  int8 count = 0;
1184  /* recDescNpcBountyList = 'NBL' <-- descrives a full list of [typeID: qty]
1185  * recDescNpcBountyListTruncated = 'NBLT' <-- describes a trunicated list
1186 recDescription = 'DESC'
1187 recDescNpcBountyList = 'NBL'
1188 recDescNpcBountyListTruncated = 'NBLT'
1189 recStoreItems = 'STOREITEMS'
1190  */
1191 
1210  for (auto cur : m_bountyMap) {
1211  std::string reason = "NBLT: "; //this needs to be populated as [NBL(T): type:amt, type:amt, ... ] to get proper shit in client
1212  std::map<uint32, RatDataMap>::iterator itr = m_ratMap.find(cur.first);
1213  if (itr != m_ratMap.end()) {
1214  count = itr->second.size();
1215  for (auto cur : itr->second) {
1216  reason += std::to_string(cur.first);
1217  reason += ":";
1218  reason += std::to_string(cur.second);
1219  if (count > 1)
1220  reason += ",";
1221  --count;
1222  }
1223  // will have to figure out how to *correctly* limit this data to count<20 or so...
1224  } //else {
1225  reason += ",..."; // this will show as "truncated" in client
1226  //}
1228  count = 0;
1229  }
1230  m_ratMap.clear();
1231  m_bountyMap.clear();
1232 }
1233 
1235 {
1236  if (!m_spawnMgr->IsInitialized())
1237  return;
1238 
1239  uint8 count = m_beltCount;
1240  if (count < 1)
1241  return;
1242 
1243  if (is_log_enabled(SPAWN__MESSAGE))
1244  _log(SPAWN__MESSAGE, "Spawn called for bubble %u(%u) in %s(%u)[%.4f], region %u.",
1245  pBubble->GetID(), sBubbleMgr.GetBeltID(pBubble->GetID()), m_data.name.c_str(), m_data.systemID, m_data.securityRating, m_data.regionID);
1246  if (count > 15)
1247  count = 15;
1248  if ((m_activeRatSpawns < count ) or (pBubble->IsGate())) {
1249  if (m_spawnMgr->DoSpawnForBubble(pBubble)) {
1250  m_ratBubbles.emplace(pBubble->GetID(), pBubble);
1251  if (is_log_enabled(SPAWN__TRACE))
1252  _log(SPAWN__TRACE, "SystemManager::DoSpawnForBubble() completed for %s(%u) in bubble %u. %u items in m_ratBubbles", \
1253  m_data.name.c_str(), m_data.systemID, pBubble->GetID(), m_ratBubbles.size());
1254  } else {
1255  if (is_log_enabled(SPAWN__TRACE))
1256  _log(SPAWN__TRACE, "SystemManager::DoSpawnForBubble() returned false for bubble %u.", pBubble->GetID());
1257  }
1258  }
1259 }
1260 
1262 {
1263  if (is_log_enabled(SPAWN__MESSAGE))
1264  _log(SPAWN__MESSAGE, "SystemManager::GetSpawnBubbles() - called for %s(%u)", m_data.name.c_str(), m_data.systemID);
1265  SpawnBubbleMap::iterator itr = m_ratBubbles.begin();
1266  while (itr != m_ratBubbles.end())
1267  bubbleMap->emplace(itr->first, itr->second);
1268 }
1269 
1271 {
1272  if (pBubble->IsBelt()) {
1273  m_ratBubbles.erase(pBubble->GetID());
1275  } else if (pBubble->IsGate()) {
1276  m_ratBubbles.erase(pBubble->GetID());
1278  }
1279  if (is_log_enabled(SPAWN__MESSAGE))
1280  _log(SPAWN__MESSAGE, "SystemManager::RemoveSpawnBubble() - called for bubbleID %u in %s(%u).", pBubble->GetID(), m_data.name.c_str(), m_data.systemID);
1281 }
1282 
1284 {
1285  return m_beltVector.at(MakeRandomInt(0, m_beltCount));
1286 }
1287 
1288 void SystemManager::MakeSetState(const SystemBubble* pBubble, SetState& into) const {
1289  using namespace Destiny;
1290  Buffer* stateBuffer(new Buffer());
1291 
1292  AddBall_header head = AddBall_header();
1293  head.packet_type = 0; // 0 = full state 1 = balls
1294  head.stamp = into.stamp;
1295  stateBuffer->Append( head );
1296 
1297  std::map<uint32, SystemEntity*> visibleEntities;
1298 
1299  // get all static entities for this system
1300  for (auto cur : m_staticEntities)
1301  visibleEntities.emplace(cur.first, cur.second);
1302 
1303  // get all operational static entities and add to visibleEntities map
1304  for (auto cur : m_opStaticEntities)
1305  visibleEntities.emplace(cur.first, cur.second);
1306 
1307  // get our ship. bubble->GetEntities() does not include cloaked items
1308  std::map<uint32, SystemEntity*>::const_iterator itr = m_ticEntities.find(into.ego);
1309  if (itr != m_ticEntities.end())
1310  visibleEntities.emplace(itr->first, itr->second);
1311 
1312  // query bubble to get dynamic entities
1313  pBubble->GetEntities(visibleEntities);
1314 
1315  into.slims = new PyList();
1316  into.slims->clear();
1317  into.effectStates = new PyList();
1318  into.effectStates->clear();
1319  into.allianceBridges = new PyList();
1320  into.allianceBridges->clear(); //activeBeacon and activeBridge data found in fleetSvc.py
1321 
1322  //go through all visible entities and gather the info we need...
1323  for (auto cur : visibleEntities) {
1324  if (!cur.second->IsMissileSE() or !cur.second->IsFieldSE())
1325  into.damageState[ cur.first ] = cur.second->MakeDamageState();
1326 
1327  into.slims->AddItem( new PyObject( "foo.SlimItem", cur.second->MakeSlimItem()));
1328 
1329  //append the destiny binary data...
1330  cur.second->EncodeDestiny( *stateBuffer );
1331 
1332  // get tower effect state (if applicable)
1333  if (cur.second->IsTowerSE())
1334  cur.second->GetTowerSE()->GetEffectState(*(into.effectStates));
1335 
1343  // if (cur.second->IsJumpBridgeSE)
1344  //ss.allianceBridges -- jumpbridges et al.
1345  // [for shipID, toSolarsystemID, toBeaconID in bag.allianceBridges:]
1346  }
1347 
1348  into.destiny_state = new PyBuffer( &stateBuffer );
1349  into.droneState = pBubble->GetDroneState(); //SystemDB::GetSolDroneState( m_data.systemID );
1350 
1351  /* SolarSystem info. this avoids the old way of a DB hit for every call. */
1352  PyPackedRow* row = new PyPackedRow(sDataMgr.CreateHeader());
1353  row->SetField("itemID", new PyLong(m_data.systemID));
1354  row->SetField("typeID", new PyInt(5));
1355  row->SetField("ownerID", PyStatic.NewOne()); // should this be owning factionID? yes
1356  row->SetField("locationID", new PyInt(m_data.constellationID));
1357  row->SetField("flagID", PyStatic.NewZero());
1358  row->SetField("quantity", PyStatic.NewNegOne());
1359  row->SetField("groupID", new PyInt(5));
1360  row->SetField("categoryID", new PyInt(2));
1361  row->SetField("customInfo", new PyString(""));
1362  into.solItem = row;
1363 
1364  if (is_log_enabled(DESTINY__SETSTATE)) {
1365  _log( DESTINY__SETSTATE, "Current State of %s", m_data.name.c_str() );
1366  into.Dump( DESTINY__SETSTATE, " " );
1367  }
1368 
1369  if (is_log_enabled(DESTINY__SETSTATE_DECODE)) {
1370  _log( DESTINY__SETSTATE_DECODE, " Decoded:" );
1371  Destiny::DumpUpdate( DESTINY__SETSTATE_DECODE, &( into.destiny_state->content() )[0], (uint32)into.destiny_state->content().size() );
1372  }
1373 }
1374 
1376 {
1377  if (m_clients.empty())
1378  return;
1379 
1380  if (is_log_enabled(DESTINY__MESSAGE)) {
1381  if (pSE->SysBubble() != nullptr) { //Don't attempt to log if bubble is null (ie, on static structure initial launch)
1382  GPoint bCenter(pSE->SysBubble()->GetCenter());
1383  _log(DESTINY__MESSAGE, "SystemManager::SendStaticBall() - Adding static entity %s(%u) to bubble %u. Dist to center: %.2f", \
1384  pSE->GetName(), pSE->GetID(), pSE->SysBubble()->GetID(), bCenter.distance(pSE->GetPosition()));
1385  }
1386  }
1387 
1388  Buffer* destinyBuffer = new Buffer();
1389  //create AddBalls header
1391  head.packet_type = 1; // 0 = full state 1 = balls
1392  head.stamp = sEntityList.GetStamp();
1393  destinyBuffer->Append( head );
1394 
1395  AddBalls2 addballs2;
1396  addballs2.stateStamp = sEntityList.GetStamp();
1397  addballs2.extraBallData = new PyList();
1398 
1399  if (pSE->IsContainerSE()) {
1400  addballs2.extraBallData->AddItem(pSE->MakeSlimItem());
1401  } else {
1402  PyTuple* balls = new PyTuple(2);
1403  balls->SetItem(0, pSE->MakeSlimItem());
1404  balls->SetItem(1, pSE->MakeDamageState());
1405  addballs2.extraBallData->AddItem(balls);
1406  }
1407 
1408  if (addballs2.extraBallData->size() < 1) {
1409  SafeDelete( destinyBuffer );
1410  return;
1411  }
1412 
1413  pSE->EncodeDestiny(*destinyBuffer);
1414  addballs2.state = new PyBuffer(&destinyBuffer); //consumed
1415 
1416  if (is_log_enabled(DESTINY__BALL_DUMP))
1417  addballs2.Dump( DESTINY__BALL_DUMP, " " );
1418  _log( DESTINY__BALL_DECODE, " Ball Decoded:" );
1419  if (is_log_enabled(DESTINY__BALL_DECODE))
1420  Destiny::DumpUpdate( DESTINY__BALL_DECODE, &( addballs2.state->content() )[0], (uint32)addballs2.state->content().size() );
1421 
1422  //send the update
1423  PyTuple* rsp = addballs2.Encode();
1424  // does this need to be incremented? the others do...
1425  for (auto cur : m_clients) {
1426  PyIncRef(rsp);
1427  cur.second->QueueDestinyUpdate(&rsp, true);
1428  }
1429 
1430  //cleanup
1431  SafeDelete(destinyBuffer);
1432 }
1433 
1435 {
1437 }
1438 
1440 {
1441  // just in case this is called from elsewhere (which it may be), make sure we remove entity from our map.
1442  auto itr = m_entities.find(iRef->itemID());
1443  if (itr != m_entities.end()) {
1444  _log(ITEM__TRACE, "%s(%u): Removed from system manager for %s(%u)", iRef->name(), iRef->itemID(), m_data.name.c_str(), m_data.systemID);
1445  m_entities.erase(itr);
1446  } else {
1447  _log(ITEM__WARNING, "%s(%u): Called RemoveEntity(), but they weren\'t found in system manager for %s(%u)", \
1448  iRef->name(), iRef->itemID(), m_data.name.c_str(), m_data.systemID);
1449  }
1450 
1452 }
1453 
1455  std::map<uint32, SystemEntity*>::const_iterator itr = m_entities.find(entityID);
1456  if (itr == m_entities.end())
1457  return nullptr;
1458  return itr->second;
1459 }
1460 
1462 {
1463  std::map<uint32, NPC*>::const_iterator itr = m_npcs.find(entityID);
1464  if (itr == m_npcs.end())
1465  return nullptr;
1466  return itr->second;
1467 }
1468 
1470 {
1472 }
1473 
1475 {
1477 }
1478 
1480 {
1482 }
1483 
1485 {
1486  std::map<uint32, SystemEntity*>::iterator itr = m_planetMap.find(planetID);
1487  if (itr != m_planetMap.end())
1488  return itr->second;
1489  return nullptr;
1490 }
1491 
1493 {
1494  std::map<double, SystemEntity*> sorted;
1495  for (auto cur : m_planetMap)
1496  sorted.insert(std::pair<double, SystemEntity*>(myPos.distance(cur.second->GetPosition()), cur.second));
1497 
1498  std::map<double, SystemEntity*>::iterator itr = sorted.begin();
1499 
1500  return itr->second->GetID();
1501 }
1502 
1504 {
1505  std::map<double, SystemEntity*> sorted;
1506  for (auto cur : m_planetMap)
1507  sorted.insert(std::pair<double, SystemEntity*>(myPos.distance(cur.second->GetPosition()), cur.second));
1508 
1509  std::map<double, SystemEntity*>::iterator itr = sorted.begin();
1510 
1511  return itr->second;
1512 }
1513 
1515 {
1516  std::map<double, SystemEntity*> sorted;
1517  for (auto cur : m_gateMap)
1518  sorted.insert(std::pair<double, SystemEntity*>(myPos.distance(cur.second->GetPosition()), cur.second));
1519 
1520  std::map<double, SystemEntity*>::iterator itr = sorted.begin();
1521 
1522  return itr->second;
1523 }
1524 
1526 {
1527  std::map<double, SystemEntity*> sorted;
1528  for (auto cur : m_moonMap)
1529  sorted.insert(std::pair<double, SystemEntity*>(myPos.distance(cur.second->GetPosition()), cur.second));
1530 
1531  std::map<double, SystemEntity*>::iterator itr = sorted.begin();
1532 
1533  return itr->second;
1534 }
1535 
1536 void SystemManager::GetClientList(std::vector< Client* >& cVec)
1537 {
1538  for (auto cur : m_clients)
1539  cVec.push_back(cur.second);
1540 }
1541 
1542 void SystemManager::DScan(int64 range, const GPoint& pos, std::vector<SystemEntity*>& vector )
1543 {
1559  for (auto cur : m_entities) {
1560  // these dont show on dscan
1561  if (IsTempItem(cur.first))
1562  continue;
1563  if (IsAsteroidID(cur.first))
1564  if (!sConfig.server.AsteroidsOnDScan)
1565  continue;
1566  if (IsNPC(cur.first))
1567  continue;
1568  if (cur.second->IsDeployableSE()) // not sure if this is right or not
1569  continue;
1570  if (cur.second->IsShipSE()) {
1571  if (cur.second->GetGroupID() == EVEDB::invGroups::CovertOps)
1572  continue;
1573  if (cur.second->GetGroupID() == EVEDB::invGroups::CombatRecon)
1574  continue;
1575  }
1576  if (cur.second->DestinyMgr() != nullptr)
1577  if (cur.second->DestinyMgr()->IsCloaked())
1578  continue;
1579  // made it this far. add item to scan list
1580  if (pos.distance(cur.second->GetPosition()) < range)
1581  vector.push_back(cur.second);
1582  }
1583 }
1584 
1586 {
1587  /* return list of dict
1588  * itemID, typeID, catID, name, pos[x,y,z]
1589  *
1590  * already have statics, so add players, empty ships, pos', npcs, drones (anything that requires a tic)
1591  */
1592 
1593  PyList* list = new PyList();
1594  for (auto cur : m_ticEntities) {
1595  PyDict* dict = new PyDict();
1596  dict->SetItemString("itemID", new PyInt(cur.first));
1597  dict->SetItemString("ownerName", new PyString(sDataMgr.GetOwnerName(cur.second->GetOwnerID())));
1598  dict->SetItemString("typeID", new PyInt(cur.second->GetTypeID()));
1599  dict->SetItemString("catID", new PyInt(cur.second->GetCategoryID()));
1600  dict->SetItemString("name", new PyString(cur.second->GetName()));
1601  dict->SetItemString("x", new PyLong(cur.second->x()));
1602  dict->SetItemString("y", new PyLong(cur.second->y()));
1603  dict->SetItemString("z", new PyLong(cur.second->z()));
1604  list->AddItem(dict);
1605  }
1606  return list;
1607 }
1608 
1609 void SystemManager::GetAllEntities(std::vector< CosmicSignature >& vector)
1610 {
1613  for (auto cur : m_ticEntities) {
1616  sig.ownerID = cur.second->GetOwnerID();
1617  sig.sigID = sEntityList.GetAnomalyID(); // result.id
1618  sig.sigItemID = cur.first;
1619  sig.sigStrength = 0.9f; // these arent warpable yet
1620  sig.systemID = m_data.systemID;
1621  sig.position = cur.second->GetPosition();
1622  sig.sigGroupID = cur.second->GetGroupID(); // result.groupID
1623  sig.sigTypeID = cur.second->GetTypeID(); // result.typeID
1624  // if scanGroupID is anom or sig, use scanAttributeID to determine site type (in client code)
1625  // scanGroupID must be one of the 5 groups coded in client (sig, anom, ship, drone, structure)
1626  // scanGroupID of sig and anom are cached on client side
1627  switch (cur.second->GetCategoryID()) {
1629  case EVEDB::invCategories::Charge: { // probes, missiles (at time of scan), and ??
1630  sig.scanAttributeID = AttrScanStrengthDronesProbes; // result.strengthAttributeID
1632  } break;
1637  sig.scanAttributeID = AttrScanStrengthStructures; // result.strengthAttributeID
1639  } break;
1641  sig.scanAttributeID = AttrScanStrengthShips; // result.strengthAttributeID
1643  } break;
1645  sig.scanAttributeID = AttrScanStrengthSignatures; // result.strengthAttributeID
1646  sig.scanGroupID = Scanning::Group::Signature; // Scrap(1) is for filter only
1647  sig.sigName = cur.second->GetName(); // result.DungeonName - only used when scanGroupID is sig or anom
1648  } break;
1651  case EVEDB::invCategories::Deployable: // mobile warp disruptor
1652  default: {
1653  sig.scanAttributeID = AttrScanAllStrength; // result.strengthAttributeID (Unknown)
1654  sig.scanGroupID = Scanning::Group::Anomaly; // Celestial(64) is only for filter
1655  sig.sigName = cur.second->GetName(); // result.DungeonName - only used when scanGroupID is sig or anom
1656  } break;
1657  }
1658  vector.push_back(sig);
1659  }
1660 }
1661 
1662 
1663 // time related methods to manipulate hour/24hour map data
1665 {
1667 
1668  uint16 jumps = 0;
1669  uint16 stamp = sEntityList.GetStamp() -60;
1670  std::map<uint32, uint8>::iterator itr = m_jumpMap.begin();
1671  while (itr != m_jumpMap.end()) {
1672  if (itr->first < stamp) {
1673  itr = m_jumpMap.erase(itr);
1674  continue;
1675  } else {
1676  jumps += itr->second;
1677  ++itr;
1678  }
1679  }
1680 
1681  // this is jumps/hour data
1682  //MapDB::UpdateJumps(m_data.systemID, jumps);
1683 
1684  // if system and jumpmap are both empty, set activity time for unload timer
1685  if (SafeToUnload())
1686  if (m_activityTime == 0)
1687  if (m_clients.empty())
1688  if (m_jumpMap.empty())
1689  m_activityTime = sEntityList.GetStamp() -50;
1691 }
1692 
1693 // checks for if it is safe to mark the system for unloading
1695 {
1696  for (auto cur: GetOperationalStatics()) {
1697  //If there are any ongoing operations by operational static structures, we don't want to unload the system until this is complete
1698  if (cur.second->IsPOSSE()) {
1699  if ((cur.second->GetPOSSE()->GetProcState() == EVEPOS::ProcState::Unanchoring) or
1700  (cur.second->GetPOSSE()->GetProcState() == EVEPOS::ProcState::Anchoring) or
1701  (cur.second->GetPOSSE()->GetProcState() == EVEPOS::ProcState::Offlining) or
1702  (cur.second->GetPOSSE()->GetProcState() == EVEPOS::ProcState::Onlining)) {
1703  return false;
1704  }
1705  }
1706  }
1707  return true; //by default, its always safe to unload
1708 }
1709 
1710 // not sure how to do this one yet...
1712 {
1713  int64 timeNow = GetFileTimeNow();
1714  timeNow += EvE::Time::Hour;
1715 
1716  //if (m_killData.killsDateTime < timeNow)
1717 
1719 }
1720 
1722 {
1723  m_docked = 0;
1724  for (auto cur : m_clients)
1725  if (cur.second->IsDocked())
1726  ++m_docked;
1727 }
1728 
1730 {
1731 
1732 }
1733 
1734 /*
1735  uint16 killsHour;
1736  uint16 kills24Hour;
1737  uint16 factionKills;
1738  uint16 factionKills24Hour;
1739  uint16 podKillsHour;
1740  uint16 podKills24Hour;
1741 
1742  int64 killsDateTime;
1743  int64 kills24DateTime;
1744  int64 factionDateTime;
1745  int64 faction24DateTime;
1746  int64 podDateTime;
1747  int64 pod24DateTime;
1748  */
1749 
1750 
1751 bool SystemManager::IsNull(std::map<uint32, SystemEntity*>::iterator& i)
1752 {
1753  /* you have to change this parameter to the type of the container
1754  * you are using and the type of the element inside the container.
1755  * if this finds use again, it should be changed to a template.
1756  */
1757 
1758  uint8 buffer[sizeof(i)];
1759  memset(buffer, 0, sizeof(i));
1760  memcpy(buffer, &i, sizeof(i));
1761  return *buffer == 0;
1762  /* I found that the size of any iterator is 12 bytes long.
1763  * I also found that if the first byte of the iterator that
1764  * is copy to the buffer is zero, then the iterator is invalid.
1765  * Otherwise it is valid. I like to call invalid iterators also as "null iterators".
1766  */
1767 }
#define IsStaticItem(itemID)
Definition: EVE_Defines.h:266
Definition: IHub.h:15
void Append(const T &value)
Appends a single value to buffer.
Definition: Buffer.h:437
Base Python wire object.
Definition: PyRep.h:66
virtual StationSE * GetStationSE()
Definition: SystemEntity.h:100
bool Init(AnomalyMgr *anomMgr, SpawnMgr *spawnMgr)
Definition: DungeonMgr.cpp:182
#define sConfig
A macro for easier access to the singleton.
bool LoadSystemDynamics()
bool Init(BeltMgr *beltMgr, DungeonMgr *dungMgr, SpawnMgr *spawnMgr)
Definition: AnomalyMgr.cpp:78
unsigned __int8 uint8
Definition: eve-compat.h:46
void SetPosition(const GPoint &pos)
Definition: SystemEntity.h:212
void RemoveNPC(NPC *pNPC)
SpawnBubbleMap m_roidBubbles
SystemEntity * GetSE(uint32 entityID) const
bool IsBelt()
Definition: SystemBubble.h:64
void AddEntity(SystemEntity *pSE, bool addSignal=true)
static bool LoadSystemDynamicEntities(uint32 systemID, std::vector< DBSystemDynamicEntity > &into)
Definition: SystemDB.cpp:137
#define IsAsteroidID(itemID)
Definition: EVE_Defines.h:259
void RemoveClient(Client *pClient, bool count=false, bool jump=false)
virtual ProbeSE * GetProbeSE()
Definition: SystemEntity.h:112
#define _log(type, fmt,...)
Definition: logsys.h:124
const GPoint GetRandPointOnMoon(uint32 systemID)
Definition: SBU.h:15
Python string.
Definition: PyRep.h:430
virtual bool IsNPCSE()
Definition: SystemEntity.h:186
static void SetSystemActive(uint32 sysID, bool active=false)
Definition: MapDB.cpp:212
void Init(uint32 regionID)
Definition: BeltMgr.cpp:36
Python's dictionary.
Definition: PyRep.h:719
bool IsInitialized()
Definition: SpawnMgr.h:59
virtual bool Load()
Definition: NPC.cpp:86
NPC * GetNPCSE(uint32 entityID) const
virtual bool IsShipSE()
Definition: SystemEntity.h:190
std::string name
SystemGPoint mGP
void RemoveSpawnBubble(SystemBubble *pBubble)
std::map< uint32, SystemEntity * > m_opStaticEntities
virtual PlanetSE * GetPlanetSE()
Definition: SystemEntity.h:101
std::string sigID
static bool LoadPlayerDynamicEntities(uint32 systemID, std::vector< DBSystemDynamicEntity > &into)
Definition: SystemDB.cpp:208
SystemBubble * SysBubble()
Definition: SystemEntity.h:195
void Process()
Definition: DungeonMgr.cpp:228
void SetCustomsOffice(CustomsSE *pSE)
Definition: Planet.h:67
virtual ShipSE * GetShipSE()
Definition: SystemEntity.h:137
void GetEntities(std::map< uint32, SystemEntity * > &into) const
ShipItemRef GetShipItemRef()
Definition: Ship.h:362
virtual bool IsProbeSE()
Definition: SystemEntity.h:159
#define sProfiler
Definition: dbcore.cpp:39
uint8 m_activeGateSpawns
itemID[count] Create count or of the specified() x() entityID Translocate to the specified entity Immediately stops setting then Sends Bubble AddBalls and Destiny SetState(resets spaceview with current server data)" ) COMMAND( sendstate
void ClearAll()
Definition: BeltMgr.cpp:71
virtual void Init()
SystemEntity * GetClosestGateSE(const GPoint &myPos)
int32 GetCharacterID() const
Definition: Client.h:113
DungeonMgr * m_dungMgr
virtual bool IsOperSE()
Definition: SystemEntity.h:180
std::map< uint32, RatDataMap > m_ratMap
std::map< uint32, BountyData > m_bountyMap
std::map< uint32, SystemEntity * > m_gateMap
void Process()
Definition: BeltMgr.cpp:125
#define sEntityList
Definition: EntityList.h:208
static void LoadDynamicData(uint32 sysID, SystemKillData &data)
Definition: MapDB.cpp:117
void GetClientList(std::vector< Client * > &cVec)
uint32 GetRandBeltID()
SystemEntity * GetPlanet(uint32 planetID)
void AddMarker(SystemEntity *pSE, bool sendBall=false, bool addSignal=false)
bool Init()
Definition: SpawnMgr.cpp:62
const char * name()
void SetFleetID(uint32 set)
Definition: SystemEntity.h:221
PyObject * GetDroneState() const
std::string sigName
TargetManager * TargetMgr()
Definition: SystemEntity.h:197
bool IsNull(std::map< uint32, SystemEntity * >::iterator &i)
Python tuple.
Definition: PyRep.h:567
Definition: Sentry.h:20
uint32 GetClosestPlanetID(const GPoint &myPos)
bool BuildDynamicEntity(const DBSystemDynamicEntity &entity, uint32 launcherID=0)
void Process()
Definition: AnomalyMgr.cpp:156
Definition: Ship.h:301
virtual WreckSE * GetWreckSE()
Definition: SystemEntity.h:108
virtual bool IsPlanetSE()
Definition: SystemEntity.h:149
signed __int8 int8
Definition: eve-compat.h:45
const GPoint & GetPosition() const
Definition: SystemEntity.h:211
virtual bool IsGateSE()
Definition: SystemEntity.h:148
bool LoadPlayerDynamics()
void AddItem(PyRep *i)
Definition: PyRep.h:701
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
std::map< uint16, uint8 > RatDataMap
const GPoint GetRandPointOnPlanet(uint32 systemID)
PyRep * GetCurrentEntities()
const ItemType & type() const
void Unload()
Definition: Inventory.cpp:62
#define is_log_enabled(type)
Definition: logsys.h:78
void LogOut()
Definition: Ship.cpp:84
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
virtual PyDict * MakeSlimItem()
void CreateSystemChannel(int32 channelID)
Definition: LSCService.cpp:951
Definition: gpoint.h:33
ShipItemRef GetShipFromInventory(uint32 shipID)
virtual bool IsCOSE()
Definition: SystemEntity.h:164
std::map< uint32, uint8 > m_jumpMap
SystemData m_data
double GetTimeUSeconds()
Definition: utils_time.cpp:116
Generic class for buffers.
Definition: Buffer.h:40
bool InFleet()
Definition: Client.h:142
bool LoadSystemStatics()
InventoryItemRef GetSelf()
Definition: SystemEntity.h:202
std::map< uint32, SystemEntity * > m_ticEntities
std::map< uint32, Client * > m_clients
std::map< uint32, SystemEntity * > m_planetMap
Python object.
Definition: PyRep.h:826
virtual bool IsStationSE()
Definition: SystemEntity.h:151
PyTuple * MakeDamageState()
void RemoveNPC()
Definition: NPC.cpp:279
CargoContainerRef GetContainerFromInventory(uint32 contID)
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:610
void AddBounty(uint32 charID, BountyData &data)
SpawnBubbleMap m_ratBubbles
static SystemEntity * BuildEntity(SystemManager &pSysMgr, const DBSystemDynamicEntity &entity)
virtual bool IsContainerSE()
Definition: SystemEntity.h:157
uint16 GetID()
Definition: SystemBubble.h:91
Definition: Probes.h:71
void RemoveEntity(SystemEntity *pSE)
SystemEntity * GetClosestPlanetSE(const GPoint &myPos)
static void TranserFunds(uint32 fromID, uint32 toID, double amount, std::string reason="", uint8 entryTypeID=Journal::EntryType::Undefined, uint32 referenceID=0, uint16 fromKey=Account::KeyType::Cash, uint16 toKey=Account::KeyType::Cash, Client *pClient=nullptr)
Python integer.
Definition: PyRep.h:231
void SetBeltMgr(BeltMgr *beltMgr)
Definition: SystemEntity.h:333
void SetDockCount(Client *pClient, bool docked=false)
SpawnMgr * m_spawnMgr
void UnloadStation()
Definition: Station.cpp:333
std::vector< uint32 > m_beltVector
void RemoveItemFromInventory(InventoryItemRef item)
void SetAttribute(uint16 attrID, int num, bool notify=true)
BeltMgr * m_beltMgr
uint32 GetID()
Definition: SystemEntity.h:207
Definition: Array.h:18
bool Check(bool reset=true)
Definition: timer.cpp:62
void AddClient(Client *pClient, bool count=false, bool jump=false)
#define PyStatic
Definition: PyRep.h:1209
uint32 GetFleetID() const
Definition: Client.h:146
X * get() const
Definition: RefPtr.h:213
static void UpdatePilotCount(uint32 sysID, uint16 docked=0, uint16 space=0)
Definition: MapDB.cpp:225
Definition: NPC.h:41
const char * GetName() const
Definition: Client.h:94
void GetAllEntities(std::vector< CosmicSignature > &vector)
const char * GetName() const
Definition: SystemEntity.h:210
void Close()
Definition: AnomalyMgr.cpp:171
#define IsCharacterID(itemID)
Definition: EVE_Defines.h:206
void RemoveItemFromInventory(InventoryItemRef iRef)
Definition: Client.h:66
Definition: Drone.h:46
SystemEntity * GetClosestMoonSE(const GPoint &myPos)
LSCService * lsc_service
Definition: PyServiceMgr.h:77
itemID[count] Create count or of the specified() x() entityID Translocate to the specified entity Immediately stops ship
void Process()
Definition: SpawnMgr.cpp:85
StationItemRef GetStationFromInventory(uint32 stationID)
static RefPtr StaticCast(const RefPtr< Y > &oth)
Acts as static_cast from one RefPtr to another.
Definition: RefPtr.h:238
unsigned __int32 uint32
Definition: eve-compat.h:50
uint32 systemID
#define PyIncRef(op)
Definition: PyRep.h:56
virtual bool isGlobal()
Definition: SystemEntity.h:142
uint32 regionID
PyServiceMgr * GetServiceMgr()
Definition: SystemManager.h:88
void AddItemToInventory(InventoryItemRef item)
void SendStaticBall(SystemEntity *pSE)
uint32 corporationID
virtual void EncodeDestiny(Buffer &into)
static bool LoadSystemStaticEntities(uint32 systemID, std::vector< DBSystemEntity > &into)
Definition: SystemDB.cpp:110
std::map< uint32, SystemEntity * > GetOperationalStatics()
bool IsGate()
Definition: SystemBubble.h:65
void AddNPC(NPC *pNPC)
void AddSignal(SystemEntity *pSE, uint32 id=0)
Definition: AnomalyMgr.cpp:422
static void ClearDungeons()
Definition: ManagerDB.cpp:690
double GetFileTimeNow()
Definition: utils_time.cpp:84
float securityRating
#define IsTempItem(itemID)
Definition: EVE_Defines.h:333
void ManipulateTimeData()
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
void MakeSetState(const SystemBubble *pBubble, SetState &into) const
std::map< uint32, SystemBubble * > SpawnBubbleMap
Definition: SystemManager.h:93
GaExpInl bool isZero() const
Definition: GaTypes.h:188
void DScan(int64 range, const GPoint &pos, std::vector< SystemEntity * > &vector)
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type()() itemID() copy() materialLevel()() itemID(attributeID)-Retrieves attribute value." ) COMMAND( setattr
bool SetField(uint32 index, PyRep *value)
Definition: PyRep.cpp:1031
bool LoadContents()
Definition: Inventory.cpp:113
uint8 m_activeRatSpawns
AnomalyMgr * m_anomMgr
void DumpUpdate(LogType into, const uint8 *data, uint32 len)
Definition: TCU.h:15
void DoSpawnForBubble(SystemBubble *pBubble)
void RemoveSignal(uint32 itemID)
Definition: AnomalyMgr.cpp:518
Definition: Moon.h:28
SystemKillData m_killData
static void AddJump(uint32 sysID)
Definition: MapDB.cpp:218
virtual bool IsBeltSE()
Definition: SystemEntity.h:147
void traceStack(void)
Definition: misc.cpp:169
float radius() const
Definition: ItemType.h:68
Definition: Tower.h:19
virtual void Delete()
void GetSpawnBubbles(SpawnBubbleMap *bubbleMap)
SolarSystemRef m_solarSystemRef
uint32 m_activityTime
#define sItemFactory
Definition: ItemFactory.h:165
std::map< uint32, SystemEntity * > m_entities
Python buffer.
Definition: PyRep.h:382
Packed row.
Definition: PyRep.h:961
uint32 constellationID
GaExpInl GaFloat distance(const GaVec3 &oth) const
Definition: GaTypes.h:158
void SetMySE(SystemEntity *pSE)
Definition: Container.h:93
void SystemUnload(uint32 systemID, uint32 constID, uint32 regionID)
Definition: LSCService.cpp:913
PyServiceMgr & m_services
void SetMySE(SystemEntity *pSE)
Definition: Container.h:208
std::map< uint32, NPC * > m_npcs
virtual bool IsStaticEntity()
Definition: SystemEntity.h:146
void SetPlanet(uint32 planetID)
Definition: CustomsOffice.h:62
#define sBubbleMgr
Inventory * GetMyInventory()
Definition: InventoryItem.h:91
unsigned __int16 uint16
Definition: eve-compat.h:48
SystemManager(uint32 systemID, PyServiceMgr &svc)
bool DoSpawnForBubble(SystemBubble *pBubble)
Definition: SpawnMgr.cpp:344
std::map< uint32, SystemEntity * > m_staticEntities
#define IsNPC(itemID)
Definition: EVE_Defines.h:300
InventoryItemRef GetByID(uint32 id) const
Definition: Inventory.cpp:415
GPoint GetCenter()
Definition: SystemBubble.h:93
Python list.
Definition: PyRep.h:639
virtual bool LoadExtras()
Definition: SystemEntity.h:251
void AddItemToInventory(InventoryItemRef iRef)
uint32 itemID() const
Definition: InventoryItem.h:98
void SetItemString(const char *key, PyRep *value)
SetItemString adds or sets a database entry.
Definition: PyRep.h:812
Python long integer.
Definition: PyRep.h:261
std::map< uint32, SystemEntity * > m_moonMap
void SetLaunchedByID(uint32 launcherID)
Definition: Container.h:263
#define sDataMgr
static void UpdateKillData(uint32 sysID, SystemKillData &data)
Definition: MapDB.cpp:239
void Start(uint32 setTimerTime=0, bool changeResetTimer=true)
Definition: timer.cpp:81