Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
MiscHandler.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
6#include "AccountMgr.h"
7#include "AccountMgr.h"
8#include "Battlefield.h"
9#include "BattlefieldMgr.h"
10#include "Battleground.h"
11#include "BattlegroundMgr.h"
12#include "BigNumber.h"
13#include "CellImpl.h"
14#include "CharacterBoost.h"
15#include "Chat.h"
16#include "Common.h"
17#include "CreatureAI.h"
18#include "DatabaseEnv.h"
19#include "DB2Stores.h"
20#include "DBCEnums.h"
21#include "GameObjectAI.h"
22#include "GossipDef.h"
23#include "Group.h"
24#include "GuildMgr.h"
25#include "InstanceScript.h"
26#include "Language.h"
27#include "Log.h"
28#include "LootMgr.h"
29#include "MapManager.h"
30#include "Object.h"
31#include "ObjectAccessor.h"
32#include "ObjectMgr.h"
33#include "Opcodes.h"
34#include "OutdoorPvP.h"
35#include "Pet.h"
36#include "Player.h"
37#include "ScriptMgr.h"
38#include "SocialMgr.h"
39#include "Spell.h"
40#include "UpdateData.h"
41#include "Vehicle.h"
42#include "World.h"
43#include "WorldPacket.h"
44#include "WorldSession.h"
45#include "zlib.h"
46
47namespace
48{
49struct GuidRequest
50{
51 ObjectGuid guid;
52};
53
54struct UInt8Request
55{
56 uint8 value;
57};
58
59struct UInt32Request
60{
61 uint32 value;
62};
63
64struct Int32Request
65{
66 int32 value;
67};
68
69struct UInt64Request
70{
71 uint64 value;
72};
73
74struct BoolRequest
75{
76 bool value;
77};
78
79struct StringRequest
80{
81 std::string value;
82};
83
84struct GossipSelectOptionRequest
85{
86 ObjectGuid guid;
87 std::string code;
88 uint32 gossipListId;
89 uint32 menuId;
90};
91
92struct SetPvPRequest
93{
94 bool hasStatus;
95 bool newPvPStatus;
96};
97
98struct AddFriendRequest
99{
100 std::string name;
101 std::string note;
102};
103
104struct ContactNotesRequest
105{
106 uint64 guid;
107 std::string note;
108};
109
110struct BugReportRequest
111{
112 std::string content;
113 std::string type;
114 uint32 suggestion;
115};
116
117struct ResurrectResponseRequest
118{
119 ObjectGuid guid;
120 uint32 status;
121};
122
123struct AreaTriggerRequest
124{
125 uint32 triggerId;
126 uint8 unk1;
127 uint8 unk2;
128};
129
130struct ActionButtonRequest
131{
132 ObjectGuid buttonStream;
133 uint8 slotId;
134};
135
136struct WorldTeleportRequest
137{
138 uint32 time;
139 uint32 mapId;
140 float positionX;
141 float positionY;
142 float positionZ;
143 float orientation;
144};
145
146struct ComplainRequest
147{
148 uint64 spammerGuid;
149 uint32 unk1;
150 uint32 unk2;
151 uint32 unk3;
152 uint32 unk4;
153 std::string description;
154 uint8 spamType;
155};
156
157struct TimeSyncRequest
158{
159 uint32 counter;
160 uint32 clientTicks;
161};
162
163struct DiscardedTimeSyncAcksRequest
164{
165 bool hasCounter;
166 uint32 counter;
167};
168
169struct UpdateMissileTrajectoryRequest
170{
171 uint64 guid;
172 uint32 spellId;
173 float elevation;
174 float speed;
175 float curX;
176 float curY;
177 float curZ;
178 float targetX;
179 float targetY;
180 float targetZ;
181 uint8 moveStop;
182};
183
184struct SceneCompletedRequest
185{
186 uint32 unk;
187 uint8 hasData;
188};
189
190void ReadRepopRequest(WorldPacket& recvData)
191{
192 recvData.read_skip<uint8>();
193}
194
195GossipSelectOptionRequest ReadGossipSelectOptionRequest(WorldPacket& recvData, Player* player)
196{
197 GossipSelectOptionRequest request;
198 uint8 boxTextLength = 0;
199
200 recvData >> request.gossipListId >> request.menuId;
201
202 request.guid[3] = recvData.ReadBit();
203 request.guid[0] = recvData.ReadBit();
204 request.guid[1] = recvData.ReadBit();
205 request.guid[4] = recvData.ReadBit();
206 request.guid[7] = recvData.ReadBit();
207 request.guid[5] = recvData.ReadBit();
208 request.guid[6] = recvData.ReadBit();
209 boxTextLength = recvData.ReadBits(8);
210 request.guid[2] = recvData.ReadBit();
211
212 recvData.ReadByteSeq(request.guid[7]);
213 recvData.ReadByteSeq(request.guid[3]);
214 recvData.ReadByteSeq(request.guid[4]);
215 recvData.ReadByteSeq(request.guid[6]);
216 recvData.ReadByteSeq(request.guid[0]);
217 recvData.ReadByteSeq(request.guid[5]);
218
219 if (player->PlayerTalkClass->IsGossipOptionCoded(request.gossipListId))
220 request.code = recvData.ReadString(boxTextLength);
221
222 recvData.ReadByteSeq(request.guid[2]);
223 recvData.ReadByteSeq(request.guid[1]);
224
225 return request;
226}
227
228SetPvPRequest ReadSetPvPRequest(WorldPacket& recvData)
229{
230 SetPvPRequest request;
231 request.hasStatus = recvData.size() == 1;
232 request.newPvPStatus = false;
233
234 if (request.hasStatus)
235 request.newPvPStatus = recvData.ReadBit();
236
237 return request;
238}
239
240UInt32Request ReadUInt32Request(WorldPacket& recvData)
241{
242 UInt32Request request;
243 recvData >> request.value;
244 return request;
245}
246
247Int32Request ReadInt32Request(WorldPacket& recvData)
248{
249 Int32Request request;
250 recvData >> request.value;
251 return request;
252}
253
254UInt8Request ReadUInt8Request(WorldPacket& recvData)
255{
256 UInt8Request request;
257 recvData >> request.value;
258 return request;
259}
260
261UInt64Request ReadUInt64Request(WorldPacket& recvData)
262{
263 UInt64Request request;
264 recvData >> request.value;
265 return request;
266}
267
268StringRequest ReadStringRequest(WorldPacket& recvData)
269{
270 StringRequest request;
271 recvData >> request.value;
272 return request;
273}
274
275GuidRequest ReadSetSelectionRequest(WorldPacket& recvData)
276{
277 GuidRequest request;
278
279 request.guid[7] = recvData.ReadBit();
280 request.guid[6] = recvData.ReadBit();
281 request.guid[5] = recvData.ReadBit();
282 request.guid[4] = recvData.ReadBit();
283 request.guid[3] = recvData.ReadBit();
284 request.guid[2] = recvData.ReadBit();
285 request.guid[1] = recvData.ReadBit();
286 request.guid[0] = recvData.ReadBit();
287
288 recvData.ReadByteSeq(request.guid[0]);
289 recvData.ReadByteSeq(request.guid[7]);
290 recvData.ReadByteSeq(request.guid[3]);
291 recvData.ReadByteSeq(request.guid[5]);
292 recvData.ReadByteSeq(request.guid[1]);
293 recvData.ReadByteSeq(request.guid[4]);
294 recvData.ReadByteSeq(request.guid[6]);
295 recvData.ReadByteSeq(request.guid[2]);
296
297 return request;
298}
299
300void ReadContactListRequest(WorldPacket& recvData)
301{
302 recvData.read_skip<uint32>(); // always 1
303}
304
305AddFriendRequest ReadAddFriendRequest(WorldPacket& recvData)
306{
307 AddFriendRequest request;
308 recvData >> request.name;
309 recvData >> request.note;
310 return request;
311}
312
313StringRequest ReadAddIgnoreRequest(WorldPacket& recvData)
314{
315 return ReadStringRequest(recvData);
316}
317
318ContactNotesRequest ReadSetContactNotesRequest(WorldPacket& recvData)
319{
320 ContactNotesRequest request;
321 recvData >> request.guid >> request.note;
322 return request;
323}
324
325BugReportRequest ReadBugReportRequest(WorldPacket& recvData)
326{
327 BugReportRequest request;
328 uint32 contentLength;
329 uint32 typeLength;
330
331 recvData >> request.suggestion >> contentLength;
332 request.content = recvData.ReadString(contentLength);
333
334 recvData >> typeLength;
335 request.type = recvData.ReadString(typeLength);
336
337 return request;
338}
339
340void ReadReclaimCorpseRequest(WorldPacket& recvData)
341{
342 ObjectGuid guid;
343
344 recvData.ReadGuidMask(guid, 1, 5, 7, 2, 6, 3, 0, 4);
345 recvData.ReadGuidBytes(guid, 2, 5, 4, 6, 1, 0, 7, 3);
346}
347
348ResurrectResponseRequest ReadResurrectResponseRequest(WorldPacket& recvData)
349{
350 ResurrectResponseRequest request;
351
352 recvData >> request.status;
353
354 request.guid[3] = recvData.ReadBit();
355 request.guid[0] = recvData.ReadBit();
356 request.guid[6] = recvData.ReadBit();
357 request.guid[4] = recvData.ReadBit();
358 request.guid[5] = recvData.ReadBit();
359 request.guid[2] = recvData.ReadBit();
360 request.guid[1] = recvData.ReadBit();
361 request.guid[7] = recvData.ReadBit();
362
363 recvData.ReadByteSeq(request.guid[7]);
364 recvData.ReadByteSeq(request.guid[0]);
365 recvData.ReadByteSeq(request.guid[1]);
366 recvData.ReadByteSeq(request.guid[3]);
367 recvData.ReadByteSeq(request.guid[4]);
368 recvData.ReadByteSeq(request.guid[6]);
369 recvData.ReadByteSeq(request.guid[2]);
370 recvData.ReadByteSeq(request.guid[5]);
371
372 return request;
373}
374
375AreaTriggerRequest ReadAreaTriggerRequest(WorldPacket& recvData)
376{
377 AreaTriggerRequest request;
378 recvData >> request.triggerId;
379 request.unk1 = recvData.ReadBit();
380 request.unk2 = recvData.ReadBit();
381 return request;
382}
383
384UInt32Request ReadRequestAccountDataRequest(WorldPacket& recvData)
385{
386 UInt32Request request;
387 request.value = recvData.ReadBits(3);
388 return request;
389}
390
391ActionButtonRequest ReadSetActionButtonRequest(WorldPacket& recvData)
392{
393 ActionButtonRequest request;
394 recvData >> request.slotId;
395 recvData.ReadGuidMask(request.buttonStream, 7, 0, 5, 2, 1, 6, 3, 4);
396 recvData.ReadGuidBytes(request.buttonStream, 6, 7, 3, 5, 2, 1, 4, 0);
397 return request;
398}
399
400void ReadMoveTimeSkippedRequest(WorldPacket& recvData)
401{
402 ObjectGuid guid;
403 recvData.read_skip<uint32>(); // time skipped
404
405 recvData.ReadGuidMask(guid, 5, 0, 7, 4, 1, 2, 6, 3);
406 recvData.ReadGuidBytes(guid, 7, 2, 0, 6, 1, 5, 3, 4);
407}
408
409GuidRequest ReadInspectRequest(WorldPacket& recvData)
410{
411 GuidRequest request;
412
413 request.guid[0] = recvData.ReadBit();
414 request.guid[3] = recvData.ReadBit();
415 request.guid[7] = recvData.ReadBit();
416 request.guid[2] = recvData.ReadBit();
417 request.guid[5] = recvData.ReadBit();
418 request.guid[1] = recvData.ReadBit();
419 request.guid[4] = recvData.ReadBit();
420 request.guid[6] = recvData.ReadBit();
421
422 recvData.ReadByteSeq(request.guid[3]);
423 recvData.ReadByteSeq(request.guid[5]);
424 recvData.ReadByteSeq(request.guid[2]);
425 recvData.ReadByteSeq(request.guid[4]);
426 recvData.ReadByteSeq(request.guid[1]);
427 recvData.ReadByteSeq(request.guid[6]);
428 recvData.ReadByteSeq(request.guid[0]);
429 recvData.ReadByteSeq(request.guid[7]);
430
431 return request;
432}
433
434GuidRequest ReadInspectHonorStatsRequest(WorldPacket& recvData)
435{
436 GuidRequest request;
437 recvData.ReadGuidMask(request.guid, 4, 3, 6, 1, 0, 2, 5, 7);
438 recvData.ReadGuidBytes(request.guid, 0, 5, 1, 4, 2, 6, 7, 3);
439 return request;
440}
441
442WorldTeleportRequest ReadWorldTeleportRequest(WorldPacket& recvData)
443{
444 WorldTeleportRequest request;
445 recvData >> request.time;
446 recvData >> request.mapId;
447 recvData >> request.positionX;
448 recvData >> request.positionY;
449 recvData >> request.positionZ;
450 recvData >> request.orientation;
451 return request;
452}
453
454ComplainRequest ReadComplainRequest(WorldPacket& recvData)
455{
456 ComplainRequest request = ComplainRequest();
457 recvData >> request.spamType;
458 recvData >> request.spammerGuid;
459
460 switch (request.spamType)
461 {
462 case 0:
463 recvData >> request.unk1;
464 recvData >> request.unk2;
465 recvData >> request.unk3;
466 break;
467 case 1:
468 recvData >> request.unk1;
469 recvData >> request.unk2;
470 recvData >> request.unk3;
471 recvData >> request.unk4;
472 recvData >> request.description;
473 break;
474 }
475
476 return request;
477}
478
479BoolRequest ReadFarSightRequest(WorldPacket& recvData)
480{
481 BoolRequest request;
482 request.value = recvData.ReadBit();
483 return request;
484}
485
486TimeSyncRequest ReadTimeSyncRequest(WorldPacket& recvData)
487{
488 TimeSyncRequest request;
489 recvData >> request.counter >> request.clientTicks;
490 return request;
491}
492
493GuidRequest ReadQueryInspectAchievementsRequest(WorldPacket& recvData)
494{
495 GuidRequest request;
496
497 request.guid[2] = recvData.ReadBit();
498 request.guid[7] = recvData.ReadBit();
499 request.guid[1] = recvData.ReadBit();
500 request.guid[5] = recvData.ReadBit();
501 request.guid[4] = recvData.ReadBit();
502 request.guid[0] = recvData.ReadBit();
503 request.guid[3] = recvData.ReadBit();
504 request.guid[6] = recvData.ReadBit();
505
506 recvData.ReadByteSeq(request.guid[7]);
507 recvData.ReadByteSeq(request.guid[2]);
508 recvData.ReadByteSeq(request.guid[0]);
509 recvData.ReadByteSeq(request.guid[4]);
510 recvData.ReadByteSeq(request.guid[1]);
511 recvData.ReadByteSeq(request.guid[5]);
512 recvData.ReadByteSeq(request.guid[6]);
513 recvData.ReadByteSeq(request.guid[3]);
514
515 return request;
516}
517
518GuidRequest ReadAreaSpiritHealerQueryRequest(WorldPacket& recvData)
519{
520 GuidRequest request;
521 recvData.ReadGuidMask(request.guid, 5, 6, 0, 4, 1, 2, 7, 3);
522 recvData.ReadGuidBytes(request.guid, 0, 2, 6, 7, 1, 5, 3, 4);
523 return request;
524}
525
526GuidRequest ReadAreaSpiritHealerQueueRequest(WorldPacket& recvData)
527{
528 GuidRequest request;
529
530 request.guid[5] = recvData.ReadBit();
531 request.guid[4] = recvData.ReadBit();
532 request.guid[0] = recvData.ReadBit();
533 request.guid[2] = recvData.ReadBit();
534 request.guid[7] = recvData.ReadBit();
535 request.guid[1] = recvData.ReadBit();
536 request.guid[6] = recvData.ReadBit();
537 request.guid[3] = recvData.ReadBit();
538
539 recvData.ReadByteSeq(request.guid[1]);
540 recvData.ReadByteSeq(request.guid[7]);
541 recvData.ReadByteSeq(request.guid[6]);
542 recvData.ReadByteSeq(request.guid[2]);
543 recvData.ReadByteSeq(request.guid[4]);
544 recvData.ReadByteSeq(request.guid[3]);
545 recvData.ReadByteSeq(request.guid[0]);
546 recvData.ReadByteSeq(request.guid[5]);
547
548 return request;
549}
550
551BoolRequest ReadInstanceLockResponseRequest(WorldPacket& recvPacket)
552{
553 BoolRequest request;
554 request.value = recvPacket.ReadBit();
555 return request;
556}
557
558UpdateMissileTrajectoryRequest ReadUpdateMissileTrajectoryRequest(WorldPacket& recvPacket)
559{
560 UpdateMissileTrajectoryRequest request;
561 recvPacket >> request.guid >> request.spellId >> request.elevation >> request.speed;
562 recvPacket >> request.curX >> request.curY >> request.curZ;
563 recvPacket >> request.targetX >> request.targetY >> request.targetZ;
564 recvPacket >> request.moveStop;
565 return request;
566}
567
568GuidRequest ReadObjectUpdateFailedRequest(WorldPacket& recvPacket)
569{
570 GuidRequest request;
571
572 request.guid[3] = recvPacket.ReadBit();
573 request.guid[5] = recvPacket.ReadBit();
574 request.guid[6] = recvPacket.ReadBit();
575 request.guid[0] = recvPacket.ReadBit();
576 request.guid[1] = recvPacket.ReadBit();
577 request.guid[2] = recvPacket.ReadBit();
578 request.guid[7] = recvPacket.ReadBit();
579 request.guid[4] = recvPacket.ReadBit();
580
581 recvPacket.ReadByteSeq(request.guid[0]);
582 recvPacket.ReadByteSeq(request.guid[6]);
583 recvPacket.ReadByteSeq(request.guid[5]);
584 recvPacket.ReadByteSeq(request.guid[7]);
585 recvPacket.ReadByteSeq(request.guid[2]);
586 recvPacket.ReadByteSeq(request.guid[1]);
587 recvPacket.ReadByteSeq(request.guid[3]);
588 recvPacket.ReadByteSeq(request.guid[4]);
589
590 return request;
591}
592
593DiscardedTimeSyncAcksRequest ReadDiscardedTimeSyncAcksRequest(WorldPacket& recvData)
594{
595 DiscardedTimeSyncAcksRequest request;
596 request.hasCounter = false;
597 request.counter = 0;
598
599 bool hasInfo = !recvData.ReadBit();
600 if (hasInfo)
601 {
602 request.hasCounter = true;
603 recvData >> request.counter;
604 }
605
606 return request;
607}
608
609SceneCompletedRequest ReadSceneCompletedRequest(WorldPacket& recvPacket)
610{
611 SceneCompletedRequest request;
612 request.unk = 0;
613 request.hasData = recvPacket.ReadBit();
614 if (request.hasData)
615 request.unk = recvPacket.read<uint32>();
616 return request;
617}
618}
619
621{
622 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_REPOP_REQUEST Message");
623
624 ReadRepopRequest(recvData);
625
626 if (GetPlayer()->IsAlive() || GetPlayer()->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
627 return;
628
629 if (GetPlayer()->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
630 return; // silently return, client should display the error by itself
631
632 // the world update order is sessions, players, creatures
633 // the netcode runs in parallel with all of these
634 // creatures can kill players
635 // so if the server is lagging enough the player can
636 // release spirit after he's killed but before he is updated
637 if (GetPlayer()->getDeathState() == DeathState::JUST_DIED)
638 {
639 SF_LOG_DEBUG("network", "HandleRepopRequestOpcode: got request after player %s(%d) was killed and before he was updated",
640 GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
642 }
643
644 //this is spirit release confirm?
648}
649
651{
652 SF_LOG_DEBUG("network", "WORLD: CMSG_GOSSIP_SELECT_OPTION");
653
654 GossipSelectOptionRequest request = ReadGossipSelectOptionRequest(recvData, _player);
655
656 Creature* unit = NULL;
657 GameObject* go = NULL;
658 if (IS_CRE_OR_VEH_GUID(request.guid))
659 {
661 if (!unit)
662 {
663 SF_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(request.guid)));
664 return;
665 }
666 }
667 else if (IS_GAMEOBJECT_GUID(request.guid))
668 {
669 go = _player->GetMap()->GetGameObject(request.guid);
670 if (!go)
671 {
672 SF_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - GameObject (GUID: %u) not found.", uint32(GUID_LOPART(request.guid)));
673 return;
674 }
675 }
676 else
677 {
678 SF_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for highguid %u. lowpart %u.", uint32(GUID_HIPART(request.guid)), uint32(GUID_LOPART(request.guid)));
679 return;
680 }
681
682 // remove fake death
683 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
685
686 if ((unit && unit->GetCreatureTemplate()->ScriptID != unit->LastUsedScriptID) || (go && go->GetGOInfo()->ScriptId != go->LastUsedScriptID))
687 {
688 SF_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id");
689 if (unit)
691 if (go)
693 _player->PlayerTalkClass->SendCloseGossip();
694 return;
695 }
696 if (!request.code.empty())
697 {
698 if (unit)
699 {
700 unit->AI()->sGossipSelectCode(_player, request.menuId, request.gossipListId, request.code.c_str());
701 if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(request.gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(request.gossipListId), request.code.c_str()))
702 _player->OnGossipSelect(unit, request.gossipListId, request.menuId);
703 }
704 else
705 {
706 go->AI()->GossipSelectCode(_player, request.menuId, request.gossipListId, request.code.c_str());
707 sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(request.gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(request.gossipListId), request.code.c_str());
708 }
709 }
710 else
711 {
712 if (unit)
713 {
714 unit->AI()->sGossipSelect(_player, request.menuId, request.gossipListId);
715 if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(request.gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(request.gossipListId)))
716 _player->OnGossipSelect(unit, request.gossipListId, request.menuId);
717 }
718 else
719 {
720 go->AI()->GossipSelect(_player, request.menuId, request.gossipListId);
721 if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(request.gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(request.gossipListId)))
722 _player->OnGossipSelect(go, request.gossipListId, request.menuId);
723 }
724 }
725}
726
728{
729 //CMSG_WHO
730 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
731
732 time_t now = time(NULL);
733 if (now - timeLastWhoCommand < 5)
734 return;
735 else timeLastWhoCommand = now;
736
737 uint32 levelMin, levelMax, raceMask, classMask, zonesCount, wordCount;
738 uint32 zoneIds[10]; // 10 is client limit
739 bool requestServerInfo, showEnemies, showArenaPlayers, exactName;
740 uint8 playerLen, guildLen, realmNameLen, guildRealmNameLen;
741 std::string playerName, guildName, realmName, guildRealmName;
742
743 recvData >> classMask; // race mask
744 recvData >> raceMask; // minimal player level, default 100 (MAX_LEVEL)
745 recvData >> levelMax; // maximal player level, default 0
746 recvData >> levelMin; // class mask
747
748 showEnemies = recvData.ReadBit();
749 exactName = recvData.ReadBit();
750 requestServerInfo = recvData.ReadBit();
751 guildRealmNameLen = recvData.ReadBits(9);
752 showArenaPlayers = recvData.ReadBit();
753 playerLen = recvData.ReadBits(6);
754
755 zonesCount = recvData.ReadBits(4); // zones count, client limit = 10 (2.0.10)
756 if (zonesCount > 10) // can't be received from real client or broken packet
757 return;
758
759 realmNameLen = recvData.ReadBits(9);
760 guildLen = recvData.ReadBits(7);
761
762 wordCount = recvData.ReadBits(3);
763 if (wordCount > 4)
764 return; // can't be received from real client or broken packet
765
766 uint8* wordLens = new uint8[wordCount];
767 std::string* words = new std::string[wordCount];
768
769 for (uint8 i = 0; i < wordCount; i++)
770 wordLens[i] = recvData.ReadBits(7);
771
772 std::wstring wWords[4];
773 for (uint32 i = 0; i < wordCount; ++i)
774 {
775 std::string temp;
776 recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
777
778 if (!Utf8toWStr(temp, wWords[i]))
779 continue;
780
781 wstrToLower(wWords[i]);
782
783 SF_LOG_DEBUG("network", "String %u: %s", i, temp.c_str());
784 }
785
786 guildRealmName = recvData.ReadString(guildRealmNameLen);
787
788 for (uint32 i = 0; i < zonesCount; ++i)
789 {
790 recvData >> zoneIds[i]; // zone id, 0 if zone is unknown...
791 SF_LOG_DEBUG("network", "Zone %u: %u", i, zoneIds[i]);
792 }
793
794 // NYI
795 playerName = recvData.ReadString(playerLen);
796 realmName = recvData.ReadString(realmNameLen);
797 guildName = recvData.ReadString(guildLen);
798
799 uint32 virtualRealmAddress = 0;
800 int32 faction = 0, locale = 0;
801
802 if (requestServerInfo)
803 {
804 recvData >> locale;
805 recvData >> virtualRealmAddress;
806 recvData >> faction;
807 }
808
809 SF_LOG_DEBUG("network", "Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", levelMin, levelMax, playerName.c_str(), guildName.c_str(), raceMask, classMask, zonesCount, wordCount);
810
811 std::wstring wPlayerName, wGuildName;
812 if (!(Utf8toWStr(playerName, wPlayerName) && Utf8toWStr(guildName, wGuildName)))
813 return;
814
815 wstrToLower(wPlayerName);
816 wstrToLower(wGuildName);
817
818 // SMSG_WHO
819 // client send in case not set max level value 100 but Skyfire supports 255 max level,
820 // update it to show GMs with characters after 100 level
821 if (levelMax >= MAX_LEVEL)
822 levelMax = STRONG_MAX_LEVEL;
823
824 uint32 team = _player->GetTeam();
825
826 //bool allowTwoSideWhoList = sWorld->GetBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
827 uint32 gmLevelInWhoList = sWorld->getIntConfig(WorldIntConfigs::CONFIG_GM_LEVEL_IN_WHO_LIST);
828 uint8 displaycount = 0, matchcount = 0;
829
830 ByteBuffer bytesData;
831 WorldPacket data(SMSG_WHO);
832
833 size_t pos = data.bitwpos();
834 data.WriteBits(displaycount, 6);
835
837 HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
838 for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
839 {
840 Player* target = itr->second;
841 // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
843 continue;
844
845 // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
847 continue;
848
849 // do not process players which are not in world
850 if (!target->IsInWorld())
851 continue;
852
853 // check if target is globally visible for player
854 if (!target->IsVisibleGloballyFor(_player))
855 continue;
856
857 // check if target's level is in level range
858 uint8 level = target->getLevel();
859 if (level < levelMin || level > levelMax)
860 continue;
861
862 // check if class matches classmask
863 uint8 class_ = target->getClass();
864 if (!(classMask & (1 << class_)))
865 continue;
866
867 // check if race matches racemask
868 uint32 race = target->getRace();
869 if (!(raceMask & (1 << race)))
870 continue;
871
872 uint32 zoneId = target->GetZoneId();
873 uint8 gender = target->getGender();
874
875 bool z_show = true;
876 for (uint32 i = 0; i < zonesCount; ++i)
877 {
878 if (zoneIds[i] == zoneId)
879 {
880 z_show = true;
881 break;
882 }
883
884 z_show = false;
885 }
886 if (!z_show)
887 continue;
888
889 std::string pname = target->GetName();
890 std::wstring wpname;
891 if (!Utf8toWStr(pname, wpname))
892 continue;
893 wstrToLower(wpname);
894
895 if (!(wPlayerName.empty() || wpname.find(wPlayerName) != std::wstring::npos))
896 continue;
897
898 std::string gname = sGuildMgr->GetGuildNameById(target->GetGuildId());
899 std::wstring wgname;
900 if (!Utf8toWStr(gname, wgname))
901 continue;
902 wstrToLower(wgname);
903
904 if (!(wGuildName.empty() || wgname.find(wGuildName) != std::wstring::npos))
905 continue;
906
907 std::string aname;
908 if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId))
909 aname = areaEntry->m_AreaName[GetSessionDbcLocale()];
910
911 bool s_show = true;
912 for (uint32 i = 0; i < wordCount; ++i)
913 {
914 if (!wWords[i].empty())
915 {
916 if (wgname.find(wWords[i]) != std::wstring::npos ||
917 wpname.find(wWords[i]) != std::wstring::npos ||
918 Utf8FitTo(aname, wWords[i]))
919 {
920 s_show = true;
921 break;
922 }
923 s_show = false;
924 }
925 }
926 if (!s_show)
927 continue;
928
929 // 49 is maximum player count sent to client - can be overridden
930 // through config, but is unstable
931 if ((matchcount++) >= sWorld->getIntConfig(WorldIntConfigs::CONFIG_MAX_WHO))
932 continue;
933
934 ObjectGuid playerGuid = target->GetGUID();
935 ObjectGuid accountId = target->GetSession()->GetAccountId();
936 ObjectGuid guildGuid = target->GetGuild() ? target->GetGuild()->GetGUID() : 0;
937
938 data.WriteBit(accountId[2]);
939 data.WriteBit(playerGuid[2]);
940 data.WriteBit(accountId[7]);
941 data.WriteBit(guildGuid[5]);
942 data.WriteBits(gname.size(), 7);
943 data.WriteBit(accountId[1]);
944 data.WriteBit(accountId[5]);
945 data.WriteBit(guildGuid[7]);
946 data.WriteBit(playerGuid[5]);
947 data.WriteBit(false);
948 data.WriteBit(guildGuid[1]);
949 data.WriteBit(playerGuid[6]);
950 data.WriteBit(guildGuid[2]);
951 data.WriteBit(playerGuid[4]);
952 data.WriteBit(guildGuid[0]);
953 data.WriteBit(guildGuid[3]);
954 data.WriteBit(accountId[6]);
955 data.WriteBit(false);
956 data.WriteBit(playerGuid[1]);
957 data.WriteBit(guildGuid[4]);
958 data.WriteBit(accountId[0]);
959
960 if (DeclinedName const* names = itr->second->GetDeclinedNames())
961 {
962 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
963 data.WriteBits(names->name[i].size(), 14);
964 }
965 else
966 {
967 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
968 data.WriteBits(0, 7);
969 }
970
971 data.WriteBit(playerGuid[3]);
972 data.WriteBit(guildGuid[6]);
973 data.WriteBit(playerGuid[0]);
974 data.WriteBit(accountId[4]);
975 data.WriteBit(accountId[3]);
976 data.WriteBit(playerGuid[7]);
977 data.WriteBits(pname.size(), 6);
978
979 bytesData.WriteByteSeq(playerGuid[1]);
980 bytesData << uint32(target->GetSession()->GetVirtualRealmID());
981 bytesData.WriteByteSeq(playerGuid[7]);
982 bytesData << uint32(realmID); // NYI. guild creation virtual realm id.
983 bytesData.WriteByteSeq(playerGuid[4]);
984 bytesData.WriteString(pname);
985 bytesData.WriteByteSeq(guildGuid[1]);
986 bytesData.WriteByteSeq(playerGuid[0]);
987 bytesData.WriteByteSeq(guildGuid[2]);
988 bytesData.WriteByteSeq(guildGuid[0]);
989 bytesData.WriteByteSeq(guildGuid[4]);
990 bytesData.WriteByteSeq(playerGuid[3]);
991 bytesData.WriteByteSeq(guildGuid[6]);
992 bytesData << uint32(target->GetSession()->GetAccountId());
993 bytesData.WriteString(gname);
994 bytesData.WriteByteSeq(guildGuid[3]);
995 bytesData.WriteByteSeq(accountId[4]);
996 bytesData << uint8(class_);
997 bytesData.WriteByteSeq(accountId[7]);
998 bytesData.WriteByteSeq(playerGuid[6]);
999 bytesData.WriteByteSeq(playerGuid[2]);
1000
1001 if (DeclinedName const* names = itr->second->GetDeclinedNames())
1002 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1003 bytesData.WriteString(names->name[i]);
1004
1005 bytesData.WriteByteSeq(accountId[2]);
1006 bytesData.WriteByteSeq(accountId[3]);
1007 bytesData << uint8(race);
1008 bytesData.WriteByteSeq(guildGuid[7]);
1009 bytesData.WriteByteSeq(accountId[1]);
1010 bytesData.WriteByteSeq(accountId[5]);
1011 bytesData.WriteByteSeq(accountId[6]);
1012 bytesData.WriteByteSeq(playerGuid[5]);
1013 bytesData.WriteByteSeq(accountId[0]);
1014 bytesData << uint8(gender);
1015 bytesData.WriteByteSeq(guildGuid[5]);
1016 bytesData << uint8(level);
1017 bytesData << int32(zoneId);
1018
1019 ++displaycount;
1020 }
1021
1022 data.FlushBits();
1023 data.PutBits(pos, displaycount, 6);
1024 data.append(bytesData);
1025
1026 SendPacket(&data);
1027
1028 delete[] words;
1029 delete[] wordLens;
1030
1031 SF_LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
1032}
1033
1035{
1036 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - %u", uint8(GetSecurity()));
1037
1038 if (uint64 lguid = GetPlayer()->GetLootGUID())
1039 DoLootRelease(lguid);
1040
1043
1046
1047 uint32 reason = 0;
1048 if (GetPlayer()->IsInCombat() && !canLogoutInCombat)
1049 reason = 1;
1050 else if (GetPlayer()->IsFalling())
1051 reason = 3; // is jumping or falling
1052 else if (GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
1053 reason = 2; // FIXME - Need the correct value
1054
1055 WorldPacket data(SMSG_LOGOUT_RESPONSE, 1 + 4);
1056 data << uint32(reason);
1057 data.WriteBit(instantLogout);
1058 data.FlushBits();
1059 SendPacket(&data);
1060
1061 if (reason)
1062 {
1063 LogoutRequest(0);
1064 return;
1065 }
1066
1067 // instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
1068 if (instantLogout)
1069 {
1070 LogoutPlayer(true);
1071 return;
1072 }
1073
1074 // not set flags if player can't free move to prevent lost state at logout cancel
1075 if (GetPlayer()->CanFreeMove())
1076 {
1078 GetPlayer()->SetRooted(true);
1080 }
1081
1082 LogoutRequest(time(NULL));
1083}
1084
1086{
1087 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_PLAYER_LOGOUT Message");
1088}
1089
1091{
1092 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_LOGOUT_CANCEL Message");
1093
1094 // Player have already logged out serverside, too late to cancel
1095 if (!GetPlayer())
1096 return;
1097
1098 LogoutRequest(0);
1099
1101 SendPacket(&data);
1102
1103 // not remove flags if can't free move - its not set in Logout request code.
1104 if (GetPlayer()->CanFreeMove())
1105 {
1107 GetPlayer()->SetRooted(false);
1108
1111
1114 }
1115
1116 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_LOGOUT_CANCEL_ACK Message");
1117}
1118
1120{
1121 SetPvPRequest request = ReadSetPvPRequest(recvData);
1122 if (request.hasStatus)
1123 {
1126 }
1127}
1129{
1132
1134 {
1135 if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.EndTimer)
1136 GetPlayer()->UpdatePvP(true, true);
1137 }
1138 else
1139 {
1140 if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP())
1141 GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off
1142 }
1143
1144 //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
1145 // pvp->HandlePlayerActivityChanged(_player);
1146}
1147
1149{
1150 UInt32Request request = ReadUInt32Request(recvData);
1151
1152 SF_LOG_DEBUG("network", "WORLD: Recvd ZONE_UPDATE: %u", request.value);
1153
1154 // use server size data
1155 uint32 newzone, newarea;
1156 GetPlayer()->GetZoneAndAreaId(newzone, newarea);
1157 GetPlayer()->UpdateZone(newzone, newarea);
1158 //GetPlayer()->SendInitWorldStates(true, newZone);
1159}
1160
1162{
1163 if (GetPlayer()->IsAlive() || !GetPlayer()->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
1164 return;
1165
1167}
1168
1170{
1171 uint32 zoneId = _player->GetZoneId();
1172 uint32 team = _player->GetTeam();
1173
1174 std::vector<uint32> GraveyardIds;
1175
1176 GraveYardContainer::const_iterator it;
1177 std::pair<GraveYardContainer::const_iterator, GraveYardContainer::const_iterator> range;
1178 range = sObjectMgr->GraveYardStore.equal_range(zoneId);
1179
1180 for (it = range.first; it != range.second && GraveyardIds.size() < 16; ++it) // client max
1181 {
1182 if (it->second.team == 0 || it->second.team == team)
1183 GraveyardIds.push_back(it->first);
1184 }
1185
1186 if (GraveyardIds.empty())
1187 {
1188 SF_LOG_DEBUG("network", "No graveyards found for zone %u for %u (team %u) in CMSG_REQUEST_CEMETERY_LIST", zoneId, m_GUIDLow, team);
1189 return;
1190 }
1191
1192 bool IsGossipTriggered = false;
1193 WorldPacket data(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, 4 + 4 * GraveyardIds.size());
1194
1195 data.WriteBits(GraveyardIds.size(), 22);
1196 data << IsGossipTriggered;
1197
1198 for (uint32 i = 0; i < GraveyardIds.size(); ++i)
1199 data << uint32(GraveyardIds[i]);
1200
1201 SendPacket(&data);
1202}
1203
1205{
1206 GuidRequest request = ReadSetSelectionRequest(recvData);
1207 _player->SetSelection(request.guid);
1208}
1209
1211{
1212 // SF_LOG_DEBUG("network", "WORLD: Received CMSG_STAND_STATE_CHANGE"); -- too many spam in log at lags/debug stop
1213 UInt32Request request = ReadUInt32Request(recvData);
1214
1215 _player->SetStandState(request.value);
1216}
1217
1219{
1220 ReadContactListRequest(recvData);
1221 SF_LOG_DEBUG("network", "WORLD: Received CMSG_CONTACT_LIST");
1222 _player->GetSocial()->SendSocialList(_player);
1223}
1224
1226{
1227 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ADD_FRIEND");
1228
1229 AddFriendRequest request = ReadAddFriendRequest(recvData);
1230
1231 request.name = request.name.substr(0, request.name.find("-"));
1232 if (!normalizePlayerName(request.name))
1233 return;
1234
1235 SF_LOG_DEBUG("network", "WORLD: %s asked to add friend : '%s'",
1236 GetPlayer()->GetName().c_str(), request.name.c_str());
1237
1239
1240 stmt->setString(0, request.name);
1241
1242 _addFriendCallback.SetParam(request.note);
1243 _addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
1244}
1245
1246void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const& friendNote)
1247{
1248 if (!GetPlayer())
1249 return;
1250
1251 uint64 friendGuid;
1252 uint32 friendAccountId;
1253 uint32 team;
1254 FriendsResult friendResult;
1255
1256 friendResult = FRIEND_NOT_FOUND;
1257 friendGuid = 0;
1258
1259 if (result)
1260 {
1261 Field* fields = result->Fetch();
1262
1263 friendGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
1264 team = Player::TeamForRace(fields[1].GetUInt8());
1265 friendAccountId = fields[2].GetUInt32();
1266
1268 {
1269 if (friendGuid)
1270 {
1271 if (friendGuid == GetPlayer()->GetGUID())
1272 friendResult = FRIEND_SELF;
1273 else if (GetPlayer()->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND))
1274 friendResult = FRIEND_ENEMY;
1275 else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
1276 friendResult = FRIEND_ALREADY;
1277 else
1278 {
1279 Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
1280 if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
1281 friendResult = FRIEND_ADDED_ONLINE;
1282 else
1283 friendResult = FRIEND_ADDED_OFFLINE;
1284 if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
1285 {
1286 friendResult = FRIEND_LIST_FULL;
1287 SF_LOG_DEBUG("network", "WORLD: %s's friend list is full.", GetPlayer()->GetName().c_str());
1288 }
1289 }
1290 GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
1291 }
1292 }
1293 }
1294
1295 sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
1296
1297 SF_LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
1298}
1299
1301{
1302 SF_LOG_DEBUG("network", "WORLD: Received CMSG_DEL_FRIEND");
1303
1304 UInt64Request request = ReadUInt64Request(recvData);
1305
1306 _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(request.value), false);
1307
1308 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(request.value), false);
1309
1310 SF_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
1311}
1312
1314{
1315 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ADD_IGNORE");
1316
1317 StringRequest request = ReadAddIgnoreRequest(recvData);
1318
1319 if (!normalizePlayerName(request.value))
1320 return;
1321
1322 SF_LOG_DEBUG("network", "WORLD: %s asked to Ignore: '%s'",
1323 GetPlayer()->GetName().c_str(), request.value.c_str());
1324
1325 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
1326
1327 stmt->setString(0, request.value);
1328
1329 _addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
1330}
1331
1333{
1334 if (!GetPlayer())
1335 return;
1336
1337 uint64 IgnoreGuid;
1338 FriendsResult ignoreResult;
1339
1340 ignoreResult = FRIEND_IGNORE_NOT_FOUND;
1341 IgnoreGuid = 0;
1342
1343 if (result)
1344 {
1345 IgnoreGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
1346
1347 if (IgnoreGuid)
1348 {
1349 if (IgnoreGuid == GetPlayer()->GetGUID()) //not add yourself
1350 ignoreResult = FRIEND_IGNORE_SELF;
1351 else if (GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)))
1352 ignoreResult = FRIEND_IGNORE_ALREADY;
1353 else
1354 {
1355 ignoreResult = FRIEND_IGNORE_ADDED;
1356
1357 // ignore list full
1358 if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
1359 ignoreResult = FRIEND_IGNORE_FULL;
1360 }
1361 }
1362 }
1363
1364 sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
1365
1366 SF_LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
1367}
1368
1370{
1371 SF_LOG_DEBUG("network", "WORLD: Received CMSG_DEL_IGNORE");
1372
1373 UInt64Request request = ReadUInt64Request(recvData);
1374
1375 _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(request.value), true);
1376
1377 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(request.value), false);
1378
1379 SF_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
1380}
1381
1383{
1384 SF_LOG_DEBUG("network", "CMSG_SET_CONTACT_NOTES");
1385 ContactNotesRequest request = ReadSetContactNotesRequest(recvData);
1386 _player->GetSocial()->SetFriendNote(GUID_LOPART(request.guid), request.note);
1387}
1388
1390{
1391 BugReportRequest request = ReadBugReportRequest(recvData);
1392
1393 if (request.suggestion == 0)
1394 SF_LOG_DEBUG("network", "WORLD: Received CMSG_BUG [Bug Report]");
1395 else
1396 SF_LOG_DEBUG("network", "WORLD: Received CMSG_BUG [Suggestion]");
1397
1398 SF_LOG_DEBUG("network", "%s", request.type.c_str());
1399 SF_LOG_DEBUG("network", "%s", request.content.c_str());
1400
1401 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_BUG_REPORT);
1402
1403 stmt->setString(0, request.type);
1404 stmt->setString(1, request.content);
1405
1406 CharacterDatabase.Execute(stmt);
1407}
1408
1410{
1411 SF_LOG_DEBUG("network", "WORLD: Received CMSG_RECLAIM_CORPSE");
1412
1413 ReadReclaimCorpseRequest(recvData);
1414
1415 if (GetPlayer()->IsAlive())
1416 return;
1417
1418 // do not allow corpse reclaim in arena
1419 if (GetPlayer()->InArena())
1420 return;
1421
1422 // body not released yet
1424 return;
1425
1426 Corpse* corpse = GetPlayer()->GetCorpse();
1427
1428 if (!corpse)
1429 return;
1430
1431 // prevent resurrect before 30-sec delay after body release not finished
1432 if (time_t(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType() == CorpseType::CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL)))
1433 return;
1434
1435 if (!corpse->IsWithinDistInMap(GetPlayer(), CORPSE_RECLAIM_RADIUS, true))
1436 return;
1437
1438 // resurrect
1439 GetPlayer()->ResurrectPlayer(GetPlayer()->InBattleground() ? 1.0f : 0.5f);
1440
1441 // spawn bones
1443}
1444
1446{
1447 SF_LOG_DEBUG("network", "WORLD: Received CMSG_RESURRECT_RESPONSE");
1448
1449 ResurrectResponseRequest request = ReadResurrectResponseRequest(recvData);
1450
1451 if (GetPlayer()->IsAlive())
1452 return;
1453
1454 if (request.status == 1)
1455 {
1456 GetPlayer()->ClearResurrectRequestData(); // reject
1457 return;
1458 }
1459
1460 if (!GetPlayer()->IsRessurectRequestedBy(request.guid))
1461 return;
1462
1464}
1465
1467{
1468 AreaTriggerRequest request = ReadAreaTriggerRequest(recvData);
1469
1470 SF_LOG_DEBUG("network", "CMSG_AREATRIGGER. Trigger ID: %u, Unk1: %u, Unk2: %u", request.triggerId, request.unk1, request.unk2);
1471
1472 Player* player = GetPlayer();
1473 if (player->IsInFlight())
1474 {
1475 SF_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) in flight, ignore Area Trigger ID:%u, unk1: %u, unk2: %u",
1476 player->GetName().c_str(), player->GetGUIDLow(), request.triggerId, request.unk1, request.unk2);
1477 return;
1478 }
1479
1480 AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(request.triggerId);
1481 if (!atEntry)
1482 {
1483 SF_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) send unknown (by DBC) Area Trigger ID:%u, unk1: %u, unk2: %u",
1484 player->GetName().c_str(), player->GetGUIDLow(), request.triggerId, request.unk1, request.unk2);
1485 return;
1486 }
1487
1488 if (player->GetMapId() != atEntry->mapid)
1489 {
1490 SF_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (trigger map: %u player map: %u), ignore Area Trigger ID: %u, unk1: %u, unk2: %u",
1491 player->GetName().c_str(), atEntry->mapid, player->GetMapId(), player->GetGUIDLow(), request.triggerId, request.unk1, request.unk2);
1492 return;
1493 }
1494
1495 // delta is safe radius
1496 const float delta = 5.0f;
1497
1498 if (atEntry->radius > 0)
1499 {
1500 // if we have radius check it
1501 float dist = player->GetDistance(atEntry->x, atEntry->y, atEntry->z);
1502 if (dist > atEntry->radius + delta)
1503 {
1504 SF_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (radius: %f distance: %f), ignore Area Trigger ID: %u, unk1: %u, unk2: %u",
1505 player->GetName().c_str(), player->GetGUIDLow(), atEntry->radius, dist, request.triggerId, request.unk1, request.unk2);
1506 return;
1507 }
1508 }
1509 else
1510 {
1511 // we have only extent
1512
1513 // rotate the players position instead of rotating the whole cube, that way we can make a simplified
1514 // is-in-cube check and we have to calculate only one point instead of 4
1515
1516 // 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
1517 double rotation = 2 * M_PI - atEntry->box_orientation;
1518 double sinVal = std::sin(rotation);
1519 double cosVal = std::cos(rotation);
1520
1521 float playerBoxDistX = player->GetPositionX() - atEntry->x;
1522 float playerBoxDistY = player->GetPositionY() - atEntry->y;
1523
1524 float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY * sinVal);
1525 float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX * sinVal);
1526
1527 // box edges are parallel to coordiante axis, so we can treat every dimension independently :D
1528 float dz = player->GetPositionZ() - atEntry->z;
1529 float dx = rotPlayerX - atEntry->x;
1530 float dy = rotPlayerY - atEntry->y;
1531 if ((fabs(dx) > atEntry->box_x / 2 + delta) ||
1532 (fabs(dy) > atEntry->box_y / 2 + delta) ||
1533 (fabs(dz) > atEntry->box_z / 2 + delta))
1534 {
1535 SF_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotatedPlayerX: %f rotatedPlayerY: %f dZ:%f), ignore Area Trigger ID: %u, unk1: %u, unk2: %u",
1536 player->GetName().c_str(), player->GetGUIDLow(), atEntry->box_x / 2, atEntry->box_y / 2, atEntry->box_z / 2, rotPlayerX, rotPlayerY, dz, request.triggerId, request.unk1, request.unk2);
1537 return;
1538 }
1539 }
1540
1541 if (player->isDebugAreaTriggers)
1543
1544 if (sScriptMgr->OnAreaTrigger(player, atEntry))
1545 return;
1546
1547 if (player->IsAlive())
1548 if (uint32 questId = sObjectMgr->GetQuestForAreaTrigger(request.triggerId))
1549 if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
1550 player->AreaExploredOrEventHappens(questId);
1551
1552 if (sObjectMgr->IsTavernAreaTrigger(request.triggerId))
1553 {
1554 TavernRestArea const* restArea = sObjectMgr->GetTavernRestArea(request.triggerId);
1555
1556 // The first bit is set in known 5.4.8 captures; the second bit carries the
1557 // enter/leave state for the trigger.
1558 if (!request.unk2)
1559 {
1560 if (player->GetRestType() == REST_TYPE_IN_TAVERN)
1561 {
1563 player->SetRestType(REST_TYPE_NO);
1564 }
1565
1566 return;
1567 }
1568
1569 if (restArea && !sObjectMgr->IsInTavernRestArea(*restArea, player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()))
1570 return;
1571
1572 // set resting flag we are in the inn
1574
1575 if (restArea)
1576 player->InnEnter(time(NULL), restArea->MapId, restArea->X, restArea->Y, restArea->Z,
1577 restArea->Radius, restArea->BoxX, restArea->BoxY, restArea->BoxZ, restArea->BoxOrientation);
1578 else
1579 player->InnEnter(time(NULL), atEntry->mapid, atEntry->x, atEntry->y, atEntry->z);
1580
1582
1583 if (sWorld->IsFFAPvPRealm())
1585
1586 return;
1587 }
1588
1589 if (Battleground* bg = player->GetBattleground())
1590 if (bg->GetStatus() == STATUS_IN_PROGRESS)
1591 {
1592 bg->HandleAreaTrigger(player, request.triggerId);
1593 return;
1594 }
1595
1596 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
1597 if (pvp->HandleAreaTrigger(_player, request.triggerId))
1598 return;
1599
1600 AreaTriggerStruct const* at = sObjectMgr->GetAreaTrigger(request.triggerId);
1601 if (!at)
1602 return;
1603
1604 bool teleported = false;
1605 if (player->GetMapId() != at->target_mapId)
1606 {
1607 if (!sMapMgr->CanPlayerEnter(at->target_mapId, player, false))
1608 return;
1609
1610 if (Group* group = player->GetGroup())
1611 if (group->isLFGGroup() && player->GetMap()->IsInstance())
1612 teleported = player->TeleportToBGEntryPoint();
1613 }
1614
1615 if (!teleported)
1617}
1618
1620{
1621 SF_LOG_DEBUG("network", "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
1622
1623 uint32 timestamp = 0, decompressedSize = 0, compCount = 0;
1624 uint8 type = 0;
1625 recvData >> decompressedSize >> timestamp >> compCount;
1626
1627 if (decompressedSize == 0) // erase
1628 {
1629 SetAccountData(AccountDataType(type), 0, "");
1630
1632 type = recvData.ReadBits(3);
1633 data << uint32(type);
1634 data << uint32(0);
1635 SendPacket(&data);
1636
1637 return;
1638 }
1639
1640 if (decompressedSize > 0xFFFF)
1641 {
1642 recvData.rfinish(); // unneeded warning spam in this case
1643 SF_LOG_DEBUG("network", "UAD: Account data packet too big, size %u", decompressedSize);
1644 return;
1645 }
1646
1647 ByteBuffer dest;
1648 dest.resize(decompressedSize);
1649
1650 uLongf realSize = decompressedSize;
1651 if (uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recvData.contents() + recvData.rpos()), compCount) != Z_OK)
1652 {
1653 recvData.rfinish(); // unneeded warning spam in this case
1654 SF_LOG_DEBUG("network", "UAD: Failed to decompress account data");
1655 return;
1656 }
1657
1658 recvData.rpos(recvData.rpos() + compCount);
1659
1660 type = recvData.ReadBits(3);
1661
1662 AccountDataType UADType = AccountDataType(type);
1664 {
1665 SF_LOG_DEBUG("network", "UAD: Unknown account data type: %u", type);
1666 return;
1667 }
1668
1669 std::string adata;
1670 dest >> adata;
1671
1672 SetAccountData(UADType, timestamp, adata);
1673
1675 data << uint32(UADType);
1676 data << uint32(0);
1677 SendPacket(&data);
1678}
1679
1681{
1682 SF_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
1683
1684 UInt32Request request = ReadRequestAccountDataRequest(recvData);
1685
1686 SF_LOG_DEBUG("network", "RAD: type %u", request.value);
1687
1688 AccountDataType RADType = AccountDataType(request.value);
1690 {
1691 SF_LOG_DEBUG("network", "RAD: Unknown account data type: %u", request.value);
1692 return;
1693 }
1694
1695 AccountData* adata = GetAccountData(RADType);
1696
1697 uint32 size = adata->Data.size();
1698
1699 uLongf destSize = compressBound(size);
1700
1701 ByteBuffer dest;
1702 dest.resize(destSize);
1703
1704 if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK)
1705 {
1706 SF_LOG_DEBUG("network", "RAD: Failed to compress account data");
1707 return;
1708 }
1709
1710 dest.resize(destSize);
1711
1712 WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8 + 4 + 4 + 4 + destSize);
1713
1714 ObjectGuid guid;
1715
1716 data.WriteBits(request.value, 3); // type (0-7)
1717 data.WriteGuidMask(guid, 5, 1, 3, 7, 0, 4, 2, 6);
1718
1719 data.WriteGuidBytes(guid, 3, 1, 5);
1720 data << uint32(size); // decompressed length
1721 data << uint32(destSize);
1722 data.append(dest);
1723 data.WriteGuidBytes(guid, 7, 4, 0, 6, 2);
1724 data << uint32(adata->Time); // unix time
1725
1726 SendPacket(&data);
1727}
1728
1730{
1731 // Instructs the server we wish to receive few amounts of large packets (SMSG_MULTIPLE_PACKETS?)
1732 // instead of large amount of small packets
1733 return 0;
1734}
1735
1737{
1738 ActionButtonRequest request = ReadSetActionButtonRequest(recvData);
1739
1740 ActionButtonPACKET* button = reinterpret_cast<ActionButtonPACKET*>(&request.buttonStream);
1741 button->id = ACTION_BUTTON_ACTION(request.buttonStream);
1742 button->unk = ACTION_BUTTON_TYPE(request.buttonStream);
1743
1744 SF_LOG_DEBUG("network", "CMSG_SET_ACTION_BUTTON slotId: %u actionId: %u buttontype: %u", request.slotId, button->id, button->unk);
1745
1746 if (!button->id)
1747 GetPlayer()->removeActionButton(request.slotId);
1748 else
1749 GetPlayer()->addActionButton(request.slotId, button->id, ActionButtonType(button->unk));
1750}
1751
1753{
1754 SF_LOG_DEBUG("network", "WORLD: Received CMSG_COMPLETE_CINEMATIC");
1755 // If player has sight bound to visual waypoint NPC we should remove it
1757}
1758
1760{
1761 SF_LOG_DEBUG("network", "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
1762}
1763
1765{
1766 SF_LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_TIME_SKIPPED");
1767
1768 ReadMoveTimeSkippedRequest(recvData);
1769
1770 //TODO!
1771
1772 /*
1773 GetPlayer()->ModifyLastMoveTime(-int32(time_skipped));
1774 */
1775}
1776
1778{
1779 SF_LOG_DEBUG("network", "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
1780
1781 // no used
1782 recvData.rfinish(); // prevent warnings spam
1783}
1784
1786{
1787 // no used
1788 recvData.rfinish(); // prevent warnings spam
1789 /*
1790 uint64 guid;
1791 recvData >> guid;
1792
1793 // now can skip not our packet
1794 if (_player->GetGUID() != guid)
1795 {
1796 recvData.rfinish(); // prevent warnings spam
1797 return;
1798 }
1799
1800 SF_LOG_DEBUG("network", "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK");
1801
1802 recvData.read_skip<uint32>(); // unk
1803
1804 MovementInfo movementInfo;
1805 movementInfo.guid = guid;
1806 ReadMovementInfo(recvData, &movementInfo);
1807 recvData.read_skip<float>(); // unk2
1808 */
1809}
1810
1812{
1813 // no used
1814 recvData.rfinish(); // prevent warnings spam
1815 /*
1816 uint64 guid;
1817 recvData >> guid;
1818
1819 // now can skip not our packet
1820 if (_player->GetGUID() != guid)
1821 {
1822 recvData.rfinish(); // prevent warnings spam
1823 return;
1824 }
1825
1826 SF_LOG_DEBUG("network", "WORLD: CMSG_FORCE_MOVE_ROOT_ACK");
1827
1828 recvData.read_skip<uint32>(); // unk
1829
1830 MovementInfo movementInfo;
1831 ReadMovementInfo(recvData, &movementInfo);
1832 */
1833}
1834
1836{
1837 // not used
1838 recvData.rfinish(); // prevent warnings spam
1839}
1840
1842{
1843 UInt8Request request = ReadUInt8Request(recvData);
1844
1845 if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
1846 {
1847 if (request.value != 0)
1848 SF_LOG_ERROR("network", "WorldSession::HandleSetActionBarToggles in not logged state with value: %u, ignored", uint32(request.value));
1849 return;
1850 }
1851
1853}
1854
1856{
1857 UInt8Request request = ReadUInt8Request(recvData); // 0 or 1 expected
1858
1859 WorldPacket data(SMSG_PLAYED_TIME, 4 + 4 + 1);
1860 data << uint32(_player->GetTotalPlayedTime());
1861 data << uint32(_player->GetLevelPlayedTime());
1862 data << uint8(request.value); // 0 - will not show in chat frame
1863 SendPacket(&data);
1864}
1865
1867{
1868 GuidRequest request = ReadInspectRequest(recvData);
1869
1870 SF_LOG_DEBUG("network", "WORLD: Received CMSG_INSPECT");
1871
1872 Player* player = ObjectAccessor::FindPlayer(request.guid);
1873 if (!player)
1874 {
1875 SF_LOG_DEBUG("network", "CMSG_INSPECT: No player found from GUID: " UI64FMTD, (uint64)request.guid);
1876 return;
1877 }
1878
1879 _player->SendInspectResult(player);
1880}
1881
1883{
1884 GuidRequest request = ReadInspectHonorStatsRequest(recvData);
1885
1886 Player* player = ObjectAccessor::FindPlayer(request.guid);
1887
1888 if (!player)
1889 {
1890 SF_LOG_DEBUG("network", "CMSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, (uint64)request.guid);
1891 return;
1892 }
1893
1894 ObjectGuid playerGuid = player->GetGUID();
1895 WorldPacket data(SMSG_INSPECT_HONOR_STATS, 8 + 1 + 4 + 4);
1896
1898 data << uint16(player->GetUInt16Value(PLAYER_FIELD_YESTERDAY_HONORABLE_KILLS, 1)); // yesterday kills
1899 data << uint16(player->GetUInt16Value(PLAYER_FIELD_YESTERDAY_HONORABLE_KILLS, 0)); // today kills
1900 data << uint8(0); // rank
1901
1902 data.WriteGuidMask(playerGuid, 2, 1, 6, 4, 5, 3, 7, 0);
1903 data.WriteGuidBytes(playerGuid, 1, 3, 6, 7, 2, 4, 5, 0);
1904
1905 SendPacket(&data);
1906}
1907
1909{
1910 WorldTeleportRequest request = ReadWorldTeleportRequest(recvData);
1911
1912 SF_LOG_DEBUG("network", "WORLD: Received CMSG_WORLD_TELEPORT");
1913
1914 if (GetPlayer()->IsInFlight())
1915 {
1916 SF_LOG_DEBUG("network", "Player '%s' (GUID: %u) in flight, ignore worldport command.",
1917 GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
1918 return;
1919 }
1920
1921 SF_LOG_DEBUG("network", "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f",
1922 GetPlayer()->GetName().c_str(), request.time, request.mapId, request.positionX, request.positionY, request.positionZ, request.orientation);
1923
1925 GetPlayer()->TeleportTo(request.mapId, request.positionX, request.positionY, request.positionZ, request.orientation);
1926 else
1928}
1929
1931{
1932 SF_LOG_DEBUG("network", "Received opcode CMSG_WHOIS");
1933 StringRequest request = ReadStringRequest(recvData);
1934
1936 {
1938 return;
1939 }
1940
1941 if (request.value.empty() || !normalizePlayerName(request.value))
1942 {
1944 return;
1945 }
1946
1947 Player* player = sObjectAccessor->FindPlayerByName(request.value);
1948
1949 if (!player)
1950 {
1951 SendNotification(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, request.value.c_str());
1952 return;
1953 }
1954
1955 uint32 accid = player->GetSession()->GetAccountId();
1956
1957 PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_WHOIS);
1958
1959 stmt->setUInt32(0, accid);
1960
1961 PreparedQueryResult result = LoginDatabase.Query(stmt);
1962
1963 if (!result)
1964 {
1966 return;
1967 }
1968
1969 Field* fields = result->Fetch();
1970 std::string acc = fields[0].GetString();
1971 if (acc.empty())
1972 acc = "Unknown";
1973 std::string email = fields[1].GetString();
1974 if (email.empty())
1975 email = "Unknown";
1976 std::string lastip = fields[2].GetString();
1977 if (lastip.empty())
1978 lastip = "Unknown";
1979
1980 std::string msg = request.value + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
1981
1982 WorldPacket data(SMSG_WHOIS, msg.size() + 1);
1983 data.WriteBits(msg.size(), 11);
1984 data.FlushBits();
1985 if (msg.size())
1986 data.WriteString(msg);
1987 SendPacket(&data);
1988
1989 SF_LOG_DEBUG("network", "Received whois command from player %s for character %s",
1990 GetPlayer()->GetName().c_str(), request.value.c_str());
1991}
1992
1994{
1995 SF_LOG_DEBUG("network", "WORLD: CMSG_COMPLAIN");
1996
1997 ComplainRequest request = ReadComplainRequest(recvData);
1998
1999 // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam.
2000 // if it's mail spam - ALL mails from this spammer automatically removed by client
2001
2002 // Complaint Received message
2004 data << uint8(0); // value 1 resets CGChat::m_complaintsSystemStatus in client. (unused?)
2005 data << uint8(0); // value 0xC generates a "CalendarError" in client.
2006 SendPacket(&data);
2007
2008 SF_LOG_DEBUG("network", "REPORT SPAM: type %u, guid %u, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", request.spamType, GUID_LOPART(request.spammerGuid), request.unk1, request.unk2, request.unk3, request.unk4, request.description.c_str());
2009}
2010
2012{
2013 SF_LOG_DEBUG("network", "CMSG_REALM_SPLIT");
2014
2015 UInt32Request request = ReadUInt32Request(recvData);
2016 std::string const splitDate = "01/01/01";
2017 uint32 const splitState = 0; // 0 normal, 1 split, 2 split pending
2018
2019 WorldPacket data(SMSG_REALM_SPLIT, 4 + 4 + splitDate.size());
2020 data.WriteBits(splitDate.size(), 7);
2021 data << splitState;
2022 data << request.value;
2023 data.WriteString(splitDate);
2024 SendPacket(&data);
2025 //SF_LOG_DEBUG("response sent %u", unk);
2026}
2027
2029{
2030 SF_LOG_DEBUG("network", "WORLD: CMSG_FAR_SIGHT");
2031
2032 BoolRequest request = ReadFarSightRequest(recvData);
2033 if (request.value)
2034 {
2035 SF_LOG_DEBUG("network", "Added FarSight " UI64FMTD " to player %u", _player->GetUInt64Value(PLAYER_FIELD_FARSIGHT_OBJECT), _player->GetGUIDLow());
2036 if (WorldObject* target = _player->GetViewpoint())
2037 _player->SetSeer(target);
2038 else
2039 SF_LOG_ERROR("network", "Player %s (GUID: %u) requests non-existing seer " UI64FMTD, _player->GetName().c_str(), GUID_LOPART(_player->GetGUID()), _player->GetUInt64Value(PLAYER_FIELD_FARSIGHT_OBJECT));
2040 }
2041 else
2042 {
2043 SF_LOG_DEBUG("network", "Player %u set vision to self", _player->GetGUIDLow());
2044 _player->SetSeer(_player);
2045 }
2046
2048}
2049
2051{
2052 SF_LOG_DEBUG("network", "CMSG_SET_TITLE");
2053
2054 Int32Request request = ReadInt32Request(recvData);
2055 int32 title = request.value;
2056
2057 // -1 at none
2058 if (title > 0 && title < MAX_TITLE_INDEX)
2059 {
2060 if (!GetPlayer()->HasTitle(title))
2061 return;
2062 }
2063 else
2064 title = 0;
2065
2067}
2068
2070{
2072 data << uint32(TitleIndex);
2073 SendPacket(&data);
2074}
2075
2077{
2079 data << uint32(TitleIndex);
2080 SendPacket(&data);
2081}
2082
2084{
2085 SF_LOG_DEBUG("network", "CMSG_TIME_SYNC_RESPONSE");
2086
2087 TimeSyncRequest request = ReadTimeSyncRequest(recvData);
2088
2089 while (!_player->m_timeSyncQueue.empty() && _player->m_timeSyncQueue.front() < request.counter)
2090 {
2091 SF_LOG_DEBUG("network", "Discarding stale time sync counter %u for player %s before response %u",
2092 _player->m_timeSyncQueue.front(), _player->GetName().c_str(), request.counter);
2093 _player->m_timeSyncQueue.pop();
2094 }
2095
2096 if (_player->m_timeSyncQueue.empty())
2097 {
2098 SF_LOG_DEBUG("network", "Ignoring time sync response %u from player %s with no pending request",
2099 request.counter, _player->GetName().c_str());
2100 return;
2101 }
2102
2103 if (request.counter != _player->m_timeSyncQueue.front())
2104 {
2105 SF_LOG_DEBUG("network", "Ignoring out of order time sync response %u from player %s, expected %u",
2106 request.counter, _player->GetName().c_str(), _player->m_timeSyncQueue.front());
2107 return;
2108 }
2109
2110 SF_LOG_DEBUG("network", "Time sync received: counter %u, client ticks %u, time since last sync %u", request.counter, request.clientTicks, request.clientTicks - _player->m_timeSyncClient);
2111
2112 uint32 ourTicks = request.clientTicks + (getMSTime() - _player->m_timeSyncServer);
2113
2114 // diff should be small
2115 SF_LOG_DEBUG("network", "Our ticks: %u, diff %u, latency %u", ourTicks, ourTicks - request.clientTicks, GetLatency());
2116
2117 _player->m_timeSyncClient = request.clientTicks;
2118 _player->m_timeSyncQueue.pop();
2119}
2120
2122{
2123 SF_LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES");
2124
2125 if (Group* group = _player->GetGroup())
2126 {
2127 if (group->IsLeader(_player->GetGUID()))
2128 group->ResetInstances(InstanceResetMethod::INSTANCE_RESET_ALL, false, _player);
2129 }
2130 else
2131 _player->ResetInstances(InstanceResetMethod::INSTANCE_RESET_ALL, false);
2132}
2133
2135{
2136 SF_LOG_DEBUG("network", "Received: CMSG_SET_DUNGEON_DIFFICULTY");
2137
2138 UInt32Request request = ReadUInt32Request(recvData);
2139
2140 DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(request.value);
2141 if (!difficultyEntry)
2142 {
2143 SF_LOG_DEBUG("network", "%d sent an invalid instance mode %u!",
2144 _player->GetGUIDLow(), request.value);
2145 return;
2146 }
2147
2148 if (difficultyEntry->maptype != MAP_DUNGEON)
2149 {
2150 SF_LOG_DEBUG("network", "%d sent an non-dungeon instance mode %d!",
2151 _player->GetGUIDLow(), difficultyEntry->DiffID);
2152 return;
2153 }
2154
2155 DifficultyID difficulty = DifficultyID(difficultyEntry->DiffID);
2156 if (difficulty == _player->GetDungeonDifficulty())
2157 return;
2158
2159 // cannot reset while in an instance
2160 Map* map = _player->FindMap();
2161 if (map && map->IsNonRaidInstance())
2162 {
2163 SF_LOG_DEBUG("network", "player (Name: %s, GUID: %u) tried to reset the instance while player is inside!",
2164 _player->GetName().c_str(), _player->GetGUIDLow());
2165 return;
2166 }
2167
2168 Group* group = _player->GetGroup();
2169 if (group)
2170 {
2171 if (group->IsLeader(_player->GetGUID()))
2172 {
2173 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
2174 {
2175 Player* groupGuy = itr->GetSource();
2176 if (!groupGuy)
2177 continue;
2178
2179 if (!groupGuy->IsInMap(groupGuy))
2180 return;
2181
2182 if (groupGuy->GetMap()->IsNonRaidInstance())
2183 {
2184 SF_LOG_DEBUG("network", "player %d tried to reset the instance while group member (Name: %s, GUID: %u) is inside!",
2185 _player->GetGUIDLow(), groupGuy->GetName().c_str(), groupGuy->GetGUIDLow());
2186 return;
2187 }
2188 }
2189 // the difficulty is set even if the instances can't be reset
2190 //_player->SendDungeonDifficulty(true);
2192 group->SetDungeonDifficulty(DifficultyID(difficulty));
2193 }
2194 }
2195 else
2196 {
2198 _player->SetDungeonDifficulty(DifficultyID(difficulty));
2199 _player->SendDungeonDifficulty();
2200 }
2201}
2202
2204{
2205 SF_LOG_DEBUG("network", "Received: CMSG_SET_RAID_DIFFICULTY");
2206
2207 UInt32Request request = ReadUInt32Request(recvData);
2208
2209 DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(request.value);
2210 if (!difficultyEntry)
2211 {
2212 SF_LOG_DEBUG("network", "%d sent an invalid instance mode %u!",
2213 _player->GetGUIDLow(), request.value);
2214 return;
2215 }
2216 if (difficultyEntry->maptype != MAP_RAID)
2217 {
2218 SF_LOG_DEBUG("network", "%d sent an non-raid instance mode %u!",
2219 _player->GetGUIDLow(), difficultyEntry->DiffID);
2220 return;
2221 }
2222
2223 DifficultyID difficulty = DifficultyID(difficultyEntry->DiffID);
2224 if (difficulty == _player->GetRaidDifficulty())
2225 return;
2226
2227 // cannot reset while in an instance
2228 Map* map = _player->FindMap();
2229 if (map && map->IsRaid())
2230 {
2231 SF_LOG_DEBUG("network", "player %d tried to reset the raid while inside!", _player->GetGUIDLow());
2232 return;
2233 }
2234
2235 Group* group = _player->GetGroup();
2236 if (group)
2237 {
2238 if (group->IsLeader(_player->GetGUID()))
2239 {
2240 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
2241 {
2242 Player* groupGuy = itr->GetSource();
2243 if (!groupGuy)
2244 continue;
2245
2246 if (!groupGuy->IsInMap(groupGuy))
2247 return;
2248
2249 if (groupGuy->GetMap()->IsRaid())
2250 {
2251 SF_LOG_DEBUG("network", "player %d tried to reset the raid while inside!", _player->GetGUIDLow());
2252 return;
2253 }
2254 }
2255 // the difficulty is set even if the instances can't be reset
2256 //_player->SendDungeonDifficulty(true);
2258 group->SetRaidDifficulty(DifficultyID(difficulty));
2259 }
2260 }
2261 else
2262 {
2264 _player->SetRaidDifficulty(DifficultyID(difficulty));
2265 _player->SendRaidDifficulty();
2266 }
2267}
2268
2270{
2271 SF_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA");
2272
2273 //If player is not mounted, so go out :)
2274 if (!_player->IsMounted()) // not blizz like; no any messages on blizz
2275 {
2277 return;
2278 }
2279
2280 if (_player->IsInFlight()) // not blizz like; no any messages on blizz
2281 {
2283 return;
2284 }
2285
2286 _player->RemoveAurasByType(SPELL_AURA_MOUNTED); // Calls Dismount()
2287}
2288
2290{
2291 if (_player->GetVehicle())
2292 _player->VehicleSpellInitialize();
2293 else if (Unit* minion = _player->GetFirstControlled())
2294 {
2295 if (minion->IsPet())
2296 _player->PetSpellInitialize();
2297 else if (minion->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
2298 _player->CharmSpellInitialize();
2299 }
2300}
2301
2303{
2304 SF_LOG_DEBUG("network", "WORLD: CMSG_SET_TAXI_BENCHMARK_MODE");
2305
2306 UInt8Request request = ReadUInt8Request(recvData);
2307
2309
2310 SF_LOG_DEBUG("network", "Client used \"/timetest %d\" command", request.value);
2311}
2312
2314{
2315 GuidRequest request = ReadQueryInspectAchievementsRequest(recvData);
2316
2317 Player* player = ObjectAccessor::FindPlayer(request.guid);
2318 if (!player)
2319 {
2320 SF_LOG_DEBUG("network", "CMSG_QUERY_INSPECT_ACHIEVEMENTS: Inspected Player " UI64FMTD, (uint64)request.guid);
2321 return;
2322 }
2323
2325}
2326
2328{
2329 UInt32Request request = ReadUInt32Request(recvData);
2330
2331 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
2332 guild->GetAchievementMgr().SendAchievementInfo(_player, request.value);
2333}
2334
2336{
2337 // empty opcode
2338 SF_LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE");
2339
2340 WorldPacket data(SMSG_UI_TIME, 4);
2341 data << uint32(time(NULL));
2342 SendPacket(&data);
2343}
2344
2346{
2347 // empty opcode
2348 SF_LOG_DEBUG("network", "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
2349
2351}
2352
2353void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreas)
2354{
2355 ObjectGuid guid = _player->GetGUID();
2356
2357 WorldPacket data(SMSG_PHASE_SHIFT_CHANGE, 1 + 8 + 2 * phaseIds.size() + 4 + 2 * worldMapAreas.size() + 2 * terrainswaps.size() + 4);
2358 data.WriteGuidMask(guid, 0, 3, 1, 4, 6, 2, 7, 5);
2359
2360 data.WriteGuidBytes(guid, 4, 3, 2);
2361
2362 data << uint32(phaseIds.size()) * 2; // Phase.dbc ids
2363 for (std::set<uint32>::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr)
2364 data << uint16(*itr);
2365
2366 data.WriteGuidBytes(guid, 0, 6);
2367
2368 data << uint32(0); // Inactive terrain swaps
2369 //for (uint8 i = 0; i < inactiveSwapsCount; ++i)
2370 // data << uint16(0);
2371
2372 data.WriteGuidBytes(guid, 1, 7);
2373
2374 data << uint32(worldMapAreas.size()) * 2; // WorldMapArea.dbc id (controls map display)
2375 for (std::set<uint32>::const_iterator itr = worldMapAreas.begin(); itr != worldMapAreas.end(); ++itr)
2376 data << uint16(*itr);
2377
2378 data << uint32(terrainswaps.size()) * 2; // Active terrain swaps
2379 for (std::set<uint32>::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr)
2380 data << uint16(*itr);
2381
2382 data.WriteGuidBytes(guid, 5);
2383
2384 data << uint32(phaseIds.size() ? 0 : 8); // flags (not phasemask)
2385
2386 SendPacket(&data);
2387}
2388
2389// Battlefield and Battleground
2391{
2392 SF_LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
2393
2394 Battleground* bg = _player->GetBattleground();
2395
2396 GuidRequest request = ReadAreaSpiritHealerQueryRequest(recvData);
2397
2398 Creature* unit = GetPlayer()->GetMap()->GetCreature(request.guid);
2399 if (!unit)
2400 return;
2401
2402 if (!unit->IsSpiritService()) // it's not spirit service
2403 return;
2404
2405 if (bg)
2406 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, request.guid);
2407
2408 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
2409 bf->SendAreaSpiritHealerQueryOpcode(_player, request.guid);
2410}
2411
2413{
2414 SF_LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
2415
2416 Battleground* bg = _player->GetBattleground();
2417
2418 GuidRequest request = ReadAreaSpiritHealerQueueRequest(recvData);
2419
2420 Creature* unit = GetPlayer()->GetMap()->GetCreature(request.guid);
2421 if (!unit)
2422 return;
2423
2424 if (!unit->IsSpiritService()) // it's not spirit service
2425 return;
2426
2427 if (bg)
2428 bg->AddPlayerToResurrectQueue(request.guid, _player->GetGUID());
2429
2430 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
2431 bf->AddPlayerToResurrectQueue(request.guid, _player->GetGUID());
2432}
2433
2435{
2436 if (_player->IsInFlight())
2437 return;
2438
2439 if (/*Battlefield* bf = */sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
2440 {
2441 // bf->PlayerAskToLeave(_player); FIXME
2442 return;
2443 }
2444
2445 AreaTableEntry const* atEntry = sAreaStore.LookupEntry(_player->GetAreaId());
2446 if (!atEntry || !(atEntry->m_flags & AREA_FLAG_WINTERGRASP_2))
2447 return;
2448
2449 _player->BuildPlayerRepop();
2450 _player->ResurrectPlayer(100);
2451 _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
2452}
2453
2455{
2456 BoolRequest request = ReadInstanceLockResponseRequest(recvPacket);
2457
2458 if (!_player->HasPendingBind())
2459 {
2460 SF_LOG_INFO("network", "InstanceLockResponse: Player %s (guid %u) tried to bind himself/teleport to graveyard without a pending bind!",
2461 _player->GetName().c_str(), _player->GetGUIDLow());
2462 return;
2463 }
2464
2465 if (request.value)
2466 _player->BindToInstance();
2467 else
2468 _player->RepopAtGraveyard();
2469
2470 _player->SetPendingBind(0, 0);
2471}
2472
2473namespace
2474{
2475 // No server DB2 loaded — replying (even with size 0) can crash the 5.4.8 client.
2476 bool AlwaysSkipHotfixReply(uint32 type)
2477 {
2478 switch (type)
2479 {
2488 return true;
2489 default:
2490 return false;
2491 }
2492 }
2493
2494 bool IsPlausibleHotfixEntry(uint32 entry)
2495 {
2496 return entry != 0 && entry <= 0x00FFFFFF;
2497 }
2498
2499 bool ShouldSendHotfixReply(uint32 type, uint32 entry)
2500 {
2501 if (AlwaysSkipHotfixReply(type))
2502 return false;
2503 return IsPlausibleHotfixEntry(entry);
2504 }
2505
2506 void SendEmptyDbReply(WorldSession* session, uint32 entry, uint32 type, char const* reason)
2507 {
2509 data << uint32(entry);
2510 data << uint32(time(NULL));
2511 data << uint32(type);
2512 data << uint32(0);
2513
2514 session->SendPacket(&data);
2515 SF_LOG_INFO("network", "SMSG_DB_REPLY: empty hotfix entry %u type %u (%s)", entry, type, reason);
2516 }
2517
2518 bool IsKnownHotfixType(uint32 type)
2519 {
2520 switch (type)
2521 {
2536 case DB2_REPLY_CREATURE:
2538 case DB2_REPLY_CURVE:
2543 case DB2_REPLY_ITEM:
2550 case DB2_REPLY_KEYCHAIN:
2551 case DB2_REPLY_LOCALE:
2552 case DB2_REPLY_LOCATION:
2555 case DB2_REPLY_PATH:
2574 case DB2_REPLY_VIGNETTE:
2579 return true;
2580 default:
2581 return false;
2582 }
2583 }
2584}
2585
2587{
2588 uint32 type, count;
2589 recvPacket >> type;
2590
2591 DB2StorageBase const* store = GetDB2Storage(type);
2592 bool const knownHotfixType = IsKnownHotfixType(type);
2593 bool const knownUnsupportedType = !store && knownHotfixType;
2594 if (!store && !knownUnsupportedType)
2595 {
2596 SF_LOG_ERROR("network", "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", type);
2597 recvPacket.rfinish();
2598 return;
2599 }
2600
2601 count = recvPacket.ReadBits(21);
2602
2603 std::vector<ObjectGuid> guids(count);
2604 for (uint32 i = 0; i < count; ++i)
2605 {
2606 recvPacket.ReadGuidMask(guids[i], 6, 3, 0, 1, 4, 5, 7, 2);
2607 }
2608
2609 std::vector<uint32> entries(count);
2610 for (uint32 i = 0; i < count; ++i)
2611 {
2612 recvPacket.ReadByteSeq(guids[i][1]);
2613 recvPacket >> entries[i];
2614 recvPacket.ReadGuidBytes(guids[i], 0, 5, 6, 4, 7, 2, 3);
2615 }
2616
2617 if (knownUnsupportedType)
2618 {
2619 for (uint32 i = 0; i < count; ++i)
2620 {
2621 if (!ShouldSendHotfixReply(type, entries[i]))
2622 {
2623 SF_LOG_INFO("network", "CMSG_REQUEST_HOTFIX: skipped entry %u type %u", entries[i], type);
2624 continue;
2625 }
2626
2627 SendEmptyDbReply(this, entries[i], type, "unsupported store");
2628 }
2629
2630 return;
2631 }
2632
2633 for (uint32 i = 0; i < count; ++i)
2634 {
2635 if (!ShouldSendHotfixReply(type, entries[i]))
2636 {
2637 SF_LOG_INFO("network", "CMSG_REQUEST_HOTFIX: skipped entry %u type %u", entries[i], type);
2638 continue;
2639 }
2640
2641 // temp: this should be moved once broadcast text is properly implemented
2642 if (type == DB2_REPLY_BROADCAST_TEXT)
2643 {
2644 SF_LOG_INFO("network", "SMSG_DB_REPLY: broadcast text hotfix entry %u (gossip hack)", entries[i]);
2645 SendBroadcastText(entries[i]);
2646 continue;
2647 }
2648
2649 if (!store->HasRecord(entries[i]))
2650 continue;
2651
2652 ByteBuffer record;
2653 store->WriteRecord(entries[i], (uint32)GetSessionDbcLocale(), record);
2654
2656 data << uint32(entries[i]);
2657 data << uint32(time(NULL));
2658 data << uint32(type);
2659 data << uint32(record.size());
2660 data.append(record);
2661
2662 SendPacket(&data);
2663
2664 SF_LOG_DEBUG("network", "SMSG_DB_REPLY: Sent hotfix entry: %u type: %u", entries[i], type);
2665 }
2666}
2667
2669{
2670 /*
2671 * This is a hack fix! Still uses Gossip Id's instead of Broadcast Id's.
2672 * Major database changed required at some point.
2673 */
2674
2675 ByteBuffer buffer;
2676 std::string defaultText = "Greetings, $n";
2677
2678 GossipText const* pGossip = sObjectMgr->GetGossipText(entry);
2679
2680 uint16 nrmTextLength = pGossip ? pGossip->Options[0].Text_0.length() : defaultText.length();
2681 uint16 altTextLength = pGossip ? pGossip->Options[0].Text_1.length() : defaultText.length();
2682
2683 buffer << uint32(entry);
2684 buffer << uint32(pGossip ? pGossip->Options[0].Language : 0);
2685 buffer << uint16(nrmTextLength);
2686
2687 if (nrmTextLength)
2688 buffer << std::string(pGossip ? pGossip->Options[0].Text_0 : defaultText);
2689
2690 buffer << uint16(altTextLength);
2691
2692 if (altTextLength)
2693 buffer << std::string(pGossip ? pGossip->Options[0].Text_1 : defaultText);
2694
2695 for (int i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++)
2696 buffer << uint32(0);
2697
2698 buffer << uint32(1);
2699
2701 data << uint32(entry);
2702 data << uint32(time(NULL));
2704 data << uint32(buffer.size());
2705 data.append(buffer);
2706
2707 SendPacket(&data);
2708}
2709
2711{
2712 SF_LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
2713
2714 UpdateMissileTrajectoryRequest request = ReadUpdateMissileTrajectoryRequest(recvPacket);
2715
2716 Unit* caster = ObjectAccessor::GetUnit(*_player, request.guid);
2717 Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL;
2718 if (!spell || spell->m_spellInfo->Id != request.spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
2719 {
2720 recvPacket.rfinish();
2721 return;
2722 }
2723
2724 Position pos = *spell->m_targets.GetSrcPos();
2725 pos.Relocate(request.curX, request.curY, request.curZ);
2726 spell->m_targets.ModSrc(pos);
2727
2728 pos = *spell->m_targets.GetDstPos();
2729 pos.Relocate(request.targetX, request.targetY, request.targetZ);
2730 spell->m_targets.ModDst(pos);
2731
2732 spell->m_targets.SetElevation(request.elevation);
2733 spell->m_targets.SetSpeed(request.speed);
2734
2735 if (request.moveStop)
2736 {
2737 uint32 opcode;
2738 recvPacket >> opcode;
2739 recvPacket.SetOpcode(MSG_MOVE_STOP); // always set to MSG_MOVE_STOP in client SetOpcode
2740 HandleMovementOpcodes(recvPacket);
2741 }
2742}
2743
2745{
2746 ReadUInt8Request(recvPacket);
2747
2748 // do something?
2749}
2750
2752{
2753 GuidRequest request = ReadObjectUpdateFailedRequest(recvPacket);
2754
2755 WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), request.guid);
2756 if (request.guid == GetPlayer()->GetGUID())
2757 SF_LOG_ERROR("network", "Object update failed for object " UI64FMTD " (%s) for player %s (%u)", uint64(request.guid), obj ? obj->GetName().c_str() : "object-not-found", GetPlayerName().c_str(), GetGuidLow());
2758 else
2759 SF_LOG_DEBUG("network", "Object update failed for object " UI64FMTD " (%s) for player %s (%u)", uint64(request.guid), obj ? obj->GetName().c_str() : "object-not-found", GetPlayerName().c_str(), GetGuidLow());
2760
2761 // If create object failed for current player then client will be stuck on loading screen
2762 //if (_player->GetGUID() == guid)
2763 //{
2764 // LogoutPlayer(true);
2765 // return;
2766 //}
2767
2768 // Pretend we've never seen this object
2769 //_player->m_clientGUIDs.erase(guid);
2770}
2771
2773{
2774 SF_LOG_DEBUG("network", "WORLD: CMSG_SAVE_CUF_PROFILES");
2775
2776 uint8 count = (uint8)recvPacket.ReadBits(19);
2777
2778 if (count > MAX_CUF_PROFILES)
2779 {
2780 SF_LOG_ERROR("entities.player", "HandleSaveCUFProfiles - %s tried to save more than %i CUF profiles. Hacking attempt?", GetPlayerName().c_str(), MAX_CUF_PROFILES);
2781 recvPacket.rfinish();
2782 return;
2783 }
2784
2785 CUFProfile* profiles[MAX_CUF_PROFILES];
2786 uint8 strlens[MAX_CUF_PROFILES];
2787
2788 for (uint8 i = 0; i < count; ++i)
2789 {
2790 profiles[i] = new CUFProfile;
2791 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_2, recvPacket.ReadBit());
2792 profiles[i]->BoolOptions.set(CUF_DISPLAY_MAIN_TANK_AND_ASSIST, recvPacket.ReadBit());
2793 profiles[i]->BoolOptions.set(CUF_DISPLAY_POWER_BAR, recvPacket.ReadBit());
2794 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_10_PLAYERS, recvPacket.ReadBit());
2795 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_3_PLAYERS, recvPacket.ReadBit());
2796 profiles[i]->BoolOptions.set(CUF_UNK_156, recvPacket.ReadBit());
2797 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_40_PLAYERS, recvPacket.ReadBit());
2798 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_2_PLAYERS, recvPacket.ReadBit());
2799 profiles[i]->BoolOptions.set(CUF_KEEP_GROUPS_TOGETHER, recvPacket.ReadBit());
2800 profiles[i]->BoolOptions.set(CUF_USE_CLASS_COLORS, recvPacket.ReadBit());
2801 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_25_PLAYERS, recvPacket.ReadBit());
2802 profiles[i]->BoolOptions.set(CUF_UNK_145, recvPacket.ReadBit());
2803 strlens[i] = (uint8)recvPacket.ReadBits(7);
2804 profiles[i]->BoolOptions.set(CUF_DISPLAY_PETS, recvPacket.ReadBit());
2805 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVP, recvPacket.ReadBit());
2806 profiles[i]->BoolOptions.set(CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS, recvPacket.ReadBit());
2807 profiles[i]->BoolOptions.set(CUF_DISPLAY_NON_BOSS_DEBUFFS, recvPacket.ReadBit());
2808 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_15_PLAYERS, recvPacket.ReadBit());
2809 profiles[i]->BoolOptions.set(CUF_UNK_157, recvPacket.ReadBit());
2810 profiles[i]->BoolOptions.set(CUF_DISPLAY_BORDER, recvPacket.ReadBit());
2811 profiles[i]->BoolOptions.set(CUF_DISPLAY_HORIZONTAL_GROUPS, recvPacket.ReadBit());
2812 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_1, recvPacket.ReadBit());
2813 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_5_PLAYERS, recvPacket.ReadBit());
2814 profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVE, recvPacket.ReadBit());
2815 profiles[i]->BoolOptions.set(CUF_DISPLAY_HEAL_PREDICTION, recvPacket.ReadBit());
2816 profiles[i]->BoolOptions.set(CUF_DISPLAY_AGGRO_HIGHLIGHT, recvPacket.ReadBit());
2817 }
2818
2819 for (uint8 i = 0; i < count; ++i)
2820 {
2821 recvPacket >> profiles[i]->FrameHeight;
2822 recvPacket >> profiles[i]->Unk146;
2823 recvPacket >> profiles[i]->HealthText;
2824 recvPacket >> profiles[i]->FrameWidth;
2825 recvPacket >> profiles[i]->Unk148;
2826 recvPacket >> profiles[i]->SortBy;
2827 recvPacket >> profiles[i]->Unk150;
2828 profiles[i]->ProfileName = recvPacket.ReadString(strlens[i]);
2829 recvPacket >> profiles[i]->Unk147;
2830 recvPacket >> profiles[i]->Unk152;
2831 recvPacket >> profiles[i]->Unk154;
2832
2833 GetPlayer()->SaveCUFProfile(i, profiles[i]);
2834 }
2835
2836 for (uint8 i = count; i < MAX_CUF_PROFILES; ++i)
2837 GetPlayer()->SaveCUFProfile(i, NULL);
2838}
2839
2841{
2842 Player* player = GetPlayer();
2843
2844 uint8 count = player->GetCUFProfilesCount();
2845
2846 ByteBuffer byteBuffer(25 * count);
2847 WorldPacket data(SMSG_LOAD_CUF_PROFILES, 5 * count + 25 * count);
2848
2849 data.WriteBits(count, 20);
2850 for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i)
2851 {
2852 CUFProfile* profile = player->GetCUFProfile(i);
2853 if (!profile)
2854 continue;
2855
2858 data.WriteBit(profile->BoolOptions[CUF_UNK_157]);
2861 data.WriteBit(profile->BoolOptions[CUF_DISPLAY_BORDER]);
2865 data.WriteBits(profile->ProfileName.size(), 8);
2866 data.WriteBit(profile->BoolOptions[CUF_DISPLAY_PETS]);
2868 data.WriteBit(profile->BoolOptions[CUF_UNK_145]);
2870 data.WriteBit(profile->BoolOptions[CUF_UNK_156]);
2882
2883 byteBuffer << uint16(profile->Unk152);
2884 byteBuffer << uint16(profile->Unk154);
2885 byteBuffer << uint8(profile->HealthText);
2886 byteBuffer.WriteString(profile->ProfileName);
2887 byteBuffer << uint8(profile->Unk147);
2888 byteBuffer << uint8(profile->Unk146);
2889 byteBuffer << uint16(profile->FrameHeight);
2890 byteBuffer << uint8(profile->Unk148);
2891 byteBuffer << uint8(profile->SortBy);
2892 byteBuffer << uint16(profile->FrameWidth);
2893 byteBuffer << uint16(profile->Unk150);
2894 }
2895
2896 data.FlushBits();
2897 data.append(byteBuffer);
2898 SendPacket(&data);
2899}
2900
2901#define JOIN_THE_ALLIANCE 1
2902#define JOIN_THE_HORDE 0
2903
2905{
2906 UInt32Request request = ReadUInt32Request(recvPacket);
2907
2908 if (_player->getRace() != RACE_PANDAREN_NEUTRAL)
2909 return;
2910
2911 if (request.value == JOIN_THE_HORDE)
2912 {
2913 _player->SetByteValue(UNIT_FIELD_SEX, 0, RACE_PANDAREN_HORDE);
2914 _player->setFactionForRace(RACE_PANDAREN_HORDE);
2915 _player->SaveToDB();
2916 WorldLocation location(1, 1357.62f, -4373.55f, 26.13f, 0.13f);
2917 _player->TeleportTo(location);
2918 _player->SetHomebind(location, 363);
2919 _player->learnSpell(669, false); // Language Orcish
2920 _player->learnSpell(108127, false); // Language Pandaren
2921 }
2922 else if (request.value == JOIN_THE_ALLIANCE)
2923 {
2925 _player->setFactionForRace(RACE_PANDAREN_ALLIANCE);
2926 _player->SaveToDB();
2927 WorldLocation location(0, -8960.02f, 516.10f, 96.36f, 0.67f);
2928 _player->TeleportTo(location);
2929 _player->SetHomebind(location, 9);
2930 _player->learnSpell(668, false); // Language Common
2931 _player->learnSpell(108127, false); // Language Pandaren
2932 }
2933
2934 if (_player->GetQuestStatus(31450) == QUEST_STATUS_INCOMPLETE)
2935 _player->KilledMonsterCredit(64594);
2936
2937 _player->SendMovieStart(116);
2938}
2939
2941{
2942 SF_LOG_DEBUG("network", "WORLD: CMSG_DISCARDED_TIME_SYNC_ACKS");
2943
2944 DiscardedTimeSyncAcksRequest request = ReadDiscardedTimeSyncAcksRequest(recvData);
2945 if (!_player)
2946 return;
2947
2948 if (!request.hasCounter)
2949 return;
2950
2951 while (!_player->m_timeSyncQueue.empty())
2952 {
2953 uint32 counter = _player->m_timeSyncQueue.front();
2954 _player->m_timeSyncQueue.pop();
2955
2956 SF_LOG_DEBUG("network", "Discarded time sync ack %u from player %s, removed pending counter %u",
2957 request.counter, _player->GetName().c_str(), counter);
2958
2959 if (counter >= request.counter)
2960 break;
2961 }
2962}
2963
2965{
2967 data << uint32(SoundKitID);
2968 SendPacket(&data);
2969}
2970
2972{
2973 WorldPacket data(SMSG_PAGETEXT, 8);
2974 data.WriteGuidMask(GameObjectGUID, 0, 3, 2, 6, 5, 1, 7, 4);
2975 data.WriteGuidBytes(GameObjectGUID, 6, 2, 7, 0, 5, 3, 1, 4);
2976 _player->SendDirectMessage(&data);
2977}
2978
2980{
2981 SF_LOG_ERROR("network", "recv CMSG_SCENE_COMPLETED");
2982 SceneCompletedRequest request = ReadSceneCompletedRequest(recvPacket);
2983 SF_LOG_ERROR("network", "hasData %u", request.hasData);
2984}
2985
2987{
2989 data.WriteGuidMask(guid, 0, 4, 2, 6, 5, 1, 3, 7);
2990
2991 data.WriteGuidBytes(guid, 3);
2992 data << ItemID;
2993 data << uint32(drunkenState);
2994 data.WriteGuidBytes(guid, 4, 6, 7, 0, 2, 5, 1);
2995 _player->SendMessageToSet(&data, true);
2996}
#define sBattlefieldMgr
@ STATUS_IN_PROGRESS
#define sBattlegroundMgr
@ CHAR_SEL_GUID_RACE_ACC_BY_NAME
@ CHAR_SEL_GUID_BY_NAME
@ CHAR_INS_BUG_REPORT
AccountTypes
Definition Common.h:129
#define M_PI
Definition Common.h:192
#define CORPSE_RECLAIM_RADIUS
Definition Corpse.h:23
@ CORPSE_RESURRECTABLE_PVP
Definition Corpse.h:18
DB2StorageBase const * GetDB2Storage(uint32 type)
@ MAX_LEVEL
Definition DBCEnums.h:20
@ STRONG_MAX_LEVEL
Definition DBCEnums.h:24
@ MAP_DUNGEON
Definition DBCEnums.h:394
@ MAP_RAID
Definition DBCEnums.h:395
DifficultyID
Definition DBCEnums.h:330
@ AREA_FLAG_WINTERGRASP_2
Definition DBCEnums.h:324
DBCStorage< AreaTableEntry > sAreaStore(AreaTableEntryfmt)
DBCStorage< AreaTriggerEntry > sAreaTriggerStore(AreaTriggerEntryfmt)
DBCStorage< DifficultyEntry > sDifficultyStore(Difficultyfmt)
AreaTableEntry const * GetAreaEntryByAreaID(uint32 area_id)
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
std::uint16_t uint16
Definition Define.h:78
#define sGuildMgr
Definition GuildMgr.h:53
@ LANG_PLAYER_NOT_EXIST_OR_OFFLINE
Definition Language.h:753
@ LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND
Definition Language.h:754
@ LANG_DEBUG_AREATRIGGER_REACHED
Definition Language.h:954
@ LANG_CHAR_NON_MOUNTED
Definition Language.h:35
@ LANG_YOU_IN_FLIGHT
Definition Language.h:31
@ LANG_YOU_NOT_HAVE_PERMISSION
Definition Language.h:749
@ LANG_NEED_CHARACTER_NAME
Definition Language.h:752
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
@ LOGIN_SEL_ACCOUNT_WHOIS
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition Map.h:629
#define sMapMgr
Definition MapManager.h:145
#define JOIN_THE_HORDE
#define JOIN_THE_ALLIANCE
#define MAX_GOSSIP_TEXT_OPTIONS
Definition NPCHandler.h:27
#define sObjectAccessor
uint32 GUID_LOPART(uint64 x)
bool IS_GAMEOBJECT_GUID(uint64 guid)
bool IS_CRE_OR_VEH_GUID(uint64 guid)
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
uint32 GUID_HIPART(uint64 guid)
bool normalizePlayerName(std::string &name)
#define sObjectMgr
Definition ObjectMgr.h:1617
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:25
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition Player.h:830
@ PLAYER_FLAGS_IN_PVP
Definition Player.h:546
@ PLAYER_FLAGS_RESTING
Definition Player.h:542
@ PLAYER_FLAGS_GHOST
Definition Player.h:541
@ PLAYER_FLAGS_TAXI_BENCHMARK
Definition Player.h:554
@ PLAYER_FLAGS_PVP_TIMER
Definition Player.h:555
ActionButtonType
Definition Player.h:325
#define ACTION_BUTTON_TYPE(X)
Definition Player.h:348
#define MAX_TITLE_INDEX
Definition Player.h:572
@ CUF_DISPLAY_NON_BOSS_DEBUFFS
Definition Player.h:220
@ CUF_AUTO_ACTIVATE_40_PLAYERS
Definition Player.h:230
@ CUF_DISPLAY_HEAL_PREDICTION
Definition Player.h:214
@ CUF_UNK_157
Definition Player.h:237
@ CUF_AUTO_ACTIVATE_5_PLAYERS
Definition Player.h:226
@ CUF_AUTO_ACTIVATE_3_PLAYERS
Definition Player.h:225
@ CUF_DISPLAY_HORIZONTAL_GROUPS
Definition Player.h:221
@ CUF_AUTO_ACTIVATE_PVE
Definition Player.h:234
@ CUF_AUTO_ACTIVATE_SPEC_1
Definition Player.h:231
@ CUF_UNK_145
Definition Player.h:235
@ CUF_USE_CLASS_COLORS
Definition Player.h:219
@ CUF_AUTO_ACTIVATE_PVP
Definition Player.h:233
@ CUF_DISPLAY_MAIN_TANK_AND_ASSIST
Definition Player.h:213
@ CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS
Definition Player.h:216
@ CUF_AUTO_ACTIVATE_SPEC_2
Definition Player.h:232
@ CUF_UNK_156
Definition Player.h:236
@ CUF_AUTO_ACTIVATE_2_PLAYERS
Definition Player.h:224
@ CUF_DISPLAY_POWER_BAR
Definition Player.h:217
@ CUF_DISPLAY_AGGRO_HIGHLIGHT
Definition Player.h:215
@ CUF_AUTO_ACTIVATE_25_PLAYERS
Definition Player.h:229
@ CUF_KEEP_GROUPS_TOGETHER
Definition Player.h:211
@ CUF_DISPLAY_BORDER
Definition Player.h:218
@ CUF_DISPLAY_PETS
Definition Player.h:212
@ CUF_AUTO_ACTIVATE_10_PLAYERS
Definition Player.h:227
@ CUF_AUTO_ACTIVATE_15_PLAYERS
Definition Player.h:228
#define ACTION_BUTTON_ACTION(X)
Definition Player.h:347
#define MAX_CUF_PROFILES
Maximum number of CompactUnitFrames profiles.
Definition Player.h:206
@ REST_TYPE_NO
Definition Player.h:822
@ REST_TYPE_IN_TAVERN
Definition Player.h:823
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
#define sScriptMgr
Definition ScriptMgr.h:764
@ RACE_PANDAREN_NEUTRAL
@ RACE_PANDAREN_ALLIANCE
@ RACE_PANDAREN_HORDE
DrunkenState
#define SF_SHARED_GUARD
Definition SharedMutex.h:17
#define sSocialMgr
Definition SocialMgr.h:134
FriendsResult
Results of friend related commands.
Definition SocialMgr.h:56
@ FRIEND_IGNORE_FULL
Definition SocialMgr.h:68
@ FRIEND_IGNORE_REMOVED
Definition SocialMgr.h:73
@ FRIEND_ENEMY
Definition SocialMgr.h:67
@ FRIEND_ALREADY
Definition SocialMgr.h:65
@ FRIEND_ADDED_OFFLINE
Definition SocialMgr.h:64
@ FRIEND_NOT_FOUND
Definition SocialMgr.h:61
@ FRIEND_ADDED_ONLINE
Definition SocialMgr.h:63
@ FRIEND_IGNORE_ADDED
Definition SocialMgr.h:72
@ FRIEND_IGNORE_NOT_FOUND
Definition SocialMgr.h:70
@ FRIEND_IGNORE_SELF
Definition SocialMgr.h:69
@ FRIEND_IGNORE_ALREADY
Definition SocialMgr.h:71
@ FRIEND_SELF
Definition SocialMgr.h:66
@ FRIEND_REMOVED
Definition SocialMgr.h:62
@ FRIEND_LIST_FULL
Definition SocialMgr.h:58
@ SPELL_AURA_PREVENT_RESURRECTION
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_FEIGN_DEATH
uint32 getMSTime()
Definition Timer.h:12
@ UNIT_NPC_FLAG_NONE
Definition Unit.h:686
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition Unit.h:813
@ JUST_DIED
Definition Unit.h:504
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ UNIT_STAND_STATE_SIT
Definition Unit.h:163
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:1098
@ CURRENT_GENERIC_SPELL
Definition Unit.h:1109
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition Unit.h:257
@ UNIT_STATE_DIED
Definition Unit.h:512
@ UNIT_FLAG_STUNNED
Definition Unit.h:643
@ UNIT_FIELD_SHAPESHIFT_FORM
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_SEX
@ PLAYER_FIELD_FARSIGHT_OBJECT
@ PLAYER_FIELD_LIFETIME_MAX_RANK
@ PLAYER_FIELD_YESTERDAY_HONORABLE_KILLS
@ PLAYER_FIELD_PLAYER_TITLE
@ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS
@ PLAYER_FIELD_PLAYER_FLAGS
bool Utf8FitTo(const std::string &str, const std::wstring &search)
Definition Util.cpp:473
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition Util.cpp:305
void wstrToLower(std::wstring &str)
Definition Util.h:314
static AccountTypes GetSecurity(uint32 accountId)
static bool IsPlayerAccount(AccountTypes gmlevel)
void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid)
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void read_skip()
Definition ByteBuffer.h:502
size_t rpos() const
Definition ByteBuffer.h:470
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
size_t bitwpos() const
Returns position of last written bit.
Definition ByteBuffer.h:492
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void resize(size_t newsize)
Definition ByteBuffer.h:612
void ReadByteSeq(uint8 &b)
Definition ByteBuffer.h:215
void append(T value)
Definition ByteBuffer.h:147
void rfinish()
Definition ByteBuffer.h:478
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
void PutBits(size_t pos, T value, uint32 bitCount)
Definition ByteBuffer.h:283
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
size_t size() const
Definition ByteBuffer.h:609
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
uint8 * contents()
Definition ByteBuffer.h:605
bool ReadBit()
Definition ByteBuffer.h:180
void PSendSysMessage(const char *format,...) ATTR_PRINTF(2
Definition Chat.cpp:221
virtual void SendSysMessage(const char *str)
Definition Chat.cpp:153
time_t const & GetGhostTime() const
Definition Corpse.h:56
CorpseType GetType() const
Definition Corpse.h:58
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:524
CreatureAI * AI() const
Definition Creature.h:483
Interface class for common access.
Definition DB2Store.h:16
virtual void WriteRecord(uint32 id, uint32 locale, ByteBuffer &buffer) const =0
virtual bool HasRecord(uint32 id) const =0
Definition Field.h:16
std::string GetString() const
Definition Field.h:228
uint32 GetUInt32() const
Definition Field.h:105
virtual bool GossipSelectCode(Player *, uint32, uint32, char const *)
virtual bool GossipSelect(Player *, uint32, uint32)
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:643
GameObjectAI * AI() const
Definition GameObject.h:824
Definition Group.h:147
void SetDungeonDifficulty(DifficultyID difficulty)
Definition Group.cpp:2240
void SetRaidDifficulty(DifficultyID difficulty)
Definition Group.cpp:2264
GroupReference * GetFirstMember()
Definition Group.h:225
bool IsLeader(uint64 guid) const
Definition Group.cpp:2608
void ResetInstances(InstanceResetMethod method, bool isRaid, Player *SendMsgTo)
Definition Group.cpp:2301
GroupReference * next()
Definition Guild.h:324
uint64 GetGUID() const
Definition Guild.h:758
static SF_SHARED_MUTEX * GetLock()
UNORDERED_MAP< uint64, T * > MapType
Definition Map.h:238
bool IsRaid() const
Definition Map.h:372
Creature * GetCreature(uint64 guid)
Definition Map.cpp:3179
bool IsNonRaidInstance() const
Definition Map.h:371
bool IsInstance() const
Definition Map.h:368
static WorldObject * GetWorldObject(WorldObject const &, uint64)
static Unit * GetUnit(WorldObject const &, uint64 guid)
static Player * FindPlayer(uint64)
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition Object.cpp:1158
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
bool IsInWorld() const
Definition Object.h:114
uint16 GetUInt16Value(uint16 index, uint8 offset) const
Definition Object.cpp:350
uint32 GetGUIDLow() const
Definition Object.h:120
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:1317
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1345
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
void ToggleFlag(uint16 index, uint32 flag)
Definition Object.cpp:1301
uint32 GetTeam() const
Definition Player.h:2527
void removeActionButton(uint8 button)
Definition Player.cpp:6820
uint8 GetCUFProfilesCount() const
Definition Player.h:1873
uint32 GetGuildId() const
Definition Player.h:2291
void KillPlayer()
Definition Player.cpp:5284
void InnEnter(time_t time, uint32 mapid, float x, float y, float z, float radius=0.0f, float boxX=0.0f, float boxY=0.0f, float boxZ=0.0f, float boxOrientation=0.0f)
Definition Player.cpp:1796
void UpdateZone(uint32 newZone, uint32 newArea)
Definition Player.cpp:8126
void SaveCUFProfile(uint8 id, CUFProfile *profile)
Definition Player.h:1865
void ResurectUsingRequestData()
Definition Player.cpp:19817
void StopCinematic()
Definition Player.cpp:6909
Guild * GetGuild()
Definition Player.cpp:22662
WorldSession * GetSession() const
Definition Player.h:2417
OutdoorPvP * GetOutdoorPvP() const
Definition Player.cpp:19552
void RepopAtGraveyard()
Definition Player.cpp:5585
static uint32 TeamForRace(uint8 race)
Definition Player.cpp:7072
void SendRespondInspectAchievements(Player *player) const
Definition Player.cpp:21003
void UpdateVisibilityForPlayer()
Definition Player.cpp:18329
void ClearResurrectRequestData()
Definition Player.h:2197
void SetRestType(RestType n_r_type)
Definition Player.h:1444
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:15663
bool TeleportToBGEntryPoint()
Definition Player.cpp:2341
Corpse * GetCorpse() const
Definition Player.cpp:5385
Battleground * GetBattleground() const
Definition Player.cpp:19212
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition Player.cpp:2836
Group * GetGroup()
Definition Player.h:2972
CUFProfile * GetCUFProfile(uint8 id) const
Definition Player.h:1869
void SpawnCorpseBones()
Definition Player.cpp:5378
PvPInfo pvpInfo
Definition Player.h:2233
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:2090
bool IsVisibleGloballyFor(Player const *player) const
Definition Player.cpp:18107
void AreaExploredOrEventHappens(uint32 questId)
QuestStatus GetQuestStatus(uint32 quest_id) const
PlayerSocial * GetSocial()
Definition Player.h:1346
ActionButton * addActionButton(uint8 button, uint32 action, ActionButtonType type)
Definition Player.cpp:6805
void BuildPlayerRepop()
Definition Player.cpp:5152
bool isDebugAreaTriggers
Definition Player.h:3142
void UpdatePvP(bool state, bool override=false)
Definition Player.cpp:17484
RestType GetRestType() const
Definition Player.h:1440
PlayerMenu * PlayerTalkClass
Definition Player.h:2680
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:5203
bool IsGossipOptionCoded(uint32 selection) const
Definition GossipDef.h:256
void SetFriendNote(uint32 friendGuid, std::string note)
void setString(const uint8 index, const std::string &value)
void setUInt32(const uint8 index, const uint32 value)
void ModDst(Position const &pos)
Definition Spell.cpp:412
bool HasSrc() const
Definition Spell.h:216
void SetSpeed(float speed)
Definition Spell.h:223
bool HasDst() const
Definition Spell.h:217
void SetElevation(float elevation)
Definition Spell.h:221
void ModSrc(Position const &pos)
Definition Spell.cpp:360
Position const * GetSrcPos() const
Definition Spell.cpp:337
WorldLocation const * GetDstPos() const
Definition Spell.cpp:383
Definition Spell.h:289
SpellCastTargets m_targets
Definition Spell.h:535
SpellInfo const *const m_spellInfo
Definition Spell.h:530
uint32 Id
Definition SpellInfo.h:160
virtual void sGossipSelectCode(Player *, uint32, uint32, char const *)
Definition UnitAI.h:248
virtual void sGossipSelect(Player *, uint32, uint32)
Definition UnitAI.h:247
Definition Unit.h:1367
uint8 getGender() const
Definition Unit.h:1551
uint8 getClass() const
Definition Unit.h:1543
bool IsAlive() const
Definition Unit.h:2032
bool IsInFlight() const
Definition Unit.h:1891
void SetRooted(bool apply, bool packetOnly=false)
Definition Unit.cpp:6794
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
uint8 getLevel() const
Definition Unit.h:1528
void SetStandState(uint8 state)
Definition Unit.cpp:5902
bool IsSpiritService() const
Definition Unit.h:1882
bool IsInCombat() const
Definition Unit.h:1896
uint8 getRace() const
Definition Unit.h:1535
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:2363
uint32 GetMapId() const
Definition Object.h:546
Map * GetMap() const
Definition Object.h:740
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1735
uint32 LastUsedScriptID
Definition Object.h:794
std::string const & GetName() const
Definition Object.h:664
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1666
uint32 GetZoneId() const
Definition Object.cpp:1597
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:1607
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1703
void SetOpcode(Opcodes opcode)
Definition WorldPacket.h:39
Player session in the World.
void SendBroadcastText(uint32 entry)
void HandleGossipSelectOptionOpcode(WorldPacket &recvPacket)
void LogoutPlayer(bool save)
Log the player out
AccountData * GetAccountData(AccountDataType type)
void HandleSetDungeonDifficultyOpcode(WorldPacket &recvData)
void HandleSetSelectionOpcode(WorldPacket &recvPacket)
void HandleInspectOpcode(WorldPacket &recvPacket)
void HandleTimeSyncResp(WorldPacket &recvData)
void HandleDiscardedTimeSyncAcks(WorldPacket &recvData)
void HandleCompleteCinematic(WorldPacket &recvPacket)
void HandleSceneCompleted(WorldPacket &recvPacket)
void HandleNextCinematicCamera(WorldPacket &recvPacket)
void HandleViolenceLevel(WorldPacket &recvPacket)
void LogoutRequest(time_t requestTime)
Engage the logout process for the user.
void HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const &friendNote)
void HandlePlayedTime(WorldPacket &recvPacket)
void HandleLogoutRequestOpcode(WorldPacket &recvPacket)
void HandleResetInstancesOpcode(WorldPacket &recvData)
void SendNotification(const char *format,...) ATTR_PRINTF(2
void HandleWorldStateUITimerUpdate(WorldPacket &recvData)
uint32 GetGuidLow() const
Get player guid if available. Use for logging purposes only.
void HandleMoveRootAck(WorldPacket &recvPacket)
void HandleRequestAccountData(WorldPacket &recvPacket)
void HandleWhoisOpcode(WorldPacket &recvData)
AccountTypes GetSecurity() const
void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
void HandleSetActionButtonOpcode(WorldPacket &recvPacket)
void HandleComplainOpcode(WorldPacket &recvData)
void HandleDelIgnoreOpcode(WorldPacket &recvPacket)
void HandleWhoOpcode(WorldPacket &recvPacket)
void SendLoadCUFProfiles()
void HandleMoveTimeSkippedOpcode(WorldPacket &recvData)
void HandleRepopRequestOpcode(WorldPacket &recvPacket)
QueryCallback< PreparedQueryResult, std::string > _addFriendCallback
void HandleCancelMountAuraOpcode(WorldPacket &recvData)
void HandleMovementOpcodes(WorldPacket &recvPacket)
void HandleResurrectResponseOpcode(WorldPacket &recvPacket)
LocaleConstant GetSessionDbcLocale() const
void HandleSelectFactionOpcode(WorldPacket &recvPacket)
void HandleSaveCUFProfiles(WorldPacket &recvPacket)
void SendCrossedInebriationThreshold(ObjectGuid guid, uint32 ItemID, DrunkenState drunkenState)
void HandleGuildAchievementProgressQuery(WorldPacket &recvData)
Player * GetPlayer() const
void HandleDelFriendOpcode(WorldPacket &recvPacket)
void HandleBugOpcode(WorldPacket &recvPacket)
void HandleContactListOpcode(WorldPacket &recvPacket)
void HandlePlayerLogoutOpcode(WorldPacket &recvPacket)
PreparedQueryResultFuture _addIgnoreCallback
void SendPageText(ObjectGuid GameObjectGUID)
void HandleReturnToGraveyard(WorldPacket &recvPacket)
void HandleSetRaidDifficultyOpcode(WorldPacket &recvData)
uint32 GetVirtualRealmID() const
void HandleStandStateChangeOpcode(WorldPacket &recvPacket)
void HandleReadyForAccountDataTimes(WorldPacket &recvData)
void SendTitleEarned(uint32 TitleIndex)
void HandleUpdateMissileTrajectory(WorldPacket &recvPacket)
void HandleLogoutCancelOpcode(WorldPacket &recvPacket)
void HandleMoveUnRootAck(WorldPacket &recvPacket)
bool HasPermission(uint32 permissionId)
void HandleAreaTriggerOpcode(WorldPacket &recvPacket)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleAreaSpiritHealerQueryOpcode(WorldPacket &recvData)
time_t timeLastWhoCommand
uint32 GetAccountId() const
void HandleObjectUpdateFailedOpcode(WorldPacket &recvPacket)
void HandleUpdateAccountData(WorldPacket &recvPacket)
void HandleTogglePvP(WorldPacket &recvPacket)
void HandleRequestHotfix(WorldPacket &recvPacket)
void HandleInstanceLockResponse(WorldPacket &recvPacket)
void HandleSetContactNotesOpcode(WorldPacket &recvPacket)
void HandleFarSightOpcode(WorldPacket &recvData)
Player * _player
int32 HandleEnableNagleAlgorithm()
void HandleSetPvP(WorldPacket &recvPacket)
uint32 GetLatency() const
void HandleSetActionBarToggles(WorldPacket &recvData)
void HandleSetTitleOpcode(WorldPacket &recvData)
void HandleReclaimCorpseOpcode(WorldPacket &recvPacket)
void HandleWorldTeleportOpcode(WorldPacket &recvData)
void HandleAddIgnoreOpcode(WorldPacket &recvPacket)
void HandleAddFriendOpcode(WorldPacket &recvPacket)
void SendSetPhaseShift(std::set< uint32 > const &phaseIds, std::set< uint32 > const &terrainswaps, std::set< uint32 > const &worldAreas)
void SendPlayMusic(uint32 SoundKitID)
void DoLootRelease(uint64 lguid)
void HandleQueryInspectAchievements(WorldPacket &recvData)
void HandleSetTaxiBenchmarkOpcode(WorldPacket &recvData)
void HandleHearthAndResurrect(WorldPacket &recvData)
void SendAccountDataTimes(uint32 mask)
void HandleMoveGravityAck(WorldPacket &recvData)
void HandleRequestCemeteryList(WorldPacket &recvPacket)
void HandleAreaSpiritHealerQueueOpcode(WorldPacket &recvData)
void SendTitleLost(uint32 TitleIndex)
std::string const & GetPlayerName() const
void HandleZoneUpdateOpcode(WorldPacket &recvPacket)
void HandleRequestPetInfoOpcode(WorldPacket &recvData)
void HandleRealmSplitOpcode(WorldPacket &recvData)
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)
void HandleInspectHonorStatsOpcode(WorldPacket &recvPacket)
void HandleFeatherFallAck(WorldPacket &recvData)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
#define DB2_REPLY_GAMEOBJECTS
#define DB2_REPLY_DEVICE_BLACKLIST
#define DB2_REPLY_SPELL_VISUAL_EFFECT_NAME
#define DB2_REPLY_ITEM
#define DB2_REPLY_WB_ACCESS_CONTROL_LIST
#define DB2_REPLY_BATTLE_PET_VISUAL
#define DB2_REPLY_BATTLE_PET_ABILITY_TURN
#define DB2_REPLY_LOCATION
#define DB2_REPLY_BATTLE_PET_ABILITY_STATE
#define DB2_REPLY_ITEM_UPGRADE
#define DB2_REPLY_QUEST_PACKAGE_ITEM
#define DB2_REPLY_SPELL_REAGENTS
#define DB2_REPLY_ITEM_TO_MOUNT_SPELL
#define DB2_REPLY_BATTLE_PET_SPECIES
#define DB2_REPLY_SPELL_VISUAL_KIT
#define DB2_REPLY_PATH_NODE_PROPERTY
#define DB2_REPLY_SCENE_SCRIPT_PACKAGE
#define DB2_REPLY_SPELL_MISSILE
#define DB2_REPLY_BATTLE_PET_ABILITY
#define DB2_REPLY_BATTLE_PET_ABILITY_EFFECT
#define DB2_REPLY_PATH_PROPERTY
#define DB2_REPLY_PATH_NODE
#define DB2_REPLY_WB_PERMISSIONS
#define DB2_REPLY_CREATURE_DIFFICULTY
#define DB2_REPLY_SPELL_VISUAL_MISSILE
#define DB2_REPLY_VIGNETTE
#define DB2_REPLY_SPELL_EFFECT_CAMERA_SHAKES
#define DB2_REPLY_ITEM_TO_BATTLE_PET
#define DB2_REPLY_KEYCHAIN
#define DB2_REPLY_SPELL_VISUAL
#define DB2_REPLY_ITEM_EXTENDED_COST
#define DB2_REPLY_CURVE_POINT
#define DB2_REPLY_BATTLE_PET_STATE
#define DB2_REPLY_SCENE_SCRIPT_PACKAGE_MEMBER
#define DB2_REPLY_ITEM_SPARSE
#define DB2_REPLY_BATTLE_PET_BREED_STATE
#define DB2_REPLY_SCENE_SCRIPT
#define DB2_REPLY_BATTLE_PET_SPECIES_STATE
#define DB2_REPLY_BATTLE_PET_BREED_QUALITY
#define DB2_REPLY_CURVE
#define DB2_REPLY_WB_CERT_BLACKLIST
#define DB2_REPLY_PATH
#define DB2_REPLY_RULE_SET_RAID_LOOT_UPGRADE
#define GLOBAL_CACHE_MASK
#define DB2_REPLY_LOCALE
#define DB2_REPLY_DRIVER_BLACKLIST
#define DB2_REPLY_ITEM_CURRENCY_COST
AccountDataType
#define DB2_REPLY_MAP_CHALLENGE_MODE
#define DB2_REPLY_CREATURE
#define DB2_REPLY_RULE_SET_ITEM_UPGRADE
#define DB2_REPLY_BROADCAST_TEXT
#define DB2_REPLY_SPELL_MISSILE_MOTION
#define DB2_REPLY_BATTLE_PET_SPECIESX_ABILITY
#define DB2_REPLY_BATTLE_PET_EFFECT_PROPERTIES
#define DB2_REPLY_BATTLE_PET_NPC_TEAM_MEMBER
#define DB2_REPLY_WB_CERT_WHITELIST
#define DB2_REPLY_MARKETING_PROMOTIONS_X_LOCALE
#define DB2_REPLY_SPELL_VISUAL_KIT_MODEL_ATTACH
@ SMSG_TITLE_LOST
Definition Opcodes.h:1031
@ SMSG_PAGETEXT
Definition Opcodes.h:841
@ SMSG_COMPLAIN_RESULT
Definition Opcodes.h:619
@ SMSG_WHO
Definition Opcodes.h:1067
@ SMSG_CROSSED_INEBRIATION_THRESHOLD
Definition Opcodes.h:631
@ SMSG_INSPECT_HONOR_STATS
Definition Opcodes.h:721
@ SMSG_WHOIS
Definition Opcodes.h:1068
@ SMSG_UPDATE_ACCOUNT_DATA
Definition Opcodes.h:1044
@ SMSG_LOGOUT_RESPONSE
Definition Opcodes.h:764
@ SMSG_REQUEST_CEMETERY_LIST_RESPONSE
Definition Opcodes.h:935
@ SMSG_PHASE_SHIFT_CHANGE
Definition Opcodes.h:875
@ SMSG_PLAY_MUSIC
Definition Opcodes.h:879
@ SMSG_UPDATE_ACCOUNT_DATA_COMPLETE
Definition Opcodes.h:1045
@ SMSG_TITLE_EARNED
Definition Opcodes.h:1030
@ SMSG_UI_TIME
Definition Opcodes.h:1043
@ SMSG_DB_REPLY
Definition Opcodes.h:632
@ SMSG_REALM_SPLIT
Definition Opcodes.h:930
@ SMSG_LOGOUT_CANCEL_ACK
Definition Opcodes.h:762
@ MSG_MOVE_STOP
Definition Opcodes.h:494
@ SMSG_LOAD_CUF_PROFILES
Definition Opcodes.h:758
@ SMSG_PLAYED_TIME
Definition Opcodes.h:876
#define sWorld
Definition World.h:910
uint32 realmID
Id of the realm.
Definition Main.cpp:73
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition World.h:252
@ RBAC_PERM_ALLOW_GM_FRIEND
Definition RBAC.h:80
@ RBAC_PERM_OPCODE_WHOIS
Definition RBAC.h:83
@ RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS
Definition RBAC.h:75
@ RBAC_PERM_OPCODE_WORLD_TELEPORT
Definition RBAC.h:82
@ RBAC_PERM_TWO_SIDE_WHO_LIST
Definition RBAC.h:68
@ RBAC_PERM_TWO_SIDE_ADD_FRIEND
Definition RBAC.h:69
@ RBAC_PERM_INSTANT_LOGOUT
Definition RBAC.h:41
LoginDatabaseWorkerPool LoginDatabase
Definition Main.cpp:54
std::string Data
uint32 m_flags
float box_orientation
uint32 mapid
float box_x
float radius
float z
float box_z
float box_y
float y
float x
float target_Orientation
Definition ObjectMgr.h:410
Represents a CompactUnitFrame profile.
Definition Player.h:246
uint8 HealthText
Definition Player.h:281
uint16 Unk152
Definition Player.h:290
uint8 Unk147
Definition Player.h:285
uint16 FrameWidth
Definition Player.h:279
uint8 SortBy
Definition Player.h:280
uint16 FrameHeight
Definition Player.h:278
uint8 Unk146
Definition Player.h:284
std::string ProfileName
Definition Player.h:277
uint16 Unk150
Definition Player.h:289
uint8 Unk148
Definition Player.h:286
std::bitset< CUF_BOOL_OPTIONS_COUNT > BoolOptions
Definition Player.h:293
uint16 Unk154
Definition Player.h:291
uint32 maptype
uint32 DiffID
GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]
Definition NPCHandler.h:31
std::string Text_0
Definition NPCHandler.h:20
std::string Text_1
Definition NPCHandler.h:21
float GetPositionZ() const
Definition Object.h:330
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void Relocate(float x, float y)
Definition Object.h:302
time_t EndTimer
Definition Player.h:450
float BoxOrientation
Definition ObjectMgr.h:148