TrinityCore
HotfixHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
19#include "Containers.h"
20#include "DB2Stores.h"
21#include "GameTime.h"
22#include "HotfixPackets.h"
23#include "Log.h"
24#include "Realm.h"
25#include "World.h"
26
28{
29 DB2StorageBase const* store = sDB2Manager.GetStorage(dbQuery.TableHash);
31 {
33 dbReply.TableHash = dbQuery.TableHash;
34 dbReply.RecordID = record.RecordID;
35
36 if (store && store->HasRecord(record.RecordID))
37 {
40 store->WriteRecord(record.RecordID, GetSessionDbcLocale(), dbReply.Data);
41
42 if (std::vector<DB2Manager::HotfixOptionalData> const* optionalDataEntries = sDB2Manager.GetHotfixOptionalData(dbQuery.TableHash, record.RecordID, GetSessionDbcLocale()))
43 {
44 for (DB2Manager::HotfixOptionalData const& optionalData : *optionalDataEntries)
45 {
46 dbReply.Data << uint32(optionalData.Key);
47 dbReply.Data.append(optionalData.Data.data(), optionalData.Data.size());
48 }
49 }
50 }
51 else
52 {
53 TC_LOG_TRACE("network", "CMSG_DB_QUERY_BULK: {} requested non-existing entry {} in datastore: {}", GetPlayerInfo(), record.RecordID, dbQuery.TableHash);
55 }
56
57 SendPacket(dbReply.Write());
58 }
59}
60
62{
64 availableHotfixes.VirtualRealmAddress = realm.Id.GetAddress();
65
66 for (auto const& [pushId, push] : sDB2Manager.GetHotfixData())
67 {
68 if (!(push.AvailableLocalesMask & (1 << GetSessionDbcLocale())))
69 continue;
70
71 availableHotfixes.Hotfixes.insert(push.Records.front().ID);
72 }
73
74 SendPacket(availableHotfixes.Write());
75}
76
78{
79 DB2Manager::HotfixContainer const& hotfixes = sDB2Manager.GetHotfixData();
80 WorldPackets::Hotfix::HotfixConnect hotfixQueryResponse;
81 hotfixQueryResponse.Hotfixes.reserve(hotfixQuery.Hotfixes.size());
82 for (int32 hotfixId : hotfixQuery.Hotfixes)
83 {
84 if (DB2Manager::HotfixPush const* hotfixRecords = Trinity::Containers::MapGetValuePtr(hotfixes, hotfixId))
85 {
86 for (DB2Manager::HotfixRecord const& hotfixRecord : hotfixRecords->Records)
87 {
88 if (!(hotfixRecord.AvailableLocalesMask & (1 << GetSessionDbcLocale())))
89 continue;
90
91 WorldPackets::Hotfix::HotfixConnect::HotfixData& hotfixData = hotfixQueryResponse.Hotfixes.emplace_back();
92 hotfixData.Record = hotfixRecord;
94 {
95 DB2StorageBase const* storage = sDB2Manager.GetStorage(hotfixRecord.TableHash);
96 if (storage && storage->HasRecord(uint32(hotfixRecord.RecordID)))
97 {
98 std::size_t pos = hotfixQueryResponse.HotfixContent.size();
99 storage->WriteRecord(uint32(hotfixRecord.RecordID), GetSessionDbcLocale(), hotfixQueryResponse.HotfixContent);
100
101 if (std::vector<DB2Manager::HotfixOptionalData> const* optionalDataEntries = sDB2Manager.GetHotfixOptionalData(hotfixRecord.TableHash, hotfixRecord.RecordID, GetSessionDbcLocale()))
102 {
103 for (DB2Manager::HotfixOptionalData const& optionalData : *optionalDataEntries)
104 {
105 hotfixQueryResponse.HotfixContent << uint32(optionalData.Key);
106 hotfixQueryResponse.HotfixContent.append(optionalData.Data.data(), optionalData.Data.size());
107 }
108 }
109
110 hotfixData.Size = hotfixQueryResponse.HotfixContent.size() - pos;
111 }
112 else if (std::vector<uint8> const* blobData = sDB2Manager.GetHotfixBlobData(hotfixRecord.TableHash, hotfixRecord.RecordID, GetSessionDbcLocale()))
113 {
114 hotfixData.Size = blobData->size();
115 hotfixQueryResponse.HotfixContent.append(blobData->data(), blobData->size());
116 }
117 else
118 // Do not send Status::Valid when we don't have a hotfix blob for current locale
120 }
121 }
122 }
123 }
124
125 SendPacket(hotfixQueryResponse.Write());
126}
#define sDB2Manager
Definition: DB2Stores.h:538
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_TRACE(filterType__,...)
Definition: Log.h:153
void append(T value)
Definition: ByteBuffer.h:143
size_t size() const
Definition: ByteBuffer.h:536
std::map< int32, HotfixPush > HotfixContainer
Definition: DB2Stores.h:404
Interface class for common access.
Definition: DB2Store.h:31
void WriteRecord(uint32 id, LocaleConstant locale, ByteBuffer &buffer) const
Definition: DB2Store.cpp:41
bool HasRecord(uint32 id) const
Definition: DB2Store.h:43
std::set< DB2Manager::HotfixId > Hotfixes
Definition: HotfixPackets.h:68
WorldPacket const * Write() override
std::vector< DBQueryRecord > Queries
Definition: HotfixPackets.h:43
DB2Manager::HotfixRecord::Status Status
Definition: HotfixPackets.h:56
WorldPacket const * Write() override
WorldPacket const * Write() override
std::vector< HotfixData > Hotfixes
Definition: HotfixPackets.h:96
void HandleDBQueryBulk(WorldPackets::Hotfix::DBQueryBulk &dbQuery)
LocaleConstant GetSessionDbcLocale() const
std::string GetPlayerInfo() const
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleHotfixRequest(WorldPackets::Hotfix::HotfixRequest &hotfixQuery)
void SendAvailableHotfixes()
Realm realm
Definition: World.cpp:3966
time_t GetGameTime()
Definition: GameTime.cpp:44
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition: MapUtils.h:29
uint32 GetAddress() const
Definition: Realm.h:56
Battlenet::RealmHandle Id
Definition: Realm.h:82