mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[7299] Implemented circular loop detection for pools in pools
As a result, the last relation that makes the loop is automatically removed. An error message is displayed and core go on loading remaining records. Signed-off-by: Neo2003 <neo.2003@hotmail.fr>
This commit is contained in:
parent
5da8bdf16e
commit
125bf4bfd6
3 changed files with 48 additions and 1 deletions
|
|
@ -270,6 +270,30 @@ void PoolHandler::LoadFromDB()
|
|||
mPoolSearchMap.insert(p);
|
||||
|
||||
} while( result->NextRow() );
|
||||
|
||||
// Now check for circular reference
|
||||
for(uint16 i=0; i<max_pool_id; ++i)
|
||||
{
|
||||
std::set<uint16> checkedPools;
|
||||
for(SearchMap::iterator poolItr = mPoolSearchMap.find(i); poolItr != mPoolSearchMap.end(); poolItr = mPoolSearchMap.find(poolItr->second))
|
||||
{
|
||||
checkedPools.insert(poolItr->first);
|
||||
if(checkedPools.find(poolItr->second) != checkedPools.end())
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss<< "The pool(s) ";
|
||||
for (std::set<uint16>::const_iterator itr=checkedPools.begin(); itr!=checkedPools.end(); ++itr)
|
||||
ss << *itr << " ";
|
||||
ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
|
||||
<< poolItr->first << " and child pool " << poolItr->second;
|
||||
sLog.outErrorDb(ss.str().c_str());
|
||||
mPoolPoolGroups[poolItr->second].RemoveOneRelation(poolItr->first);
|
||||
mPoolSearchMap.erase(poolItr);
|
||||
--count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u pools in mother pools", count );
|
||||
delete result;
|
||||
|
|
@ -518,6 +542,28 @@ void PoolHandler::PoolGroup<PoolHandler::Pool>::Despawn1Object(uint32 child_pool
|
|||
poolhandler.DespawnPool(child_pool_id);
|
||||
}
|
||||
|
||||
// Method for a pool only to remove any found record causing a circular dependency loop
|
||||
template<>
|
||||
void PoolHandler::PoolGroup<PoolHandler::Pool>::RemoveOneRelation(uint16 child_pool_id)
|
||||
{
|
||||
for (PoolObjectList::iterator itr = ExplicitlyChanced.begin(); itr != ExplicitlyChanced.end(); ++itr)
|
||||
{
|
||||
if(itr->guid == child_pool_id)
|
||||
{
|
||||
ExplicitlyChanced.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (PoolObjectList::iterator itr = EqualChanced.begin(); itr != EqualChanced.end(); ++itr)
|
||||
{
|
||||
if(itr->guid == child_pool_id)
|
||||
{
|
||||
EqualChanced.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method that Spawn 1+ creatures or gameobject
|
||||
// if cache is false (initialization or event start), X creatures are spawned with X <= limit (< if limit higher that the number of creatures in pool)
|
||||
// if cache is true, this means only one has to be spawned (or respawned if the rolled one is same as cached one)
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ class PoolHandler::PoolGroup
|
|||
void SpawnObject(uint32 limit, bool cache=false);
|
||||
bool Spawn1Object(uint32 guid);
|
||||
bool ReSpawn1Object(uint32 guid);
|
||||
void RemoveOneRelation(uint16 child_pool_id);
|
||||
private:
|
||||
typedef std::vector<PoolObject> PoolObjectList;
|
||||
uint32 CacheValue; // Store the guid of the removed creature/gameobject during a pool update
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7298"
|
||||
#define REVISION_NR "7299"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue