diff options
Diffstat (limited to 'src/server/game/Maps/Map.cpp')
-rw-r--r-- | src/server/game/Maps/Map.cpp | 106 |
1 files changed, 48 insertions, 58 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b55ce4dd3e5..7a4721f474e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -77,7 +77,7 @@ Map::~Map() // Delete all waiting spawns, else there will be a memory leak // This doesn't delete from database. - DeleteRespawnInfo(); + UnloadAllRespawnInfos(); while (!i_worldObjects.empty()) { @@ -3052,9 +3052,12 @@ void Map::Respawn(RespawnInfo* info, SQLTransaction dbTrans) if (!CheckRespawn(info)) { if (info->respawnTime) - SaveRespawnTime(info->type, info->spawnId, info->entry, info->respawnTime, info->zoneId, info->gridId, true, true, dbTrans); + { + _respawnTimes.decrease(info->handle); + SaveRespawnInfoDB(*info, dbTrans); + } else - RemoveRespawnTime(info); + DeleteRespawnInfo(info, dbTrans); return; } @@ -3062,23 +3065,13 @@ void Map::Respawn(RespawnInfo* info, SQLTransaction dbTrans) SpawnObjectType const type = info->type; uint32 const gridId = info->gridId; ObjectGuid::LowType const spawnId = info->spawnId; - RemoveRespawnTime(info); + DeleteRespawnInfo(info, dbTrans); DoRespawn(type, spawnId, gridId); } -void Map::Respawn(std::vector<RespawnInfo*>& respawnData, SQLTransaction dbTrans) +bool Map::AddRespawnInfo(RespawnInfo const& info) { - SQLTransaction trans = dbTrans ? dbTrans : CharacterDatabase.BeginTransaction(); - for (RespawnInfo* info : respawnData) - Respawn(info, trans); - if (!dbTrans) - CharacterDatabase.CommitTransaction(trans); -} - -void Map::AddRespawnInfo(RespawnInfo& info, bool replace) -{ - if (!info.spawnId) - return; + ASSERT(info.spawnId, "Attempt to schedule respawn with zero spawnid (type %u)", uint32(info.type)); RespawnInfoMap& bySpawnIdMap = GetRespawnMapForType(info.type); @@ -3086,13 +3079,10 @@ void Map::AddRespawnInfo(RespawnInfo& info, bool replace) if (it != bySpawnIdMap.end()) // spawnid already has a respawn scheduled { RespawnInfo* const existing = it->second; - if (replace || info.respawnTime < existing->respawnTime) // delete existing in this case + if (info.respawnTime < existing->respawnTime) // delete existing in this case DeleteRespawnInfo(existing); - else // don't delete existing, instead replace respawn time so caller saves the correct time - { - info.respawnTime = existing->respawnTime; - return; - } + else + return false; } // if we get to this point, we should insert the respawninfo (there either was no prior entry, or it was deleted already) @@ -3100,6 +3090,7 @@ void Map::AddRespawnInfo(RespawnInfo& info, bool replace) ri->handle = _respawnTimes.push(ri); bool success = bySpawnIdMap.emplace(ri->spawnId, ri).second; ASSERT(success, "Insertion of respawn info with id (%u,%u) into spawn id map failed - state desync.", uint32(ri->type), ri->spawnId); + return true; } static void PushRespawnInfoFrom(std::vector<RespawnInfo*>& data, RespawnInfoMap const& map, uint32 zoneId) @@ -3125,7 +3116,7 @@ RespawnInfo* Map::GetRespawnInfo(SpawnObjectType type, ObjectGuid::LowType spawn return it->second; } -void Map::DeleteRespawnInfo() // delete everything +void Map::UnloadAllRespawnInfos() // delete everything from memory { for (RespawnInfo* info : _respawnTimes) delete info; @@ -3134,7 +3125,7 @@ void Map::DeleteRespawnInfo() // delete everything _gameObjectRespawnTimesBySpawnId.clear(); } -void Map::DeleteRespawnInfo(RespawnInfo* info) +void Map::DeleteRespawnInfo(RespawnInfo* info, SQLTransaction dbTrans) { // Delete from all relevant containers to ensure consistency ASSERT(info); @@ -3143,15 +3134,10 @@ void Map::DeleteRespawnInfo(RespawnInfo* info) size_t const n = GetRespawnMapForType(info->type).erase(info->spawnId); ASSERT(n == 1, "Respawn stores inconsistent for map %u, spawnid %u (type %u)", GetId(), info->spawnId, uint32(info->type)); - //respawn heap + // respawn heap _respawnTimes.erase(info->handle); - // then cleanup the object - delete info; -} - -void Map::RemoveRespawnTime(RespawnInfo* info, bool doRespawn, SQLTransaction dbTrans) -{ + // database PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESPAWN); stmt->setUInt16(0, info->type); stmt->setUInt32(1, info->spawnId); @@ -3159,19 +3145,8 @@ void Map::RemoveRespawnTime(RespawnInfo* info, bool doRespawn, SQLTransaction db stmt->setUInt32(3, GetInstanceId()); CharacterDatabase.ExecuteOrAppend(dbTrans, stmt); - if (doRespawn) - Respawn(info); - else - DeleteRespawnInfo(info); -} - -void Map::RemoveRespawnTime(std::vector<RespawnInfo*>& respawnData, bool doRespawn, SQLTransaction dbTrans) -{ - SQLTransaction trans = dbTrans ? dbTrans : CharacterDatabase.BeginTransaction(); - for (RespawnInfo* info : respawnData) - RemoveRespawnTime(info, doRespawn, trans); - if (!dbTrans) - CharacterDatabase.CommitTransaction(trans); + // then cleanup the object + delete info; } void Map::ProcessRespawns() @@ -3200,6 +3175,7 @@ void Map::ProcessRespawns() { ASSERT(now < next->respawnTime); // infinite loop guard _respawnTimes.decrease(next->handle); + SaveRespawnInfoDB(*next); } } } @@ -3280,7 +3256,7 @@ bool Map::SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn, bool force, std::v continue; // we need to remove the respawn time, otherwise we'd end up double spawning - RemoveRespawnTime(data->type, data->spawnId, false); + RemoveRespawnTime(data->type, data->spawnId); } // don't spawn if the grid isn't loaded (will be handled in grid loader) @@ -4298,12 +4274,15 @@ void Map::UpdateIteratorBack(Player* player) m_mapRefIter = m_mapRefIter->nocheck_prev(); } -void Map::SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 zoneId, uint32 gridId, bool writeDB, bool replace, SQLTransaction dbTrans) +void Map::SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 zoneId, uint32 gridId, SQLTransaction dbTrans, bool startup) { + if (!spawnId) + return; + if (!respawnTime) { // Delete only - RemoveRespawnTime(type, spawnId, false, dbTrans); + RemoveRespawnTime(type, spawnId, dbTrans); return; } @@ -4314,19 +4293,23 @@ void Map::SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uin ri.respawnTime = respawnTime; ri.gridId = gridId; ri.zoneId = zoneId; - AddRespawnInfo(ri, replace); + bool success = AddRespawnInfo(ri); - if (writeDB) - SaveRespawnTimeDB(type, spawnId, ri.respawnTime, dbTrans); // might be different from original respawn time if we didn't replace + if (startup) + { + if (!success) + TC_LOG_ERROR("maps", "Attempt to load saved respawn %" PRIu64 " for (%u,%u) failed - duplicate respawn? Skipped.", respawnTime, uint32(type), spawnId); + } + else if (success) + SaveRespawnInfoDB(ri, dbTrans); } -void Map::SaveRespawnTimeDB(SpawnObjectType type, ObjectGuid::LowType spawnId, time_t respawnTime, SQLTransaction dbTrans) +void Map::SaveRespawnInfoDB(RespawnInfo const& info, SQLTransaction dbTrans) { - // Just here for support of compatibility mode PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_RESPAWN); - stmt->setUInt16(0, type); - stmt->setUInt32(1, spawnId); - stmt->setUInt64(2, uint64(respawnTime)); + stmt->setUInt16(0, info.type); + stmt->setUInt32(1, info.spawnId); + stmt->setUInt64(2, uint64(info.respawnTime)); stmt->setUInt16(3, GetId()); stmt->setUInt32(4, GetInstanceId()); CharacterDatabase.ExecuteOrAppend(dbTrans, stmt); @@ -4346,10 +4329,17 @@ void Map::LoadRespawnTimes() ObjectGuid::LowType spawnId = fields[1].GetUInt32(); uint64 respawnTime = fields[2].GetUInt64(); - if (SpawnData const* data = sObjectMgr->GetSpawnData(type, spawnId)) - SaveRespawnTime(type, spawnId, data->id, time_t(respawnTime), GetZoneId(data->spawnPoint), Trinity::ComputeGridCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY()).GetId(), false); + if (type < SPAWN_TYPE_MAX) + { + if (SpawnData const* data = sObjectMgr->GetSpawnData(type, spawnId)) + SaveRespawnTime(type, spawnId, data->id, time_t(respawnTime), GetZoneId(data->spawnPoint), Trinity::ComputeGridCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY()).GetId(), nullptr, true); + else + TC_LOG_ERROR("maps", "Loading saved respawn time of %" PRIu64 " for spawnid (%u,%u) - spawn does not exist, ignoring", respawnTime, uint32(type), spawnId); + } else - TC_LOG_ERROR("maps", "Loading saved respawn time of %" PRIu64 " for spawnid (%u,%u) - spawn does not exist, ignoring", respawnTime, uint32(type), spawnId); + { + TC_LOG_ERROR("maps", "Loading saved respawn time of %" PRIu64 " for spawnid (%u,%u) - invalid spawn type, ignoring", respawnTime, uint32(type), spawnId); + } } while (result->NextRow()); } |