diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 43 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 18 | ||||
| -rw-r--r-- | src/server/game/Handlers/HotfixHandler.cpp | 93 | ||||
| -rw-r--r-- | src/server/game/Handlers/QueryHandler.cpp | 31 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/AllPackets.h | 1 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/HotfixPackets.cpp | 101 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/HotfixPackets.h | 108 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/QueryPackets.cpp | 26 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/QueryPackets.h | 31 | ||||
| -rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.cpp | 1 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.h | 13 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSocket.h | 2 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 16 | ||||
| -rw-r--r-- | src/server/game/World/World.h | 1 | ||||
| -rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 4 | ||||
| -rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 8 |
17 files changed, 373 insertions, 130 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index d37ec2ee846..66ee56c21ca 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -963,50 +963,45 @@ void DB2Manager::LoadHotfixData() { uint32 oldMSTime = getMSTime(); - QueryResult result = HotfixDatabase.Query("SELECT TableHash, RecordID, `Timestamp`, Deleted FROM hotfix_data"); + QueryResult result = HotfixDatabase.Query("SELECT Id, TableHash, RecordId, Deleted FROM hotfix_data ORDER BY Id"); if (!result) { - TC_LOG_INFO("misc", ">> Loaded 0 hotfix info entries."); + TC_LOG_INFO("server.loading", ">> Loaded 0 hotfix info entries."); return; } uint32 count = 0; - _hotfixData.reserve(result->GetRowCount()); + std::map<std::pair<uint32, int32>, bool> deletedRecords; do { Field* fields = result->Fetch(); - HotfixNotify info; - info.TableHash = fields[0].GetUInt32(); - info.Entry = fields[1].GetUInt32(); - info.Timestamp = fields[2].GetUInt32(); - _hotfixData.push_back(info); - - if (fields[3].GetBool()) + int32 id = fields[0].GetInt32(); + uint32 tableHash = fields[1].GetUInt32(); + int32 recordId = fields[2].GetInt32(); + bool deleted = fields[3].GetBool(); + if (_stores.find(tableHash) == _stores.end()) { - auto itr = _stores.find(info.TableHash); - if (itr != _stores.end()) - itr->second->EraseRecord(info.Entry); + TC_LOG_ERROR("sql.sql", "Table `hotfix_data` references unknown DB2 store by hash 0x%X in hotfix id %d", tableHash, id); + continue; } + HotfixData& data = _hotfixData[id]; + data.Id = id; + data.Records.emplace_back(tableHash, recordId); + deletedRecords[std::make_pair(tableHash, recordId)] = deleted; ++count; } while (result->NextRow()); - TC_LOG_INFO("misc", ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - -time_t DB2Manager::GetHotfixDate(uint32 entry, uint32 type) const -{ - time_t ret = 0; - for (HotfixNotify const& hotfix : _hotfixData) - if (hotfix.Entry == entry && hotfix.TableHash == type) - if (time_t(hotfix.Timestamp) > ret) - ret = time_t(hotfix.Timestamp); + for (auto itr = deletedRecords.begin(); itr != deletedRecords.end(); ++itr) + if (itr->second) + if (DB2StorageBase* store = Trinity::Containers::MapGetValuePtr(_stores, itr->first.first)) + store->EraseRecord(itr->first.second); - return ret ? ret : time(nullptr); + TC_LOG_INFO("server.loading", ">> Loaded %u hotfix records in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } 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 2c284ddcc04..d161ac438cb 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -209,14 +209,19 @@ TC_GAME_API extern TaxiMask sAllianceTax TC_GAME_API extern TaxiPathSetBySource sTaxiPathSetBySource; TC_GAME_API extern TaxiPathNodesByPath sTaxiPathNodesByPath; -struct HotfixNotify +struct HotfixRecord { + HotfixRecord(uint32 tableHash, int32 recordId) : TableHash(tableHash), RecordId(recordId) { } + uint32 TableHash; - uint32 Timestamp; - uint32 Entry; + int32 RecordId; }; -typedef std::vector<HotfixNotify> HotfixData; +struct HotfixData +{ + int32 Id; + std::vector<HotfixRecord> Records; +}; #define DEFINE_DB2_SET_COMPARATOR(structure) \ struct structure ## Comparator \ @@ -285,8 +290,7 @@ public: DB2StorageBase const* GetStorage(uint32 type) const; void LoadHotfixData(); - HotfixData const* GetHotfixData() const { return &_hotfixData; } - time_t GetHotfixDate(uint32 entry, uint32 type) const; + std::map<int32, HotfixData> const& GetHotfixData() const { return _hotfixData; } std::vector<uint32> GetAreasForGroup(uint32 areaGroupId) const; std::vector<ArtifactPowerEntry const*> GetArtifactPowers(uint8 artifactId) const; @@ -354,7 +358,7 @@ public: private: StorageMap _stores; - HotfixData _hotfixData; + std::map<int32, HotfixData> _hotfixData; AreaGroupMemberContainer _areaGroupMembers; ArtifactPowersContainer _artifactPowers; diff --git a/src/server/game/Handlers/HotfixHandler.cpp b/src/server/game/Handlers/HotfixHandler.cpp new file mode 100644 index 00000000000..656afb6858f --- /dev/null +++ b/src/server/game/Handlers/HotfixHandler.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "WorldSession.h" +#include "Containers.h" +#include "DB2Stores.h" +#include "HotfixPackets.h" +#include "Log.h" + +void WorldSession::HandleDBQueryBulk(WorldPackets::Hotfix::DBQueryBulk& dbQuery) +{ + DB2StorageBase const* store = sDB2Manager.GetStorage(dbQuery.TableHash); + if (!store) + { + TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: %s requested unsupported unknown hotfix type: %u", GetPlayerInfo().c_str(), dbQuery.TableHash); + return; + } + + for (WorldPackets::Hotfix::DBQueryBulk::DBQueryRecord const& record : dbQuery.Queries) + { + WorldPackets::Hotfix::DBReply dbReply; + dbReply.TableHash = dbQuery.TableHash; + dbReply.RecordID = record.RecordID; + + if (store->HasRecord(record.RecordID)) + { + dbReply.Allow = true; + dbReply.Timestamp = sWorld->GetGameTime(); + store->WriteRecord(record.RecordID, GetSessionDbcLocale(), dbReply.Data); + } + else + { + TC_LOG_TRACE("network", "CMSG_DB_QUERY_BULK: %s requested non-existing entry %u in datastore: %u", GetPlayerInfo().c_str(), record.RecordID, dbQuery.TableHash); + dbReply.Timestamp = time(NULL); + } + + SendPacket(dbReply.Write()); + } +} + +void WorldSession::SendHotfixList(int32 version) +{ + SendPacket(WorldPackets::Hotfix::HotfixList(version, sDB2Manager.GetHotfixData()).Write()); +} + +void WorldSession::HandleHotfixQuery(WorldPackets::Hotfix::HotfixQuery& hotfixQuery) +{ + std::map<int32, HotfixData> const& hotfixes = sDB2Manager.GetHotfixData(); + WorldPackets::Hotfix::HotfixQueryResponse hotfixQueryResponse; + hotfixQueryResponse.Hotfixes.reserve(hotfixQuery.Hotfixes.size()); + for (int32 hotfixId : hotfixQuery.Hotfixes) + { + if (HotfixData const* hotfix = Trinity::Containers::MapGetValuePtr(hotfixes, hotfixId)) + { + WorldPackets::Hotfix::HotfixQueryResponse::HotfixData hotfixData; + hotfixData.ID = hotfix->Id; + + for (HotfixRecord const& hotfixRecord : hotfix->Records) + { + DB2StorageBase const* storage = sDB2Manager.GetStorage(hotfixRecord.TableHash); + + WorldPackets::Hotfix::HotfixQueryResponse::HotfixRecord record; + record.TableHash = hotfixRecord.TableHash; + record.RecordID = hotfixRecord.RecordId; + if (storage->HasRecord(hotfixRecord.RecordId)) + { + record.HotfixData = boost::in_place(); + storage->WriteRecord(hotfixRecord.RecordId, GetSessionDbcLocale(), *record.HotfixData); + } + + hotfixData.Records.emplace_back(std::move(record)); + } + + hotfixQueryResponse.Hotfixes.emplace_back(std::move(hotfixData)); + } + } + + SendPacket(hotfixQueryResponse.Write()); +} diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index a934f05cd67..6006f66772c 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -393,37 +393,6 @@ void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& quest SendPacket(response.Write()); } -void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) -{ - DB2StorageBase const* store = sDB2Manager.GetStorage(packet.TableHash); - if (!store) - { - TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: %s requested unsupported unknown hotfix type: %u", GetPlayerInfo().c_str(), packet.TableHash); - return; - } - - for (WorldPackets::Query::DBQueryBulk::DBQueryRecord const& rec : packet.Queries) - { - WorldPackets::Query::DBReply response; - response.TableHash = packet.TableHash; - response.RecordID = rec.RecordID; - - if (store->HasRecord(rec.RecordID)) - { - response.Allow = true; - response.Timestamp = sDB2Manager.GetHotfixDate(rec.RecordID, packet.TableHash); - store->WriteRecord(rec.RecordID, GetSessionDbcLocale(), response.Data); - } - else - { - TC_LOG_TRACE("network", "CMSG_DB_QUERY_BULK: %s requested non-existing entry %u in datastore: %u", GetPlayerInfo().c_str(), rec.RecordID, packet.TableHash); - response.Timestamp = time(NULL); - } - - SendPacket(response.Write()); - } -} - /** * Handles the packet sent by the client when requesting information about item text. * diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index e1fe1860388..98370db4073 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -44,6 +44,7 @@ #include "GarrisonPackets.h" #include "GuildFinderPackets.h" #include "GuildPackets.h" +#include "HotfixPackets.h" #include "InspectPackets.h" #include "InstancePackets.h" #include "ItemPackets.h" diff --git a/src/server/game/Server/Packets/HotfixPackets.cpp b/src/server/game/Server/Packets/HotfixPackets.cpp new file mode 100644 index 00000000000..fa1fabf3bf4 --- /dev/null +++ b/src/server/game/Server/Packets/HotfixPackets.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "HotfixPackets.h" +#include "PacketUtilities.h" + +void WorldPackets::Hotfix::DBQueryBulk::Read() +{ + _worldPacket >> TableHash; + + uint32 count = _worldPacket.ReadBits(13); + + Queries.resize(count); + for (uint32 i = 0; i < count; ++i) + { + _worldPacket >> Queries[i].GUID; + _worldPacket >> Queries[i].RecordID; + } +} + +WorldPacket const* WorldPackets::Hotfix::DBReply::Write() +{ + _worldPacket << uint32(TableHash); + _worldPacket << uint32(RecordID); + _worldPacket << uint32(Timestamp); + _worldPacket.WriteBit(Allow); + _worldPacket << uint32(Data.size()); + _worldPacket.append(Data); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Hotfix::HotfixList::Write() +{ + _worldPacket << int32(HotfixCacheVersion); + _worldPacket << uint32(Hotfixes.size()); + for (auto const& hotfixEntry : Hotfixes) + _worldPacket << int32(hotfixEntry.first); + + return &_worldPacket; +} + +void WorldPackets::Hotfix::HotfixQuery::Read() +{ + uint32 hotfixCount = _worldPacket.read<uint32>(); + if (hotfixCount > sDB2Manager.GetHotfixData().size()) + throw PacketArrayMaxCapacityException(hotfixCount, sDB2Manager.GetHotfixData().size()); + + Hotfixes.resize(hotfixCount); + for (int32& hotfixId : Hotfixes) + _worldPacket >> hotfixId; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Hotfix::HotfixQueryResponse::HotfixRecord const& hotfixRecord) +{ + data << uint32(hotfixRecord.TableHash); + data << int32(hotfixRecord.RecordID); + data.WriteBit(hotfixRecord.HotfixData.is_initialized()); + if (hotfixRecord.HotfixData) + { + data << uint32(hotfixRecord.HotfixData->size()); + data.append(*hotfixRecord.HotfixData); + } + else + data << uint32(0); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Hotfix::HotfixQueryResponse::HotfixData const& hotfixData) +{ + data << int32(hotfixData.ID); + data << uint32(hotfixData.Records.size()); + for (WorldPackets::Hotfix::HotfixQueryResponse::HotfixRecord const& hotfixRecord : hotfixData.Records) + data << hotfixRecord; + + return data; +} + +WorldPacket const* WorldPackets::Hotfix::HotfixQueryResponse::Write() +{ + _worldPacket << uint32(Hotfixes.size()); + for (HotfixData const& hotfix : Hotfixes) + _worldPacket << hotfix; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/HotfixPackets.h b/src/server/game/Server/Packets/HotfixPackets.h new file mode 100644 index 00000000000..eb87ddba1e6 --- /dev/null +++ b/src/server/game/Server/Packets/HotfixPackets.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HotfixPackets_h__ +#define HotfixPackets_h__ + +#include "Packet.h" +#include "Common.h" +#include "DB2Stores.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace Hotfix + { + class DBQueryBulk final : public ClientPacket + { + public: + struct DBQueryRecord + { + ObjectGuid GUID; + uint32 RecordID = 0; + }; + + DBQueryBulk(WorldPacket&& packet) : ClientPacket(CMSG_DB_QUERY_BULK, std::move(packet)) { } + + void Read() override; + + uint32 TableHash = 0; + std::vector<DBQueryRecord> Queries; + }; + + class DBReply final : public ServerPacket + { + public: + DBReply() : ServerPacket(SMSG_DB_REPLY, 12) { } + + WorldPacket const* Write() override; + + uint32 TableHash = 0; + uint32 Timestamp = 0; + uint32 RecordID = 0; + bool Allow = false; + ByteBuffer Data; + }; + + class HotfixList final : public ServerPacket + { + public: + HotfixList(int32 hotfixCacheVersion, std::map<int32, HotfixData> const& hotfixes) + : ServerPacket(SMSG_HOTFIX_LIST), HotfixCacheVersion(hotfixCacheVersion), Hotfixes(hotfixes) { } + + WorldPacket const* Write() override; + + int32 HotfixCacheVersion; + std::map<int32, HotfixData> const& Hotfixes; + }; + + class HotfixQuery final : public ClientPacket + { + public: + HotfixQuery(WorldPacket&& packet) : ClientPacket(CMSG_HOTFIX_QUERY, std::move(packet)) { } + + void Read() override; + + std::vector<int32> Hotfixes; + }; + + class HotfixQueryResponse final : public ServerPacket + { + public: + struct HotfixRecord + { + uint32 TableHash = 0; + int32 RecordID = 0; + Optional<ByteBuffer> HotfixData; + }; + + struct HotfixData + { + int32 ID = 0; + std::vector<HotfixRecord> Records; + }; + + HotfixQueryResponse() : ServerPacket(SMSG_HOTFIX_QUERY_RESPONSE) { } + + WorldPacket const* Write() override; + + std::vector<HotfixData> Hotfixes; + }; + } +} + +#endif // HotfixPackets_h__ diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index f2627203cce..84cdb5e1e47 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -254,32 +254,6 @@ WorldPacket const* WorldPackets::Query::QueryNPCTextResponse::Write() return &_worldPacket; } -void WorldPackets::Query::DBQueryBulk::Read() -{ - _worldPacket >> TableHash; - - uint32 count = _worldPacket.ReadBits(13); - - Queries.resize(count); - for (uint32 i = 0; i < count; ++i) - { - _worldPacket >> Queries[i].GUID; - _worldPacket >> Queries[i].RecordID; - } -} - -WorldPacket const* WorldPackets::Query::DBReply::Write() -{ - _worldPacket << uint32(TableHash); - _worldPacket << uint32(RecordID); - _worldPacket << uint32(Timestamp); - _worldPacket.WriteBit(Allow); - _worldPacket << uint32(Data.size()); - _worldPacket.append(Data); - - return &_worldPacket; -} - void WorldPackets::Query::QueryGameObject::Read() { _worldPacket >> GameObjectID; diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index 0d669e6ff31..a5f95a9dc49 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -176,37 +176,6 @@ namespace WorldPackets uint32 BroadcastTextID[MAX_NPC_TEXT_OPTIONS]; }; - class DBQueryBulk final : public ClientPacket - { - public: - struct DBQueryRecord - { - ObjectGuid GUID; - uint32 RecordID = 0; - }; - - DBQueryBulk(WorldPacket&& packet) : ClientPacket(CMSG_DB_QUERY_BULK, std::move(packet)) { } - - void Read() override; - - uint32 TableHash = 0; - std::vector<DBQueryRecord> Queries; - }; - - class DBReply final : public ServerPacket - { - public: - DBReply() : ServerPacket(SMSG_DB_REPLY, 12) { } - - WorldPacket const* Write() override; - - uint32 TableHash = 0; - uint32 Timestamp = 0; - uint32 RecordID = 0; - bool Allow = false; - ByteBuffer Data; - }; - class QueryGameObject final : public ClientPacket { public: diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index fd6769cb16b..809a2d2c36b 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -445,7 +445,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GUILD_UPDATE_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildUpdateInfoText); DEFINE_HANDLER(CMSG_GUILD_UPDATE_MOTD_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildUpdateMotdText); DEFINE_HANDLER(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect); - DEFINE_HANDLER(CMSG_HOTFIX_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_HOTFIX_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleHotfixQuery); DEFINE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode); DEFINE_HANDLER(CMSG_INITIATE_ROLE_POLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateRolePoll); DEFINE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode); @@ -1257,8 +1257,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIXES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index c9daf2a274f..62e83ce253e 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1047,6 +1047,7 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue SendSetTimeZoneInformation(); SendFeatureSystemStatusGlueScreen(); SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION)); + SendHotfixList(int32(sWorld->getIntConfig(CONFIG_HOTFIX_CACHE_VERSION))); SendTutorialsData(); if (PreparedQueryResult characterCountsResult = holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_REALM_CHARACTER_COUNTS)) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 2438bb2a426..3703cdcf513 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -351,6 +351,12 @@ namespace WorldPackets class LFGuildSetGuildPost; } + namespace Hotfix + { + class DBQueryBulk; + class HotfixQuery; + } + namespace Inspect { class Inspect; @@ -545,7 +551,6 @@ namespace WorldPackets class QueryPlayerName; class QueryPageText; class QueryNPCText; - class DBQueryBulk; class QueryGameObject; class QueryCorpseLocationFromClient; class QueryCorpseTransport; @@ -933,6 +938,7 @@ class TC_GAME_API WorldSession void SendAuthResponse(uint32 code, bool queued, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); + void SendHotfixList(int32 version); void InitializeSession(); void InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQueryHolder* holder); @@ -1251,10 +1257,11 @@ class TC_GAME_API WorldSession void HandleNameQueryOpcode(WorldPackets::Query::QueryPlayerName& packet); void HandleQueryTimeOpcode(WorldPackets::Query::QueryTime& queryTime); void HandleCreatureQuery(WorldPackets::Query::QueryCreature& packet); - void HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet); - void HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObject& packet); + void HandleDBQueryBulk(WorldPackets::Hotfix::DBQueryBulk& dbQuery); + void HandleHotfixQuery(WorldPackets::Hotfix::HotfixQuery& hotfixQuery); + void HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortResponse& packet); void HandleMoveWorldportAck(); // for server-side calls void HandleSuspendTokenResponse(WorldPackets::Movement::SuspendTokenResponse& suspendTokenResponse); diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 1a3e4e71b25..14ce250d622 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -53,7 +53,7 @@ struct PacketHeader uint32 Size; uint16 Command; - bool IsValidSize() { return Size < 10240; } + bool IsValidSize() { return Size < 0x10000; } bool IsValidOpcode() { return Command < NUM_OPCODE_HANDLERS; } }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 6560f3c1d92..08ea6e57195 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1206,6 +1206,18 @@ void World::LoadConfigSettings(bool reload) TC_LOG_ERROR("server.loading", "ClientCacheVersion can't be negative %d, ignored.", clientCacheId); } + if (int32 hotfixCacheId = sConfigMgr->GetIntDefault("HotfixCacheVersion", 0)) + { + // overwrite DB/old value + if (hotfixCacheId > 0) + { + m_int_configs[CONFIG_HOTFIX_CACHE_VERSION] = hotfixCacheId; + TC_LOG_INFO("server.loading", "Hotfix cache version set to: %u", hotfixCacheId); + } + else + TC_LOG_ERROR("server.loading", "HotfixCacheVersion can't be negative %d, ignored.", hotfixCacheId); + } + m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] = sConfigMgr->GetIntDefault("Guild.NewsLogRecordsCount", GUILD_NEWSLOG_MAX_RECORDS); if (m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] > GUILD_NEWSLOG_MAX_RECORDS) m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] = GUILD_NEWSLOG_MAX_RECORDS; @@ -3380,14 +3392,14 @@ void World::UpdateMaxSessionCounters() void World::LoadDBVersion() { - QueryResult result = WorldDatabase.Query("SELECT db_version, cache_id FROM version LIMIT 1"); - if (result) + if (QueryResult result = WorldDatabase.Query("SELECT db_version, cache_id, hotfix_cache_id FROM version LIMIT 1")) { Field* fields = result->Fetch(); m_DBVersion = fields[0].GetString(); // will be overwrite by config values if different and non-0 m_int_configs[CONFIG_CLIENTCACHE_VERSION] = fields[1].GetUInt32(); + m_int_configs[CONFIG_HOTFIX_CACHE_VERSION] = fields[2].GetUInt32(); } if (m_DBVersion.empty()) diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index c6fbe7e47ab..4bab6c0fb3b 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -341,6 +341,7 @@ enum WorldIntConfigs CONFIG_LOGDB_CLEARINTERVAL, CONFIG_LOGDB_CLEARTIME, CONFIG_CLIENTCACHE_VERSION, + CONFIG_HOTFIX_CACHE_VERSION, CONFIG_GUILD_NEWS_LOG_COUNT, CONFIG_GUILD_EVENT_LOG_COUNT, CONFIG_GUILD_BANK_EVENT_LOG_COUNT, diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 49c77735605..df1e32ace59 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -67,7 +67,7 @@ class TC_SHARED_API ByteBuffer _storage.reserve(reserve); } - ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos), + ByteBuffer(ByteBuffer&& buf) noexcept : _rpos(buf._rpos), _wpos(buf._wpos), _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf.Move()) { } ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos), @@ -75,7 +75,7 @@ class TC_SHARED_API ByteBuffer ByteBuffer(MessageBuffer&& buffer); - std::vector<uint8>&& Move() + std::vector<uint8>&& Move() noexcept { _rpos = 0; _wpos = 0; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 7f662a5c954..37af5263fe6 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1165,6 +1165,14 @@ OffhandCheckAtSpellUnlearn = 1 ClientCacheVersion = 0 # +# HotfixCacheVersion +# Description: Hotfix cache version for hotfix cache data reset. Use any value different +# from DB and not recently been used to trigger client side cache reset. +# Default: 0 - (Use DB value from world DB version.hotfix_id field) + +HotfixCacheVersion = 0 + +# # Event.Announce # Description: Announce events. # Default: 0 - (Disabled) |
