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
18#include "WorldSession.h"
19#include "Account.h"
20#include "AccountMgr.h"
22#include "Bag.h"
23#include "BattlePetMgr.h"
24#include "BattlegroundMgr.h"
25#include "BattlenetPackets.h"
26#include "CharacterPackets.h"
27#include "ChatPackets.h"
28#include "ClientConfigPackets.h"
29#include "Containers.h"
30#include "DatabaseEnv.h"
31#include "DB2Stores.h"
32#include "GameTime.h"
33#include "Group.h"
34#include "Guild.h"
35#include "GuildMgr.h"
36#include "Hyperlinks.h"
37#include "IpAddress.h"
38#include "Log.h"
39#include "Map.h"
40#include "Metric.h"
41#include "MiscPackets.h"
42#include "ObjectMgr.h"
43#include "OutdoorPvPMgr.h"
44#include "PacketUtilities.h"
45#include "Player.h"
46#include "QueryHolder.h"
48#include "Random.h"
49#include "RBAC.h"
50#include "RealmList.h"
51#include "ScriptMgr.h"
52#include "SocialMgr.h"
53#include "World.h"
54#include "WorldSocket.h"
55#include <boost/circular_buffer.hpp>
56
57namespace {
58
59std::string const DefaultPlayerName = "<none>";
60
61} // namespace
62
64{
65 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
66
67 //let's check if our opcode can be really processed in Map::Update()
68 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
69 return true;
70
71 //we do not process thread-unsafe packets
73 return false;
74
75 Player* player = m_pSession->GetPlayer();
76 if (!player)
77 return false;
78
79 //in Map::Update() we do not process packets where player is not in world!
80 return player->IsInWorld();
81}
82
83//we should process ALL packets when player is not in world/logged in
84//OR packet handler is not thread-safe!
86{
87 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
88
89 //check if packet handler is supposed to be safe
90 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
91 return true;
92
93 //thread-unsafe packets should be processed in World::UpdateSessions()
95 return true;
96
97 //no player attached? -> our client! ^^
98 Player* player = m_pSession->GetPlayer();
99 if (!player)
100 return true;
101
102 //lets process all packets for non-in-the-world player
103 return (player->IsInWorld() == false);
104}
105
107WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccountId, std::string&& battlenetAccountEmail,
108 std::shared_ptr<WorldSocket>&& sock, AccountTypes sec, uint8 expansion, time_t mute_time, std::string&& os, Minutes timezoneOffset,
109 uint32 build, ClientBuild::VariantId clientBuildVariant, LocaleConstant locale, uint32 recruiter, bool isARecruiter) :
110 m_muteTime(mute_time),
111 m_timeOutTime(0),
112 AntiDOS(this),
113 m_GUIDLow(UI64LIT(0)),
114 _player(nullptr),
115 m_Socket({ std::move(sock), nullptr }),
116 _security(sec),
117 _accountId(id),
118 _accountName(std::move(name)),
119 _battlenetAccount(new Battlenet::Account(this, ObjectGuid::Create<HighGuid::BNetAccount>(battlenetAccountId), std::move(battlenetAccountEmail))),
120 m_accountExpansion(expansion),
121 m_expansion(std::min<uint8>(expansion, sWorld->getIntConfig(CONFIG_EXPANSION))),
122 _os(std::move(os)),
123 _clientBuild(build),
124 _clientBuildVariant(clientBuildVariant),
125 _realmListSecret(),
126 _battlenetRequestToken(0),
127 _logoutTime(0),
128 m_inQueue(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 _filterAddonMessages(false),
139 recruiterId(recruiter),
140 isRecruiter(isARecruiter),
141 _RBACData(nullptr),
142 expireTime(60000), // 1 min after socket loss, session is deleted
143 forceExit(false),
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 _battlePetMgr(std::make_unique<BattlePets::BattlePetMgr>(this)),
151 _collectionMgr(std::make_unique<CollectionMgr>(this))
152{
153 if (m_Socket[CONNECTION_TYPE_REALM])
154 {
155 m_Address = m_Socket[CONNECTION_TYPE_REALM]->GetRemoteIpAddress().to_string();
156 ResetTimeOutTime(false);
157 LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
158 }
159
160 _instanceConnectKey.Raw = UI64LIT(0);
161}
162
165{
167 if (_player)
168 LogoutPlayer (true);
169
171 for (uint8 i = 0; i < 2; ++i)
172 {
173 if (m_Socket[i])
174 {
175 m_Socket[i]->CloseSocket();
176 m_Socket[i].reset();
177 }
178 }
179
180 delete _RBACData;
181
183 WorldPacket* packet = nullptr;
184 while (_recvQueue.next(packet))
185 delete packet;
186
187 LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
188}
189
195
200
205
206std::string const & WorldSession::GetPlayerName() const
207{
208 return _player != nullptr ? _player->GetName() : DefaultPlayerName;
209}
210
212{
213 if (_player)
214 return Trinity::StringFormat("[Player: {} {}, Account: {}]", _player->GetName(), _player->GetGUID(), GetAccountId());
215
217 return Trinity::StringFormat("[Player: Logging in: {}, Account: {}]", m_playerLoading, GetAccountId());
218
219 return Trinity::StringFormat("[Player: Account: {}]", GetAccountId());
220}
221
223void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
224{
225 if (!opcodeTable.IsValid(static_cast<OpcodeServer>(packet->GetOpcode())))
226 {
227 char const* specialName = packet->GetOpcode() == UNKNOWN_OPCODE ? "UNKNOWN_OPCODE" : "INVALID_OPCODE";
228 TC_LOG_ERROR("network.opcode", "Prevented sending of {} (0x{:04X}) to {}", specialName, packet->GetOpcode(), GetPlayerInfo());
229 return;
230 }
231
232 ServerOpcodeHandler const* handler = opcodeTable[static_cast<OpcodeServer>(packet->GetOpcode())];
233 if (!handler)
234 {
235 TC_LOG_ERROR("network.opcode", "Prevented sending of opcode {} with non existing handler to {}", packet->GetOpcode(), GetPlayerInfo());
236 return;
237 }
238
239 // Default connection index defined in Opcodes.cpp table
240 ConnectionType conIdx = handler->ConnectionIndex;
241
242 // Override connection index
243 if (packet->GetConnection() != CONNECTION_TYPE_DEFAULT)
244 {
246 {
247 TC_LOG_ERROR("network.opcode", "Prevented sending of instance only opcode {} with connection type {} to {}", packet->GetOpcode(), uint32(packet->GetConnection()), GetPlayerInfo());
248 return;
249 }
250
251 conIdx = packet->GetConnection();
252 }
253
254 if (!m_Socket[conIdx])
255 {
256 TC_LOG_ERROR("network.opcode", "Prevented sending of {} to non existent socket {} to {}", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())), uint32(conIdx), GetPlayerInfo());
257 return;
258 }
259
260 if (!forced)
261 {
262 if (handler->Status == STATUS_UNHANDLED)
263 {
264 TC_LOG_ERROR("network.opcode", "Prevented sending disabled opcode {} to {}", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())), GetPlayerInfo());
265 return;
266 }
267 }
268
269#ifdef TRINITY_DEBUG
270 // Code for network use statistic
271 static uint64 sendPacketCount = 0;
272 static uint64 sendPacketBytes = 0;
273
274 static time_t firstTime = GameTime::GetGameTime();
275 static time_t lastTime = firstTime; // next 60 secs start time
276
277 static uint64 sendLastPacketCount = 0;
278 static uint64 sendLastPacketBytes = 0;
279
280 time_t cur_time = GameTime::GetGameTime();
281
282 if ((cur_time - lastTime) < 60)
283 {
284 sendPacketCount += 1;
285 sendPacketBytes += packet->size();
286
287 sendLastPacketCount += 1;
288 sendLastPacketBytes += packet->size();
289 }
290 else
291 {
292 uint64 minTime = uint64(cur_time - lastTime);
293 uint64 fullTime = uint64(lastTime - firstTime);
294 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));
295 TC_LOG_DEBUG("misc", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount)/minTime, float(sendLastPacketBytes)/minTime);
296
297 lastTime = cur_time;
298 sendLastPacketCount = 1;
299 sendLastPacketBytes = packet->wpos(); // wpos is real written size
300 }
301#endif // !TRINITY_DEBUG
302
303 sScriptMgr->OnPacketSend(this, *packet);
304
305 TC_LOG_TRACE("network.opcode", "S->C: {} {}", GetPlayerInfo(), GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())));
306 m_Socket[conIdx]->SendPacket(*packet);
307}
308
309void WorldSession::AddInstanceConnection(WorldSession* session, std::weak_ptr<WorldSocket> sockRef, ConnectToKey key)
310{
311 std::shared_ptr<WorldSocket> socket = sockRef.lock();
312 if (!socket || !socket->IsOpen())
313 return;
314
315 if (!session || session->GetConnectToInstanceKey() != key.Raw)
316 {
317 socket->SendAuthResponseError(ERROR_TIMED_OUT);
318 socket->DelayedCloseSocket();
319 return;
320 }
321
322 socket->SetWorldSession(session);
323 session->m_Socket[CONNECTION_TYPE_INSTANCE] = std::move(socket);
324 session->HandleContinuePlayerLogin();
325}
326
329{
330 _recvQueue.add(new WorldPacket(std::move(new_packet)));
331}
332
334void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, char const* status, const char *reason)
335{
336 TC_LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
337 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
338}
339
342{
343 if (!sLog->ShouldLog("network.opcode", LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
344 return;
345
346 TC_LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
347 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
348 packet->print_storage();
349}
350
353{
358 m_Socket[CONNECTION_TYPE_REALM]->CloseSocket();
359
362 WorldPacket* packet = nullptr;
364 bool deletePacket = true;
365 std::vector<WorldPacket*> requeuePackets;
366 uint32 processedPackets = 0;
367 time_t currentTime = GameTime::GetGameTime();
368
369 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 100;
370
371 while (m_Socket[CONNECTION_TYPE_REALM] && _recvQueue.next(packet, updater))
372 {
373 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
374 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
375 TC_METRIC_DETAILED_TIMER("worldsession_update_opcode_time", TC_METRIC_TAG("opcode", opHandle->Name));
376
377 try
378 {
379 switch (opHandle->Status)
380 {
381 case STATUS_LOGGEDIN:
382 if (!_player)
383 {
384 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
388 {
389 requeuePackets.push_back(packet);
390 deletePacket = false;
391 TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode {} with with status STATUS_LOGGEDIN. "
392 "Player is currently not in world yet.", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())));
393 }
394 }
395 else if (_player->IsInWorld())
396 {
397 if(AntiDOS.EvaluateOpcode(*packet, currentTime))
398 {
399 sScriptMgr->OnPacketReceive(this, *packet);
400 opHandle->Call(this, *packet);
401 }
402 else
403 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
404 }
405 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
406 break;
408 if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
409 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
410 "the player has not logged in yet and not recently logout");
411 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
412 {
413 // not expected _player or must checked in packet hanlder
414 sScriptMgr->OnPacketReceive(this, *packet);
415 opHandle->Call(this, *packet);
416 }
417 else
418 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
419 break;
420 case STATUS_TRANSFER:
421 if (!_player)
422 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
423 else if (_player->IsInWorld())
424 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
425 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
426 {
427 sScriptMgr->OnPacketReceive(this, *packet);
428 opHandle->Call(this, *packet);
429 }
430 else
431 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
432 break;
433 case STATUS_AUTHED:
434 // prevent cheating with skip queue wait
435 if (m_inQueue)
436 {
437 LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
438 break;
439 }
440
441 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
442 // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
443 if (packet->GetOpcode() == CMSG_ENUM_CHARACTERS)
445
446 if (AntiDOS.EvaluateOpcode(*packet, currentTime))
447 {
448 sScriptMgr->OnPacketReceive(this, *packet);
449 opHandle->Call(this, *packet);
450 }
451 else
452 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
453 break;
454 case STATUS_NEVER:
455 TC_LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode()))
456 , GetPlayerInfo());
457 break;
458 case STATUS_UNHANDLED:
459 TC_LOG_ERROR("network.opcode", "Received not handled opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode()))
460 , GetPlayerInfo());
461 break;
462 case STATUS_IGNORED:
463 break;
464 }
465 }
467 {
468 TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException {} occured while parsing a packet (opcode: {}) from {} address {}. Skipped packet.",
470
472 {
473 switch (ihe.GetReason())
474 {
476 KickPlayer("WorldSession::Update Invalid chat link");
477 break;
479 KickPlayer("WorldSession::Update Illegal chat link");
480 break;
481 default:
482 break;
483 }
484 }
485 }
486 catch (ByteBufferException const& bbe)
487 {
488 TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException {} occured while parsing a packet (opcode: {}) from {} address {}. Skipped packet.",
490 packet->hexlike();
491 }
492
493 if (deletePacket)
494 delete packet;
495
496 deletePacket = true;
497
498 processedPackets++;
499
500 //process only a max amout of packets in 1 Update() call.
501 //Any leftover will be processed in next update
502 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
503 break;
504 }
505
506 TC_METRIC_VALUE("processed_packets", processedPackets);
507
508 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
509
510 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
511 {
512 // Send time sync packet every 10s.
513 if (_timeSyncTimer > 0)
514 {
515 if (diff >= _timeSyncTimer)
516 SendTimeSync();
517 else
518 _timeSyncTimer -= diff;
519 }
520 }
521
523
524 //check if we are safe to proceed with logout
525 //logout procedure should happen only in World::UpdateSessions() method!!!
526 if (updater.ProcessUnsafe())
527 {
529 if (ShouldLogOut(currentTime) && m_playerLoading.IsEmpty())
530 LogoutPlayer(true);
531
533 if (std::ranges::any_of(m_Socket, [](std::shared_ptr<WorldSocket> const& s) { return s && !s->IsOpen(); }))
534 {
535 expireTime -= expireTime > diff ? diff : expireTime;
536 if (expireTime < diff || forceExit || !GetPlayer())
537 {
538 for (std::shared_ptr<WorldSocket>& socket : m_Socket)
539 {
540 if (socket)
541 {
542 socket->CloseSocket();
543 socket.reset();
544 }
545 }
546 }
547 }
548
550 return false; //Will remove this session from the world session map
551 }
552
553 return true;
554}
555
558{
559 // finish pending transfers before starting the logout
562
563 m_playerLogout = true;
564 m_playerSave = save;
565
566 if (_player)
567 {
568 if (!_player->GetLootGUID().IsEmpty())
570
572 if (_player->GetDeathTimer())
573 {
577 }
579 {
580 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
585 }
586 else if (_player->HasPendingBind())
587 {
589 _player->SetPendingBind(0, 0);
590 }
591
592 //drop a flag if player is carrying it
594 bg->EventPlayerLoggedOut(_player);
595
596 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
597
598 for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
599 {
601 if (bgQueueTypeId != BATTLEGROUND_QUEUE_NONE)
602 {
603 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
604 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
605 queue.RemovePlayer(_player->GetGUID(), true);
606 }
607 }
608
609 // Repop at Graveyard or other player far teleport will prevent saving player because of not present map
610 // Teleport player immediately for correct player save
613
615 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
616 guild->HandleMemberLogout(this);
617
620
622 if (_battlePetMgr->HasJournalLock())
623 _battlePetMgr->ToggleJournalLock(false);
624
627
629
630 // exit areatriggers before saving to remove auras applied by them
632
634 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
635 if (save)
636 {
637 uint32 eslot;
638 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
639 {
640 eslot = j - BUYBACK_SLOT_START;
642 _player->SetBuybackPrice(eslot, 0);
643 _player->SetBuybackTimestamp(eslot, 0);
644 }
645 _player->SaveToDB();
646 }
647
650
653
655 if (Group* group = _player->GetGroup())
656 {
657 group->SendUpdate();
658 if (group->GetLeaderGUID() == _player->GetGUID())
659 group->StartLeaderOfflineTimer();
660 }
661
663 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
665
667 sScriptMgr->OnPlayerLogout(_player);
668
669 TC_METRIC_EVENT("player_events", "Logout", _player->GetName());
670
672 // the player may not be in the world when logging out
673 // e.g if he got disconnected during a transfer to another map
674 // calls to GetMap in this case may cause crashes
677 TC_LOG_INFO("entities.player.character", "Account: {} (IP: {}) Logout Character:[{}] {} Level: {}, XP: {}/{} ({} left)",
680
681 if (Map* _map = _player->FindMap())
682 _map->RemovePlayerFromMap(_player, true);
683
684 SetPlayer(nullptr);
685
689 TC_LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
690
693 stmt->setUInt32(0, GetAccountId());
694 CharacterDatabase.Execute(stmt);
695 }
696
698 {
699 m_Socket[CONNECTION_TYPE_INSTANCE]->CloseSocket();
701 }
702
703 m_playerLogout = false;
704 m_playerSave = false;
707}
708
710void WorldSession::KickPlayer(std::string_view reason)
711{
712 TC_LOG_INFO("network.kick", "{} kicked with reason: {}", GetPlayerInfo(), reason);
713
714 for (std::shared_ptr<WorldSocket> const& socket : m_Socket)
715 {
716 if (socket)
717 {
718 socket->CloseSocket();
719 forceExit = true;
720 }
721 }
722}
723
725{
727 return true;
728
729 TC_LOG_ERROR("network", "Player {}{} sent a message with an invalid link:\n{}", GetPlayer()->GetName(),
730 GetPlayer()->GetGUID().ToString(), str);
731
733 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
734
735 return false;
736}
737
739{
740 if (str.find('|') == std::string::npos)
741 return true;
742
743 TC_LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n{}", GetPlayer()->GetName(),
744 GetPlayer()->GetGUID().ToString(), str);
745
747 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
748
749 return false;
750}
751
752void WorldSession::SendNotification(char const* format, ...)
753{
754 if (format)
755 {
756 va_list ap;
757 char szStr[1024];
758 szStr[0] = '\0';
759 va_start(ap, format);
760 vsnprintf(szStr, 1024, format, ap);
761 va_end(ap);
762
764 }
765}
766
768{
769 char const* format = GetTrinityString(stringId);
770 if (format)
771 {
772 va_list ap;
773 char szStr[1024];
774 szStr[0] = '\0';
775 va_start(ap, stringId);
776 vsnprintf(szStr, 1024, format, ap);
777 va_end(ap);
778
780 }
781}
782
784{
786}
787
789{
790 return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex());
791}
792
794{
795 if (GetPlayer())
797 else if (!onlyActive)
799}
800
805
807{
808 TC_LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}", GetOpcodeNameForLogging(null.GetOpcode()), GetPlayerInfo());
809}
810
812{
813 TC_LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}"
815}
816
818{
819 boost::system::error_code ignored_error;
820 boost::asio::ip::address instanceAddress;
821 if (std::shared_ptr<Realm const> currentRealm = sRealmList->GetCurrentRealm())
822 instanceAddress = currentRealm->GetAddressForClient(Trinity::Net::make_address(GetRemoteAddress(), ignored_error));
823
826 _instanceConnectKey.Fields.Key = urand(0, 0x7FFFFFFF);
827
829 connectTo.Key = _instanceConnectKey.Raw;
831 connectTo.Serial = serial;
832
833 WorldPackets::Auth::ConnectTo::ConnectPayload& payload = connectTo.Payload.emplace_back();
834 payload.Port = sWorld->getIntConfig(CONFIG_PORT_WORLD);
835 if (instanceAddress.is_v4())
836 {
837 memcpy(payload.Address.Address.V4.data(), instanceAddress.to_v4().to_bytes().data(), 4);
839 }
840 else
841 {
842 // client always uses v4 address for loopback and v4 mapped addresses
843 boost::asio::ip::address_v6 v6 = instanceAddress.to_v6();
844 if (v6.is_loopback())
845 {
846 memcpy(payload.Address.Address.V4.data(), boost::asio::ip::address_v4::loopback().to_bytes().data(), 4);
848 }
849 else if (v6.is_v4_mapped())
850 {
851 memcpy(payload.Address.Address.V4.data(), Trinity::Net::make_address_v4(Trinity::Net::v4_mapped, v6).to_bytes().data(), 4);
853 }
854 else
855 {
856 memcpy(payload.Address.Address.V6.data(), v6.to_bytes().data(), 16);
858 }
859 }
860 connectTo.Con = CONNECTION_TYPE_INSTANCE;
861
862 SendPacket(connectTo.Write());
863}
864
866{
867 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
868 if (mask & (1 << i))
870
871 if (!result)
872 return;
873
874 do
875 {
876 Field* fields = result->Fetch();
877 uint32 type = fields[0].GetUInt8();
878 if (type >= NUM_ACCOUNT_DATA_TYPES)
879 {
880 TC_LOG_ERROR("misc", "Table `{}` have invalid account data type ({}), ignore.",
881 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
882 continue;
883 }
884
885 if ((mask & (1 << type)) == 0)
886 {
887 TC_LOG_ERROR("misc", "Table `{}` have non appropriate for table account data type ({}), ignore.",
888 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
889 continue;
890 }
891
892 _accountData[type].Time = fields[1].GetInt64();
893 _accountData[type].Data = fields[2].GetString();
894 }
895 while (result->NextRow());
896}
897
898void WorldSession::SetAccountData(AccountDataType type, time_t time, std::string const& data)
899{
900 if ((1 << type) & GLOBAL_CACHE_MASK)
901 {
903 stmt->setUInt32(0, GetAccountId());
904 stmt->setUInt8(1, type);
905 stmt->setInt64(2, time);
906 stmt->setString(3, data);
907 CharacterDatabase.Execute(stmt);
908 }
909 else
910 {
911 // _player can be NULL and packet received after logout but m_GUID still store correct guid
912 if (!m_GUIDLow)
913 return;
914
916 stmt->setUInt64(0, m_GUIDLow);
917 stmt->setUInt8(1, type);
918 stmt->setInt64(2, time);
919 stmt->setString(3, data);
920 CharacterDatabase.Execute(stmt);
921 }
922
923 _accountData[type].Time = time;
924 _accountData[type].Data = data;
925}
926
928{
930 accountDataTimes.PlayerGuid = playerGuid;
931 accountDataTimes.ServerTime = GameTime::GetSystemTime();
932 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
933 if (mask & (1 << i))
934 accountDataTimes.AccountTimes[i] = GetAccountData(AccountDataType(i))->Time;
935
936 SendPacket(accountDataTimes.Write());
937}
938
940{
941 _tutorials = { };
942
943 if (result)
944 {
945 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
946 _tutorials[i] = (*result)[i].GetUInt32();
948 }
949
950 _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
951}
952
959
961{
963 return;
964
965 bool const hasTutorialsInDB = (_tutorialsChanged & TUTORIALS_FLAG_LOADED_FROM_DB) != 0;
966 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(hasTutorialsInDB ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
967 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
968 stmt->setUInt32(i, _tutorials[i]);
970 trans->Append(stmt);
971
972 // now has, set flag so next save uses update query
973 if (!hasTutorialsInDB)
975
976 _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
977}
978
980{
981 if (!result)
982 return;
983
985 do
986 {
987 Field* fields = result->Fetch();
988 SystemTimePoint restrictionExpireTime = SystemTimePoint::clock::from_time_t(fields[1].GetUInt64());
989 if (restrictionExpireTime > now)
990 _instanceResetTimes.try_emplace(fields[0].GetUInt32(), restrictionExpireTime);
991 } while (result->NextRow());
992}
993
995{
996 if (_instanceResetTimes.empty())
997 return;
998
1000 stmt->setUInt32(0, GetAccountId());
1001 trans->Append(stmt);
1002
1003 for (auto const& [instanceId, restrictionExpireTime] : _instanceResetTimes)
1004 {
1005 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES);
1006 stmt->setUInt32(0, GetAccountId());
1007 stmt->setUInt32(1, instanceId);
1008 stmt->setUInt64(2, SystemTimePoint::clock::to_time_t(restrictionExpireTime));
1009 trans->Append(stmt);
1010 }
1011}
1012
1014{
1016
1017 if (_instanceResetTimes.size() < sWorld->getIntConfig(CONFIG_MAX_INSTANCES_PER_HOUR))
1018 return true;
1019
1020 if (instanceId == 0)
1021 return false;
1022
1023 return _instanceResetTimes.contains(instanceId);
1024}
1025
1027{
1028 _instanceResetTimes.try_emplace(instanceId, enterTime + 1h);
1029}
1030
1032{
1033 Trinity::Containers::EraseIf(_instanceResetTimes, [now = GameTime::GetSystemTime()](std::pair<uint32 const, SystemTimePoint> const& value)
1034 {
1035 return value.second < now;
1036 });
1037}
1038
1040{
1041 if (elementsResult)
1042 {
1043 do
1044 {
1045 DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (playerDataElementAccountId)(floatValue)(int64Value)) fields { *elementsResult };
1046
1047 PlayerDataElementAccountEntry const* entry = sPlayerDataElementAccountStore.LookupEntry(fields.playerDataElementAccountId().GetUInt32());
1048 if (!entry)
1049 continue;
1050
1051 PlayerDataAccount::Element& element = _playerDataAccount.Elements.emplace_back();
1052 element.Id = entry->ID;
1053 element.NeedSave = false;
1054
1055 switch (entry->GetType())
1056 {
1058 element.Int64Value = fields.int64Value().GetInt64();
1059 break;
1061 element.FloatValue = fields.floatValue().GetFloat();
1062 break;
1063 default:
1064 break;
1065 }
1066 } while (elementsResult->NextRow());
1067 }
1068
1069 if (flagsResult)
1070 {
1071 do
1072 {
1073 DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (storageIndex)(mask)) fields { *flagsResult };
1074
1075 Trinity::Containers::EnsureWritableVectorIndex(_playerDataAccount.Flags, fields.storageIndex().GetUInt32()) = { .Value = fields.mask().GetUInt64(), .NeedSave = false };
1076 } while (flagsResult->NextRow());
1077 }
1078}
1079
1081{
1084 {
1085 if (!element.NeedSave)
1086 continue;
1087
1089 stmt->setUInt32(0, GetBattlenetAccountId());
1090 stmt->setUInt32(1, element.Id);
1091 transaction->Append(stmt);
1092
1093 element.NeedSave = false;
1094
1095 PlayerDataElementAccountEntry const* entry = sPlayerDataElementAccountStore.LookupEntry(element.Id);
1096 if (!entry)
1097 continue;
1098
1099 switch (entry->GetType())
1100 {
1102 if (!element.Int64Value)
1103 continue;
1105 stmt->setUInt32(0, GetBattlenetAccountId());
1106 stmt->setUInt32(1, element.Id);
1107 stmt->setNull(2);
1108 stmt->setInt64(3, element.Int64Value);
1109 transaction->Append(stmt);
1110 break;
1112 if (!element.FloatValue)
1113 continue;
1115 stmt->setUInt32(0, GetBattlenetAccountId());
1116 stmt->setUInt32(1, element.Id);
1117 stmt->setFloat(2, element.FloatValue);
1118 stmt->setNull(3);
1119 transaction->Append(stmt);
1120 break;
1121 }
1122 }
1123
1124 for (std::size_t i = 0; i < _playerDataAccount.Flags.size(); ++i)
1125 {
1127 if (!flag.NeedSave)
1128 continue;
1129
1130 stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_PLAYER_DATA_FLAGS_ACCOUNT);
1131 stmt->setUInt32(0, GetBattlenetAccountId());
1132 stmt->setUInt32(1, i);
1133 transaction->Append(stmt);
1134
1135 flag.NeedSave = false;
1136
1137 if (!flag.Value)
1138 continue;
1139
1140 stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_PLAYER_DATA_FLAGS_ACCOUNT);
1141 stmt->setUInt32(0, GetBattlenetAccountId());
1142 stmt->setUInt32(1, i);
1143 stmt->setUInt64(2, flag.Value);
1144 transaction->Append(stmt);
1145 }
1146}
1147
1149{
1150 auto elementItr = std::ranges::find(_playerDataAccount.Elements, dataElementId, &PlayerDataAccount::Element::Id);
1151 if (elementItr == _playerDataAccount.Elements.end())
1152 {
1153 elementItr = _playerDataAccount.Elements.emplace(_playerDataAccount.Elements.end());
1154 elementItr->Id = dataElementId;
1155 }
1156
1157 elementItr->NeedSave = true;
1158 elementItr->FloatValue = value;
1159}
1160
1162{
1163 auto elementItr = std::ranges::find(_playerDataAccount.Elements, dataElementId, &PlayerDataAccount::Element::Id);
1164 if (elementItr == _playerDataAccount.Elements.end())
1165 {
1166 elementItr = _playerDataAccount.Elements.emplace(_playerDataAccount.Elements.end());
1167 elementItr->Id = dataElementId;
1168 }
1169
1170 elementItr->NeedSave = true;
1171 elementItr->Int64Value = value;
1172}
1173
1175{
1176 PlayerDataFlagAccountEntry const* entry = sPlayerDataFlagAccountStore.LookupEntry(dataFlagId);
1177 if (!entry)
1178 return;
1179
1180 uint32 fieldOffset = entry->StorageIndex / PLAYER_DATA_FLAG_VALUE_BITS;
1181 uint64 flagValue = UI64LIT(1) << (entry->StorageIndex % PLAYER_DATA_FLAG_VALUE_BITS);
1182
1184 if (on)
1185 flag.Value |= flagValue;
1186 else
1187 flag.Value &= ~flagValue;
1188
1189 flag.NeedSave = true;
1190}
1191
1192bool WorldSession::IsAddonRegistered(std::string_view prefix) const
1193{
1194 if (!_filterAddonMessages) // if we have hit the softcap (64) nothing should be filtered
1195 return true;
1196
1198}
1199
1204
1206{
1207 // This is always sent after CMSG_CHAT_UNREGISTER_ALL_ADDON_PREFIXES
1210 {
1211 _filterAddonMessages = false;
1212 return;
1213 }
1214
1215 _filterAddonMessages = true;
1216}
1217
1219{
1220 _player = player;
1221
1222 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1223 if (_player)
1225}
1226
1233
1238
1243
1248
1250{
1251 uint32 id = GetAccountId();
1252 uint8 secLevel = GetSecurity();
1253
1254 TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1255 id, _accountName, sRealmList->GetCurrentRealmId().Realm, secLevel);
1256
1257 _RBACData = new rbac::RBACData(id, _accountName, sRealmList->GetCurrentRealmId().Realm, secLevel);
1259}
1260
1262{
1263 uint32 id = GetAccountId();
1264 uint8 secLevel = GetSecurity();
1265
1266 TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1267 id, _accountName, sRealmList->GetCurrentRealmId().Realm, secLevel);
1268
1269 _RBACData = new rbac::RBACData(id, _accountName, sRealmList->GetCurrentRealmId().Realm, secLevel);
1270 return _RBACData->LoadFromDBAsync();
1271}
1272
1274{
1275public:
1276 enum
1277 {
1281
1284
1286
1287 bool Initialize(uint32 accountId, uint32 /*battlenetAccountId*/)
1288 {
1289 bool ok = true;
1290
1292 stmt->setUInt32(0, accountId);
1293 ok = SetPreparedQuery(GLOBAL_ACCOUNT_DATA, stmt) && ok;
1294
1295 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS);
1296 stmt->setUInt32(0, accountId);
1297 ok = SetPreparedQuery(TUTORIALS, stmt) && ok;
1298
1299 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES);
1300 stmt->setUInt32(0, accountId);
1301 ok = SetPreparedQuery(INSTANCE_TIMES, stmt) && ok;
1302
1303 return ok;
1304 }
1305};
1306
1308{
1309public:
1310 enum
1311 {
1325
1328
1330
1331 bool Initialize(uint32 accountId, uint32 battlenetAccountId)
1332 {
1333 bool ok = true;
1334
1336 stmt->setUInt32(0, battlenetAccountId);
1337 ok = SetPreparedQuery(GLOBAL_ACCOUNT_TOYS, stmt) && ok;
1338
1339 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BATTLE_PETS);
1340 stmt->setUInt32(0, battlenetAccountId);
1341 stmt->setInt32(1, sRealmList->GetCurrentRealmId().Realm);
1342 ok = SetPreparedQuery(BATTLE_PETS, stmt) && ok;
1343
1344 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BATTLE_PET_SLOTS);
1345 stmt->setUInt32(0, battlenetAccountId);
1346 ok = SetPreparedQuery(BATTLE_PET_SLOTS, stmt) && ok;
1347
1348 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_HEIRLOOMS);
1349 stmt->setUInt32(0, battlenetAccountId);
1351
1352 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MOUNTS);
1353 stmt->setUInt32(0, battlenetAccountId);
1354 ok = SetPreparedQuery(MOUNTS, stmt) && ok;
1355
1357 stmt->setUInt32(0, accountId);
1359
1360 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ITEM_APPEARANCES);
1361 stmt->setUInt32(0, battlenetAccountId);
1362 ok = SetPreparedQuery(ITEM_APPEARANCES, stmt) && ok;
1363
1364 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES);
1365 stmt->setUInt32(0, battlenetAccountId);
1367
1368 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS);
1369 stmt->setUInt32(0, battlenetAccountId);
1370 ok = SetPreparedQuery(TRANSMOG_ILLUSIONS, stmt) && ok;
1371
1372 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_TRANSMOG_OUTFITS);
1373 stmt->setUInt32(0, battlenetAccountId);
1374 ok = SetPreparedQuery(TRANSMOG_OUTFITS, stmt) && ok;
1375
1376 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_WARBAND_SCENES);
1377 stmt->setUInt32(0, battlenetAccountId);
1378 ok = SetPreparedQuery(WARBAND_SCENES, stmt) && ok;
1379
1381 stmt->setUInt32(0, battlenetAccountId);
1383
1384 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_PLAYER_DATA_FLAGS_ACCOUNT);
1385 stmt->setUInt32(0, battlenetAccountId);
1387
1388 return ok;
1389 }
1390};
1391
1393{
1394 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1395 if (!realmHolder->Initialize(GetAccountId(), GetBattlenetAccountId()))
1396 {
1398 return;
1399 }
1400
1401 std::shared_ptr<AccountInfoQueryHolder> holder = std::make_shared<AccountInfoQueryHolder>();
1402 if (!holder->Initialize(GetAccountId(), GetBattlenetAccountId()))
1403 {
1405 return;
1406 }
1407
1408 struct ForkJoinState
1409 {
1410 std::shared_ptr<AccountInfoQueryHolderPerRealm> Character;
1411 std::shared_ptr<AccountInfoQueryHolder> Login;
1412 };
1413
1414 std::shared_ptr<ForkJoinState> state = std::make_shared<ForkJoinState>();
1415
1416 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this, state, realmHolder](SQLQueryHolderBase const& /*result*/)
1417 {
1418 state->Character = realmHolder;
1419 if (state->Login && state->Character)
1420 InitializeSessionCallback(*state->Login, *state->Character);
1421 });
1422
1423 AddQueryHolderCallback(LoginDatabase.DelayQueryHolder(holder)).AfterComplete([this, state, holder](SQLQueryHolderBase const& /*result*/)
1424 {
1425 state->Login = holder;
1426 if (state->Login && state->Character)
1427 InitializeSessionCallback(*state->Login, *state->Character);
1428 });
1429}
1430
1432{
1444
1445 if (!m_inQueue)
1446 SendAuthResponse(ERROR_OK, false);
1447 else
1449
1450 SetInQueue(false);
1451 ResetTimeOutTime(false);
1452
1459
1461 {
1462 do
1463 {
1464 Field* fields = characterCountsResult->Fetch();
1465 _realmCharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8();
1466
1467 } while (characterCountsResult->NextRow());
1468 }
1469
1471 bnetConnected.State = 1;
1472 SendPacket(bnetConnected.Write());
1473
1476}
1477
1479{
1480 return _RBACData;
1481}
1482
1484{
1485 if (!_RBACData)
1487
1488 bool hasPermission = _RBACData->HasPermission(permission);
1489 TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: {}, Name: {}, realmId: {}]",
1490 _RBACData->GetId(), _RBACData->GetName(), sRealmList->GetCurrentRealmId().Realm);
1491
1492 return hasPermission;
1493}
1494
1496{
1497 TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: {}, Name: {}, realmId: {}]",
1498 _RBACData->GetId(), _RBACData->GetName(), sRealmList->GetCurrentRealmId().Realm);
1499 delete _RBACData;
1500 _RBACData = nullptr;
1501}
1502
1504{
1505 uint32 maxPacketCounterAllowed = GetMaxPacketCounterAllowed(p.GetOpcode());
1506
1507 // Return true if there no limit for the opcode
1508 if (!maxPacketCounterAllowed)
1509 return true;
1510
1511 PacketCounter& packetCounter = _PacketThrottlingMap[p.GetOpcode()];
1512 if (packetCounter.lastReceiveTime != time)
1513 {
1514 packetCounter.lastReceiveTime = time;
1515 packetCounter.amountCounter = 0;
1516 }
1517
1518 // Check if player is flooding some packets
1519 if (++packetCounter.amountCounter <= maxPacketCounterAllowed)
1520 return true;
1521
1522 TC_LOG_WARN("network", "AntiDOS: Account {}, IP: {}, Ping: {}, Character: {}, flooding packet (opc: {} (0x{:X}), count: {})",
1524 opcodeTable[static_cast<OpcodeClient>(p.GetOpcode())]->Name, p.GetOpcode(), packetCounter.amountCounter);
1525
1526 switch (_policy)
1527 {
1528 case POLICY_LOG:
1529 return true;
1530 case POLICY_KICK:
1531 {
1532 TC_LOG_WARN("network", "AntiDOS: Player kicked!");
1533 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1534 return false;
1535 }
1536 case POLICY_BAN:
1537 {
1539 uint32 duration = sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANDURATION); // in seconds
1540 std::string nameOrIp = "";
1541 switch (bm)
1542 {
1543 case BAN_CHARACTER: // not supported, ban account
1544 case BAN_ACCOUNT: (void)sAccountMgr->GetName(Session->GetAccountId(), nameOrIp); break;
1545 case BAN_IP: nameOrIp = Session->GetRemoteAddress(); break;
1546 }
1547 sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
1548 TC_LOG_WARN("network", "AntiDOS: Player automatically banned for {} seconds.", duration);
1549 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1550 return false;
1551 }
1552 default: // invalid policy
1553 return true;
1554 }
1555}
1556
1558{
1559 uint32 maxPacketCounterAllowed;
1560 switch (opcode)
1561 {
1562 // CPU usage sending 2000 packets/second on a 3.70 GHz 4 cores on Win x64
1563 // [% CPU mysqld] [%CPU worldserver RelWithDebInfo]
1564 case CMSG_PLAYER_LOGIN: // 0 0.5
1565 case CMSG_QUERY_PLAYER_NAMES: // 0 1
1566 case CMSG_QUERY_PET_NAME: // 0 1
1567 case CMSG_QUERY_NPC_TEXT: // 0 1
1568 case CMSG_ATTACK_STOP: // 0 1
1569 case CMSG_QUERY_TIME: // 0 1
1570 case CMSG_QUERY_CORPSE_TRANSPORT: // 0 1
1571 case CMSG_MOVE_TIME_SKIPPED: // 0 1
1572 case CMSG_QUERY_NEXT_MAIL_TIME: // 0 1
1573 case CMSG_SET_SHEATHED: // 0 1
1574 case CMSG_UPDATE_RAID_TARGET: // 0 1
1575 case CMSG_LOGOUT_REQUEST: // 0 1
1576 case CMSG_PET_RENAME: // 0 1
1578 case CMSG_COMPLETE_CINEMATIC: // 0 1
1579 case CMSG_BANKER_ACTIVATE: // 0 1
1580 case CMSG_BUY_ACCOUNT_BANK_TAB: // 0 1
1581 case CMSG_OPT_OUT_OF_LOOT: // 0 1
1582 case CMSG_DUEL_RESPONSE: // 0 1
1583 case CMSG_CALENDAR_COMPLAIN: // 0 1
1584 case CMSG_QUERY_QUEST_INFO: // 0 1.5
1585 case CMSG_QUERY_GAME_OBJECT: // 0 1.5
1586 case CMSG_QUERY_CREATURE: // 0 1.5
1587 case CMSG_QUEST_GIVER_STATUS_QUERY: // 0 1.5
1588 case CMSG_QUERY_GUILD_INFO: // 0 1.5
1589 case CMSG_TAXI_NODE_STATUS_QUERY: // 0 1.5
1590 case CMSG_TAXI_QUERY_AVAILABLE_NODES: // 0 1.5
1591 case CMSG_QUEST_GIVER_QUERY_QUEST: // 0 1.5
1592 case CMSG_QUERY_PAGE_TEXT: // 0 1.5
1593 case CMSG_GUILD_BANK_TEXT_QUERY: // 0 1.5
1595 case CMSG_MOVE_SET_FACING: // 0 1.5
1596 case CMSG_MOVE_SET_FACING_HEARTBEAT: // 0 1.5
1597 case CMSG_MOVE_SET_PITCH: // 0 1.5
1598 case CMSG_REQUEST_PARTY_MEMBER_STATS: // 0 1.5
1599 case CMSG_QUEST_GIVER_COMPLETE_QUEST: // 0 1.5
1600 case CMSG_SET_ACTION_BUTTON: // 0 1.5
1601 case CMSG_SET_ACTION_BAR_TOGGLES: // not profiled
1602 case CMSG_RESET_INSTANCES: // 0 1.5
1603 case CMSG_HEARTH_AND_RESURRECT: // 0 1.5
1604 case CMSG_TOGGLE_PVP: // 0 1.5
1605 case CMSG_PET_ABANDON: // 0 1.5
1606 case CMSG_ACTIVATE_TAXI: // 0 1.5
1607 case CMSG_SELF_RES: // 0 1.5
1608 case CMSG_UNLEARN_SKILL: // 0 1.5
1609 case CMSG_SAVE_EQUIPMENT_SET: // 0 1.5
1610 case CMSG_DELETE_EQUIPMENT_SET: // 0 1.5
1611 case CMSG_DISMISS_CRITTER: // 0 1.5
1612 case CMSG_REPOP_REQUEST: // 0 1.5
1613 case CMSG_PARTY_INVITE: // 0 1.5
1614 case CMSG_PARTY_INVITE_RESPONSE: // 0 1.5
1615 case CMSG_PARTY_UNINVITE: // 0 1.5
1616 case CMSG_LEAVE_GROUP: // 0 1.5
1617 case CMSG_BATTLEMASTER_JOIN_ARENA: // 0 1.5
1618 case CMSG_BATTLEFIELD_LEAVE: // 0 1.5
1619 case CMSG_GUILD_BANK_LOG_QUERY: // 0 2
1620 case CMSG_LOGOUT_CANCEL: // 0 2
1621 case CMSG_ALTER_APPEARANCE: // 0 2
1622 case CMSG_QUEST_CONFIRM_ACCEPT: // 0 2
1623 case CMSG_GUILD_EVENT_LOG_QUERY: // 0 2.5
1625 case CMSG_BEGIN_TRADE: // 0 2.5
1626 case CMSG_INITIATE_TRADE: // 0 3
1627 case CMSG_CHAT_ADDON_MESSAGE: // 0 3.5
1629 case CMSG_CHAT_MESSAGE_AFK: // 0 3.5
1630 case CMSG_CHAT_MESSAGE_CHANNEL: // 0 3.5
1631 case CMSG_CHAT_MESSAGE_DND: // 0 3.5
1632 case CMSG_CHAT_MESSAGE_EMOTE: // 0 3.5
1633 case CMSG_CHAT_MESSAGE_GUILD: // 0 3.5
1634 case CMSG_CHAT_MESSAGE_OFFICER: // 0 3.5
1635 case CMSG_CHAT_MESSAGE_PARTY: // 0 3.5
1636 case CMSG_CHAT_MESSAGE_RAID: // 0 3.5
1637 case CMSG_CHAT_MESSAGE_RAID_WARNING: // 0 3.5
1638 case CMSG_CHAT_MESSAGE_SAY: // 0 3.5
1639 case CMSG_CHAT_MESSAGE_WHISPER: // 0 3.5
1640 case CMSG_CHAT_MESSAGE_YELL: // 0 3.5
1641 case CMSG_INSPECT: // 0 3.5
1642 case CMSG_AREA_SPIRIT_HEALER_QUERY: // not profiled
1643 case CMSG_STAND_STATE_CHANGE: // not profiled
1644 case CMSG_RANDOM_ROLL: // not profiled
1645 case CMSG_TIME_SYNC_RESPONSE: // not profiled
1646 case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: // not profiled
1647 case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK: // not profiled
1649 case CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK: // not profiled
1650 case CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK: // not profiled
1652 case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK: // not profiled
1653 case CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK: // not profiled
1654 case CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK: // not profiled
1656 {
1657 // "0" is a magic number meaning there's no limit for the opcode.
1658 // All the opcodes above must cause little CPU usage and no sync/async database queries at all
1659 maxPacketCounterAllowed = 0;
1660 break;
1661 }
1662
1664 case CMSG_QUEST_LOG_REMOVE_QUEST: // 0 4
1666 case CMSG_SEND_CONTACT_LIST: // 0 5
1667 case CMSG_AUTOBANK_ITEM: // 0 6
1668 case CMSG_AUTOSTORE_BANK_ITEM: // 0 6
1669 case CMSG_WHO: // 0 7
1670 case CMSG_RIDE_VEHICLE_INTERACT: // 0 8
1672 {
1673 maxPacketCounterAllowed = 200;
1674 break;
1675 }
1676
1677 case CMSG_GUILD_SET_MEMBER_NOTE: // 1 2 1 async db query
1678 case CMSG_SET_CONTACT_NOTES: // 1 2.5 1 async db query
1679 case CMSG_CALENDAR_GET: // 0 1.5 medium upload bandwidth usage
1680 case CMSG_GUILD_BANK_QUERY_TAB: // 0 3.5 medium upload bandwidth usage
1681 case CMSG_QUERY_INSPECT_ACHIEVEMENTS: // 0 13 high upload bandwidth usage
1682 case CMSG_GAME_OBJ_REPORT_USE: // not profiled
1683 case CMSG_GAME_OBJ_USE: // not profiled
1684 case CMSG_DECLINE_PETITION: // not profiled
1685 {
1686 maxPacketCounterAllowed = 50;
1687 break;
1688 }
1689
1690 case CMSG_QUEST_POI_QUERY: // 0 25 very high upload bandwidth usage
1691 {
1692 maxPacketCounterAllowed = MAX_QUEST_LOG_SIZE;
1693 break;
1694 }
1695
1696 case CMSG_SPELL_CLICK: // not profiled
1697 case CMSG_MOVE_DISMISS_VEHICLE: // not profiled
1698 {
1699 maxPacketCounterAllowed = 20;
1700 break;
1701 }
1702
1703 case CMSG_SIGN_PETITION: // 9 4 2 sync 1 async db queries
1704 case CMSG_TURN_IN_PETITION: // 8 5.5 2 sync db query
1705 case CMSG_CHANGE_SUB_GROUP: // 6 5 1 sync 1 async db queries
1706 case CMSG_QUERY_PETITION: // 4 3.5 1 sync db query
1707 case CMSG_CHAR_CUSTOMIZE: // 5 5 1 sync db query
1708 case CMSG_CHAR_RACE_OR_FACTION_CHANGE: // 5 5 1 sync db query
1709 case CMSG_CHAR_DELETE: // 4 4 1 sync db query
1710 case CMSG_DEL_FRIEND: // 7 5 1 async db query
1711 case CMSG_ADD_FRIEND: // 6 4 1 async db query
1712 case CMSG_CHARACTER_RENAME_REQUEST: // 5 3 1 async db query
1713 case CMSG_BUG_REPORT: // 1 1 1 async db query
1714 case CMSG_SET_PARTY_LEADER: // 1 2 1 async db query
1715 case CMSG_CONVERT_RAID: // 1 5 1 async db query
1716 case CMSG_SET_ASSISTANT_LEADER: // 1 2 1 async db query
1717 case CMSG_MOVE_CHANGE_VEHICLE_SEATS: // not profiled
1718 case CMSG_PETITION_BUY: // not profiled 1 sync 1 async db queries
1719 case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled
1720 case CMSG_REQUEST_VEHICLE_NEXT_SEAT: // not profiled
1721 case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: // not profiled
1722 case CMSG_REQUEST_VEHICLE_EXIT: // not profiled
1723 case CMSG_EJECT_PASSENGER: // not profiled
1724 case CMSG_ITEM_PURCHASE_REFUND: // not profiled
1725 case CMSG_SOCKET_GEMS: // not profiled
1726 case CMSG_WRAP_ITEM: // not profiled
1727 case CMSG_REPORT_PVP_PLAYER_AFK: // not profiled
1728 {
1729 maxPacketCounterAllowed = 10;
1730 break;
1731 }
1732
1733 case CMSG_CREATE_CHARACTER: // 7 5 3 async db queries
1734 case CMSG_ENUM_CHARACTERS: // 22 3 2 async db queries
1735 case CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT: // 22 3 2 async db queries
1736 case CMSG_SUBMIT_USER_FEEDBACK: // not profiled 1 async db query
1737 case CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT: // not profiled 1 async db query
1738 case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query
1739 case CMSG_CALENDAR_UPDATE_EVENT: // not profiled
1740 case CMSG_CALENDAR_REMOVE_EVENT: // not profiled
1741 case CMSG_CALENDAR_COPY_EVENT: // not profiled
1742 case CMSG_CALENDAR_INVITE: // not profiled
1743 case CMSG_CALENDAR_EVENT_SIGN_UP: // not profiled
1744 case CMSG_CALENDAR_RSVP: // not profiled
1745 case CMSG_CALENDAR_MODERATOR_STATUS: // not profiled
1746 case CMSG_CALENDAR_REMOVE_INVITE: // not profiled
1747 case CMSG_SET_LOOT_METHOD: // not profiled
1748 case CMSG_GUILD_INVITE_BY_NAME: // not profiled
1749 case CMSG_ACCEPT_GUILD_INVITE: // not profiled
1750 case CMSG_GUILD_DECLINE_INVITATION: // not profiled
1751 case CMSG_GUILD_LEAVE: // not profiled
1752 case CMSG_GUILD_DELETE: // not profiled
1753 case CMSG_GUILD_SET_GUILD_MASTER: // not profiled
1754 case CMSG_GUILD_UPDATE_MOTD_TEXT: // not profiled
1755 case CMSG_GUILD_SET_RANK_PERMISSIONS: // not profiled
1756 case CMSG_GUILD_ADD_RANK: // not profiled
1757 case CMSG_GUILD_DELETE_RANK: // not profiled
1758 case CMSG_GUILD_UPDATE_INFO_TEXT: // not profiled
1759 case CMSG_GUILD_BANK_DEPOSIT_MONEY: // not profiled
1760 case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
1761 case CMSG_GUILD_BANK_BUY_TAB: // not profiled
1762 case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
1763 case CMSG_GUILD_BANK_SET_TAB_TEXT: // not profiled
1764 case CMSG_SAVE_GUILD_EMBLEM: // not profiled
1765 case CMSG_PETITION_RENAME_GUILD: // not profiled
1766 case CMSG_CONFIRM_RESPEC_WIPE: // not profiled
1767 case CMSG_SET_DUNGEON_DIFFICULTY: // not profiled
1768 case CMSG_SET_RAID_DIFFICULTY: // not profiled
1769 case CMSG_SET_PARTY_ASSIGNMENT: // not profiled
1770 case CMSG_DO_READY_CHECK: // not profiled
1771 {
1772 maxPacketCounterAllowed = 3;
1773 break;
1774 }
1775
1776 case CMSG_GET_ITEM_PURCHASE_DATA: // not profiled
1777 {
1778 maxPacketCounterAllowed = PLAYER_SLOTS_COUNT + MAX_BAG_SIZE * (
1783 break;
1784 }
1785 case CMSG_HOTFIX_REQUEST: // not profiled
1786 {
1787 maxPacketCounterAllowed = 1;
1788 break;
1789 }
1790 case CMSG_CHECK_IS_ADVENTURE_MAP_POI_VALID: // not profiled
1791 {
1792 // 12.0.1: all entries of the db2 are sent
1793 maxPacketCounterAllowed = sAdventureMapPOIStore.GetNumRows();
1794 break;
1795 }
1796 default:
1797 {
1798 maxPacketCounterAllowed = 100;
1799 break;
1800 }
1801 }
1802
1803 return maxPacketCounterAllowed;
1804}
1805
1809
1815
1817{
1819 timeSyncRequest.SequenceIndex = _timeSyncNextCounter;
1820 SendPacket(timeSyncRequest.Write());
1821
1823
1824 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1825 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1827}
1828
#define sAccountMgr
Definition AccountMgr.h:105
#define MAX_BAG_SIZE
Definition Bag.h:22
#define sBattlegroundMgr
@ ERROR_TIMED_OUT
@ 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_ACCOUNT_INSTANCE_LOCK_TIMES
LocaleConstant
Definition Common.h:51
AccountTypes
Definition Common.h:42
DB2Storage< PlayerDataElementAccountEntry > sPlayerDataElementAccountStore("PlayerDataElementAccount.db2", &PlayerDataElementAccountLoadInfo::Instance)
DB2Storage< AdventureMapPOIEntry > sAdventureMapPOIStore("AdventureMapPOI.db2", &AdventureMapPoiLoadInfo::Instance)
DB2Storage< PlayerDataFlagAccountEntry > sPlayerDataFlagAccountStore("PlayerDataFlagAccount.db2", &PlayerDataFlagAccountLoadInfo::Instance)
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
SQLTransaction< LoginDatabaseConnection > LoginDatabaseTransaction
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:156
int64_t int64
Definition Define.h:149
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
#define UI64LIT(N)
Definition Define.h:139
uint32_t uint32
Definition Define.h:154
std::chrono::system_clock::time_point SystemTimePoint
Definition Duration.h:41
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition Duration.h:32
#define sGuildMgr
Definition GuildMgr.h:76
@ LOG_LEVEL_TRACE
Definition LogCommon.h:27
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:173
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:182
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:176
#define sLog
Definition Log.h:156
#define TC_LOG_WARN(filterType__, message__,...)
Definition Log.h:179
#define TC_LOG_TRACE(filterType__, message__,...)
Definition Log.h:170
@ LOGIN_SEL_BATTLE_PETS
@ LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES
@ LOGIN_INS_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT
@ LOGIN_SEL_ACCOUNT_TOYS
@ LOGIN_SEL_BNET_PLAYER_DATA_FLAGS_ACCOUNT
@ LOGIN_SEL_ACCOUNT_MOUNTS
@ LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID
@ LOGIN_SEL_BNET_TRANSMOG_OUTFITS
@ LOGIN_DEL_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT
@ LOGIN_SEL_ACCOUNT_HEIRLOOMS
@ LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS
@ LOGIN_DEL_BNET_PLAYER_DATA_FLAGS_ACCOUNT
@ LOGIN_SEL_BNET_WARBAND_SCENES
@ LOGIN_INS_BNET_PLAYER_DATA_FLAGS_ACCOUNT
@ LOGIN_SEL_BATTLE_PET_SLOTS
@ LOGIN_SEL_BNET_ITEM_APPEARANCES
@ LOGIN_SEL_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT
#define TC_METRIC_DETAILED_TIMER(category,...)
Definition Metric.h:240
#define TC_METRIC_VALUE(category, value,...)
Definition Metric.h:206
#define TC_METRIC_EVENT(category, title, description)
Definition Metric.h:201
#define TC_METRIC_TAG(name, value)
Definition Metric.h:187
#define sObjectMgr
Definition ObjectMgr.h:1873
OpcodeTable opcodeTable
Definition Opcodes.cpp:37
constexpr uint32 UNKNOWN_OPCODE
Definition Opcodes.h:35
ConnectionType
Definition Opcodes.h:27
@ CONNECTION_TYPE_INSTANCE
Definition Opcodes.h:29
@ CONNECTION_TYPE_DEFAULT
Definition Opcodes.h:32
@ CONNECTION_TYPE_REALM
Definition Opcodes.h:28
constexpr bool IsInstanceOnlyOpcode(uint32 opcode)
Definition Opcodes.h:2558
OpcodeServer
Definition Opcodes.h:1105
constexpr FormattedOpcodeName< OpcodeClient > GetOpcodeNameForLogging(OpcodeClient opcode)
Lookup opcode name for human understandable logging.
Definition Opcodes.h:2639
@ STATUS_IGNORED
Definition Opcodes.h:2588
@ STATUS_LOGGEDIN
Definition Opcodes.h:2583
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition Opcodes.h:2585
@ STATUS_TRANSFER
Definition Opcodes.h:2584
@ STATUS_NEVER
Definition Opcodes.h:2586
@ STATUS_AUTHED
Definition Opcodes.h:2582
@ STATUS_UNHANDLED
Definition Opcodes.h:2587
@ PROCESS_INPLACE
Definition Opcodes.h:2593
@ PROCESS_THREADUNSAFE
Definition Opcodes.h:2594
OpcodeClient
Definition Opcodes.h:38
@ CMSG_TIME_SYNC_RESPONSE
Definition Opcodes.h:1008
@ CMSG_QUERY_PAGE_TEXT
Definition Opcodes.h:787
@ CMSG_TURN_IN_PETITION
Definition Opcodes.h:1026
@ CMSG_CALENDAR_ADD_EVENT
Definition Opcodes.h:150
@ CMSG_ATTACK_STOP
Definition Opcodes.h:66
@ CMSG_SEND_CONTACT_LIST
Definition Opcodes.h:907
@ CMSG_CALENDAR_RSVP
Definition Opcodes.h:162
@ CMSG_ENUM_CHARACTERS
Definition Opcodes.h:351
@ CMSG_CHAT_MESSAGE_YELL
Definition Opcodes.h:229
@ CMSG_EJECT_PASSENGER
Definition Opcodes.h:344
@ CMSG_QUERY_GAME_OBJECT
Definition Opcodes.h:780
@ CMSG_LOGOUT_REQUEST
Definition Opcodes.h:575
@ CMSG_CHAT_MESSAGE_WHISPER
Definition Opcodes.h:228
@ CMSG_PET_RENAME
Definition Opcodes.h:767
@ CMSG_GUILD_SET_RANK_PERMISSIONS
Definition Opcodes.h:456
@ CMSG_CHAT_ADDON_MESSAGE_TARGETED
Definition Opcodes.h:194
@ CMSG_CHAT_MESSAGE_EMOTE
Definition Opcodes.h:220
@ CMSG_SET_SHEATHED
Definition Opcodes.h:952
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition Opcodes.h:883
@ CMSG_REPOP_REQUEST
Definition Opcodes.h:844
@ CMSG_PET_ABANDON
Definition Opcodes.h:753
@ CMSG_CHAT_MESSAGE_CHANNEL
Definition Opcodes.h:218
@ CMSG_QUEST_CONFIRM_ACCEPT
Definition Opcodes.h:802
@ CMSG_DELETE_EQUIPMENT_SET
Definition Opcodes.h:318
@ CMSG_TOGGLE_PVP
Definition Opcodes.h:1012
@ CMSG_GUILD_BANK_DEPOSIT_MONEY
Definition Opcodes.h:418
@ CMSG_SUBMIT_USER_FEEDBACK
Definition Opcodes.h:989
@ CMSG_GUILD_LEAVE
Definition Opcodes.h:438
@ CMSG_CHANGE_SUB_GROUP
Definition Opcodes.h:185
@ CMSG_CHAT_MESSAGE_GUILD
Definition Opcodes.h:221
@ CMSG_GUILD_SET_GUILD_MASTER
Definition Opcodes.h:454
@ CMSG_CONVERT_RAID
Definition Opcodes.h:298
@ CMSG_GUILD_BANK_WITHDRAW_MONEY
Definition Opcodes.h:425
@ CMSG_SET_CONTACT_NOTES
Definition Opcodes.h:925
@ CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK
Definition Opcodes.h:629
@ CMSG_CALENDAR_REMOVE_INVITE
Definition Opcodes.h:161
@ CMSG_GUILD_DELETE_RANK
Definition Opcodes.h:430
@ CMSG_SET_ACTION_BAR_TOGGLES
Definition Opcodes.h:916
@ CMSG_CALENDAR_EVENT_SIGN_UP
Definition Opcodes.h:154
@ CMSG_SAVE_EQUIPMENT_SET
Definition Opcodes.h:894
@ CMSG_QUEST_POI_QUERY
Definition Opcodes.h:814
@ CMSG_SIGN_PETITION
Definition Opcodes.h:964
@ CMSG_SOCKET_GEMS
Definition Opcodes.h:967
@ CMSG_QUERY_CREATURE
Definition Opcodes.h:779
@ CMSG_MOVE_DISMISS_VEHICLE
Definition Opcodes.h:612
@ CMSG_CALENDAR_INVITE
Definition Opcodes.h:158
@ CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT
Definition Opcodes.h:992
@ CMSG_MOVE_HEARTBEAT
Definition Opcodes.h:636
@ CMSG_MOVE_FORCE_GRAVITY_MODIFIER_CHANGE_ACK
Definition Opcodes.h:623
@ CMSG_DUEL_RESPONSE
Definition Opcodes.h:343
@ CMSG_MOVE_TIME_SKIPPED
Definition Opcodes.h:698
@ CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK
Definition Opcodes.h:630
@ CMSG_QUEST_GIVER_QUERY_QUEST
Definition Opcodes.h:809
@ CMSG_COMPLETE_CINEMATIC
Definition Opcodes.h:280
@ CMSG_QUEST_GIVER_REQUEST_REWARD
Definition Opcodes.h:810
@ CMSG_SELF_RES
Definition Opcodes.h:903
@ CMSG_ACTIVATE_TAXI
Definition Opcodes.h:49
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition Opcodes.h:881
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition Opcodes.h:882
@ CMSG_RANDOM_ROLL
Definition Opcodes.h:830
@ CMSG_DECLINE_PETITION
Definition Opcodes.h:317
@ CMSG_REQUEST_VEHICLE_EXIT
Definition Opcodes.h:880
@ CMSG_SET_ASSISTANT_LEADER
Definition Opcodes.h:921
@ CMSG_CHAT_MESSAGE_RAID_WARNING
Definition Opcodes.h:226
@ CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK
Definition Opcodes.h:632
@ CMSG_ACCEPT_GUILD_INVITE
Definition Opcodes.h:40
@ CMSG_OPT_OUT_OF_LOOT
Definition Opcodes.h:735
@ CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition Opcodes.h:622
@ CMSG_DO_READY_CHECK
Definition Opcodes.h:342
@ CMSG_CALENDAR_COMPLAIN
Definition Opcodes.h:152
@ CMSG_CHAT_MESSAGE_SAY
Definition Opcodes.h:227
@ CMSG_AUTOSTORE_BANK_ITEM
Definition Opcodes.h:89
@ CMSG_CHAT_MESSAGE_AFK
Definition Opcodes.h:217
@ CMSG_GUILD_ADD_RANK
Definition Opcodes.h:414
@ CMSG_DISMISS_CRITTER
Definition Opcodes.h:339
@ CMSG_BUG_REPORT
Definition Opcodes.h:142
@ CMSG_QUEST_GIVER_COMPLETE_QUEST
Definition Opcodes.h:807
@ CMSG_CHAR_DELETE
Definition Opcodes.h:191
@ CMSG_CHAR_RACE_OR_FACTION_CHANGE
Definition Opcodes.h:192
@ CMSG_STAND_STATE_CHANGE
Definition Opcodes.h:983
@ CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT
Definition Opcodes.h:352
@ CMSG_CONFIRM_RESPEC_WIPE
Definition Opcodes.h:284
@ CMSG_AUTOBANK_ITEM
Definition Opcodes.h:88
@ CMSG_CHAR_CUSTOMIZE
Definition Opcodes.h:190
@ CMSG_SET_PARTY_LEADER
Definition Opcodes.h:940
@ CMSG_CHAT_MESSAGE_RAID
Definition Opcodes.h:225
@ CMSG_CHARACTER_RENAME_REQUEST
Definition Opcodes.h:187
@ CMSG_BANKER_ACTIVATE
Definition Opcodes.h:101
@ CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK
Definition Opcodes.h:627
@ CMSG_LEAVE_GROUP
Definition Opcodes.h:540
@ CMSG_CALENDAR_COPY_EVENT
Definition Opcodes.h:153
@ CMSG_CHAT_MESSAGE_DND
Definition Opcodes.h:219
@ CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:626
@ CMSG_QUERY_INSPECT_ACHIEVEMENTS
Definition Opcodes.h:783
@ CMSG_MOVE_SET_FACING
Definition Opcodes.h:668
@ CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:628
@ CMSG_CALENDAR_MODERATOR_STATUS
Definition Opcodes.h:159
@ CMSG_ALTER_APPEARANCE
Definition Opcodes.h:59
@ CMSG_TAXI_NODE_STATUS_QUERY
Definition Opcodes.h:1003
@ CMSG_QUERY_QUEST_INFO
Definition Opcodes.h:794
@ CMSG_QUEST_GIVER_CHOOSE_REWARD
Definition Opcodes.h:805
@ CMSG_GUILD_UPDATE_MOTD_TEXT
Definition Opcodes.h:459
@ CMSG_SET_ACTION_BUTTON
Definition Opcodes.h:917
@ CMSG_WRAP_ITEM
Definition Opcodes.h:1062
@ CMSG_GUILD_DECLINE_INVITATION
Definition Opcodes.h:428
@ CMSG_RIDE_VEHICLE_INTERACT
Definition Opcodes.h:891
@ CMSG_MOVE_CHANGE_VEHICLE_SEATS
Definition Opcodes.h:607
@ CMSG_GET_ITEM_PURCHASE_DATA
Definition Opcodes.h:395
@ CMSG_QUEST_GIVER_ACCEPT_QUEST
Definition Opcodes.h:804
@ CMSG_GAME_OBJ_REPORT_USE
Definition Opcodes.h:356
@ CMSG_QUERY_PETITION
Definition Opcodes.h:788
@ CMSG_SET_DUNGEON_DIFFICULTY
Definition Opcodes.h:928
@ CMSG_GUILD_BANK_LOG_QUERY
Definition Opcodes.h:419
@ CMSG_BEGIN_TRADE
Definition Opcodes.h:135
@ CMSG_INSPECT
Definition Opcodes.h:525
@ CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK
Definition Opcodes.h:624
@ CMSG_QUERY_NPC_TEXT
Definition Opcodes.h:786
@ CMSG_QUEST_GIVER_STATUS_QUERY
Definition Opcodes.h:812
@ CMSG_AREA_SPIRIT_HEALER_QUERY
Definition Opcodes.h:60
@ CMSG_SET_PARTY_ASSIGNMENT
Definition Opcodes.h:939
@ CMSG_DEL_FRIEND
Definition Opcodes.h:320
@ CMSG_GUILD_BANK_TEXT_QUERY
Definition Opcodes.h:423
@ CMSG_TAXI_QUERY_AVAILABLE_NODES
Definition Opcodes.h:1004
@ CMSG_QUEST_LOG_REMOVE_QUEST
Definition Opcodes.h:813
@ CMSG_MOVE_SET_PITCH
Definition Opcodes.h:673
@ CMSG_QUERY_NEXT_MAIL_TIME
Definition Opcodes.h:785
@ CMSG_QUEST_GIVER_STATUS_MULTIPLE_QUERY
Definition Opcodes.h:811
@ CMSG_GUILD_EVENT_LOG_QUERY
Definition Opcodes.h:432
@ CMSG_SAVE_GUILD_EMBLEM
Definition Opcodes.h:895
@ CMSG_CHECK_IS_ADVENTURE_MAP_POI_VALID
Definition Opcodes.h:237
@ CMSG_CHAT_ADDON_MESSAGE
Definition Opcodes.h:193
@ CMSG_CHAT_MESSAGE_OFFICER
Definition Opcodes.h:223
@ CMSG_PARTY_INVITE_RESPONSE
Definition Opcodes.h:738
@ CMSG_QUERY_TIME
Definition Opcodes.h:799
@ CMSG_ADD_FRIEND
Definition Opcodes.h:53
@ CMSG_SET_RAID_DIFFICULTY
Definition Opcodes.h:947
@ CMSG_MOVE_SET_FACING_HEARTBEAT
Definition Opcodes.h:669
@ CMSG_GUILD_BANK_SET_TAB_TEXT
Definition Opcodes.h:422
@ CMSG_CALENDAR_GET
Definition Opcodes.h:155
@ CMSG_QUERY_PET_NAME
Definition Opcodes.h:789
@ CMSG_LOGOUT_CANCEL
Definition Opcodes.h:572
@ CMSG_PETITION_RENAME_GUILD
Definition Opcodes.h:750
@ CMSG_BATTLEMASTER_JOIN_ARENA
Definition Opcodes.h:107
@ CMSG_WHO
Definition Opcodes.h:1058
@ CMSG_GUILD_INVITE_BY_NAME
Definition Opcodes.h:437
@ CMSG_HEARTH_AND_RESURRECT
Definition Opcodes.h:460
@ CMSG_GUILD_UPDATE_INFO_TEXT
Definition Opcodes.h:458
@ CMSG_PLAYER_LOGIN
Definition Opcodes.h:772
@ CMSG_CREATE_CHARACTER
Definition Opcodes.h:312
@ CMSG_CALENDAR_UPDATE_EVENT
Definition Opcodes.h:164
@ CMSG_CHAT_MESSAGE_PARTY
Definition Opcodes.h:224
@ CMSG_RESET_INSTANCES
Definition Opcodes.h:888
@ CMSG_GUILD_DELETE
Definition Opcodes.h:429
@ CMSG_HOTFIX_REQUEST
Definition Opcodes.h:462
@ CMSG_PARTY_INVITE
Definition Opcodes.h:737
@ CMSG_GUILD_SET_MEMBER_NOTE
Definition Opcodes.h:455
@ CMSG_BATTLEFIELD_LEAVE
Definition Opcodes.h:102
@ CMSG_PARTY_UNINVITE
Definition Opcodes.h:739
@ CMSG_SET_LOOT_METHOD
Definition Opcodes.h:937
@ CMSG_BUY_ACCOUNT_BANK_TAB
Definition Opcodes.h:146
@ CMSG_ITEM_PURCHASE_REFUND
Definition Opcodes.h:530
@ CMSG_UNLEARN_SKILL
Definition Opcodes.h:1031
@ CMSG_INITIATE_TRADE
Definition Opcodes.h:523
@ CMSG_QUERY_GUILD_INFO
Definition Opcodes.h:782
@ CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT
Definition Opcodes.h:776
@ CMSG_SPELL_CLICK
Definition Opcodes.h:975
@ CMSG_QUERY_PLAYER_NAMES
Definition Opcodes.h:790
@ CMSG_CALENDAR_REMOVE_EVENT
Definition Opcodes.h:160
@ CMSG_UPDATE_RAID_TARGET
Definition Opcodes.h:1040
@ CMSG_REPORT_PVP_PLAYER_AFK
Definition Opcodes.h:845
@ CMSG_GUILD_BANK_BUY_TAB
Definition Opcodes.h:417
@ CMSG_QUERY_CORPSE_TRANSPORT
Definition Opcodes.h:777
@ CMSG_PETITION_BUY
Definition Opcodes.h:749
@ CMSG_GUILD_BANK_QUERY_TAB
Definition Opcodes.h:420
@ CMSG_REQUEST_PARTY_MEMBER_STATS
Definition Opcodes.h:867
@ CMSG_GUILD_BANK_UPDATE_TAB
Definition Opcodes.h:424
@ CMSG_GAME_OBJ_USE
Definition Opcodes.h:357
@ CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:621
#define sOutdoorPvPMgr
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
@ INVENTORY_SLOT_BAG_START
Definition Player.h:759
@ INVENTORY_SLOT_BAG_END
Definition Player.h:760
@ BUYBACK_SLOT_END
Definition Player.h:785
@ BUYBACK_SLOT_START
Definition Player.h:784
@ BANK_SLOT_BAG_END
Definition Player.h:778
@ BANK_SLOT_BAG_START
Definition Player.h:777
@ ACCOUNT_BANK_SLOT_BAG_END
Definition Player.h:817
@ ACCOUNT_BANK_SLOT_BAG_START
Definition Player.h:816
@ PLAYER_DATA_FLAG_VALUE_BITS
Definition Player.h:160
@ REAGENT_BAG_SLOT_END
Definition Player.h:766
@ REAGENT_BAG_SLOT_START
Definition Player.h:765
@ PLAYER_SLOTS_COUNT
Definition Player.h:701
#define DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(result_type, fields_list)
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:43
@ QUEST_FLAGS_FAIL_ON_LOGOUT
Definition QuestDef.h:245
Role Based Access Control related classes definition.
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:43
#define sRealmList
Definition RealmList.h:95
#define sScriptMgr
Definition ScriptMgr.h:1449
constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE
static constexpr uint8 PLAYER_MAX_BATTLEGROUND_QUEUES
@ EXPANSION_BATTLE_FOR_AZEROTH
#define MAX_ACCOUNT_TUTORIAL_VALUES
BanMode
Ban function modes.
@ BAN_ACCOUNT
@ BAN_IP
@ BAN_CHARACTER
@ FRIEND_OFFLINE
Definition SocialMgr.h:72
#define sSocialMgr
Definition SocialMgr.h:173
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
uint32 getMSTime()
Definition Timer.h:33
@ TUTORIALS_FLAG_LOADED_FROM_DB
@ TUTORIALS_FLAG_CHANGED
@ TUTORIALS_FLAG_NONE
#define GLOBAL_CACHE_MASK
AccountDataType
#define NUM_ACCOUNT_DATA_TYPES
bool Initialize(uint32 accountId, uint32)
bool Initialize(uint32 accountId, uint32 battlenetAccountId)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void SetDestroyedObject(bool destroyed)
Definition BaseEntity.h:199
bool IsInWorld() const
Definition BaseEntity.h:158
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
char const * what() const noexcept override
Definition ByteBuffer.h:37
size_t rpos() const
Definition ByteBuffer.h:449
void hexlike() const
void print_storage() const
size_t wpos() const
Definition ByteBuffer.h:462
size_t size() const
Definition ByteBuffer.h:580
Class used to access individual fields of database query result.
Definition Field.h:94
uint32 GetUInt32() const noexcept
Definition Field.cpp:57
uint8 GetUInt8() const noexcept
Definition Field.cpp:29
std::string GetString() const noexcept
Definition Field.cpp:113
int64 GetInt64() const noexcept
Definition Field.cpp:78
Definition Group.h:209
Definition Guild.h:329
void add(T const &item)
Adds an item to the queue.
Definition LockedQueue.h:40
void readd(Iterator begin, Iterator end)
Adds items back to front of the queue.
Definition LockedQueue.h:55
bool next(T &result)
Gets the next result in the queue, if any.
Definition LockedQueue.h:62
virtual bool Process(WorldPacket *packet) override
Definition Map.h:227
LowType GetCounter() const
Definition ObjectGuid.h:336
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
std::string ToString() const
bool IsValid(OpcodeClient index) const
Definition Opcodes.h:2650
virtual bool ProcessUnsafe() const
WorldSession *const m_pSession
void CleanupChannels()
Definition Player.cpp:4763
uint32 GetXP() const
Definition Player.h:1313
bool IsBeingTeleportedFar() const
Definition Player.h:2388
void KillPlayer()
Definition Player.cpp:4355
void SetInvSlot(uint32 slot, ObjectGuid guid)
Definition Player.h:1594
void FailQuestsWithFlag(QuestFlags flag)
Definition Player.cpp:15362
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Player.cpp:379
uint32 GetDeathTimer() const
Definition Player.h:2468
void RemoveSocial()
Definition Player.cpp:30725
ObjectGuid const & GetLootGUID() const
Definition Player.h:2246
bool HasPendingBind() const
Definition Player.h:2764
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:25735
void RepopAtGraveyard()
Definition Player.cpp:4687
void ClearWhisperWhiteList()
Definition Player.h:2852
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:22031
Battleground * GetBattleground() const
Definition Player.cpp:25650
ObjectGuid::LowType GetGuildId() const
Definition Player.h:2147
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition Player.cpp:20000
uint32 GetXPForNextLevel() const
Definition Player.h:1314
void SaveToDB(bool create=false)
Definition Player.cpp:20386
void SetBuybackTimestamp(uint32 slot, time_t timestamp)
Definition Player.h:1616
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2781
void BuildPlayerRepop()
Definition Player.cpp:4212
void UninviteFromGroup()
Definition Player.cpp:2066
void SetBuybackPrice(uint32 slot, uint32 price)
Definition Player.h:1615
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition Player.cpp:25675
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setInt64(uint8 index, int64 value)
void setFloat(uint8 index, float value)
void setUInt64(uint8 index, uint64 value)
void setInt32(uint8 index, int32 value)
void setUInt8(uint8 index, uint8 value)
void SetSize(size_t size)
PreparedQueryResult GetPreparedResult(size_t index) const
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition QueryHolder.h:70
bool SetPreparedQuery(size_t index, PreparedStatement< T > *stmt)
Definition QueryHolder.h:48
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3973
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition Unit.cpp:6031
void ExitAllAreaTriggers()
Definition Unit.cpp:5552
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4832
uint8 GetLevel() const
Definition Unit.h:769
Map * FindMap() const
Definition Object.h:412
std::string const & GetName() const
Definition Object.h:342
uint32 GetZoneId() const
Definition Object.h:332
ConnectionType GetConnection() const
Definition WorldPacket.h:65
uint32 GetOpcode() const
Definition WorldPacket.h:62
WorldPacket const * Write() override
std::vector< ConnectPayload > Payload
Array< std::string, MAX_PREFIXES > Prefixes
std::array< Timestamp<>, NUM_ACCOUNT_DATA_TYPES > AccountTimes
OpcodeClient GetOpcode() const
Definition Packet.h:68
WorldPacket const * Write() override
WorldPacket const * Write() override
std::array< uint32, MAX_ACCOUNT_TUTORIAL_VALUES > TutorialData
bool Process(WorldPacket *packet) override
bool EvaluateOpcode(WorldPacket &p, time_t time) const
uint32 GetMaxPacketCounterAllowed(uint32 opcode) const
PacketThrottlingMap _PacketThrottlingMap
Player session in the World.
void HandleUnregisterAllAddonPrefixesOpcode(WorldPackets::Chat::ChatUnregisterAllAddonPrefixes &packet)
void SetPlayer(Player *player)
bool m_playerRecentlyLogout
bool Update(uint32 diff, PacketFilter &updater)
Update the WorldSession (triggered by World update)
std::unique_ptr< Battlenet::Account > _battlenetAccount
void LogoutPlayer(bool save)
Log the player out
uint8 _tutorialsChanged
AccountData _accountData[NUM_ACCOUNT_DATA_TYPES]
char const * GetTrinityString(uint32 entry) const
ObjectGuid GetBattlenetAccountGUID() const
void LoadTutorialsData(PreparedQueryResult result)
void UpdateInstanceEnterTimes()
void SendClientCacheVersion(uint32 version)
void SetPlayerDataFlagAccount(uint32 dataFlagId, bool on)
void SendConnectToInstance(WorldPackets::Auth::ConnectToSerial serial)
void HandleMoveWorldportAck()
void SendNotification(char const *format,...) ATTR_PRINTF(2
std::array< std::shared_ptr< WorldSocket >, MAX_CONNECTION_TYPES > m_Socket
bool CanAccessAlliedRaces() const
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
void SendAuthResponse(uint32 code, bool queued, uint32 queuePos=0)
void LoadPlayerDataAccount(PreparedQueryResult const &elementsResult, PreparedQueryResult const &flagsResult)
QueryCallbackProcessor _queryProcessor
std::array< uint32, MAX_ACCOUNT_TUTORIAL_VALUES > _tutorials
AccountTypes GetSecurity() const
LocaleConstant GetSessionDbLocaleIndex() const
rbac::RBACData * GetRBACData() const
bool PlayerDisconnected() const
bool DisallowHyperlinksAndMaybeKick(std::string const &str)
class WorldSession::DosProtection AntiDOS
void LoadAccountData(PreparedQueryResult result, uint32 mask)
std::atomic< time_t > m_timeOutTime
uint64 GetConnectToInstanceKey() const
uint32 _timeSyncTimer
std::unordered_map< uint32, uint8 > _realmCharacterCounts
WorldSession(uint32 id, std::string &&name, uint32 battlenetAccountId, std::string &&battlenetAccountEmail, std::shared_ptr< WorldSocket > &&sock, AccountTypes sec, uint8 expansion, time_t mute_time, std::string &&os, Minutes timezoneOffset, uint32 build, ClientBuild::VariantId clientBuildVariant, LocaleConstant locale, uint32 recruiter, bool isARecruiter)
WorldSession constructor.
std::string GetPlayerInfo() const
Player * GetPlayer() const
rbac::RBACData * _RBACData
std::unique_ptr< CollectionMgr > _collectionMgr
void SendAuthWaitQueue(uint32 position)
Handle the authentication waiting queue (to be completed)
void Handle_EarlyProccess(WorldPackets::Null &null)
~WorldSession()
WorldSession destructor.
void SetLogoutStartTime(time_t requestTime)
Engage the logout process for the user.
void SendSetTimeZoneInformation()
void LogUnexpectedOpcode(WorldPacket *packet, char const *status, const char *reason)
Logging helper for unexpected opcodes.
void RegisterTimeSync(uint32 counter)
std::string _accountName
AccountData const * GetAccountData(AccountDataType type) const
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
bool CanSpeak() const
uint32 _timeSyncNextCounter
void SavePlayerDataAccount(LoginDatabaseTransaction const &transaction)
void Handle_NULL(WorldPackets::Null &null)
ObjectGuid m_playerLoading
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
QueryCallback LoadPermissionsAsync()
void SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans)
std::string const & GetRemoteAddress() const
void SetInQueue(bool state)
Session in auth.queue currently.
ObjectGuid::LowType m_GUIDLow
bool HasPermission(uint32 permissionId)
void LoadInstanceTimeRestrictions(PreparedQueryResult result)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetBattlenetAccountId() const
PlayerDataAccount _playerDataAccount
uint32 GetAccountId() const
uint8 GetAccountExpansion() const
ConnectToKey _instanceConnectKey
void SendTutorialsData()
std::unordered_map< uint32, SystemTimePoint > _instanceResetTimes
void QueuePacket(WorldPacket &&new_packet)
Add an incoming packet to the queue.
Player * _player
void SetPlayerDataElementAccount(uint32 dataElementId, float value)
bool UpdateAndCheckInstanceCount(uint32 instanceId)
uint32 GetLatency() const
void ProcessQueryCallbacks()
void InitializeSessionCallback(LoginDatabaseQueryHolder const &holder, CharacterDatabaseQueryHolder const &realmHolder)
void HandleAddonRegisteredPrefixesOpcode(WorldPackets::Chat::ChatRegisterAddonPrefixes &packet)
void DoLootReleaseAll()
std::vector< std::string > _registeredAddonPrefixes
void SendAccountDataTimes(ObjectGuid playerGuid, uint32 mask)
bool IsAddonRegistered(std::string_view prefix) const
void HandleContinuePlayerLogin()
void SaveTutorialsData(CharacterDatabaseTransaction trans)
LockedQueue< WorldPacket * > _recvQueue
std::string const & GetPlayerName() const
void ResetTimeOutTime(bool onlyActive)
void InitializeSession()
void KickPlayer(std::string_view reason)
Kick a player out of the World.
void InvalidateRBACData()
static void AddInstanceConnection(WorldSession *session, std::weak_ptr< WorldSocket > sockRef, ConnectToKey key)
void SetAccountData(AccountDataType type, time_t time, std::string const &data)
void SendFeatureSystemStatusGlueScreen()
void LogUnprocessedTail(WorldPacket const *packet)
Logging helper for unexpected opcodes.
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
bool ValidateHyperlinksAndMaybeKick(std::string const &str)
AsyncCallbackProcessor< TransactionCallback > _transactionCallbacks
void SendAvailableHotfixes()
bool IsConnectionIdle() const
std::unique_ptr< BattlePets::BattlePetMgr > _battlePetMgr
void AddInstanceEnterTime(uint32 instanceId, SystemTimePoint enterTime)
bool _filterAddonMessages
std::map< uint32, int64 > _pendingTimeSyncRequests
uint32 GetId() const
Gets the Id of the Object.
Definition RBAC.h:827
QueryCallback LoadFromDBAsync()
Definition RBAC.cpp:200
std::string const & GetName() const
Gets the Name of the Object.
Definition RBAC.h:825
void LoadFromDB()
Loads all permissions assigned to current account.
Definition RBAC.cpp:187
bool HasPermission(uint32 permission) const
Definition RBAC.h:845
#define sWorld
Definition World.h:919
uint32 GetVirtualRealmAddress()
Definition World.cpp:3500
@ CONFIG_MAX_INSTANCES_PER_HOUR
Definition World.h:379
@ CONFIG_SOCKET_TIMEOUTTIME
Definition World.h:245
@ CONFIG_CLIENTCACHE_VERSION
Definition World.h:358
@ CONFIG_PACKET_SPOOF_BANDURATION
Definition World.h:397
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition World.h:427
@ CONFIG_PACKET_SPOOF_POLICY
Definition World.h:395
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition World.h:318
@ CONFIG_PACKET_SPOOF_BANMODE
Definition World.h:396
@ CONFIG_EXPANSION
Definition World.h:306
@ CONFIG_PORT_WORLD
Definition World.h:244
SystemTimePoint GetSystemTime()
Current chrono system_clock time point.
Definition GameTime.cpp:62
time_t GetGameTime()
Definition GameTime.cpp:52
constexpr void EraseIf(Container &c, Predicate p)
Definition Containers.h:283
constexpr decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
Definition Containers.h:299
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
struct advstd::ranges::Contains contains
@ RBAC_PERM_IGNORE_IDLE_CONNECTION
Definition RBAC.h:60
std::string Data
HandlerFunction Call
Definition Opcodes.h:2607
SessionStatus Status
Definition Opcodes.h:2606
char const * Name
Definition Opcodes.h:2605
PacketProcessing ProcessingPlace
Definition Opcodes.h:2608
uint32 amountCounter
time_t lastReceiveTime
PlayerDataElementType GetType() const
SessionStatus Status
Definition Opcodes.h:2614
ConnectionType ConnectionIndex
Definition Opcodes.h:2615
union WorldPackets::Auth::ConnectTo::SocketAddress::@312 Address
std::vector< Element > Elements
struct WorldSession::ConnectToKey::@320 Fields