Core/DataStores: Updated sending out hotfixes

This commit is contained in:
Shauren
2017-04-19 19:10:49 +02:00
parent 15b1aaff41
commit 6636ca8585
19 changed files with 382 additions and 130 deletions

View File

@@ -0,0 +1,8 @@
DROP TABLE IF EXISTS `hotfix_data`;
CREATE TABLE `hotfix_data` (
`Id` int(11) NOT NULL,
`TableHash` int(10) unsigned NOT NULL,
`RecordId` int(11) NOT NULL,
`Deleted` tinyint(3) unsigned NULL DEFAULT '0',
PRIMARY KEY (`Id`, `TableHash`, `RecordId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1 @@
ALTER TABLE `version` ADD `hotfix_cache_id` int(11) NOT NULL DEFAULT '0';

View File

@@ -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));
}
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);
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);
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

View File

@@ -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;

View File

@@ -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());
}

View File

@@ -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.
*

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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;

View File

@@ -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:

View File

@@ -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);

View File

@@ -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))

View File

@@ -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);

View File

@@ -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; }
};

View File

@@ -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())

View File

@@ -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,

View File

@@ -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;

View File

@@ -1164,6 +1164,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.