[7770] Prevent access to possible deleted aura's spell proto in Aura::HandleModStealth.
[AHbot.git] / src / game / GroupHandler.cpp
blobb7c55e664db2a655e3e20257a48cdea034ff2b67
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "Opcodes.h"
22 #include "Log.h"
23 #include "WorldPacket.h"
24 #include "WorldSession.h"
25 #include "World.h"
26 #include "ObjectMgr.h"
27 #include "Player.h"
28 #include "Group.h"
29 #include "SocialMgr.h"
30 #include "Util.h"
32 /* differeces from off:
33 -you can uninvite yourself - is is useful
34 -you can accept invitation even if leader went offline
36 /* todo:
37 -group_destroyed msg is sent but not shown
38 -reduce xp gaining when in raid group
39 -quest sharing has to be corrected
40 -FIX sending PartyMemberStats
43 void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res)
45 WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1));
46 data << (uint32)operation;
47 data << member;
48 data << (uint32)res;
50 SendPacket( &data );
53 void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
55 std::string membername;
56 recv_data >> membername;
58 // attempt add selected player
60 // cheating
61 if(!normalizePlayerName(membername))
63 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
64 return;
67 Player *player = objmgr.GetPlayer(membername.c_str());
69 // no player
70 if(!player)
72 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET);
73 return;
76 // can't group with
77 if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
79 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY);
80 return;
82 if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
84 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE);
85 return;
87 // just ignore us
88 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
90 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
91 return;
94 Group *group = GetPlayer()->GetGroup();
95 if( group && group->isBGGroup() )
96 group = GetPlayer()->GetOriginalGroup();
98 Group *group2 = player->GetGroup();
99 if( group2 && group2->isBGGroup() )
100 group2 = player->GetOriginalGroup();
101 // player already in another group or invited
102 if( group2 || player->GetGroupInvite() )
104 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP);
105 return;
108 if(group)
110 // not have permissions for invite
111 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
113 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
114 return;
116 // not have place
117 if(group->IsFull())
119 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
120 return;
124 // ok, but group not exist, start a new group
125 // but don't create and save the group to the DB until
126 // at least one person joins
127 if(!group)
129 group = new Group;
130 // new group: if can't add then delete
131 if(!group->AddLeaderInvite(GetPlayer()))
133 delete group;
134 return;
136 if(!group->AddInvite(player))
138 delete group;
139 return;
142 else
144 // already existed group: if can't add then just leave
145 if(!group->AddInvite(player))
147 return;
151 // ok, we do it
152 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
153 data << uint8(1); // ok
154 data << GetPlayer()->GetName();
155 player->GetSession()->SendPacket(&data);
157 SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK);
160 void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
162 Group *group = GetPlayer()->GetGroupInvite();
163 if (!group) return;
165 if(group->GetLeaderGUID() == GetPlayer()->GetGUID())
167 sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
168 return;
171 // remove in from ivites in any case
172 group->RemoveInvite(GetPlayer());
174 /** error handling **/
175 /********************/
177 // not have place
178 if(group->IsFull())
180 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL);
181 return;
184 Player* leader = objmgr.GetPlayer(group->GetLeaderGUID());
186 // forming a new group, create it
187 if(!group->IsCreated())
189 if( leader )
190 group->RemoveInvite(leader);
191 group->Create(group->GetLeaderGUID(), group->GetLeaderName());
192 objmgr.AddGroup(group);
195 // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
196 if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
197 return;
201 void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
203 Group *group = GetPlayer()->GetGroupInvite();
204 if (!group) return;
206 // remember leader if online
207 Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
209 // uninvite, group can be deleted
210 GetPlayer()->UninviteFromGroup();
212 if(!leader || !leader->GetSession())
213 return;
215 // report
216 WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
217 data << GetPlayer()->GetName();
218 leader->GetSession()->SendPacket( &data );
221 void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
223 CHECK_PACKET_SIZE(recv_data,8);
225 uint64 guid;
226 recv_data >> guid;
228 //can't uninvite yourself
229 if(guid == GetPlayer()->GetGUID())
231 sLog.outError("WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
232 return;
235 PartyResult res = GetPlayer()->CanUninviteFromGroup();
236 if(res != PARTY_RESULT_OK)
238 SendPartyResult(PARTY_OP_LEAVE, "", res);
239 return;
242 Group* grp = GetPlayer()->GetGroup();
243 if(!grp)
244 return;
246 if(grp->IsMember(guid))
248 Player::RemoveFromGroup(grp,guid);
249 return;
252 if(Player* plr = grp->GetInvited(guid))
254 plr->UninviteFromGroup();
255 return;
258 SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_NOT_IN_YOUR_PARTY);
261 void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
263 CHECK_PACKET_SIZE(recv_data,1);
265 std::string membername;
266 recv_data >> membername;
268 // player not found
269 if(!normalizePlayerName(membername))
270 return;
272 // can't uninvite yourself
273 if(GetPlayer()->GetName() == membername)
275 sLog.outError("WorldSession::HandleGroupUninviteNameOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
276 return;
279 PartyResult res = GetPlayer()->CanUninviteFromGroup();
280 if(res != PARTY_RESULT_OK)
282 SendPartyResult(PARTY_OP_LEAVE, "", res);
283 return;
286 Group* grp = GetPlayer()->GetGroup();
287 if(!grp)
288 return;
290 if(uint64 guid = grp->GetMemberGUID(membername))
292 Player::RemoveFromGroup(grp,guid);
293 return;
296 if(Player* plr = grp->GetInvited(membername))
298 plr->UninviteFromGroup();
299 return;
302 SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
305 void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
307 CHECK_PACKET_SIZE(recv_data,8);
309 Group *group = GetPlayer()->GetGroup();
310 if(!group)
311 return;
313 uint64 guid;
314 recv_data >> guid;
316 Player *player = objmgr.GetPlayer(guid);
318 /** error handling **/
319 if (!player || !group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group)
320 return;
321 /********************/
323 // everything's fine, do it
324 group->ChangeLeader(guid);
327 void WorldSession::HandleGroupLeaveOpcode( WorldPacket & /*recv_data*/ )
329 if(!GetPlayer()->GetGroup())
330 return;
332 if(_player->InBattleGround())
334 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
335 return;
338 /** error handling **/
339 /********************/
341 // everything's fine, do it
342 SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
344 GetPlayer()->RemoveFromGroup();
347 void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
349 CHECK_PACKET_SIZE(recv_data,4+8+4);
351 Group *group = GetPlayer()->GetGroup();
352 if(!group)
353 return;
355 uint32 lootMethod;
356 uint64 lootMaster;
357 uint32 lootThreshold;
358 recv_data >> lootMethod >> lootMaster >> lootThreshold;
360 /** error handling **/
361 if(!group->IsLeader(GetPlayer()->GetGUID()))
362 return;
363 /********************/
365 // everything's fine, do it
366 group->SetLootMethod((LootMethod)lootMethod);
367 group->SetLooterGuid(lootMaster);
368 group->SetLootThreshold((ItemQualities)lootThreshold);
369 group->SendUpdate();
372 void WorldSession::HandleLootRoll( WorldPacket &recv_data )
374 CHECK_PACKET_SIZE(recv_data,8+4+1);
376 if(!GetPlayer()->GetGroup())
377 return;
379 uint64 Guid;
380 uint32 NumberOfPlayers;
381 uint8 Choise;
382 recv_data >> Guid; //guid of the item rolled
383 recv_data >> NumberOfPlayers;
384 recv_data >> Choise; //0: pass, 1: need, 2: greed
386 //sLog.outDebug("WORLD RECIEVE CMSG_LOOT_ROLL, From:%u, Numberofplayers:%u, Choise:%u", (uint32)Guid, NumberOfPlayers, Choise);
388 Group* group = GetPlayer()->GetGroup();
389 if(!group)
390 return;
392 // everything's fine, do it
393 group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise);
396 void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
398 CHECK_PACKET_SIZE(recv_data,4+4);
400 if(!GetPlayer()->GetGroup())
401 return;
403 float x, y;
404 recv_data >> x;
405 recv_data >> y;
407 //sLog.outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
409 /** error handling **/
410 /********************/
412 // everything's fine, do it
413 WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
414 data << GetPlayer()->GetGUID();
415 data << x;
416 data << y;
417 GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
420 void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
422 CHECK_PACKET_SIZE(recv_data,4+4);
424 uint32 minimum, maximum, roll;
425 recv_data >> minimum;
426 recv_data >> maximum;
428 /** error handling **/
429 if(minimum > maximum || maximum > 10000) // < 32768 for urand call
430 return;
431 /********************/
433 // everything's fine, do it
434 roll = urand(minimum, maximum);
436 //sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
438 WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
439 data << minimum;
440 data << maximum;
441 data << roll;
442 data << GetPlayer()->GetGUID();
443 if(GetPlayer()->GetGroup())
444 GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
445 else
446 SendPacket(&data);
449 void WorldSession::HandleRaidIconTargetOpcode( WorldPacket & recv_data )
451 CHECK_PACKET_SIZE(recv_data,1);
453 Group *group = GetPlayer()->GetGroup();
454 if(!group)
455 return;
457 uint8 x;
458 recv_data >> x;
460 /** error handling **/
461 /********************/
463 // everything's fine, do it
464 if(x == 0xFF) // target icon request
466 group->SendTargetIconList(this);
468 else // target icon update
470 // recheck
471 CHECK_PACKET_SIZE(recv_data,1+8);
473 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
474 return;
476 uint64 guid;
477 recv_data >> guid;
478 group->SetTargetIcon(x, guid);
482 void WorldSession::HandleRaidConvertOpcode( WorldPacket & /*recv_data*/ )
484 Group *group = GetPlayer()->GetGroup();
485 if(!group)
486 return;
488 if(_player->InBattleGround())
489 return;
491 /** error handling **/
492 if(!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
493 return;
494 /********************/
496 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
497 SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_OK);
498 group->ConvertToRaid();
501 void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
503 CHECK_PACKET_SIZE(recv_data,1+1);
505 // we will get correct pointer for group here, so we don't have to check if group is BG raid
506 Group *group = GetPlayer()->GetGroup();
507 if(!group)
508 return;
510 std::string name;
511 uint8 groupNr;
512 recv_data >> name;
514 // recheck
515 CHECK_PACKET_SIZE(recv_data,(name.size()+1)+1);
517 recv_data >> groupNr;
519 /** error handling **/
520 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
521 return;
523 if (!group->HasFreeSlotSubGroup(groupNr))
524 return;
525 /********************/
527 // everything's fine, do it
528 group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
531 void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data )
533 CHECK_PACKET_SIZE(recv_data,8+1);
535 Group *group = GetPlayer()->GetGroup();
536 if(!group)
537 return;
539 uint64 guid;
540 uint8 flag;
541 recv_data >> guid;
542 recv_data >> flag;
544 /** error handling **/
545 if(!group->IsLeader(GetPlayer()->GetGUID()))
546 return;
547 /********************/
549 // everything's fine, do it
550 group->SetAssistant(guid, (flag==0?false:true));
553 void WorldSession::HandleGroupPromoteOpcode( WorldPacket & recv_data )
555 CHECK_PACKET_SIZE(recv_data, 1+1+8);
557 Group *group = GetPlayer()->GetGroup();
558 if(!group)
559 return;
561 uint8 flag1, flag2;
562 uint64 guid;
563 recv_data >> flag1 >> flag2;
564 recv_data >> guid;
565 // if(flag1) Main Assist
566 // 0x4
567 // if(flag2) Main Tank
568 // 0x2
570 /** error handling **/
571 if(!group->IsLeader(GetPlayer()->GetGUID()))
572 return;
573 /********************/
575 // everything's fine, do it
576 if(flag1 == 1)
577 group->SetMainAssistant(guid);
578 if(flag2 == 1)
579 group->SetMainTank(guid);
582 void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data )
584 Group *group = GetPlayer()->GetGroup();
585 if(!group)
586 return;
588 if(recv_data.empty()) // request
590 /** error handling **/
591 if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
592 return;
593 /********************/
595 // everything's fine, do it
596 WorldPacket data(MSG_RAID_READY_CHECK, 8);
597 data << GetPlayer()->GetGUID();
598 group->BroadcastPacket(&data, false, -1);
600 group->OfflineReadyCheck();
602 else // answer
604 uint8 state;
605 recv_data >> state;
607 // everything's fine, do it
608 WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9);
609 data << GetPlayer()->GetGUID();
610 data << state;
611 group->BroadcastReadyCheck(&data);
615 void WorldSession::HandleRaidReadyCheckFinishOpcode( WorldPacket & /*recv_data*/ )
617 //Group* group = GetPlayer()->GetGroup();
618 //if(!group)
619 // return;
621 //if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
622 // return;
624 // Is any reaction need?
627 void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
629 uint32 mask = player->GetGroupUpdateFlag();
631 if (mask == GROUP_UPDATE_FLAG_NONE)
632 return;
634 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
635 mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
637 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
638 mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);
640 uint32 byteCount = 0;
641 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
642 if (mask & (1 << i))
643 byteCount += GroupUpdateLength[i];
645 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
646 data->append(player->GetPackGUID());
647 *data << (uint32) mask;
649 if (mask & GROUP_UPDATE_FLAG_STATUS)
651 if (player)
653 if (player->IsPvP())
654 *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
655 else
656 *data << (uint16) MEMBER_STATUS_ONLINE;
658 else
659 *data << (uint16) MEMBER_STATUS_OFFLINE;
662 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
663 *data << (uint32) player->GetHealth();
665 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
666 *data << (uint32) player->GetMaxHealth();
668 Powers powerType = player->getPowerType();
669 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
670 *data << (uint8) powerType;
672 if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
673 *data << (uint16) player->GetPower(powerType);
675 if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
676 *data << (uint16) player->GetMaxPower(powerType);
678 if (mask & GROUP_UPDATE_FLAG_LEVEL)
679 *data << (uint16) player->getLevel();
681 if (mask & GROUP_UPDATE_FLAG_ZONE)
682 *data << (uint16) player->GetZoneId();
684 if (mask & GROUP_UPDATE_FLAG_POSITION)
685 *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY();
687 if (mask & GROUP_UPDATE_FLAG_AURAS)
689 const uint64& auramask = player->GetAuraUpdateMask();
690 *data << uint64(auramask);
691 for(uint32 i = 0; i < MAX_AURAS; ++i)
693 if(auramask & (uint64(1) << i))
695 *data << uint32(player->GetVisibleAura(i));
696 *data << uint8(1);
701 Pet *pet = player->GetPet();
702 if (mask & GROUP_UPDATE_FLAG_PET_GUID)
704 if(pet)
705 *data << (uint64) pet->GetGUID();
706 else
707 *data << (uint64) 0;
710 if (mask & GROUP_UPDATE_FLAG_PET_NAME)
712 if(pet)
713 *data << pet->GetName();
714 else
715 *data << (uint8) 0;
718 if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
720 if(pet)
721 *data << (uint16) pet->GetDisplayId();
722 else
723 *data << (uint16) 0;
726 if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
728 if(pet)
729 *data << (uint32) pet->GetHealth();
730 else
731 *data << (uint32) 0;
734 if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
736 if(pet)
737 *data << (uint32) pet->GetMaxHealth();
738 else
739 *data << (uint32) 0;
742 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
744 if(pet)
745 *data << (uint8) pet->getPowerType();
746 else
747 *data << (uint8) 0;
750 if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
752 if(pet)
753 *data << (uint16) pet->GetPower(pet->getPowerType());
754 else
755 *data << (uint16) 0;
758 if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
760 if(pet)
761 *data << (uint16) pet->GetMaxPower(pet->getPowerType());
762 else
763 *data << (uint16) 0;
766 if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
768 if(pet)
770 const uint64& auramask = pet->GetAuraUpdateMask();
771 *data << uint64(auramask);
772 for(uint32 i = 0; i < MAX_AURAS; ++i)
774 if(auramask & (uint64(1) << i))
776 *data << uint32(pet->GetVisibleAura(i));
777 *data << uint8(1);
781 else
782 *data << (uint64) 0;
786 /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
787 void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
789 CHECK_PACKET_SIZE(recv_data, 8);
791 sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
792 uint64 Guid;
793 recv_data >> Guid;
795 Player *player = objmgr.GetPlayer(Guid);
796 if(!player)
798 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
799 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
800 data.appendPackGUID(Guid);
801 data << (uint32) GROUP_UPDATE_FLAG_STATUS;
802 data << (uint16) MEMBER_STATUS_OFFLINE;
803 SendPacket(&data);
804 return;
807 Pet *pet = player->GetPet();
809 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
810 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
811 data.append(player->GetPackGUID());
813 uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
814 if(pet)
815 mask1 = 0x7FFFFFFF; // for hunters and other classes with pets
817 Powers powerType = player->getPowerType();
818 data << (uint32) mask1; // group update mask
819 data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
820 data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
821 data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
822 data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
823 data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
824 data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
825 data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL
826 data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE
827 data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION
828 data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION
830 uint64 auramask = 0;
831 size_t maskPos = data.wpos();
832 data << (uint64) auramask; // placeholder
833 for(uint8 i = 0; i < MAX_AURAS; ++i)
835 if(uint32 aura = player->GetVisibleAura(i))
837 auramask |= (uint64(1) << i);
838 data << (uint32) aura;
839 data << (uint8) 1;
842 data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
844 if(pet)
846 Powers petpowertype = pet->getPowerType();
847 data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
848 data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
849 data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
850 data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
851 data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
852 data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
853 data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
854 data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
856 uint64 petauramask = 0;
857 size_t petMaskPos = data.wpos();
858 data << (uint64) petauramask; // placeholder
859 for(uint8 i = 0; i < MAX_AURAS; ++i)
861 if(uint32 petaura = pet->GetVisibleAura(i))
863 petauramask |= (uint64(1) << i);
864 data << (uint32) petaura;
865 data << (uint8) 1;
868 data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS
870 else
872 data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME
873 data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS
876 SendPacket(&data);
879 /*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ )
881 // every time the player checks the character screen
882 _player->SendRaidInfo();
885 /*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
887 sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
890 void WorldSession::HandleGroupPassOnLootOpcode( WorldPacket & recv_data )
892 CHECK_PACKET_SIZE(recv_data, 4);
894 sLog.outDebug("WORLD: Received CMSG_GROUP_PASS_ON_LOOT");
896 uint32 unkn;
897 recv_data >> unkn;
899 // ignore if player not loaded
900 if(!GetPlayer()) // needed because STATUS_AUTHED
902 if(unkn!=0)
903 sLog.outError("CMSG_GROUP_PASS_ON_LOOT value<>0 for not-loaded character!");
904 return;
907 if(unkn!=0)
908 sLog.outError("CMSG_GROUP_PASS_ON_LOOT: activation not implemented!");