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 "MovementPackets.h"
43#include "MoveSpline.h"
44#include "ObjectAccessor.h"
45#include "ObjectMgr.h"
46#include "Opcodes.h"
47#include "OutdoorPvPMgr.h"
48#include "PacketUtilities.h"
49#include "Player.h"
50#include "Realm.h"
51#include "ScriptMgr.h"
52#include "SocialMgr.h"
53#include "QueryHolder.h"
54#include "Vehicle.h"
55#include "WardenMac.h"
56#include "WardenWin.h"
57#include "World.h"
58#include "WorldPacket.h"
59#include "WorldSocket.h"
60#include <boost/circular_buffer.hpp>
61#include <zlib.h>
62
63namespace {
64
65std::string const DefaultPlayerName = "<none>";
66
67} // namespace
68
70{
71 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
72
73 //let's check if our opcode can be really processed in Map::Update()
74 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
75 return true;
76
77 //we do not process thread-unsafe packets
79 return false;
80
81 Player* player = m_pSession->GetPlayer();
82 if (!player)
83 return false;
84
85 //in Map::Update() we do not process packets where player is not in world!
86 return player->IsInWorld();
87}
88
89//we should process ALL packets when player is not in world/logged in
90//OR packet handler is not thread-safe!
92{
93 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
94
95 //check if packet handler is supposed to be safe
96 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
97 return true;
98
99 //thread-unsafe packets should be processed in World::UpdateSessions()
100 if (opHandle->ProcessingPlace == PROCESS_THREADUNSAFE)
101 return true;
102
103 //no player attached? -> our client! ^^
104 Player* player = m_pSession->GetPlayer();
105 if (!player)
106 return true;
107
108 //lets process all packets for non-in-the-world player
109 return (player->IsInWorld() == false);
110}
111
113WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
114 Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
115 m_muteTime(mute_time),
116 m_timeOutTime(0),
117 AntiDOS(this),
118 m_GUIDLow(0),
119 _player(nullptr),
120 m_Socket(std::move(sock)),
121 _security(sec),
122 _accountId(id),
123 _accountName(std::move(name)),
124 m_expansion(expansion),
125 _logoutTime(0),
126 m_inQueue(false),
127 m_playerLoading(false),
128 m_playerLogout(false),
129 m_playerRecentlyLogout(false),
130 m_playerSave(false),
131 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
132 m_sessionDbLocaleIndex(locale),
133 _timezoneOffset(timezoneOffset),
134 m_latency(0),
135 m_TutorialsChanged(TUTORIALS_FLAG_NONE),
136 recruiterId(recruiter),
137 isRecruiter(isARecruiter),
138 _RBACData(nullptr),
139 expireTime(60000), // 1 min after socket loss, session is deleted
140 forceExit(false),
141 m_currentBankerGUID(),
142 _timeSyncClockDeltaQueue(std::make_unique<boost::circular_buffer<std::pair<int64, uint32>>>(6)),
143 _timeSyncClockDelta(0),
144 _pendingTimeSyncRequests(),
145 _timeSyncNextCounter(0),
146 _timeSyncTimer(0),
147 _calendarEventCreationCooldown(0),
148 _gameClient(new GameClient(this))
149{
150 memset(m_Tutorials, 0, sizeof(m_Tutorials));
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(const char *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(string_id);
690 if (format)
691 {
692 va_list ap;
693 char szStr[1024];
694 szStr[0] = '\0';
695 va_start(ap, string_id);
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 TC_LOG_ERROR("network.opcode", "Received deprecated opcode {} from {}"
748 , GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
749}
750
752{
753 if (position == 0)
754 {
756 packet << uint8(AUTH_OK);
757 SendPacket(&packet);
758 }
759 else
760 {
762 packet << uint8(AUTH_WAIT_QUEUE);
763 packet << uint32(position);
764 packet << uint8(0); // unk
765 SendPacket(&packet);
766 }
767}
768
770{
771 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
772 if (mask & (1 << i))
774
775 if (!result)
776 return;
777
778 do
779 {
780 Field* fields = result->Fetch();
781 uint32 type = fields[0].GetUInt8();
782 if (type >= NUM_ACCOUNT_DATA_TYPES)
783 {
784 TC_LOG_ERROR("misc", "Table `{}` have invalid account data type ({}), ignore.",
785 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
786 continue;
787 }
788
789 if ((mask & (1 << type)) == 0)
790 {
791 TC_LOG_ERROR("misc", "Table `{}` have non appropriate for table account data type ({}), ignore.",
792 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
793 continue;
794 }
795
796 m_accountData[type].Time = time_t(fields[1].GetUInt32());
797 m_accountData[type].Data = fields[2].GetString();
798 }
799 while (result->NextRow());
800}
801
802void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string const& data)
803{
804 uint32 id = 0;
806 if ((1 << type) & GLOBAL_CACHE_MASK)
807 {
808 id = GetAccountId();
809 index = CHAR_REP_ACCOUNT_DATA;
810 }
811 else
812 {
813 // _player can be NULL and packet received after logout but m_GUID still store correct guid
814 if (!m_GUIDLow)
815 return;
816
817 id = m_GUIDLow;
819 }
820
821 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
822 stmt->setUInt32(0, id);
823 stmt->setUInt8 (1, type);
824 stmt->setUInt32(2, uint32(tm));
825 stmt->setString(3, data);
826 CharacterDatabase.Execute(stmt);
827
828 m_accountData[type].Time = tm;
829 m_accountData[type].Data = data;
830}
831
833{
835 data << uint32(GameTime::GetGameTime()); // Server time
836 data << uint8(1);
837 data << uint32(mask); // type mask
838 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
839 if (mask & (1 << i))
840 data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
841 SendPacket(&data);
842}
843
845{
846 memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
847
848 if (result)
849 {
850 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
851 m_Tutorials[i] = (*result)[i].GetUInt32();
853 }
854
855 m_TutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
856}
857
865
867{
869 return;
870
871 bool const hasTutorialsInDB = (m_TutorialsChanged & TUTORIALS_FLAG_LOADED_FROM_DB) != 0;
872 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(hasTutorialsInDB ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
873 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
874 stmt->setUInt32(i, m_Tutorials[i]);
876 trans->Append(stmt);
877
878 // now has, set flag so next save uses update query
879 if (!hasTutorialsInDB)
881
882 m_TutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
883}
884
886{
887 if (!result)
888 return;
889
891 do
892 {
893 Field* fields = result->Fetch();
894 SystemTimePoint restrictionExpireTime = SystemTimePoint::clock::from_time_t(fields[1].GetUInt64());
895 if (restrictionExpireTime > now)
896 _instanceResetTimes.try_emplace(fields[0].GetUInt32(), restrictionExpireTime);
897 } while (result->NextRow());
898}
899
901{
902 if (_instanceResetTimes.empty())
903 return;
904
906 stmt->setUInt32(0, GetAccountId());
907 trans->Append(stmt);
908
909 for (auto const& [instanceId, restrictionExpireTime] : _instanceResetTimes)
910 {
911 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES);
912 stmt->setUInt32(0, GetAccountId());
913 stmt->setUInt32(1, instanceId);
914 stmt->setUInt64(2, SystemTimePoint::clock::to_time_t(restrictionExpireTime));
915 trans->Append(stmt);
916 }
917}
918
920{
922
923 if (_instanceResetTimes.size() < sWorld->getIntConfig(CONFIG_MAX_INSTANCES_PER_HOUR))
924 return true;
925
926 if (instanceId == 0)
927 return false;
928
929 return _instanceResetTimes.contains(instanceId);
930}
931
933{
934 _instanceResetTimes.try_emplace(instanceId, enterTime + 1h);
935}
936
938{
939 Trinity::Containers::EraseIf(_instanceResetTimes, [now = GameTime::GetSystemTime()](std::pair<uint32 const, SystemTimePoint> const& value)
940 {
941 return value.second < now;
942 });
943}
944
946{
947 data >> *mi;
948 if (mi->guid.IsEmpty())
949 {
950 TC_LOG_ERROR("entities.unit", "WorldSession::ReadMovementInfo: mi->guid is empty, opcode {}", static_cast<uint32>(data.GetOpcode()));
951 return;
952 }
953
954 Unit* mover = ValidateAndGetUnitBeingMoved(mi->guid, true /*all remaining uses are ack handlers*/);
955 ValidateMovementInfo(mover, mi);
956}
957
959{
960 *data << mi->guid.WriteAsPacked();
961 *data << *mi;
962}
963
965{
966 if (data.rpos() + 4 > data.size())
967 return;
968
969 uint32 size;
970 data >> size;
971
972 if (!size)
973 return;
974
975 if (size > 0xFFFFF)
976 {
977 TC_LOG_DEBUG("addon", "WorldSession::ReadAddonsInfo: AddOnInfo too big, size {}", size);
978 return;
979 }
980
981 uLongf uSize = size;
982
983 uint32 pos = data.rpos();
984
985 ByteBuffer addonInfo;
986 addonInfo.resize(size);
987
988 _addons.SecureAddons.clear();
989
990 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
991 {
992 try
993 {
994 _addons.SecureAddons.resize(std::min(addonInfo.read<uint32>(), Addons::MaxSecureAddons));
995
997 {
998 uint32 publicKeyCrc, urlCrc;
999
1000 addonInfo >> addon.Name >> addon.HasKey;
1001 addonInfo >> publicKeyCrc >> urlCrc;
1002
1003 TC_LOG_DEBUG("addon", "AddOn: {} (CRC: 0x{:x}) - has key: 0x{:x} - URL CRC: 0x{:x}", addon.Name, publicKeyCrc, addon.HasKey, urlCrc);
1004
1005 if (SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addon.Name))
1006 {
1007 if (publicKeyCrc != savedAddon->CRC)
1008 {
1009 if (addon.HasKey)
1010 {
1011 addon.Status = SecureAddonInfo::BANNED;
1012 TC_LOG_WARN("addon", " Addon: {}: modified (CRC: 0x{:x}) - accountID {})", addon.Name, savedAddon->CRC, GetAccountId());
1013 }
1014 else
1015 addon.Status = SecureAddonInfo::SECURE_HIDDEN;
1016 }
1017 else
1018 {
1019 addon.Status = SecureAddonInfo::SECURE_HIDDEN;
1020 TC_LOG_DEBUG("addon", "Addon: {}: validated (CRC: 0x{:x}) - accountID {}", addon.Name, savedAddon->CRC, GetAccountId());
1021 }
1022 }
1023 else
1024 {
1025 addon.Status = SecureAddonInfo::BANNED;
1026 TC_LOG_WARN("addon", "Addon: {}: not registered as known secure addon - accountId {}", addon.Name, GetAccountId());
1027 }
1028 }
1029
1030 addonInfo.rpos(addonInfo.size() - 4);
1031
1032 addonInfo >> _addons.LastBannedAddOnTimestamp;
1033 TC_LOG_DEBUG("addon", "AddOn: Newest banned addon timestamp: {}", _addons.LastBannedAddOnTimestamp);
1034 }
1035 catch (ByteBufferException const& e)
1036 {
1037 TC_LOG_DEBUG("addon", "AddOn: Addon packet read error! {}", e.what());
1038 }
1039 }
1040 else
1041 TC_LOG_DEBUG("addon", "AddOn: Addon packet uncompress error!");
1042}
1043
1045{
1046 // Send new uncached banned addons
1048 uint32 lastBannedAddOnTimestamp = _addons.LastBannedAddOnTimestamp;
1049 if (!bannedAddons->empty() && bannedAddons->back().Timestamp < lastBannedAddOnTimestamp) // cheating attempt OR connecting to a realm with different configured banned addons, send everything
1050 lastBannedAddOnTimestamp = 0;
1051
1052 auto itr = std::ranges::lower_bound(*bannedAddons, lastBannedAddOnTimestamp, std::ranges::less(), &BannedAddon::Timestamp);
1053
1055 addonInfo.Addons = _addons.SecureAddons;
1056 addonInfo.BannedAddons = { itr, bannedAddons->end() };
1057 SendPacket(addonInfo.Write());
1058}
1059
1061{
1062 _player = player;
1063
1064 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1065 if (_player)
1067}
1068
1075
1080
1085
1086void WorldSession::InitWarden(SessionKey const& k, std::string const& os)
1087{
1088 if (os == "Win")
1089 {
1090 _warden = std::make_unique<WardenWin>();
1091 _warden->Init(this, k);
1092 }
1093 else if (os == "OSX")
1094 {
1095 // Disabled as it is causing the client to crash
1096 // _warden = std::make_unique<WardenMac>();
1097 // _warden->Init(this, k);
1098 }
1099}
1100
1102{
1103 uint32 id = GetAccountId();
1104 uint8 secLevel = GetSecurity();
1105
1106 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1108}
1109
1111{
1112 uint32 id = GetAccountId();
1113 uint8 secLevel = GetSecurity();
1114
1115 TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1116 id, _accountName, realm.Id.Realm, secLevel);
1117
1118 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1119 return _RBACData->LoadFromDBAsync();
1120}
1121
1123{
1124public:
1125 enum
1126 {
1130
1133
1135
1136 bool Initialize(uint32 accountId)
1137 {
1138 bool ok = true;
1139
1141 stmt->setUInt32(0, accountId);
1142 ok = SetPreparedQuery(GLOBAL_ACCOUNT_DATA, stmt) && ok;
1143
1144 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS);
1145 stmt->setUInt32(0, accountId);
1146 ok = SetPreparedQuery(TUTORIALS, stmt) && ok;
1147
1148 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES);
1149 stmt->setUInt32(0, accountId);
1150 ok = SetPreparedQuery(INSTANCE_TIMES, stmt) && ok;
1151
1152 return ok;
1153 }
1154};
1155
1157{
1158 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1159 if (!realmHolder->Initialize(GetAccountId()))
1160 {
1162 return;
1163 }
1164
1165 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this](SQLQueryHolderBase const& holder)
1166 {
1167 InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm const&>(holder));
1168 });
1169}
1170
1189
1191{
1192 return _RBACData;
1193}
1194
1196{
1197 if (!_RBACData)
1199
1200 bool hasPermission = _RBACData->HasPermission(permission);
1201 TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: {}, Name: {}, realmId: {}]",
1203
1204 return hasPermission;
1205}
1206
1208{
1209 TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: {}, Name: {}, realmId: {}]",
1211 delete _RBACData;
1212 _RBACData = nullptr;
1213}
1214
1216{
1217 uint32 maxPacketCounterAllowed = GetMaxPacketCounterAllowed(p.GetOpcode());
1218
1219 // Return true if there no limit for the opcode
1220 if (!maxPacketCounterAllowed)
1221 return true;
1222
1223 PacketCounter& packetCounter = _PacketThrottlingMap[p.GetOpcode()];
1224 if (packetCounter.lastReceiveTime != time)
1225 {
1226 packetCounter.lastReceiveTime = time;
1227 packetCounter.amountCounter = 0;
1228 }
1229
1230 // Check if player is flooding some packets
1231 if (++packetCounter.amountCounter <= maxPacketCounterAllowed)
1232 return true;
1233
1234 TC_LOG_WARN("network", "AntiDOS: Account {}, IP: {}, Ping: {}, Character: {}, flooding packet (opc: {} (0x{:X}), count: {})",
1236 opcodeTable[static_cast<OpcodeClient>(p.GetOpcode())]->Name, p.GetOpcode(), packetCounter.amountCounter);
1237
1238 switch (_policy)
1239 {
1240 case POLICY_LOG:
1241 return true;
1242 case POLICY_KICK:
1243 {
1244 TC_LOG_WARN("network", "AntiDOS: Player kicked!");
1245 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1246 return false;
1247 }
1248 case POLICY_BAN:
1249 {
1251 uint32 duration = sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANDURATION); // in seconds
1252 std::string nameOrIp = "";
1253 switch (bm)
1254 {
1255 case BAN_CHARACTER: // not supported, ban account
1256 case BAN_ACCOUNT: (void)sAccountMgr->GetName(Session->GetAccountId(), nameOrIp); break;
1257 case BAN_IP: nameOrIp = Session->GetRemoteAddress(); break;
1258 }
1259 sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
1260 TC_LOG_WARN("network", "AntiDOS: Player automatically banned for {} seconds.", duration);
1261 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1262 return false;
1263 }
1264 default: // invalid policy
1265 return true;
1266 }
1267}
1268
1270{
1271 uint32 maxPacketCounterAllowed;
1272 switch (opcode)
1273 {
1274 // CPU usage sending 2000 packets/second on a 3.70 GHz 4 cores on Win x64
1275 // [% CPU mysqld] [%CPU worldserver RelWithDebInfo]
1276 case CMSG_PLAYER_LOGIN: // 0 0.5
1277 case CMSG_NAME_QUERY: // 0 1
1278 case CMSG_PET_NAME_QUERY: // 0 1
1279 case CMSG_NPC_TEXT_QUERY: // 0 1
1280 case CMSG_ATTACK_STOP: // 0 1
1281 case CMSG_QUERY_QUESTS_COMPLETED: // 0 1
1282 case CMSG_QUERY_TIME: // 0 1
1284 case CMSG_MOVE_TIME_SKIPPED: // 0 1
1285 case MSG_QUERY_NEXT_MAIL_TIME: // 0 1
1286 case CMSG_SET_SHEATHED: // 0 1
1287 case MSG_RAID_TARGET_UPDATE: // 0 1
1288 case CMSG_PLAYER_LOGOUT: // 0 1
1289 case CMSG_LOGOUT_REQUEST: // 0 1
1290 case CMSG_PET_RENAME: // 0 1
1291 case CMSG_QUESTGIVER_CANCEL: // 0 1
1293 case CMSG_COMPLETE_CINEMATIC: // 0 1
1294 case CMSG_BANKER_ACTIVATE: // 0 1
1295 case CMSG_BUY_BANK_SLOT: // 0 1
1296 case CMSG_OPT_OUT_OF_LOOT: // 0 1
1297 case CMSG_DUEL_ACCEPTED: // 0 1
1298 case CMSG_DUEL_CANCELLED: // 0 1
1299 case CMSG_CALENDAR_COMPLAIN: // 0 1
1300 case CMSG_QUEST_QUERY: // 0 1.5
1301 case CMSG_ITEM_QUERY_SINGLE: // 0 1.5
1302 case CMSG_ITEM_NAME_QUERY: // 0 1.5
1303 case CMSG_GAMEOBJECT_QUERY: // 0 1.5
1304 case CMSG_CREATURE_QUERY: // 0 1.5
1305 case CMSG_QUESTGIVER_STATUS_QUERY: // 0 1.5
1306 case CMSG_GUILD_QUERY: // 0 1.5
1307 case CMSG_ARENA_TEAM_QUERY: // 0 1.5
1308 case CMSG_TAXINODE_STATUS_QUERY: // 0 1.5
1309 case CMSG_TAXIQUERYAVAILABLENODES: // 0 1.5
1310 case CMSG_QUESTGIVER_QUERY_QUEST: // 0 1.5
1311 case CMSG_PAGE_TEXT_QUERY: // 0 1.5
1312 case MSG_QUERY_GUILD_BANK_TEXT: // 0 1.5
1313 case MSG_CORPSE_QUERY: // 0 1.5
1314 case MSG_MOVE_SET_FACING: // 0 1.5
1315 case CMSG_REQUEST_PARTY_MEMBER_STATS: // 0 1.5
1316 case CMSG_QUESTGIVER_COMPLETE_QUEST: // 0 1.5
1317 case CMSG_SET_ACTION_BUTTON: // 0 1.5
1318 case CMSG_RESET_INSTANCES: // 0 1.5
1319 case CMSG_HEARTH_AND_RESURRECT: // 0 1.5
1320 case CMSG_TOGGLE_PVP: // 0 1.5
1321 case CMSG_PET_ABANDON: // 0 1.5
1322 case CMSG_ACTIVATETAXIEXPRESS: // 0 1.5
1323 case CMSG_ACTIVATETAXI: // 0 1.5
1324 case CMSG_SELF_RES: // 0 1.5
1325 case CMSG_UNLEARN_SKILL: // 0 1.5
1326 case CMSG_EQUIPMENT_SET_SAVE: // 0 1.5
1327 case CMSG_DELETEEQUIPMENT_SET: // 0 1.5
1328 case CMSG_DISMISS_CRITTER: // 0 1.5
1329 case CMSG_REPOP_REQUEST: // 0 1.5
1330 case CMSG_GROUP_INVITE: // 0 1.5
1331 case CMSG_GROUP_DECLINE: // 0 1.5
1332 case CMSG_GROUP_ACCEPT: // 0 1.5
1333 case CMSG_GROUP_UNINVITE_GUID: // 0 1.5
1334 case CMSG_GROUP_UNINVITE: // 0 1.5
1335 case CMSG_GROUP_DISBAND: // 0 1.5
1336 case CMSG_BATTLEMASTER_JOIN_ARENA: // 0 1.5
1337 case CMSG_LEAVE_BATTLEFIELD: // 0 1.5
1338 case MSG_GUILD_BANK_LOG_QUERY: // 0 2
1339 case CMSG_LOGOUT_CANCEL: // 0 2
1340 case CMSG_REALM_SPLIT: // 0 2
1341 case CMSG_ALTER_APPEARANCE: // 0 2
1342 case CMSG_QUEST_CONFIRM_ACCEPT: // 0 2
1343 case MSG_GUILD_EVENT_LOG_QUERY: // 0 2.5
1346 case CMSG_BEGIN_TRADE: // 0 2.5
1347 case CMSG_INITIATE_TRADE: // 0 3
1348 case CMSG_MESSAGECHAT: // 0 3.5
1349 case CMSG_INSPECT: // 0 3.5
1350 case CMSG_AREA_SPIRIT_HEALER_QUERY: // not profiled
1351 case CMSG_STANDSTATECHANGE: // not profiled
1352 case MSG_RANDOM_ROLL: // not profiled
1353 case CMSG_TIME_SYNC_RESP: // not profiled
1354 case CMSG_TRAINER_BUY_SPELL: // not profiled
1355 case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: // not profiled
1356 case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: // not profiled
1357 case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: // not profiled
1358 case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: // not profiled
1359 case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: // not profiled
1360 case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: // not profiled
1361 case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: // not profiled
1362 case CMSG_FORCE_TURN_RATE_CHANGE_ACK: // not profiled
1363 case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: // not profiled
1364 {
1365 // "0" is a magic number meaning there's no limit for the opcode.
1366 // All the opcodes above must cause little CPU usage and no sync/async database queries at all
1367 maxPacketCounterAllowed = 0;
1368 break;
1369 }
1370
1371 case CMSG_QUESTGIVER_ACCEPT_QUEST: // 0 4
1372 case CMSG_QUESTLOG_REMOVE_QUEST: // 0 4
1374 case CMSG_CONTACT_LIST: // 0 5
1375 case CMSG_LEARN_PREVIEW_TALENTS: // 0 6
1376 case CMSG_AUTOBANK_ITEM: // 0 6
1377 case CMSG_AUTOSTORE_BANK_ITEM: // 0 6
1378 case CMSG_WHO: // 0 7
1379 case CMSG_PLAYER_VEHICLE_ENTER: // 0 8
1380 case CMSG_LEARN_PREVIEW_TALENTS_PET: // not profiled
1381 case MSG_MOVE_HEARTBEAT:
1382 {
1383 maxPacketCounterAllowed = 200;
1384 break;
1385 }
1386
1387 case CMSG_GUILD_SET_PUBLIC_NOTE: // 1 2 1 async db query
1388 case CMSG_GUILD_SET_OFFICER_NOTE: // 1 2 1 async db query
1389 case CMSG_SET_CONTACT_NOTES: // 1 2.5 1 async db query
1390 case CMSG_CALENDAR_GET_CALENDAR: // 0 1.5 medium upload bandwidth usage
1391 case CMSG_GUILD_BANK_QUERY_TAB: // 0 3.5 medium upload bandwidth usage
1392 case CMSG_QUERY_INSPECT_ACHIEVEMENTS: // 0 13 high upload bandwidth usage
1393 case CMSG_GAMEOBJ_REPORT_USE: // not profiled
1394 case CMSG_GAMEOBJ_USE: // not profiled
1395 case MSG_PETITION_DECLINE: // not profiled
1396 {
1397 maxPacketCounterAllowed = 50;
1398 break;
1399 }
1400
1401 case CMSG_QUEST_POI_QUERY: // 0 25 very high upload bandwidth usage
1402 {
1403 maxPacketCounterAllowed = MAX_QUEST_LOG_SIZE;
1404 break;
1405 }
1406
1407 case CMSG_GM_REPORT_LAG: // 1 3 1 async db query
1408 case CMSG_SPELLCLICK: // not profiled
1409 case CMSG_REMOVE_GLYPH: // not profiled
1410 case CMSG_DISMISS_CONTROLLED_VEHICLE: // not profiled
1411 {
1412 maxPacketCounterAllowed = 20;
1413 break;
1414 }
1415
1416 case CMSG_PETITION_SIGN: // 9 4 2 sync 1 async db queries
1417 case CMSG_TURN_IN_PETITION: // 8 5.5 2 sync db query
1418 case CMSG_GROUP_CHANGE_SUB_GROUP: // 6 5 1 sync 1 async db queries
1419 case CMSG_PETITION_QUERY: // 4 3.5 1 sync db query
1420 case CMSG_CHAR_RACE_CHANGE: // 5 4 1 sync db query
1421 case CMSG_CHAR_CUSTOMIZE: // 5 5 1 sync db query
1422 case CMSG_CHAR_FACTION_CHANGE: // 5 5 1 sync db query
1423 case CMSG_CHAR_DELETE: // 4 4 1 sync db query
1424 case CMSG_DEL_FRIEND: // 7 5 1 async db query
1425 case CMSG_ADD_FRIEND: // 6 4 1 async db query
1426 case CMSG_CHAR_RENAME: // 5 3 1 async db query
1427 case CMSG_GMSURVEY_SUBMIT: // 2 3 1 async db query
1428 case CMSG_BUG: // 1 1 1 async db query
1429 case CMSG_GROUP_SET_LEADER: // 1 2 1 async db query
1430 case CMSG_GROUP_RAID_CONVERT: // 1 5 1 async db query
1431 case CMSG_GROUP_ASSISTANT_LEADER: // 1 2 1 async db query
1432 case CMSG_PETITION_BUY: // not profiled 1 sync 1 async db queries
1433 case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: // not profiled
1434 case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled
1435 case CMSG_REQUEST_VEHICLE_NEXT_SEAT: // not profiled
1436 case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: // not profiled
1437 case CMSG_REQUEST_VEHICLE_EXIT: // not profiled
1438 case CMSG_CONTROLLER_EJECT_PASSENGER: // not profiled
1439 case CMSG_ITEM_REFUND: // not profiled
1440 case CMSG_SOCKET_GEMS: // not profiled
1441 case CMSG_WRAP_ITEM: // not profiled
1442 case CMSG_REPORT_PVP_AFK: // not profiled
1443 {
1444 maxPacketCounterAllowed = 10;
1445 break;
1446 }
1447
1448 case CMSG_CHAR_CREATE: // 7 5 3 async db queries
1449 case CMSG_CHAR_ENUM: // 22 3 2 async db queries
1450 case CMSG_GMTICKET_CREATE: // 1 25 1 async db query
1451 case CMSG_GMTICKET_UPDATETEXT: // 0 15 1 async db query
1452 case CMSG_GMTICKET_DELETETICKET: // 1 25 1 async db query
1453 case CMSG_GMRESPONSE_RESOLVE: // 1 25 1 async db query
1454 case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query
1455 case CMSG_CALENDAR_UPDATE_EVENT: // not profiled
1456 case CMSG_CALENDAR_REMOVE_EVENT: // not profiled
1457 case CMSG_CALENDAR_COPY_EVENT: // not profiled
1458 case CMSG_CALENDAR_EVENT_INVITE: // not profiled
1459 case CMSG_CALENDAR_EVENT_SIGNUP: // not profiled
1460 case CMSG_CALENDAR_EVENT_RSVP: // not profiled
1461 case CMSG_CALENDAR_EVENT_REMOVE_INVITE: // not profiled
1462 case CMSG_CALENDAR_EVENT_MODERATOR_STATUS: // not profiled
1463 case CMSG_ARENA_TEAM_INVITE: // not profiled
1464 case CMSG_ARENA_TEAM_ACCEPT: // not profiled
1465 case CMSG_ARENA_TEAM_DECLINE: // not profiled
1466 case CMSG_ARENA_TEAM_LEAVE: // not profiled
1467 case CMSG_ARENA_TEAM_DISBAND: // not profiled
1468 case CMSG_ARENA_TEAM_REMOVE: // not profiled
1469 case CMSG_ARENA_TEAM_LEADER: // not profiled
1470 case CMSG_LOOT_METHOD: // not profiled
1471 case CMSG_GUILD_INVITE: // not profiled
1472 case CMSG_GUILD_ACCEPT: // not profiled
1473 case CMSG_GUILD_DECLINE: // not profiled
1474 case CMSG_GUILD_LEAVE: // not profiled
1475 case CMSG_GUILD_DISBAND: // not profiled
1476 case CMSG_GUILD_LEADER: // not profiled
1477 case CMSG_GUILD_MOTD: // not profiled
1478 case CMSG_GUILD_RANK: // not profiled
1479 case CMSG_GUILD_ADD_RANK: // not profiled
1480 case CMSG_GUILD_DEL_RANK: // not profiled
1481 case CMSG_GUILD_INFO_TEXT: // not profiled
1482 case CMSG_GUILD_BANK_DEPOSIT_MONEY: // not profiled
1483 case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
1484 case CMSG_GUILD_BANK_BUY_TAB: // not profiled
1485 case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
1486 case CMSG_SET_GUILD_BANK_TEXT: // not profiled
1487 case MSG_SAVE_GUILD_EMBLEM: // not profiled
1488 case MSG_PETITION_RENAME: // not profiled
1489 case MSG_TALENT_WIPE_CONFIRM: // not profiled
1490 case MSG_SET_DUNGEON_DIFFICULTY: // not profiled
1491 case MSG_SET_RAID_DIFFICULTY: // not profiled
1492 case MSG_PARTY_ASSIGNMENT: // not profiled
1493 case MSG_RAID_READY_CHECK: // not profiled
1494 {
1495 maxPacketCounterAllowed = 3;
1496 break;
1497 }
1498
1499 case CMSG_ITEM_REFUND_INFO: // not profiled
1500 {
1501 maxPacketCounterAllowed = PLAYER_SLOTS_COUNT;
1502 break;
1503 }
1504 default:
1505 {
1506 maxPacketCounterAllowed = 100;
1507 break;
1508 }
1509 }
1510
1511 return maxPacketCounterAllowed;
1512}
1513
1517
1523
1525{
1528 SendPacket(&data);
1529
1531
1532 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1533 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1535}
#define sAccountMgr
Definition AccountMgr.h:96
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
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition Common.h:65
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:602
@ BUYBACK_SLOT_START
Definition Player.h:601
@ PLAYER_SLOTS_COUNT
Definition Player.h:544
#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
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:308
void resize(size_t newsize)
Definition ByteBuffer.h:412
void hexlike() const
void print_storage() const
size_t wpos() const
Definition ByteBuffer.h:321
size_t size() const
Definition ByteBuffer.h:409
uint8 * contents()
Definition ByteBuffer.h:395
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:281
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:699
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:585
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:4847
uint32 GetXP() const
Definition Player.h:1018
bool IsBeingTeleportedFar() const
Definition Player.h:1822
void KillPlayer()
Definition Player.cpp:4434
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Player.cpp:369
bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:23079
uint32 GetDeathTimer() const
Definition Player.h:1888
void RemoveSocial()
Definition Player.cpp:26498
bool HasPendingBind() const
Definition Player.h:2155
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:23120
ObjectGuid GetLootGUID() const
Definition Player.h:1714
void RepopAtGraveyard()
Definition Player.cpp:4773
void ClearWhisperWhiteList()
Definition Player.h:2248
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:20310
Battleground * GetBattleground() const
Definition Player.cpp:23049
ObjectGuid::LowType GetGuildId() const
Definition Player.h:1620
Group * GetGroup()
Definition Player.h:2171
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition Player.cpp:18700
uint32 GetXPForNextLevel() const
Definition Player.h:1019
void SaveToDB(bool create=false)
Definition Player.cpp:18984
void BuildPlayerRepop()
Definition Player.cpp:4292
void UninviteFromGroup()
Definition Player.cpp:2303
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition Player.cpp:23066
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:769
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3765
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4542
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5691
uint8 GetLevel() const
Definition Unit.h:889
Map * FindMap() const
Definition Object.h:450
std::string const & GetName() const
Definition Object.h:382
uint32 GetZoneId() const
Definition Object.h:373
uint16 GetOpcode() const
Definition WorldPacket.h:80
WorldPacket const * Write() override
std::span< BannedAddon const > BannedAddons
std::span< SecureAddonInfo const > Addons
std::string const & GetInvalidValue() const
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
AccountData * GetAccountData(AccountDataType type)
char const * GetTrinityString(uint32 entry) const
std::string m_Address
void LoadTutorialsData(PreparedQueryResult result)
void UpdateInstanceEnterTimes()
Unit * ValidateAndGetUnitBeingMoved(ObjectGuid guid, bool forStatusAck) const
void SendClientCacheVersion(uint32 version)
void HandleMoveWorldportAck()
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
void SendNotification(const char *format,...) ATTR_PRINTF(2
static void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
QueryCallbackProcessor _queryProcessor
void InitWarden(SessionKey const &k, std::string const &os)
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
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
void Handle_Deprecated(WorldPacket &recvPacket)
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]
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
uint8 m_TutorialsChanged
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)
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()
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
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)
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)
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
@ SMSG_TUTORIAL_FLAGS
Definition Opcodes.h:282
@ 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
@ SMSG_TIME_SYNC_REQ
Definition Opcodes.h:941
@ 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:900
Realm realm
Definition World.cpp:3605
@ CONFIG_MAX_INSTANCES_PER_HOUR
Definition World.h:356
@ CONFIG_SOCKET_TIMEOUTTIME
Definition World.h:218
@ CONFIG_CLIENTCACHE_VERSION
Definition World.h:337
@ CONFIG_PACKET_SPOOF_BANDURATION
Definition World.h:373
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition World.h:402
@ CONFIG_PACKET_SPOOF_POLICY
Definition World.h:371
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition World.h:294
@ CONFIG_PACKET_SPOOF_BANMODE
Definition World.h:372
@ 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