TrinityCore
Loading...
Searching...
No Matches
WorldSession.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
22#include "WorldSession.h"
23#include "AccountMgr.h"
24#include "AddonMgr.h"
25#include "BattlegroundMgr.h"
26#include "CharacterPackets.h"
27#include "ClientConfigPackets.h"
28#include "Config.h"
29#include "Common.h"
30#include "Containers.h"
31#include "DatabaseEnv.h"
32#include "DBCStructure.h"
33#include "GameClient.h"
34#include "GameTime.h"
35#include "Group.h"
36#include "Guild.h"
37#include "GuildMgr.h"
38#include "Hyperlinks.h"
39#include "Log.h"
40#include "Map.h"
41#include "Metric.h"
42#include "MiscPackets.h"
43#include "MovementPackets.h"
44#include "MoveSpline.h"
45#include "ObjectAccessor.h"
46#include "ObjectMgr.h"
47#include "Opcodes.h"
48#include "OutdoorPvPMgr.h"
49#include "PacketUtilities.h"
50#include "Player.h"
51#include "Realm.h"
52#include "ScriptMgr.h"
53#include "SocialMgr.h"
54#include "QueryHolder.h"
55#include "Vehicle.h"
56#include "WardenMac.h"
57#include "WardenWin.h"
58#include "World.h"
59#include "WorldPacket.h"
60#include "WorldSocket.h"
61#include <boost/circular_buffer.hpp>
62#include <zlib.h>
63
64namespace {
65
66std::string const DefaultPlayerName = "<none>";
67
68} // namespace
69
71{
72 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
73
74 //let's check if our opcode can be really processed in Map::Update()
75 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
76 return true;
77
78 //we do not process thread-unsafe packets
80 return false;
81
82 Player* player = m_pSession->GetPlayer();
83 if (!player)
84 return false;
85
86 //in Map::Update() we do not process packets where player is not in world!
87 return player->IsInWorld();
88}
89
90//we should process ALL packets when player is not in world/logged in
91//OR packet handler is not thread-safe!
93{
94 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
95
96 //check if packet handler is supposed to be safe
97 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
98 return true;
99
100 //thread-unsafe packets should be processed in World::UpdateSessions()
101 if (opHandle->ProcessingPlace == PROCESS_THREADUNSAFE)
102 return true;
103
104 //no player attached? -> our client! ^^
105 Player* player = m_pSession->GetPlayer();
106 if (!player)
107 return true;
108
109 //lets process all packets for non-in-the-world player
110 return (player->IsInWorld() == false);
111}
112
114WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
115 Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
116 m_muteTime(mute_time),
117 m_timeOutTime(0),
118 AntiDOS(this),
119 m_GUIDLow(0),
120 _player(nullptr),
121 m_Socket(std::move(sock)),
122 _security(sec),
123 _accountId(id),
124 _accountName(std::move(name)),
125 m_expansion(expansion),
126 _logoutTime(0),
127 m_inQueue(false),
128 m_playerLoading(false),
129 m_playerLogout(false),
130 m_playerRecentlyLogout(false),
131 m_playerSave(false),
132 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
133 m_sessionDbLocaleIndex(locale),
134 _timezoneOffset(timezoneOffset),
135 m_latency(0),
136 _tutorials(),
137 _tutorialsChanged(TUTORIALS_FLAG_NONE),
138 recruiterId(recruiter),
139 isRecruiter(isARecruiter),
140 _RBACData(nullptr),
141 expireTime(60000), // 1 min after socket loss, session is deleted
142 forceExit(false),
143 m_currentBankerGUID(),
144 _timeSyncClockDeltaQueue(std::make_unique<boost::circular_buffer<std::pair<int64, uint32>>>(6)),
145 _timeSyncClockDelta(0),
146 _pendingTimeSyncRequests(),
147 _timeSyncNextCounter(0),
148 _timeSyncTimer(0),
149 _calendarEventCreationCooldown(0),
150 _gameClient(new GameClient(this))
151{
152 if (m_Socket)
153 {
154 m_Address = m_Socket->GetRemoteIpAddress().to_string();
155 ResetTimeOutTime(false);
156 LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
157 }
158
159}
160
163{
165 if (_player)
166 LogoutPlayer (true);
167
169 if (m_Socket)
170 {
171 m_Socket->CloseSocket();
172 m_Socket = nullptr;
173 }
174
175 delete _RBACData;
176
177 delete _gameClient;
178
180 WorldPacket* packet = nullptr;
181 while (_recvQueue.next(packet))
182 delete packet;
183
184 LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
185}
186
187std::string const & WorldSession::GetPlayerName() const
188{
189 return _player != nullptr ? _player->GetName() : DefaultPlayerName;
190}
191
193{
194 if (_player)
195 return Trinity::StringFormat("[Player: {} {}, Account: {}]", _player->GetName(), _player->GetGUID(), GetAccountId());
196
197 if (m_playerLoading)
198 return Trinity::StringFormat("[Player: Logging in, Account: {}]", GetAccountId());
199
200 return Trinity::StringFormat("[Player: Account: {}]", GetAccountId());
201}
202
205{
206 ASSERT(packet->GetOpcode() != NULL_OPCODE);
207
208 if (!m_Socket)
209 return;
210
211#ifdef TRINITY_DEBUG
212 // Code for network use statistic
213 static uint64 sendPacketCount = 0;
214 static uint64 sendPacketBytes = 0;
215
216 static time_t firstTime = time(nullptr);
217 static time_t lastTime = firstTime; // next 60 secs start time
218
219 static uint64 sendLastPacketCount = 0;
220 static uint64 sendLastPacketBytes = 0;
221
222 time_t cur_time = time(nullptr);
223
224 if ((cur_time - lastTime) < 60)
225 {
226 sendPacketCount += 1;
227 sendPacketBytes += packet->size();
228
229 sendLastPacketCount += 1;
230 sendLastPacketBytes += packet->size();
231 }
232 else
233 {
234 uint64 minTime = uint64(cur_time - lastTime);
235 uint64 fullTime = uint64(lastTime - firstTime);
236 TC_LOG_DEBUG("misc", "Send all time packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {} time: {}", sendPacketCount, sendPacketBytes, float(sendPacketCount)/fullTime, float(sendPacketBytes)/fullTime, uint32(fullTime));
237 TC_LOG_DEBUG("misc", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount)/minTime, float(sendLastPacketBytes)/minTime);
238
239 lastTime = cur_time;
240 sendLastPacketCount = 1;
241 sendLastPacketBytes = packet->wpos(); // wpos is real written size
242 }
243#endif // !TRINITY_DEBUG
244
245 sScriptMgr->OnPacketSend(this, *packet);
246
247 TC_LOG_TRACE("network.opcode", "S->C: {} {}", GetPlayerInfo(), GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())));
248 m_Socket->SendPacket(*packet);
249}
250
253{
254 _recvQueue.add(new_packet);
255}
256
258void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, char const* status, const char *reason)
259{
260 TC_LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
261 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
262}
263
266{
267 if (!sLog->ShouldLog("network.opcode", LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
268 return;
269
270 TC_LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
271 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
272 packet->print_storage();
273}
274
277{
282 m_Socket->CloseSocket();
283
286 WorldPacket* packet = nullptr;
288 bool deletePacket = true;
289 std::vector<WorldPacket*> requeuePackets;
290 uint32 processedPackets = 0;
291 time_t currentTime = GameTime::GetGameTime();
292
293 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 100;
294
295 while (m_Socket && _recvQueue.next(packet, updater))
296 {
297 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
298 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
299 TC_METRIC_DETAILED_TIMER("worldsession_update_opcode_time", TC_METRIC_TAG("opcode", opHandle->Name));
300
301 try
302 {
303 switch (opHandle->Status)
304 {
305 case STATUS_LOGGEDIN:
306 if (!_player)
307 {
308 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
312 {
313 requeuePackets.push_back(packet);
314 deletePacket = false;
315 TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode {} with with status STATUS_LOGGEDIN. "
316 "Player is currently not in world yet.", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())));
317 }
318 }
319 else if (_player->IsInWorld())
320 {
321 if(AntiDOS.EvaluateOpcode(*packet, currentTime))
322 {
323 sScriptMgr->OnPacketReceive(this, *packet);
324 opHandle->Call(this, *packet);
325 LogUnprocessedTail(packet);
326 }
327 else
328 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
329 }
330 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
331 break;
333 if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
334 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
335 "the player has not logged in yet and not recently logout");
336 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
337 {
338 // not expected _player or must checked in packet hanlder
339 sScriptMgr->OnPacketReceive(this, *packet);
340 opHandle->Call(this, *packet);
341 LogUnprocessedTail(packet);
342 }
343 else
344 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
345 break;
346 case STATUS_TRANSFER:
347 if (!_player)
348 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
349 else if (_player->IsInWorld())
350 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
351 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
352 {
353 sScriptMgr->OnPacketReceive(this, *packet);
354 opHandle->Call(this, *packet);
355 LogUnprocessedTail(packet);
356 }
357 else
358 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
359 break;
360 case STATUS_AUTHED:
361 // prevent cheating with skip queue wait
362 if (m_inQueue)
363 {
364 LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
365 break;
366 }
367
368 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
369 // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
370 if (packet->GetOpcode() == CMSG_CHAR_ENUM)
372
373 if (AntiDOS.EvaluateOpcode(*packet, currentTime))
374 {
375 sScriptMgr->OnPacketReceive(this, *packet);
376 opHandle->Call(this, *packet);
377 LogUnprocessedTail(packet);
378 }
379 else
380 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
381 break;
382 case STATUS_NEVER:
383 TC_LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode()))
384 , GetPlayerInfo());
385 break;
386 case STATUS_UNHANDLED:
387 TC_LOG_DEBUG("network.opcode", "Received not handled opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode()))
388 , GetPlayerInfo());
389 break;
390 }
391 }
393 {
394 TC_LOG_ERROR("network", "{} sent {} with an invalid link:\n{}", GetPlayerInfo(),
395 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
396
398 KickPlayer("WorldSession::Update Invalid chat link");
399 }
401 {
402 TC_LOG_ERROR("network", "{} sent {} which illegally contained a hyperlink:\n{}", GetPlayerInfo(),
403 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
404
406 KickPlayer("WorldSession::Update Illegal chat link");
407 }
409 {
410 TC_LOG_ERROR("network", "PacketArrayMaxCapacityException: {} while parsing {} from {}.",
411 pamce.what(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
412 }
413 catch (ByteBufferException const&)
414 {
415 TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: {}) from client {}, accountid={}. Skipped packet.",
416 packet->GetOpcode(), GetRemoteAddress(), GetAccountId());
417 packet->hexlike();
418 }
419
420 if (deletePacket)
421 delete packet;
422
423 deletePacket = true;
424
425 processedPackets++;
426
427 //process only a max amout of packets in 1 Update() call.
428 //Any leftover will be processed in next update
429 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
430 break;
431 }
432
433 TC_METRIC_VALUE("processed_packets", processedPackets);
434
435 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
436
437 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
438 {
439 // Send time sync packet every 10s.
440 if (_timeSyncTimer > 0)
441 {
442 if (diff >= _timeSyncTimer)
443 SendTimeSync();
444 else
445 _timeSyncTimer -= diff;
446 }
447 }
448
450
451 //check if we are safe to proceed with logout
452 //logout procedure should happen only in World::UpdateSessions() method!!!
453 if (updater.ProcessUnsafe())
454 {
455 if (m_Socket && m_Socket->IsOpen() && _warden)
456 _warden->Update(diff);
457
459 if (ShouldLogOut(currentTime) && !m_playerLoading)
460 LogoutPlayer(true);
461
463 if (m_Socket && !m_Socket->IsOpen())
464 {
465 if (GetPlayer() && _warden)
466 _warden->Update(diff);
467
468 expireTime -= expireTime > diff ? diff : expireTime;
469 if (expireTime < diff || forceExit || !GetPlayer())
470 {
471 m_Socket = nullptr;
472 }
473 }
474
475 if (!m_Socket)
476 return false; //Will remove this session from the world session map
477 }
478
479 return true;
480}
481
484{
485 // finish pending transfers before starting the logout
488
489 m_playerLogout = true;
490 m_playerSave = save;
491
492 if (_player)
493 {
494 ObjectGuid lguid = _player->GetLootGUID();
495 if (!lguid.IsEmpty())
496 DoLootRelease(lguid);
497
499 if (_player->GetDeathTimer())
500 {
504 }
506 {
507 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
512 }
513 else if (_player->HasPendingBind())
514 {
516 _player->SetPendingBind(0, 0);
517 }
518
519 //drop a flag if player is carrying it
521 bg->EventPlayerLoggedOut(_player);
522
523 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
524
525 for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
526 {
528 if (bgQueueTypeId != BATTLEGROUND_QUEUE_NONE)
529 {
530 // track if player logs out after invited to join BG
532 {
534 stmt->setUInt32(0, _player->GetGUID().GetCounter());
536 CharacterDatabase.Execute(stmt);
537 }
538
539 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
540 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
541 queue.RemovePlayer(_player->GetGUID(), true);
542 }
543 }
544
545 // Repop at Graveyard or other player far teleport will prevent saving player because of not present map
546 // Teleport player immediately for correct player save
549
551 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
552 guild->HandleMemberLogout(this);
553
556
559
561 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
562 if (save)
563 {
564 uint32 eslot;
565 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
566 {
567 eslot = j - BUYBACK_SLOT_START;
571 }
572 _player->SaveToDB();
573 }
574
577
580
582 if (Group* group = _player->GetGroup())
583 {
584 group->SendUpdate();
585 group->ResetMaxEnchantingLevel();
586 if (group->GetLeaderGUID() == _player->GetGUID())
587 group->StartLeaderOfflineTimer();
588 }
589
591 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
593
595 sScriptMgr->OnPlayerLogout(_player);
596
597 TC_METRIC_EVENT("player_events", "Logout", _player->GetName());
598
600 // the player may not be in the world when logging out
601 // e.g if he got disconnected during a transfer to another map
602 // calls to GetMap in this case may cause crashes
604 TC_LOG_INFO("entities.player.character", "Account: {} (IP: {}) Logout Character:[{}] {} Level: {}, XP: {}/{} ({} left)",
607 if (Map* _map = _player->FindMap())
608 _map->RemovePlayerFromMap(_player, true);
609
610 SetPlayer(nullptr);
611
615 TC_LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
616
619 stmt->setUInt32(0, GetAccountId());
620 CharacterDatabase.Execute(stmt);
621 }
622
623 m_playerLogout = false;
624 m_playerSave = false;
627}
628
630void WorldSession::KickPlayer(std::string const& reason)
631{
632 if (m_Socket)
633 {
634 TC_LOG_INFO("network.kick", "Account: {} Character: '{}' {} kicked with reason: {}", GetAccountId(), _player ? _player->GetName() : "<none>",
635 _player ? _player->GetGUID().ToString() : "", reason);
636
637 m_Socket->CloseSocket();
638 forceExit = true;
639 }
640}
641
643{
645 return true;
646
647 TC_LOG_ERROR("network", "Player {}{} sent a message with an invalid link:\n{}", GetPlayer()->GetName(),
648 GetPlayer()->GetGUID().ToString(), str);
649
651 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
652
653 return false;
654}
655
657{
658 if (str.find('|') == std::string::npos)
659 return true;
660
661 TC_LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n{}", GetPlayer()->GetName(),
662 GetPlayer()->GetGUID().ToString(), str);
663
665 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
666
667 return false;
668}
669
670void WorldSession::SendNotification(char const* format, ...)
671{
672 if (format)
673 {
674 va_list ap;
675 char szStr[1024];
676 szStr[0] = '\0';
677 va_start(ap, format);
678 vsnprintf(szStr, 1024, format, ap);
679 va_end(ap);
680
681 WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1));
682 data << szStr;
683 SendPacket(&data);
684 }
685}
686
688{
689 char const* format = GetTrinityString(stringId);
690 if (format)
691 {
692 va_list ap;
693 char szStr[1024];
694 szStr[0] = '\0';
695 va_start(ap, stringId);
696 vsnprintf(szStr, 1024, format, ap);
697 va_end(ap);
698
699 WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1));
700 data << szStr;
701 SendPacket(&data);
702 }
703}
704
706{
708}
709
711{
712 return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex());
713}
714
716{
717 if (GetPlayer())
719 else if (!onlyActive)
721}
722
727
729{
730 TC_LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(null.GetOpcode())), GetPlayerInfo());
731}
732
734{
735 TC_LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}"
736 , GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
737}
738
740{
741 TC_LOG_ERROR("network.opcode", "Received server-side opcode {} from {}"
742 , GetOpcodeNameForLogging(static_cast<OpcodeServer>(recvPacket.GetOpcode())), GetPlayerInfo());
743}
744
746{
747 if (position == 0)
748 {
750 packet << uint8(AUTH_OK);
751 SendPacket(&packet);
752 }
753 else
754 {
756 packet << uint8(AUTH_WAIT_QUEUE);
757 packet << uint32(position);
758 packet << uint8(0); // unk
759 SendPacket(&packet);
760 }
761}
762
764{
765 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
766 if (mask & (1 << i))
768
769 if (!result)
770 return;
771
772 do
773 {
774 Field* fields = result->Fetch();
775 uint32 type = fields[0].GetUInt8();
776 if (type >= NUM_ACCOUNT_DATA_TYPES)
777 {
778 TC_LOG_ERROR("misc", "Table `{}` have invalid account data type ({}), ignore.",
779 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
780 continue;
781 }
782
783 if ((mask & (1 << type)) == 0)
784 {
785 TC_LOG_ERROR("misc", "Table `{}` have non appropriate for table account data type ({}), ignore.",
786 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
787 continue;
788 }
789
790 _accountData[type].Time = time_t(fields[1].GetUInt32());
791 _accountData[type].Data = fields[2].GetString();
792 }
793 while (result->NextRow());
794}
795
796void WorldSession::SetAccountData(AccountDataType type, time_t time, std::string const& data)
797{
798 uint32 id = 0;
800 if ((1 << type) & GLOBAL_CACHE_MASK)
801 {
802 id = GetAccountId();
803 index = CHAR_REP_ACCOUNT_DATA;
804 }
805 else
806 {
807 // _player can be NULL and packet received after logout but m_GUID still store correct guid
808 if (!m_GUIDLow)
809 return;
810
811 id = m_GUIDLow;
813 }
814
815 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
816 stmt->setUInt32(0, id);
817 stmt->setUInt8 (1, type);
818 stmt->setUInt32(2, uint32(time));
819 stmt->setString(3, data);
820 CharacterDatabase.Execute(stmt);
821
822 _accountData[type].Time = time;
823 _accountData[type].Data = data;
824}
825
827{
829 data << uint32(GameTime::GetGameTime()); // Server time
830 data << uint8(1);
831 data << uint32(mask); // type mask
832 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
833 if (mask & (1 << i))
834 data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
835 SendPacket(&data);
836}
837
839{
840 _tutorials = { };
841
842 if (result)
843 {
844 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
845 _tutorials[i] = (*result)[i].GetUInt32();
847 }
848
849 _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
850}
851
858
860{
862 return;
863
864 bool const hasTutorialsInDB = (_tutorialsChanged & TUTORIALS_FLAG_LOADED_FROM_DB) != 0;
865 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(hasTutorialsInDB ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
866 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
867 stmt->setUInt32(i, _tutorials[i]);
869 trans->Append(stmt);
870
871 // now has, set flag so next save uses update query
872 if (!hasTutorialsInDB)
874
875 _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
876}
877
879{
880 if (!result)
881 return;
882
884 do
885 {
886 Field* fields = result->Fetch();
887 SystemTimePoint restrictionExpireTime = SystemTimePoint::clock::from_time_t(fields[1].GetUInt64());
888 if (restrictionExpireTime > now)
889 _instanceResetTimes.try_emplace(fields[0].GetUInt32(), restrictionExpireTime);
890 } while (result->NextRow());
891}
892
894{
895 if (_instanceResetTimes.empty())
896 return;
897
899 stmt->setUInt32(0, GetAccountId());
900 trans->Append(stmt);
901
902 for (auto const& [instanceId, restrictionExpireTime] : _instanceResetTimes)
903 {
904 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES);
905 stmt->setUInt32(0, GetAccountId());
906 stmt->setUInt32(1, instanceId);
907 stmt->setUInt64(2, SystemTimePoint::clock::to_time_t(restrictionExpireTime));
908 trans->Append(stmt);
909 }
910}
911
913{
915
916 if (_instanceResetTimes.size() < sWorld->getIntConfig(CONFIG_MAX_INSTANCES_PER_HOUR))
917 return true;
918
919 if (instanceId == 0)
920 return false;
921
922 return _instanceResetTimes.contains(instanceId);
923}
924
926{
927 _instanceResetTimes.try_emplace(instanceId, enterTime + 1h);
928}
929
931{
932 Trinity::Containers::EraseIf(_instanceResetTimes, [now = GameTime::GetSystemTime()](std::pair<uint32 const, SystemTimePoint> const& value)
933 {
934 return value.second < now;
935 });
936}
937
939{
940 data >> *mi;
941 if (mi->guid.IsEmpty())
942 {
943 TC_LOG_ERROR("entities.unit", "WorldSession::ReadMovementInfo: mi->guid is empty, opcode {}", static_cast<uint32>(data.GetOpcode()));
944 return;
945 }
946
947 Unit* mover = ValidateAndGetUnitBeingMoved(mi->guid, static_cast<OpcodeClient>(data.GetOpcode()), true /*all remaining uses are ack handlers*/);
948 ValidateMovementInfo(mover, mi);
949}
950
952{
953 *data << mi->guid.WriteAsPacked();
954 *data << *mi;
955}
956
958{
959 if (data.rpos() + 4 > data.size())
960 return;
961
962 uint32 size;
963 data >> size;
964
965 if (!size)
966 return;
967
968 if (size > 0xFFFFF)
969 {
970 TC_LOG_DEBUG("addon", "WorldSession::ReadAddonsInfo: AddOnInfo too big, size {}", size);
971 return;
972 }
973
974 uLongf uSize = size;
975
976 uint32 pos = data.rpos();
977
978 ByteBuffer addonInfo;
979 addonInfo.resize(size);
980
981 _addons.SecureAddons.clear();
982
983 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
984 {
985 try
986 {
987 _addons.SecureAddons.resize(std::min(addonInfo.read<uint32>(), Addons::MaxSecureAddons));
988
990 {
991 uint32 publicKeyCrc, urlCrc;
992
993 addonInfo >> addon.Name >> addon.HasKey;
994 addonInfo >> publicKeyCrc >> urlCrc;
995
996 TC_LOG_DEBUG("addon", "AddOn: {} (CRC: 0x{:x}) - has key: 0x{:x} - URL CRC: 0x{:x}", addon.Name, publicKeyCrc, addon.HasKey, urlCrc);
997
998 if (SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addon.Name))
999 {
1000 if (publicKeyCrc != savedAddon->CRC)
1001 {
1002 if (addon.HasKey)
1003 {
1004 addon.Status = SecureAddonInfo::BANNED;
1005 TC_LOG_WARN("addon", " Addon: {}: modified (CRC: 0x{:x}) - accountID {})", addon.Name, savedAddon->CRC, GetAccountId());
1006 }
1007 else
1008 addon.Status = SecureAddonInfo::SECURE_HIDDEN;
1009 }
1010 else
1011 {
1012 addon.Status = SecureAddonInfo::SECURE_HIDDEN;
1013 TC_LOG_DEBUG("addon", "Addon: {}: validated (CRC: 0x{:x}) - accountID {}", addon.Name, savedAddon->CRC, GetAccountId());
1014 }
1015 }
1016 else
1017 {
1018 addon.Status = SecureAddonInfo::BANNED;
1019 TC_LOG_WARN("addon", "Addon: {}: not registered as known secure addon - accountId {}", addon.Name, GetAccountId());
1020 }
1021 }
1022
1023 addonInfo.rpos(addonInfo.size() - 4);
1024
1025 addonInfo >> _addons.LastBannedAddOnTimestamp;
1026 TC_LOG_DEBUG("addon", "AddOn: Newest banned addon timestamp: {}", _addons.LastBannedAddOnTimestamp);
1027 }
1028 catch (ByteBufferException const& e)
1029 {
1030 TC_LOG_DEBUG("addon", "AddOn: Addon packet read error! {}", e.what());
1031 }
1032 }
1033 else
1034 TC_LOG_DEBUG("addon", "AddOn: Addon packet uncompress error!");
1035}
1036
1038{
1039 // Send new uncached banned addons
1041 uint32 lastBannedAddOnTimestamp = _addons.LastBannedAddOnTimestamp;
1042 if (!bannedAddons->empty() && bannedAddons->back().Timestamp < lastBannedAddOnTimestamp) // cheating attempt OR connecting to a realm with different configured banned addons, send everything
1043 lastBannedAddOnTimestamp = 0;
1044
1045 auto itr = std::ranges::lower_bound(*bannedAddons, lastBannedAddOnTimestamp, std::ranges::less(), &BannedAddon::Timestamp);
1046
1048 addonInfo.Addons = _addons.SecureAddons;
1049 addonInfo.BannedAddons = { itr, bannedAddons->end() };
1050 SendPacket(addonInfo.Write());
1051}
1052
1054{
1055 _player = player;
1056
1057 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1058 if (_player)
1060}
1061
1068
1073
1078
1079void WorldSession::InitWarden(SessionKey const& k, std::string const& os)
1080{
1081 if (os == "Win")
1082 {
1083 _warden = std::make_unique<WardenWin>();
1084 _warden->Init(this, k);
1085 }
1086 else if (os == "OSX")
1087 {
1088 // Disabled as it is causing the client to crash
1089 // _warden = std::make_unique<WardenMac>();
1090 // _warden->Init(this, k);
1091 }
1092}
1093
1095{
1096 uint32 id = GetAccountId();
1097 uint8 secLevel = GetSecurity();
1098
1099 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1101}
1102
1104{
1105 uint32 id = GetAccountId();
1106 uint8 secLevel = GetSecurity();
1107
1108 TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1109 id, _accountName, realm.Id.Realm, secLevel);
1110
1111 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1112 return _RBACData->LoadFromDBAsync();
1113}
1114
1116{
1117public:
1118 enum
1119 {
1123
1126
1128
1129 bool Initialize(uint32 accountId)
1130 {
1131 bool ok = true;
1132
1134 stmt->setUInt32(0, accountId);
1135 ok = SetPreparedQuery(GLOBAL_ACCOUNT_DATA, stmt) && ok;
1136
1137 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS);
1138 stmt->setUInt32(0, accountId);
1139 ok = SetPreparedQuery(TUTORIALS, stmt) && ok;
1140
1141 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES);
1142 stmt->setUInt32(0, accountId);
1143 ok = SetPreparedQuery(INSTANCE_TIMES, stmt) && ok;
1144
1145 return ok;
1146 }
1147};
1148
1150{
1151 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1152 if (!realmHolder->Initialize(GetAccountId()))
1153 {
1155 return;
1156 }
1157
1158 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this](SQLQueryHolderBase const& holder)
1159 {
1160 InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm const&>(holder));
1161 });
1162}
1163
1182
1184{
1185 return _RBACData;
1186}
1187
1189{
1190 if (!_RBACData)
1192
1193 bool hasPermission = _RBACData->HasPermission(permission);
1194 TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: {}, Name: {}, realmId: {}]",
1196
1197 return hasPermission;
1198}
1199
1201{
1202 TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: {}, Name: {}, realmId: {}]",
1204 delete _RBACData;
1205 _RBACData = nullptr;
1206}
1207
1209{
1210 uint32 maxPacketCounterAllowed = GetMaxPacketCounterAllowed(p.GetOpcode());
1211
1212 // Return true if there no limit for the opcode
1213 if (!maxPacketCounterAllowed)
1214 return true;
1215
1216 PacketCounter& packetCounter = _PacketThrottlingMap[p.GetOpcode()];
1217 if (packetCounter.lastReceiveTime != time)
1218 {
1219 packetCounter.lastReceiveTime = time;
1220 packetCounter.amountCounter = 0;
1221 }
1222
1223 // Check if player is flooding some packets
1224 if (++packetCounter.amountCounter <= maxPacketCounterAllowed)
1225 return true;
1226
1227 TC_LOG_WARN("network", "AntiDOS: Account {}, IP: {}, Ping: {}, Character: {}, flooding packet (opc: {} (0x{:X}), count: {})",
1229 opcodeTable[static_cast<OpcodeClient>(p.GetOpcode())]->Name, p.GetOpcode(), packetCounter.amountCounter);
1230
1231 switch (_policy)
1232 {
1233 case POLICY_LOG:
1234 return true;
1235 case POLICY_KICK:
1236 {
1237 TC_LOG_WARN("network", "AntiDOS: Player kicked!");
1238 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1239 return false;
1240 }
1241 case POLICY_BAN:
1242 {
1244 uint32 duration = sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANDURATION); // in seconds
1245 std::string nameOrIp = "";
1246 switch (bm)
1247 {
1248 case BAN_CHARACTER: // not supported, ban account
1249 case BAN_ACCOUNT: (void)sAccountMgr->GetName(Session->GetAccountId(), nameOrIp); break;
1250 case BAN_IP: nameOrIp = Session->GetRemoteAddress(); break;
1251 }
1252 sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
1253 TC_LOG_WARN("network", "AntiDOS: Player automatically banned for {} seconds.", duration);
1254 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1255 return false;
1256 }
1257 default: // invalid policy
1258 return true;
1259 }
1260}
1261
1263{
1264 uint32 maxPacketCounterAllowed;
1265 switch (opcode)
1266 {
1267 // CPU usage sending 2000 packets/second on a 3.70 GHz 4 cores on Win x64
1268 // [% CPU mysqld] [%CPU worldserver RelWithDebInfo]
1269 case CMSG_PLAYER_LOGIN: // 0 0.5
1270 case CMSG_NAME_QUERY: // 0 1
1271 case CMSG_PET_NAME_QUERY: // 0 1
1272 case CMSG_NPC_TEXT_QUERY: // 0 1
1273 case CMSG_ATTACK_STOP: // 0 1
1274 case CMSG_QUERY_QUESTS_COMPLETED: // 0 1
1275 case CMSG_QUERY_TIME: // 0 1
1277 case CMSG_MOVE_TIME_SKIPPED: // 0 1
1278 case MSG_QUERY_NEXT_MAIL_TIME: // 0 1
1279 case CMSG_SET_SHEATHED: // 0 1
1280 case MSG_RAID_TARGET_UPDATE: // 0 1
1281 case CMSG_PLAYER_LOGOUT: // 0 1
1282 case CMSG_LOGOUT_REQUEST: // 0 1
1283 case CMSG_PET_RENAME: // 0 1
1284 case CMSG_QUESTGIVER_CANCEL: // 0 1
1286 case CMSG_COMPLETE_CINEMATIC: // 0 1
1287 case CMSG_BANKER_ACTIVATE: // 0 1
1288 case CMSG_BUY_BANK_SLOT: // 0 1
1289 case CMSG_OPT_OUT_OF_LOOT: // 0 1
1290 case CMSG_DUEL_ACCEPTED: // 0 1
1291 case CMSG_DUEL_CANCELLED: // 0 1
1292 case CMSG_CALENDAR_COMPLAIN: // 0 1
1293 case CMSG_QUEST_QUERY: // 0 1.5
1294 case CMSG_ITEM_QUERY_SINGLE: // 0 1.5
1295 case CMSG_ITEM_NAME_QUERY: // 0 1.5
1296 case CMSG_GAMEOBJECT_QUERY: // 0 1.5
1297 case CMSG_CREATURE_QUERY: // 0 1.5
1298 case CMSG_QUESTGIVER_STATUS_QUERY: // 0 1.5
1299 case CMSG_GUILD_QUERY: // 0 1.5
1300 case CMSG_ARENA_TEAM_QUERY: // 0 1.5
1301 case CMSG_TAXINODE_STATUS_QUERY: // 0 1.5
1302 case CMSG_TAXIQUERYAVAILABLENODES: // 0 1.5
1303 case CMSG_QUESTGIVER_QUERY_QUEST: // 0 1.5
1304 case CMSG_PAGE_TEXT_QUERY: // 0 1.5
1305 case MSG_QUERY_GUILD_BANK_TEXT: // 0 1.5
1306 case MSG_CORPSE_QUERY: // 0 1.5
1307 case MSG_MOVE_SET_FACING: // 0 1.5
1308 case CMSG_REQUEST_PARTY_MEMBER_STATS: // 0 1.5
1309 case CMSG_QUESTGIVER_COMPLETE_QUEST: // 0 1.5
1310 case CMSG_SET_ACTION_BUTTON: // 0 1.5
1311 case CMSG_RESET_INSTANCES: // 0 1.5
1312 case CMSG_HEARTH_AND_RESURRECT: // 0 1.5
1313 case CMSG_TOGGLE_PVP: // 0 1.5
1314 case CMSG_PET_ABANDON: // 0 1.5
1315 case CMSG_ACTIVATETAXIEXPRESS: // 0 1.5
1316 case CMSG_ACTIVATETAXI: // 0 1.5
1317 case CMSG_SELF_RES: // 0 1.5
1318 case CMSG_UNLEARN_SKILL: // 0 1.5
1319 case CMSG_EQUIPMENT_SET_SAVE: // 0 1.5
1320 case CMSG_DELETEEQUIPMENT_SET: // 0 1.5
1321 case CMSG_DISMISS_CRITTER: // 0 1.5
1322 case CMSG_REPOP_REQUEST: // 0 1.5
1323 case CMSG_GROUP_INVITE: // 0 1.5
1324 case CMSG_GROUP_DECLINE: // 0 1.5
1325 case CMSG_GROUP_ACCEPT: // 0 1.5
1326 case CMSG_GROUP_UNINVITE_GUID: // 0 1.5
1327 case CMSG_GROUP_UNINVITE: // 0 1.5
1328 case CMSG_GROUP_DISBAND: // 0 1.5
1329 case CMSG_BATTLEMASTER_JOIN_ARENA: // 0 1.5
1330 case CMSG_LEAVE_BATTLEFIELD: // 0 1.5
1331 case MSG_GUILD_BANK_LOG_QUERY: // 0 2
1332 case CMSG_LOGOUT_CANCEL: // 0 2
1333 case CMSG_REALM_SPLIT: // 0 2
1334 case CMSG_ALTER_APPEARANCE: // 0 2
1335 case CMSG_QUEST_CONFIRM_ACCEPT: // 0 2
1336 case MSG_GUILD_EVENT_LOG_QUERY: // 0 2.5
1339 case CMSG_BEGIN_TRADE: // 0 2.5
1340 case CMSG_INITIATE_TRADE: // 0 3
1341 case CMSG_MESSAGECHAT: // 0 3.5
1342 case CMSG_INSPECT: // 0 3.5
1343 case CMSG_AREA_SPIRIT_HEALER_QUERY: // not profiled
1344 case CMSG_STANDSTATECHANGE: // not profiled
1345 case MSG_RANDOM_ROLL: // not profiled
1346 case CMSG_TIME_SYNC_RESP: // not profiled
1347 case CMSG_TRAINER_BUY_SPELL: // not profiled
1348 case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: // not profiled
1349 case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: // not profiled
1350 case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: // not profiled
1351 case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: // not profiled
1352 case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: // not profiled
1353 case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: // not profiled
1354 case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: // not profiled
1355 case CMSG_FORCE_TURN_RATE_CHANGE_ACK: // not profiled
1356 case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: // not profiled
1357 {
1358 // "0" is a magic number meaning there's no limit for the opcode.
1359 // All the opcodes above must cause little CPU usage and no sync/async database queries at all
1360 maxPacketCounterAllowed = 0;
1361 break;
1362 }
1363
1364 case CMSG_QUESTGIVER_ACCEPT_QUEST: // 0 4
1365 case CMSG_QUESTLOG_REMOVE_QUEST: // 0 4
1367 case CMSG_CONTACT_LIST: // 0 5
1368 case CMSG_LEARN_PREVIEW_TALENTS: // 0 6
1369 case CMSG_AUTOBANK_ITEM: // 0 6
1370 case CMSG_AUTOSTORE_BANK_ITEM: // 0 6
1371 case CMSG_WHO: // 0 7
1372 case CMSG_PLAYER_VEHICLE_ENTER: // 0 8
1373 case CMSG_LEARN_PREVIEW_TALENTS_PET: // not profiled
1374 case MSG_MOVE_HEARTBEAT:
1375 {
1376 maxPacketCounterAllowed = 200;
1377 break;
1378 }
1379
1380 case CMSG_GUILD_SET_PUBLIC_NOTE: // 1 2 1 async db query
1381 case CMSG_GUILD_SET_OFFICER_NOTE: // 1 2 1 async db query
1382 case CMSG_SET_CONTACT_NOTES: // 1 2.5 1 async db query
1383 case CMSG_CALENDAR_GET_CALENDAR: // 0 1.5 medium upload bandwidth usage
1384 case CMSG_GUILD_BANK_QUERY_TAB: // 0 3.5 medium upload bandwidth usage
1385 case CMSG_QUERY_INSPECT_ACHIEVEMENTS: // 0 13 high upload bandwidth usage
1386 case CMSG_GAMEOBJ_REPORT_USE: // not profiled
1387 case CMSG_GAMEOBJ_USE: // not profiled
1388 case MSG_PETITION_DECLINE: // not profiled
1389 {
1390 maxPacketCounterAllowed = 50;
1391 break;
1392 }
1393
1394 case CMSG_QUEST_POI_QUERY: // 0 25 very high upload bandwidth usage
1395 {
1396 maxPacketCounterAllowed = MAX_QUEST_LOG_SIZE;
1397 break;
1398 }
1399
1400 case CMSG_GM_REPORT_LAG: // 1 3 1 async db query
1401 case CMSG_SPELLCLICK: // not profiled
1402 case CMSG_REMOVE_GLYPH: // not profiled
1403 case CMSG_DISMISS_CONTROLLED_VEHICLE: // not profiled
1404 {
1405 maxPacketCounterAllowed = 20;
1406 break;
1407 }
1408
1409 case CMSG_PETITION_SIGN: // 9 4 2 sync 1 async db queries
1410 case CMSG_TURN_IN_PETITION: // 8 5.5 2 sync db query
1411 case CMSG_GROUP_CHANGE_SUB_GROUP: // 6 5 1 sync 1 async db queries
1412 case CMSG_PETITION_QUERY: // 4 3.5 1 sync db query
1413 case CMSG_CHAR_RACE_CHANGE: // 5 4 1 sync db query
1414 case CMSG_CHAR_CUSTOMIZE: // 5 5 1 sync db query
1415 case CMSG_CHAR_FACTION_CHANGE: // 5 5 1 sync db query
1416 case CMSG_CHAR_DELETE: // 4 4 1 sync db query
1417 case CMSG_DEL_FRIEND: // 7 5 1 async db query
1418 case CMSG_ADD_FRIEND: // 6 4 1 async db query
1419 case CMSG_CHAR_RENAME: // 5 3 1 async db query
1420 case CMSG_GMSURVEY_SUBMIT: // 2 3 1 async db query
1421 case CMSG_BUG: // 1 1 1 async db query
1422 case CMSG_GROUP_SET_LEADER: // 1 2 1 async db query
1423 case CMSG_GROUP_RAID_CONVERT: // 1 5 1 async db query
1424 case CMSG_GROUP_ASSISTANT_LEADER: // 1 2 1 async db query
1425 case CMSG_PETITION_BUY: // not profiled 1 sync 1 async db queries
1426 case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: // not profiled
1427 case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled
1428 case CMSG_REQUEST_VEHICLE_NEXT_SEAT: // not profiled
1429 case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: // not profiled
1430 case CMSG_REQUEST_VEHICLE_EXIT: // not profiled
1431 case CMSG_CONTROLLER_EJECT_PASSENGER: // not profiled
1432 case CMSG_ITEM_REFUND: // not profiled
1433 case CMSG_SOCKET_GEMS: // not profiled
1434 case CMSG_WRAP_ITEM: // not profiled
1435 case CMSG_REPORT_PVP_AFK: // not profiled
1436 {
1437 maxPacketCounterAllowed = 10;
1438 break;
1439 }
1440
1441 case CMSG_CHAR_CREATE: // 7 5 3 async db queries
1442 case CMSG_CHAR_ENUM: // 22 3 2 async db queries
1443 case CMSG_GMTICKET_CREATE: // 1 25 1 async db query
1444 case CMSG_GMTICKET_UPDATETEXT: // 0 15 1 async db query
1445 case CMSG_GMTICKET_DELETETICKET: // 1 25 1 async db query
1446 case CMSG_GMRESPONSE_RESOLVE: // 1 25 1 async db query
1447 case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query
1448 case CMSG_CALENDAR_UPDATE_EVENT: // not profiled
1449 case CMSG_CALENDAR_REMOVE_EVENT: // not profiled
1450 case CMSG_CALENDAR_COPY_EVENT: // not profiled
1451 case CMSG_CALENDAR_EVENT_INVITE: // not profiled
1452 case CMSG_CALENDAR_EVENT_SIGNUP: // not profiled
1453 case CMSG_CALENDAR_EVENT_RSVP: // not profiled
1454 case CMSG_CALENDAR_EVENT_REMOVE_INVITE: // not profiled
1455 case CMSG_CALENDAR_EVENT_MODERATOR_STATUS: // not profiled
1456 case CMSG_ARENA_TEAM_INVITE: // not profiled
1457 case CMSG_ARENA_TEAM_ACCEPT: // not profiled
1458 case CMSG_ARENA_TEAM_DECLINE: // not profiled
1459 case CMSG_ARENA_TEAM_LEAVE: // not profiled
1460 case CMSG_ARENA_TEAM_DISBAND: // not profiled
1461 case CMSG_ARENA_TEAM_REMOVE: // not profiled
1462 case CMSG_ARENA_TEAM_LEADER: // not profiled
1463 case CMSG_LOOT_METHOD: // not profiled
1464 case CMSG_GUILD_INVITE: // not profiled
1465 case CMSG_GUILD_ACCEPT: // not profiled
1466 case CMSG_GUILD_DECLINE: // not profiled
1467 case CMSG_GUILD_LEAVE: // not profiled
1468 case CMSG_GUILD_DISBAND: // not profiled
1469 case CMSG_GUILD_LEADER: // not profiled
1470 case CMSG_GUILD_MOTD: // not profiled
1471 case CMSG_GUILD_RANK: // not profiled
1472 case CMSG_GUILD_ADD_RANK: // not profiled
1473 case CMSG_GUILD_DEL_RANK: // not profiled
1474 case CMSG_GUILD_INFO_TEXT: // not profiled
1475 case CMSG_GUILD_BANK_DEPOSIT_MONEY: // not profiled
1476 case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
1477 case CMSG_GUILD_BANK_BUY_TAB: // not profiled
1478 case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
1479 case CMSG_SET_GUILD_BANK_TEXT: // not profiled
1480 case MSG_SAVE_GUILD_EMBLEM: // not profiled
1481 case MSG_PETITION_RENAME: // not profiled
1482 case MSG_TALENT_WIPE_CONFIRM: // not profiled
1483 case MSG_SET_DUNGEON_DIFFICULTY: // not profiled
1484 case MSG_SET_RAID_DIFFICULTY: // not profiled
1485 case MSG_PARTY_ASSIGNMENT: // not profiled
1486 case MSG_RAID_READY_CHECK: // not profiled
1487 {
1488 maxPacketCounterAllowed = 3;
1489 break;
1490 }
1491
1492 case CMSG_ITEM_REFUND_INFO: // not profiled
1493 {
1494 maxPacketCounterAllowed = PLAYER_SLOTS_COUNT;
1495 break;
1496 }
1497 default:
1498 {
1499 maxPacketCounterAllowed = 100;
1500 break;
1501 }
1502 }
1503
1504 return maxPacketCounterAllowed;
1505}
1506
1510
1516
1518{
1520 timeSyncRequest.SequenceIndex = _timeSyncNextCounter;
1521 SendPacket(timeSyncRequest.Write());
1522
1524
1525 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1526 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1528}
#define sAccountMgr
Definition AccountMgr.h:97
std::array< uint8, SESSION_KEY_LENGTH > SessionKey
Definition AuthDefines.h:25
@ STATUS_AUTHED
Definition AuthSession.h:43
#define sBattlegroundMgr
@ BG_DESERTION_TYPE_INVITE_LOGOUT
CharacterDatabaseStatements
@ CHAR_INS_TUTORIALS
@ CHAR_UPD_TUTORIALS
@ CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES
@ CHAR_SEL_TUTORIALS
@ CHAR_SEL_ACCOUNT_DATA
@ CHAR_UPD_ACCOUNT_ONLINE
@ CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES
@ CHAR_REP_PLAYER_ACCOUNT_DATA
@ CHAR_REP_ACCOUNT_DATA
@ CHAR_INS_DESERTER_TRACK
@ CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES
LocaleConstant
Definition Common.h:48
AccountTypes
Definition Common.h:39
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
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
int64_t int64
Definition Define.h:128
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
std::chrono::system_clock::time_point SystemTimePoint
Definition Duration.h:37
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition Duration.h:30
#define ASSERT
Definition Errors.h:68
#define sGuildMgr
Definition GuildMgr.h:59
@ LOG_LEVEL_TRACE
Definition LogCommon.h:27
#define TC_LOG_WARN(filterType__,...)
Definition Log.h:162
#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 sLog
Definition Log.h:130
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
#define TC_METRIC_DETAILED_TIMER(category,...)
Definition Metric.h:230
#define TC_METRIC_VALUE(category, value,...)
Definition Metric.h:203
#define TC_METRIC_EVENT(category, title, description)
Definition Metric.h:195
#define TC_METRIC_TAG(name, value)
Definition Metric.h:169
#define sObjectMgr
Definition ObjectMgr.h:1721
#define sOutdoorPvPMgr
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:42
@ BUYBACK_SLOT_END
Definition Player.h:610
@ BUYBACK_SLOT_START
Definition Player.h:609
@ PLAYER_SLOTS_COUNT
Definition Player.h:552
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:36
#define sScriptMgr
Definition ScriptMgr.h:1168
@ AUTH_WAIT_QUEUE
@ AUTH_SYSTEM_ERROR
@ AUTH_OK
constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE
#define PLAYER_MAX_BATTLEGROUND_QUEUES
#define MAX_ACCOUNT_TUTORIAL_VALUES
BanMode
Ban function modes.
@ BAN_ACCOUNT
@ BAN_IP
@ BAN_CHARACTER
@ FRIEND_OFFLINE
Definition SocialMgr.h:70
#define sSocialMgr
Definition SocialMgr.h:159
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
uint32 getMSTime()
Definition Timer.h:33
@ PLAYER_FIELD_BUYBACK_PRICE_1
@ PLAYER_FIELD_VENDORBUYBACK_SLOT_1
@ PLAYER_FIELD_BUYBACK_TIMESTAMP_1
bool Initialize(uint32 accountId)
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
char const * what() const noexcept override
Definition ByteBuffer.h:36
size_t rpos() const
Definition ByteBuffer.h:312
void resize(size_t newsize)
Definition ByteBuffer.h:416
void hexlike() const
void print_storage() const
size_t wpos() const
Definition ByteBuffer.h:325
size_t size() const
Definition ByteBuffer.h:413
uint8 * contents()
Definition ByteBuffer.h:399
PacketProcessing ProcessingPlace
Definition Opcodes.h:1391
virtual void Call(WorldSession *session, WorldPacket &packet) const =0
Class used to access individual fields of database query result.
Definition Field.h:92
uint8 GetUInt8() const
Definition Field.cpp:29
std::string GetString() const
Definition Field.cpp:125
Definition Group.h:165
Definition Guild.h:284
void add(const T &item)
Adds an item to the queue.
Definition LockedQueue.h:50
void readd(Iterator begin, Iterator end)
Adds items back to front of the queue.
Definition LockedQueue.h:61
bool next(T &result)
Gets the next result in the queue, if any.
Definition LockedQueue.h:68
virtual bool Process(WorldPacket *packet) override
Definition Map.h:302
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid const Empty
Definition ObjectGuid.h:140
bool IsEmpty() const
Definition ObjectGuid.h:172
PackedGuidWriter WriteAsPacked() const
Definition ObjectGuid.h:152
std::string ToString() const
bool IsInWorld() const
Definition Object.h:73
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:691
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:577
char const * Name
Definition Opcodes.h:1379
SessionStatus Status
Definition Opcodes.h:1380
virtual bool ProcessUnsafe() const
WorldSession *const m_pSession
void CleanupChannels()
Definition Player.cpp:4866
uint32 GetXP() const
Definition Player.h:996
bool IsBeingTeleportedFar() const
Definition Player.h:1808
void KillPlayer()
Definition Player.cpp:4462
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Player.cpp:373
bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:23054
uint32 GetDeathTimer() const
Definition Player.h:1875
void RemoveSocial()
Definition Player.cpp:26480
bool HasPendingBind() const
Definition Player.h:2143
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:23095
ObjectGuid GetLootGUID() const
Definition Player.h:1700
void RepopAtGraveyard()
Definition Player.cpp:4792
void ClearWhisperWhiteList()
Definition Player.h:2236
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:20308
Battleground * GetBattleground() const
Definition Player.cpp:23024
ObjectGuid::LowType GetGuildId() const
Definition Player.h:1605
Group * GetGroup()
Definition Player.h:2159
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition Player.cpp:18704
uint32 GetXPForNextLevel() const
Definition Player.h:997
void SaveToDB(bool create=false)
Definition Player.cpp:18989
void BuildPlayerRepop()
Definition Player.cpp:4320
void UninviteFromGroup()
Definition Player.cpp:2335
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition Player.cpp:23041
void setUInt32(uint8 index, uint32 value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
void setString(uint8 index, std::string const &value)
void SetSize(size_t size)
PreparedQueryResult GetPreparedResult(size_t index) const
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition QueryHolder.h:76
bool SetPreparedQuery(size_t index, PreparedStatement< T > *stmt)
Definition QueryHolder.h:44
Definition Unit.h:783
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3788
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4565
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5633
uint8 GetLevel() const
Definition Unit.h:903
Map * FindMap() const
Definition Object.h:452
std::string const & GetName() const
Definition Object.h:384
uint32 GetZoneId() const
Definition Object.h:375
uint16 GetOpcode() const
Definition WorldPacket.h:58
WorldPacket const * Write() override
std::span< BannedAddon const > BannedAddons
std::span< SecureAddonInfo const > Addons
std::string const & GetInvalidValue() const
WorldPacket const * Write() override
WorldPacket const * Write() override
std::array< uint32, MAX_ACCOUNT_TUTORIAL_VALUES > TutorialData
virtual bool Process(WorldPacket *packet) override
bool EvaluateOpcode(WorldPacket &p, time_t time) const
uint32 GetMaxPacketCounterAllowed(uint16 opcode) const
PacketThrottlingMap _PacketThrottlingMap
Player session in the World.
void SetPlayer(Player *player)
bool m_playerRecentlyLogout
bool Update(uint32 diff, PacketFilter &updater)
Update the WorldSession (triggered by World update)
void LogoutPlayer(bool save)
Log the player out
uint8 _tutorialsChanged
AccountData _accountData[NUM_ACCOUNT_DATA_TYPES]
char const * GetTrinityString(uint32 entry) const
std::string m_Address
void LoadTutorialsData(PreparedQueryResult result)
void UpdateInstanceEnterTimes()
void SendClientCacheVersion(uint32 version)
void HandleMoveWorldportAck()
void SendNotification(char const *format,...) ATTR_PRINTF(2
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
static void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
QueryCallbackProcessor _queryProcessor
void InitWarden(SessionKey const &k, std::string const &os)
std::array< uint32, MAX_ACCOUNT_TUTORIAL_VALUES > _tutorials
AccountTypes GetSecurity() const
LocaleConstant GetSessionDbLocaleIndex() const
rbac::RBACData * GetRBACData() const
void ReadAddonsInfo(ByteBuffer &data)
std::shared_ptr< WorldSocket > m_Socket
bool DisallowHyperlinksAndMaybeKick(std::string const &str)
std::map< uint32, uint32 > _pendingTimeSyncRequests
void QueuePacket(WorldPacket *new_packet)
Add an incoming packet to the queue.
class WorldSession::DosProtection AntiDOS
void LoadAccountData(PreparedQueryResult result, uint32 mask)
std::atomic< time_t > m_timeOutTime
uint32 _timeSyncTimer
std::string GetPlayerInfo() const
void KickPlayer(std::string const &reason)
Kick a player out of the World.
Player * GetPlayer() const
rbac::RBACData * _RBACData
void Handle_NULL(WorldPacket &recvPacket)
void SendAuthWaitQueue(uint32 position)
Handle the authentication waiting queue (to be completed)
~WorldSession()
WorldSession destructor.
void SetLogoutStartTime(time_t requestTime)
Engage the logout process for the user.
WorldSession(uint32 id, std::string &&name, std::shared_ptr< WorldSocket > sock, AccountTypes sec, uint8 expansion, time_t mute_time, Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter)
WorldSession constructor.
void LogUnexpectedOpcode(WorldPacket *packet, char const *status, const char *reason)
Logging helper for unexpected opcodes.
void Handle_EarlyProccess(WorldPacket &recvPacket)
bool ValidateMovementInfo(Unit const *mover, MovementInfo *mi) const
std::string _accountName
AccountData const * GetAccountData(AccountDataType type) const
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
void InitializeSessionCallback(CharacterDatabaseQueryHolder const &realmHolder)
bool CanSpeak() const
uint32 _timeSyncNextCounter
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
QueryCallback LoadPermissionsAsync()
void SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans)
std::string const & GetRemoteAddress() const
void SetInQueue(bool state)
Session in auth.queue currently.
struct WorldSession::Addons _addons
ObjectGuid::LowType m_GUIDLow
bool HasPermission(uint32 permissionId)
void LoadInstanceTimeRestrictions(PreparedQueryResult result)
uint32 GetAccountId() const
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
void SendTutorialsData()
std::unordered_map< uint32, SystemTimePoint > _instanceResetTimes
Player * _player
bool UpdateAndCheckInstanceCount(uint32 instanceId)
void LogUnprocessedTail(WorldPacket *packet)
Logging helper for unexpected opcodes.
GameClient * _gameClient
void DoLootRelease(ObjectGuid lguid)
uint32 GetLatency() const
void ProcessQueryCallbacks()
void Handle_ServerSide(WorldPacket &recvPacket)
Unit * ValidateAndGetUnitBeingMoved(ObjectGuid guid, OpcodeClient opcode, bool forStatusAck) const
void SendAccountDataTimes(uint32 mask)
void SaveTutorialsData(CharacterDatabaseTransaction trans)
LockedQueue< WorldPacket * > _recvQueue
std::string const & GetPlayerName() const
time_t m_muteTime
std::unique_ptr< Warden > _warden
void ResetTimeOutTime(bool onlyActive)
void InitializeSession()
void InvalidateRBACData()
void SetAccountData(AccountDataType type, time_t time, std::string const &data)
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
bool ValidateHyperlinksAndMaybeKick(std::string const &str)
AsyncCallbackProcessor< TransactionCallback > _transactionCallbacks
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos=0)
bool IsConnectionIdle() const
void AddInstanceEnterTime(uint32 instanceId, SystemTimePoint enterTime)
uint32 GetId() const
Gets the Id of the Object.
Definition RBAC.h:815
QueryCallback LoadFromDBAsync()
Definition RBAC.cpp:187
std::string const & GetName() const
Gets the Name of the Object.
Definition RBAC.h:813
void LoadFromDB()
Loads all permissions assigned to current account.
Definition RBAC.cpp:174
bool HasPermission(uint32 permission) const
Definition RBAC.h:833
Opcodes
Definition Opcodes.h:29
std::string GetOpcodeNameForLogging(Opcodes opcode)
Lookup opcode name for human understandable logging.
Definition Opcodes.cpp:1469
OpcodeTable opcodeTable
Definition Opcodes.cpp:51
#define GLOBAL_CACHE_MASK
AccountDataType
#define NUM_ACCOUNT_DATA_TYPES
@ CMSG_QUESTGIVER_QUERY_QUEST
Definition Opcodes.h:419
@ CMSG_CALENDAR_EVENT_MODERATOR_STATUS
Definition Opcodes.h:1106
@ CMSG_LEARN_PREVIEW_TALENTS
Definition Opcodes.h:1246
@ CMSG_TURN_IN_PETITION
Definition Opcodes.h:481
@ CMSG_CALENDAR_ADD_EVENT
Definition Opcodes.h:1098
@ MSG_RANDOM_ROLL
Definition Opcodes.h:536
@ CMSG_ATTACK_STOP
Definition Opcodes.h:351
@ CMSG_CALENDAR_EVENT_REMOVE_INVITE
Definition Opcodes.h:1104
@ MSG_PETITION_DECLINE
Definition Opcodes.h:479
@ CMSG_SPELLCLICK
Definition Opcodes.h:1045
@ MSG_MOVE_SET_FACING
Definition Opcodes.h:247
@ CMSG_GUILD_DEL_RANK
Definition Opcodes.h:592
@ CMSG_LOGOUT_REQUEST
Definition Opcodes.h:104
@ CMSG_PET_RENAME
Definition Opcodes.h:404
@ CMSG_QUEST_QUERY
Definition Opcodes.h:121
@ CMSG_SET_GUILD_BANK_TEXT
Definition Opcodes.h:1064
@ CMSG_REPORT_PVP_AFK
Definition Opcodes.h:1025
@ CMSG_ARENA_TEAM_DISBAND
Definition Opcodes.h:882
@ MSG_RAID_READY_CHECK
Definition Opcodes.h:831
@ CMSG_SET_SHEATHED
Definition Opcodes.h:509
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition Opcodes.h:1174
@ CMSG_QUESTGIVER_STATUS_QUERY
Definition Opcodes.h:415
@ CMSG_REPOP_REQUEST
Definition Opcodes.h:375
@ SMSG_ACCOUNT_DATA_TIMES
Definition Opcodes.h:550
@ CMSG_ACTIVATETAXI
Definition Opcodes.h:458
@ CMSG_PETITION_QUERY
Definition Opcodes.h:483
@ CMSG_PET_ABANDON
Definition Opcodes.h:403
@ CMSG_QUEST_CONFIRM_ACCEPT
Definition Opcodes.h:440
@ CMSG_FORCE_PITCH_RATE_CHANGE_ACK
Definition Opcodes.h:1146
@ CMSG_QUESTGIVER_COMPLETE_QUEST
Definition Opcodes.h:423
@ CMSG_GMTICKET_CREATE
Definition Opcodes.h:546
@ CMSG_TOGGLE_PVP
Definition Opcodes.h:624
@ CMSG_CALENDAR_EVENT_INVITE
Definition Opcodes.h:1102
@ CMSG_GUILD_ACCEPT
Definition Opcodes.h:161
@ CMSG_ITEM_REFUND_INFO
Definition Opcodes.h:1232
@ CMSG_ACTIVATETAXIEXPRESS
Definition Opcodes.h:815
@ CMSG_GUILD_BANK_DEPOSIT_MONEY
Definition Opcodes.h:1033
@ CMSG_GUILD_LEAVE
Definition Opcodes.h:170
@ CMSG_CREATURE_QUERY
Definition Opcodes.h:125
@ CMSG_GUILD_BANK_WITHDRAW_MONEY
Definition Opcodes.h:1034
@ CMSG_SET_CONTACT_NOTES
Definition Opcodes.h:136
@ CMSG_QUEST_POI_QUERY
Definition Opcodes.h:512
@ CMSG_GM_REPORT_LAG
Definition Opcodes.h:1311
@ CMSG_SOCKET_GEMS
Definition Opcodes.h:868
@ MSG_QUERY_GUILD_BANK_TEXT
Definition Opcodes.h:1063
@ CMSG_GAMEOBJ_REPORT_USE
Definition Opcodes.h:1182
@ CMSG_MOVE_TIME_SKIPPED
Definition Opcodes.h:747
@ CMSG_CHAR_ENUM
Definition Opcodes.h:84
@ MSG_SAVE_GUILD_EMBLEM
Definition Opcodes.h:526
@ CMSG_COMPLETE_CINEMATIC
Definition Opcodes.h:281
@ CMSG_SELF_RES
Definition Opcodes.h:720
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition Opcodes.h:1173
@ SMSG_NOTIFICATION
Definition Opcodes.h:488
@ CMSG_ARENA_TEAM_REMOVE
Definition Opcodes.h:881
@ CMSG_GROUP_ASSISTANT_LEADER
Definition Opcodes.h:684
@ CMSG_QUESTGIVER_ACCEPT_QUEST
Definition Opcodes.h:422
@ CMSG_CHAR_RACE_CHANGE
Definition Opcodes.h:1301
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition Opcodes.h:1172
@ CMSG_REQUEST_VEHICLE_EXIT
Definition Opcodes.h:1171
@ CMSG_GUILD_INVITE
Definition Opcodes.h:159
@ CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:258
@ CMSG_GUILD_DECLINE
Definition Opcodes.h:162
@ MSG_TALENT_WIPE_CONFIRM
Definition Opcodes.h:711
@ CMSG_GROUP_INVITE
Definition Opcodes.h:139
@ CMSG_TIME_SYNC_RESP
Definition Opcodes.h:942
@ CMSG_FORCE_TURN_RATE_CHANGE_ACK
Definition Opcodes.h:764
@ CMSG_NAME_QUERY
Definition Opcodes.h:109
@ CMSG_ARENA_TEAM_LEADER
Definition Opcodes.h:883
@ CMSG_GROUP_UNINVITE
Definition Opcodes.h:146
@ MSG_SET_RAID_DIFFICULTY
Definition Opcodes.h:1288
@ CMSG_GMRESPONSE_RESOLVE
Definition Opcodes.h:1293
@ CMSG_CONTROLLER_EJECT_PASSENGER
Definition Opcodes.h:1222
@ CMSG_DELETEEQUIPMENT_SET
Definition Opcodes.h:347
@ CMSG_OPT_OUT_OF_LOOT
Definition Opcodes.h:1062
@ CMSG_EQUIPMENT_SET_SAVE
Definition Opcodes.h:1242
@ CMSG_CALENDAR_COMPLAIN
Definition Opcodes.h:1123
@ CMSG_GUILD_SET_OFFICER_NOTE
Definition Opcodes.h:594
@ CMSG_CALENDAR_EVENT_SIGNUP
Definition Opcodes.h:1239
@ CMSG_AUTOSTORE_BANK_ITEM
Definition Opcodes.h:671
@ CMSG_STANDSTATECHANGE
Definition Opcodes.h:286
@ CMSG_GROUP_CHANGE_SUB_GROUP
Definition Opcodes.h:667
@ MSG_GUILD_BANK_LOG_QUERY
Definition Opcodes.h:1035
@ CMSG_GUILD_ADD_RANK
Definition Opcodes.h:591
@ CMSG_DISMISS_CRITTER
Definition Opcodes.h:1194
@ CMSG_CALENDAR_GET_CALENDAR
Definition Opcodes.h:1094
@ CMSG_CHAR_DELETE
Definition Opcodes.h:85
@ CMSG_PET_NAME_QUERY
Definition Opcodes.h:111
@ MSG_RAID_TARGET_UPDATE
Definition Opcodes.h:830
@ CMSG_LEARN_PREVIEW_TALENTS_PET
Definition Opcodes.h:1247
@ CMSG_AUTOBANK_ITEM
Definition Opcodes.h:672
@ CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:929
@ CMSG_GROUP_SET_LEADER
Definition Opcodes.h:149
@ CMSG_ARENA_TEAM_ACCEPT
Definition Opcodes.h:878
@ CMSG_CHAR_CUSTOMIZE
Definition Opcodes.h:1168
@ CMSG_BUG
Definition Opcodes.h:487
@ CMSG_BANKER_ACTIVATE
Definition Opcodes.h:468
@ CMSG_ITEM_REFUND
Definition Opcodes.h:1233
@ CMSG_CALENDAR_COPY_EVENT
Definition Opcodes.h:1101
@ CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
Definition Opcodes.h:260
@ CMSG_GUILD_DISBAND
Definition Opcodes.h:172
@ CMSG_ITEM_NAME_QUERY
Definition Opcodes.h:737
@ CMSG_GMTICKET_UPDATETEXT
Definition Opcodes.h:548
@ CMSG_QUERY_INSPECT_ACHIEVEMENTS
Definition Opcodes.h:1160
@ CMSG_CONTACT_LIST
Definition Opcodes.h:131
@ CMSG_CHAR_RENAME
Definition Opcodes.h:740
@ CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY
Definition Opcodes.h:1076
@ CMSG_CALENDAR_EVENT_RSVP
Definition Opcodes.h:1103
@ CMSG_TAXINODE_STATUS_QUERY
Definition Opcodes.h:455
@ MSG_PARTY_ASSIGNMENT
Definition Opcodes.h:939
@ CMSG_ARENA_TEAM_INVITE
Definition Opcodes.h:876
@ CMSG_GMSURVEY_SUBMIT
Definition Opcodes.h:839
@ CMSG_GROUP_DISBAND
Definition Opcodes.h:152
@ CMSG_ALTER_APPEARANCE
Definition Opcodes.h:1091
@ MSG_MOVE_HEARTBEAT
Definition Opcodes.h:267
@ CMSG_GMTICKET_DELETETICKET
Definition Opcodes.h:564
@ CMSG_SET_ACTION_BUTTON
Definition Opcodes.h:325
@ CMSG_WRAP_ITEM
Definition Opcodes.h:496
@ CMSG_GAMEOBJECT_QUERY
Definition Opcodes.h:123
@ CMSG_LOOT_METHOD
Definition Opcodes.h:151
@ CMSG_GROUP_ACCEPT
Definition Opcodes.h:143
@ CMSG_GUILD_RANK
Definition Opcodes.h:590
@ CMSG_BEGIN_TRADE
Definition Opcodes.h:308
@ CMSG_GUILD_QUERY
Definition Opcodes.h:113
@ CMSG_QUESTGIVER_REQUEST_REWARD
Definition Opcodes.h:425
@ CMSG_LEAVE_BATTLEFIELD
Definition Opcodes.h:766
@ CMSG_INSPECT
Definition Opcodes.h:305
@ CMSG_GROUP_UNINVITE_GUID
Definition Opcodes.h:147
@ CMSG_AREA_SPIRIT_HEALER_QUERY
Definition Opcodes.h:767
@ CMSG_DISMISS_CONTROLLED_VEHICLE
Definition Opcodes.h:1162
@ CMSG_DEL_FRIEND
Definition Opcodes.h:135
@ CMSG_GUILD_INFO_TEXT
Definition Opcodes.h:793
@ CMSG_TAXIQUERYAVAILABLENODES
Definition Opcodes.h:457
@ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE
Definition Opcodes.h:1208
@ CMSG_MESSAGECHAT
Definition Opcodes.h:178
@ CMSG_QUERY_TIME
Definition Opcodes.h:491
@ CMSG_QUESTLOG_REMOVE_QUEST
Definition Opcodes.h:433
@ MSG_CORPSE_QUERY
Definition Opcodes.h:563
@ CMSG_ADD_FRIEND
Definition Opcodes.h:134
@ CMSG_QUESTGIVER_CANCEL
Definition Opcodes.h:429
@ CMSG_PAGE_TEXT_QUERY
Definition Opcodes.h:119
@ CMSG_FORCE_RUN_SPEED_CHANGE_ACK
Definition Opcodes.h:256
@ CMSG_LOGOUT_CANCEL
Definition Opcodes.h:107
@ CMSG_GROUP_RAID_CONVERT
Definition Opcodes.h:683
@ CMSG_READY_FOR_ACCOUNT_DATA_TIMES
Definition Opcodes.h:1308
@ CMSG_CHAR_CREATE
Definition Opcodes.h:83
@ CMSG_BATTLEMASTER_JOIN_ARENA
Definition Opcodes.h:885
@ CMSG_WHO
Definition Opcodes.h:127
@ CMSG_HEARTH_AND_RESURRECT
Definition Opcodes.h:1209
@ CMSG_CORPSE_MAP_POSITION_QUERY
Definition Opcodes.h:1235
@ CMSG_PLAYER_LOGIN
Definition Opcodes.h:90
@ CMSG_PLAYER_LOGOUT
Definition Opcodes.h:103
@ CMSG_NPC_TEXT_QUERY
Definition Opcodes.h:412
@ CMSG_CALENDAR_UPDATE_EVENT
Definition Opcodes.h:1099
@ CMSG_RESET_INSTANCES
Definition Opcodes.h:826
@ CMSG_GROUP_DECLINE
Definition Opcodes.h:144
@ MSG_SET_DUNGEON_DIFFICULTY
Definition Opcodes.h:838
@ CMSG_GUILD_SET_PUBLIC_NOTE
Definition Opcodes.h:593
@ CMSG_DUEL_CANCELLED
Definition Opcodes.h:394
@ CMSG_GUILD_LEADER
Definition Opcodes.h:173
@ CMSG_TRAINER_BUY_SPELL
Definition Opcodes.h:463
@ MSG_GUILD_EVENT_LOG_QUERY
Definition Opcodes.h:1052
@ MSG_QUERY_NEXT_MAIL_TIME
Definition Opcodes.h:673
@ CMSG_UNLEARN_SKILL
Definition Opcodes.h:543
@ CMSG_INITIATE_TRADE
Definition Opcodes.h:307
@ CMSG_DUEL_ACCEPTED
Definition Opcodes.h:393
@ CMSG_QUESTGIVER_CHOOSE_REWARD
Definition Opcodes.h:427
@ CMSG_FORCE_WALK_SPEED_CHANGE_ACK
Definition Opcodes.h:760
@ CMSG_ARENA_TEAM_DECLINE
Definition Opcodes.h:879
@ SMSG_AUTH_RESPONSE
Definition Opcodes.h:523
@ CMSG_REALM_SPLIT
Definition Opcodes.h:937
@ CMSG_CALENDAR_REMOVE_EVENT
Definition Opcodes.h:1100
@ CMSG_ARENA_TEAM_QUERY
Definition Opcodes.h:872
@ CMSG_QUERY_QUESTS_COMPLETED
Definition Opcodes.h:1309
@ CMSG_CHAR_FACTION_CHANGE
Definition Opcodes.h:1270
@ CMSG_GUILD_BANK_BUY_TAB
Definition Opcodes.h:1031
@ MSG_PETITION_RENAME
Definition Opcodes.h:734
@ CMSG_PETITION_BUY
Definition Opcodes.h:474
@ CMSG_PETITION_SIGN
Definition Opcodes.h:477
@ CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition Opcodes.h:927
@ CMSG_ARENA_TEAM_LEAVE
Definition Opcodes.h:880
@ CMSG_REMOVE_GLYPH
Definition Opcodes.h:1191
@ CMSG_GUILD_BANK_QUERY_TAB
Definition Opcodes.h:1028
@ CMSG_PLAYER_VEHICLE_ENTER
Definition Opcodes.h:1221
@ CMSG_BUY_BANK_SLOT
Definition Opcodes.h:470
@ CMSG_REQUEST_PARTY_MEMBER_STATS
Definition Opcodes.h:668
@ CMSG_ITEM_QUERY_SINGLE
Definition Opcodes.h:115
@ CMSG_GUILD_BANK_UPDATE_TAB
Definition Opcodes.h:1032
@ CMSG_GUILD_MOTD
Definition Opcodes.h:174
@ CMSG_GAMEOBJ_USE
Definition Opcodes.h:206
@ CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:762
@ TUTORIALS_FLAG_LOADED_FROM_DB
@ TUTORIALS_FLAG_CHANGED
@ TUTORIALS_FLAG_NONE
@ STATUS_LOGGEDIN
Definition Opcodes.h:1356
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition Opcodes.h:1358
@ STATUS_TRANSFER
Definition Opcodes.h:1357
@ STATUS_NEVER
Definition Opcodes.h:1359
@ STATUS_UNHANDLED
Definition Opcodes.h:1360
@ NULL_OPCODE
Definition Opcodes.h:1346
@ PROCESS_INPLACE
Definition Opcodes.h:1365
@ PROCESS_THREADUNSAFE
Definition Opcodes.h:1366
#define sWorld
Definition World.h:901
Realm realm
Definition World.cpp:3610
@ CONFIG_MAX_INSTANCES_PER_HOUR
Definition World.h:357
@ CONFIG_SOCKET_TIMEOUTTIME
Definition World.h:219
@ CONFIG_CLIENTCACHE_VERSION
Definition World.h:338
@ CONFIG_PACKET_SPOOF_BANDURATION
Definition World.h:374
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition World.h:403
@ CONFIG_PACKET_SPOOF_POLICY
Definition World.h:372
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition World.h:295
@ CONFIG_PACKET_SPOOF_BANMODE
Definition World.h:373
@ CONFIG_BATTLEGROUND_TRACK_DESERTERS
Definition World.h:128
std::vector< BannedAddon > BannedAddonList
Definition AddonMgr.h:53
SavedAddon const * GetAddonInfo(const std::string &name)
Definition AddonMgr.cpp:110
BannedAddonList const * GetBannedAddons()
Definition AddonMgr.cpp:122
SystemTimePoint GetSystemTime()
Current chrono system_clock time point.
Definition GameTime.cpp:52
time_t GetGameTime()
Definition GameTime.cpp:42
void EraseIf(Container &c, Predicate p)
Definition Containers.h:231
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
@ RBAC_PERM_IGNORE_IDLE_CONNECTION
Definition RBAC.h:60
STL namespace.
std::string Data
uint32 Timestamp
Definition AddonMgr.h:42
ObjectGuid guid
uint32 amountCounter
time_t lastReceiveTime
uint32 Realm
Definition Realm.h:44
RealmHandle Id
Definition Realm.h:67
static uint32 constexpr MaxSecureAddons
std::vector< SecureAddonInfo > SecureAddons