TrinityCore
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 "QueryHolder.h"
24#include "AccountMgr.h"
26#include "BattlePetMgr.h"
27#include "BattlegroundMgr.h"
28#include "BattlenetPackets.h"
29#include "CharacterPackets.h"
30#include "ChatPackets.h"
31#include "ClientConfigPackets.h"
32#include "DatabaseEnv.h"
33#include "GameTime.h"
34#include "Group.h"
35#include "Guild.h"
36#include "GuildMgr.h"
37#include "Hyperlinks.h"
38#include "IpAddress.h"
39#include "Log.h"
40#include "Map.h"
41#include "Metric.h"
42#include "MiscPackets.h"
43#include "ObjectMgr.h"
44#include "OutdoorPvPMgr.h"
45#include "PacketUtilities.h"
46#include "Player.h"
47#include "QueryHolder.h"
48#include "Random.h"
49#include "RBAC.h"
50#include "Realm.h"
51#include "ScriptMgr.h"
52#include "SocialMgr.h"
53#include "WardenWin.h"
54#include "World.h"
55#include "WorldSocket.h"
56#include <boost/circular_buffer.hpp>
57
58namespace {
59
60std::string const DefaultPlayerName = "<none>";
61
62} // namespace
63
65{
66 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
67
68 //let's check if our opcode can be really processed in Map::Update()
69 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
70 return true;
71
72 //we do not process thread-unsafe packets
74 return false;
75
76 Player* player = m_pSession->GetPlayer();
77 if (!player)
78 return false;
79
80 //in Map::Update() we do not process packets where player is not in world!
81 return player->IsInWorld();
82}
83
84//we should process ALL packets when player is not in world/logged in
85//OR packet handler is not thread-safe!
87{
88 ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
89
90 //check if packet handler is supposed to be safe
91 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
92 return true;
93
94 //thread-unsafe packets should be processed in World::UpdateSessions()
96 return true;
97
98 //no player attached? -> our client! ^^
99 Player* player = m_pSession->GetPlayer();
100 if (!player)
101 return true;
102
103 //lets process all packets for non-in-the-world player
104 return (player->IsInWorld() == false);
105}
106
108WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
109 std::string os, Minutes timezoneOffset, 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 _security(sec),
116 _accountId(id),
117 _accountName(std::move(name)),
118 _battlenetAccountId(battlenetAccountId),
119 m_accountExpansion(expansion),
120 m_expansion(std::min<uint8>(expansion, sWorld->getIntConfig(CONFIG_EXPANSION))),
121 _os(std::move(os)),
122 _battlenetRequestToken(0),
123 _logoutTime(0),
124 m_inQueue(false),
125 m_playerLogout(false),
126 m_playerRecentlyLogout(false),
127 m_playerSave(false),
128 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
129 m_sessionDbLocaleIndex(locale),
130 _timezoneOffset(timezoneOffset),
131 m_latency(0),
132 _tutorialsChanged(TUTORIALS_FLAG_NONE),
133 _filterAddonMessages(false),
134 recruiterId(recruiter),
135 isRecruiter(isARecruiter),
136 _RBACData(nullptr),
137 expireTime(60000), // 1 min after socket loss, session is deleted
138 forceExit(false),
139 _timeSyncClockDeltaQueue(std::make_unique<boost::circular_buffer<std::pair<int64, uint32>>>(6)),
140 _timeSyncClockDelta(0),
141 _pendingTimeSyncRequests(),
142 _timeSyncNextCounter(0),
143 _timeSyncTimer(0),
144 _calendarEventCreationCooldown(0),
145 _battlePetMgr(std::make_unique<BattlePets::BattlePetMgr>(this)),
146 _collectionMgr(std::make_unique<CollectionMgr>(this))
147{
148 memset(_tutorials, 0, sizeof(_tutorials));
149
150 if (sock)
151 {
152 m_Address = sock->GetRemoteIpAddress().to_string();
153 ResetTimeOutTime(false);
154 LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
155 }
156
157 m_Socket[CONNECTION_TYPE_REALM] = std::move(sock);
159}
160
163{
165 if (_player)
166 LogoutPlayer (true);
167
169 for (uint8 i = 0; i < 2; ++i)
170 {
171 if (m_Socket[i])
172 {
173 m_Socket[i]->CloseSocket();
174 m_Socket[i].reset();
175 }
176 }
177
178 delete _RBACData;
179
181 WorldPacket* packet = nullptr;
182 while (_recvQueue.next(packet))
183 delete packet;
184
185 LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
186}
187
189{
192}
193
194std::string const & WorldSession::GetPlayerName() const
195{
196 return _player != nullptr ? _player->GetName() : DefaultPlayerName;
197}
198
200{
201 std::ostringstream ss;
202
203 ss << "[Player: ";
205 ss << "Logging in: " << m_playerLoading.ToString() << ", ";
206 else if (_player)
207 ss << _player->GetName() << ' ' << _player->GetGUID().ToString() << ", ";
208
209 ss << "Account: " << GetAccountId() << "]";
210
211 return ss.str();
212}
213
215void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
216{
217 if (packet->GetOpcode() == NULL_OPCODE)
218 {
219 TC_LOG_ERROR("network.opcode", "Prevented sending of NULL_OPCODE to {}", GetPlayerInfo());
220 return;
221 }
222 else if (packet->GetOpcode() == UNKNOWN_OPCODE)
223 {
224 TC_LOG_ERROR("network.opcode", "Prevented sending of UNKNOWN_OPCODE to {}", GetPlayerInfo());
225 return;
226 }
227
228 ServerOpcodeHandler const* handler = opcodeTable[static_cast<OpcodeServer>(packet->GetOpcode())];
229
230 if (!handler)
231 {
232 TC_LOG_ERROR("network.opcode", "Prevented sending of opcode {} with non existing handler to {}", packet->GetOpcode(), GetPlayerInfo());
233 return;
234 }
235
236 // Default connection index defined in Opcodes.cpp table
237 ConnectionType conIdx = handler->ConnectionIndex;
238
239 // Override connection index
240 if (packet->GetConnection() != CONNECTION_TYPE_DEFAULT)
241 {
243 {
244 TC_LOG_ERROR("network.opcode", "Prevented sending of instance only opcode {} with connection type {} to {}", packet->GetOpcode(), uint32(packet->GetConnection()), GetPlayerInfo());
245 return;
246 }
247
248 conIdx = packet->GetConnection();
249 }
250
251 if (!m_Socket[conIdx])
252 {
253 TC_LOG_ERROR("network.opcode", "Prevented sending of {} to non existent socket {} to {}", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())), uint32(conIdx), GetPlayerInfo());
254 return;
255 }
256
257 if (!forced)
258 {
259 if (handler->Status == STATUS_UNHANDLED)
260 {
261 TC_LOG_ERROR("network.opcode", "Prevented sending disabled opcode {} to {}", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())), GetPlayerInfo());
262 return;
263 }
264 }
265
266#ifdef TRINITY_DEBUG
267 // Code for network use statistic
268 static uint64 sendPacketCount = 0;
269 static uint64 sendPacketBytes = 0;
270
271 static time_t firstTime = GameTime::GetGameTime();
272 static time_t lastTime = firstTime; // next 60 secs start time
273
274 static uint64 sendLastPacketCount = 0;
275 static uint64 sendLastPacketBytes = 0;
276
277 time_t cur_time = GameTime::GetGameTime();
278
279 if ((cur_time - lastTime) < 60)
280 {
281 sendPacketCount += 1;
282 sendPacketBytes += packet->size();
283
284 sendLastPacketCount += 1;
285 sendLastPacketBytes += packet->size();
286 }
287 else
288 {
289 uint64 minTime = uint64(cur_time - lastTime);
290 uint64 fullTime = uint64(lastTime - firstTime);
291 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));
292 TC_LOG_DEBUG("misc", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount)/minTime, float(sendLastPacketBytes)/minTime);
293
294 lastTime = cur_time;
295 sendLastPacketCount = 1;
296 sendLastPacketBytes = packet->wpos(); // wpos is real written size
297 }
298#endif // !TRINITY_DEBUG
299
300 sScriptMgr->OnPacketSend(this, *packet);
301
302 TC_LOG_TRACE("network.opcode", "S->C: {} {}", GetPlayerInfo(), GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())));
303 m_Socket[conIdx]->SendPacket(*packet);
304}
305
308{
309 _recvQueue.add(new_packet);
310}
311
313void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, char const* status, const char *reason)
314{
315 TC_LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
316 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
317}
318
321{
322 if (!sLog->ShouldLog("network.opcode", LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
323 return;
324
325 TC_LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
326 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
327 packet->print_storage();
328}
329
332{
337 m_Socket[CONNECTION_TYPE_REALM]->CloseSocket();
338
341 WorldPacket* packet = nullptr;
343 bool deletePacket = true;
344 std::vector<WorldPacket*> requeuePackets;
345 uint32 processedPackets = 0;
346 time_t currentTime = GameTime::GetGameTime();
347
348 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 100;
349
350 while (m_Socket[CONNECTION_TYPE_REALM] && _recvQueue.next(packet, updater))
351 {
352 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
353 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
354 TC_METRIC_DETAILED_TIMER("worldsession_update_opcode_time", TC_METRIC_TAG("opcode", opHandle->Name));
355
356 try
357 {
358 switch (opHandle->Status)
359 {
360 case STATUS_LOGGEDIN:
361 if (!_player)
362 {
363 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
367 {
368 requeuePackets.push_back(packet);
369 deletePacket = false;
370 TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode {} with with status STATUS_LOGGEDIN. "
371 "Player is currently not in world yet.", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())));
372 }
373 }
374 else if (_player->IsInWorld())
375 {
376 if(AntiDOS.EvaluateOpcode(*packet, currentTime))
377 {
378 sScriptMgr->OnPacketReceive(this, *packet);
379 opHandle->Call(this, *packet);
380 }
381 else
382 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
383 }
384 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
385 break;
387 if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
388 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
389 "the player has not logged in yet and not recently logout");
390 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
391 {
392 // not expected _player or must checked in packet hanlder
393 sScriptMgr->OnPacketReceive(this, *packet);
394 opHandle->Call(this, *packet);
395 }
396 else
397 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
398 break;
399 case STATUS_TRANSFER:
400 if (!_player)
401 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
402 else if (_player->IsInWorld())
403 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
404 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
405 {
406 sScriptMgr->OnPacketReceive(this, *packet);
407 opHandle->Call(this, *packet);
408 }
409 else
410 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
411 break;
412 case STATUS_AUTHED:
413 // prevent cheating with skip queue wait
414 if (m_inQueue)
415 {
416 LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
417 break;
418 }
419
420 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
421 // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
422 if (packet->GetOpcode() == CMSG_ENUM_CHARACTERS)
424
425 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_NEVER:
434 TC_LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode()))
435 , GetPlayerInfo());
436 break;
437 case STATUS_UNHANDLED:
438 TC_LOG_ERROR("network.opcode", "Received not handled opcode {} from {}", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode()))
439 , GetPlayerInfo());
440 break;
441 }
442 }
444 {
445 TC_LOG_ERROR("network", "{} sent {} with an invalid link:\n{}", GetPlayerInfo(),
446 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
447
449 KickPlayer("WorldSession::Update Invalid chat link");
450 }
452 {
453 TC_LOG_ERROR("network", "{} sent {} which illegally contained a hyperlink:\n{}", GetPlayerInfo(),
454 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
455
457 KickPlayer("WorldSession::Update Illegal chat link");
458 }
460 {
461 TC_LOG_ERROR("network", "PacketArrayMaxCapacityException: {} while parsing {} from {}.",
462 pamce.what(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
463 }
464 catch (ByteBufferException const&)
465 {
466 TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: {}) from client {}, accountid={}. Skipped packet.",
467 packet->GetOpcode(), GetRemoteAddress(), GetAccountId());
468 packet->hexlike();
469 }
470
471 if (deletePacket)
472 delete packet;
473
474 deletePacket = true;
475
476 processedPackets++;
477
478 //process only a max amout of packets in 1 Update() call.
479 //Any leftover will be processed in next update
480 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
481 break;
482 }
483
484 TC_METRIC_VALUE("processed_packets", processedPackets);
485
486 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
487
488 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
489 {
490 // Send time sync packet every 10s.
491 if (_timeSyncTimer > 0)
492 {
493 if (diff >= _timeSyncTimer)
494 SendTimeSync();
495 else
496 _timeSyncTimer -= diff;
497 }
498 }
499
501
502 //check if we are safe to proceed with logout
503 //logout procedure should happen only in World::UpdateSessions() method!!!
504 if (updater.ProcessUnsafe())
505 {
507 _warden->Update(diff);
508
510 if (ShouldLogOut(currentTime) && m_playerLoading.IsEmpty())
511 LogoutPlayer(true);
512
516 {
517 if (GetPlayer() && _warden)
518 _warden->Update(diff);
519
520 expireTime -= expireTime > diff ? diff : expireTime;
521 if (expireTime < diff || forceExit || !GetPlayer())
522 {
524 {
525 m_Socket[CONNECTION_TYPE_REALM]->CloseSocket();
527 }
529 {
530 m_Socket[CONNECTION_TYPE_INSTANCE]->CloseSocket();
532 }
533 }
534 }
535
537 return false; //Will remove this session from the world session map
538 }
539
540 return true;
541}
542
545{
546 // finish pending transfers before starting the logout
549
550 m_playerLogout = true;
551 m_playerSave = save;
552
553 if (_player)
554 {
555 if (!_player->GetLootGUID().IsEmpty())
557
559 if (_player->GetDeathTimer())
560 {
564 }
566 {
567 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
572 }
573 else if (_player->HasPendingBind())
574 {
576 _player->SetPendingBind(0, 0);
577 }
578
579 //drop a flag if player is carrying it
581 bg->EventPlayerLoggedOut(_player);
582
586
587 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
588
589 for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
590 {
592 if (bgQueueTypeId != BATTLEGROUND_QUEUE_NONE)
593 {
594 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
595 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
596 queue.RemovePlayer(_player->GetGUID(), true);
597 }
598 }
599
600 // Repop at Graveyard or other player far teleport will prevent saving player because of not present map
601 // Teleport player immediately for correct player save
604
606 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
607 guild->HandleMemberLogout(this);
608
610 _player->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
611
613 if (_battlePetMgr->HasJournalLock())
614 _battlePetMgr->ToggleJournalLock(false);
615
618
620
622 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
623 if (save)
624 {
625 uint32 eslot;
626 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
627 {
628 eslot = j - BUYBACK_SLOT_START;
630 _player->SetBuybackPrice(eslot, 0);
631 _player->SetBuybackTimestamp(eslot, 0);
632 }
633 _player->SaveToDB();
634 }
635
638
641
643 if (Group* group = _player->GetGroup())
644 {
645 group->SendUpdate();
646 if (group->GetLeaderGUID() == _player->GetGUID())
647 group->StartLeaderOfflineTimer();
648 }
649
651 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
653
655 sScriptMgr->OnPlayerLogout(_player);
656
657 TC_METRIC_EVENT("player_events", "Logout", _player->GetName());
658
660 // the player may not be in the world when logging out
661 // e.g if he got disconnected during a transfer to another map
662 // calls to GetMap in this case may cause crashes
665 TC_LOG_INFO("entities.player.character", "Account: {} (IP: {}) Logout Character:[{}] {} Level: {}, XP: {}/{} ({} left)",
668
669 if (Map* _map = _player->FindMap())
670 _map->RemovePlayerFromMap(_player, true);
671
672 SetPlayer(nullptr);
673
677 TC_LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
678
681 stmt->setUInt32(0, GetAccountId());
682 CharacterDatabase.Execute(stmt);
683 }
684
686 {
687 m_Socket[CONNECTION_TYPE_INSTANCE]->CloseSocket();
689 }
690
691 m_playerLogout = false;
692 m_playerSave = false;
695}
696
698void WorldSession::KickPlayer(std::string const& reason)
699{
700 TC_LOG_INFO("network.kick", "Account: {} Character: '{}' {} kicked with reason: {}", GetAccountId(), _player ? _player->GetName() : "<none>",
701 _player ? _player->GetGUID().ToString() : "", reason);
702
703 for (uint8 i = 0; i < 2; ++i)
704 {
705 if (m_Socket[i])
706 {
707 m_Socket[i]->CloseSocket();
708 forceExit = true;
709 }
710 }
711}
712
714{
716 return true;
717
718 TC_LOG_ERROR("network", "Player {}{} sent a message with an invalid link:\n{}", GetPlayer()->GetName(),
719 GetPlayer()->GetGUID().ToString(), str);
720
722 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
723
724 return false;
725}
726
728{
729 if (str.find('|') == std::string::npos)
730 return true;
731
732 TC_LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n{}", GetPlayer()->GetName(),
733 GetPlayer()->GetGUID().ToString(), str);
734
736 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
737
738 return false;
739}
740
741void WorldSession::SendNotification(char const* format, ...)
742{
743 if (format)
744 {
745 va_list ap;
746 char szStr[1024];
747 szStr[0] = '\0';
748 va_start(ap, format);
749 vsnprintf(szStr, 1024, format, ap);
750 va_end(ap);
751
753 }
754}
755
757{
758 char const* format = GetTrinityString(stringId);
759 if (format)
760 {
761 va_list ap;
762 char szStr[1024];
763 szStr[0] = '\0';
764 va_start(ap, stringId);
765 vsnprintf(szStr, 1024, format, ap);
766 va_end(ap);
767
769 }
770}
771
773{
775}
776
778{
779 return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex());
780}
781
783{
784 if (GetPlayer())
786 else if (!onlyActive)
788}
789
791{
793}
794
796{
797 TC_LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}", GetOpcodeNameForLogging(null.GetOpcode()), GetPlayerInfo());
798}
799
801{
802 TC_LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}"
804}
805
807{
808 boost::system::error_code ignored_error;
809 boost::asio::ip::address instanceAddress = realm.GetAddressForClient(Trinity::Net::make_address(GetRemoteAddress(), ignored_error));
810
813 _instanceConnectKey.Fields.Key = urand(0, 0x7FFFFFFF);
814
816 connectTo.Key = _instanceConnectKey.Raw;
817 connectTo.Serial = serial;
818 connectTo.Payload.Port = sWorld->getIntConfig(CONFIG_PORT_INSTANCE);
819 if (instanceAddress.is_v4())
820 {
821 memcpy(connectTo.Payload.Where.Address.V4.data(), instanceAddress.to_v4().to_bytes().data(), 4);
823 }
824 else
825 {
826 memcpy(connectTo.Payload.Where.Address.V6.data(), instanceAddress.to_v6().to_bytes().data(), 16);
828 }
829 connectTo.Con = CONNECTION_TYPE_INSTANCE;
830
831 SendPacket(connectTo.Write());
832}
833
835{
836 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
837 if (mask & (1 << i))
839
840 if (!result)
841 return;
842
843 do
844 {
845 Field* fields = result->Fetch();
846 uint32 type = fields[0].GetUInt8();
847 if (type >= NUM_ACCOUNT_DATA_TYPES)
848 {
849 TC_LOG_ERROR("misc", "Table `{}` have invalid account data type ({}), ignore.",
850 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
851 continue;
852 }
853
854 if ((mask & (1 << type)) == 0)
855 {
856 TC_LOG_ERROR("misc", "Table `{}` have non appropriate for table account data type ({}), ignore.",
857 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
858 continue;
859 }
860
861 _accountData[type].Time = fields[1].GetInt64();
862 _accountData[type].Data = fields[2].GetString();
863 }
864 while (result->NextRow());
865}
866
867void WorldSession::SetAccountData(AccountDataType type, time_t time, std::string const& data)
868{
869 if ((1 << type) & GLOBAL_CACHE_MASK)
870 {
872 stmt->setUInt32(0, GetAccountId());
873 stmt->setUInt8(1, type);
874 stmt->setInt64(2, time);
875 stmt->setString(3, data);
876 CharacterDatabase.Execute(stmt);
877 }
878 else
879 {
880 // _player can be NULL and packet received after logout but m_GUID still store correct guid
881 if (!m_GUIDLow)
882 return;
883
885 stmt->setUInt64(0, m_GUIDLow);
886 stmt->setUInt8(1, type);
887 stmt->setInt64(2, time);
888 stmt->setString(3, data);
889 CharacterDatabase.Execute(stmt);
890 }
891
892 _accountData[type].Time = time;
893 _accountData[type].Data = data;
894}
895
897{
899 accountDataTimes.PlayerGuid = playerGuid;
900 accountDataTimes.ServerTime = GameTime::GetSystemTime();
901 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
902 if (mask & (1 << i))
903 accountDataTimes.AccountTimes[i] = GetAccountData(AccountDataType(i))->Time;
904
905 SendPacket(accountDataTimes.Write());
906}
907
909{
910 memset(_tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
911
912 if (result)
913 {
914 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
915 _tutorials[i] = (*result)[i].GetUInt32();
917 }
918
919 _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
920}
921
923{
925 memcpy(packet.TutorialData, _tutorials, sizeof(_tutorials));
926 SendPacket(packet.Write());
927}
928
930{
932 return;
933
934 bool const hasTutorialsInDB = (_tutorialsChanged & TUTORIALS_FLAG_LOADED_FROM_DB) != 0;
935 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(hasTutorialsInDB ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
936 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
937 stmt->setUInt32(i, _tutorials[i]);
939 trans->Append(stmt);
940
941 // now has, set flag so next save uses update query
942 if (!hasTutorialsInDB)
944
945 _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED;
946}
947
948bool WorldSession::IsAddonRegistered(std::string_view prefix) const
949{
950 if (!_filterAddonMessages) // if we have hit the softcap (64) nothing should be filtered
951 return true;
952
953 if (_registeredAddonPrefixes.empty())
954 return false;
955
956 std::vector<std::string>::const_iterator itr = std::find(_registeredAddonPrefixes.begin(), _registeredAddonPrefixes.end(), prefix);
957 return itr != _registeredAddonPrefixes.end();
958}
959
961{
963}
964
966{
967 // This is always sent after CMSG_CHAT_UNREGISTER_ALL_ADDON_PREFIXES
970 {
971 _filterAddonMessages = false;
972 return;
973 }
974
976}
977
979{
980 _player = player;
981
982 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
983 if (_player)
985}
986
988{
992}
993
995{
996 return _transactionCallbacks.AddCallback(std::move(callback));
997}
998
1000{
1001 return _queryHolderProcessor.AddCallback(std::move(callback));
1002}
1003
1005{
1007}
1008
1010{
1011 if (_os == "Win")
1012 {
1013 _warden = std::make_unique<WardenWin>();
1014 _warden->Init(this, k);
1015 }
1016 else if (_os == "Wn64")
1017 {
1018 // Not implemented
1019 }
1020 else if (_os == "Mc64")
1021 {
1022 // Not implemented
1023 }
1024}
1025
1027{
1028 uint32 id = GetAccountId();
1029 uint8 secLevel = GetSecurity();
1030
1031 TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1032 id, _accountName, realm.Id.Realm, secLevel);
1033
1034 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1036}
1037
1039{
1040 uint32 id = GetAccountId();
1041 uint8 secLevel = GetSecurity();
1042
1043 TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: {}, Name: {}, realmId: {}, secLevel: {}]",
1044 id, _accountName, realm.Id.Realm, secLevel);
1045
1046 _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
1047 return _RBACData->LoadFromDBAsync();
1048}
1049
1051{
1052public:
1053 enum
1054 {
1057
1060
1062
1063 bool Initialize(uint32 accountId, uint32 /*battlenetAccountId*/)
1064 {
1065 bool ok = true;
1066
1068 stmt->setUInt32(0, accountId);
1069 ok = SetPreparedQuery(GLOBAL_ACCOUNT_DATA, stmt) && ok;
1070
1071 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS);
1072 stmt->setUInt32(0, accountId);
1073 ok = SetPreparedQuery(TUTORIALS, stmt) && ok;
1074
1075 return ok;
1076 }
1077};
1078
1080{
1081public:
1082 enum
1083 {
1093
1096
1098
1099 bool Initialize(uint32 accountId, uint32 battlenetAccountId)
1100 {
1101 bool ok = true;
1102
1104 stmt->setUInt32(0, battlenetAccountId);
1105 ok = SetPreparedQuery(GLOBAL_ACCOUNT_TOYS, stmt) && ok;
1106
1107 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BATTLE_PETS);
1108 stmt->setUInt32(0, battlenetAccountId);
1109 stmt->setInt32(1, realm.Id.Realm);
1110 ok = SetPreparedQuery(BATTLE_PETS, stmt) && ok;
1111
1112 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BATTLE_PET_SLOTS);
1113 stmt->setUInt32(0, battlenetAccountId);
1114 ok = SetPreparedQuery(BATTLE_PET_SLOTS, stmt) && ok;
1115
1116 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_HEIRLOOMS);
1117 stmt->setUInt32(0, battlenetAccountId);
1119
1120 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MOUNTS);
1121 stmt->setUInt32(0, battlenetAccountId);
1122 ok = SetPreparedQuery(MOUNTS, stmt) && ok;
1123
1125 stmt->setUInt32(0, accountId);
1127
1128 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ITEM_APPEARANCES);
1129 stmt->setUInt32(0, battlenetAccountId);
1130 ok = SetPreparedQuery(ITEM_APPEARANCES, stmt) && ok;
1131
1132 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES);
1133 stmt->setUInt32(0, battlenetAccountId);
1135
1136 stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS);
1137 stmt->setUInt32(0, battlenetAccountId);
1138 ok = SetPreparedQuery(TRANSMOG_ILLUSIONS, stmt) && ok;
1139
1140 return ok;
1141 }
1142};
1143
1145{
1146 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1147 if (!realmHolder->Initialize(GetAccountId(), GetBattlenetAccountId()))
1148 {
1150 return;
1151 }
1152
1153 std::shared_ptr<AccountInfoQueryHolder> holder = std::make_shared<AccountInfoQueryHolder>();
1154 if (!holder->Initialize(GetAccountId(), GetBattlenetAccountId()))
1155 {
1157 return;
1158 }
1159
1160 struct ForkJoinState
1161 {
1162 std::shared_ptr<AccountInfoQueryHolderPerRealm> Character;
1163 std::shared_ptr<AccountInfoQueryHolder> Login;
1164 };
1165
1166 std::shared_ptr<ForkJoinState> state = std::make_shared<ForkJoinState>();
1167
1168 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this, state, realmHolder](SQLQueryHolderBase const& /*result*/)
1169 {
1170 state->Character = realmHolder;
1171 if (state->Login && state->Character)
1172 InitializeSessionCallback(*state->Login, *state->Character);
1173 });
1174
1175 AddQueryHolderCallback(LoginDatabase.DelayQueryHolder(holder)).AfterComplete([this, state, holder](SQLQueryHolderBase const& /*result*/)
1176 {
1177 state->Login = holder;
1178 if (state->Login && state->Character)
1179 InitializeSessionCallback(*state->Login, *state->Character);
1180 });
1181}
1182
1184{
1192
1193 if (!m_inQueue)
1194 SendAuthResponse(ERROR_OK, false);
1195 else
1197
1198 SetInQueue(false);
1199 ResetTimeOutTime(false);
1200
1207
1209 {
1210 do
1211 {
1212 Field* fields = characterCountsResult->Fetch();
1213 _realmCharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8();
1214
1215 } while (characterCountsResult->NextRow());
1216 }
1217
1219 bnetConnected.State = 1;
1220 SendPacket(bnetConnected.Write());
1221
1224}
1225
1227{
1228 return _RBACData;
1229}
1230
1232{
1233 if (!_RBACData)
1235
1236 bool hasPermission = _RBACData->HasPermission(permission);
1237 TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: {}, Name: {}, realmId: {}]",
1239
1240 return hasPermission;
1241}
1242
1244{
1245 TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: {}, Name: {}, realmId: {}]",
1247 delete _RBACData;
1248 _RBACData = nullptr;
1249}
1250
1252{
1253 uint32 maxPacketCounterAllowed = GetMaxPacketCounterAllowed(p.GetOpcode());
1254
1255 // Return true if there no limit for the opcode
1256 if (!maxPacketCounterAllowed)
1257 return true;
1258
1259 PacketCounter& packetCounter = _PacketThrottlingMap[p.GetOpcode()];
1260 if (packetCounter.lastReceiveTime != time)
1261 {
1262 packetCounter.lastReceiveTime = time;
1263 packetCounter.amountCounter = 0;
1264 }
1265
1266 // Check if player is flooding some packets
1267 if (++packetCounter.amountCounter <= maxPacketCounterAllowed)
1268 return true;
1269
1270 TC_LOG_WARN("network", "AntiDOS: Account {}, IP: {}, Ping: {}, Character: {}, flooding packet (opc: {} (0x{:X}), count: {})",
1272 opcodeTable[static_cast<OpcodeClient>(p.GetOpcode())]->Name, p.GetOpcode(), packetCounter.amountCounter);
1273
1274 switch (_policy)
1275 {
1276 case POLICY_LOG:
1277 return true;
1278 case POLICY_KICK:
1279 {
1280 TC_LOG_WARN("network", "AntiDOS: Player kicked!");
1281 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1282 return false;
1283 }
1284 case POLICY_BAN:
1285 {
1287 uint32 duration = sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANDURATION); // in seconds
1288 std::string nameOrIp = "";
1289 switch (bm)
1290 {
1291 case BAN_CHARACTER: // not supported, ban account
1292 case BAN_ACCOUNT: (void)sAccountMgr->GetName(Session->GetAccountId(), nameOrIp); break;
1293 case BAN_IP: nameOrIp = Session->GetRemoteAddress(); break;
1294 }
1295 sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
1296 TC_LOG_WARN("network", "AntiDOS: Player automatically banned for {} seconds.", duration);
1297 Session->KickPlayer("WorldSession::DosProtection::EvaluateOpcode AntiDOS");
1298 return false;
1299 }
1300 default: // invalid policy
1301 return true;
1302 }
1303}
1304
1306{
1307 uint32 maxPacketCounterAllowed;
1308 switch (opcode)
1309 {
1310 // CPU usage sending 2000 packets/second on a 3.70 GHz 4 cores on Win x64
1311 // [% CPU mysqld] [%CPU worldserver RelWithDebInfo]
1312 case CMSG_PLAYER_LOGIN: // 0 0.5
1313 case CMSG_QUERY_PLAYER_NAMES: // 0 1
1314 case CMSG_QUERY_PET_NAME: // 0 1
1315 case CMSG_QUERY_NPC_TEXT: // 0 1
1316 case CMSG_ATTACK_STOP: // 0 1
1317 case CMSG_QUERY_TIME: // 0 1
1318 case CMSG_QUERY_CORPSE_TRANSPORT: // 0 1
1319 case CMSG_MOVE_TIME_SKIPPED: // 0 1
1320 case CMSG_QUERY_NEXT_MAIL_TIME: // 0 1
1321 case CMSG_SET_SHEATHED: // 0 1
1322 case CMSG_UPDATE_RAID_TARGET: // 0 1
1323 case CMSG_LOGOUT_REQUEST: // 0 1
1324 case CMSG_PET_RENAME: // 0 1
1326 case CMSG_COMPLETE_CINEMATIC: // 0 1
1327 case CMSG_BANKER_ACTIVATE: // 0 1
1328 case CMSG_BUY_BANK_SLOT: // 0 1
1329 case CMSG_OPT_OUT_OF_LOOT: // 0 1
1330 case CMSG_DUEL_RESPONSE: // 0 1
1331 case CMSG_CALENDAR_COMPLAIN: // 0 1
1332 case CMSG_QUERY_QUEST_INFO: // 0 1.5
1333 case CMSG_QUERY_GAME_OBJECT: // 0 1.5
1334 case CMSG_QUERY_CREATURE: // 0 1.5
1335 case CMSG_QUEST_GIVER_STATUS_QUERY: // 0 1.5
1336 case CMSG_QUERY_GUILD_INFO: // 0 1.5
1337 case CMSG_TAXI_NODE_STATUS_QUERY: // 0 1.5
1338 case CMSG_TAXI_QUERY_AVAILABLE_NODES: // 0 1.5
1339 case CMSG_QUEST_GIVER_QUERY_QUEST: // 0 1.5
1340 case CMSG_QUERY_PAGE_TEXT: // 0 1.5
1341 case CMSG_GUILD_BANK_TEXT_QUERY: // 0 1.5
1343 case CMSG_MOVE_SET_FACING: // 0 1.5
1344 case CMSG_MOVE_SET_FACING_HEARTBEAT: // 0 1.5
1345 case CMSG_MOVE_SET_PITCH: // 0 1.5
1346 case CMSG_REQUEST_PARTY_MEMBER_STATS: // 0 1.5
1347 case CMSG_QUEST_GIVER_COMPLETE_QUEST: // 0 1.5
1348 case CMSG_SET_ACTION_BUTTON: // 0 1.5
1349 case CMSG_SET_ACTION_BAR_TOGGLES: // not profiled
1350 case CMSG_RESET_INSTANCES: // 0 1.5
1351 case CMSG_HEARTH_AND_RESURRECT: // 0 1.5
1352 case CMSG_TOGGLE_PVP: // 0 1.5
1353 case CMSG_PET_ABANDON: // 0 1.5
1354 case CMSG_ACTIVATE_TAXI: // 0 1.5
1355 case CMSG_SELF_RES: // 0 1.5
1356 case CMSG_UNLEARN_SKILL: // 0 1.5
1357 case CMSG_SAVE_EQUIPMENT_SET: // 0 1.5
1358 case CMSG_DELETE_EQUIPMENT_SET: // 0 1.5
1359 case CMSG_DISMISS_CRITTER: // 0 1.5
1360 case CMSG_REPOP_REQUEST: // 0 1.5
1361 case CMSG_PARTY_INVITE: // 0 1.5
1362 case CMSG_PARTY_INVITE_RESPONSE: // 0 1.5
1363 case CMSG_PARTY_UNINVITE: // 0 1.5
1364 case CMSG_LEAVE_GROUP: // 0 1.5
1365 case CMSG_BATTLEMASTER_JOIN_ARENA: // 0 1.5
1366 case CMSG_BATTLEFIELD_LEAVE: // 0 1.5
1367 case CMSG_GUILD_BANK_LOG_QUERY: // 0 2
1368 case CMSG_LOGOUT_CANCEL: // 0 2
1369 case CMSG_ALTER_APPEARANCE: // 0 2
1370 case CMSG_QUEST_CONFIRM_ACCEPT: // 0 2
1371 case CMSG_GUILD_EVENT_LOG_QUERY: // 0 2.5
1373 case CMSG_BEGIN_TRADE: // 0 2.5
1374 case CMSG_INITIATE_TRADE: // 0 3
1375 case CMSG_CHAT_ADDON_MESSAGE: // 0 3.5
1377 case CMSG_CHAT_MESSAGE_AFK: // 0 3.5
1378 case CMSG_CHAT_MESSAGE_CHANNEL: // 0 3.5
1379 case CMSG_CHAT_MESSAGE_DND: // 0 3.5
1380 case CMSG_CHAT_MESSAGE_EMOTE: // 0 3.5
1381 case CMSG_CHAT_MESSAGE_GUILD: // 0 3.5
1382 case CMSG_CHAT_MESSAGE_OFFICER: // 0 3.5
1383 case CMSG_CHAT_MESSAGE_PARTY: // 0 3.5
1384 case CMSG_CHAT_MESSAGE_RAID: // 0 3.5
1385 case CMSG_CHAT_MESSAGE_RAID_WARNING: // 0 3.5
1386 case CMSG_CHAT_MESSAGE_SAY: // 0 3.5
1387 case CMSG_CHAT_MESSAGE_WHISPER: // 0 3.5
1388 case CMSG_CHAT_MESSAGE_YELL: // 0 3.5
1389 case CMSG_INSPECT: // 0 3.5
1390 case CMSG_AREA_SPIRIT_HEALER_QUERY: // not profiled
1391 case CMSG_STAND_STATE_CHANGE: // not profiled
1392 case CMSG_RANDOM_ROLL: // not profiled
1393 case CMSG_TIME_SYNC_RESPONSE: // not profiled
1394 case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: // not profiled
1395 case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK: // not profiled
1397 case CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK: // not profiled
1398 case CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK: // not profiled
1400 case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK: // not profiled
1401 case CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK: // not profiled
1402 case CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK: // not profiled
1403 {
1404 // "0" is a magic number meaning there's no limit for the opcode.
1405 // All the opcodes above must cause little CPU usage and no sync/async database queries at all
1406 maxPacketCounterAllowed = 0;
1407 break;
1408 }
1409
1411 case CMSG_QUEST_LOG_REMOVE_QUEST: // 0 4
1413 case CMSG_SEND_CONTACT_LIST: // 0 5
1414 case CMSG_AUTOBANK_ITEM: // 0 6
1415 case CMSG_AUTOSTORE_BANK_ITEM: // 0 6
1416 case CMSG_WHO: // 0 7
1417 case CMSG_RIDE_VEHICLE_INTERACT: // 0 8
1419 {
1420 maxPacketCounterAllowed = 200;
1421 break;
1422 }
1423
1424 case CMSG_GUILD_SET_MEMBER_NOTE: // 1 2 1 async db query
1425 case CMSG_SET_CONTACT_NOTES: // 1 2.5 1 async db query
1426 case CMSG_CALENDAR_GET: // 0 1.5 medium upload bandwidth usage
1427 case CMSG_GUILD_BANK_QUERY_TAB: // 0 3.5 medium upload bandwidth usage
1428 case CMSG_QUERY_INSPECT_ACHIEVEMENTS: // 0 13 high upload bandwidth usage
1429 case CMSG_GAME_OBJ_REPORT_USE: // not profiled
1430 case CMSG_GAME_OBJ_USE: // not profiled
1431 case CMSG_DECLINE_PETITION: // not profiled
1432 {
1433 maxPacketCounterAllowed = 50;
1434 break;
1435 }
1436
1437 case CMSG_QUEST_POI_QUERY: // 0 25 very high upload bandwidth usage
1438 {
1439 maxPacketCounterAllowed = MAX_QUEST_LOG_SIZE;
1440 break;
1441 }
1442
1443 case CMSG_SPELL_CLICK: // not profiled
1444 case CMSG_MOVE_DISMISS_VEHICLE: // not profiled
1445 {
1446 maxPacketCounterAllowed = 20;
1447 break;
1448 }
1449
1450 case CMSG_SIGN_PETITION: // 9 4 2 sync 1 async db queries
1451 case CMSG_TURN_IN_PETITION: // 8 5.5 2 sync db query
1452 case CMSG_CHANGE_SUB_GROUP: // 6 5 1 sync 1 async db queries
1453 case CMSG_QUERY_PETITION: // 4 3.5 1 sync db query
1454 case CMSG_CHAR_CUSTOMIZE: // 5 5 1 sync db query
1455 case CMSG_CHAR_RACE_OR_FACTION_CHANGE: // 5 5 1 sync db query
1456 case CMSG_CHAR_DELETE: // 4 4 1 sync db query
1457 case CMSG_DEL_FRIEND: // 7 5 1 async db query
1458 case CMSG_ADD_FRIEND: // 6 4 1 async db query
1459 case CMSG_CHARACTER_RENAME_REQUEST: // 5 3 1 async db query
1460 case CMSG_BUG_REPORT: // 1 1 1 async db query
1461 case CMSG_SET_PARTY_LEADER: // 1 2 1 async db query
1462 case CMSG_CONVERT_RAID: // 1 5 1 async db query
1463 case CMSG_SET_ASSISTANT_LEADER: // 1 2 1 async db query
1464 case CMSG_MOVE_CHANGE_VEHICLE_SEATS: // not profiled
1465 case CMSG_PETITION_BUY: // not profiled 1 sync 1 async db queries
1466 case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled
1467 case CMSG_REQUEST_VEHICLE_NEXT_SEAT: // not profiled
1468 case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: // not profiled
1469 case CMSG_REQUEST_VEHICLE_EXIT: // not profiled
1470 case CMSG_EJECT_PASSENGER: // not profiled
1471 case CMSG_ITEM_PURCHASE_REFUND: // not profiled
1472 case CMSG_SOCKET_GEMS: // not profiled
1473 case CMSG_WRAP_ITEM: // not profiled
1474 case CMSG_REPORT_PVP_PLAYER_AFK: // not profiled
1475 {
1476 maxPacketCounterAllowed = 10;
1477 break;
1478 }
1479
1480 case CMSG_CREATE_CHARACTER: // 7 5 3 async db queries
1481 case CMSG_ENUM_CHARACTERS: // 22 3 2 async db queries
1482 case CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT: // 22 3 2 async db queries
1483 case CMSG_SUBMIT_USER_FEEDBACK: // not profiled 1 async db query
1484 case CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT: // not profiled 1 async db query
1485 case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query
1486 case CMSG_CALENDAR_UPDATE_EVENT: // not profiled
1487 case CMSG_CALENDAR_REMOVE_EVENT: // not profiled
1488 case CMSG_CALENDAR_COPY_EVENT: // not profiled
1489 case CMSG_CALENDAR_INVITE: // not profiled
1490 case CMSG_CALENDAR_EVENT_SIGN_UP: // not profiled
1491 case CMSG_CALENDAR_RSVP: // not profiled
1492 case CMSG_CALENDAR_MODERATOR_STATUS: // not profiled
1493 case CMSG_CALENDAR_REMOVE_INVITE: // not profiled
1494 case CMSG_SET_LOOT_METHOD: // not profiled
1495 case CMSG_GUILD_INVITE_BY_NAME: // not profiled
1496 case CMSG_ACCEPT_GUILD_INVITE: // not profiled
1497 case CMSG_GUILD_DECLINE_INVITATION: // not profiled
1498 case CMSG_GUILD_LEAVE: // not profiled
1499 case CMSG_GUILD_DELETE: // not profiled
1500 case CMSG_GUILD_SET_GUILD_MASTER: // not profiled
1501 case CMSG_GUILD_UPDATE_MOTD_TEXT: // not profiled
1502 case CMSG_GUILD_SET_RANK_PERMISSIONS: // not profiled
1503 case CMSG_GUILD_ADD_RANK: // not profiled
1504 case CMSG_GUILD_DELETE_RANK: // not profiled
1505 case CMSG_GUILD_UPDATE_INFO_TEXT: // not profiled
1506 case CMSG_GUILD_BANK_DEPOSIT_MONEY: // not profiled
1507 case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
1508 case CMSG_GUILD_BANK_BUY_TAB: // not profiled
1509 case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
1510 case CMSG_GUILD_BANK_SET_TAB_TEXT: // not profiled
1511 case CMSG_SAVE_GUILD_EMBLEM: // not profiled
1512 case CMSG_PETITION_RENAME_GUILD: // not profiled
1513 case CMSG_CONFIRM_RESPEC_WIPE: // not profiled
1514 case CMSG_SET_DUNGEON_DIFFICULTY: // not profiled
1515 case CMSG_SET_RAID_DIFFICULTY: // not profiled
1516 case CMSG_SET_PARTY_ASSIGNMENT: // not profiled
1517 case CMSG_DO_READY_CHECK: // not profiled
1518 {
1519 maxPacketCounterAllowed = 3;
1520 break;
1521 }
1522
1523 case CMSG_GET_ITEM_PURCHASE_DATA: // not profiled
1524 {
1525 maxPacketCounterAllowed = PLAYER_SLOTS_COUNT;
1526 break;
1527 }
1528 case CMSG_HOTFIX_REQUEST: // not profiled
1529 {
1530 maxPacketCounterAllowed = 1;
1531 break;
1532 }
1533 default:
1534 {
1535 maxPacketCounterAllowed = 100;
1536 break;
1537 }
1538 }
1539
1540 return maxPacketCounterAllowed;
1541}
1542
1544{
1545}
1546
1548{
1551}
1552
1554{
1556 timeSyncRequest.SequenceIndex = _timeSyncNextCounter;
1557 SendPacket(timeSyncRequest.Write());
1558
1560
1561 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1562 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1564}
1565
1567{
1568 int64 movementTime = int64(time) + _timeSyncClockDelta;
1569 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
1570 {
1571 TC_LOG_WARN("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
1572 return GameTime::GetGameTimeMS();
1573 }
1574 else
1575 return uint32(movementTime);
1576}
#define sAccountMgr
Definition: AccountMgr.h:98
std::array< uint8, SESSION_KEY_LENGTH > SessionKey
Definition: AuthDefines.h:25
#define sBattlegroundMgr
@ ERROR_INTERNAL
@ CHAR_INS_TUTORIALS
@ CHAR_UPD_TUTORIALS
@ CHAR_SEL_TUTORIALS
@ CHAR_SEL_ACCOUNT_DATA
@ CHAR_UPD_ACCOUNT_ONLINE
@ CHAR_REP_PLAYER_ACCOUNT_DATA
@ CHAR_REP_ACCOUNT_DATA
LocaleConstant
Definition: Common.h:48
AccountTypes
Definition: Common.h:39
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint8_t uint8
Definition: Define.h:144
int64_t int64
Definition: Define.h:137
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
#define UI64LIT(N)
Definition: Define.h:127
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition: Duration.h:35
#define sGuildMgr
Definition: GuildMgr.h:70
@ 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
@ LOGIN_SEL_BATTLE_PETS
@ LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES
@ LOGIN_SEL_ACCOUNT_TOYS
@ LOGIN_SEL_ACCOUNT_MOUNTS
@ LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID
@ LOGIN_SEL_ACCOUNT_HEIRLOOMS
@ LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS
@ LOGIN_SEL_BATTLE_PET_SLOTS
@ LOGIN_SEL_BNET_ITEM_APPEARANCES
#define TC_METRIC_DETAILED_TIMER(category,...)
Definition: Metric.h:241
#define TC_METRIC_VALUE(category, value,...)
Definition: Metric.h:214
#define TC_METRIC_EVENT(category, title, description)
Definition: Metric.h:206
#define TC_METRIC_TAG(name, value)
Definition: Metric.h:180
#define sObjectMgr
Definition: ObjectMgr.h:1946
#define sOutdoorPvPMgr
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:43
@ BUYBACK_SLOT_END
Definition: Player.h:707
@ BUYBACK_SLOT_START
Definition: Player.h:706
@ PLAYER_SLOTS_COUNT
Definition: Player.h:620
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:44
@ QUEST_FLAGS_FAIL_ON_LOGOUT
Definition: QuestDef.h:225
Role Based Access Control related classes definition.
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
#define sScriptMgr
Definition: ScriptMgr.h:1418
constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE
static constexpr uint8 PLAYER_MAX_BATTLEGROUND_QUEUES
@ EXPANSION_BATTLE_FOR_AZEROTH
Definition: SharedDefines.h:97
#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:161
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
uint32 getMSTime()
Definition: Timer.h:33
bool Initialize(uint32 accountId, uint32)
bool Initialize(uint32 accountId, uint32 battlenetAccountId)
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
char const * what() const noexcept override
Definition: ByteBuffer.h:36
size_t rpos() const
Definition: ByteBuffer.h:399
void hexlike() const
Definition: ByteBuffer.cpp:177
void print_storage() const
Definition: ByteBuffer.cpp:146
size_t wpos() const
Definition: ByteBuffer.h:412
size_t size() const
Definition: ByteBuffer.h:536
PacketProcessing ProcessingPlace
Definition: Opcodes.h:2152
virtual void Call(WorldSession *session, WorldPacket &packet) const =0
Class used to access individual fields of database query result.
Definition: Field.h:90
uint8 GetUInt8() const
Definition: Field.cpp:30
std::string GetString() const
Definition: Field.cpp:118
int64 GetInt64() const
Definition: Field.cpp:86
uint32 GetUInt32() const
Definition: Field.cpp:62
Definition: Group.h:197
Definition: Guild.h:329
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:189
LowType GetCounter() const
Definition: ObjectGuid.h:293
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
bool IsEmpty() const
Definition: ObjectGuid.h:319
std::string ToString() const
Definition: ObjectGuid.cpp:554
bool IsInWorld() const
Definition: Object.h:154
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void SetDestroyedObject(bool destroyed)
Definition: Object.h:196
char const * Name
Definition: Opcodes.h:2140
SessionStatus Status
Definition: Opcodes.h:2141
virtual bool ProcessUnsafe() const
Definition: WorldSession.h:921
WorldSession *const m_pSession
Definition: WorldSession.h:924
void CleanupChannels()
Definition: Player.cpp:4910
uint32 GetXP() const
Definition: Player.h:1196
bool m_InstanceValid
Definition: Player.h:2571
bool IsBeingTeleportedFar() const
Definition: Player.h:2221
void KillPlayer()
Definition: Player.cpp:4495
void SetInvSlot(uint32 slot, ObjectGuid guid)
Definition: Player.h:1454
void FailQuestsWithFlag(QuestFlags flag)
Definition: Player.cpp:15494
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={})
Definition: Player.cpp:1250
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition: Player.cpp:386
uint32 GetDeathTimer() const
Definition: Player.h:2291
void RemoveSocial()
Definition: Player.cpp:29816
ObjectGuid const & GetLootGUID() const
Definition: Player.h:2091
bool HasPendingBind() const
Definition: Player.h:2587
WorldLocation m_homebind
Definition: Player.h:2503
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition: Player.cpp:25061
void RepopAtGraveyard()
Definition: Player.cpp:4832
void ClearWhisperWhiteList()
Definition: Player.h:2677
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:21537
Battleground * GetBattleground() const
Definition: Player.cpp:24976
ObjectGuid::LowType GetGuildId() const
Definition: Player.h:1993
bool IsGameMaster() const
Definition: Player.h:1178
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition: Player.cpp:19682
uint32 GetXPForNextLevel() const
Definition: Player.h:1197
void SaveToDB(bool create=false)
Definition: Player.cpp:19978
void SetBuybackTimestamp(uint32 slot, time_t timestamp)
Definition: Player.h:1476
Group * GetGroup(Optional< uint8 > partyIndex)
Definition: Player.h:2606
void BuildPlayerRepop()
Definition: Player.cpp:4350
void UninviteFromGroup()
Definition: Player.cpp:2166
void SetBuybackPrice(uint32 slot, uint32 price)
Definition: Player.h:1475
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition: Player.cpp:25001
void setInt32(const uint8 index, const int32 value)
void setUInt8(const uint8 index, const uint8 value)
void setInt64(const uint8 index, const int64 value)
void setUInt32(const uint8 index, const uint32 value)
void setString(const uint8 index, const std::string &value)
void setUInt64(const uint8 index, const uint64 value)
void SetSize(size_t size)
Definition: QueryHolder.cpp:69
PreparedQueryResult GetPreparedResult(size_t index) const
Definition: QueryHolder.cpp:37
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition: QueryHolder.h:69
bool SetPreparedQuery(size_t index, PreparedStatement< T > *stmt)
Definition: QueryHolder.h:47
ConnectionType ConnectionIndex
Definition: Opcodes.h:2161
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3812
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5827
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4674
uint8 GetLevel() const
Definition: Unit.h:746
Map * FindMap() const
Definition: Object.h:625
std::string const & GetName() const
Definition: Object.h:555
uint32 GetZoneId() const
Definition: Object.h:545
ConnectionType GetConnection() const
Definition: WorldPacket.h:87
uint32 GetOpcode() const
Definition: WorldPacket.h:84
WorldPacket const * Write() override
WorldPacket const * Write() override
Array< std::string, MAX_PREFIXES > Prefixes
Definition: ChatPackets.h:285
std::array< Timestamp<>, NUM_ACCOUNT_DATA_TYPES > AccountTimes
OpcodeClient GetOpcode() const
Definition: Packet.h:68
std::string const & GetInvalidValue() const
WorldPacket const * Write() override
WorldPacket const * Write() override
uint32 TutorialData[MAX_ACCOUNT_TUTORIAL_VALUES]
Definition: MiscPackets.h:240
bool Process(WorldPacket *packet) override
bool EvaluateOpcode(WorldPacket &p, time_t time) const
uint32 GetMaxPacketCounterAllowed(uint16 opcode) const
DosProtection(WorldSession *s)
PacketThrottlingMap _PacketThrottlingMap
Player session in the World.
Definition: WorldSession.h:963
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)
void LogoutPlayer(bool save)
Log the player out
uint8 _tutorialsChanged
AccountData _accountData[NUM_ACCOUNT_DATA_TYPES]
char const * GetTrinityString(uint32 entry) const
std::string m_Address
void LoadTutorialsData(PreparedQueryResult result)
void SendClientCacheVersion(uint32 version)
Definition: AuthHandler.cpp:83
void SendConnectToInstance(WorldPackets::Auth::ConnectToSerial serial)
void HandleMoveWorldportAck()
void SendNotification(char const *format,...) ATTR_PRINTF(2
bool CanAccessAlliedRaces() const
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
void SendAuthResponse(uint32 code, bool queued, uint32 queuePos=0)
Definition: AuthHandler.cpp:32
QueryCallbackProcessor _queryProcessor
uint32 _tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
AccountTypes GetSecurity() const
Definition: WorldSession.h:999
LocaleConstant GetSessionDbLocaleIndex() const
bool PlayerDisconnected() const
void LoadPermissions()
int64 _timeSyncClockDelta
bool DisallowHyperlinksAndMaybeKick(std::string const &str)
std::map< uint32, uint32 > _pendingTimeSyncRequests
uint32 AdjustClientMovementTime(uint32 time) const
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
void InitWarden(SessionKey const &k)
std::unordered_map< uint32, uint8 > _realmCharacterCounts
std::string GetPlayerInfo() const
void KickPlayer(std::string const &reason)
Kick a player out of the World.
std::string _os
Player * GetPlayer() const
rbac::RBACData * _RBACData
std::unique_ptr< CollectionMgr > _collectionMgr
void SendAuthWaitQueue(uint32 position)
Handle the authentication waiting queue (to be completed)
Definition: AuthHandler.cpp:69
void Handle_EarlyProccess(WorldPackets::Null &null)
~WorldSession()
WorldSession destructor.
void SetLogoutStartTime(time_t requestTime)
Engage the logout process for the user.
void SendSetTimeZoneInformation()
Definition: AuthHandler.cpp:91
void LogUnexpectedOpcode(WorldPacket *packet, char const *status, const char *reason)
Logging helper for unexpected opcodes.
std::string _accountName
AccountData const * GetAccountData(AccountDataType type) const
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
bool CanSpeak() const
uint32 _timeSyncNextCounter
void Handle_NULL(WorldPackets::Null &null)
ObjectGuid m_playerLoading
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
QueryCallback LoadPermissionsAsync()
std::string const & GetRemoteAddress() const
void SetInQueue(bool state)
Session in auth.queue currently.
ObjectGuid::LowType m_GUIDLow
void ResetTimeSync()
bool HasPermission(uint32 permissionId)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetBattlenetAccountId() const
uint32 GetAccountId() const
uint8 GetAccountExpansion() const
ConnectToKey _instanceConnectKey
void SendTutorialsData()
Player * _player
uint32 GetLatency() const
void ProcessQueryCallbacks()
std::shared_ptr< WorldSocket > m_Socket[MAX_CONNECTION_TYPES]
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
uint32 expireTime
void SaveTutorialsData(CharacterDatabaseTransaction trans)
WorldSession(uint32 id, std::string &&name, uint32 battlenetAccountId, std::shared_ptr< WorldSocket > sock, AccountTypes sec, uint8 expansion, time_t mute_time, std::string os, Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter)
WorldSession constructor.
LockedQueue< WorldPacket * > _recvQueue
std::string const & GetPlayerName() const
time_t m_muteTime
std::unique_ptr< Warden > _warden
void ResetTimeOutTime(bool onlyActive)
void InitializeSession()
void InvalidateRBACData()
void SetAccountData(AccountDataType type, time_t time, std::string const &data)
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()
rbac::RBACData * GetRBACData()
bool IsConnectionIdle() const
std::unique_ptr< BattlePets::BattlePetMgr > _battlePetMgr
bool _filterAddonMessages
uint32 GetId() const
Gets the Id of the Object.
Definition: RBAC.h:816
QueryCallback LoadFromDBAsync()
Definition: RBAC.cpp:187
std::string const & GetName() const
Gets the Name of the Object.
Definition: RBAC.h:814
void LoadFromDB()
Loads all permissions assigned to current account.
Definition: RBAC.cpp:174
bool HasPermission(uint32 permission) const
Definition: RBAC.h:834
ConnectionType
Definition: Opcodes.h:29
OpcodeClient
Definition: Opcodes.h:46
std::string GetOpcodeNameForLogging(OpcodeClient opcode)
Lookup opcode name for human understandable logging.
Definition: Opcodes.cpp:2205
OpcodeTable opcodeTable
Definition: Opcodes.cpp:38
bool IsInstanceOnlyOpcode(uint32 opcode)
Definition: Opcodes.h:2093
OpcodeServer
Definition: Opcodes.h:901
#define GLOBAL_CACHE_MASK
Definition: WorldSession.h:873
AccountDataType
Definition: WorldSession.h:852
#define NUM_ACCOUNT_DATA_TYPES
Definition: WorldSession.h:870
@ CONNECTION_TYPE_INSTANCE
Definition: Opcodes.h:31
@ CONNECTION_TYPE_DEFAULT
Definition: Opcodes.h:34
@ CONNECTION_TYPE_REALM
Definition: Opcodes.h:30
@ CMSG_TIME_SYNC_RESPONSE
Definition: Opcodes.h:848
@ CMSG_QUERY_PAGE_TEXT
Definition: Opcodes.h:648
@ CMSG_TURN_IN_PETITION
Definition: Opcodes.h:861
@ CMSG_CALENDAR_ADD_EVENT
Definition: Opcodes.h:155
@ CMSG_ATTACK_STOP
Definition: Opcodes.h:72
@ CMSG_SEND_CONTACT_LIST
Definition: Opcodes.h:757
@ CMSG_CALENDAR_RSVP
Definition: Opcodes.h:167
@ CMSG_ENUM_CHARACTERS
Definition: Opcodes.h:338
@ CMSG_CHAT_MESSAGE_YELL
Definition: Opcodes.h:229
@ CMSG_EJECT_PASSENGER
Definition: Opcodes.h:332
@ CMSG_QUERY_GAME_OBJECT
Definition: Opcodes.h:642
@ CMSG_LOGOUT_REQUEST
Definition: Opcodes.h:473
@ CMSG_CHAT_MESSAGE_WHISPER
Definition: Opcodes.h:228
@ CMSG_PET_RENAME
Definition: Opcodes.h:629
@ CMSG_GUILD_SET_RANK_PERMISSIONS
Definition: Opcodes.h:430
@ CMSG_CHAT_ADDON_MESSAGE_TARGETED
Definition: Opcodes.h:198
@ CMSG_CHAT_MESSAGE_EMOTE
Definition: Opcodes.h:220
@ CMSG_SET_SHEATHED
Definition: Opcodes.h:797
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition: Opcodes.h:735
@ CMSG_REPOP_REQUEST
Definition: Opcodes.h:698
@ CMSG_PET_ABANDON
Definition: Opcodes.h:615
@ CMSG_CHAT_MESSAGE_CHANNEL
Definition: Opcodes.h:218
@ CMSG_QUEST_CONFIRM_ACCEPT
Definition: Opcodes.h:662
@ CMSG_DELETE_EQUIPMENT_SET
Definition: Opcodes.h:311
@ CMSG_TOGGLE_PVP
Definition: Opcodes.h:852
@ CMSG_GUILD_BANK_DEPOSIT_MONEY
Definition: Opcodes.h:397
@ CMSG_SUBMIT_USER_FEEDBACK
Definition: Opcodes.h:829
@ CMSG_GUILD_LEAVE
Definition: Opcodes.h:416
@ CMSG_CHANGE_SUB_GROUP
Definition: Opcodes.h:189
@ CMSG_CHAT_MESSAGE_GUILD
Definition: Opcodes.h:221
@ CMSG_GUILD_SET_GUILD_MASTER
Definition: Opcodes.h:428
@ CMSG_CONVERT_RAID
Definition: Opcodes.h:294
@ CMSG_GUILD_BANK_WITHDRAW_MONEY
Definition: Opcodes.h:404
@ CMSG_SET_CONTACT_NOTES
Definition: Opcodes.h:772
@ CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK
Definition: Opcodes.h:521
@ CMSG_CALENDAR_REMOVE_INVITE
Definition: Opcodes.h:166
@ CMSG_GUILD_DELETE_RANK
Definition: Opcodes.h:409
@ CMSG_SET_ACTION_BAR_TOGGLES
Definition: Opcodes.h:764
@ CMSG_CALENDAR_EVENT_SIGN_UP
Definition: Opcodes.h:159
@ CMSG_SAVE_EQUIPMENT_SET
Definition: Opcodes.h:747
@ CMSG_QUEST_POI_QUERY
Definition: Opcodes.h:674
@ CMSG_SIGN_PETITION
Definition: Opcodes.h:808
@ CMSG_SOCKET_GEMS
Definition: Opcodes.h:811
@ CMSG_QUERY_CREATURE
Definition: Opcodes.h:641
@ CMSG_MOVE_DISMISS_VEHICLE
Definition: Opcodes.h:507
@ CMSG_CALENDAR_INVITE
Definition: Opcodes.h:163
@ CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT
Definition: Opcodes.h:832
@ CMSG_MOVE_HEARTBEAT
Definition: Opcodes.h:528
@ CMSG_DUEL_RESPONSE
Definition: Opcodes.h:331
@ CMSG_MOVE_TIME_SKIPPED
Definition: Opcodes.h:586
@ CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK
Definition: Opcodes.h:522
@ CMSG_QUEST_GIVER_QUERY_QUEST
Definition: Opcodes.h:668
@ CMSG_COMPLETE_CINEMATIC
Definition: Opcodes.h:278
@ CMSG_QUEST_GIVER_REQUEST_REWARD
Definition: Opcodes.h:669
@ CMSG_SELF_RES
Definition: Opcodes.h:753
@ CMSG_ACTIVATE_TAXI
Definition: Opcodes.h:55
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition: Opcodes.h:733
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition: Opcodes.h:734
@ CMSG_RANDOM_ROLL
Definition: Opcodes.h:689
@ CMSG_DECLINE_PETITION
Definition: Opcodes.h:310
@ CMSG_REQUEST_VEHICLE_EXIT
Definition: Opcodes.h:732
@ CMSG_SET_ASSISTANT_LEADER
Definition: Opcodes.h:768
@ CMSG_CHAT_MESSAGE_RAID_WARNING
Definition: Opcodes.h:226
@ CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK
Definition: Opcodes.h:524
@ CMSG_ACCEPT_GUILD_INVITE
Definition: Opcodes.h:48
@ CMSG_OPT_OUT_OF_LOOT
Definition: Opcodes.h:600
@ CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition: Opcodes.h:515
@ CMSG_DO_READY_CHECK
Definition: Opcodes.h:330
@ CMSG_CALENDAR_COMPLAIN
Definition: Opcodes.h:157
@ CMSG_CHAT_MESSAGE_SAY
Definition: Opcodes.h:227
@ CMSG_AUTOSTORE_BANK_ITEM
Definition: Opcodes.h:97
@ CMSG_CHAT_MESSAGE_AFK
Definition: Opcodes.h:217
@ CMSG_GUILD_ADD_RANK
Definition: Opcodes.h:392
@ CMSG_DISMISS_CRITTER
Definition: Opcodes.h:327
@ CMSG_BUG_REPORT
Definition: Opcodes.h:148
@ CMSG_QUEST_GIVER_COMPLETE_QUEST
Definition: Opcodes.h:666
@ CMSG_CHAR_DELETE
Definition: Opcodes.h:195
@ CMSG_CHAR_RACE_OR_FACTION_CHANGE
Definition: Opcodes.h:196
@ CMSG_STAND_STATE_CHANGE
Definition: Opcodes.h:824
@ CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT
Definition: Opcodes.h:339
@ CMSG_CONFIRM_RESPEC_WIPE
Definition: Opcodes.h:281
@ CMSG_AUTOBANK_ITEM
Definition: Opcodes.h:95
@ CMSG_CHAR_CUSTOMIZE
Definition: Opcodes.h:194
@ CMSG_SET_PARTY_LEADER
Definition: Opcodes.h:787
@ CMSG_CHAT_MESSAGE_RAID
Definition: Opcodes.h:225
@ CMSG_CHARACTER_RENAME_REQUEST
Definition: Opcodes.h:191
@ CMSG_BANKER_ACTIVATE
Definition: Opcodes.h:108
@ CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK
Definition: Opcodes.h:519
@ CMSG_LEAVE_GROUP
Definition: Opcodes.h:452
@ CMSG_CALENDAR_COPY_EVENT
Definition: Opcodes.h:158
@ CMSG_CHAT_MESSAGE_DND
Definition: Opcodes.h:219
@ CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:518
@ CMSG_QUERY_INSPECT_ACHIEVEMENTS
Definition: Opcodes.h:645
@ CMSG_MOVE_SET_FACING
Definition: Opcodes.h:557
@ CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:520
@ CMSG_CALENDAR_MODERATOR_STATUS
Definition: Opcodes.h:164
@ CMSG_ALTER_APPEARANCE
Definition: Opcodes.h:65
@ CMSG_TAXI_NODE_STATUS_QUERY
Definition: Opcodes.h:844
@ CMSG_QUERY_QUEST_INFO
Definition: Opcodes.h:655
@ CMSG_QUEST_GIVER_CHOOSE_REWARD
Definition: Opcodes.h:664
@ CMSG_GUILD_UPDATE_MOTD_TEXT
Definition: Opcodes.h:433
@ CMSG_SET_ACTION_BUTTON
Definition: Opcodes.h:765
@ CMSG_WRAP_ITEM
Definition: Opcodes.h:897
@ CMSG_GUILD_DECLINE_INVITATION
Definition: Opcodes.h:407
@ CMSG_RIDE_VEHICLE_INTERACT
Definition: Opcodes.h:743
@ CMSG_MOVE_CHANGE_VEHICLE_SEATS
Definition: Opcodes.h:504
@ CMSG_GET_ITEM_PURCHASE_DATA
Definition: Opcodes.h:376
@ CMSG_QUEST_GIVER_ACCEPT_QUEST
Definition: Opcodes.h:663
@ CMSG_GAME_OBJ_REPORT_USE
Definition: Opcodes.h:343
@ CMSG_QUERY_PETITION
Definition: Opcodes.h:649
@ CMSG_SET_DUNGEON_DIFFICULTY
Definition: Opcodes.h:775
@ CMSG_GUILD_BANK_LOG_QUERY
Definition: Opcodes.h:398
@ CMSG_BEGIN_TRADE
Definition: Opcodes.h:142
@ CMSG_INSPECT
Definition: Opcodes.h:440
@ CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK
Definition: Opcodes.h:516
@ CMSG_QUERY_NPC_TEXT
Definition: Opcodes.h:647
@ CMSG_QUEST_GIVER_STATUS_QUERY
Definition: Opcodes.h:671
@ CMSG_AREA_SPIRIT_HEALER_QUERY
Definition: Opcodes.h:66
@ CMSG_SET_PARTY_ASSIGNMENT
Definition: Opcodes.h:786
@ CMSG_DEL_FRIEND
Definition: Opcodes.h:312
@ CMSG_GUILD_BANK_TEXT_QUERY
Definition: Opcodes.h:402
@ CMSG_TAXI_QUERY_AVAILABLE_NODES
Definition: Opcodes.h:845
@ CMSG_QUEST_LOG_REMOVE_QUEST
Definition: Opcodes.h:673
@ CMSG_MOVE_SET_PITCH
Definition: Opcodes.h:562
@ CMSG_QUERY_NEXT_MAIL_TIME
Definition: Opcodes.h:646
@ CMSG_QUEST_GIVER_STATUS_MULTIPLE_QUERY
Definition: Opcodes.h:670
@ CMSG_GUILD_EVENT_LOG_QUERY
Definition: Opcodes.h:411
@ CMSG_SAVE_GUILD_EMBLEM
Definition: Opcodes.h:748
@ CMSG_CHAT_ADDON_MESSAGE
Definition: Opcodes.h:197
@ CMSG_CHAT_MESSAGE_OFFICER
Definition: Opcodes.h:223
@ CMSG_PARTY_INVITE_RESPONSE
Definition: Opcodes.h:603
@ CMSG_QUERY_TIME
Definition: Opcodes.h:659
@ CMSG_ADD_FRIEND
Definition: Opcodes.h:59
@ CMSG_SET_RAID_DIFFICULTY
Definition: Opcodes.h:792
@ CMSG_MOVE_SET_FACING_HEARTBEAT
Definition: Opcodes.h:558
@ CMSG_GUILD_BANK_SET_TAB_TEXT
Definition: Opcodes.h:401
@ CMSG_CALENDAR_GET
Definition: Opcodes.h:160
@ CMSG_QUERY_PET_NAME
Definition: Opcodes.h:650
@ CMSG_LOGOUT_CANCEL
Definition: Opcodes.h:471
@ CMSG_PETITION_RENAME_GUILD
Definition: Opcodes.h:612
@ CMSG_BATTLEMASTER_JOIN_ARENA
Definition: Opcodes.h:114
@ CMSG_WHO
Definition: Opcodes.h:894
@ CMSG_GUILD_INVITE_BY_NAME
Definition: Opcodes.h:415
@ CMSG_HEARTH_AND_RESURRECT
Definition: Opcodes.h:434
@ CMSG_GUILD_UPDATE_INFO_TEXT
Definition: Opcodes.h:432
@ CMSG_PLAYER_LOGIN
Definition: Opcodes.h:634
@ CMSG_CREATE_CHARACTER
Definition: Opcodes.h:306
@ CMSG_CALENDAR_UPDATE_EVENT
Definition: Opcodes.h:169
@ CMSG_CHAT_MESSAGE_PARTY
Definition: Opcodes.h:224
@ CMSG_RESET_INSTANCES
Definition: Opcodes.h:740
@ CMSG_GUILD_DELETE
Definition: Opcodes.h:408
@ CMSG_HOTFIX_REQUEST
Definition: Opcodes.h:436
@ CMSG_PARTY_INVITE
Definition: Opcodes.h:602
@ CMSG_GUILD_SET_MEMBER_NOTE
Definition: Opcodes.h:429
@ CMSG_BATTLEFIELD_LEAVE
Definition: Opcodes.h:109
@ CMSG_PARTY_UNINVITE
Definition: Opcodes.h:604
@ CMSG_SET_LOOT_METHOD
Definition: Opcodes.h:784
@ CMSG_ITEM_PURCHASE_REFUND
Definition: Opcodes.h:443
@ CMSG_UNLEARN_SKILL
Definition: Opcodes.h:866
@ CMSG_INITIATE_TRADE
Definition: Opcodes.h:439
@ CMSG_QUERY_GUILD_INFO
Definition: Opcodes.h:644
@ CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT
Definition: Opcodes.h:638
@ CMSG_SPELL_CLICK
Definition: Opcodes.h:816
@ CMSG_QUERY_PLAYER_NAMES
Definition: Opcodes.h:651
@ CMSG_CALENDAR_REMOVE_EVENT
Definition: Opcodes.h:165
@ CMSG_UPDATE_RAID_TARGET
Definition: Opcodes.h:875
@ CMSG_REPORT_PVP_PLAYER_AFK
Definition: Opcodes.h:703
@ CMSG_GUILD_BANK_BUY_TAB
Definition: Opcodes.h:396
@ CMSG_QUERY_CORPSE_TRANSPORT
Definition: Opcodes.h:639
@ CMSG_PETITION_BUY
Definition: Opcodes.h:611
@ CMSG_GUILD_BANK_QUERY_TAB
Definition: Opcodes.h:399
@ CMSG_BUY_BANK_SLOT
Definition: Opcodes.h:151
@ CMSG_REQUEST_PARTY_MEMBER_STATS
Definition: Opcodes.h:723
@ CMSG_GUILD_BANK_UPDATE_TAB
Definition: Opcodes.h:403
@ CMSG_GAME_OBJ_USE
Definition: Opcodes.h:344
@ CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:514
@ TUTORIALS_FLAG_LOADED_FROM_DB
Definition: WorldSession.h:909
@ TUTORIALS_FLAG_CHANGED
Definition: WorldSession.h:908
@ TUTORIALS_FLAG_NONE
Definition: WorldSession.h:907
@ STATUS_LOGGEDIN
Definition: Opcodes.h:2117
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition: Opcodes.h:2119
@ STATUS_TRANSFER
Definition: Opcodes.h:2118
@ STATUS_NEVER
Definition: Opcodes.h:2120
@ STATUS_AUTHED
Definition: Opcodes.h:2116
@ STATUS_UNHANDLED
Definition: Opcodes.h:2121
@ UNKNOWN_OPCODE
Definition: Opcodes.h:41
@ NULL_OPCODE
Definition: Opcodes.h:42
@ PROCESS_INPLACE
Definition: Opcodes.h:2126
@ PROCESS_THREADUNSAFE
Definition: Opcodes.h:2127
#define sWorld
Definition: World.h:931
Realm realm
Definition: World.cpp:3966
@ CONFIG_SOCKET_TIMEOUTTIME
Definition: World.h:241
@ CONFIG_CLIENTCACHE_VERSION
Definition: World.h:361
@ CONFIG_PORT_INSTANCE
Definition: World.h:240
@ CONFIG_PACKET_SPOOF_BANDURATION
Definition: World.h:407
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition: World.h:437
@ CONFIG_PACKET_SPOOF_POLICY
Definition: World.h:405
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition: World.h:320
@ CONFIG_PACKET_SPOOF_BANMODE
Definition: World.h:406
@ CONFIG_EXPANSION
Definition: World.h:308
TC_GAME_API bool GetName(uint32 accountId, std::string &name)
SystemTimePoint GetSystemTime()
Current chrono system_clock time point.
Definition: GameTime.cpp:54
time_t GetGameTime()
Definition: GameTime.cpp:44
uint32 GetGameTimeMS()
Definition: GameTime.cpp:49
std::string ToString(Type &&val, Params &&... params)
@ RBAC_PERM_IGNORE_IDLE_CONNECTION
Definition: RBAC.h:60
STL namespace.
std::string Data
Definition: WorldSession.h:879
uint32 amountCounter
Definition: WorldSession.h:958
time_t lastReceiveTime
Definition: WorldSession.h:957
boost::asio::ip::address GetAddressForClient(boost::asio::ip::address const &clientAddr) const
Definition: Realm.cpp:32
Battlenet::RealmHandle Id
Definition: Realm.h:82
union WorldPackets::Auth::ConnectTo::SocketAddress::@324 Address
struct WorldSession::ConnectToKey::@330 Fields