diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-03-13 18:51:29 +0100 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2024-03-25 20:21:24 +0100 |
commit | 64724464407e5b7646a48e6a5191d6fd8997ac77 (patch) | |
tree | c2ddc8dcdfc7032e9d60fb59735895b388c0b096 | |
parent | 382d67622fc9b4ec7eeb9e3f8bd56876133901fd (diff) |
Core/Misc: Use our new unique_trackable_ptr for various classes exposed to scripts (not actually used anywhere currently)
(cherry picked from commit 4779fa5048642b57a0f69de7ab56b9d563c1cbc4)
32 files changed, 177 insertions, 129 deletions
diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index 66627e24b0a..02576edbd5c 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -4090,9 +4090,9 @@ void CriteriaMgr::LoadCriteriaList() scenarioCriteriaTreeIds[scenarioStep->Criteriatreeid] = scenarioStep; std::unordered_map<uint32 /*criteriaTreeID*/, QuestObjective const*> questObjectiveCriteriaTreeIds; - for (auto const& questTemplatePair : sObjectMgr->GetQuestTemplates()) + for (auto const& [questId, quest] : sObjectMgr->GetQuestTemplates()) { - for (QuestObjective const& objective : questTemplatePair.second.Objectives) + for (QuestObjective const& objective : quest->Objectives) { if (objective.Type != QUEST_OBJECTIVE_CRITERIA_TREE) continue; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 9d123881401..fff4ceebca7 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -124,7 +124,6 @@ Battleground::~Battleground() for (uint32 i = 0; i < size; ++i) DelObject(i); - sBattlegroundMgr->RemoveBattleground(GetTypeID(), GetInstanceID()); // unload map if (m_Map) { diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index a3e0ca3ee32..b01152636e5 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -22,6 +22,7 @@ #include "ObjectGuid.h" #include "Position.h" #include "SharedDefines.h" +#include "UniqueTrackablePtr.h" #include "ZoneScript.h" #include <deque> #include <map> @@ -497,6 +498,9 @@ class TC_GAME_API Battleground : public ZoneScript // Called when valid BattlegroundMap is assigned to the battleground virtual void OnMapSet([[maybe_unused]] BattlegroundMap* map) { } + Trinity::unique_weak_ptr<Battleground> GetWeakPtr() const { return m_weakRef; } + void SetWeakPtr(Trinity::unique_weak_ptr<Battleground> weakRef) { m_weakRef = std::move(weakRef); } + protected: // this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends Battleground void EndNow(); @@ -612,5 +616,7 @@ class TC_GAME_API Battleground : public ZoneScript // Time when the first message "the battle will begin in 2minutes" is send (or 1m for arenas) time_t _preparationStartTime; + + Trinity::unique_weak_ptr<Battleground> m_weakRef; }; #endif diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index b07012c59db..37311c718f2 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -84,22 +84,7 @@ BattlegroundMgr::~BattlegroundMgr() void BattlegroundMgr::DeleteAllBattlegrounds() { - for (BattlegroundDataContainer::iterator itr1 = bgDataStore.begin(); itr1 != bgDataStore.end(); ++itr1) - { - BattlegroundData& data = itr1->second; - - while (!data.m_Battlegrounds.empty()) - delete data.m_Battlegrounds.begin()->second; - - data.m_Battlegrounds.clear(); - } - bgDataStore.clear(); - - for (auto itr = m_BGFreeSlotQueue.begin(); itr != m_BGFreeSlotQueue.end(); ++itr) - while (!itr->second.empty()) - delete itr->second.front(); - m_BGFreeSlotQueue.clear(); } @@ -122,18 +107,19 @@ void BattlegroundMgr::Update(uint32 diff) for (BattlegroundContainer::iterator itr = itrDelete; itr != bgs.end();) { itrDelete = itr++; - Battleground* bg = itrDelete->second; + Battleground* bg = itrDelete->second.get(); bg->Update(m_UpdateTimer); if (bg->ToBeDeleted()) { - itrDelete->second = nullptr; - bgs.erase(itrDelete); BattlegroundClientIdsContainer& clients = itr1->second.m_ClientBattlegroundIds[bg->GetBracketId()]; if (!clients.empty()) clients.erase(bg->GetClientInstanceID()); - delete bg; + // move out unique_ptr to delete after erasing + Trinity::unique_trackable_ptr<Battleground> bgPtr = std::move(itrDelete->second); + + bgs.erase(itrDelete); } } } @@ -270,7 +256,7 @@ Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTy BattlegroundContainer const& bgs = it->second.m_Battlegrounds; BattlegroundContainer::const_iterator itr = bgs.find(instanceId); if (itr != bgs.end()) - return itr->second; + return itr->second.get(); } return nullptr; @@ -745,10 +731,9 @@ void BattlegroundMgr::RemoveFromBGFreeSlotQueue(uint32 mapId, uint32 instanceId) void BattlegroundMgr::AddBattleground(Battleground* bg) { if (bg) - bgDataStore[bg->GetTypeID()].m_Battlegrounds[bg->GetInstanceID()] = bg; -} - -void BattlegroundMgr::RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId) -{ - bgDataStore[bgTypeId].m_Battlegrounds.erase(instanceId); + { + Trinity::unique_trackable_ptr<Battleground>& ptr = bgDataStore[bg->GetTypeID()].m_Battlegrounds[bg->GetInstanceID()]; + ptr.reset(bg); + bg->SetWeakPtr(ptr); + } } diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index ff62461b6c2..854f6da9cfa 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -22,12 +22,13 @@ #include "DBCEnums.h" #include "Battleground.h" #include "BattlegroundQueue.h" +#include "UniqueTrackablePtr.h" #include <unordered_map> class Battleground; struct BattlemasterListEntry; -typedef std::map<uint32, Battleground*> BattlegroundContainer; +typedef std::map<uint32, Trinity::unique_trackable_ptr<Battleground>> BattlegroundContainer; typedef std::set<uint32> BattlegroundClientIdsContainer; typedef std::unordered_map<uint32, BattlegroundTypeId> BattleMastersMap; @@ -102,7 +103,6 @@ class TC_GAME_API BattlegroundMgr Battleground* CreateNewBattleground(BattlegroundQueueTypeId queueId, BattlegroundBracketId bracketId); void AddBattleground(Battleground* bg); - void RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId); void AddToBGFreeSlotQueue(Battleground* bg); void RemoveFromBGFreeSlotQueue(uint32 mapId, uint32 instanceId); BGFreeSlotQueueContainer& GetBGFreeSlotQueueStore(uint32 mapId); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 8e31a00d45f..b6434b2b0b0 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -69,7 +69,7 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max MAX_VISIBILITY_DISTANCE }; -Object::Object() : m_values(this) +Object::Object() : m_values(this), m_scriptRef(this, NoopObjectDeleter()) { m_objectTypeId = TYPEID_OBJECT; m_objectType = TYPEMASK_OBJECT; @@ -114,6 +114,11 @@ void Object::AddToWorld() // synchronize values mirror with values array (changes will send in updatecreate opcode any way ASSERT(!m_objectUpdated); ClearUpdateMask(false); + + // Set new ref when adding to world (except if we already have one - also set in constructor to allow scripts to work in initialization phase) + // Changing the ref when adding/removing from world prevents accessing players on different maps (possibly from another thread) + if (!m_scriptRef) + m_scriptRef.reset(this, NoopObjectDeleter()); } void Object::RemoveFromWorld() @@ -125,6 +130,8 @@ void Object::RemoveFromWorld() // if we remove from world then sending changes not required ClearUpdateMask(true); + + m_scriptRef = nullptr; } void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 07cf03d3e28..2df91649ae5 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -32,6 +32,7 @@ #include "Position.h" #include "SharedDefines.h" #include "SpellDefines.h" +#include "UniqueTrackablePtr.h" #include "UpdateFields.h" #include <list> #include <unordered_map> @@ -260,6 +261,8 @@ class TC_GAME_API Object virtual std::string GetDebugInfo() const; + Trinity::unique_weak_ptr<Object> GetWeakPtr() const { return m_scriptRef; } + virtual Loot* GetLootForPlayer([[maybe_unused]] Player const* player) const { return nullptr; } protected: @@ -399,6 +402,9 @@ class TC_GAME_API Object bool m_isNewObject; bool m_isDestroyedObject; + struct NoopObjectDeleter { void operator()(Object*) const { /*noop - not managed*/ } }; + Trinity::unique_trackable_ptr<Object> m_scriptRef; + Object(Object const& right) = delete; Object(Object&& right) = delete; Object& operator=(Object const& right) = delete; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 37e84f8b105..7003838c8bb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3847,7 +3847,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); if (ObjectGuid::LowType guildId = sCharacterCache->GetCharacterGuildIdByGuid(playerguid)) if (Guild* guild = sGuildMgr->GetGuildById(guildId)) - guild->DeleteMember(trans, playerguid, false, false, true); + guild->DeleteMember(trans, playerguid, false, false); // remove from arena teams LeaveAllArenaTeams(playerguid); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 688628d2cd6..fd85298a660 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4250,8 +4250,8 @@ void Unit::RemoveAllAuras() { sstr << "m_ownedAuras:" << "\n"; - for (std::pair<uint32 const, Aura*>& auraPair : m_ownedAuras) - sstr << auraPair.second->GetDebugInfo() << "\n"; + for (auto const& [spellId, aura] : m_ownedAuras) + sstr << aura->GetDebugInfo() << "\n"; } TC_LOG_ERROR("entities.unit", "{}", sstr.str()); @@ -11386,7 +11386,7 @@ bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry, bool loading /*= fa if (!vehInfo) return false; - m_vehicleKit = std::make_unique<Vehicle>(this, vehInfo, creatureEntry); + m_vehicleKit = Trinity::make_unique_trackable<Vehicle>(this, vehInfo, creatureEntry); m_updateFlag.Vehicle = true; m_unitTypeMask |= UNIT_MASK_VEHICLE; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 86040e3dcbd..7957161d9e7 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1690,6 +1690,7 @@ class TC_GAME_API Unit : public WorldObject bool CreateVehicleKit(uint32 id, uint32 creatureEntry, bool loading = false); void RemoveVehicleKit(bool onRemoveFromWorld = false); Vehicle* GetVehicleKit() const { return m_vehicleKit.get(); } + Trinity::unique_weak_ptr<Vehicle> GetVehicleKitWeakPtr() const { return m_vehicleKit; } Vehicle* GetVehicle() const { return m_vehicle; } void SetVehicle(Vehicle* vehicle) { m_vehicle = vehicle; } bool IsOnVehicle(Unit const* vehicle) const; @@ -1888,7 +1889,7 @@ class TC_GAME_API Unit : public WorldObject uint32 m_regenTimer; Vehicle* m_vehicle; - std::unique_ptr<Vehicle> m_vehicleKit; + Trinity::unique_trackable_ptr<Vehicle> m_vehicleKit; uint32 m_unitTypeMask; LiquidTypeEntry const* _lastLiquid; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index d00f313e56d..1d5a4abede9 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -993,3 +993,8 @@ std::string Vehicle::GetDebugInfo() const return sstr.str(); } + +Trinity::unique_weak_ptr<Vehicle> Vehicle::GetWeakPtr() const +{ + return _me->GetVehicleKitWeakPtr(); +} diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index a888a8a9007..e0ca5e9d632 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -19,8 +19,9 @@ #define __TRINITY_VEHICLE_H #include "Object.h" -#include "VehicleDefines.h" +#include "UniqueTrackablePtr.h" #include "Unit.h" +#include "VehicleDefines.h" #include <list> struct VehicleEntry; @@ -73,6 +74,8 @@ class TC_GAME_API Vehicle final : public TransportBase std::string GetDebugInfo() const; + Trinity::unique_weak_ptr<Vehicle> GetWeakPtr() const; + protected: friend class VehicleJoinEvent; uint32 UsableSeatNum; ///< Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 76d05614af6..a40f31552f0 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -4565,9 +4565,10 @@ void ObjectMgr::LoadQuests() Field* fields = result->Fetch(); uint32 questId = fields[0].GetUInt32(); - auto itr = _questTemplates.emplace(std::piecewise_construct, std::forward_as_tuple(questId), std::forward_as_tuple(fields)).first; - if (itr->second.IsAutoPush()) - _questTemplatesAutoPush.push_back(&itr->second); + auto itr = _questTemplates.emplace(std::piecewise_construct, std::forward_as_tuple(questId), std::forward_as_tuple(new Quest(fields))).first; + itr->second->_weakRef = itr->second; + if (itr->second->IsAutoPush()) + _questTemplatesAutoPush.push_back(itr->second.get()); } while (result->NextRow()); struct QuestLoaderHelper @@ -4642,7 +4643,7 @@ void ObjectMgr::LoadQuests() auto itr = _questTemplates.find(questId); if (itr != _questTemplates.end()) - (itr->second.*loader.LoaderFunction)(fields); + (itr->second.get()->*loader.LoaderFunction)(fields); else TC_LOG_ERROR("server.loading", "Table `{}` has data for quest {} but such quest does not exist", loader.TableName, questId); } while (result->NextRow()); @@ -4683,7 +4684,7 @@ void ObjectMgr::LoadQuests() // Do not throw error here because error for non existing quest is thrown while loading quest objectives. we do not need duplication auto itr = _questTemplates.find(questId); if (itr != _questTemplates.end()) - itr->second.LoadQuestObjectiveVisualEffect(fields); + itr->second->LoadQuestObjectiveVisualEffect(fields); } while (result->NextRow()); } @@ -4696,7 +4697,7 @@ void ObjectMgr::LoadQuests() if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, questPair.first, nullptr)) continue; - Quest* qinfo = &questPair.second; + Quest* qinfo = questPair.second.get(); // additional quest integrity checks (GO, creature_template and items must be loaded already) @@ -5276,7 +5277,7 @@ void ObjectMgr::LoadQuests() auto prevQuestItr = _questTemplates.find(prevQuestId); if (prevQuestItr == _questTemplates.end()) TC_LOG_ERROR("sql.sql", "Quest {} has PrevQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId()); - else if (prevQuestItr->second._breadcrumbForQuestId) + else if (prevQuestItr->second->_breadcrumbForQuestId) TC_LOG_ERROR("sql.sql", "Quest {} should not be unlocked by breadcrumb quest {}", qinfo->_id, prevQuestId); else if (qinfo->_prevQuestID > 0) qinfo->DependentPreviousQuests.push_back(prevQuestId); @@ -5288,7 +5289,7 @@ void ObjectMgr::LoadQuests() if (nextQuestItr == _questTemplates.end()) TC_LOG_ERROR("sql.sql", "Quest {} has NextQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->_nextQuestID); else - nextQuestItr->second.DependentPreviousQuests.push_back(qinfo->GetQuestId()); + nextQuestItr->second->DependentPreviousQuests.push_back(qinfo->GetQuestId()); } if (uint32 breadcrumbForQuestId = std::abs(qinfo->_breadcrumbForQuestId)) @@ -5313,7 +5314,7 @@ void ObjectMgr::LoadQuests() if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, questPair.first, nullptr)) continue; - Quest* qinfo = &questPair.second; + Quest* qinfo = questPair.second.get(); uint32 qid = qinfo->GetQuestId(); uint32 breadcrumbForQuestId = std::abs(qinfo->_breadcrumbForQuestId); std::set<uint32> questSet; @@ -6762,7 +6763,8 @@ uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, uint32 team, bool allowed_alt Quest const* ObjectMgr::GetQuestTemplate(uint32 quest_id) const { - return Trinity::Containers::MapGetValuePtr(_questTemplates, quest_id); + auto itr = _questTemplates.find(quest_id); + return itr != _questTemplates.end() ? itr->second.get() : nullptr; } void ObjectMgr::LoadGraveyardZones() @@ -10851,7 +10853,7 @@ void ObjectMgr::InitializeQueriesData(QueryDataGroup mask) // Initialize Query Data for quests if (mask & QUERY_DATA_QUESTS) for (auto& questTemplatePair : _questTemplates) - pool.PostWork([quest = &questTemplatePair.second]() { quest->InitializeQueryData(); }); + pool.PostWork([quest = questTemplatePair.second.get()]() { quest->InitializeQueryData(); }); // Initialize Quest POI data if (mask & QUERY_DATA_POIS) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 392fb9abaef..2ffc9f94989 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -36,6 +36,7 @@ #include "SharedDefines.h" #include "Trainer.h" #include "VehicleDefines.h" +#include "UniqueTrackablePtr.h" #include <iterator> #include <map> #include <unordered_map> @@ -1067,7 +1068,7 @@ class TC_GAME_API ObjectMgr static ObjectMgr* instance(); - typedef std::unordered_map<uint32, Quest> QuestContainer; + typedef std::unordered_map<uint32, Trinity::unique_trackable_ptr<Quest>> QuestContainer; typedef std::unordered_map<uint32 /*questObjectiveId*/, QuestObjective const*> QuestObjectivesByIdContainer; typedef std::unordered_map<uint32, AreaTriggerStruct> AreaTriggerContainer; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index ea6c783571e..9f585f1fa04 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -59,7 +59,7 @@ Group::Group() : m_leaderGuid(), m_leaderFactionGroup(0), m_leaderName(""), m_gr m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_NORMAL_RAID), m_legacyRaidDifficulty(DIFFICULTY_10_N), m_bgGroup(nullptr), m_bfGroup(nullptr), m_lootMethod(PERSONAL_LOOT), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_dbStoreId(0), m_isLeaderOffline(false), -m_readyCheckStarted(false), m_readyCheckTimer(Milliseconds::zero()), m_activeMarkers(0) +m_readyCheckStarted(false), m_readyCheckTimer(Milliseconds::zero()), m_activeMarkers(0), m_scriptRef(this, NoopGroupDeleter()) { for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].Clear(); diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index ee28dcb7f9a..917da8dc599 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -26,6 +26,7 @@ #include "RaceMask.h" #include "SharedDefines.h" #include "Timer.h" +#include "UniqueTrackablePtr.h" #include <map> class Battlefield; @@ -409,6 +410,8 @@ class TC_GAME_API Group void StartCountdown(CountdownTimerType timerType, Seconds duration, Optional<time_t> startTime = { }); CountdownInfo const* GetCountdownInfo(CountdownTimerType timerType) const; + Trinity::unique_weak_ptr<Group> GetWeakPtr() const { return m_scriptRef; } + protected: bool _setMembersGroup(ObjectGuid guid, uint8 group); void _homebindIfInstance(Player* player); @@ -455,5 +458,8 @@ class TC_GAME_API Group uint32 m_activeMarkers; std::array<std::unique_ptr<CountdownInfo>, 3> _countdowns; + + struct NoopGroupDeleter { void operator()(Group*) const { /*noop - not managed*/ } }; + Trinity::unique_trackable_ptr<Group> m_scriptRef; }; #endif diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index dd37eb767fb..714d9fd4729 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1761,7 +1761,8 @@ void Guild::HandleAcceptMember(WorldSession* session) void Guild::HandleLeaveMember(WorldSession* session) { Player* player = session->GetPlayer(); - bool disband = false; + + sCalendarMgr->RemovePlayerGuildEventsAndSignups(player->GetGUID(), GetId()); // If leader is leaving if (_IsLeader(player)) @@ -1773,7 +1774,6 @@ void Guild::HandleLeaveMember(WorldSession* session) { // Guild is disbanded if leader leaves. Disband(); - disband = true; } } else @@ -1781,16 +1781,11 @@ void Guild::HandleLeaveMember(WorldSession* session) _LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUID().GetCounter()); SendEventPlayerLeft(GetMember(player->GetGUID())); + SendCommandResult(session, GUILD_COMMAND_LEAVE_GUILD, ERR_GUILD_COMMAND_SUCCESS, m_name); + CharacterDatabaseTransaction trans(nullptr); DeleteMember(trans, player->GetGUID(), false, false); - - SendCommandResult(session, GUILD_COMMAND_LEAVE_GUILD, ERR_GUILD_COMMAND_SUCCESS, m_name); } - - sCalendarMgr->RemovePlayerGuildEventsAndSignups(player->GetGUID(), GetId()); - - if (disband) - delete this; } void Guild::HandleRemoveMember(WorldSession* session, ObjectGuid guid) @@ -1821,11 +1816,11 @@ void Guild::HandleRemoveMember(WorldSession* session, ObjectGuid guid) _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUID().GetCounter(), guid.GetCounter()); SendEventPlayerLeft(member, memberMe, true); + SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_COMMAND_SUCCESS, name); + // After call to DeleteMember pointer to member becomes invalid CharacterDatabaseTransaction trans(nullptr); DeleteMember(trans, guid, false, true); - - SendCommandResult(session, GUILD_COMMAND_REMOVE_PLAYER, ERR_GUILD_COMMAND_SUCCESS, name); } } } @@ -2145,7 +2140,6 @@ void Guild::HandleDelete(WorldSession* session) { Disband(); TC_LOG_DEBUG("guild", "{} successfully deleted", GetGUID().ToString()); - delete this; } } @@ -2708,13 +2702,8 @@ bool Guild::Validate() if (!leader) { CharacterDatabaseTransaction dummy(nullptr); - DeleteMember(dummy, m_leaderGuid); - // If no more members left, disband guild - if (m_members.empty()) - { - Disband(); + if (DeleteMember(dummy, m_leaderGuid)) return false; - } } else if (!leader->IsRank(GuildRankId::GuildMaster)) _SetLeader(trans, *leader); @@ -2963,7 +2952,7 @@ bool Guild::AddMember(CharacterDatabaseTransaction trans, ObjectGuid guid, Optio return true; } -void Guild::DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bool isDisbanding, bool isKicked, bool canDeleteGuild) +bool Guild::DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bool isDisbanding, bool isKicked) { // Guild master can be deleted when loading guild and guid doesn't exist in characters table // or when he is removed from guild by gm command @@ -2982,9 +2971,7 @@ void Guild::DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bo if (!newLeader) { Disband(); - if (canDeleteGuild) - delete this; - return; + return true; } _SetLeader(trans, *newLeader); @@ -3018,6 +3005,14 @@ void Guild::DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bo Guild::_DeleteMemberFromDB(trans, guid.GetCounter()); if (!isDisbanding) _UpdateAccountsNumber(); + + if (m_members.empty()) + { + Disband(); + return true; + } + + return false; } bool Guild::ChangeMemberRank(CharacterDatabaseTransaction trans, ObjectGuid guid, GuildRankId newRank) diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 10384f091d1..ea39a1682b7 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -25,6 +25,7 @@ #include "Optional.h" #include "RaceMask.h" #include "SharedDefines.h" +#include "UniqueTrackablePtr.h" #include <set> #include <unordered_map> @@ -843,7 +844,7 @@ class TC_GAME_API Guild // Members // Adds member to guild. If rankId == GUILD_RANK_NONE, lowest rank is assigned. bool AddMember(CharacterDatabaseTransaction trans, ObjectGuid guid, Optional<GuildRankId> rankId = {}); - void DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bool isDisbanding = false, bool isKicked = false, bool canDeleteGuild = false); + bool DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bool isDisbanding = false, bool isKicked = false); bool ChangeMemberRank(CharacterDatabaseTransaction trans, ObjectGuid guid, GuildRankId newRank); bool IsMember(ObjectGuid guid) const; uint32 GetMembersCount() const { return uint32(m_members.size()); } @@ -872,6 +873,9 @@ class TC_GAME_API Guild bool HasAchieved(uint32 achievementId) const; void UpdateCriteria(CriteriaType type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject const* ref, Player* player); + Trinity::unique_weak_ptr<Guild> GetWeakPtr() const { return m_weakRef; } + void SetWeakPtr(Trinity::unique_weak_ptr<Guild> weakRef) { m_weakRef = std::move(weakRef); } + protected: ObjectGuid::LowType m_id; std::string m_name; @@ -894,6 +898,8 @@ class TC_GAME_API Guild LogHolder<NewsLogEntry> m_newsLog; std::unique_ptr<GuildAchievementMgr> m_achievementMgr; + Trinity::unique_weak_ptr<Guild> m_weakRef; + private: inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); } RankInfo const* GetRankInfo(GuildRankId rankId) const; diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index f7d8dd86f6e..b7d32576147 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -17,8 +17,8 @@ #include "GuildMgr.h" #include "AchievementMgr.h" -#include "DatabaseEnv.h" #include "DB2Stores.h" +#include "DatabaseEnv.h" #include "Guild.h" #include "Log.h" #include "ObjectMgr.h" @@ -29,15 +29,13 @@ GuildMgr::GuildMgr() : NextGuildId(UI64LIT(1)) { } -GuildMgr::~GuildMgr() -{ - for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) - delete itr->second; -} +GuildMgr::~GuildMgr() = default; void GuildMgr::AddGuild(Guild* guild) { - GuildStore[guild->GetId()] = guild; + Trinity::unique_trackable_ptr<Guild>& ptr = GuildStore[guild->GetId()]; + ptr.reset(guild); + guild->SetWeakPtr(ptr); } void GuildMgr::RemoveGuild(ObjectGuid::LowType guildId) @@ -66,7 +64,7 @@ Guild* GuildMgr::GetGuildById(ObjectGuid::LowType guildId) const { GuildContainer::const_iterator itr = GuildStore.find(guildId); if (itr != GuildStore.end()) - return itr->second; + return itr->second.get(); return nullptr; } @@ -84,9 +82,9 @@ Guild* GuildMgr::GetGuildByGuid(ObjectGuid guid) const Guild* GuildMgr::GetGuildByName(std::string_view guildName) const { - for (auto [id, guild] : GuildStore) + for (auto const& [id, guild] : GuildStore) if (StringEqualI(guild->GetName(), guildName)) - return guild; + return guild.get(); return nullptr; } @@ -109,7 +107,7 @@ Guild* GuildMgr::GetGuildByLeader(ObjectGuid guid) const { for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) if (itr->second->GetLeaderGUID() == guid) - return itr->second; + return itr->second.get(); return nullptr; } @@ -483,10 +481,10 @@ void GuildMgr::LoadGuilds() for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end();) { - Guild* guild = itr->second; + Guild* guild = itr->second.get(); ++itr; - if (guild && !guild->Validate()) - delete guild; + if (guild) + guild->Validate(); } TC_LOG_INFO("server.loading", ">> Validated data of loaded guilds in {} ms", GetMSTimeDiffToNow(oldMSTime)); @@ -562,6 +560,6 @@ void GuildMgr::ResetTimes(bool week) CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW)); for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) - if (Guild* guild = itr->second) + if (Guild* guild = itr->second.get()) guild->ResetTimes(week); } diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index f700f8122c1..5c021648a28 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -20,6 +20,7 @@ #include "Define.h" #include "ObjectGuid.h" +#include "UniqueTrackablePtr.h" #include <unordered_map> #include <vector> @@ -60,7 +61,7 @@ public: void ResetTimes(bool week); protected: - typedef std::unordered_map<ObjectGuid::LowType, Guild*> GuildContainer; + typedef std::unordered_map<ObjectGuid::LowType, Trinity::unique_trackable_ptr<Guild>> GuildContainer; ObjectGuid::LowType NextGuildId; GuildContainer GuildStore; std::vector<GuildReward> GuildRewards; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 01d75d58b51..ebb57753f3a 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -2314,7 +2314,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa { // Reset guild if (Guild* guild = sGuildMgr->GetGuildById(characterInfo->GuildId)) - guild->DeleteMember(trans, factionChangeInfo->Guid, false, false, true); + guild->DeleteMember(trans, factionChangeInfo->Guid, false, false); Player::LeaveAllArenaTeams(factionChangeInfo->Guid); } @@ -2432,14 +2432,14 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa // Disable all old-faction specific quests { ObjectMgr::QuestContainer const& questTemplates = sObjectMgr->GetQuestTemplates(); - for (auto const& questTemplatePair : questTemplates) + for (auto const& [questId, quest] : questTemplates) { Trinity::RaceMask<uint64> newRaceMask = (newTeamId == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE; - if (questTemplatePair.second.GetAllowableRaces().RawValue != uint64(-1) && (questTemplatePair.second.GetAllowableRaces() & newRaceMask).IsEmpty()) + if (quest->GetAllowableRaces().RawValue != uint64(-1) && (quest->GetAllowableRaces() & newRaceMask).IsEmpty()) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST); stmt->setUInt64(0, lowGuid); - stmt->setUInt32(1, questTemplatePair.first); + stmt->setUInt32(1, questId); trans->Append(stmt); } } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 78a8cb3e647..0339d92a6ee 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -35,6 +35,7 @@ #include "SharedDefines.h" #include "SpawnData.h" #include "Timer.h" +#include "UniqueTrackablePtr.h" #include "WorldStateDefines.h" #include <bitset> #include <list> @@ -312,6 +313,9 @@ class TC_GAME_API Map : public GridRefManager<NGridType> uint32 GetInstanceId() const { return i_InstanceId; } + Trinity::unique_weak_ptr<Map> GetWeakPtr() const { return m_weakRef; } + void SetWeakPtr(Trinity::unique_weak_ptr<Map> weakRef) { m_weakRef = std::move(weakRef); } + static TransferAbortParams PlayerCannotEnter(uint32 mapid, Player* player); virtual TransferAbortParams CannotEnter(Player* /*player*/) { return { TRANSFER_ABORT_NONE }; } char const* GetMapName() const; @@ -605,6 +609,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> MapEntry const* i_mapEntry; Difficulty i_spawnMode; uint32 i_InstanceId; + Trinity::unique_weak_ptr<Map> m_weakRef; uint32 m_unloadTimer; float m_VisibleDistance; DynamicMapTree _dynamicTree; diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index a5adf85a197..3288b8551d1 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -65,7 +65,8 @@ MapManager* MapManager::instance() Map* MapManager::FindMap_i(uint32 mapId, uint32 instanceId) const { - return Trinity::Containers::MapGetValuePtr(i_maps, { mapId, instanceId }); + auto itr = i_maps.find({ mapId, instanceId }); + return itr != i_maps.end() ? itr->second.get() : nullptr; } Map* MapManager::CreateWorldMap(uint32 mapId, uint32 instanceId) @@ -230,7 +231,14 @@ Map* MapManager::CreateMap(uint32 mapId, Player* player) } if (map) - i_maps[{ map->GetId(), map->GetInstanceId() }] = map; + { + Trinity::unique_trackable_ptr<Map>& ptr = i_maps[{ map->GetId(), map->GetInstanceId() }]; + if (ptr.get() != map) + { + ptr.reset(map); + map->SetWeakPtr(ptr); + } + } return map; } @@ -295,7 +303,7 @@ void MapManager::Update(uint32 diff) { if (iter->second->CanUnload(diff)) { - if (DestroyMap(iter->second)) + if (DestroyMap(iter->second.get())) iter = i_maps.erase(iter); else ++iter; @@ -332,7 +340,6 @@ bool MapManager::DestroyMap(Map* map) sMapMgr->FreeInstanceId(map->GetInstanceId()); // erase map - delete map; return true; } @@ -348,9 +355,6 @@ void MapManager::UnloadAll() iter->second->UnloadAll(); // then delete them - for (auto iter = i_maps.begin(); iter != i_maps.end(); ++iter) - delete iter->second; - i_maps.clear(); if (m_updater.activated()) diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 53a7c731c43..aec828daff5 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -23,6 +23,7 @@ #include "MapUpdater.h" #include "Position.h" #include "SharedDefines.h" +#include "UniqueTrackablePtr.h" #include <boost/dynamic_bitset_fwd.hpp> #include <map> #include <shared_mutex> @@ -131,7 +132,7 @@ class TC_GAME_API MapManager private: using MapKey = std::pair<uint32, uint32>; - typedef std::map<MapKey, Map*> MapMapType; + typedef std::map<MapKey, Trinity::unique_trackable_ptr<Map>> MapMapType; typedef boost::dynamic_bitset<size_t> InstanceIds; Map* FindMap_i(uint32 mapId, uint32 instanceId) const; @@ -161,7 +162,7 @@ void MapManager::DoForAllMaps(Worker&& worker) std::shared_lock<std::shared_mutex> lock(_mapsLock); for (auto const& [key, map] : i_maps) - worker(map); + worker(map.get()); } template<typename Worker> @@ -175,7 +176,7 @@ void MapManager::DoForAllMapsWithMapId(uint32 mapId, Worker&& worker) ); for (auto const& [key, map] : range) - worker(map); + worker(map.get()); } #define sMapMgr MapManager::instance() diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index f795eedb51c..a518302143a 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -25,6 +25,7 @@ #include "Optional.h" #include "RaceMask.h" #include "SharedDefines.h" +#include "UniqueTrackablePtr.h" #include "WorldPacket.h" #include <bitset> #include <vector> @@ -719,6 +720,8 @@ class TC_GAME_API Quest // Helpers static uint32 RoundXPValue(uint32 xp); + Trinity::unique_weak_ptr<Quest> GetWeakPtr() const { return _weakRef; } + std::vector<uint32> DependentPreviousQuests; std::vector<uint32> DependentBreadcrumbQuests; std::array<WorldPacket, TOTAL_LOCALES> QueryData; @@ -828,6 +831,8 @@ class TC_GAME_API Quest uint32 _specialFlags = 0; // custom flags, not sniffed/WDB std::bitset<MAX_QUEST_OBJECTIVE_TYPE> _usedQuestObjectiveTypes; uint32 _scriptId = 0; + + Trinity::unique_weak_ptr<Quest> _weakRef; }; struct QuestStatusData diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 02790ed5d77..329ba558659 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -467,7 +467,7 @@ m_applyTime(GameTime::GetGameTime()), m_owner(createInfo._owner), m_timeCla(0), m_casterLevel(createInfo.Caster ? createInfo.Caster->GetLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1), m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr), m_procCooldown(TimePoint::min()), -m_lastProcAttemptTime(GameTime::Now() - Seconds(10)), m_lastProcSuccessTime(GameTime::Now() - Seconds(120)) +m_lastProcAttemptTime(GameTime::Now() - Seconds(10)), m_lastProcSuccessTime(GameTime::Now() - Seconds(120)), m_scriptRef(this, NoopAuraDeleter()) { for (SpellPowerEntry const* power : m_spellInfo->PowerCosts) if (power && (power->ManaPerSecond != 0 || power->PowerPctPerSecond > 0.0f)) @@ -614,6 +614,8 @@ void Aura::_Remove(AuraRemoveMode removeMode) m_dropEvent->ScheduleAbort(); m_dropEvent = nullptr; } + + m_scriptRef = nullptr; } void Aura::UpdateTargetMap(Unit* caster, bool apply) diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 195f5a2fda6..c38f8ee78ec 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -20,6 +20,7 @@ #include "SpellAuraDefines.h" #include "SpellInfo.h" +#include "UniqueTrackablePtr.h" #include <typeinfo> class SpellInfo; @@ -308,6 +309,8 @@ class TC_GAME_API Aura virtual std::string GetDebugInfo() const; + Trinity::unique_weak_ptr<Aura> GetWeakPtr() const { return m_scriptRef; } + Aura(Aura const&) = delete; Aura(Aura&&) = delete; @@ -356,6 +359,9 @@ class TC_GAME_API Aura std::vector<AuraApplication*> _removedApplications; AuraEffectVector _effects; + + struct NoopAuraDeleter { void operator()(Aura*) const { /*noop - not managed*/ } }; + Trinity::unique_trackable_ptr<Aura> m_scriptRef; }; class TC_GAME_API UnitAura : public Aura diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 53f3f79bc92..bb43a8be767 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -59,6 +59,7 @@ #include "TemporarySummon.h" #include "TradeData.h" #include "TraitPackets.h" +#include "UniqueTrackablePtr.h" #include "Util.h" #include "VMapFactory.h" #include "Vehicle.h" @@ -483,18 +484,19 @@ SpellValue::SpellValue(SpellInfo const* proto, WorldObject const* caster) class TC_GAME_API SpellEvent : public BasicEvent { public: - SpellEvent(Spell* spell); + explicit SpellEvent(Spell* spell); ~SpellEvent(); bool Execute(uint64 e_time, uint32 p_time) override; void Abort(uint64 e_time) override; bool IsDeletable() const override; - Spell const* GetSpell() const { return m_Spell; } + Spell const* GetSpell() const { return m_Spell.get(); } + Trinity::unique_weak_ptr<Spell> GetSpellWeakPtr() const { return m_Spell; } std::string GetDebugInfo() const { return m_Spell->GetDebugInfo(); } protected: - Spell* m_Spell; + Trinity::unique_trackable_ptr<Spell> m_Spell; }; Spell::Spell(WorldObject* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID /*= ObjectGuid::Empty*/, @@ -8116,9 +8118,8 @@ Unit* Spell::GetUnitCasterForEffectHandlers() const return m_originalCaster ? m_originalCaster : m_caster->ToUnit(); } -SpellEvent::SpellEvent(Spell* spell) : BasicEvent() +SpellEvent::SpellEvent(Spell* spell) : BasicEvent(), m_Spell(spell) { - m_Spell = spell; } SpellEvent::~SpellEvent() @@ -8126,11 +8127,7 @@ SpellEvent::~SpellEvent() if (m_Spell->getState() != SPELL_STATE_FINISHED) m_Spell->cancel(); - if (m_Spell->IsDeletable()) - { - delete m_Spell; - } - else + if (!m_Spell->IsDeletable()) { TC_LOG_ERROR("spells", "~SpellEvent: {} {} tried to delete non-deletable spell {}. Was not deleted, causes memory leak.", (m_Spell->GetCaster()->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), m_Spell->GetCaster()->GetGUID().ToString(), m_Spell->m_spellInfo->Id); @@ -8958,6 +8955,11 @@ std::string Spell::GetDebugInfo() const return sstr.str(); } +Trinity::unique_weak_ptr<Spell> Spell::GetWeakPtr() const +{ + return _spellEvent->GetSpellWeakPtr(); +} + bool Spell::IsWithinLOS(WorldObject const* source, WorldObject const* target, bool targetAsSourceLocation, VMAP::ModelIgnoreFlags ignoreFlags) const { if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT)) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9deaa008721..0c484b5ba56 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -26,6 +26,7 @@ #include "Position.h" #include "SharedDefines.h" #include "SpellDefines.h" +#include "UniqueTrackablePtr.h" #include <memory> namespace WorldPackets::Spells @@ -664,6 +665,9 @@ class TC_GAME_API Spell int64 GetCorpseTargetCountForEffect(SpellEffIndex effect) const; std::string GetDebugInfo() const; + + Trinity::unique_weak_ptr<Spell> GetWeakPtr() const; + void CallScriptOnResistAbsorbCalculateHandlers(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount); bool IsWithinLOS(WorldObject const* source, WorldObject const* target, bool targetAsSourceLocation, VMAP::ModelIgnoreFlags ignoreFlags) const; diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp index c824e370632..1518d0b5422 100644 --- a/src/server/scripts/Commands/cs_guild.cpp +++ b/src/server/scripts/Commands/cs_guild.cpp @@ -143,8 +143,6 @@ public: return false; targetGuild->Disband(); - delete targetGuild; - return true; } @@ -192,7 +190,7 @@ public: return false; CharacterDatabaseTransaction trans(nullptr); - targetGuild->DeleteMember(trans, targetGuid, false, true, true); + targetGuild->DeleteMember(trans, targetGuid, false, true); return true; } diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index 2986bb3ce13..2bbcf492c4a 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -135,8 +135,8 @@ public: Player* player = handler->GetPlayer(); for (auto const& [id, quest] : sObjectMgr->GetQuestTemplates()) { - if (quest.GetAllowableClasses() && player->SatisfyQuestClass(&quest, false)) - player->LearnQuestRewardedSpells(&quest); + if (quest->GetAllowableClasses() && player->SatisfyQuestClass(quest.get(), false)) + player->LearnQuestRewardedSpells(quest.get()); } return true; } diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index 354820cb2ec..e2e62eb3373 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -684,16 +684,16 @@ public: if (handler->GetSession()) { int32 maxLevel = 0; - if (Optional<ContentTuningLevels> questLevels = sDB2Manager.GetContentTuningData(questTemplatePair.second.GetContentTuningId(), 0)) + if (Optional<ContentTuningLevels> questLevels = sDB2Manager.GetContentTuningData(questTemplatePair.second->GetContentTuningId(), 0)) maxLevel = questLevels->MaxLevel; int32 scalingFactionGroup = 0; - if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(questTemplatePair.second.GetContentTuningId())) + if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(questTemplatePair.second->GetContentTuningId())) scalingFactionGroup = contentTuning->GetScalingFactionGroup(); handler->PSendSysMessage(LANG_QUEST_LIST_CHAT, questTemplatePair.first, questTemplatePair.first, - handler->GetSession()->GetPlayer()->GetQuestLevel(&questTemplatePair.second), - handler->GetSession()->GetPlayer()->GetQuestMinLevel(&questTemplatePair.second), + handler->GetSession()->GetPlayer()->GetQuestLevel(questTemplatePair.second.get()), + handler->GetSession()->GetPlayer()->GetQuestMinLevel(questTemplatePair.second.get()), maxLevel, scalingFactionGroup, title.c_str(), statusStr); } @@ -708,7 +708,7 @@ public: } } - std::string title = questTemplatePair.second.GetLogTitle(); + std::string title = questTemplatePair.second->GetLogTitle(); if (title.empty()) continue; @@ -743,16 +743,16 @@ public: if (handler->GetSession()) { int32 maxLevel = 0; - if (Optional<ContentTuningLevels> questLevels = sDB2Manager.GetContentTuningData(questTemplatePair.second.GetContentTuningId(), 0)) + if (Optional<ContentTuningLevels> questLevels = sDB2Manager.GetContentTuningData(questTemplatePair.second->GetContentTuningId(), 0)) maxLevel = questLevels->MaxLevel; int32 scalingFactionGroup = 0; - if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(questTemplatePair.second.GetContentTuningId())) + if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(questTemplatePair.second->GetContentTuningId())) scalingFactionGroup = contentTuning->GetScalingFactionGroup(); handler->PSendSysMessage(LANG_QUEST_LIST_CHAT, questTemplatePair.first, questTemplatePair.first, - handler->GetSession()->GetPlayer()->GetQuestLevel(&questTemplatePair.second), - handler->GetSession()->GetPlayer()->GetQuestMinLevel(&questTemplatePair.second), + handler->GetSession()->GetPlayer()->GetQuestLevel(questTemplatePair.second.get()), + handler->GetSession()->GetPlayer()->GetQuestMinLevel(questTemplatePair.second.get()), maxLevel, scalingFactionGroup, title.c_str(), statusStr); } |