TrinityCore
Loading...
Searching...
No Matches
ClientBuildInfo.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 "ClientBuildInfo.h"
19#include "DatabaseEnv.h"
20#include "Log.h"
21#include "Util.h"
22#include <algorithm>
23#include <cctype>
24
25namespace
26{
27std::vector<ClientBuild::Info> Builds;
28}
29
30namespace ClientBuild
31{
32std::array<char, 5> ToCharArray(uint32 value)
33{
34 auto normalize = [](uint8 c) -> char
35 {
36 if (!c || std::isprint(c))
37 return char(c);
38 return ' ';
39 };
40
41 std::array<char, 5> chars = { char((value >> 24) & 0xFF), char((value >> 16) & 0xFF), char((value >> 8) & 0xFF), char(value & 0xFF), '\0' };
42
43 auto firstNonZero = std::ranges::find_if(chars, [](char c) { return c != '\0'; });
44 if (firstNonZero != chars.end())
45 {
46 // move leading zeros to end
47 std::rotate(chars.begin(), firstNonZero, chars.end());
48
49 // ensure we only have printable characters remaining
50 std::ranges::transform(chars, chars.begin(), normalize);
51 }
52
53 return chars;
54}
55
56bool Platform::IsValid(std::string_view platform)
57{
58 if (platform.length() > sizeof(uint32))
59 return false;
60
61 switch (ToFourCC(platform))
62 {
63 case Win_x86:
64 case Mac_x86:
65 return true;
66 default:
67 break;
68 }
69
70 return false;
71}
72
74{
75 Builds.clear();
76
77 // 0 1 2 3 4
78 if (QueryResult result = LoginDatabase.Query("SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build FROM build_info ORDER BY build ASC"))
79 {
80 do
81 {
82 Field* fields = result->Fetch();
83 Info& build = Builds.emplace_back();
84 build.MajorVersion = fields[0].GetUInt32();
85 build.MinorVersion = fields[1].GetUInt32();
86 build.BugfixVersion = fields[2].GetUInt32();
87 std::string hotfixVersion = fields[3].GetString();
88 if (hotfixVersion.length() < build.HotfixVersion.size())
89 std::ranges::copy(hotfixVersion, build.HotfixVersion.begin());
90 else
91 build.HotfixVersion = { };
92
93 build.Build = fields[4].GetUInt32();
94
95 } while (result->NextRow());
96 }
97
98 // 0 1 2
99 if (QueryResult result = LoginDatabase.Query("SELECT `build`, `platform`, `executableHash` FROM `build_executable_hash`"))
100 {
101 do
102 {
103 Field* fields = result->Fetch();
104
105 uint32 build = fields[0].GetInt32();
106 auto buildInfo = std::ranges::find(Builds, build, &Info::Build);
107 if (buildInfo == Builds.end())
108 {
109 TC_LOG_ERROR("sql.sql", "ClientBuild::LoadBuildInfo: Unknown `build` {} in `build_executable_hash` - missing from `build_info`, skipped.", build);
110 continue;
111 }
112
113 std::string_view platform = fields[1].GetStringView();
114 if (!Platform::IsValid(platform))
115 {
116 TC_LOG_ERROR("sql.sql", "ClientBuild::LoadBuildInfo: Invalid platform {} for `build` {} in `build_executable_hash`, skipped.", platform, build);
117 continue;
118 }
119
120 ExecutableHash& buildKey = buildInfo->ExecutableHashes.emplace_back();
121 buildKey.Platform = ToFourCC(platform);
122 buildKey.Hash = fields[2].GetBinary<ExecutableHash::Size>();
123
124 } while (result->NextRow());
125 }
126}
127
129{
130 auto buildInfo = std::ranges::find(Builds, build, &Info::Build);
131 return buildInfo != Builds.end() ? &*buildInfo : nullptr;
132}
133
135{
136 auto buildInfo = std::ranges::lower_bound(Builds, build, {}, &Info::Build);
137 return buildInfo != Builds.end() ? (buildInfo->MajorVersion * 10000 + buildInfo->MinorVersion * 100 + buildInfo->BugfixVersion) : 0;
138}
139}
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
Class used to access individual fields of database query result.
Definition Field.h:92
std::string GetString() const
Definition Field.cpp:125
std::vector< uint8 > GetBinary() const
Definition Field.cpp:149
std::string_view GetStringView() const
Definition Field.cpp:137
uint32 GetUInt32() const
Definition Field.cpp:61
int32 GetInt32() const
Definition Field.cpp:69
constexpr uint32 Win_x86
TC_SHARED_API bool IsValid(std::string_view platform)
constexpr uint32 Mac_x86
constexpr uint32 ToFourCC(std::string_view text)
Info const * GetBuildInfo(uint32 build)
std::array< char, 5 > ToCharArray(uint32 value)
uint32 GetMinorMajorBugfixVersionForBuild(uint32 build)
std::array< uint8, Size > Hash
static constexpr std::size_t Size
std::array< char, 4 > HotfixVersion