EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BubbleManager.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 <algorithm>
28 #include <functional>
29 #include "eve-server.h"
30 
31 #include "Client.h"
32 #include "EntityList.h"
33 #include "EVE_Scanning.h"
34 #include "EVEServerConfig.h"
35 #include "system/BubbleManager.h"
36 #include "system/Container.h"
37 #include "system/SystemBubble.h"
38 #include "system/SystemEntity.h"
39 #include "system/SystemManager.h"
40 
41 
43 : m_wanderTimer(0),
44 m_emptyTimer(0),
45 m_bubbleID(0)
46 {
47  m_bubbles.clear();
48  m_wanderers.clear();
49  m_bubbleIDMap.clear();
50  m_sysBubbleMap.clear();
51 }
52 
54 }
55 
57  // start timers
58  m_emptyTimer.Start(60000); //60s
59  m_wanderTimer.Start(60000); //60s
60 
61  sLog.Blue(" BubbleMgr", "Bubble Manager Initialized.");
62  return 1;
63 }
64 
66  for (auto cur : m_bubbles)
67  SafeDelete(cur);
68 
69  sLog.Warning(" BubbleMgr", "Bubble Manager has been closed." );
70 }
71 
73  double profileStartTime = GetTimeUSeconds();
74 
75  for (auto cur : m_bubbles) {
76  // process each belt and gate bubble for spawns
77  if (cur->IsBelt() or cur->IsGate())
78  cur->Process();
79  // process each mission and incursion bubble -placeholder
80  if (cur->IsMission() or cur->IsIncursion())
81  cur->Process();
82  }
83 
84  if (m_wanderTimer.Check()) { //60s
85  m_wanderers.clear();
86  std::list<SystemBubble*>::iterator itr = m_bubbles.begin();
87  while (itr != m_bubbles.end()) {
88  if (*itr == nullptr) {
89  itr = m_bubbles.erase(itr);
90  continue;
91  }
92  if ((*itr)->HasDynamics())
93  (*itr)->ProcessWander(m_wanderers);
94  ++itr;
95  }
96 
97  if (!m_wanderers.empty()) {
98  for (auto cur : m_wanderers) {
99  // do we really want to check this?
100  if (cur->GetPosition().isNaN() or cur->GetPosition().isInf() or cur->GetPosition().isZero()) {
101  // position error. this will screw things up. if haspilot, send error.
102  if (cur->HasPilot())
103  cur->GetPilot()->SendErrorMsg("Internal Server Error. Ref: ServerError 35148<br>Please either dock or relog.");
104  continue;
105  }
106  _log(DESTINY__WARNING, "BubbleManager::Process() - Wanderer %s(%u) in system %s(%u) is being added to a bubble.", \
107  cur->GetName(), cur->GetID(), cur->SystemMgr()->GetName(), cur->SystemMgr()->GetID());
108  CheckBubble(cur);
109  }
110  m_wanderers.clear();
111  }
112  }
113 
114  if (m_emptyTimer.Check()) //60s
115  RemoveEmpty();
116 
117  if (sConfig.debug.UseProfiling)
118  sProfiler.AddTime(Profile::bubbles, GetTimeUSeconds() - profileStartTime);
119 }
120 
122  SystemBubble *pBubble = pSE->SysBubble();
123  if (pBubble != nullptr) {
124  if (pBubble->InBubble(pSE->GetPosition())) {
125  _log(DESTINY__BUBBLE_DEBUG, "BubbleManager::CheckBubble() - Entity '%s'(%u) at (%.2f,%.2f,%.2f) is still located in bubble %u at %.2f,%.2f,%.2f.",\
126  pSE->GetName(), pSE->GetID(), pSE->GetPosition().x, pSE->GetPosition().y, pSE->GetPosition().z,\
127  pBubble->GetID(), pBubble->x(), pBubble->y(), pBubble->z());
128  return;
129  }
130 
131  _log(DESTINY__BUBBLE_DEBUG, "BubbleManager::CheckBubble() - Entity '%s'(%u) at (%.2f,%.2f,%.2f) is no longer located in bubble %u at %.2f,%.2f,%.2f. Removing...",\
132  pSE->GetName(), pSE->GetID(), pSE->GetPosition().x, pSE->GetPosition().y, pSE->GetPosition().z,\
133  pBubble->GetID(), pBubble->x(), pBubble->y(), pBubble->z());
134  pBubble->Remove(pSE);
135  }
136 
137  _log(DESTINY__BUBBLE_DEBUG, "BubbleManager::CheckBubble() - SystemEntity '%s'(%u) not currently in any Bubble...adding", pSE->GetName(), pSE->GetID() );
138  Add(pSE);
139 }
140 
142 {
143  std::list<SystemBubble*>::iterator itr = m_bubbles.begin();
144  while (itr != m_bubbles.end()) {
145  if ((*itr)->IsEmpty()) {
146  _log(DESTINY__BUBBLE_DEBUG, "BubbleManager::RemoveEmpty() - Bubble %u is empty and is being deleted from the system.", (*itr)->GetID() );
147  RemoveBubble((*itr)->GetSystem()->GetID(), (*itr));
148  itr = m_bubbles.erase(itr);
149  } else {
150  ++itr;
151  }
152  }
153 }
154 
155 void BubbleManager::Add(SystemEntity* pSE, bool isPostWarp /*false*/) {
156  if (pSE == nullptr)
157  return;
158 
159  if (pSE->GetPosition().isZero()) {
160  SystemGPoint sGP;
162  }
163 
164  GPoint center(pSE->GetPosition());
165  if (isPostWarp) {
166  // Calculate new bubble's center based on entity's velocity and current position
167  NewBubbleCenter( pSE->GetVelocity(), center );
168  }
169 
170  SystemBubble* pBubble(GetBubble(pSE->SystemMgr(), center));
171  if (pBubble != nullptr) {
172  if (pSE->SysBubble() != nullptr) {
173  if (pBubble->GetSystemID() != pSE->SystemMgr()->GetID()) {
174  // this is an error. bad bubble
175  _log(DESTINY__ERROR, "BubbleManager::Add(): bubble SysID %u != pSE SysID %u", pBubble->GetSystemID(), pSE->SystemMgr()->GetID() );
176  pSE->SysBubble()->Remove(pSE);
177  } else if (pSE->SysBubble() != pBubble) {
178  _log(DESTINY__BUBBLE_TRACE, "BubbleManager::Add(): bubbleID %u != pSE bubbleID %u", pBubble->GetID(), pSE->SysBubble()->GetID() );
179  pSE->SysBubble()->Remove(pSE);
180  } else if (pSE->SysBubble()->InBubble(pSE->GetPosition())) {
181  _log(DESTINY__BUBBLE_TRACE, "BubbleManager::Add(): Entity %s(%u) still in Bubble %u", pSE->GetName(), pSE->GetID(), pBubble->GetID() );
182  return;
183  }
184  }
185  _log(DESTINY__BUBBLE_TRACE, "BubbleManager::Add(): Entity %s(%u) being added to Bubble %u", pSE->GetName(), pSE->GetID(), pBubble->GetID() );
186  pBubble->Add(pSE);
187  } else {
188  _log(DESTINY__ERROR, "BubbleManager::Add(): GetBubble() returned nullptr for %s:%u, at (%.2f, %.2f, %.2f).", \
189  pSE->SystemMgr()->GetName(), pSE->SystemMgr()->GetID(), center.x, center.y, center.z );
190  }
191 }
192 
193 void BubbleManager::NewBubbleCenter(GVector shipVelocity, GPoint &newCenter) {
194  shipVelocity.normalize();
195  newCenter += (shipVelocity * (BUBBLE_RADIUS_METERS /2));
196 }
197 
199  // suns, planets and moons arent in bubbles
200  //if (ent->IsStaticEntity())
201  // return;
202  if (ent->SysBubble() != nullptr) {
203  _log(DESTINY__BUBBLE_TRACE, "BubbleManager::Remove(): Entity %s(%u) being removed from Bubble %u", ent->GetName(), ent->GetID(), ent->SysBubble()->GetID() );
204  ent->SysBubble()->Remove(ent);
205  }
206 }
207 
216  return FindBubble(ent->SystemMgr()->GetID(), ent->GetPosition());
217 }
218 
219 SystemBubble* BubbleManager::FindBubble(uint32 systemID, const GPoint &pos) const {
220  // Finds a range containing all elements whose key is k.
221  // pair<iterator, iterator> equal_range(const key_type& k)
222  _log(DESTINY__BUBBLE_DEBUG, "BubbleManager::FindBubble() - Searching point %.1f, %.1f, %.1f in system %u.", \
223  pos.x, pos.y, pos.z, systemID);
224 
225  auto range = m_sysBubbleMap.equal_range(systemID);
226  for ( auto itr = range.first; itr != range.second; ++itr )
227  if (itr->second->InBubble(pos))
228  return itr->second;
229 
230  //not in any existing bubble.
231  return nullptr;
232 }
233 
235 {
236  SystemBubble* pBubble(FindBubble(sysMgr->GetID(), pos));
237  if (pBubble == nullptr)
238  pBubble = MakeBubble(sysMgr, pos);
239 
240  return pBubble;
241 }
242 
244  // determine if new center (pos) is within 2x radius of another bubble center. (overlap)
245  auto range = m_sysBubbleMap.equal_range(sysMgr->GetID());
246  for ( auto itr = range.first; itr != range.second; ++itr )
247  if (itr->second->IsOverlap(pos)) {
248  GVector dir(itr->second->GetCenter(), pos);
249  dir.normalize();
250  _log(DESTINY__BUBBLE_DEBUG, "BubbleManager::MakeBubble()::IsOverlap() - dir: %.3f,%.3f,%.3f", dir.x, dir.y, dir.z);
251  // move pos away from center
252  pos = itr->second->GetCenter() + (dir * (BUBBLE_RADIUS_METERS * 2));
253  break;
254  }
255 
256  SystemBubble* pBubble = new SystemBubble(sysMgr, pos, BUBBLE_RADIUS_METERS);
257  if (pBubble != nullptr) {
258  m_bubbles.push_back(pBubble);
259  m_bubbleIDMap.emplace(pBubble->GetID(), pBubble);
260  m_sysBubbleMap.emplace(sysMgr->GetID(), pBubble);
261  if (sConfig.debug.BubbleTrack)
262  pBubble->MarkCenter();
263  }
264  return pBubble;
265 }
266 
268 {
269  std::map<uint32, SystemBubble*>::iterator itr = m_bubbleIDMap.find(bubbleID);
270  if (itr != m_bubbleIDMap.end())
271  return itr->second;
272  return nullptr;
273 }
274 
276 {
277  auto range = m_sysBubbleMap.equal_range(systemID);
278  for (auto itr = range.first; itr != range.second; ++itr){
279  m_bubbles.remove(itr->second);
280  m_bubbleIDMap.erase(itr->second->GetID());
281  }
282 
283  m_sysBubbleMap.erase(systemID);
284 }
285 
287 {
288  auto range = m_sysBubbleMap.equal_range(systemID);
289  for (auto itr = range.first; itr != range.second; ++itr)
290  if (itr->second == pSB) {
291  m_sysBubbleMap.erase(itr);
292  return;
293  }
294  std::map<uint32, SystemBubble*>::iterator itr = m_bubbleIDMap.find(pSB->GetID());
295  if (itr != m_bubbleIDMap.end())
296  m_bubbleIDMap.erase(itr);
297 }
298 
299 /* for beltmgr */
300 void BubbleManager::AddSpawnID(uint16 bubbleID, uint32 spawnID)
301 {
302  m_spawnIDs.emplace(bubbleID, spawnID);
303 }
304 
306 {
307  // is this right??
308  auto range = m_spawnIDs.equal_range(bubbleID);
309  for (auto itr = range.first; itr != range.second; ++itr )
310  if (itr->second == spawnID) {
311  m_spawnIDs.erase(itr);
312  return;
313  }
314 }
315 
317 {
318  std::map<uint16, uint32>::iterator itr = m_spawnIDs.find(bubbleID);
319  if (itr == m_spawnIDs.end())
320  return 0;
321  return itr->second;
322 }
323 
325  uint32 count = 0;
326  auto range = m_sysBubbleMap.equal_range(systemID);
327  for (auto itr = range.first; itr != range.second; ++itr)
328  ++count;
329  return count;
330 }
331 
332 void BubbleManager::GetBubbleCenterMarkers(std::vector<CosmicSignature>& anom) {
333  ContainerSE* cSE(nullptr);
334  for (auto cur : m_sysBubbleMap) {
335  cSE = cur.second->GetCenterMarker();
336  if (cSE == nullptr)
337  continue;
339  sig.ownerID = cSE->GetOwnerID();
340  sig.sigID = cSE->GetSelf()->customInfo(); // result.id
341  sig.sigItemID = cSE->GetID();
342  sig.sigName = cSE->GetName(); // result.DungeonName
343  //sig.sigGroupID = EVEDB::invGroups::Cosmic_Anomaly; // result.groupID
344  sig.sigStrength = 1.0;
345  //sig.sigTypeID = EVEDB::invTypes::CosmicAnomaly; // result.typeID
346  sig.systemID = cur.first;
347  sig.position = cSE->GetPosition();
348  sig.scanAttributeID = AttrScanMagnetometricStrength; // result.strengthAttributeID
350  anom.push_back(sig);
351  cSE = nullptr;
352  }
353 }
354 
355 void BubbleManager::GetBubbleCenterMarkers(uint32 systemID, std::vector<CosmicSignature>& anom) {
356  ContainerSE* cSE(nullptr);
357  auto range = m_sysBubbleMap.equal_range(systemID);
358  for (auto itr = range.first; itr != range.second; ++itr) {
359  cSE = itr->second->GetCenterMarker();
360  if (cSE == nullptr)
361  continue;
363  sig.ownerID = cSE->GetOwnerID();
364  sig.sigID = cSE->GetSelf()->customInfo();
365  sig.sigItemID = cSE->GetID();
366  sig.sigName = cSE->GetName();
367  //sig.sigGroupID = EVEDB::invGroups::Cosmic_Anomaly;
368  sig.sigStrength = 1.0;
369  //sig.sigTypeID = EVEDB::invTypes::CosmicAnomaly;
370  sig.systemID = systemID;
371  sig.position = cSE->GetPosition();
374  anom.push_back(sig);
375  cSE = nullptr;
376  }
377 }
378 
379 
381  for (auto cur : m_sysBubbleMap)
382  cur.second->MarkCenter();
383 }
384 
386  for (auto cur : m_sysBubbleMap)
387  cur.second->RemoveMarkers();
388 }
389 
391  auto range = m_sysBubbleMap.equal_range(systemID);
392  for (auto itr = range.first; itr != range.second; ++itr)
393  itr->second->MarkCenter();
394 }
395 
397  auto range = m_sysBubbleMap.equal_range(systemID);
398  for (auto itr = range.first; itr != range.second; ++itr)
399  itr->second->RemoveMarkers();
400 }
#define sConfig
A macro for easier access to the singleton.
SystemBubble * MakeBubble(SystemManager *sysMgr, GPoint pos)
double y() const
Definition: SystemBubble.h:89
void RemoveBubble(uint32 systemID, SystemBubble *pSB)
#define _log(type, fmt,...)
Definition: logsys.h:124
uint32 GetSystemID()
Definition: SystemBubble.h:92
std::string sigID
SystemBubble * SysBubble()
Definition: SystemEntity.h:195
bool InBubble(const GPoint &pt, bool inWarp=false) const
const std::string & customInfo() const
std::vector< SystemEntity * > m_wanderers
uint32 GetOwnerID()
Definition: SystemEntity.h:219
SystemBubble * FindBubbleByID(uint16 bubbleID)
#define sProfiler
Definition: dbcore.cpp:39
void RemoveSpawnID(uint16 bubbleID, uint32 spawnID)
void AddSpawnID(uint16 bubbleID, uint32 spawnID)
uint32 GetID() const
Definition: SystemManager.h:80
double x() const
Definition: SystemBubble.h:88
std::string sigName
GaFloat x
Definition: GaTypes.h:207
const GPoint & GetPosition() const
Definition: SystemEntity.h:211
void GetBubbleCenterMarkers(std::vector< CosmicSignature > &anom)
const GVector & GetVelocity()
Definition: SystemEntity.h:240
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
const GPoint GetRandPointOnPlanet(uint32 systemID)
GaExpInl GaFloat normalize()
Definition: GaTypes.h:163
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
Definition: gpoint.h:33
std::map< uint32, SystemBubble * > m_bubbleIDMap
DestinyManager * DestinyMgr()
Definition: SystemEntity.h:198
SystemManager * SystemMgr()
Definition: SystemEntity.h:196
double GetTimeUSeconds()
Definition: utils_time.cpp:116
InventoryItemRef GetSelf()
Definition: SystemEntity.h:202
SystemBubble * FindBubble(SystemEntity *ent) const
void ClearSystemBubbles(uint32 systemID)
uint16 GetID()
Definition: SystemBubble.h:91
void NewBubbleCenter(GVector shipVelocity, GPoint &newBubbleCenter)
void Remove(SystemEntity *ent)
uint32 GetID()
Definition: SystemEntity.h:207
bool Check(bool reset=true)
Definition: timer.cpp:62
const char * GetName() const
Definition: SystemEntity.h:210
unsigned __int32 uint32
Definition: eve-compat.h:50
void SetPosition(const GPoint &pt, bool update=false)
SystemBubble * GetBubble(SystemManager *sysMgr, const GPoint &pos)
double z() const
Definition: SystemBubble.h:90
GaFloat y
Definition: GaTypes.h:207
const char * GetName() const
Definition: SystemManager.h:84
void Remove(SystemEntity *pSE)
std::list< SystemBubble * > m_bubbles
uint32 GetBeltID(uint16 bubbleID)
void CheckBubble(SystemEntity *ent)
void Add(SystemEntity *pSE, bool isPostWarp=false)
GaExpInl bool isZero() const
Definition: GaTypes.h:188
std::map< uint16, uint32 > m_spawnIDs
Definition: gpoint.h:70
unsigned __int16 uint16
Definition: eve-compat.h:48
void Add(SystemEntity *pSE)
uint32 GetBubbleCount(uint32 systemID)
GaFloat z
Definition: GaTypes.h:207
std::unordered_multimap< uint32, SystemBubble * > m_sysBubbleMap
void Start(uint32 setTimerTime=0, bool changeResetTimer=true)
Definition: timer.cpp:81
static const float BUBBLE_RADIUS_METERS
Definition: BubbleManager.h:32