TrinityCore
Loading...
Searching...
No Matches
CharacterCache.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 "CharacterCache.h"
19#include "ArenaTeam.h"
20#include "DatabaseEnv.h"
21#include "Log.h"
22#include "MiscPackets.h"
23#include "Player.h"
24#include "Timer.h"
25#include "World.h"
26#include "WorldPacket.h"
27#include <unordered_map>
28
29namespace
30{
31 std::unordered_map<ObjectGuid, CharacterCacheEntry> _characterCacheStore;
32 std::unordered_map<std::string, CharacterCacheEntry*> _characterCacheByNameStore;
33}
34
38
42
48
71{
72 _characterCacheStore.clear();
73 uint32 oldMSTime = getMSTime();
74
75 QueryResult result = CharacterDatabase.Query("SELECT guid, name, account, race, gender, class, level FROM characters");
76 if (!result)
77 {
78 TC_LOG_INFO("server.loading", "No character name data loaded, empty query");
79 return;
80 }
81
82 do
83 {
84 Field* fields = result->Fetch();
85 AddCharacterCacheEntry(ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt32()) /*guid*/, fields[2].GetUInt32() /*account*/, fields[1].GetString() /*name*/,
86 fields[4].GetUInt8() /*gender*/, fields[3].GetUInt8() /*race*/, fields[5].GetUInt8() /*class*/, fields[6].GetUInt8() /*level*/);
87 } while (result->NextRow());
88
89 TC_LOG_INFO("server.loading", "Loaded character infos for {} characters in {} ms", _characterCacheStore.size(), GetMSTimeDiffToNow(oldMSTime));
90}
91
92/*
93Modifying functions
94*/
95void CharacterCache::AddCharacterCacheEntry(ObjectGuid const& guid, uint32 accountId, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level)
96{
97 CharacterCacheEntry& data = _characterCacheStore[guid];
98 data.Guid = guid;
99 data.Name = name;
100 data.AccountId = accountId;
101 data.Race = race;
102 data.Sex = gender;
103 data.Class = playerClass;
104 data.Level = level;
105 data.GuildId = 0; // Will be set in guild loading or guild setting
106 for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
107 data.ArenaTeamId[i] = 0; // Will be set in arena teams loading
108
109 // Fill Name to Guid Store
110 _characterCacheByNameStore[name] = &data;
111}
112
113void CharacterCache::DeleteCharacterCacheEntry(ObjectGuid const& guid, std::string const& name)
114{
115 _characterCacheStore.erase(guid);
116 _characterCacheByNameStore.erase(name);
117}
118
119void CharacterCache::UpdateCharacterData(ObjectGuid const& guid, std::string const& name, Optional<uint8> gender /*= {}*/, Optional<uint8> race /*= {}*/)
120{
121 auto itr = _characterCacheStore.find(guid);
122 if (itr == _characterCacheStore.end())
123 return;
124
125 std::string oldName = itr->second.Name;
126 itr->second.Name = name;
127
128 if (gender)
129 itr->second.Sex = *gender;
130
131 if (race)
132 itr->second.Race = *race;
133
135 invalidatePlayer.Guid = guid;
136 sWorld->SendGlobalMessage(invalidatePlayer.Write());
137
138 // Correct name -> pointer storage
139 _characterCacheByNameStore.erase(oldName);
140 _characterCacheByNameStore[name] = &itr->second;
141}
142
144{
145 auto itr = _characterCacheStore.find(guid);
146 if (itr == _characterCacheStore.end())
147 return;
148
149 itr->second.Level = level;
150}
151
153{
154 auto itr = _characterCacheStore.find(guid);
155 if (itr == _characterCacheStore.end())
156 return;
157
158 itr->second.AccountId = accountId;
159}
160
162{
163 auto itr = _characterCacheStore.find(guid);
164 if (itr == _characterCacheStore.end())
165 return;
166
167 itr->second.GuildId = guildId;
168}
169
171{
172 auto itr = _characterCacheStore.find(guid);
173 if (itr == _characterCacheStore.end())
174 return;
175
176 ASSERT(slot < 3);
177 itr->second.ArenaTeamId[slot] = arenaTeamId;
178}
179
180/*
181Getters
182*/
184{
185 return _characterCacheStore.find(guid) != _characterCacheStore.end();
186}
187
189{
190 auto itr = _characterCacheStore.find(guid);
191 if (itr != _characterCacheStore.end())
192 return &itr->second;
193
194 return nullptr;
195}
196
198{
199 auto itr = _characterCacheByNameStore.find(name);
200 if (itr != _characterCacheByNameStore.end())
201 return itr->second;
202
203 return nullptr;
204}
205
207{
208 auto itr = _characterCacheByNameStore.find(name);
209 if (itr != _characterCacheByNameStore.end())
210 return itr->second->Guid;
211
212 return ObjectGuid::Empty;
213}
214
215bool CharacterCache::GetCharacterNameByGuid(ObjectGuid guid, std::string& name) const
216{
217 auto itr = _characterCacheStore.find(guid);
218 if (itr == _characterCacheStore.end())
219 return false;
220
221 name = itr->second.Name;
222 return true;
223}
224
226{
227 auto itr = _characterCacheStore.find(guid);
228 if (itr == _characterCacheStore.end())
229 return 0;
230
231 return Player::TeamForRace(itr->second.Race);
232}
233
235{
236 auto itr = _characterCacheStore.find(guid);
237 if (itr == _characterCacheStore.end())
238 return 0;
239
240 return itr->second.AccountId;
241}
242
244{
245 auto itr = _characterCacheByNameStore.find(name);
246 if (itr != _characterCacheByNameStore.end())
247 return itr->second->AccountId;
248
249 return 0;
250}
251
253{
254 auto itr = _characterCacheStore.find(guid);
255 if (itr == _characterCacheStore.end())
256 return 0;
257
258 return itr->second.Level;
259}
260
262{
263 auto itr = _characterCacheStore.find(guid);
264 if (itr == _characterCacheStore.end())
265 return 0;
266
267 return itr->second.GuildId;
268}
269
271{
272 auto itr = _characterCacheStore.find(guid);
273 if (itr == _characterCacheStore.end())
274 return 0;
275
276 uint8 slot = ArenaTeam::GetSlotByType(type);
277 ASSERT(slot < 3);
278 return itr->second.ArenaTeamId[slot];
279}
#define MAX_ARENA_SLOT
Definition ArenaTeam.h:114
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define ASSERT
Definition Errors.h:68
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
static uint8 GetSlotByType(uint32 type)
uint32 GetCharacterTeamByGuid(ObjectGuid guid) const
ObjectGuid GetCharacterGuidByName(std::string const &name) const
uint8 GetCharacterLevelByGuid(ObjectGuid guid) const
void AddCharacterCacheEntry(ObjectGuid const &guid, uint32 accountId, std::string const &name, uint8 gender, uint8 race, uint8 playerClass, uint8 level)
void UpdateCharacterAccountId(ObjectGuid const &guid, uint32 accountId)
bool HasCharacterCacheEntry(ObjectGuid const &guid) const
CharacterCacheEntry const * GetCharacterCacheByName(std::string const &name) const
static CharacterCache * instance()
void DeleteCharacterCacheEntry(ObjectGuid const &guid, std::string const &name)
uint32 GetCharacterAccountIdByGuid(ObjectGuid guid) const
void UpdateCharacterData(ObjectGuid const &guid, std::string const &name, Optional< uint8 > gender={}, Optional< uint8 > race={})
uint32 GetCharacterArenaTeamIdByGuid(ObjectGuid guid, uint8 type) const
void UpdateCharacterLevel(ObjectGuid const &guid, uint8 level)
uint32 GetCharacterAccountIdByName(std::string const &name) const
void LoadCharacterCacheStorage()
Loads several pieces of information on server startup with the GUID There is no further database quer...
CharacterCacheEntry const * GetCharacterCacheByGuid(ObjectGuid const &guid) const
ObjectGuid::LowType GetCharacterGuildIdByGuid(ObjectGuid guid) const
void UpdateCharacterGuildId(ObjectGuid const &guid, ObjectGuid::LowType guildId)
void UpdateCharacterArenaTeamId(ObjectGuid const &guid, uint8 slot, uint32 arenaTeamId)
bool GetCharacterNameByGuid(ObjectGuid guid, std::string &name) const
Class used to access individual fields of database query result.
Definition Field.h:92
static ObjectGuid const Empty
Definition ObjectGuid.h:140
uint32 LowType
Definition ObjectGuid.h:142
static uint32 TeamForRace(uint8 race)
Definition Player.cpp:6271
WorldPacket const * Write() override
#define sWorld
Definition World.h:901
ObjectGuid::LowType GuildId