mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[11137] Fixed crash at reset normal dungeon while map loaded.
* Map Persistent noe have direct pointer back to map if map loaded. That let simplify some code and avoid map search. * Crash showup in result changes in code logic related to reset processing. * Also fix more old bug with reset normal dungeon with not loaded map. * Reverse MapPersistentState::HasRespawnTimes and MapPersistentState::HasBounds() results to expected for function names and update related calls. Thanks to Schmoozerd for help in research problem.
This commit is contained in:
parent
5858aae4d9
commit
47060fe4b1
5 changed files with 30 additions and 23 deletions
|
|
@ -47,7 +47,7 @@ Map::~Map()
|
||||||
sWorld.DecreaseScheduledScriptCount(m_scriptSchedule.size());
|
sWorld.DecreaseScheduledScriptCount(m_scriptSchedule.size());
|
||||||
|
|
||||||
if (m_persistentState)
|
if (m_persistentState)
|
||||||
m_persistentState->SetUsedByMapState(false); // field pointer can be deleted after this
|
m_persistentState->SetUsedByMapState(NULL); // field pointer can be deleted after this
|
||||||
|
|
||||||
if(i_data)
|
if(i_data)
|
||||||
{
|
{
|
||||||
|
|
@ -96,7 +96,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
|
||||||
m_TerrainData->AddRef();
|
m_TerrainData->AddRef();
|
||||||
|
|
||||||
m_persistentState = sMapPersistentStateMgr.AddPersistentState(i_mapEntry, GetInstanceId(), GetDifficulty(), 0, IsDungeon());
|
m_persistentState = sMapPersistentStateMgr.AddPersistentState(i_mapEntry, GetInstanceId(), GetDifficulty(), 0, IsDungeon());
|
||||||
m_persistentState->SetUsedByMapState(true);
|
m_persistentState->SetUsedByMapState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::InitVisibilityDistance()
|
void Map::InitVisibilityDistance()
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ static uint32 resetEventTypeDelay[MAX_RESET_EVENT_TYPE] = { 0, 3600, 900, 300, 6
|
||||||
|
|
||||||
MapPersistentState::MapPersistentState(uint16 MapId, uint32 InstanceId, Difficulty difficulty)
|
MapPersistentState::MapPersistentState(uint16 MapId, uint32 InstanceId, Difficulty difficulty)
|
||||||
: m_instanceid(InstanceId), m_mapid(MapId),
|
: m_instanceid(InstanceId), m_mapid(MapId),
|
||||||
m_difficulty(difficulty), m_usedByMap(false)
|
m_difficulty(difficulty), m_usedByMap(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ bool WorldPersistentState::CanBeUnload() const
|
||||||
{
|
{
|
||||||
// prevent unload if used for loaded map
|
// prevent unload if used for loaded map
|
||||||
// prevent unload if respawn data still exist (will not prevent reset by scheduler)
|
// prevent unload if respawn data still exist (will not prevent reset by scheduler)
|
||||||
return MapPersistentState::CanBeUnload() && HasRespawnTimes();
|
return MapPersistentState::CanBeUnload() && !HasRespawnTimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
//== DungeonPersistentState functions =====================
|
//== DungeonPersistentState functions =====================
|
||||||
|
|
@ -161,7 +161,7 @@ DungeonPersistentState::~DungeonPersistentState()
|
||||||
bool DungeonPersistentState::CanBeUnload() const
|
bool DungeonPersistentState::CanBeUnload() const
|
||||||
{
|
{
|
||||||
// prevent unload if any bounded groups or online bounded player still exists
|
// prevent unload if any bounded groups or online bounded player still exists
|
||||||
return MapPersistentState::CanBeUnload() && HasBounds() && HasRespawnTimes();
|
return MapPersistentState::CanBeUnload() && !HasBounds() && !HasRespawnTimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -172,7 +172,7 @@ void DungeonPersistentState::SaveToDB()
|
||||||
// state instance data too
|
// state instance data too
|
||||||
std::string data;
|
std::string data;
|
||||||
|
|
||||||
if (Map *map = sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
if (Map *map = GetMap())
|
||||||
{
|
{
|
||||||
InstanceData *iData = map->GetInstanceData();
|
InstanceData *iData = map->GetInstanceData();
|
||||||
if(iData && iData->Save())
|
if(iData && iData->Save())
|
||||||
|
|
@ -192,7 +192,7 @@ void DungeonPersistentState::DeleteRespawnTimes()
|
||||||
CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", GetInstanceId());
|
CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", GetInstanceId());
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
ClearRespawnTimes();
|
ClearRespawnTimes(); // state can be deleted at call if only respawn data prevent unload
|
||||||
}
|
}
|
||||||
|
|
||||||
void DungeonPersistentState::DeleteFromDB()
|
void DungeonPersistentState::DeleteFromDB()
|
||||||
|
|
@ -711,19 +711,25 @@ void MapPersistentStateManager::_ResetSave(PersistentStateMap& holder, Persisten
|
||||||
|
|
||||||
void MapPersistentStateManager::_ResetInstance(uint32 mapid, uint32 instanceId)
|
void MapPersistentStateManager::_ResetInstance(uint32 mapid, uint32 instanceId)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("InstanceSaveMgr::_ResetInstance %u, %u", mapid, instanceId);
|
DEBUG_LOG("MapPersistentStateManager::_ResetInstance %u, %u", mapid, instanceId);
|
||||||
Map * iMap = sMapMgr.FindMap(mapid, instanceId);
|
|
||||||
if (!iMap || !iMap->Instanceable())
|
|
||||||
return;
|
|
||||||
|
|
||||||
PersistentStateMap::iterator itr = m_instanceSaveByInstanceId.find(instanceId);
|
PersistentStateMap::iterator itr = m_instanceSaveByInstanceId.find(instanceId);
|
||||||
if (itr != m_instanceSaveByInstanceId.end())
|
if (itr != m_instanceSaveByInstanceId.end())
|
||||||
|
{
|
||||||
|
// delay reset until map unload for loaded map
|
||||||
|
if (Map * iMap = itr->second->GetMap())
|
||||||
|
{
|
||||||
|
MANGOS_ASSERT(iMap->IsDungeon());
|
||||||
|
|
||||||
|
((DungeonMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_ResetSave(m_instanceSaveByInstanceId, itr);
|
_ResetSave(m_instanceSaveByInstanceId, itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DeleteInstanceFromDB(instanceId); // even if state not loaded
|
DeleteInstanceFromDB(instanceId); // even if state not loaded
|
||||||
|
|
||||||
if (iMap->IsDungeon())
|
|
||||||
((DungeonMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPersistentStateManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeLeft)
|
void MapPersistentStateManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeLeft)
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,11 @@ class MapPersistentState
|
||||||
Difficulty GetDifficulty() const { return m_difficulty; }
|
Difficulty GetDifficulty() const { return m_difficulty; }
|
||||||
|
|
||||||
bool IsUsedByMap() const { return m_usedByMap; }
|
bool IsUsedByMap() const { return m_usedByMap; }
|
||||||
void SetUsedByMapState(bool state)
|
Map* GetMap() const { return m_usedByMap; } // Can be NULL if map not loaded for persistent state
|
||||||
|
void SetUsedByMapState(Map* map)
|
||||||
{
|
{
|
||||||
m_usedByMap = state;
|
m_usedByMap = map;
|
||||||
if (!state)
|
if (!map)
|
||||||
UnloadIfEmpty();
|
UnloadIfEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +91,7 @@ class MapPersistentState
|
||||||
|
|
||||||
bool UnloadIfEmpty();
|
bool UnloadIfEmpty();
|
||||||
void ClearRespawnTimes();
|
void ClearRespawnTimes();
|
||||||
bool HasRespawnTimes() const { return m_creatureRespawnTimes.empty() && m_goRespawnTimes.empty(); }
|
bool HasRespawnTimes() const { return !m_creatureRespawnTimes.empty() || !m_goRespawnTimes.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetCreatureRespawnTime(uint32 loguid, time_t t);
|
void SetCreatureRespawnTime(uint32 loguid, time_t t);
|
||||||
|
|
@ -102,7 +103,7 @@ class MapPersistentState
|
||||||
uint32 m_instanceid;
|
uint32 m_instanceid;
|
||||||
uint32 m_mapid;
|
uint32 m_mapid;
|
||||||
Difficulty m_difficulty;
|
Difficulty m_difficulty;
|
||||||
bool m_usedByMap; // true when instance map loaded, lock MapPersistentState from unload
|
Map* m_usedByMap; // NULL if map not loaded, non-NULL lock MapPersistentState from unload
|
||||||
|
|
||||||
// persistent data
|
// persistent data
|
||||||
RespawnTimes m_creatureRespawnTimes; // lock MapPersistentState from unload, for example for temporary bound dungeon unload delay
|
RespawnTimes m_creatureRespawnTimes; // lock MapPersistentState from unload, for example for temporary bound dungeon unload delay
|
||||||
|
|
@ -184,7 +185,7 @@ class DungeonPersistentState : public MapPersistentState
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload
|
bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload
|
||||||
bool HasBounds() const { return m_playerList.empty() && m_groupList.empty(); }
|
bool HasBounds() const { return !m_playerList.empty() || !m_groupList.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::list<Player*> PlayerListType;
|
typedef std::list<Player*> PlayerListType;
|
||||||
|
|
@ -315,7 +316,7 @@ class MANGOS_DLL_DECL MapPersistentStateManager : public MaNGOS::Singleton<MapPe
|
||||||
private:
|
private:
|
||||||
typedef UNORDERED_MAP<uint32 /*InstanceId or MapId*/, MapPersistentState*> PersistentStateMap;
|
typedef UNORDERED_MAP<uint32 /*InstanceId or MapId*/, MapPersistentState*> PersistentStateMap;
|
||||||
|
|
||||||
// called by scheduler
|
// called by scheduler for DungeonPersistentStates
|
||||||
void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeleft);
|
void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeleft);
|
||||||
void _ResetInstance(uint32 mapid, uint32 instanceId);
|
void _ResetInstance(uint32 mapid, uint32 instanceId);
|
||||||
void _CleanupExpiredInstancesAtTime(time_t t);
|
void _CleanupExpiredInstancesAtTime(time_t t);
|
||||||
|
|
|
||||||
|
|
@ -2496,7 +2496,7 @@ enum InstanceResetMethod
|
||||||
INSTANCE_RESET_GLOBAL,
|
INSTANCE_RESET_GLOBAL,
|
||||||
INSTANCE_RESET_GROUP_DISBAND,
|
INSTANCE_RESET_GROUP_DISBAND,
|
||||||
INSTANCE_RESET_GROUP_JOIN,
|
INSTANCE_RESET_GROUP_JOIN,
|
||||||
INSTANCE_RESET_RESPAWN_DELAY
|
INSTANCE_RESET_RESPAWN_DELAY // called from reset scheduler for request reset at map unload when map loaded at reset attempt for normal dungeon difficulty
|
||||||
};
|
};
|
||||||
|
|
||||||
// byte value (UNIT_FIELD_BYTES_2,3)
|
// byte value (UNIT_FIELD_BYTES_2,3)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11136"
|
#define REVISION_NR "11137"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue