TrinityCore
Loading...
Searching...
No Matches
AccountMgr.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 "AccountMgr.h"
19#include "Config.h"
20#include "DatabaseEnv.h"
21#include "CryptoHash.h"
22#include "Log.h"
23#include "ObjectAccessor.h"
24#include "Player.h"
25#include "Realm.h"
26#include "ScriptMgr.h"
27#include "SRP6.h"
28#include "Util.h"
29#include "World.h"
30#include "WorldSession.h"
31
33
38
44
45AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email /*= ""*/)
46{
47 if (utf8length(username) > MAX_ACCOUNT_STR)
48 return AccountOpResult::AOR_NAME_TOO_LONG; // username's too long
49
50 if (utf8length(password) > MAX_PASS_STR)
51 return AccountOpResult::AOR_PASS_TOO_LONG; // password's too long
52
53 Utf8ToUpperOnlyLatin(username);
54 Utf8ToUpperOnlyLatin(password);
56
57 if (GetId(username))
58 return AccountOpResult::AOR_NAME_ALREADY_EXIST; // username does already exist
59
61
62 stmt->setString(0, username);
63 auto [salt, verifier] = Trinity::Crypto::SRP6::MakeRegistrationData(username, password);
64 stmt->setBinary(1, salt);
65 stmt->setBinary(2, verifier);
66 stmt->setString(3, email);
67 stmt->setString(4, email);
68
69 LoginDatabase.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail
70
71 stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT);
72 LoginDatabase.Execute(stmt);
73
74 return AccountOpResult::AOR_OK; // everything's fine
75}
76
78{
79 // Check if accounts exists
81 loginStmt->setUInt32(0, accountId);
82 PreparedQueryResult result = LoginDatabase.Query(loginStmt);
83
84 if (!result)
86
87 // Obtain accounts characters
89
90 stmt->setUInt32(0, accountId);
91
92 result = CharacterDatabase.Query(stmt);
93
94 if (result)
95 {
96 do
97 {
98 ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>((*result)[0].GetUInt32());
99
100 // Kick if player is online
102 {
103 WorldSession* s = p->GetSession();
104 s->KickPlayer("AccountMgr::DeleteAccount Deleting the account"); // mark session to remove at next session list update
105 s->LogoutPlayer(false); // logout player without waiting next session list update
106 }
107
108 Player::DeleteFromDB(guid, accountId, false); // no need to update realm characters
109 } while (result->NextRow());
110 }
111
112 // table realm specific but common for all characters of account for realm
113 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS);
114 stmt->setUInt32(0, accountId);
115 CharacterDatabase.Execute(stmt);
116
117 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA);
118 stmt->setUInt32(0, accountId);
119 CharacterDatabase.Execute(stmt);
120
121 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_BAN);
122 stmt->setUInt32(0, accountId);
123 CharacterDatabase.Execute(stmt);
124
125 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES);
126 stmt->setUInt32(0, accountId);
127 CharacterDatabase.Execute(stmt);
128
129 LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
130
131 loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT);
132 loginStmt->setUInt32(0, accountId);
133 trans->Append(loginStmt);
134
135 loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS);
136 loginStmt->setUInt32(0, accountId);
137 trans->Append(loginStmt);
138
139 loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS);
140 loginStmt->setUInt32(0, accountId);
141 trans->Append(loginStmt);
142
143 loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_BANNED);
144 loginStmt->setUInt32(0, accountId);
145 trans->Append(loginStmt);
146
147 loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_MUTED);
148 loginStmt->setUInt32(0, accountId);
149 trans->Append(loginStmt);
150
151 LoginDatabase.CommitTransaction(trans);
152
154}
155
156AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword)
157{
158 // Check if accounts exists
160 stmt->setUInt32(0, accountId);
161 PreparedQueryResult result = LoginDatabase.Query(stmt);
162
163 if (!result)
165
166 if (utf8length(newUsername) > MAX_ACCOUNT_STR)
168
169 if (utf8length(newPassword) > MAX_PASS_STR)
171
172 Utf8ToUpperOnlyLatin(newUsername);
173 Utf8ToUpperOnlyLatin(newPassword);
174
175 stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_USERNAME);
176 stmt->setString(0, newUsername);
177 stmt->setUInt32(1, accountId);
178 LoginDatabase.Execute(stmt);
179
180 auto [salt, verifier] = Trinity::Crypto::SRP6::MakeRegistrationData(newUsername, newPassword);
181 stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGON);
182 stmt->setBinary(0, salt);
183 stmt->setBinary(1, verifier);
184 stmt->setUInt32(2, accountId);
185 LoginDatabase.Execute(stmt);
186
188}
189
190AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPassword)
191{
192 std::string username;
193
194 if (!GetName(accountId, username))
195 {
196 sScriptMgr->OnFailedPasswordChange(accountId);
197 return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist
198 }
199
200 if (utf8length(newPassword) > MAX_PASS_STR)
201 {
202 sScriptMgr->OnFailedPasswordChange(accountId);
204 }
205
206 Utf8ToUpperOnlyLatin(username);
207 Utf8ToUpperOnlyLatin(newPassword);
208 auto [salt, verifier] = Trinity::Crypto::SRP6::MakeRegistrationData(username, newPassword);
209
211 stmt->setBinary(0, salt);
212 stmt->setBinary(1, verifier);
213 stmt->setUInt32(2, accountId);;
214 LoginDatabase.Execute(stmt);
215
216 sScriptMgr->OnPasswordChange(accountId);
218}
219
220AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail)
221{
222 std::string username;
223
224 if (!GetName(accountId, username))
225 {
226 sScriptMgr->OnFailedEmailChange(accountId);
227 return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist
228 }
229
230 if (utf8length(newEmail) > MAX_EMAIL_STR)
231 {
232 sScriptMgr->OnFailedEmailChange(accountId);
234 }
235
236 Utf8ToUpperOnlyLatin(username);
237 Utf8ToUpperOnlyLatin(newEmail);
238
240
241 stmt->setString(0, newEmail);
242 stmt->setUInt32(1, accountId);
243
244 LoginDatabase.Execute(stmt);
245
246 sScriptMgr->OnEmailChange(accountId);
248}
249
250AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmail)
251{
252 std::string username;
253
254 if (!GetName(accountId, username))
255 {
256 sScriptMgr->OnFailedEmailChange(accountId);
257 return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist
258 }
259
260 if (utf8length(newEmail) > MAX_EMAIL_STR)
261 {
262 sScriptMgr->OnFailedEmailChange(accountId);
264 }
265
266 Utf8ToUpperOnlyLatin(username);
267 Utf8ToUpperOnlyLatin(newEmail);
268
270
271 stmt->setString(0, newEmail);
272 stmt->setUInt32(1, accountId);
273
274 LoginDatabase.Execute(stmt);
275
276 sScriptMgr->OnEmailChange(accountId);
278}
279
280uint32 AccountMgr::GetId(std::string_view username)
281{
283 stmt->setStringView(0, username);
284 PreparedQueryResult result = LoginDatabase.Query(stmt);
285
286 return (result) ? (*result)[0].GetUInt32() : 0;
287}
288
290{
292 stmt->setUInt32(0, accountId);
293 stmt->setInt32(1, realmId);
294 PreparedQueryResult result = LoginDatabase.Query(stmt);
295
296 return (result) ? (*result)[0].GetUInt8() : uint32(SEC_PLAYER);
297}
298
299QueryCallback AccountMgr::GetSecurityAsync(uint32 accountId, int32 realmId, std::function<void(uint32)> callback)
300{
302 stmt->setUInt32(0, accountId);
303 stmt->setInt32(1, realmId);
304 return LoginDatabase.AsyncQuery(stmt).WithPreparedCallback([callback = std::move(callback)](PreparedQueryResult result)
305 {
306 callback(result ? uint32((*result)[0].GetUInt8()) : uint32(SEC_PLAYER));
307 });
308}
309
310bool AccountMgr::GetName(uint32 accountId, std::string& name)
311{
313 stmt->setUInt32(0, accountId);
314 PreparedQueryResult result = LoginDatabase.Query(stmt);
315
316 if (result)
317 {
318 name = (*result)[0].GetString();
319 return true;
320 }
321
322 return false;
323}
324
325bool AccountMgr::GetEmail(uint32 accountId, std::string& email)
326{
328 stmt->setUInt32(0, accountId);
329 PreparedQueryResult result = LoginDatabase.Query(stmt);
330
331 if (result)
332 {
333 email = (*result)[0].GetString();
334 return true;
335 }
336
337 return false;
338}
339
340bool AccountMgr::CheckPassword(uint32 accountId, std::string password)
341{
342 std::string username;
343
344 if (!GetName(accountId, username))
345 return false;
346
347 Utf8ToUpperOnlyLatin(username);
348 Utf8ToUpperOnlyLatin(password);
349
351 stmt->setUInt32(0, accountId);
352
353 if (PreparedQueryResult result = LoginDatabase.Query(stmt))
354 {
357 if (Trinity::Crypto::SRP6::CheckLogin(username, password, salt, verifier))
358 return true;
359 }
360
361 return false;
362}
363
364bool AccountMgr::CheckEmail(uint32 accountId, std::string newEmail)
365{
366 std::string oldEmail;
367
368 // We simply return false for a non-existing email
369 if (!GetEmail(accountId, oldEmail))
370 return false;
371
372 Utf8ToUpperOnlyLatin(oldEmail);
373 Utf8ToUpperOnlyLatin(newEmail);
374
375 if (strcmp(oldEmail.c_str(), newEmail.c_str()) == 0)
376 return true;
377
378 return false;
379}
380
382{
383 // check character count
385 stmt->setUInt32(0, accountId);
386 PreparedQueryResult result = CharacterDatabase.Query(stmt);
387
388 return (result) ? (*result)[0].GetUInt64() : 0;
389}
390
391bool AccountMgr::IsBannedAccount(std::string const& name)
392{
394 stmt->setString(0, name);
395 PreparedQueryResult result = LoginDatabase.Query(stmt);
396
397 if (!result)
398 return false;
399
400 return true;
401}
402
404{
405 return gmlevel == SEC_PLAYER;
406}
407
409{
410 return gmlevel >= SEC_ADMINISTRATOR && gmlevel <= SEC_CONSOLE;
411}
412
414{
415 return gmlevel == SEC_CONSOLE;
416}
417
419{
420 ClearRBAC();
421
422 TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC");
423 uint32 oldMSTime = getMSTime();
424 uint32 count1 = 0;
425 uint32 count2 = 0;
426 uint32 count3 = 0;
427
428 TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading permissions");
429 QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions");
430 if (!result)
431 {
432 TC_LOG_INFO("server.loading", ">> Loaded 0 account permission definitions. DB table `rbac_permissions` is empty.");
433 return;
434 }
435
436 do
437 {
438 Field* field = result->Fetch();
439 uint32 id = field[0].GetUInt32();
440 _permissions[id] = new rbac::RBACPermission(id, field[1].GetString());
441 ++count1;
442 }
443 while (result->NextRow());
444
445 TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading linked permissions");
446 result = LoginDatabase.Query("SELECT id, linkedId FROM rbac_linked_permissions ORDER BY id ASC");
447 if (!result)
448 {
449 TC_LOG_INFO("server.loading", ">> Loaded 0 linked permissions. DB table `rbac_linked_permissions` is empty.");
450 return;
451 }
452
453 uint32 permissionId = 0;
454 rbac::RBACPermission* permission = nullptr;
455
456 do
457 {
458 Field* field = result->Fetch();
459 uint32 newId = field[0].GetUInt32();
460 if (permissionId != newId)
461 {
462 permissionId = newId;
463 permission = _permissions[newId];
464 }
465
466 uint32 linkedPermissionId = field[1].GetUInt32();
467 if (linkedPermissionId == permissionId)
468 {
469 TC_LOG_ERROR("sql.sql", "RBAC Permission {} has itself as linked permission. Ignored", permissionId);
470 continue;
471 }
472 permission->AddLinkedPermission(linkedPermissionId);
473 ++count2;
474 }
475 while (result->NextRow());
476
477 TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions");
478 result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = {} OR realmId = -1) ORDER BY secId ASC", realm.Id.Realm);
479 if (!result)
480 {
481 TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
482 return;
483 }
484
485 uint8 secId = 255;
486 rbac::RBACPermissionContainer* permissions = nullptr;
487 do
488 {
489 Field* field = result->Fetch();
490 uint32 newId = field[0].GetUInt32();
491 if (secId != newId || permissions == nullptr)
492 {
493 secId = newId;
494 permissions = &_defaultPermissions[secId];
495 }
496
497 permissions->insert(field[1].GetUInt32());
498 ++count3;
499 }
500 while (result->NextRow());
501
502 TC_LOG_INFO("server.loading", ">> Loaded {} permission definitions, {} linked permissions and {} default permissions in {} ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime));
503}
504
505void AccountMgr::UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId)
506{
507 if (rbac && securityLevel != rbac->GetSecurityLevel())
508 rbac->SetSecurityLevel(securityLevel);
509
510 LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
511 // Delete old security level from DB
512 if (realmId == -1)
513 {
515 stmt->setUInt32(0, accountId);
516 trans->Append(stmt);
517 }
518 else
519 {
521 stmt->setUInt32(0, accountId);
522 stmt->setUInt32(1, realmId);
523 trans->Append(stmt);
524 }
525
526 // Add new security level
527 if (securityLevel)
528 {
530 stmt->setUInt32(0, accountId);
531 stmt->setUInt8(1, securityLevel);
532 stmt->setInt32(2, realmId);
533 trans->Append(stmt);
534 }
535
536 LoginDatabase.CommitTransaction(trans);
537}
538
540{
541 TC_LOG_TRACE("rbac", "AccountMgr::GetRBACPermission: {}", permissionId);
542 rbac::RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId);
543 if (it != _permissions.end())
544 return it->second;
545
546 return nullptr;
547}
548
549bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 realmId)
550{
551 if (!accountId)
552 {
553 TC_LOG_ERROR("rbac", "AccountMgr::HasPermission: Wrong accountId 0");
554 return false;
555 }
556
557 rbac::RBACData rbac(accountId, "", realmId, GetSecurity(accountId, realmId));
558 rbac.LoadFromDB();
559 bool hasPermission = rbac.HasPermission(permissionId);
560
561 TC_LOG_DEBUG("rbac", "AccountMgr::HasPermission [AccountId: {}, PermissionId: {}, realmId: {}]: {}",
562 accountId, permissionId, realmId, hasPermission);
563 return hasPermission;
564}
565
567{
568 for (std::pair<uint32 const, rbac::RBACPermission*>& permission : _permissions)
569 delete permission.second;
570
571 _permissions.clear();
572 _defaultPermissions.clear();
573}
574
576{
577 TC_LOG_TRACE("rbac", "AccountMgr::GetRBACDefaultPermissions: secLevel {} - size: {}", secLevel, uint32(_defaultPermissions[secLevel].size()));
578 return _defaultPermissions[secLevel];
579}
#define MAX_ACCOUNT_STR
Definition AccountMgr.h:42
#define MAX_PASS_STR
Definition AccountMgr.h:41
#define MAX_EMAIL_STR
Definition AccountMgr.h:43
AccountOpResult
Definition AccountMgr.h:24
@ CHAR_DEL_CHARACTER_BAN
@ CHAR_DEL_TUTORIALS
@ CHAR_SEL_SUM_CHARS
@ CHAR_DEL_ACCOUNT_DATA
@ CHAR_SEL_CHARS_BY_ACCOUNT_ID
@ CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES
@ SEC_PLAYER
Definition Common.h:40
@ SEC_ADMINISTRATOR
Definition Common.h:43
@ SEC_CONSOLE
Definition Common.h:44
SQLTransaction< LoginDatabaseConnection > LoginDatabaseTransaction
std::shared_ptr< ResultSet > QueryResult
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define TC_LOG_TRACE(filterType__,...)
Definition Log.h:153
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
@ LOGIN_GET_EMAIL_BY_ID
@ LOGIN_UPD_EMAIL
@ LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM
@ LOGIN_GET_ACCOUNT_ID_BY_USERNAME
@ LOGIN_UPD_REG_EMAIL
@ LOGIN_SEL_ACCOUNT_BY_ID
@ LOGIN_DEL_ACCOUNT_MUTED
@ LOGIN_DEL_ACCOUNT_BANNED
@ LOGIN_DEL_ACCOUNT_ACCESS
@ LOGIN_UPD_USERNAME
@ LOGIN_GET_GMLEVEL_BY_REALMID
@ LOGIN_UPD_LOGON
@ LOGIN_GET_USERNAME_BY_ID
@ LOGIN_DEL_ACCOUNT
@ LOGIN_INS_REALM_CHARACTERS_INIT
@ LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME
@ LOGIN_INS_ACCOUNT_ACCESS
@ LOGIN_DEL_REALM_CHARACTERS
@ LOGIN_SEL_CHECK_PASSWORD
@ LOGIN_INS_ACCOUNT
#define sScriptMgr
Definition ScriptMgr.h:1168
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
Definition Util.cpp:610
size_t utf8length(std::string &utf8str)
Definition Util.cpp:349
static AccountOpResult ChangeRegEmail(uint32 accountId, std::string newEmail)
AccountOpResult CreateAccount(std::string username, std::string password, std::string email="")
void LoadRBAC()
static AccountOpResult DeleteAccount(uint32 accountId)
static bool CheckPassword(uint32 accountId, std::string password)
rbac::RBACPermissionsContainer _permissions
Definition AccountMgr.h:92
static AccountOpResult ChangeEmail(uint32 accountId, std::string newEmail)
static uint32 GetSecurity(uint32 accountId, int32 realmId)
static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword)
static uint32 GetCharactersCount(uint32 accountId)
void UpdateAccountAccess(rbac::RBACData *rbac, uint32 accountId, uint8 securityLevel, int32 realmId)
static bool IsPlayerAccount(uint32 gmlevel)
void ClearRBAC()
static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword)
static QueryCallback GetSecurityAsync(uint32 accountId, int32 realmId, std::function< void(uint32)> callback)
static bool IsConsoleAccount(uint32 gmlevel)
static AccountMgr * instance()
rbac::RBACPermissionContainer const & GetRBACDefaultPermissions(uint8 secLevel)
static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId)
static bool GetEmail(uint32 accountId, std::string &email)
rbac::RBACDefaultPermissionsContainer _defaultPermissions
Definition AccountMgr.h:93
static bool CheckEmail(uint32 accountId, std::string newEmail)
static bool IsBannedAccount(std::string const &name)
rbac::RBACPermission const * GetRBACPermission(uint32 permission) const
static bool IsAdminAccount(uint32 gmlevel)
static uint32 GetId(std::string_view username)
static bool GetName(uint32 accountId, std::string &name)
Class used to access individual fields of database query result.
Definition Field.h:92
uint32 GetUInt32() const
Definition Field.cpp:61
static void DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRealmChars=true, bool deleteFinally=false)
Definition Player.cpp:3885
void setUInt32(uint8 index, uint32 value)
void setStringView(uint8 index, std::string_view value)
void setInt32(uint8 index, int32 value)
void setUInt8(uint8 index, uint8 value)
void setBinary(uint8 index, std::vector< uint8 > const &value)
void setString(uint8 index, std::string const &value)
static constexpr size_t SALT_LENGTH
Definition SRP6.h:34
static constexpr size_t VERIFIER_LENGTH
Definition SRP6.h:36
std::array< uint8, SALT_LENGTH > Salt
Definition SRP6.h:35
static std::pair< Salt, Verifier > MakeRegistrationData(std::string const &username, std::string const &password)
Definition SRP6.cpp:32
std::array< uint8, VERIFIER_LENGTH > Verifier
Definition SRP6.h:37
static bool CheckLogin(std::string const &username, std::string const &password, Salt const &salt, Verifier const &verifier)
Definition SRP6.h:47
Player session in the World.
void LogoutPlayer(bool save)
Log the player out
void KickPlayer(std::string const &reason)
Kick a player out of the World.
void AddLinkedPermission(uint32 id)
Adds a new linked Permission.
Definition RBAC.h:784
Realm realm
Definition World.cpp:3605
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
std::set< uint32 > RBACPermissionContainer
Definition RBAC.h:768
uint32 Realm
Definition Realm.h:44
RealmHandle Id
Definition Realm.h:67