TrinityCore
GameTables.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 "GameTables.h"
19#include "ItemTemplate.h"
20#include "Timer.h"
21#include "Log.h"
22#include "StringConvert.h"
23#include "Util.h"
24#include <boost/filesystem/path.hpp>
25#include <fstream>
26#include <sstream>
27
41
42template<class T>
43inline uint32 LoadGameTable(std::vector<std::string>& errors, GameTable<T>& storage, boost::filesystem::path const& path)
44{
45 std::ifstream stream(path.string());
46 if (!stream)
47 {
48 errors.push_back(Trinity::StringFormat("GameTable file {} cannot be opened.", path.string()));
49 return 0;
50 }
51
52 std::string headers;
53 if (!std::getline(stream, headers))
54 {
55 errors.push_back(Trinity::StringFormat("GameTable file {} is empty.", path.string()));
56 return 0;
57 }
58
59 std::vector<std::string_view> columnDefs = Trinity::Tokenize(headers, '\t', false);
60
61 ASSERT(columnDefs.size() - 1 == sizeof(T) / sizeof(float),
62 "GameTable '%s' has different count of columns " SZFMTD " than expected by size of C++ structure (" SZFMTD ").",
63 path.string().c_str(), columnDefs.size() - 1, sizeof(T) / sizeof(float));
64
65 std::vector<T> data;
66 data.emplace_back(); // row id 0, unused
67
68 std::string line;
69 while (std::getline(stream, line))
70 {
71 RemoveCRLF(line); // file extracted from client will always have CRLF line endings, on linux opening file in text mode will not work, manually erase \r
72 std::vector<std::string_view> values = Trinity::Tokenize(line, '\t', true);
73 if (values.empty())
74 break;
75
76 // make end point just after last nonempty token
77 auto end = values.begin() + values.size() - 1;
78 while (end->empty() && end != values.begin())
79 --end;
80
81 if (values.begin() == end)
82 break;
83
84 ++end;
85
86 ASSERT(std::size_t(std::distance(values.begin(), end)) == columnDefs.size(), SZFMTD " == " SZFMTD, std::size_t(std::distance(values.begin(), end)), columnDefs.size());
87
88 // client ignores id column - CombatRatings has copypasted rows for levels > 110
89 //ASSERT(Trinity::StringTo<int32>(values[0], 10) == data.size(),
90 // "Unexpected row identifier %d at row " SZFMTD " (expected " SZFMTD ")",
91 // Trinity::StringTo<int32>(values[0], 10).value_or(0), data.size(), data.size());
92
93 data.emplace_back();
94 float* row = reinterpret_cast<float*>(&data.back());
95 for (auto itr = values.begin() + 1; itr != end; ++itr)
96 *row++ = Trinity::StringTo<float>(*itr, 10).value_or(0.0f);
97 }
98
99 storage.SetData(std::move(data));
100 return 1;
101}
102
103void LoadGameTables(std::string const& dataPath)
104{
105 uint32 oldMSTime = getMSTime();
106
107 boost::filesystem::path gtPath(dataPath);
108 gtPath /= "gt";
109
110 std::vector<std::string> bad_gt_files;
111 uint32 gameTableCount = 0, expectedGameTableCount = 0;
112
113 auto LOAD_GT = [&]<typename T>(GameTable<T>& gameTable, char const* file)
114 {
115 gameTableCount += LoadGameTable(bad_gt_files, gameTable, gtPath / file);
116 ++expectedGameTableCount;
117 };
118
119 LOAD_GT(sArtifactKnowledgeMultiplierGameTable, "ArtifactKnowledgeMultiplier.txt");
120 LOAD_GT(sArtifactLevelXPGameTable, "ArtifactLevelXP.txt");
121 LOAD_GT(sBarberShopCostBaseGameTable, "BarberShopCostBase.txt");
122 LOAD_GT(sBaseMPGameTable, "BaseMp.txt");
123 LOAD_GT(sBattlePetXPGameTable, "BattlePetXP.txt");
124 LOAD_GT(sCombatRatingsGameTable, "CombatRatings.txt");
125 LOAD_GT(sCombatRatingsMultByILvlGameTable, "CombatRatingsMultByILvl.txt");
126 LOAD_GT(sItemSocketCostPerLevelGameTable, "ItemSocketCostPerLevel.txt");
127 LOAD_GT(sHpPerStaGameTable, "HpPerSta.txt");
128 LOAD_GT(sNpcManaCostScalerGameTable, "NPCManaCostScaler.txt");
129 LOAD_GT(sSpellScalingGameTable, "SpellScaling.txt");
130 LOAD_GT(sStaminaMultByILvlGameTable, "StaminaMultByILvl.txt");
131 LOAD_GT(sXpGameTable, "xp.txt");
132
133#undef LOAD_GT
134
135 // error checks
136 if (gameTableCount != expectedGameTableCount)
137 {
138 std::ostringstream str;
139 for (std::string const& err : bad_gt_files)
140 str << err << std::endl;
141
142 WPFatal(false, "Some required *.txt GameTable files (" SZFMTD ") not found or not compatible:\n%s", bad_gt_files.size(), str.str().c_str());
143 }
144
145 TC_LOG_INFO("server.loading", ">> Initialized {} GameTables in {} ms", gameTableCount, GetMSTimeDiffToNow(oldMSTime));
146}
147
148template<class T>
149float GetIlvlStatMultiplier(T const* row, InventoryType invType)
150{
151 switch (invType)
152 {
153 case INVTYPE_NECK:
154 case INVTYPE_FINGER:
155 return row->JewelryMultiplier;
156 break;
157 case INVTYPE_TRINKET:
158 return row->TrinketMultiplier;
159 break;
160 case INVTYPE_WEAPON:
161 case INVTYPE_SHIELD:
162 case INVTYPE_RANGED:
163 case INVTYPE_2HWEAPON:
166 case INVTYPE_HOLDABLE:
168 return row->WeaponMultiplier;
169 break;
170 default:
171 return row->ArmorMultiplier;
172 break;
173 }
174}
175
177template float GetIlvlStatMultiplier(GtStaminaMultByILvl const* row, InventoryType invType);
uint32_t uint32
Definition: Define.h:142
#define SZFMTD
Definition: Define.h:132
#define WPFatal(cond,...)
Definition: Errors.h:58
#define ASSERT
Definition: Errors.h:68
GameTable< GtSpellScalingEntry > sSpellScalingGameTable
Definition: GameTables.cpp:38
GameTable< GtBattlePetXPEntry > sBattlePetXPGameTable
Definition: GameTables.cpp:32
GameTable< GtItemSocketCostPerLevelEntry > sItemSocketCostPerLevelGameTable
Definition: GameTables.cpp:36
GameTable< GtStaminaMultByILvl > sStaminaMultByILvlGameTable
Definition: GameTables.cpp:39
float GetIlvlStatMultiplier(T const *row, InventoryType invType)
Definition: GameTables.cpp:149
GameTable< GtCombatRatingsEntry > sCombatRatingsGameTable
Definition: GameTables.cpp:33
void LoadGameTables(std::string const &dataPath)
Definition: GameTables.cpp:103
GameTable< GtArtifactKnowledgeMultiplierEntry > sArtifactKnowledgeMultiplierGameTable
Definition: GameTables.cpp:28
GameTable< GtXpEntry > sXpGameTable
Definition: GameTables.cpp:40
GameTable< GtHpPerStaEntry > sHpPerStaGameTable
Definition: GameTables.cpp:35
GameTable< GtNpcManaCostScalerEntry > sNpcManaCostScalerGameTable
Definition: GameTables.cpp:37
GameTable< GtBaseMPEntry > sBaseMPGameTable
Definition: GameTables.cpp:31
GameTable< GtBarberShopCostBaseEntry > sBarberShopCostBaseGameTable
Definition: GameTables.cpp:30
GameTable< GtCombatRatingsMultByILvl > sCombatRatingsMultByILvlGameTable
Definition: GameTables.cpp:34
uint32 LoadGameTable(std::vector< std::string > &errors, GameTable< T > &storage, boost::filesystem::path const &path)
Definition: GameTables.cpp:43
GameTable< GtArtifactLevelXPEntry > sArtifactLevelXPGameTable
Definition: GameTables.cpp:29
InventoryType
Definition: ItemTemplate.h:378
@ INVTYPE_FINGER
Definition: ItemTemplate.h:390
@ INVTYPE_HOLDABLE
Definition: ItemTemplate.h:402
@ INVTYPE_TRINKET
Definition: ItemTemplate.h:391
@ INVTYPE_RANGED
Definition: ItemTemplate.h:394
@ INVTYPE_RANGEDRIGHT
Definition: ItemTemplate.h:405
@ INVTYPE_WEAPON
Definition: ItemTemplate.h:392
@ INVTYPE_WEAPONMAINHAND
Definition: ItemTemplate.h:400
@ INVTYPE_WEAPONOFFHAND
Definition: ItemTemplate.h:401
@ INVTYPE_2HWEAPON
Definition: ItemTemplate.h:396
@ INVTYPE_NECK
Definition: ItemTemplate.h:381
@ INVTYPE_SHIELD
Definition: ItemTemplate.h:393
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:57
uint32 getMSTime()
Definition: Timer.h:33
TC_COMMON_API Optional< std::size_t > RemoveCRLF(std::string &str)
Definition: Util.cpp:839
void SetData(std::vector< T > data)
Definition: GameTables.h:184
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Util.cpp:56
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
Definition: StringFormat.h:38