diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-10-23 18:15:01 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-10-23 18:15:01 +0200 |
commit | 973b5f404f5b7115239a81030ad2f8dff8e165ea (patch) | |
tree | de6db7264bc6fa02652b384b4d89245295ab63d5 /src | |
parent | 1faa603d16cb51e581e43a560e54ec6e3ba8a9a4 (diff) |
Core/DataStores: Don't send hotfix ids in SMSG_AVAILABLE_HOTFIXES that don't have a hotfix blob for client locale
Closes #29378
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 31 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 12 | ||||
-rw-r--r-- | src/server/game/Handlers/HotfixHandler.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Server/Packets/HotfixPackets.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Server/Packets/HotfixPackets.h | 7 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 2 |
6 files changed, 60 insertions, 20 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index a15fcdcebf6..79e80accdb7 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -1633,7 +1633,7 @@ DB2StorageBase const* DB2Manager::GetStorage(uint32 type) const return nullptr; } -void DB2Manager::LoadHotfixData() +void DB2Manager::LoadHotfixData(uint32 localeMask) { uint32 oldMSTime = getMSTime(); @@ -1658,24 +1658,39 @@ void DB2Manager::LoadHotfixData() uint32 tableHash = fields[2].GetUInt32(); int32 recordId = fields[3].GetInt32(); HotfixRecord::Status status = static_cast<HotfixRecord::Status>(fields[4].GetUInt8()); - if (status == HotfixRecord::Status::Valid && _stores.find(tableHash) == _stores.end()) + std::bitset<TOTAL_LOCALES> availableDb2Locales = localeMask; + if (status == HotfixRecord::Status::Valid && !_stores.contains(tableHash)) { HotfixBlobKey key = std::make_pair(tableHash, recordId); - if (std::none_of(_hotfixBlob.begin(), _hotfixBlob.end(), [key](HotfixBlobMap const& blob) { return blob.find(key) != blob.end(); })) + for (std::size_t locale = 0; locale < TOTAL_LOCALES; ++locale) + { + if (!availableDb2Locales[locale]) + continue; + + if (!_hotfixBlob[locale].contains(key)) + availableDb2Locales[locale] = false; + } + + if (availableDb2Locales.none()) { TC_LOG_ERROR("sql.sql", "Table `hotfix_data` references unknown DB2 store by hash 0x{:X} and has no reference to `hotfix_blob` in hotfix id {} with RecordID: {}", tableHash, id, recordId); continue; } } - _maxHotfixId = std::max(_maxHotfixId, id); HotfixRecord hotfixRecord; hotfixRecord.TableHash = tableHash; hotfixRecord.RecordID = recordId; hotfixRecord.ID.PushID = id; hotfixRecord.ID.UniqueID = uniqueId; hotfixRecord.HotfixStatus = status; - _hotfixData[id].push_back(hotfixRecord); + hotfixRecord.AvailableLocalesMask = availableDb2Locales.to_ulong(); + + HotfixPush& push = _hotfixData[id]; + push.Records.push_back(hotfixRecord); + push.AvailableLocalesMask |= hotfixRecord.AvailableLocalesMask; + + _maxHotfixId = std::max(_maxHotfixId, id); deletedRecords[std::make_pair(tableHash, recordId)] = status == HotfixRecord::Status::RecordRemoved; ++count; } while (result->NextRow()); @@ -1853,7 +1868,11 @@ void DB2Manager::InsertNewHotfix(uint32 tableHash, uint32 recordId) hotfixRecord.RecordID = recordId; hotfixRecord.ID.PushID = ++_maxHotfixId; hotfixRecord.ID.UniqueID = rand32(); - _hotfixData[hotfixRecord.ID.PushID].push_back(hotfixRecord); + hotfixRecord.AvailableLocalesMask = 0xDFF; + + HotfixPush& push = _hotfixData[hotfixRecord.ID.PushID]; + push.Records.push_back(hotfixRecord); + push.AvailableLocalesMask |= hotfixRecord.AvailableLocalesMask; } std::vector<uint32> DB2Manager::GetAreasForGroup(uint32 areaGroupId) const diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index a6426e3483a..ad4f829aa61 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -370,6 +370,8 @@ public: HotfixId ID; Status HotfixStatus = Status::Invalid; + uint32 AvailableLocalesMask = 0; + friend std::strong_ordering operator<=>(HotfixRecord const& left, HotfixRecord const& right) { if (std::strong_ordering cmp = left.ID <=> right.ID; advstd::is_neq(cmp)) @@ -388,7 +390,13 @@ public: std::vector<uint8> Data; }; - using HotfixContainer = std::map<int32, std::vector<HotfixRecord>>; + struct HotfixPush + { + std::vector<HotfixRecord> Records; + uint32 AvailableLocalesMask = 0; + }; + + using HotfixContainer = std::map<int32, HotfixPush>; using FriendshipRepReactionSet = std::set<FriendshipRepReactionEntry const*, FriendshipRepReactionEntryComparator>; using MapDifficultyConditionsContainer = std::vector<std::pair<uint32, PlayerConditionEntry const*>>; @@ -400,7 +408,7 @@ public: uint32 LoadStores(std::string const& dataPath, LocaleConstant defaultLocale); DB2StorageBase const* GetStorage(uint32 type) const; - void LoadHotfixData(); + void LoadHotfixData(uint32 localeMask); void LoadHotfixBlob(uint32 localeMask); void LoadHotfixOptionalData(uint32 localeMask); uint32 GetHotfixCount() const; diff --git a/src/server/game/Handlers/HotfixHandler.cpp b/src/server/game/Handlers/HotfixHandler.cpp index 03170b014b7..54e70d3884e 100644 --- a/src/server/game/Handlers/HotfixHandler.cpp +++ b/src/server/game/Handlers/HotfixHandler.cpp @@ -60,7 +60,18 @@ void WorldSession::HandleDBQueryBulk(WorldPackets::Hotfix::DBQueryBulk& dbQuery) void WorldSession::SendAvailableHotfixes() { - SendPacket(WorldPackets::Hotfix::AvailableHotfixes(realm.Id.GetAddress(), sDB2Manager.GetHotfixData()).Write()); + WorldPackets::Hotfix::AvailableHotfixes availableHotfixes; + availableHotfixes.VirtualRealmAddress = realm.Id.GetAddress(); + + for (auto const& [pushId, push] : sDB2Manager.GetHotfixData()) + { + if (!(push.AvailableLocalesMask & (1 << GetSessionDbcLocale()))) + continue; + + availableHotfixes.Hotfixes.insert(push.Records.front().ID); + } + + SendPacket(availableHotfixes.Write()); } void WorldSession::HandleHotfixRequest(WorldPackets::Hotfix::HotfixRequest& hotfixQuery) @@ -70,13 +81,14 @@ void WorldSession::HandleHotfixRequest(WorldPackets::Hotfix::HotfixRequest& hotf hotfixQueryResponse.Hotfixes.reserve(hotfixQuery.Hotfixes.size()); for (int32 hotfixId : hotfixQuery.Hotfixes) { - if (std::vector<DB2Manager::HotfixRecord> const* hotfixRecords = Trinity::Containers::MapGetValuePtr(hotfixes, hotfixId)) + if (DB2Manager::HotfixPush const* hotfixRecords = Trinity::Containers::MapGetValuePtr(hotfixes, hotfixId)) { - for (DB2Manager::HotfixRecord const& hotfixRecord : *hotfixRecords) + for (DB2Manager::HotfixRecord const& hotfixRecord : hotfixRecords->Records) { - hotfixQueryResponse.Hotfixes.emplace_back(); + if (!(hotfixRecord.AvailableLocalesMask & (1 << GetSessionDbcLocale()))) + continue; - WorldPackets::Hotfix::HotfixConnect::HotfixData& hotfixData = hotfixQueryResponse.Hotfixes.back(); + WorldPackets::Hotfix::HotfixConnect::HotfixData& hotfixData = hotfixQueryResponse.Hotfixes.emplace_back(); hotfixData.Record = hotfixRecord; if (hotfixRecord.HotfixStatus == DB2Manager::HotfixRecord::Status::Valid) { diff --git a/src/server/game/Server/Packets/HotfixPackets.cpp b/src/server/game/Server/Packets/HotfixPackets.cpp index 9524a493a1c..3e22cb39e60 100644 --- a/src/server/game/Server/Packets/HotfixPackets.cpp +++ b/src/server/game/Server/Packets/HotfixPackets.cpp @@ -78,10 +78,12 @@ WorldPacket const* DBReply::Write() WorldPacket const* AvailableHotfixes::Write() { + _worldPacket.reserve(4 + 4 + sizeof(DB2Manager::HotfixId) * Hotfixes.size()); + _worldPacket << int32(VirtualRealmAddress); _worldPacket << uint32(Hotfixes.size()); - for (DB2Manager::HotfixContainer::value_type const& hotfixRecord : Hotfixes) - _worldPacket << hotfixRecord.second.front().ID; + for (DB2Manager::HotfixId const& hotfixId : Hotfixes) + _worldPacket << hotfixId; return &_worldPacket; } diff --git a/src/server/game/Server/Packets/HotfixPackets.h b/src/server/game/Server/Packets/HotfixPackets.h index 02d0cb9e453..7d85637bf26 100644 --- a/src/server/game/Server/Packets/HotfixPackets.h +++ b/src/server/game/Server/Packets/HotfixPackets.h @@ -60,13 +60,12 @@ namespace WorldPackets class AvailableHotfixes final : public ServerPacket { public: - AvailableHotfixes(int32 virtualRealmAddress, DB2Manager::HotfixContainer const& hotfixes) - : ServerPacket(SMSG_AVAILABLE_HOTFIXES), VirtualRealmAddress(virtualRealmAddress), Hotfixes(hotfixes) { } + AvailableHotfixes() : ServerPacket(SMSG_AVAILABLE_HOTFIXES, 0) { } WorldPacket const* Write() override; - int32 VirtualRealmAddress; - DB2Manager::HotfixContainer const& Hotfixes; + int32 VirtualRealmAddress = 0; + std::set<DB2Manager::HotfixId> Hotfixes; }; class HotfixRequest final : public ClientPacket diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e0c0b559a8a..c7d020f20ec 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1800,7 +1800,7 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("misc", "Loading hotfix blobs..."); sDB2Manager.LoadHotfixBlob(m_availableDbcLocaleMask); TC_LOG_INFO("misc", "Loading hotfix info..."); - sDB2Manager.LoadHotfixData(); + sDB2Manager.LoadHotfixData(m_availableDbcLocaleMask); TC_LOG_INFO("misc", "Loading hotfix optional data..."); sDB2Manager.LoadHotfixOptionalData(m_availableDbcLocaleMask); ///- Close hotfix database - it is only used during DB2 loading |