servuo/Scripts/Misc/ProtocolExtensions.cs
TrueUO f608d123a4
Bug Fixes (#4762)
-Fixed issue where client helpers could bypass the container gump and add items directly to the seed box
-SearedFireAntGoo is no longer stackable
-Blue NPC's (mainly vendors, not initial innocent) can no longer be attacked on trammel maps
-Aggressors/Aggressed from pet masters now works properly. This was suspected to crated large numbers to redundant aggressor/aggressed added to a mobiles aggressor/aggressed lists
-Aggressive action for healing a mobile while fighting another mobile has been re-enabled
-AuraDamage is now a harmful act, ie those affected will aggro on your pet!
-MLDryads should no longer attack other wild creatures during Blackthorn Invasion Instance
-More code cleanup
2020-04-21 17:25:24 -07:00

169 lines
5.1 KiB
C#

using Server.Engines.PartySystem;
using Server.Guilds;
using Server.Network;
using System;
namespace Server.Misc
{
public class ProtocolExtensions
{
private static readonly PacketHandler[] m_Handlers = new PacketHandler[0x100];
public static void Initialize()
{
PacketHandlers.Register(0xF0, 0, false, DecodeBundledPacket);
Register(0x00, true, QueryPartyLocations);
Register(0x01, true, QueryGuildsLocations);
}
public static void QueryPartyLocations(NetState state, PacketReader pvSrc)
{
Mobile from = state.Mobile;
Party party = Party.Get(from);
if (party != null)
{
AckPartyLocations ack = new AckPartyLocations(from, party);
if (ack.UnderlyingStream.Length > 8)
state.Send(ack);
}
}
private static void QueryGuildsLocations(NetState state, PacketReader pvSrc)
{
Mobile from = state.Mobile;
Guild guild = from.Guild as Guild;
if (guild != null)
{
bool locations = pvSrc.ReadByte() != 0;
AckGuildsLocations packet = new AckGuildsLocations(from, guild, locations);
if (packet.UnderlyingStream.Length > (locations ? 9 : 5))
state.Send(packet);
}
else
state.Send(new AckGuildsLocations());
}
public static void Register(int packetID, bool ingame, OnPacketReceive onReceive)
{
m_Handlers[packetID] = new PacketHandler(packetID, 0, ingame, onReceive);
}
public static PacketHandler GetHandler(int packetID)
{
if (packetID >= 0 && packetID < m_Handlers.Length)
return m_Handlers[packetID];
return null;
}
public static void DecodeBundledPacket(NetState state, PacketReader pvSrc)
{
int packetID = pvSrc.ReadByte();
PacketHandler ph = GetHandler(packetID);
if (ph != null)
{
if (ph.Ingame && state.Mobile == null)
{
Utility.PushColor(ConsoleColor.Red);
Console.WriteLine("Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID);
Utility.PopColor();
state.Dispose();
}
else if (ph.Ingame && state.Mobile.Deleted)
{
state.Dispose();
}
else
{
ph.OnReceive(state, pvSrc);
}
}
}
}
public abstract class ProtocolExtension : Packet
{
public ProtocolExtension(int packetID, int capacity)
: base(0xF0)
{
EnsureCapacity(4 + capacity);
m_Stream.Write((byte)packetID);
}
}
public class AckPartyLocations : ProtocolExtension
{
public AckPartyLocations(Mobile from, Party party)
: base(0x01, ((party.Members.Count - 1) * 9) + 4)
{
for (int i = 0; i < party.Members.Count; ++i)
{
PartyMemberInfo pmi = party.Members[i];
if (pmi == null || pmi.Mobile == from)
continue;
Mobile mob = pmi.Mobile;
if (Utility.InUpdateRange(from, mob) && from.CanSee(mob))
continue;
m_Stream.Write(mob.Serial);
m_Stream.Write((short)mob.X);
m_Stream.Write((short)mob.Y);
m_Stream.Write((byte)(mob.Map == null ? 0 : mob.Map.MapID));
}
m_Stream.Write(0);
}
}
public class AckGuildsLocations : ProtocolExtension
{
public AckGuildsLocations() : base(0x02, 5)
{
m_Stream.Write((byte)0);
m_Stream.Write(0);
}
public AckGuildsLocations(Mobile from, Guild guild, bool locations) : base(0x02, ((guild.Members.Count - 1) * (locations ? 10 : 4)) + 5)
{
m_Stream.Write((byte)(locations ? 1 : 0));
for (int i = 0; i < guild.Members.Count; ++i)
{
Mobile mob = guild.Members[i];
if (mob == null || mob == from || mob.NetState == null)
continue;
if (locations && Utility.InUpdateRange(from, mob) && from.CanSee(mob))
continue;
m_Stream.Write(mob.Serial);
if (locations)
{
m_Stream.Write((short)mob.X);
m_Stream.Write((short)mob.Y);
m_Stream.Write((byte)(mob.Map == null ? 0 : mob.Map.MapID));
if (mob.Alive)
m_Stream.Write((byte)(mob.Hits / Math.Max(mob.HitsMax, 1.0) * 100));
else
m_Stream.Write((byte)0);
}
}
m_Stream.Write(0);
}
}
}