mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[11124] Avoid save in DB instance/respawn data for BGs/Arenas.
* Fixed bug with not unloaded InstanceSave for BGs/ArenasPartly. This bug introduced with recent InstanceSave creating for all maps. * Avoid save respawn data to DB for BGs/Arenas. No reason save to DB because BGs/Arenas reset at map unload. * Always create InstanceSave for Map without recheck suggested data integrity. Map::GetInstanceSave expected always return != NULL value.
This commit is contained in:
parent
6cfa64db97
commit
01178b69e5
7 changed files with 33 additions and 78 deletions
|
|
@ -285,16 +285,6 @@ BattleGround::~BattleGround()
|
||||||
for(int i = 0; i < size; ++i)
|
for(int i = 0; i < size; ++i)
|
||||||
DelObject(i);
|
DelObject(i);
|
||||||
|
|
||||||
if (GetInstanceID()) // not spam by useless queries in case BG templates
|
|
||||||
{
|
|
||||||
// delete creature and go respawn times
|
|
||||||
CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", GetInstanceID());
|
|
||||||
CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", GetInstanceID());
|
|
||||||
// delete instance from db
|
|
||||||
CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID());
|
|
||||||
// remove from battlegrounds
|
|
||||||
}
|
|
||||||
|
|
||||||
sBattleGroundMgr.RemoveBattleGround(GetInstanceID(), GetTypeID());
|
sBattleGroundMgr.RemoveBattleGround(GetInstanceID(), GetTypeID());
|
||||||
sBattleGroundMgr.DeleteClientVisibleInstanceId(GetTypeID(), GetBracketId(), GetClientInstanceID());
|
sBattleGroundMgr.DeleteClientVisibleInstanceId(GetTypeID(), GetBracketId(), GetClientInstanceID());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ void InstanceSave::SaveToDB()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_instanceid)
|
if (GetMapEntry()->IsDungeon())
|
||||||
CharacterDatabase.PExecute("INSERT INTO instance VALUES ('%u', '%u', '"UI64FMTD"', '%u', '%s')", m_instanceid, GetMapId(), (uint64)GetResetTimeForDB(), GetDifficulty(), data.c_str());
|
CharacterDatabase.PExecute("INSERT INTO instance VALUES ('%u', '%u', '"UI64FMTD"', '%u', '%s')", m_instanceid, GetMapId(), (uint64)GetResetTimeForDB(), GetDifficulty(), data.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,14 +106,14 @@ MapEntry const* InstanceSave::GetMapEntry() const
|
||||||
|
|
||||||
void InstanceSave::DeleteFromDB()
|
void InstanceSave::DeleteFromDB()
|
||||||
{
|
{
|
||||||
if (GetInstanceId())
|
if (GetMapEntry()->IsDungeon())
|
||||||
InstanceSaveManager::DeleteInstanceFromDB(GetInstanceId());
|
InstanceSaveManager::DeleteInstanceFromDB(GetInstanceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSave::DeleteRespawnTimes()
|
void InstanceSave::DeleteRespawnTimes()
|
||||||
{
|
{
|
||||||
// possible reset for instanceable map only
|
// possible reset for instanceable map only
|
||||||
if (!m_instanceid)
|
if (!GetMapEntry()->IsDungeon())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_goRespawnTimes.clear();
|
m_goRespawnTimes.clear();
|
||||||
|
|
@ -130,8 +130,9 @@ bool InstanceSave::UnloadIfEmpty()
|
||||||
{
|
{
|
||||||
// prevent unload if any bounded groups or online bounded player still exists
|
// prevent unload if any bounded groups or online bounded player still exists
|
||||||
// also prevent unload if respawn data still exist (will not prevent reset by scheduler)
|
// also prevent unload if respawn data still exist (will not prevent reset by scheduler)
|
||||||
|
// BGs/Arenas not locked by respawn data
|
||||||
if (m_playerList.empty() && m_groupList.empty() && !m_usedByMap &&
|
if (m_playerList.empty() && m_groupList.empty() && !m_usedByMap &&
|
||||||
m_creatureRespawnTimes.empty() && m_goRespawnTimes.empty())
|
(GetMapEntry()->IsBattleGroundOrArena() || m_creatureRespawnTimes.empty() && m_goRespawnTimes.empty()))
|
||||||
{
|
{
|
||||||
sInstanceSaveMgr.RemoveInstanceSave(GetMapId(), GetInstanceId());
|
sInstanceSaveMgr.RemoveInstanceSave(GetMapId(), GetInstanceId());
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -144,6 +145,10 @@ void InstanceSave::SaveCreatureRespawnTime(uint32 loguid, time_t t)
|
||||||
{
|
{
|
||||||
SetCreatureRespawnTime(loguid, t);
|
SetCreatureRespawnTime(loguid, t);
|
||||||
|
|
||||||
|
// BGs/Arenas always reset at server restart/unload, so no reason store in DB
|
||||||
|
if (GetMapEntry()->IsBattleGroundOrArena())
|
||||||
|
return;
|
||||||
|
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, m_instanceid);
|
CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, m_instanceid);
|
||||||
if(t > sWorld.GetGameTime())
|
if(t > sWorld.GetGameTime())
|
||||||
|
|
@ -155,6 +160,10 @@ void InstanceSave::SaveGORespawnTime(uint32 loguid, time_t t)
|
||||||
{
|
{
|
||||||
SetGORespawnTime(loguid, t);
|
SetGORespawnTime(loguid, t);
|
||||||
|
|
||||||
|
// BGs/Arenas always reset at server restart/unload, so no reason store in DB
|
||||||
|
if (GetMapEntry()->IsBattleGroundOrArena())
|
||||||
|
return;
|
||||||
|
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, m_instanceid);
|
CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, m_instanceid);
|
||||||
if(t > sWorld.GetGameTime())
|
if(t > sWorld.GetGameTime())
|
||||||
|
|
@ -445,83 +454,38 @@ InstanceSaveManager::~InstanceSaveManager()
|
||||||
- adding instance into manager
|
- adding instance into manager
|
||||||
- called from InstanceMap::Add, _LoadBoundInstances, LoadGroups
|
- called from InstanceMap::Add, _LoadBoundInstances, LoadGroups
|
||||||
*/
|
*/
|
||||||
InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load)
|
InstanceSave* InstanceSaveManager::AddInstanceSave(MapEntry const* mapEntry, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load)
|
||||||
{
|
{
|
||||||
if(InstanceSave *old_save = GetInstanceSave(mapId, instanceId))
|
if (InstanceSave *old_save = GetInstanceSave(mapEntry->MapID, instanceId))
|
||||||
return old_save;
|
return old_save;
|
||||||
|
|
||||||
const MapEntry* entry = sMapStore.LookupEntry(mapId);
|
if (mapEntry->IsDungeon())
|
||||||
if (!entry)
|
|
||||||
{
|
{
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: wrong mapid = %d, instanceid = %d!", mapId, instanceId);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->Instanceable())
|
|
||||||
{
|
|
||||||
if (instanceId == 0)
|
|
||||||
{
|
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d for instanceable map!", mapId, instanceId);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))
|
|
||||||
{
|
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong difficulty %u!", mapId, instanceId, difficulty);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resetTime)
|
if (!resetTime)
|
||||||
{
|
{
|
||||||
// initialize reset time
|
// initialize reset time
|
||||||
// for normal instances if no creatures are killed the instance will reset in two hours
|
// for normal instances if no creatures are killed the instance will reset in two hours
|
||||||
if (entry->map_type == MAP_RAID || difficulty > DUNGEON_DIFFICULTY_NORMAL)
|
if (mapEntry->map_type == MAP_RAID || difficulty > DUNGEON_DIFFICULTY_NORMAL)
|
||||||
resetTime = m_Scheduler.GetResetTimeFor(mapId,difficulty);
|
resetTime = m_Scheduler.GetResetTimeFor(mapEntry->MapID, difficulty);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resetTime = time(NULL) + 2 * HOUR;
|
resetTime = time(NULL) + 2 * HOUR;
|
||||||
// normally this will be removed soon after in InstanceMap::Add, prevent error
|
// normally this will be removed soon after in InstanceMap::Add, prevent error
|
||||||
m_Scheduler.ScheduleReset(true, resetTime, InstanceResetEvent(RESET_EVENT_DUNGEON, mapId, difficulty, instanceId));
|
m_Scheduler.ScheduleReset(true, resetTime, InstanceResetEvent(RESET_EVENT_DUNGEON, mapEntry->MapID, difficulty, instanceId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (instanceId != 0)
|
|
||||||
{
|
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d for non-instanceable map!", mapId, instanceId);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (difficulty != REGULAR_DIFFICULTY)
|
DEBUG_LOG("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, reset time = %u, canRset = %u", mapEntry->MapID, instanceId, resetTime, canReset ? 1 : 0);
|
||||||
{
|
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong difficulty %u for non-instanceable map!", mapId, instanceId, difficulty);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resetTime)
|
InstanceSave *save = new InstanceSave(mapEntry->MapID, instanceId, difficulty, resetTime, canReset);
|
||||||
{
|
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong reset time %u for non-instanceable map!", mapId, instanceId, resetTime);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canReset)
|
|
||||||
{
|
|
||||||
sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong canReset %u for non-instanceable map!", mapId, instanceId, canReset ? 1 : 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, reset time = %u, canRset = %u", mapId, instanceId, resetTime, canReset ? 1 : 0);
|
|
||||||
|
|
||||||
InstanceSave *save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset);
|
|
||||||
if (!load)
|
if (!load)
|
||||||
save->SaveToDB();
|
save->SaveToDB();
|
||||||
|
|
||||||
if (entry->Instanceable())
|
if (mapEntry->Instanceable())
|
||||||
m_instanceSaveByInstanceId[instanceId] = save;
|
m_instanceSaveByInstanceId[instanceId] = save;
|
||||||
else
|
else
|
||||||
m_instanceSaveByMapId[mapId] = save;
|
m_instanceSaveByMapId[mapEntry->MapID] = save;
|
||||||
|
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
|
|
@ -565,8 +529,9 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 mapId, uint32 instanceId)
|
||||||
if (itr != m_instanceSaveByInstanceId.end())
|
if (itr != m_instanceSaveByInstanceId.end())
|
||||||
{
|
{
|
||||||
// save the resettime for normal instances only when they get unloaded
|
// save the resettime for normal instances only when they get unloaded
|
||||||
if(time_t resettime = itr->second->GetResetTimeForDB())
|
if (itr->second->GetMapEntry()->IsDungeon())
|
||||||
CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, instanceId);
|
if (time_t resettime = itr->second->GetResetTimeForDB())
|
||||||
|
CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, instanceId);
|
||||||
|
|
||||||
_ResetSave(m_instanceSaveByInstanceId, itr);
|
_ResetSave(m_instanceSaveByInstanceId, itr);
|
||||||
}
|
}
|
||||||
|
|
@ -843,7 +808,7 @@ void InstanceSaveManager::LoadCreatureRespawnTimes()
|
||||||
// instances loaded early and respawn data must exist only for existed instances (save loaded) or non-instanced maps
|
// instances loaded early and respawn data must exist only for existed instances (save loaded) or non-instanced maps
|
||||||
InstanceSave* save = instanceId
|
InstanceSave* save = instanceId
|
||||||
? GetInstanceSave(data->mapid, instanceId)
|
? GetInstanceSave(data->mapid, instanceId)
|
||||||
: AddInstanceSave(data->mapid, 0, REGULAR_DIFFICULTY, 0, false, true);
|
: AddInstanceSave(mapEntry, 0, REGULAR_DIFFICULTY, 0, false, true);
|
||||||
|
|
||||||
if (!save)
|
if (!save)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -903,7 +868,7 @@ void InstanceSaveManager::LoadGameobjectRespawnTimes()
|
||||||
// instances loaded early and respawn data must exist only for existed instances (save loaded) or non-instanced maps
|
// instances loaded early and respawn data must exist only for existed instances (save loaded) or non-instanced maps
|
||||||
InstanceSave* save = instanceId
|
InstanceSave* save = instanceId
|
||||||
? GetInstanceSave(data->mapid, instanceId)
|
? GetInstanceSave(data->mapid, instanceId)
|
||||||
: AddInstanceSave(data->mapid, 0, REGULAR_DIFFICULTY, 0, false, true);
|
: AddInstanceSave(mapEntry, 0, REGULAR_DIFFICULTY, 0, false, true);
|
||||||
|
|
||||||
if (!save)
|
if (!save)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton<InstanceSav
|
||||||
|
|
||||||
InstanceResetScheduler& GetScheduler() { return m_Scheduler; }
|
InstanceResetScheduler& GetScheduler() { return m_Scheduler; }
|
||||||
|
|
||||||
InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load = false);
|
InstanceSave* AddInstanceSave(MapEntry const* mapEntry, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load = false);
|
||||||
InstanceSave *GetInstanceSave(uint32 mapId, uint32 InstanceId);
|
InstanceSave *GetInstanceSave(uint32 mapId, uint32 InstanceId);
|
||||||
void RemoveInstanceSave(uint32 mapId, uint32 instanceId);
|
void RemoveInstanceSave(uint32 mapId, uint32 instanceId);
|
||||||
static void DeleteInstanceFromDB(uint32 instanceid);
|
static void DeleteInstanceFromDB(uint32 instanceid);
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
|
||||||
//add reference for TerrainData object
|
//add reference for TerrainData object
|
||||||
m_TerrainData->AddRef();
|
m_TerrainData->AddRef();
|
||||||
|
|
||||||
m_instanceSave = sInstanceSaveMgr.AddInstanceSave(GetId(), GetInstanceId(), GetDifficulty(), 0, Instanceable());
|
m_instanceSave = sInstanceSaveMgr.AddInstanceSave(i_mapEntry, GetInstanceId(), GetDifficulty(), 0, IsDungeon());
|
||||||
m_instanceSave->SetUsedByMapState(true);
|
m_instanceSave->SetUsedByMapState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3621,7 +3621,7 @@ void ObjectMgr::LoadGroups()
|
||||||
diff = REGULAR_DIFFICULTY; // default for both difficaly types
|
diff = REGULAR_DIFFICULTY; // default for both difficaly types
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceSave *save = sInstanceSaveMgr.AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), Difficulty(diff), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
|
InstanceSave *save = sInstanceSaveMgr.AddInstanceSave(mapEntry, fields[2].GetUInt32(), Difficulty(diff), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
|
||||||
group->BindToInstance(save, fields[3].GetBool(), true);
|
group->BindToInstance(save, fields[3].GetBool(), true);
|
||||||
}while( result->NextRow() );
|
}while( result->NextRow() );
|
||||||
delete result;
|
delete result;
|
||||||
|
|
|
||||||
|
|
@ -16681,7 +16681,7 @@ void Player::_LoadBoundInstances(QueryResult *result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// since non permanent binds are always solo bind, they can always be reset
|
// since non permanent binds are always solo bind, they can always be reset
|
||||||
InstanceSave *save = sInstanceSaveMgr.AddInstanceSave(mapId, instanceId, Difficulty(difficulty), resetTime, !perm, true);
|
InstanceSave *save = sInstanceSaveMgr.AddInstanceSave(mapEntry, instanceId, Difficulty(difficulty), resetTime, !perm, true);
|
||||||
if(save) BindToInstance(save, perm, true);
|
if(save) BindToInstance(save, perm, true);
|
||||||
} while(result->NextRow());
|
} while(result->NextRow());
|
||||||
delete result;
|
delete result;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11123"
|
#define REVISION_NR "11124"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue