diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Battlegrounds/Battleground.cpp | 1 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 119 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.h | 22 | ||||
-rwxr-xr-x | src/server/game/Groups/Group.cpp | 78 | ||||
-rwxr-xr-x | src/server/game/Groups/Group.h | 7 | ||||
-rwxr-xr-x | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 2 |
6 files changed, 119 insertions, 110 deletions
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 5791b504d6e..e0844cdcccd 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1203,7 +1203,6 @@ void Battleground::AddOrSetPlayerToCorrectBgGroup(Player *player, uint32 team) group = new Group; SetBgRaid(team, group); group->Create(player); - sObjectMgr->AddGroup(group); } else // raid already exist { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 815f1cbc770..691c647862a 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -274,6 +274,7 @@ ObjectMgr::ObjectMgr() m_guildId = 1; m_arenaTeamId = 1; m_auctionid = 1; + NextGroupStorageId = 1; } ObjectMgr::~ObjectMgr() @@ -293,7 +294,7 @@ ObjectMgr::~ObjectMgr() delete[] playerInfo[race][class_].levelInfo; // free group and guild objects - for (GroupMap::iterator itr = mGroupMap.begin(); itr != mGroupMap.end(); ++itr) + for (GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr) delete *itr; for (GuildMap::iterator itr = mGuildMap.begin(); itr != mGuildMap.end(); ++itr) @@ -311,12 +312,23 @@ ObjectMgr::~ObjectMgr() Group * ObjectMgr::GetGroupByGUID(uint32 guid) const { - // Make sure given index exists in collection - if (guid < uint32(mGroupMap.size())) - return mGroupMap[guid]; + for (GroupSet::const_iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr) + if ((*itr)->GetLowGUID() == guid) + return *itr; + + return NULL; +} + +Group* ObjectMgr::GetGroupByStorageId(uint32 storageId) const +{ + if (storageId < mGroupStorage.size()) + return mGroupStorage[storageId]; + return NULL; } + + // Guild collection Guild* ObjectMgr::GetGuildById(uint32 guildId) const { @@ -4000,19 +4012,19 @@ void ObjectMgr::LoadGroups() do { Field *fields = result->Fetch(); + Group *group = new Group; + group->LoadGroupFromDB(fields); + AddGroup(group); - uint32 guid = fields[15].GetUInt32(); + // + uint32 storageId = group->GetStorageId(); - // Groups are pulled in ascending order from db and m_hiGroupGuid is initialized with 1, - // so if the group slot is used increment until we find the first free one for a potential new group - if (sObjectMgr->GetNextGroupGuid() == guid) - sObjectMgr->SetNextGroupGuid(guid + 1); + RegisterGroupStorageId(storageId, group); + + if (storageId == NextGroupStorageId) + NextGroupStorageId++; ++count; - Group *group = new Group; - group->LoadGroupFromDB(guid, result, false); - // group load will never be false (we have run consistency sql's before loading) - AddGroup(group); } while (result->NextRow()); @@ -4030,7 +4042,7 @@ void ObjectMgr::LoadGroups() // Delete all members that does not exist CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_CHARACTER_GROUP_MEMBERS)); - // 0 1 2 3 4 + // 0 1 2 3 4 QueryResult result = CharacterDatabase.Query("SELECT guid, memberGuid, memberFlags, subgroup, roles FROM group_member ORDER BY guid"); if (!result) { @@ -4039,21 +4051,18 @@ void ObjectMgr::LoadGroups() return; } - uint32 groupLowGuid = 0; uint32 count = 0; - Group* group = NULL; + do { Field* fields = result->Fetch(); - if (groupLowGuid != fields[0].GetUInt32()) - { - groupLowGuid = fields[0].GetUInt32(); - group = GetGroupByGUID(groupLowGuid); - } - if (group) // Should never be null + Group* group = GetGroupByStorageId(fields[0].GetUInt32()); + + if (group) group->LoadMemberFromDB(fields[1].GetUInt32(), fields[2].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt8()); else - sLog->outError("ObjectMgr::LoadGroups: Consistency failed, can't find group (lowguid %u)", groupLowGuid); + sLog->outError("ObjectMgr::LoadGroups: Consistency failed, can't find group (storage id: %u)", fields[0].GetUInt32()); + ++count; } while (result->NextRow()); @@ -4062,7 +4071,6 @@ void ObjectMgr::LoadGroups() sLog->outString(); } - sLog->outString("Loading Group instance saves..."); { uint32 oldMSTime = getMSTime(); @@ -4084,7 +4092,7 @@ void ObjectMgr::LoadGroups() do { Field *fields = result->Fetch(); - Group *group = GetGroupByGUID(fields[0].GetUInt32()); + Group *group = GetGroupByStorageId(fields[0].GetUInt32()); // group will never be NULL (we have run consistency sql's before loading) MapEntry const* mapEntry = sMapStore.LookupEntry(fields[1].GetUInt32()); @@ -6658,10 +6666,9 @@ void ObjectMgr::SetHighestGuids() if (result) m_guildId = (*result)[0].GetUInt32()+1; - // The next free guid is determined during group loading, here we just preallocate the group holder result = CharacterDatabase.Query("SELECT MAX(guid) FROM groups"); if (result) - mGroupMap.resize((*result)[0].GetUInt32()+1); + mGroupStorage.resize((*result)[0].GetUInt32()+1); } uint32 ObjectMgr::GenerateArenaTeamId() @@ -6775,26 +6782,12 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) } return m_hiDoGuid++; case HIGHGUID_GROUP: - { - uint32 newGuid = m_hiGroupGuid; - - for (uint32 i = ++m_hiGroupGuid; i < 0xFFFFFFFF; ++i) - { - if (!GetGroupByGUID(i)) - { - m_hiGroupGuid = i; - break; - } - } - - // If newGuid doesn't differ from m_hiGroupGuid after the loop there is no free guid available - if (newGuid == m_hiGroupGuid) + if (m_hiGroupGuid >= 0xFFFFFFFE) { sLog->outError("Group guid overflow!! Can't continue, shutting down server. "); World::StopNow(ERROR_EXIT_CODE); } - return newGuid; - } + return m_hiGroupGuid++; case HIGHGUID_MO_TRANSPORT: if (m_hiMoTransGuid >= 0xFFFFFFFE) { @@ -9449,17 +9442,43 @@ void ObjectMgr::LoadFactionChangeReputations() sLog->outString(); } -void ObjectMgr::AddGroup(Group* group) +uint32 ObjectMgr::GenerateNewGroupStorageId() +{ + uint32 newStorageId = NextGroupStorageId; + + for (uint32 i = ++NextGroupStorageId; i < 0xFFFFFFFF; ++i) + { + if ((i < mGroupStorage.size() && mGroupStorage[i] == NULL) || i >= mGroupStorage.size()) + { + NextGroupStorageId = i; + break; + } + } + + if (newStorageId == NextGroupStorageId) + { + sLog->outError("Group storage ID overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + + return newStorageId; +} + +void ObjectMgr::RegisterGroupStorageId(uint32 storageId, Group* group) { - uint32 groupGuid = group->GetLowGUID(); // Allocate space if necessary. - if (groupGuid >= uint32(mGroupMap.size())) - mGroupMap.resize(groupGuid + 1); + if (storageId >= uint32(mGroupStorage.size())) + mGroupStorage.resize(storageId + 1); - mGroupMap[groupGuid] = group; + mGroupStorage[storageId] = group; } -void ObjectMgr::RemoveGroup(Group* group) +void ObjectMgr::FreeGroupStorageId(Group* group) { - mGroupMap[group->GetLowGUID()] = NULL; + uint32 storageId = group->GetStorageId(); + + if (storageId < NextGroupStorageId) + NextGroupStorageId = storageId; + + mGroupStorage[storageId] = NULL; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 2a588c40f61..a593d369799 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -591,7 +591,8 @@ class ObjectMgr public: typedef UNORDERED_MAP<uint32, Item*> ItemMap; - typedef std::vector<Group *> GroupMap; + typedef std::set<Group *> GroupSet; + typedef std::vector<Group *> GroupStorage; typedef std::vector <Guild *> GuildMap; @@ -626,10 +627,14 @@ class ObjectMgr void AddGameobjectInfo(GameObjectInfo *goinfo); Group * GetGroupByGUID(uint32 guid) const; - void AddGroup(Group* group); - void RemoveGroup(Group* group); - uint32 GetNextGroupGuid() { return m_hiGroupGuid; }; - void SetNextGroupGuid(uint32 nextGuid) { m_hiGroupGuid = nextGuid; }; + void AddGroup(Group* group) { mGroupSet.insert(group); } + void RemoveGroup(Group* group) { mGroupSet.erase(group); } + + uint32 GenerateNewGroupStorageId(); + void RegisterGroupStorageId(uint32 storageId, Group* group); + void FreeGroupStorageId(Group* group); + void SetNextGroupStorageId(uint32 storageId) { NextGroupStorageId = storageId; }; + Group* GetGroupByStorageId(uint32 storageId) const; Guild* GetGuildByLeader(uint64 const&guid) const; Guild* GetGuildById(uint32 guildId) const; @@ -1264,6 +1269,10 @@ class ObjectMgr uint32 m_hiGroupGuid; uint32 m_hiMoTransGuid; + // Database storage IDs + + uint32 NextGroupStorageId; + QuestMap mQuestTemplates; typedef UNORDERED_MAP<uint32, GossipText> GossipTextMap; @@ -1271,7 +1280,8 @@ class ObjectMgr typedef std::set<uint32> TavernAreaTriggerSet; typedef std::set<uint32> GameObjectForQuestSet; - GroupMap mGroupMap; + GroupSet mGroupSet; + GroupStorage mGroupStorage; GuildMap mGuildMap; ArenaTeamMap mArenaTeamMap; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index a118e1c1837..992be9b0308 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -57,7 +57,7 @@ Loot* Roll::getLoot() Group::Group() : m_leaderGuid(0), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL), m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL), m_bgGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(0), -m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0) +m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0), m_storageId(0) { for (uint8 i = 0; i < TARGETICONCOUNT; ++i) m_targetIcons[i] = 0; @@ -96,6 +96,7 @@ bool Group::Create(Player *leader) { uint64 leaderGuid = leader->GetGUID(); uint32 lowguid = sObjectMgr->GenerateLowGuid(HIGHGUID_GROUP); + m_guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_GROUP); m_leaderGuid = leaderGuid; m_leaderName = leader->GetName(); @@ -117,17 +118,20 @@ bool Group::Create(Player *leader) m_dungeonDifficulty = leader->GetDungeonDifficulty(); m_raidDifficulty = leader->GetRaidDifficulty(); + m_storageId = sObjectMgr->GenerateNewGroupStorageId(); + + sObjectMgr->RegisterGroupStorageId(m_storageId, this); + // store group in database CharacterDatabase.PExecute("INSERT INTO groups (guid,leaderGuid,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty) " "VALUES ('%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')", - lowguid, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod), + m_storageId, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod), GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], uint8(m_groupType), uint32(m_dungeonDifficulty), m_raidDifficulty); ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong. Player::ConvertInstancesToGroup(leader, this, false); - } else if (!AddMember(leader)) return false; @@ -135,18 +139,15 @@ bool Group::Create(Player *leader) return true; } -bool Group::LoadGroupFromDB(const uint32 &groupGuid, QueryResult result, bool loadMembers) +void Group::LoadGroupFromDB(Field *fields) { - if (isBGGroup()) - return false; - - Field *fields = result->Fetch(); - m_guid = MAKE_NEW_GUID(groupGuid, 0, HIGHGUID_GROUP); + m_storageId = fields[15].GetUInt32(); + m_guid = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_GROUP), 0, HIGHGUID_GROUP); m_leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); // group leader not exist if (!sObjectMgr->GetPlayerNameByGUID(fields[0].GetUInt32(), m_leaderName)) - return false; + return; m_lootMethod = LootMethod(fields[1].GetUInt8()); m_looterGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); @@ -171,27 +172,9 @@ bool Group::LoadGroupFromDB(const uint32 &groupGuid, QueryResult result, bool lo else m_raidDifficulty = Difficulty(r_diff); - if (loadMembers) - { - // 0 1 2 3 - result = CharacterDatabase.PQuery("SELECT memberGuid, memberFlags, subgroup, roles FROM group_member WHERE guid=%u", groupGuid); - if (!result) - return false; - - do - { - fields = result->Fetch(); - LoadMemberFromDB(fields[0].GetUInt32(), fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt8()); - } while (result->NextRow()); - - if (GetMembersCount() < 2) // group too small - return false; - } - - return true; } -bool Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles) +void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles) { MemberSlot member; member.guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER); @@ -200,7 +183,7 @@ bool Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, if (!sObjectMgr->GetPlayerNameByGUID(member.guid, member.name)) { CharacterDatabase.PQuery("DELETE FROM group_member WHERE memberGuid=%u", guidLow); - return false; + return; } member.group = subgroup; @@ -210,8 +193,6 @@ bool Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, m_memberSlots.push_back(member); SubGroupCounterIncrease(subgroup); - - return true; } void Group::ConvertToLFG() @@ -219,7 +200,7 @@ void Group::ConvertToLFG() m_groupType = GroupType(m_groupType | GROUPTYPE_LFG | GROUPTYPE_UNK1); m_lootMethod = NEED_BEFORE_GREED; if (!isBGGroup()) - CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), GUID_LOPART(m_guid)); + CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_storageId); SendUpdate(); } @@ -230,7 +211,7 @@ void Group::ConvertToRaid() _initRaidSubGroupsCounter(); if (!isBGGroup()) - CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), GUID_LOPART(m_guid)); + CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_storageId); SendUpdate(); // update quest related GO states (quest activity dependent from raid membership) @@ -363,7 +344,7 @@ bool Group::AddMember(Player *player) // insert into the table if we're not a battleground group if (!isBGGroup()) CharacterDatabase.PExecute("INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(%u, %u, %u, %u, %u)", - GUID_LOPART(m_guid), GUID_LOPART(member.guid), member.flags, member.group, member.roles); + m_storageId, GUID_LOPART(member.guid), member.flags, member.group, member.roles); SendUpdate(); sScriptMgr->OnGroupAddMember(this, player->GetGUID()); @@ -550,13 +531,13 @@ void Group::ChangeLeader(const uint64 &guid) // Same in the database CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = '%u'))", - GUID_LOPART(m_guid), player->GetGUIDLow()); + m_storageId, player->GetGUIDLow()); // Copy the permanent binds from the new leader to the group Player::ConvertInstancesToGroup(player, this, true); // update the group leader - CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", player->GetGUIDLow(), GUID_LOPART(m_guid)); + CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", player->GetGUIDLow(), m_storageId); } m_leaderGuid = player->GetGUID(); @@ -628,19 +609,14 @@ void Group::Disband(bool hideDestroy /* = false */) if (!isBGGroup()) { - uint32 lowguid = GUID_LOPART(m_guid); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - trans->PAppend("DELETE FROM groups WHERE guid=%u", lowguid); - trans->PAppend("DELETE FROM group_member WHERE guid=%u", lowguid); + trans->PAppend("DELETE FROM groups WHERE guid = %u", m_storageId); + trans->PAppend("DELETE FROM group_member WHERE guid = %u", m_storageId); CharacterDatabase.CommitTransaction(trans); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); - // If the deleted group guid is lower than the one we have stored for the next group creation, - // use this one instead. - if (lowguid < sObjectMgr->GetNextGroupGuid()) - sObjectMgr->SetNextGroupGuid(lowguid); - + sObjectMgr->FreeGroupStorageId(this); } sObjectMgr->RemoveGroup(this); @@ -1584,7 +1560,7 @@ void Group::SetDungeonDifficulty(Difficulty difficulty) { m_dungeonDifficulty = difficulty; if (!isBGGroup()) - CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE guid ='%u'", m_dungeonDifficulty, GUID_LOPART(m_guid)); + CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE guid ='%u'", m_dungeonDifficulty, m_storageId); for (GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -1601,7 +1577,7 @@ void Group::SetRaidDifficulty(Difficulty difficulty) { m_raidDifficulty = difficulty; if (!isBGGroup()) - CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE guid ='%u'", m_raidDifficulty, GUID_LOPART(m_guid)); + CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE guid ='%u'", m_raidDifficulty, m_storageId); for (GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -1743,7 +1719,7 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, boo InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()]; if (!load && (!bind.save || permanent != bind.perm || save != bind.save)) - CharacterDatabase.PExecute("REPLACE INTO group_instance (guid, instance, permanent) VALUES (%u, %u, %u)", GUID_LOPART(GetGUID()), save->GetInstanceId(), permanent); + CharacterDatabase.PExecute("REPLACE INTO group_instance (guid, instance, permanent) VALUES (%u, %u, %u)", m_storageId, save->GetInstanceId(), permanent); if (bind.save != save) { @@ -1755,7 +1731,9 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, boo bind.save = save; bind.perm = permanent; if (!load) - sLog->outDebug(LOG_FILTER_MAPS, "Group::BindToInstance: %d is now bound to map %d, instance %d, difficulty %d", GUID_LOPART(GetGUID()), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty()); + sLog->outDebug(LOG_FILTER_MAPS, "Group::BindToInstance: Group (guid: %u, storage id: %u) is now bound to map %d, instance %d, difficulty %d", + GUID_LOPART(GetGUID()), m_storageId, save->GetMapId(), save->GetInstanceId(), save->GetDifficulty()); + return &bind; } @@ -1765,7 +1743,7 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload) if (itr != m_boundInstances[difficulty].end()) { if (!unload) - CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND instance=%u", GUID_LOPART(GetGUID()), itr->second.save->GetInstanceId()); + CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND instance=%u", m_storageId, itr->second.save->GetInstanceId()); itr->second.save->RemoveGroup(this); // save can become invalid m_boundInstances[difficulty].erase(itr); } diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 3928b6ee54a..8858767d19c 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -183,8 +183,8 @@ class Group // group manipulation methods bool Create(Player *leader); - bool LoadGroupFromDB(const uint32 &guid, QueryResult result, bool loadMembers = true); - bool LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles); + void LoadGroupFromDB(Field *field); + void LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles); bool AddInvite(Player *player); void RemoveInvite(Player *player); void RemoveAllInvites(); @@ -213,6 +213,8 @@ class Group const uint64& GetLooterGuid() const; ItemQualities GetLootThreshold() const; + uint32 GetStorageId() { return m_storageId; }; + // member manipulation methods bool IsMember(const uint64& guid) const; bool IsLeader(const uint64& guid) const; @@ -328,5 +330,6 @@ class Group uint64 m_guid; uint32 m_counter; // used only in SMSG_GROUP_LIST uint32 m_maxEnchantingLevel; + uint32 m_storageId; // Represents the ID used in database (Can be reused by other groups if group was disbanded) }; #endif diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index b46f3a79e3a..1d001962526 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -31,7 +31,7 @@ bool CharacterDatabaseConnection::Open() PREPARE_STATEMENT(CHAR_DEL_OLD_GUILD_EVENT_LOGS, "DELETE FROM guild_eventlog WHERE LogGuid > ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_OLD_GUILD_BANK_EVENT_LOGS, "DELETE FROM guild_bank_eventlog WHERE LogGuid > ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_CHARACTER_GROUP_MEMBERS, "DELETE FROM group_member WHERE NOT EXISTS (SELECT guid FROM characters WHERE guid=memberGuid)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_CHARACTER_GROUP_MEMBERS, "DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_LEADERLESS_GROUPS, "DELETE FROM groups WHERE NOT EXISTS (SELECT guid FROM characters WHERE guid=leaderGuid)", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_DEL_TINY_GROUPS, "DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_GROUP_MEMBERS, "DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM groups)", CONNECTION_ASYNC) |