aboutsummaryrefslogtreecommitdiff
path: root/src/game/PoolHandler.cpp
diff options
context:
space:
mode:
authormegamage <none@none>2009-02-19 18:46:58 -0600
committermegamage <none@none>2009-02-19 18:46:58 -0600
commit72e8c092128a33515d6f4b48a71526ece81b17b7 (patch)
tree301c1badaa1f4b097bc425c67883258d9f7f1d3e /src/game/PoolHandler.cpp
parent83adfb5692e3daa4d09d233f193f23b746e5e4c4 (diff)
[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. Author: Neo2003 --HG-- branch : trunk
Diffstat (limited to 'src/game/PoolHandler.cpp')
-rw-r--r--src/game/PoolHandler.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/game/PoolHandler.cpp b/src/game/PoolHandler.cpp
index 961e34ab369..2eef36ba9c2 100644
--- a/src/game/PoolHandler.cpp
+++ b/src/game/PoolHandler.cpp
@@ -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)