Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
WorldSession.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
9
10#include "AccountMgr.h"
11#include "BattlegroundMgr.h"
12#include "CharacterBoost.h"
13#include "Common.h"
14#include "Config.h"
15#include "DatabaseEnv.h"
16#include "Group.h"
17#include "Guild.h"
18#include "GuildMgr.h"
19#include "Log.h"
20#include "MapManager.h"
21#include "ObjectAccessor.h"
22#include "ObjectMgr.h"
23#include "Opcodes.h"
24#include "OutdoorPvPMgr.h"
25#include "Player.h"
26#include "RuntimeMetrics.h"
27#include "ScriptMgr.h"
28#include "SocialMgr.h"
29#include "Transport.h"
30#include "Vehicle.h"
31#include "WardenMac.h"
32#include "WardenWin.h"
33#include "World.h"
34#include "WorldPacket.h"
35#include "WorldSession.h"
36#include "WorldSocket.h"
37#include "zlib.h"
38#include <zlib.h>
39
40namespace
41{
42 std::string const DefaultPlayerName = "<none>";
43} // namespace
44
46{
47 OpcodeHandler const* opHandle = clientOpcodeTable[packet->GetOpcode()];
48
49 //let's check if our opcode can be really processed in Map::Update()
50 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
51 return true;
52
53 //we do not process thread-unsafe packets
55 return false;
56
57 Player* player = m_pSession->GetPlayer();
58 if (!player)
59 return false;
60
61 //in Map::Update() we do not process packets where player is not in world!
62 return player->IsInWorld();
63}
64
65//we should process ALL packets when player is not in world/logged in
66//OR packet handler is not thread-safe!
68{
69 OpcodeHandler const* opHandle = clientOpcodeTable[packet->GetOpcode()];
70 //check if packet handler is supposed to be safe
71 if (opHandle->ProcessingPlace == PROCESS_INPLACE)
72 return true;
73
74 //thread-unsafe packets should be processed in World::UpdateSessions()
76 return true;
77
78 //no player attached? -> our client! ^^
79 Player* player = m_pSession->GetPlayer();
80 if (!player)
81 return true;
82
83 //lets process all packets for non-in-the-world player
84 return (player->IsInWorld() == false);
85}
86
88WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool hasBoost) :
89 m_muteTime(mute_time),
91 AntiDOS(this),
92 _player(NULL),
93 m_Socket(sock),
94 _security(sec),
96 _accountId(id),
97 m_expansion(expansion),
99 _warden(NULL),
100 _logoutTime(0),
101 m_inQueue(false),
102 m_playerLoading(false),
103 m_playerLogout(false),
105 m_playerSave(false),
106 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
108 m_latency(0),
110 m_TutorialsChanged(false),
112 recruiterId(recruiter),
113 isRecruiter(isARecruiter),
114 m_hasBoost(hasBoost),
116 _RBACData(NULL)
117{
118 if (sock)
119 {
120 m_Address = sock->GetRemoteAddress();
121 sock->AddReference();
123 LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
124 }
125
127
128 _compressionStream = new z_stream();
129 _compressionStream->zalloc = (alloc_func)NULL;
130 _compressionStream->zfree = (free_func)NULL;
131 _compressionStream->opaque = (voidpf)NULL;
132 _compressionStream->avail_in = 0;
133 _compressionStream->next_in = NULL;
134 int32 z_res = deflateInit(_compressionStream, sWorld->getIntConfig(WorldIntConfigs::CONFIG_COMPRESSION));
135 if (z_res != Z_OK)
136 SF_LOG_ERROR("network", "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res));
137}
138
141{
143 if (_player)
144 LogoutPlayer(true);
145
147 if (m_Socket)
148 {
149 m_Socket->DetachSession(this);
150 m_Socket->CloseSocket();
151 m_Socket->RemoveReference();
152 m_Socket = NULL;
153 }
154
155 delete _warden;
156 delete _RBACData;
157 delete m_charBooster;
158
160 WorldPacket* packet = NULL;
161 while (_recvQueue.next(packet))
162 delete packet;
163
164 LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); // One-time query
165
166 int32 z_res = deflateEnd(_compressionStream);
167 if (z_res != Z_OK && z_res != Z_DATA_ERROR) // Z_DATA_ERROR signals that internal state was BUSY
168 SF_LOG_ERROR("network", "Can't close packet compression stream (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res));
169
170 delete _compressionStream;
171}
172
173std::string const& WorldSession::GetPlayerName() const
174{
175 return _player != NULL ? _player->GetName() : DefaultPlayerName;
176}
177
179{
180 std::ostringstream ss;
181
182 ss << "[Player: " << GetPlayerName()
183 << " (Guid: " << (_player != NULL ? _player->GetGUID() : 0)
184 << ", Account: " << GetAccountId() << ")]";
185
186 return ss.str();
187}
188
191{
192 return GetPlayer() ? GetPlayer()->GetGUIDLow() : 0;
193}
194
196void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
197{
198 if (!m_Socket)
199 return;
200
201 if (packet->GetOpcode() == NULL_OPCODE)
202 {
203 SF_LOG_ERROR("network.opcode", "Prevented sending of NULL_OPCODE to %s", GetPlayerInfo().c_str());
204 return;
205 }
206 else if (packet->GetOpcode() == UNKNOWN_OPCODE)
207 {
208 SF_LOG_ERROR("network.opcode", "Prevented sending of UNKNOWN_OPCODE to %s", GetPlayerInfo().c_str());
209 return;
210 }
211
212 if (!forced)
213 {
214 OpcodeHandler const* handler = serverOpcodeTable[packet->GetOpcode()];
215 if (!handler || handler->Status == STATUS_UNHANDLED)
216 {
217 if (packet->GetOpcode() == NULL_OPCODE)
218 {
219 SF_LOG_ERROR("network.opcode", "Prevented sending disabled opcode %s to %s", GetOpcodeNameForLogging(packet->GetOpcode(), true).c_str(), GetPlayerInfo().c_str());
220 }
221 else
222 {
223 SF_LOG_ERROR("network.opcode", "Disabled opcode %s have opcode value, but is disabled missing structure update?", GetOpcodeNameForLogging(packet->GetOpcode(), true).c_str());
224 }
225 return;
226 }
227 }
228
229#ifdef SKYFIRE_DEBUG
230 // Code for network use statistic
231 static uint64 sendPacketCount = 0;
232 static uint64 sendPacketBytes = 0;
233
234 static time_t firstTime = time(NULL);
235 static time_t lastTime = firstTime; // next 60 secs start time
236
237 static uint64 sendLastPacketCount = 0;
238 static uint64 sendLastPacketBytes = 0;
239
240 time_t cur_time = time(NULL);
241
242 if ((cur_time - lastTime) < 60)
243 {
244 sendPacketCount += 1;
245 sendPacketBytes += packet->size();
246
247 sendLastPacketCount += 1;
248 sendLastPacketBytes += packet->size();
249 }
250 else
251 {
252 uint64 minTime = uint64(cur_time - lastTime);
253 uint64 fullTime = uint64(lastTime - firstTime);
254 SF_LOG_INFO("misc", "Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u", sendPacketCount, sendPacketBytes, float(sendPacketCount) / fullTime, float(sendPacketBytes) / fullTime, uint32(fullTime));
255 SF_LOG_INFO("misc", "Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount) / minTime, float(sendLastPacketBytes) / minTime);
256
257 lastTime = cur_time;
258 sendLastPacketCount = 1;
259 sendLastPacketBytes = packet->wpos(); // wpos is real written size
260 }
261#endif // !SKYFIRE_DEBUG
262
263 if (m_Socket->SendPacket(*packet) == -1)
264 m_Socket->CloseSocket();
265}
266
267void WorldSession::LogPacketMarker(std::string const& marker)
268{
269 if (m_Socket)
270 m_Socket->LogPacketMarker(marker);
271}
272
275{
276 std::size_t const packetQueueDepth = _recvQueue.add(new_packet);
278}
279
281void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char* reason) const
282{
283 SF_LOG_ERROR("network.opcode", "Received unexpected opcode %s Status: %s Reason: %s from %s",
284 GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str(), status, reason, GetPlayerInfo().c_str());
285}
286
289{
290 if (!sLog->ShouldLog("network.opcode", LogLevel::LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
291 return;
292
293 SF_LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at %u from %u) Opcode %s from %s",
294 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str(), GetPlayerInfo().c_str());
295 packet->print_storage();
296}
297
300{
302 UpdateTimeOutTime(diff);
303 m_charBooster->Update(diff);
305
308 if (IsConnectionIdle())
309 m_Socket->CloseSocket();
310
313 WorldPacket* packet = NULL;
315 bool deletePacket = true;
317 WorldPacket* firstDelayedPacket = NULL;
323 uint32 processedPackets = 0;
324
325 while (m_Socket && !m_Socket->IsClosed() &&
326 !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
327 _recvQueue.next(packet, updater))
328 {
329 if (!AntiDOS.EvaluateOpcode(*packet))
330 KickPlayer();
331
332 OpcodeHandler const* opHandle = clientOpcodeTable[packet->GetOpcode()];
333 try
334 {
335 switch (opHandle->Status)
336 {
337 case STATUS_LOGGEDIN:
338 if (!_player)
339 {
340 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
344 {
346 if (!firstDelayedPacket)
347 firstDelayedPacket = packet;
349 deletePacket = false;
350 QueuePacket(packet);
352 SF_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. "
353 "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str());
354 }
355 }
356 else if (_player->IsInWorld())
357 {
358 sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
359 (this->*opHandle->Handler)(*packet);
360 LogUnprocessedTail(packet);
361 }
362 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
363 break;
365 if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
366 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
367 "the player has not logged in yet and not recently logout");
368 else
369 {
370 // not expected _player or must checked in packet hanlder
371 sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
372 (this->*opHandle->Handler)(*packet);
373 LogUnprocessedTail(packet);
374 }
375 break;
376 case STATUS_TRANSFER:
377 if (!_player)
378 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
379 else if (_player->IsInWorld())
380 LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
381 else
382 {
383 sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
384 (this->*opHandle->Handler)(*packet);
385 LogUnprocessedTail(packet);
386 }
387 break;
388 case STATUS_AUTHED:
389 // prevent cheating with skip queue wait
390 if (m_inQueue)
391 {
392 LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
393 break;
394 }
395
396 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
397 // however when we recieve CMSG_ENUM_CHARACTERS we are surely no longer during the logout process.
398 if (packet->GetOpcode() == CMSG_ENUM_CHARACTERS)
400
401 sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
402 (this->*opHandle->Handler)(*packet);
403 LogUnprocessedTail(packet);
404 break;
405 case STATUS_NEVER:
406 SF_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str(),
407 GetPlayerInfo().c_str());
408 break;
409 case STATUS_UNHANDLED:
410 SF_LOG_ERROR("network.opcode", "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str(),
411 GetPlayerInfo().c_str());
412 break;
413 }
414 }
415 catch (ByteBufferException const&)
416 {
417 SF_LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %s) from client %s, accountid=%i. Skipped packet.",
418 GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str(), GetRemoteAddress().c_str(), GetAccountId());
419 packet->hexlike();
420 }
421
422 if (deletePacket)
423 delete packet;
424
425 deletePacket = true;
426
427#define MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE 100
428 processedPackets++;
430
431 //process only a max amout of packets in 1 Update() call.
432 //Any leftover will be processed in next update
434 break;
435 }
436
437 if (m_Socket && !m_Socket->IsClosed() && _warden)
438 _warden->Update();
439
441
442 //check if we are safe to proceed with logout
443 //logout procedure should happen only in World::UpdateSessions() method!!!
444 if (updater.ProcessLogout())
445 {
446 time_t currTime = time(NULL);
448 if (ShouldLogOut(currTime) && !m_playerLoading)
449 LogoutPlayer(true);
450
451 if (m_Socket && GetPlayer() && _warden)
452 _warden->Update();
453
455 if (m_Socket && m_Socket->IsClosed())
456 {
457 m_Socket->DetachSession(this);
458 m_Socket->RemoveReference();
459 m_Socket = NULL;
460 }
461
462 if (!m_Socket)
463 return false; //Will remove this session from the world session map
464 }
465
466 return true;
467}
468
471{
472 // finish pending transfers before starting the logout
473 while (_player && _player->IsBeingTeleportedFar())
475
476 m_playerLogout = true;
477 m_playerSave = save;
478
479 if (_player)
480 {
482
483 if (uint64 lguid = _player->GetLootGUID())
484 DoLootRelease(lguid);
485
487 //FIXME: logout must be delayed in case lost connection with client in time of combat
488 if (_player->GetDeathTimer())
489 {
490 _player->getHostileRefManager().deleteReferences();
491 _player->BuildPlayerRepop();
492 _player->RepopAtGraveyard();
493 }
494 else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
495 {
496 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
497 _player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
498 _player->KillPlayer();
499 _player->BuildPlayerRepop();
500 _player->RepopAtGraveyard();
501 }
502 else if (_player->HasPendingBind())
503 {
504 _player->RepopAtGraveyard();
505 _player->SetPendingBind(0, 0);
506 }
507
508 //drop a flag if player is carrying it
509 if (Battleground* bg = _player->GetBattleground())
510 bg->EventPlayerLoggedOut(_player);
511
513 if (!_player->m_InstanceValid && !_player->IsGameMaster())
514 _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
515
516 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
517
518 for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
519 {
520 if (BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i))
521 {
522 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
523 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
524 queue.RemovePlayer(_player->GetGUID(), true);
525 }
526 }
527
528 // Repop at GraveYard or other player far teleport will prevent saving player because of not present map
529 // Teleport player immediately for correct player save
530 while (_player->IsBeingTeleportedFar())
532
534 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
535 guild->HandleMemberLogout(this);
536
538 _player->RemovePet(NULL, PET_SAVE_AS_CURRENT, true);
539
541 _player->ClearWhisperWhiteList();
542
544 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
545 if (save)
546 {
547 uint32 eslot;
548 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
549 {
550 eslot = j - BUYBACK_SLOT_START;
551 _player->SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOTS + (eslot * 2), 0);
552 _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE + eslot, 0);
553
554 _player->SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP + eslot, 0);
555 }
556 _player->SaveToDB();
557 }
558
560 _player->CleanupChannels();
561
562 // if player is leader of a group and is holding a ready check, complete it early
563 _player->ReadyCheckComplete();
564
566 _player->UninviteFromGroup();
567
568 // remove player from the group if he is:
569 // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected)
570 if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket)
571 _player->RemoveFromGroup();
572
574 if (_player->GetGroup())
575 {
576 _player->GetGroup()->SendUpdate();
577 _player->GetGroup()->ResetMaxEnchantingLevel();
578 }
579
581 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true);
582 sSocialMgr->RemovePlayerSocial(_player->GetGUIDLow());
583
585 sScriptMgr->OnPlayerLogout(_player);
586
588 // the player may not be in the world when logging out
589 // e.g if he got disconnected during a transfer to another map
590 // calls to GetMap in this case may cause crashes
591 _player->CleanupsBeforeDelete();
592 SF_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
593 GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel());
594 if (Map* _map = _player->FindMap())
595 _map->RemovePlayerFromMap(_player, true);
596
597 SetPlayer(NULL);
598
602 SendPacket(&data);
603
604 SF_LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
605
607 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ACCOUNT_ONLINE);
608 stmt->setUInt32(0, GetAccountId());
609 CharacterDatabase.Execute(stmt);
610 }
611
612 m_playerLogout = false;
613 m_playerSave = false;
615 AntiDOS.AllowOpcode(CMSG_ENUM_CHARACTERS, true);
616 LogoutRequest(0);
617}
618
621{
622 if (m_Socket)
623 m_Socket->CloseSocket();
624}
625
626void WorldSession::SendNotification(const char* format, ...)
627{
628 if (format)
629 {
630 va_list ap;
631 char szStr[1024];
632 szStr[0] = '\0';
633 va_start(ap, format);
634 vsnprintf(szStr, 1024, format, ap);
635 va_end(ap);
636
637 size_t len = strlen(szStr);
638 WorldPacket data(SMSG_NOTIFICATION, 2 + len);
639 data.WriteBits(len, 12);
640 data.FlushBits();
641 data.append(szStr, len);
642 SendPacket(&data);
643 }
644}
645
647{
648 char const* format = GetSkyFireString(string_id);
649 if (format)
650 {
651 va_list ap;
652 char szStr[1024];
653 szStr[0] = '\0';
654 va_start(ap, string_id);
655 vsnprintf(szStr, 1024, format, ap);
656 va_end(ap);
657
658 size_t len = strlen(szStr);
659 WorldPacket data(SMSG_NOTIFICATION, 2 + len);
660 data.WriteBits(len, 12);
661 data.FlushBits();
662 data.append(szStr, len);
663 SendPacket(&data);
664 }
665}
666
667const char* WorldSession::GetSkyFireString(int32 entry) const
668{
669 return sObjectMgr->GetSkyFireString(entry, GetSessionDbLocaleIndex());
670}
671
673{
674 SF_LOG_ERROR("network.opcode", "Received unhandled opcode %s from %s",
675 GetOpcodeNameForLogging(recvPacket.GetOpcode(), false).c_str(), GetPlayerInfo().c_str());
676}
677
679{
681 data << uint8(reason);
682 SendPacket(&data);
683}
684
686{
687 SF_LOG_ERROR("network.opcode", "Received opcode %s that must be processed in WorldSocket::OnRead from %s",
688 GetOpcodeNameForLogging(recvPacket.GetOpcode(), false).c_str(), GetPlayerInfo().c_str());
689}
690
691void WorldSession::Handle_EarlyProccessContinued(WorldPacket& recvPacket) //CMSG_AUTH_CONTINUED_SESSION(void *this, int a2)
692{
693 SF_LOG_ERROR("network.opcode", "Recived opcode %s that must be processed in WorldSocket::Unknown from %s",
694 GetOpcodeNameForLogging(recvPacket.GetOpcode(), false).c_str(), GetPlayerInfo().c_str());
695
696 /*
697 void *v2; // esi@1
698
699 v2 = this;
700 sub_40F075(3913);
701 return (*(*v2 + 4))(v2, a2);
702 */
703}
704
706{
707 SF_LOG_ERROR("network.opcode", "Received deprecated opcode %s from %s",
708 GetOpcodeNameForLogging(recvPacket.GetOpcode(), false).c_str(), GetPlayerInfo().c_str());
709}
710
712{
713 if (position == 0)
714 {
716 packet.WriteBit(0); // has account info
717 packet.WriteBit(0); // has queue info
718 packet << uint8(ResponseCodes::AUTH_OK);
719 packet.FlushBits();
720 SendPacket(&packet);
721 }
722 else
723 {
725 packet.WriteBit(0); // has account info
726 packet.WriteBit(1); // has queue info
727 packet.WriteBit(0); // unk queue bool
729 packet.FlushBits();
730 packet << uint32(position);
731 SendPacket(&packet);
732 }
733}
734
741
743{
745 for (uint8 i = 0; i < maxADT; ++i)
746 if (mask & (1 << i))
748
749 if (!result)
750 return;
751
752 do
753 {
754 Field* fields = result->Fetch();
755 uint32 type = fields[0].GetUInt8();
757 {
758 SF_LOG_ERROR("misc", "Table `%s` have invalid account data type (%u), ignore.",
759 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
760 continue;
761 }
762
763 if ((mask & (1 << type)) == 0)
764 {
765 SF_LOG_ERROR("misc", "Table `%s` have non appropriate for table account data type (%u), ignore.",
766 mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
767 continue;
768 }
769
770 m_accountData[type].Time = time_t(fields[1].GetUInt32());
771 m_accountData[type].Data = fields[2].GetString();
772 } while (result->NextRow());
773}
774
775void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string const& data)
776{
777 uint32 id = 0;
778 uint32 index = 0;
779 if ((1 << uint8(type)) & GLOBAL_CACHE_MASK)
780 {
781 id = GetAccountId();
782 index = CHAR_REP_ACCOUNT_DATA;
783 }
784 else
785 {
786 // _player can be NULL and packet received after logout but m_GUID still store correct guid
787 if (!m_GUIDLow)
788 return;
789
790 id = m_GUIDLow;
792 }
793
794 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
795 stmt->setUInt32(0, id);
796 stmt->setUInt8(1, uint8(type));
797 stmt->setUInt32(2, uint32(tm));
798 stmt->setString(3, data);
799 CharacterDatabase.Execute(stmt);
800
801 m_accountData[uint8(type)].Time = tm;
802 m_accountData[uint8(type)].Data = data;
803}
804
806{
807 WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + (8 * 4));
808
809 data.WriteBit(1);
810 data.FlushBits();
811
813 for (uint8 i = 0; i < maxADT; ++i)
814 data << uint32(GetAccountData(AccountDataType(i))->Time); // also unix time
815
816 data << uint32(mask);
817 data << uint32(time(NULL)); // Server time
818
819 SendPacket(&data);
820}
821
823{
824 memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
825
826 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS);
827 stmt->setUInt32(0, GetAccountId());
828 if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
829 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
830 m_Tutorials[i] = (*result)[i].GetUInt32();
831
832 m_TutorialsChanged = false;
833}
834
842
844{
846 return;
847
848 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_HAS_TUTORIALS);
849 stmt->setUInt32(0, GetAccountId());
850 bool hasTutorials = !CharacterDatabase.Query(stmt).null();
851 // Modify data in DB
852 stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
853 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
854 stmt->setUInt32(i, m_Tutorials[i]);
856 trans->Append(stmt);
857
858 m_TutorialsChanged = false;
859}
860
862{
863 if (data.rpos() + 4 > data.size())
864 return;
865
866 uint32 size;
867 data >> size;
868
869 if (!size)
870 return;
871
872 if (size > 0xFFFFF)
873 {
874 SF_LOG_ERROR("misc", "WorldSession::ReadAddonsInfo addon info too big, size %u", size);
875 return;
876 }
877
878 uLongf uSize = size;
879
880 uint32 pos = data.rpos();
881
882 ByteBuffer addonInfo;
883 addonInfo.resize(size);
884
885 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
886 {
887 uint32 addonsCount;
888 addonInfo >> addonsCount; // addons count
889
890 for (uint32 i = 0; i < addonsCount; ++i)
891 {
892 std::string addonName;
893 uint8 usingPubKey;
894 uint32 crc, urlFile;
895
896 // check next addon data format correctness
897 if (addonInfo.rpos() + 1 > addonInfo.size())
898 return;
899
900 addonInfo >> addonName;
901
902 addonInfo >> usingPubKey >> crc >> urlFile;
903
904 SF_LOG_INFO("misc", "ADDON: Name: %s, UsePubKey: 0x%x, CRC: 0x%x, UrlFile: %i", addonName.c_str(), usingPubKey, crc, urlFile);
905
906 AddonInfo addon(addonName, true, crc, 2, usingPubKey);
907
908 SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName);
909 if (savedAddon)
910 {
911 if (addon.CRC != savedAddon->CRC)
912 SF_LOG_INFO("misc", "ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC);
913 else
914 SF_LOG_INFO("misc", "ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC);
915 }
916 else
917 {
918 AddonMgr::SaveAddon(addon);
919
920 SF_LOG_INFO("misc", "ADDON: %s (0x%x) was not known, saving...", addon.Name.c_str(), addon.CRC);
921 }
922
924 m_addonsList.push_back(addon);
925 }
926
927 uint32 currentTime;
928 addonInfo >> currentTime;
929 SF_LOG_DEBUG("network", "ADDON: CurrentTime: %u", currentTime);
930 }
931 else
932 SF_LOG_ERROR("misc", "Addon packet uncompress error!");
933}
934
936{
937 uint8 addonPublicKey[256] =
938 {
939 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
940 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
941 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
942 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
943 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
944 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
945 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
946 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
947 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
948 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
949 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
950 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
951 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
952 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
953 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
954 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
955 };
956
957 uint8 pubKeyOrder[256] =
958 {
959 0x05, 0xB0, 0x94, 0x2B, 0x1C, 0x87, 0x40, 0x08, 0xA0, 0x91, 0xE2, 0x77, 0xB5, 0xC0, 0xF0, 0x48,
960 0xF3, 0xD4, 0xD1, 0xAC, 0x15, 0xED, 0x55, 0x0A, 0x4B, 0x75, 0xF4, 0x52, 0x18, 0x14, 0x12, 0x4C,
961 0x43, 0x39, 0x9D, 0x3B, 0xC6, 0x5A, 0x16, 0x06, 0x31, 0x0C, 0x5F, 0xC1, 0x76, 0x5E, 0x28, 0x62,
962 0xFF, 0xA9, 0xD6, 0x53, 0x80, 0xDB, 0x49, 0xF7, 0x84, 0xCA, 0xDA, 0x9A, 0x70, 0x83, 0xB1, 0x6F,
963 0x90, 0x38, 0x27, 0x98, 0x30, 0x3F, 0x19, 0x72, 0x26, 0x54, 0x63, 0xA5, 0x7E, 0x22, 0x45, 0xB7,
964 0xB9, 0x34, 0x67, 0x24, 0xE9, 0x03, 0x2F, 0x8D, 0xA2, 0xE8, 0xC2, 0xFD, 0x74, 0x1B, 0x50, 0x2E,
965 0x59, 0x6B, 0xBD, 0x0E, 0xE1, 0xA7, 0x8C, 0xFA, 0xBC, 0x11, 0x1D, 0x89, 0x85, 0x4A, 0xB2, 0x3E,
966 0xEC, 0x1F, 0x65, 0x09, 0xA4, 0xC8, 0x88, 0x9F, 0xC5, 0xD8, 0xF6, 0x86, 0x00, 0x61, 0xEA, 0xA6,
967 0xCC, 0x41, 0x3C, 0xDF, 0x7A, 0x02, 0x04, 0xEF, 0xF9, 0x1E, 0xFC, 0xD3, 0x7C, 0x1A, 0x17, 0xA1,
968 0x5C, 0x8A, 0x25, 0xE3, 0x78, 0x99, 0x73, 0x97, 0xFE, 0xAD, 0xAF, 0x6C, 0x82, 0xFB, 0xAA, 0x9E,
969 0x0B, 0xF5, 0xBE, 0x68, 0xD9, 0x07, 0x4E, 0xE7, 0x9B, 0xAB, 0x37, 0x51, 0x8F, 0xCE, 0x46, 0x9C,
970 0x58, 0x2D, 0xC9, 0xB6, 0xB4, 0x10, 0xD7, 0xE6, 0x32, 0x95, 0xCB, 0xA8, 0xDC, 0xBB, 0x29, 0x3D,
971 0xEE, 0xD0, 0xE0, 0x6A, 0xCD, 0xDE, 0x2A, 0x44, 0x7F, 0xD2, 0x4D, 0x81, 0xD5, 0x0F, 0x66, 0x92,
972 0x36, 0x23, 0x5B, 0x13, 0xC7, 0x20, 0x8B, 0x96, 0xC4, 0x7D, 0x35, 0x64, 0x71, 0x6E, 0x47, 0xBF,
973 0x3A, 0xF2, 0xF8, 0x0D, 0xB8, 0xA3, 0x93, 0x4F, 0x5D, 0xE5, 0xE4, 0xBA, 0xCF, 0x01, 0x42, 0x21,
974 0x79, 0x60, 0x7B, 0xB3, 0xEB, 0xF1, 0x6D, 0x8E, 0x2C, 0x56, 0xC3, 0xAE, 0x57, 0x69, 0x33, 0xDD,
975 };
976
977 WorldPacket data(SMSG_ADDON_INFO, 1000);
978
980 data.WriteBits((uint32)bannedAddons->size(), 18);
981 data.WriteBits((uint32)m_addonsList.size(), 23);
982
983 for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
984 {
985 data.WriteBit(0); // Has URL
986 data.WriteBit(itr->Enabled);
987 data.WriteBit(!itr->UsePublicKeyOrCRC); // If client doesnt have it, send it
988 }
989
990 data.FlushBits();
991
992 for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
993 {
994 if (!itr->UsePublicKeyOrCRC)
995 {
996 size_t pos = data.wpos();
997 for (int i = 0; i < 256; i++)
998 data << uint8(0);
999
1000 for (int i = 0; i < 256; i++)
1001 data.put(pos + pubKeyOrder[i], addonPublicKey[i]);
1002 }
1003
1004 if (itr->Enabled)
1005 {
1006 data << uint8(itr->Enabled);
1007 data << uint32(0);
1008 }
1009
1010 data << uint8(itr->State);
1011 }
1012
1013 m_addonsList.clear();
1014
1015 for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
1016 {
1017 data << uint32(itr->Id);
1018 data << uint32(1); // IsBanned
1019
1020 for (int32 i = 0; i < 8; i++)
1021 data << uint32(0);
1022
1023 // Those 3 might be in wrong order
1024 data << uint32(itr->Timestamp);
1025 }
1026
1027 SendPacket(&data);
1028}
1029
1031{
1032 char timezoneString[256];
1033
1034 // TIME_ZONE_INFORMATION timeZoneInfo;
1035 // GetTimeZoneInformation(&timeZoneInfo);
1036 // wcstombs(timezoneString, timeZoneInfo.StandardName, sizeof(timezoneString));
1037
1038 snprintf(timezoneString, sizeof(timezoneString), "Etc/UTC"); // The method above cannot be used, because of non-english OS translations, so we send const data (possible strings are hardcoded in the client because of the same reason)
1039
1040 WorldPacket data(SMSG_SET_TIME_ZONE_INFORMATION, 2 + strlen(timezoneString) * 2);
1041 data.WriteBits(strlen(timezoneString), 7);
1042 data.WriteBits(strlen(timezoneString), 7);
1043 data.FlushBits();
1044 data.WriteString(timezoneString);
1045 data.WriteString(timezoneString);
1046 SendPacket(&data);
1047}
1048
1049bool WorldSession::IsAddonRegistered(const std::string& prefix) const
1050{
1051 if (!_filterAddonMessages) // if we have hit the softcap (64) nothing should be filtered
1052 return true;
1053
1054 if (_registeredAddonPrefixes.empty())
1055 return false;
1056
1057 std::vector<std::string>::const_iterator itr = std::find(_registeredAddonPrefixes.begin(), _registeredAddonPrefixes.end(), prefix);
1058 return itr != _registeredAddonPrefixes.end();
1059}
1060
1062{
1063 SF_LOG_DEBUG("network", "WORLD: Received CMSG_UNREGISTER_ALL_ADDON_PREFIXES");
1064
1066}
1067
1069{
1070 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ADDON_REGISTERED_PREFIXES");
1071
1072 // This is always sent after CMSG_UNREGISTER_ALL_ADDON_PREFIXES
1073
1074 uint32 count = recvPacket.ReadBits(24);
1075
1077 {
1078 // if we have hit the softcap (64) nothing should be filtered
1079 _filterAddonMessages = false;
1080 recvPacket.rfinish();
1081 return;
1082 }
1083
1084 std::vector<uint8> lengths(count);
1085 for (uint32 i = 0; i < count; ++i)
1086 lengths[i] = recvPacket.ReadBits(5);
1087
1088 for (uint32 i = 0; i < count; ++i)
1089 _registeredAddonPrefixes.push_back(recvPacket.ReadString(lengths[i]));
1090
1091 if (_registeredAddonPrefixes.size() > REGISTERED_ADDON_PREFIX_SOFTCAP) // shouldn't happen
1092 {
1093 _filterAddonMessages = false;
1094 return;
1095 }
1096
1097 _filterAddonMessages = true;
1098}
1099
1101{
1102 _player = player;
1103
1104 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1105 if (_player)
1106 {
1107 m_GUIDLow = _player->GetGUIDLow();
1108 if (m_Socket)
1109 m_Socket->RefreshPacketLogSessionInfo();
1110 }
1111}
1112
1114{
1115 // Callback parameters that have pointers in them should be properly
1116 // initialized to NULL here.
1117 _charCreateCallback.SetParam(NULL);
1118}
1119
1121{
1122 PreparedQueryResult result;
1123
1125 if (_charEnumCallback.ready())
1126 {
1127 _charEnumCallback.get(result);
1128 HandleCharEnum(result);
1129 _charEnumCallback.cancel();
1130 }
1131
1132 if (_charCreateCallback.IsReady())
1133 {
1134 _charCreateCallback.GetResult(result);
1136 // Don't call FreeResult() here, the callback handler will do that depending on the events in the callback chain
1137 }
1138
1140 if (_charLoginCallback.ready())
1141 {
1142 SQLQueryHolder* param;
1143 _charLoginCallback.get(param);
1145 _charLoginCallback.cancel();
1146 }
1147
1149 if (_addFriendCallback.IsReady())
1150 {
1151 std::string param = _addFriendCallback.GetParam();
1152 _addFriendCallback.GetResult(result);
1153 HandleAddFriendOpcodeCallBack(result, param);
1154 _addFriendCallback.FreeResult();
1155 }
1156
1157 //- HandleCharRenameOpcode
1158 if (_charRenameCallback.IsReady())
1159 {
1160 std::string param = _charRenameCallback.GetParam();
1161 _charRenameCallback.GetResult(result);
1163 _charRenameCallback.FreeResult();
1164 }
1165
1166 //- HandleCharAddIgnoreOpcode
1167 if (_addIgnoreCallback.ready())
1168 {
1169 _addIgnoreCallback.get(result);
1171 _addIgnoreCallback.cancel();
1172 }
1173
1174 //- SendStabledPet
1175 if (_sendStabledPetCallback.IsReady())
1176 {
1177 uint64 param = _sendStabledPetCallback.GetParam();
1178 _sendStabledPetCallback.GetResult(result);
1179 SendStablePetCallback(result, param);
1180 _sendStabledPetCallback.FreeResult();
1181 }
1182
1183 //- HandleStablePet
1184 if (_stablePetCallback.ready())
1185 {
1186 _stablePetCallback.get(result);
1188 _stablePetCallback.cancel();
1189 }
1190
1191 //- HandleUnstablePet
1192 if (_unstablePetCallback.IsReady())
1193 {
1194 uint32 param = _unstablePetCallback.GetParam();
1195 _unstablePetCallback.GetResult(result);
1196 HandleUnstablePetCallback(result, param);
1197 _unstablePetCallback.FreeResult();
1198 }
1199
1200 //- HandleStableSwapPet
1201 if (_stableSwapCallback.IsReady())
1202 {
1203 uint32 param = _stableSwapCallback.GetParam();
1204 _stableSwapCallback.GetResult(result);
1205 HandleStableSwapPetCallback(result, param);
1206 _stableSwapCallback.FreeResult();
1207 }
1208}
1209
1210void WorldSession::InitWarden(SessionKey const& k, std::string const& os)
1211{
1212 if (os == "Win")
1213 {
1214 _warden = new WardenWin();
1215 _warden->Init(this, k);
1216 }
1217 else if (os == "OSX")
1218 {
1219 // Disabled as it is causing the client to crash
1220 // _warden = new WardenMac();
1221 // _warden->Init(this, k);
1222 }
1223}
1224
1226{
1227 uint32 id = GetAccountId();
1228 std::string name;
1229 AccountMgr::GetName(id, name);
1230 AccountTypes secLevel = GetSecurity();
1231
1232 _RBACData = new rbac::RBACData(id, name, GetVirtualRealmID(), uint8(secLevel));
1233 _RBACData->LoadFromDB();
1234
1235 SF_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]",
1236 id, name.c_str(), GetVirtualRealmID(), uint8(secLevel));
1237}
1238
1243
1245{
1246 if (!_RBACData)
1248
1249 bool hasPermission = _RBACData->HasPermission(permission);
1250 SF_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]",
1251 _RBACData->GetId(), _RBACData->GetName().c_str(), GetVirtualRealmID());
1252
1253 return hasPermission;
1254}
1255
1257{
1258 SF_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]",
1259 _RBACData->GetId(), _RBACData->GetName().c_str(), GetVirtualRealmID());
1260 delete _RBACData;
1261 _RBACData = NULL;
1262}
1263
1265{
1266 if (IsOpcodeAllowed(p.GetOpcode()))
1267 return true;
1268
1269 // Opcode not allowed, let the punishment begin
1270 SF_LOG_INFO("network", "AntiDOS: Account %u, IP: %s, sent unacceptable packet (opc: %u, size: %u)",
1271 Session->GetAccountId(), Session->GetRemoteAddress().c_str(), p.GetOpcode(), (uint32)p.size());
1272
1273 switch (_policy)
1274 {
1275 case POLICY_LOG:
1276 return true;
1277 case POLICY_KICK:
1278 SF_LOG_INFO("network", "AntiDOS: Player kicked!");
1279 return false;
1280 case POLICY_BAN:
1281 {
1283 uint32 duration = sWorld->getIntConfig(WorldIntConfigs::CONFIG_PACKET_SPOOF_BANDURATION); // in seconds
1284 std::string nameOrIp = "";
1285 switch (bm)
1286 {
1287 case BAN_CHARACTER: // not supported, ban account
1288 case BAN_ACCOUNT: (void)sAccountMgr->GetName(Session->GetAccountId(), nameOrIp); break;
1289 case BAN_IP: nameOrIp = Session->GetRemoteAddress(); break;
1290 }
1291 sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
1292 SF_LOG_INFO("network", "AntiDOS: Player automatically banned for %u seconds.", duration);
1293
1294 return false;
1295 }
1296 default: // invalid policy
1297 return true;
1298 }
1299}
#define sAccountMgr
Definition AccountMgr.h:85
@ LOG_LEVEL_TRACE
Definition Appender.h:18
std::array< uint8, SESSION_KEY_LENGTH > SessionKey
Definition AuthDefines.h:8
@ STATUS_AUTHED
#define sBattlegroundMgr
@ CHAR_INS_TUTORIALS
@ CHAR_UPD_TUTORIALS
@ CHAR_SEL_TUTORIALS
@ CHAR_SEL_HAS_TUTORIALS
@ CHAR_SEL_ACCOUNT_DATA
@ CHAR_UPD_ACCOUNT_ONLINE
@ CHAR_REP_PLAYER_ACCOUNT_DATA
@ CHAR_REP_ACCOUNT_DATA
#define vsnprintf
Definition Common.h:100
LocaleConstant
Definition Common.h:138
AccountTypes
Definition Common.h:129
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition Common.h:157
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define sGuildMgr
Definition GuildMgr.h:53
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_TRACE(filterType__,...)
Definition Log.h:131
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define sLog
Definition Log.h:106
#define sObjectMgr
Definition ObjectMgr.h:1617
#define sOutdoorPvPMgr
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:22
@ BUYBACK_SLOT_END
Definition Player.h:739
@ BUYBACK_SLOT_START
Definition Player.h:738
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
#define sScriptMgr
Definition ScriptMgr.h:764
ResponseCodes
BattlegroundQueueTypeId
#define PLAYER_MAX_BATTLEGROUND_QUEUES
BanMode
Ban function modes.
@ BAN_ACCOUNT
@ BAN_IP
@ BAN_CHARACTER
#define sSocialMgr
Definition SocialMgr.h:134
@ FRIEND_OFFLINE
Definition SocialMgr.h:60
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ PLAYER_FIELD_VENDORBUYBACK_SLOTS
@ PLAYER_FIELD_BUYBACK_TIMESTAMP
@ PLAYER_FIELD_BUYBACK_PRICE
#define MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE
static bool GetName(uint32 accountId, std::string &name)
void RemovePlayer(uint64 guid, bool decreaseInvitedCount)
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void put(size_t pos, T value)
Definition ByteBuffer.h:233
size_t rpos() const
Definition ByteBuffer.h:470
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void resize(size_t newsize)
Definition ByteBuffer.h:612
void hexlike() const
void print_storage() const
void append(T value)
Definition ByteBuffer.h:147
void rfinish()
Definition ByteBuffer.h:478
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
size_t wpos() const
Definition ByteBuffer.h:483
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
size_t size() const
Definition ByteBuffer.h:609
void FlushBits()
Definition ByteBuffer.h:154
uint8 * contents()
Definition ByteBuffer.h:605
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
Definition Guild.h:324
Definition Map.h:238
virtual bool Process(WorldPacket *packet)
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
virtual bool ProcessLogout() const
WorldSession *const m_pSession
void setString(const uint8 index, const std::string &value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void RecordWorldSessionPacketQueued(uint32 queueDepth)
void RecordWorldSessionPacketProcessed(uint32 queueDepth)
Opcodes GetOpcode() const
Definition WorldPacket.h:38
bool EvaluateOpcode(WorldPacket &p) const
bool IsOpcodeAllowed(uint16 opcode) const
virtual bool Process(WorldPacket *packet)
QueryCallback< PreparedQueryResult, CharacterCreateInfo *, true > _charCreateCallback
void SetPlayer(Player *player)
bool m_playerRecentlyLogout
bool Update(uint32 diff, PacketFilter &updater)
Update the WorldSession (triggered by World update).
void SaveTutorialsData(SQLTransaction &trans)
void LogoutPlayer(bool save)
Log the player out
void KickPlayer()
Kick a player out of the World.
uint32 m_virtualRealmID
AccountData * GetAccountData(AccountDataType type)
void HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId)
std::string m_Address
const char * GetSkyFireString(int32 entry) const
Skyfire::LockedQueue< WorldPacket *, Skyfire::Mutex > _recvQueue
PreparedQueryResultFuture _stablePetCallback
void LogoutRequest(time_t requestTime)
Engage the logout process for the user.
AddonsList m_addonsList
void HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const &friendNote)
void InitializeQueryCallbackParameters()
void ReadAddonsInfo(WorldPacket &data)
LocaleConstant m_sessionDbLocaleIndex
void HandleAddonRegisteredPrefixesOpcode(WorldPacket &recvPacket)
void SendNotification(const char *format,...) ATTR_PRINTF(2
bool m_TutorialsChanged
uint32 GetGuidLow() const
Get player guid if available. Use for logging purposes only.
uint32 m_clientTimeDelay
AccountTypes GetSecurity() const
LocaleConstant GetSessionDbLocaleIndex() const
void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
void HandlePlayerLogin(LoginQueryHolder *holder)
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
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo *createInfo)
QueryCallback< PreparedQueryResult, std::string > _addFriendCallback
void UpdateTimeOutTime(uint32 diff)
std::string GetPlayerInfo() const
AccountData m_accountData[uint8(AccountDataType::NUM_ACCOUNT_DATA_TYPES)]
void SendAuthWaitQue(uint32 position)
Handle the authentication waiting queue (to be completed).
Player * GetPlayer() const
rbac::RBACData * _RBACData
void Handle_NULL(WorldPacket &recvPacket)
PreparedQueryResultFuture _charEnumCallback
void LogUnexpectedOpcode(WorldPacket *packet, const char *status, const char *reason) const
Logging helper for unexpected opcodes.
~WorldSession()
WorldSession destructor.
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string const &newName)
void Handle_EarlyProccess(WorldPacket &recvPacket)
QueryCallback< PreparedQueryResult, std::string > _charRenameCallback
void ClearPetBattlePvpQueueState()
void Handle_EarlyProccessContinued(WorldPacket &recvPacket)
void LoadTutorialsData()
PreparedQueryResultFuture _addIgnoreCallback
void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId)
uint32 GetVirtualRealmID() const
void SendAddonsInfo()
QueryCallback< PreparedQueryResult, uint32 > _unstablePetCallback
QueryResultHolderFuture _charLoginCallback
void UpdatePetBattlePvpQueueState()
void HandleMoveWorldportAckOpcode()
void HandleCharEnum(PreparedQueryResult result)
bool HasPermission(uint32 permissionId)
void SendTimezoneInformation()
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
time_t timeLastWhoCommand
uint32 GetAccountId() const
z_stream_s * _compressionStream
void SendTutorialsData()
Player * _player
void LogUnprocessedTail(WorldPacket *packet) const
Logging helper for unexpected opcodes.
WorldSocket * m_Socket
void ResetTimeOutTime()
AccountTypes _security
void LogPacketMarker(std::string const &marker)
CharacterBooster * m_charBooster
void ProcessQueryCallbacks()
std::string const & GetRemoteAddress()
std::vector< std::string > _registeredAddonPrefixes
void HandleUnregisterAddonPrefixesOpcode(WorldPacket &recvPacket)
void Handle_Deprecated(WorldPacket &recvPacket) const
void DoLootRelease(uint64 lguid)
void SendAccountDataTimes(uint32 mask)
LocaleConstant m_sessionDbcLocale
WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool hasBoost)
WorldSession constructor.
QueryCallback< PreparedQueryResult, uint32 > _stableSwapCallback
void InitWarden(SessionKey const &, std::string const &os)
std::string const & GetPlayerName() const
time_t m_muteTime
void SendStablePetCallback(PreparedQueryResult result, uint64 guid)
void InvalidateRBACData()
void HandleStablePetCallback(PreparedQueryResult result)
bool IsAddonRegistered(const std::string &prefix) const
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
QueryCallback< PreparedQueryResult, uint64 > _sendStabledPetCallback
rbac::RBACData * GetRBACData()
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)
void LoadGlobalAccountData()
Warden * _warden
bool IsConnectionIdle() const
void SendCharacterLoginFailed(ResponseCodes reason)
bool _filterAddonMessages
Handler that can communicate over stream sockets.
Definition WorldSocket.h:51
long AddReference(void)
Add reference to this object.
const std::string & GetRemoteAddress(void) const
Get address of connected peer.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
#define REGISTERED_ADDON_PREFIX_SOFTCAP
std::string GetOpcodeNameForLogging(Opcodes id, bool isServerOpcode, uint16 opcodeNumber=0)
Lookup opcode name for human understandable logging.
Definition Opcodes.h:1157
OpcodeTable clientOpcodeTable
Definition Opcodes.cpp:10
OpcodeTable serverOpcodeTable
Definition Opcodes.cpp:9
#define GLOBAL_CACHE_MASK
AccountDataType
@ STATUS_LOGGEDIN
Definition Opcodes.h:1080
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition Opcodes.h:1082
@ STATUS_TRANSFER
Definition Opcodes.h:1081
@ STATUS_NEVER
Definition Opcodes.h:1083
@ STATUS_UNHANDLED
Definition Opcodes.h:1084
@ CMSG_ENUM_CHARACTERS
Definition Opcodes.h:153
@ SMSG_ADDON_INFO
Definition Opcodes.h:509
@ SMSG_ACCOUNT_DATA_TIMES
Definition Opcodes.h:505
@ SMSG_NOTIFICATION
Definition Opcodes.h:835
@ UNKNOWN_OPCODE
Definition Opcodes.h:1073
@ SMSG_TUTORIAL_FLAGS
Definition Opcodes.h:1042
@ SMSG_LOGOUT_COMPLETE
Definition Opcodes.h:763
@ SMSG_CHARACTER_LOGIN_FAILED
Definition Opcodes.h:603
@ SMSG_SET_TIME_ZONE_INFORMATION
Definition Opcodes.h:964
@ NULL_OPCODE
Definition Opcodes.h:22
@ SMSG_AUTH_RESPONSE
Definition Opcodes.h:534
@ PROCESS_INPLACE
Definition Opcodes.h:1089
@ PROCESS_THREADUNSAFE
Definition Opcodes.h:1090
#define sWorld
Definition World.h:910
@ CONFIG_PACKET_SPOOF_BANDURATION
Definition World.h:352
@ CONFIG_PACKET_SPOOF_BANMODE
Definition World.h:351
@ CONFIG_COMPRESSION
Definition World.h:199
std::list< BannedAddon > BannedAddonList
Definition AddonMgr.h:53
SavedAddon const * GetAddonInfo(const std::string &name)
Definition AddonMgr.cpp:98
void SaveAddon(AddonInfo const &addon)
Definition AddonMgr.cpp:84
BannedAddonList const * GetBannedAddons()
Definition AddonMgr.cpp:110
RuntimeMetrics & GetRuntimeMetrics()
LoginDatabaseWorkerPool LoginDatabase
Definition Main.cpp:54
std::string Name
Definition AddonMgr.h:19
uint32 CRC
Definition AddonMgr.h:21
pOpcodeHandler Handler
Definition Opcodes.h:1104
SessionStatus Status
Definition Opcodes.h:1106
PacketProcessing ProcessingPlace
Definition Opcodes.h:1107
uint32 CRC
Definition AddonMgr.h:34