b1ea7212f3
Port From (https://github.com/TrinityCore/TrinityCore/commit/2ea8f5e6fced094f28c45ac84123c85477122567)
669 lines
25 KiB
C#
669 lines
25 KiB
C#
/*
|
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using Framework.Constants;
|
|
using Game.Entities;
|
|
using Game.Groups;
|
|
using Game.Networking;
|
|
using Game.Networking.Packets;
|
|
using System;
|
|
|
|
namespace Game
|
|
{
|
|
public partial class WorldSession
|
|
{
|
|
public void SendPartyResult(PartyOperation operation, string member, PartyResult res, uint val = 0)
|
|
{
|
|
PartyCommandResult packet = new();
|
|
|
|
packet.Name = member;
|
|
packet.Command = (byte)operation;
|
|
packet.Result = (byte)res;
|
|
packet.ResultData = val;
|
|
packet.ResultGUID = ObjectGuid.Empty;
|
|
|
|
SendPacket(packet);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.PartyInvite)]
|
|
void HandlePartyInvite(PartyInviteClient packet)
|
|
{
|
|
Player invitingPlayer = GetPlayer();
|
|
Player invitedPlayer = Global.ObjAccessor.FindPlayerByName(packet.TargetName);
|
|
|
|
// no player
|
|
if (invitedPlayer == null)
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, packet.TargetName, PartyResult.BadPlayerNameS);
|
|
return;
|
|
}
|
|
|
|
// player trying to invite himself (most likely cheating)
|
|
if (invitedPlayer == invitingPlayer)
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.BadPlayerNameS);
|
|
return;
|
|
}
|
|
|
|
// restrict invite to GMs
|
|
if (!WorldConfig.GetBoolValue(WorldCfg.AllowGmGroup) && !invitingPlayer.IsGameMaster() && invitedPlayer.IsGameMaster())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.BadPlayerNameS);
|
|
return;
|
|
}
|
|
|
|
// can't group with
|
|
if (!invitingPlayer.IsGameMaster() && !WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup) && invitingPlayer.GetTeam() != invitedPlayer.GetTeam())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.PlayerWrongFaction);
|
|
return;
|
|
}
|
|
if (invitingPlayer.GetInstanceId() != 0 && invitedPlayer.GetInstanceId() != 0 && invitingPlayer.GetInstanceId() != invitedPlayer.GetInstanceId() && invitingPlayer.GetMapId() == invitedPlayer.GetMapId())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.TargetNotInInstanceS);
|
|
return;
|
|
}
|
|
// just ignore us
|
|
if (invitedPlayer.GetInstanceId() != 0 && invitedPlayer.GetDungeonDifficultyID() != invitingPlayer.GetDungeonDifficultyID())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.IgnoringYouS);
|
|
return;
|
|
}
|
|
|
|
if (invitedPlayer.GetSocial().HasIgnore(invitingPlayer.GetGUID()))
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.IgnoringYouS);
|
|
return;
|
|
}
|
|
|
|
if (!invitedPlayer.GetSocial().HasFriend(invitingPlayer.GetGUID()) && invitingPlayer.GetLevel() < WorldConfig.GetIntValue(WorldCfg.PartyLevelReq))
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.InviteRestricted);
|
|
return;
|
|
}
|
|
|
|
Group group = invitingPlayer.GetGroup();
|
|
if (group != null && group.IsBGGroup())
|
|
group = invitingPlayer.GetOriginalGroup();
|
|
|
|
if (group == null)
|
|
group = invitingPlayer.GetGroupInvite();
|
|
|
|
Group group2 = invitedPlayer.GetGroup();
|
|
if (group2 != null && group2.IsBGGroup())
|
|
group2 = invitedPlayer.GetOriginalGroup();
|
|
|
|
PartyInvite partyInvite;
|
|
// player already in another group or invited
|
|
if (group2 || invitedPlayer.GetGroupInvite())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.AlreadyInGroupS);
|
|
|
|
if (group2)
|
|
{
|
|
// tell the player that they were invited but it failed as they were already in a group
|
|
partyInvite = new PartyInvite();
|
|
partyInvite.Initialize(invitingPlayer, packet.ProposedRoles, false);
|
|
invitedPlayer.SendPacket(partyInvite);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (group)
|
|
{
|
|
// not have permissions for invite
|
|
if (!group.IsLeader(invitingPlayer.GetGUID()) && !group.IsAssistant(invitingPlayer.GetGUID()))
|
|
{
|
|
if (group.IsCreated())
|
|
SendPartyResult(PartyOperation.Invite, "", PartyResult.NotLeader);
|
|
return;
|
|
}
|
|
// not have place
|
|
if (group.IsFull())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, "", PartyResult.GroupFull);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// ok, but group not exist, start a new group
|
|
// but don't create and save the group to the DB until
|
|
// at least one person joins
|
|
if (group == null)
|
|
{
|
|
group = new Group();
|
|
// new group: if can't add then delete
|
|
if (!group.AddLeaderInvite(invitingPlayer))
|
|
return;
|
|
|
|
if (!group.AddInvite(invitedPlayer))
|
|
{
|
|
group.RemoveAllInvites();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// already existed group: if can't add then just leave
|
|
if (!group.AddInvite(invitedPlayer))
|
|
return;
|
|
}
|
|
|
|
partyInvite = new PartyInvite();
|
|
partyInvite.Initialize(invitingPlayer, packet.ProposedRoles, true);
|
|
invitedPlayer.SendPacket(partyInvite);
|
|
|
|
SendPartyResult(PartyOperation.Invite, invitedPlayer.GetName(), PartyResult.Ok);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.PartyInviteResponse)]
|
|
void HandlePartyInviteResponse(PartyInviteResponse packet)
|
|
{
|
|
Group group = GetPlayer().GetGroupInvite();
|
|
if (!group)
|
|
return;
|
|
|
|
if (packet.Accept)
|
|
{
|
|
// Remove player from invitees in any case
|
|
group.RemoveInvite(GetPlayer());
|
|
|
|
if (group.GetLeaderGUID() == GetPlayer().GetGUID())
|
|
{
|
|
Log.outError(LogFilter.Network, "HandleGroupAcceptOpcode: player {0} ({1}) tried to accept an invite to his own group", GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
|
return;
|
|
}
|
|
|
|
// Group is full
|
|
if (group.IsFull())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, "", PartyResult.GroupFull);
|
|
return;
|
|
}
|
|
|
|
Player leader = Global.ObjAccessor.FindPlayer(group.GetLeaderGUID());
|
|
|
|
// Forming a new group, create it
|
|
if (!group.IsCreated())
|
|
{
|
|
// This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
|
|
if (!leader)
|
|
{
|
|
group.RemoveAllInvites();
|
|
return;
|
|
}
|
|
|
|
// If we're about to create a group there really should be a leader present
|
|
Cypher.Assert(leader);
|
|
group.RemoveInvite(leader);
|
|
group.Create(leader);
|
|
Global.GroupMgr.AddGroup(group);
|
|
}
|
|
|
|
// Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
|
|
if (!group.AddMember(GetPlayer()))
|
|
return;
|
|
|
|
group.BroadcastGroupUpdate();
|
|
}
|
|
else
|
|
{
|
|
// Remember leader if online (group will be invalid if group gets disbanded)
|
|
Player leader = Global.ObjAccessor.FindPlayer(group.GetLeaderGUID());
|
|
|
|
// uninvite, group can be deleted
|
|
GetPlayer().UninviteFromGroup();
|
|
|
|
if (!leader || leader.GetSession() == null)
|
|
return;
|
|
|
|
// report
|
|
GroupDecline decline = new(GetPlayer().GetName());
|
|
leader.SendPacket(decline);
|
|
}
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.PartyUninvite)]
|
|
void HandlePartyUninvite(PartyUninvite packet)
|
|
{
|
|
//can't uninvite yourself
|
|
if (packet.TargetGUID == GetPlayer().GetGUID())
|
|
{
|
|
Log.outError(LogFilter.Network, "HandleGroupUninviteGuidOpcode: leader {0}({1}) tried to uninvite himself from the group.",
|
|
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
|
return;
|
|
}
|
|
|
|
PartyResult res = GetPlayer().CanUninviteFromGroup(packet.TargetGUID);
|
|
if (res != PartyResult.Ok)
|
|
{
|
|
SendPartyResult(PartyOperation.UnInvite, "", res);
|
|
return;
|
|
}
|
|
|
|
Group grp = GetPlayer().GetGroup();
|
|
// grp is checked already above in CanUninviteFromGroup()
|
|
Cypher.Assert(grp);
|
|
|
|
if (grp.IsMember(packet.TargetGUID))
|
|
{
|
|
Player.RemoveFromGroup(grp, packet.TargetGUID, RemoveMethod.Kick, GetPlayer().GetGUID(), packet.Reason);
|
|
return;
|
|
}
|
|
Player player = grp.GetInvited(packet.TargetGUID);
|
|
if (player)
|
|
{
|
|
player.UninviteFromGroup();
|
|
return;
|
|
}
|
|
|
|
SendPartyResult(PartyOperation.UnInvite, "", PartyResult.TargetNotInGroupS);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SetPartyLeader, Processing = PacketProcessing.Inplace)]
|
|
void HandleSetPartyLeader(SetPartyLeader packet)
|
|
{
|
|
Player player = Global.ObjAccessor.FindConnectedPlayer(packet.TargetGUID);
|
|
Group group = GetPlayer().GetGroup();
|
|
|
|
if (!group || !player)
|
|
return;
|
|
|
|
if (!group.IsLeader(GetPlayer().GetGUID()) || player.GetGroup() != group)
|
|
return;
|
|
|
|
// Everything's fine, accepted.
|
|
group.ChangeLeader(packet.TargetGUID, packet.PartyIndex);
|
|
group.SendUpdate();
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SetRole)]
|
|
void HandleSetRole(SetRole packet)
|
|
{
|
|
RoleChangedInform roleChangedInform = new();
|
|
|
|
Group group = GetPlayer().GetGroup();
|
|
byte oldRole = (byte)(group ? group.GetLfgRoles(packet.TargetGUID) : 0);
|
|
if (oldRole == packet.Role)
|
|
return;
|
|
|
|
roleChangedInform.PartyIndex = packet.PartyIndex;
|
|
roleChangedInform.From = GetPlayer().GetGUID();
|
|
roleChangedInform.ChangedUnit = packet.TargetGUID;
|
|
roleChangedInform.OldRole = oldRole;
|
|
roleChangedInform.NewRole = packet.Role;
|
|
|
|
if (group)
|
|
{
|
|
group.BroadcastPacket(roleChangedInform, false);
|
|
group.SetLfgRoles(packet.TargetGUID, (LfgRoles)packet.Role);
|
|
}
|
|
else
|
|
SendPacket(roleChangedInform);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.LeaveGroup)]
|
|
void HandleLeaveGroup(LeaveGroup packet)
|
|
{
|
|
Group grp = GetPlayer().GetGroup();
|
|
Group grpInvite = GetPlayer().GetGroupInvite();
|
|
if (grp == null && grpInvite == null)
|
|
return;
|
|
|
|
if (GetPlayer().InBattleground())
|
|
{
|
|
SendPartyResult(PartyOperation.Invite, "", PartyResult.InviteRestricted);
|
|
return;
|
|
}
|
|
|
|
/** error handling **/
|
|
/********************/
|
|
|
|
// everything's fine, do it
|
|
if (grp != null)
|
|
{
|
|
SendPartyResult(PartyOperation.Leave, GetPlayer().GetName(), PartyResult.Ok);
|
|
GetPlayer().RemoveFromGroup(RemoveMethod.Leave);
|
|
}
|
|
else if (grpInvite != null && grpInvite.GetLeaderGUID() == GetPlayer().GetGUID())
|
|
{ // pending group creation being cancelled
|
|
SendPartyResult(PartyOperation.Leave, GetPlayer().GetName(), PartyResult.Ok);
|
|
grpInvite.Disband();
|
|
}
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SetLootMethod)]
|
|
void HandleSetLootMethod(SetLootMethod packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
/** error handling **/
|
|
if (!group.IsLeader(GetPlayer().GetGUID()))
|
|
return;
|
|
|
|
switch (packet.LootMethod)
|
|
{
|
|
case LootMethod.FreeForAll:
|
|
case LootMethod.MasterLoot:
|
|
case LootMethod.GroupLoot:
|
|
case LootMethod.PersonalLoot:
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
if (packet.LootThreshold < ItemQuality.Uncommon || packet.LootThreshold > ItemQuality.Artifact)
|
|
return;
|
|
|
|
if (packet.LootMethod == LootMethod.MasterLoot && !group.IsMember(packet.LootMasterGUID))
|
|
return;
|
|
|
|
// everything's fine, do it
|
|
group.SetLootMethod(packet.LootMethod);
|
|
group.SetMasterLooterGuid(packet.LootMasterGUID);
|
|
group.SetLootThreshold(packet.LootThreshold);
|
|
group.SendUpdate();
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.LootRoll)]
|
|
void HandleLootRoll(LootRoll packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
group.CountRollVote(GetPlayer().GetGUID(), packet.LootObj, (byte)(packet.LootListID - 1), packet.RollType);
|
|
|
|
switch (packet.RollType)
|
|
{
|
|
case RollType.Need:
|
|
GetPlayer().UpdateCriteria(CriteriaTypes.RollNeed, 1);
|
|
break;
|
|
case RollType.Greed:
|
|
GetPlayer().UpdateCriteria(CriteriaTypes.RollGreed, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.MinimapPing)]
|
|
void HandleMinimapPing(MinimapPingClient packet)
|
|
{
|
|
if (!GetPlayer().GetGroup())
|
|
return;
|
|
|
|
MinimapPing minimapPing = new();
|
|
minimapPing.Sender = GetPlayer().GetGUID();
|
|
minimapPing.PositionX = packet.PositionX;
|
|
minimapPing.PositionY = packet.PositionY;
|
|
GetPlayer().GetGroup().BroadcastPacket(minimapPing, true, -1, GetPlayer().GetGUID());
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.RandomRoll)]
|
|
void HandleRandomRoll(RandomRollClient packet)
|
|
{
|
|
if (packet.Min > packet.Max || packet.Max > 10000) // < 32768 for urand call
|
|
return;
|
|
|
|
GetPlayer().DoRandomRoll(packet.Min, packet.Max);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.UpdateRaidTarget)]
|
|
void HandleUpdateRaidTarget(UpdateRaidTarget packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (packet.Symbol == -1) // target icon request
|
|
group.SendTargetIconList(this, packet.PartyIndex);
|
|
else // target icon update
|
|
{
|
|
if (group.IsRaidGroup() && !group.IsLeader(GetPlayer().GetGUID()) && !group.IsAssistant(GetPlayer().GetGUID()))
|
|
return;
|
|
|
|
if (packet.Target.IsPlayer())
|
|
{
|
|
Player target = Global.ObjAccessor.FindConnectedPlayer(packet.Target);
|
|
if (!target || target.IsHostileTo(GetPlayer()))
|
|
return;
|
|
}
|
|
|
|
group.SetTargetIcon((byte)packet.Symbol, packet.Target, GetPlayer().GetGUID(), packet.PartyIndex);
|
|
}
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ConvertRaid)]
|
|
void HandleConvertRaid(ConvertRaid packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (GetPlayer().InBattleground())
|
|
return;
|
|
|
|
// error handling
|
|
if (!group.IsLeader(GetPlayer().GetGUID()) || group.GetMembersCount() < 2)
|
|
return;
|
|
|
|
// everything's fine, do it (is it 0 (PartyOperation.Invite) correct code)
|
|
SendPartyResult(PartyOperation.Invite, "", PartyResult.Ok);
|
|
|
|
// New 4.x: it is now possible to convert a raid to a group if member count is 5 or less
|
|
if (packet.Raid)
|
|
group.ConvertToRaid();
|
|
else
|
|
group.ConvertToGroup();
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.RequestPartyJoinUpdates)]
|
|
void HandleRequestPartyJoinUpdates(RequestPartyJoinUpdates packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
group.SendTargetIconList(this, packet.PartyIndex);
|
|
group.SendRaidMarkersChanged(this, packet.PartyIndex);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ChangeSubGroup, Processing = PacketProcessing.ThreadUnsafe)]
|
|
void HandleChangeSubGroup(ChangeSubGroup packet)
|
|
{
|
|
// we will get correct for group here, so we don't have to check if group is BG raid
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (packet.NewSubGroup >= MapConst.MaxRaidSubGroups)
|
|
return;
|
|
|
|
ObjectGuid senderGuid = GetPlayer().GetGUID();
|
|
if (!group.IsLeader(senderGuid) && !group.IsAssistant(senderGuid))
|
|
return;
|
|
|
|
if (!group.HasFreeSlotSubGroup(packet.NewSubGroup))
|
|
return;
|
|
|
|
group.ChangeMembersGroup(packet.TargetGUID, packet.NewSubGroup);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SwapSubGroups, Processing = PacketProcessing.ThreadUnsafe)]
|
|
void HandleSwapSubGroups(SwapSubGroups packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
ObjectGuid senderGuid = GetPlayer().GetGUID();
|
|
if (!group.IsLeader(senderGuid) && !group.IsAssistant(senderGuid))
|
|
return;
|
|
|
|
group.SwapMembersGroups(packet.FirstTarget, packet.SecondTarget);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SetAssistantLeader)]
|
|
void HandleSetAssistantLeader(SetAssistantLeader packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (!group.IsLeader(GetPlayer().GetGUID()))
|
|
return;
|
|
|
|
group.SetGroupMemberFlag(packet.Target, packet.Apply, GroupMemberFlags.Assistant);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SetPartyAssignment)]
|
|
void HandleSetPartyAssignment(SetPartyAssignment packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
ObjectGuid senderGuid = GetPlayer().GetGUID();
|
|
if (!group.IsLeader(senderGuid) && !group.IsAssistant(senderGuid))
|
|
return;
|
|
|
|
switch ((GroupMemberAssignment)packet.Assignment)
|
|
{
|
|
case GroupMemberAssignment.MainAssist:
|
|
group.RemoveUniqueGroupMemberFlag(GroupMemberFlags.MainAssist);
|
|
group.SetGroupMemberFlag(packet.Target, packet.Set, GroupMemberFlags.MainAssist);
|
|
break;
|
|
case GroupMemberAssignment.MainTank:
|
|
group.RemoveUniqueGroupMemberFlag(GroupMemberFlags.MainTank); // Remove main assist flag from current if any.
|
|
group.SetGroupMemberFlag(packet.Target, packet.Set, GroupMemberFlags.MainTank);
|
|
break;
|
|
}
|
|
|
|
group.SendUpdate();
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.DoReadyCheck)]
|
|
void HandleDoReadyCheckOpcode(DoReadyCheck packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
/** error handling **/
|
|
if (!group.IsLeader(GetPlayer().GetGUID()) && !group.IsAssistant(GetPlayer().GetGUID()))
|
|
return;
|
|
|
|
// everything's fine, do it
|
|
group.StartReadyCheck(GetPlayer().GetGUID(), packet.PartyIndex, TimeSpan.FromMilliseconds(MapConst.ReadycheckDuration));
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ReadyCheckResponse, Processing = PacketProcessing.Inplace)]
|
|
void HandleReadyCheckResponseOpcode(ReadyCheckResponseClient packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
// everything's fine, do it
|
|
group.SetMemberReadyCheck(GetPlayer().GetGUID(), packet.IsReady);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.RequestPartyMemberStats)]
|
|
void HandleRequestPartyMemberStats(RequestPartyMemberStats packet)
|
|
{
|
|
PartyMemberFullState partyMemberStats = new();
|
|
|
|
Player player = Global.ObjAccessor.FindConnectedPlayer(packet.TargetGUID);
|
|
if (!player)
|
|
{
|
|
partyMemberStats.MemberGuid = packet.TargetGUID;
|
|
partyMemberStats.MemberStats.Status = GroupMemberOnlineStatus.Offline;
|
|
}
|
|
else
|
|
partyMemberStats.Initialize(player);
|
|
|
|
SendPacket(partyMemberStats);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.RequestRaidInfo)]
|
|
void HandleRequestRaidInfo(RequestRaidInfo packet)
|
|
{
|
|
// every time the player checks the character screen
|
|
GetPlayer().SendRaidInfo();
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.OptOutOfLoot, Processing = PacketProcessing.Inplace)]
|
|
void HandleOptOutOfLoot(OptOutOfLoot packet)
|
|
{
|
|
// ignore if player not loaded
|
|
if (!GetPlayer()) // needed because STATUS_AUTHED
|
|
{
|
|
if (packet.PassOnLoot)
|
|
Log.outError(LogFilter.Network, "CMSG_OPT_OUT_OF_LOOT value<>0 for not-loaded character!");
|
|
return;
|
|
}
|
|
|
|
GetPlayer().SetPassOnGroupLoot(packet.PassOnLoot);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.InitiateRolePoll)]
|
|
void HandleInitiateRolePoll(InitiateRolePoll packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
ObjectGuid guid = GetPlayer().GetGUID();
|
|
if (!group.IsLeader(guid) && !group.IsAssistant(guid))
|
|
return;
|
|
|
|
RolePollInform rolePollInform = new();
|
|
rolePollInform.From = guid;
|
|
rolePollInform.PartyIndex = packet.PartyIndex;
|
|
group.BroadcastPacket(rolePollInform, true);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.SetEveryoneIsAssistant)]
|
|
void HandleSetEveryoneIsAssistant(SetEveryoneIsAssistant packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (!group.IsLeader(GetPlayer().GetGUID()))
|
|
return;
|
|
|
|
group.SetEveryoneIsAssistant(packet.EveryoneIsAssistant);
|
|
}
|
|
|
|
[WorldPacketHandler(ClientOpcodes.ClearRaidMarker)]
|
|
void HandleClearRaidMarker(ClearRaidMarker packet)
|
|
{
|
|
Group group = GetPlayer().GetGroup();
|
|
if (!group)
|
|
return;
|
|
|
|
if (group.IsRaidGroup() && !group.IsLeader(GetPlayer().GetGUID()) && !group.IsAssistant(GetPlayer().GetGUID()))
|
|
return;
|
|
|
|
group.DeleteRaidMarker(packet.MarkerId);
|
|
}
|
|
}
|
|
}
|