/// <summary>Handles an incoming request for a group member status</summary> /// <param name="client">the Session the incoming packet belongs to</param> /// <param name="packet">the full packet</param> public static void RequestPartyMemberStats(IRealmClient client, RealmPacketIn packet) { EntityId entityId = packet.ReadEntityId(); Group group = client.ActiveCharacter.Group; if (group == null) { return; } GroupMember member = group.GetMember(entityId.Low); if (member == null) { return; } GroupUpdateFlags groupUpdateFlags = GroupUpdateFlags.None; GroupUpdateFlags flags = member.Character == null ? groupUpdateFlags | GroupUpdateFlags.Status : groupUpdateFlags | GroupUpdateFlags.UpdateFull; SendPartyMemberStatsFull(client, member, flags); }
/// <summary> /// Sends the requested party member stats data to the client /// </summary> /// <param name="client">realm client</param> /// <param name="member">The character whose stats is going to be retrieved</param> /// <param name="flags">The stats to be retrieved from the <paramref name="member" /></param> private static void SendPartyMemberStatsInternal(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags, RealmServerOpCode opcode) { using (RealmPacketOut packet = new RealmPacketOut(opcode)) { if (opcode == RealmServerOpCode.SMSG_PARTY_MEMBER_STATS_FULL) { packet.Write((byte)0); } member.WriteIdPacked(packet); if (!member.IsOnline) { packet.WriteUShort((ushort)0); client.Send(packet, false); } else { packet.Write((uint)flags); Character character = member.Character; if (flags.HasFlag(GroupUpdateFlags.Status)) { packet.Write((ushort)character.Status); } if (flags.HasFlag(GroupUpdateFlags.Health)) { packet.Write(character.Health); } if (flags.HasFlag(GroupUpdateFlags.MaxHealth)) { packet.Write(character.MaxHealth); } if (flags.HasFlag(GroupUpdateFlags.PowerType)) { packet.Write((byte)character.PowerType); } if (flags.HasFlag(GroupUpdateFlags.Power)) { packet.Write((ushort)character.Power); } if (flags.HasFlag(GroupUpdateFlags.MaxPower)) { packet.Write((ushort)character.MaxPower); } if (flags.HasFlag(GroupUpdateFlags.Level)) { packet.Write((ushort)character.Level); } if (flags.HasFlag(GroupUpdateFlags.ZoneId)) { packet.Write(character.Zone != null ? (ushort)character.Zone.Id : (ushort)0); } if (flags.HasFlag(GroupUpdateFlags.Position)) { packet.Write((ushort)character.Position.X); packet.Write((ushort)character.Position.Y); } if (flags.HasFlag(GroupUpdateFlags.Auras)) { ulong auraUpdateMask = character.AuraUpdateMask; packet.Write(auraUpdateMask); for (byte index = 0; index < (byte)56; ++index) { if (((long)auraUpdateMask & 1L << index) != 0L) { Aura at = character.Auras.GetAt(index); packet.Write(at.Spell.Id); packet.Write((byte)at.Flags); } } } NPC activePet = character.ActivePet; if (activePet == null) { packet.Write((byte)0); packet.Write(0UL); client.Send(packet, false); } else { if (flags.HasFlag(GroupUpdateFlags.PetGuid)) { packet.Write(activePet.EntityId); } if (flags.HasFlag(GroupUpdateFlags.PetName)) { packet.WriteCString(activePet.Name); } if (flags.HasFlag(GroupUpdateFlags.PetDisplayId)) { packet.Write((ushort)activePet.DisplayId); } if (flags.HasFlag(GroupUpdateFlags.PetHealth)) { packet.Write(activePet.Health); } if (flags.HasFlag(GroupUpdateFlags.PetMaxHealth)) { packet.Write(activePet.MaxHealth); } if (flags.HasFlag(GroupUpdateFlags.PetPowerType)) { packet.Write((byte)activePet.PowerType); } if (flags.HasFlag(GroupUpdateFlags.PetPower)) { packet.Write((ushort)activePet.Power); } if (flags.HasFlag(GroupUpdateFlags.PetMaxPower)) { packet.Write((ushort)activePet.MaxPower); } if (flags.HasFlag(GroupUpdateFlags.PetAuras)) { ulong auraUpdateMask = activePet.AuraUpdateMask; packet.Write(auraUpdateMask); for (byte index = 0; index < (byte)56; ++index) { if (((long)auraUpdateMask & 1L << index) != 0L) { Aura at = activePet.Auras.GetAt(index); packet.Write(at.Spell.Id); packet.Write((byte)at.Flags); } } } client.Send(packet, false); } } } }
/// <summary> /// Sends the requested party member stats data to the client /// </summary> /// <param name="client">realm client</param> /// <param name="member">The character whose stats is going to be retrieved</param> /// <param name="flags">The stats to be retrieved from the <paramref name="member" /></param> public static void SendPartyMemberStats(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags) { SendPartyMemberStatsInternal(client, member, flags, RealmServerOpCode.SMSG_PARTY_MEMBER_STATS); }
/// <summary> /// Sends the requested party member stats data to the client /// </summary> /// <param name="client">realm client</param> /// <param name="member">The character whose stats is going to be retrieved</param> /// <param name="flags">The stats to be retrieved from the <paramref name="member"/></param> private static void SendPartyMemberStatsInternal(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags, RealmServerOpCode opcode) { using (var packet = new RealmPacketOut(opcode)) { if (opcode == RealmServerOpCode.SMSG_PARTY_MEMBER_STATS_FULL) { packet.Write((byte)0); //arena something } member.WriteIdPacked(packet); if (!member.IsOnline) { packet.WriteUShort((ushort)CharacterStatus.OFFLINE); client.Send(packet); return; } packet.Write((uint)flags); var chr = member.Character; if (flags.HasFlag(GroupUpdateFlags.Status)) { packet.Write((ushort)chr.Status); } if (flags.HasFlag(GroupUpdateFlags.Health)) { packet.Write(chr.Health); } if (flags.HasFlag(GroupUpdateFlags.MaxHealth)) { packet.Write(chr.MaxHealth); } if (flags.HasFlag(GroupUpdateFlags.PowerType)) { packet.Write((byte)chr.PowerType); } if (flags.HasFlag(GroupUpdateFlags.Power)) { packet.Write((ushort)chr.Power); } if (flags.HasFlag(GroupUpdateFlags.MaxPower)) { packet.Write((ushort)chr.MaxPower); } if (flags.HasFlag(GroupUpdateFlags.Level)) { packet.Write((ushort)chr.Level); } if (flags.HasFlag(GroupUpdateFlags.ZoneId)) { packet.Write((ushort)(chr.Zone != null ? chr.Zone.Id : ZoneId.None)); } if (flags.HasFlag(GroupUpdateFlags.Position)) { packet.Write((ushort)chr.Position.X); packet.Write((ushort)chr.Position.Y); } if (flags.HasFlag(GroupUpdateFlags.Auras)) { ulong auraMask = chr.AuraUpdateMask; packet.Write(auraMask); Aura currAura; for (byte i = 0; i < AuraHandler.MaxAuras; ++i) { if ((auraMask & ((ulong)1 << i)) != 0) { currAura = chr.Auras.GetAt(i); packet.Write(currAura.Spell.Id); packet.Write((byte)currAura.Flags); } } } NPC targetPet = chr.ActivePet; if (targetPet == null) //no pet { packet.Write((byte)0); //name packet.Write(0UL); //auras client.Send(packet); return; } if (flags.HasFlag(GroupUpdateFlags.PetGuid)) { packet.Write(targetPet.EntityId); } if (flags.HasFlag(GroupUpdateFlags.PetName)) { packet.WriteCString(targetPet.Name); } if (flags.HasFlag(GroupUpdateFlags.PetDisplayId)) { packet.Write((ushort)targetPet.DisplayId); } if (flags.HasFlag(GroupUpdateFlags.PetHealth)) { packet.Write(targetPet.Health); } if (flags.HasFlag(GroupUpdateFlags.PetMaxHealth)) { packet.Write(targetPet.MaxHealth); } if (flags.HasFlag(GroupUpdateFlags.PetPowerType)) { packet.Write((byte)targetPet.PowerType); } if (flags.HasFlag(GroupUpdateFlags.PetPower)) { packet.Write((ushort)targetPet.Power); } if (flags.HasFlag(GroupUpdateFlags.PetMaxPower)) { packet.Write((ushort)targetPet.MaxPower); } if (flags.HasFlag(GroupUpdateFlags.PetAuras)) { ulong auraMask = targetPet.AuraUpdateMask; packet.Write(auraMask); Aura currAura; for (byte i = 0; i < AuraHandler.MaxAuras; ++i) { if ((auraMask & ((ulong)1 << i)) != 0) { currAura = targetPet.Auras.GetAt(i);//chr.Auras.GetAt(i); packet.Write(currAura.Spell.Id); packet.Write((byte)currAura.Flags); } } } client.Send(packet); } }
/// <summary> /// Sends the requested party member stats data to the client /// </summary> /// <param name="client">realm client</param> /// <param name="member">The character whose stats is going to be retrieved</param> /// <param name="flags">The stats to be retrieved from the <paramref name="member"/></param> public static void SendPartyMemberStats(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags) { SendPartyMemberStatsInternal(client, member, flags, RealmServerOpCode.SMSG_PARTY_MEMBER_STATS); }
public void RemoveGroupUpdateFlag(GroupUpdateFlags flag) { m_groupUpdateMask &= ~flag; }
public void SetGroupUpdateFlag(GroupUpdateFlags flag) { m_groupUpdateMask |= flag; }
/// <summary> /// Sends the requested party member stats data to the client /// </summary> /// <param name="client">realm client</param> /// <param name="member">The character whose stats is going to be retrieved</param> /// <param name="flags">The stats to be retrieved from the <paramref name="member"/></param> private static void SendPartyMemberStatsInternal(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags, RealmServerOpCode opcode) { using (var packet = new RealmPacketOut(opcode)) { if (opcode == RealmServerOpCode.SMSG_PARTY_MEMBER_STATS_FULL) { packet.Write((byte)0); //arena something } member.WriteIdPacked(packet); if (!member.IsOnline) { packet.WriteUShort((ushort)CharacterStatus.OFFLINE); client.Send(packet, addEnd: false); return; } packet.Write((uint)flags); var chr = member.Character; if (flags.HasFlag(GroupUpdateFlags.Status)) { packet.Write((ushort)chr.Status); } if (flags.HasFlag(GroupUpdateFlags.Health)) { packet.Write(chr.Health); } if (flags.HasFlag(GroupUpdateFlags.MaxHealth)) { packet.Write(chr.MaxHealth); } if (flags.HasFlag(GroupUpdateFlags.PowerType)) { packet.Write((byte)chr.PowerType); } if (flags.HasFlag(GroupUpdateFlags.Power)) { packet.Write((ushort)chr.Power); } if (flags.HasFlag(GroupUpdateFlags.MaxPower)) { packet.Write((ushort)chr.MaxPower); } if (flags.HasFlag(GroupUpdateFlags.Level)) { packet.Write((ushort)chr.Level); } if (flags.HasFlag(GroupUpdateFlags.ZoneId)) { packet.Write((ushort)(chr.Zone != null ? chr.Zone.Id : ZoneId.None)); } if (flags.HasFlag(GroupUpdateFlags.Position)) { packet.Write((ushort)chr.Position.X); packet.Write((ushort)chr.Position.Y); } if (flags.HasFlag(GroupUpdateFlags.Auras)) { ulong auraMask = chr.AuraUpdateMask; packet.Write(auraMask); Aura currAura; for (byte i = 0; i < AuraHandler.MaxAuras; ++i) { if ((auraMask & ((ulong)1 << i)) != 0) { currAura = chr.Auras.GetAt(i); packet.Write(currAura.Spell.Id); packet.Write((byte)currAura.Flags); } } } NPC targetPet = chr.ActivePet; if (targetPet == null) //no pet { packet.Write((byte)0); //name packet.Write(0UL); //auras client.Send(packet, addEnd: false); return; } if (flags.HasFlag(GroupUpdateFlags.PetGuid)) { packet.Write(targetPet.EntityId); } if (flags.HasFlag(GroupUpdateFlags.PetName)) { packet.WriteCString(targetPet.Name); } if (flags.HasFlag(GroupUpdateFlags.PetDisplayId)) { packet.Write((ushort)targetPet.DisplayId); } if (flags.HasFlag(GroupUpdateFlags.PetHealth)) { packet.Write(targetPet.Health); } if (flags.HasFlag(GroupUpdateFlags.PetMaxHealth)) { packet.Write(targetPet.MaxHealth); } if (flags.HasFlag(GroupUpdateFlags.PetPowerType)) { packet.Write((byte)targetPet.PowerType); } if (flags.HasFlag(GroupUpdateFlags.PetPower)) { packet.Write((ushort)targetPet.Power); } if (flags.HasFlag(GroupUpdateFlags.PetMaxPower)) { packet.Write((ushort)targetPet.MaxPower); } if (flags.HasFlag(GroupUpdateFlags.PetAuras)) { ulong auraMask = targetPet.AuraUpdateMask; packet.Write(auraMask); Aura currAura; for (byte i = 0; i < AuraHandler.MaxAuras; ++i) { if ((auraMask & ((ulong)1 << i)) != 0) { currAura = targetPet.Auras.GetAt(i); //chr.Auras.GetAt(i); packet.Write(currAura.Spell.Id); packet.Write((byte)currAura.Flags); } } } client.Send(packet, addEnd: false); } }
/// <summary> /// /// </summary> /// <param name="gr"></param> /// <param name="gr2"></param> /// <param name="sb"></param> /// <param name="swe"></param> /// <returns></returns> public static bool ParsePartyMemberStatsOpcode(GenericReader gr, GenericReader gr2, StringBuilder sb, StreamWriter swe, byte direction) { sb.AppendLine("Packet offset " + gr.BaseStream.Position.ToString("X2")); sb.AppendLine("Opcode SMSG_PARTY_MEMBER_STATS (0x007E)"); byte MAX_AURAS = 56; ulong guid = gr2.ReadPackedGuid(); sb.AppendLine("GUID " + guid.ToString("X16")); GroupUpdateFlags flags = (GroupUpdateFlags)gr2.ReadUInt32(); sb.AppendLine("Flags " + flags); if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_ONLINE) != 0) { GroupMemberOnlineStatus online = (GroupMemberOnlineStatus)gr2.ReadUInt16(); // flag sb.AppendLine("Online state " + online); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_CUR_HP) != 0) { ushort hp = gr2.ReadUInt16(); sb.AppendLine("Cur. health " + hp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_MAX_HP) != 0) { ushort maxhp = gr2.ReadUInt16(); sb.AppendLine("Max health " + maxhp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_POWER_TYPE) != 0) { Powers power = (Powers)gr2.ReadByte(); sb.AppendLine("Power type " + power); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_CUR_POWER) != 0) { ushort curpower = gr2.ReadUInt16(); sb.AppendLine("Cur. power " + curpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_MAX_POWER) != 0) { ushort maxpower = gr2.ReadUInt16(); sb.AppendLine("Max power " + maxpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_LEVEL) != 0) { ushort level = gr2.ReadUInt16(); sb.AppendLine("Level " + level); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_ZONE) != 0) { ushort zone = gr2.ReadUInt16(); sb.AppendLine("Zone " + zone); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_POSITION) != 0) { short x = gr2.ReadInt16(); short y = gr2.ReadInt16(); sb.AppendLine("Position: " + x + ", " + y); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_AURAS) != 0) { ulong mask = gr2.ReadUInt64(); sb.AppendLine("Auras mask " + mask.ToString("X16")); BitArray bitArr = new BitArray(BitConverter.GetBytes(mask)); for (int i = 0; i < bitArr.Length; i++) { if (i >= MAX_AURAS) // we can have only 56 auras { break; } if (bitArr[i]) { ushort spellid = gr2.ReadUInt16(); sb.AppendLine("Aura " + i.ToString() + ": " + spellid.ToString()); byte unk = gr2.ReadByte(); sb.AppendLine("Aura unk " + i.ToString() + ": " + unk.ToString()); } } } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_GUID) != 0) { ulong petguid = gr2.ReadUInt64(); sb.AppendLine("Pet guid " + petguid.ToString("X16")); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_NAME) != 0) { string name = gr2.ReadStringNull(); sb.AppendLine("Pet name " + name); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_MODEL_ID) != 0) { ushort modelid = gr2.ReadUInt16(); sb.AppendLine("Pet model id " + modelid); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_CUR_HP) != 0) { ushort pethp = gr2.ReadUInt16(); sb.AppendLine("Pet cur. HP " + pethp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_MAX_HP) != 0) { ushort petmaxhp = gr2.ReadUInt16(); sb.AppendLine("Pet max HP " + petmaxhp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_POWER_TYPE) != 0) { Powers power = (Powers)gr2.ReadByte(); sb.AppendLine("Pet power type " + power); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_CUR_POWER) != 0) { ushort petpower = gr2.ReadUInt16(); sb.AppendLine("Pet cur. power " + petpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_MAX_POWER) != 0) { ushort petmaxpower = gr2.ReadUInt16(); sb.AppendLine("Pet max power " + petmaxpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_AURAS) != 0) { ulong mask = gr2.ReadUInt64(); sb.AppendLine("Pet auras mask " + mask.ToString("X16")); BitArray bitArr = new BitArray(BitConverter.GetBytes(mask)); for (int i = 0; i < bitArr.Length; i++) { if (i >= MAX_AURAS) // we can have only 56 auras { break; } if (bitArr[i]) { ushort spellid = gr2.ReadUInt16(); sb.AppendLine("Pet aura " + i.ToString() + ": " + spellid.ToString()); byte unk = gr2.ReadByte(); sb.AppendLine("Pet aura unk " + i.ToString() + ": " + unk.ToString()); } i++; } } if (gr2.BaseStream.Position == gr2.BaseStream.Length) { sb.AppendLine("parsed: ok..."); } else { sb.AppendLine("parsed: error..."); } return(true); }