From 8e0069f36472a03dfe18aabf503dc18226ac01e9 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 8 Feb 2010 08:19:35 +0300 Subject: [PATCH] [9327] Replace leader based indexing groups by group ids. * This must repolve problem with loot. Before if some mob killed by group member and then leader changed then group members can't loot this mob body. * Possible resolve crashes at loot. Now group storage content not dependent from leader changes. --- src/game/Creature.cpp | 8 +++--- src/game/Creature.h | 2 +- src/game/Group.cpp | 26 +++++++------------- src/game/Group.h | 2 ++ src/game/GroupHandler.cpp | 8 +++--- src/game/ObjectMgr.cpp | 52 +++++++++++++++++++++++++++++---------- src/game/ObjectMgr.h | 8 +++--- src/shared/revision_nr.h | 2 +- 8 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 6b32e462f..e2ffdf422 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -113,7 +113,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) Creature::Creature(CreatureSubtype subtype) : Unit(), i_AI(NULL), -lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), +lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), m_groupLootId(0), m_lootMoney(0), m_lootRecipient(0), m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), @@ -395,7 +395,7 @@ void Creature::Update(uint32 diff) else { m_deathTimer -= diff; - if (m_groupLootTimer && lootingGroupLeaderGUID) + if (m_groupLootTimer && m_groupLootId) { if(diff <= m_groupLootTimer) { @@ -403,10 +403,10 @@ void Creature::Update(uint32 diff) } else { - if (Group* group = sObjectMgr.GetGroupByLeaderLowGUID(GUID_LOPART(lootingGroupLeaderGUID))) + if (Group* group = sObjectMgr.GetGroupById(m_groupLootId)) group->EndRoll(); m_groupLootTimer = 0; - lootingGroupLeaderGUID = 0; + m_groupLootId = 0; } } } diff --git a/src/game/Creature.h b/src/game/Creature.h index 0386783a4..fd3428fe3 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -583,7 +583,7 @@ class MANGOS_DLL_SPEC Creature : public Unit void SetRespawnRadius(float dist) { m_respawnradius = dist; } uint32 m_groupLootTimer; // (msecs)timer used for group loot - uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse + uint32 m_groupLootId; // used to find group which is looting corpse void SendZoneUnderAttackMessage(Player* attacker); diff --git a/src/game/Group.cpp b/src/game/Group.cpp index c93922a70..a45a78cf8 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -33,18 +33,11 @@ #include "MapInstanced.h" #include "Util.h" -Group::Group() +Group::Group() : m_Id(0), m_leaderGuid(0), m_mainTank(0), m_mainAssistant(0), m_groupType(GROUPTYPE_NORMAL), + m_dungeonDifficulty(REGULAR_DIFFICULTY), m_raidDifficulty(REGULAR_DIFFICULTY), + m_bgGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_looterGuid(0), m_lootThreshold(ITEM_QUALITY_UNCOMMON), + m_subGroupsCounts(NULL) { - m_leaderGuid = 0; - m_mainTank = 0; - m_mainAssistant = 0; - m_groupType = (GroupType)0; - m_bgGroup = NULL; - m_lootMethod = (LootMethod)0; - m_looterGuid = 0; - m_lootThreshold = ITEM_QUALITY_UNCOMMON; - m_subGroupsCounts = NULL; - for (int i = 0; i < TARGETICONCOUNT; ++i) m_targetIcons[i] = 0; } @@ -123,7 +116,10 @@ bool Group::Create(const uint64 &guid, const char * name) return false; if(!isBGGroup()) + { CharacterDatabase.CommitTransaction(); + m_Id = sObjectMgr.GenerateGroupId(); + } return true; } @@ -194,6 +190,7 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool return false; } + m_Id = sObjectMgr.GenerateGroupId(); return true; } @@ -616,7 +613,7 @@ void Group::GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature) loot->items[itemSlot].is_blocked = true; creature->m_groupLootTimer = 60000; - creature->lootingGroupLeaderGUID = GetLeaderGUID(); + creature->m_groupLootId = GetId(); RollId.push_back(r); } @@ -1256,11 +1253,6 @@ void Group::_setLeader(const uint64 &guid) m_leaderGuid = slot->guid; m_leaderName = slot->name; - - // Non-BG groups stored in sObjectMgr with leader low-guids as keys - if (IsCreated() && !isBGGroup()) - sObjectMgr.UpdateGroup(old_guidlow,this); - } void Group::_removeRolls(const uint64 &guid) diff --git a/src/game/Group.h b/src/game/Group.h index 5f3b3d7ba..9a0450db4 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -180,6 +180,7 @@ class MANGOS_DLL_SPEC Group void Disband(bool hideDestroy=false); // properties accessories + uint32 GetId() const { return m_Id; } bool IsFull() const { return (m_groupType==GROUPTYPE_NORMAL) ? (m_memberSlots.size()>=MAXGROUPSIZE) : (m_memberSlots.size()>=MAXRAIDSIZE); } bool isRaidGroup() const { return m_groupType==GROUPTYPE_RAID; } bool isBGGroup() const { return m_bgGroup != NULL; } @@ -402,6 +403,7 @@ class MANGOS_DLL_SPEC Group --m_subGroupsCounts[subgroup]; } + uint32 m_Id; // 0 for not created or BG groups MemberSlotList m_memberSlots; GroupRefManager m_memberMgr; InvitesList m_invitees; diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index e7c204b67..ac3e1712a 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -189,10 +189,12 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data ) // forming a new group, create it if(!group->IsCreated()) { - if( leader ) + if (leader) group->RemoveInvite(leader); - group->Create(group->GetLeaderGUID(), group->GetLeaderName()); - sObjectMgr.AddGroup(group); + if (group->Create(group->GetLeaderGUID(), group->GetLeaderName())) + sObjectMgr.AddGroup(group); + else + return; } // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 0673d4c07..8c4c0a757 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -142,6 +142,7 @@ ObjectMgr::ObjectMgr() m_guildId = 1; m_arenaTeamId = 1; m_auctionid = 1; + m_groupId = 1; // Only zero condition left, others will be added while loading DB tables mConditions.resize(1); @@ -180,16 +181,26 @@ ObjectMgr::~ObjectMgr() itr->second.Clear(); } -Group * ObjectMgr::GetGroupByLeaderLowGUID(uint32 guid) const +Group* ObjectMgr::GetGroupById(uint32 id) const { - GroupMap::const_iterator itr = mGroupMap.find(guid); + GroupMap::const_iterator itr = mGroupMap.find(id); if (itr != mGroupMap.end()) return itr->second; return NULL; } -Guild * ObjectMgr::GetGuildById(uint32 GuildId) const +Group* ObjectMgr::GetGroupByLeaderLowGUID(uint32 guid) const +{ + for(GroupMap::const_iterator itr = mGroupMap.begin(); itr != mGroupMap.end(); ++itr) + if (GUID_LOPART(itr->second->GetLeaderGUID())==guid) + return itr->second; + + return NULL; +} + + +Guild* ObjectMgr::GetGuildById(uint32 GuildId) const { GuildMap::const_iterator itr = mGuildMap.find(GuildId); if (itr != mGuildMap.end()) @@ -3124,6 +3135,8 @@ void ObjectMgr::LoadGroups() return; } + std::map leader2groupMap; + barGoLink bar( result->GetRowCount() ); do @@ -3140,6 +3153,7 @@ void ObjectMgr::LoadGroups() continue; } AddGroup(group); + leader2groupMap[GUID_LOPART(leaderGuid)] = group->GetId(); }while( result->NextRow() ); delete result; @@ -3173,7 +3187,11 @@ void ObjectMgr::LoadGroups() uint32 leaderGuidLow = fields[3].GetUInt32(); if(!group || GUID_LOPART(group->GetLeaderGUID()) != leaderGuidLow) { - group = GetGroupByLeaderLowGUID(leaderGuidLow); + // find group id in map by leader low guid + std::map::const_iterator l2g_itr = leader2groupMap.find(leaderGuidLow); + if (l2g_itr != leader2groupMap.end()) + group = GetGroupById(l2g_itr->second); + if(!group) { sLog.outErrorDb("Incorrect entry in group_member table : no group with leader %d for member %d!", leaderGuidLow, memberGuidlow); @@ -3237,7 +3255,11 @@ void ObjectMgr::LoadGroups() if(!group || GUID_LOPART(group->GetLeaderGUID()) != leaderGuidLow) { - group = GetGroupByLeaderLowGUID(leaderGuidLow); + // find group id in map by leader low guid + std::map::const_iterator l2g_itr = leader2groupMap.find(leaderGuidLow); + if (l2g_itr != leader2groupMap.end()) + group = GetGroupById(l2g_itr->second); + if(!group) { sLog.outErrorDb("Incorrect entry in group_instance table : no group with leader %d", leaderGuidLow); @@ -5706,6 +5728,16 @@ uint32 ObjectMgr::GenerateGuildId() return m_guildId++; } +uint32 ObjectMgr::GenerateGroupId() +{ + if(m_groupId>=0xFFFFFFFE) + { + sLog.outError("Group ids overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + return m_groupId++; +} + uint32 ObjectMgr::GenerateMailID() { if(m_mailid>=0xFFFFFFFE) @@ -8426,18 +8458,12 @@ void ObjectMgr::RemoveGuild( uint32 Id ) void ObjectMgr::AddGroup( Group* group ) { - mGroupMap[GUID_LOPART(group->GetLeaderGUID())] = group ; + mGroupMap[group->GetId()] = group ; } void ObjectMgr::RemoveGroup( Group* group ) { - mGroupMap.erase(GUID_LOPART(group->GetLeaderGUID())); -} - -void ObjectMgr::UpdateGroup( uint32 old_guidlow, Group* group ) -{ - mGroupMap.erase(old_guidlow); - AddGroup(group); + mGroupMap.erase(group->GetId()); } void ObjectMgr::AddArenaTeam( ArenaTeam* arenaTeam ) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index fb22e7cb4..5eeb17aeb 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -408,10 +408,10 @@ class ObjectMgr void LoadGameobjectInfo(); void AddGameobjectInfo(GameObjectInfo *goinfo); - Group * GetGroupByLeaderLowGUID(uint32 lowguid) const; + Group* GetGroupById(uint32 id) const; + Group* GetGroupByLeaderLowGUID(uint32 guid) const; // slow way by leader guid void AddGroup(Group* group); void RemoveGroup(Group* group); - void UpdateGroup(uint32 old_guidlow, Group* group); // when need update leader guid as group key Guild* GetGuildByLeader(uint64 const&guid) const; Guild* GetGuildById(uint32 GuildId) const; @@ -656,6 +656,7 @@ class ObjectMgr uint32 GenerateAuctionID(); uint64 GenerateEquipmentSetGuid(); uint32 GenerateGuildId(); + uint32 GenerateGroupId(); uint32 GenerateItemTextID(); uint32 GenerateMailID(); uint32 GeneratePetNumber(); @@ -894,8 +895,9 @@ class ObjectMgr uint32 m_ItemTextId; uint32 m_mailid; uint32 m_hiPetNumber; + uint32 m_groupId; - // first free low guid for seelcted guid type + // first free low guid for selected guid type uint32 m_hiCharGuid; uint32 m_hiCreatureGuid; uint32 m_hiItemGuid; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 537584388..b37b5ed65 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9326" + #define REVISION_NR "9327" #endif // __REVISION_NR_H__