mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/DataStores: Updated sending out hotfixes
This commit is contained in:
8
sql/updates/hotfixes/master/2017_04_19_01_hotfixes.sql
Normal file
8
sql/updates/hotfixes/master/2017_04_19_01_hotfixes.sql
Normal 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;
|
||||
1
sql/updates/world/master/2017_04_19_01_world.sql
Normal file
1
sql/updates/world/master/2017_04_19_01_world.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `version` ADD `hotfix_cache_id` int(11) NOT NULL DEFAULT '0';
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
93
src/server/game/Handlers/HotfixHandler.cpp
Normal file
93
src/server/game/Handlers/HotfixHandler.cpp
Normal 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());
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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"
|
||||
|
||||
101
src/server/game/Server/Packets/HotfixPackets.cpp
Normal file
101
src/server/game/Server/Packets/HotfixPackets.cpp
Normal 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;
|
||||
}
|
||||
108
src/server/game/Server/Packets/HotfixPackets.h
Normal file
108
src/server/game/Server/Packets/HotfixPackets.h
Normal 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__
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user