servuo/Scripts/Misc/ProtocolExtensions.cs
VitaNex 7851c5e88c + Removed most file header regions.
+ Add MONO to Makefile compile definitions.
+ Update Ultima SDK to support MONO compile definition.
+ Rename Properties Gump parent directory to prevent VS issues.
+ Console error messages will now use red instead of dark red font.
+ Add crash state handler function to Core.
+ AI optimizations and housekeeping.
+ Context Menu optimizations and housekeeping.
+ Add ability to drop throttled packets.
+ Add string parsing support to Rectangle3D.
+ Optimize guild messages and chat.
+ IAddon implements IChopable.
+ Add more flexibility for altering Mobile names.
+ Add ability to enable or disable OPL for individual mobiles.
+ Optimize damaging regions and ensure timers are removed properly.
+ Update Welcome Timer with more intuitive message groups.
+ Normalize all virtue related objects to the Server.Services.Virtues namespace.
+ Add ability for ISpawner to append OPL and Context Menus to their spawn.
+ Add EventSink events for obtaining items, equipping items, context menus, and world broadcasts.
+ Add ability to lock a creature's direction and movement regardless of AI manipulation.
+ Add ability to dynamically change a creature's approach range and wait state.
+ Add extended enumeration features for AOS attributes.
+ Add ability to control whether creatures have blood, and its color.
+ Expose corpse flag manipulation methods.
+ Add ability to prevent criminal action when looting a corpse.
+ Corpse will now be permanently tagged as murderer at time of death if owner is a murderer.
+ Add TextDefinition support for Commodity Deed descriptions.
+ House add-on and component optimizations and housekeeping.
+ Item light is no longer backed by the direction property.
+ ITool implements IEntity.
+ Prevent trading of Siege Bless items.
+ Guards are naturally be immune to guards.
+ Siege Shard initialization housekeeping.
+ Character Creation housekeeping.
+ Generic commands housekeeping.
+ Add Mark command for staff.
2018-07-19 22:12:52 +01:00

169 lines
No EOL
5.2 KiB
C#

using System;
using Server.Engines.PartySystem;
using Server.Guilds;
using Server.Network;
namespace Server.Misc
{
public class ProtocolExtensions
{
private static readonly PacketHandler[] m_Handlers = new PacketHandler[0x100];
public static void Initialize()
{
PacketHandlers.Register(0xF0, 0, false, new OnPacketReceive(DecodeBundledPacket));
Register(0x00, true, new OnPacketReceive(QueryPartyLocations));
Register(0x01, true, new OnPacketReceive(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)
{
this.EnsureCapacity(4 + capacity);
this.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 = (PartyMemberInfo)party.Members[i];
if (pmi == null || pmi.Mobile == from)
continue;
Mobile mob = pmi.Mobile;
if (Utility.InUpdateRange(from, mob) && from.CanSee(mob))
continue;
this.m_Stream.Write((int)mob.Serial);
this.m_Stream.Write((short)mob.X);
this.m_Stream.Write((short)mob.Y);
this.m_Stream.Write((byte)(mob.Map == null ? 0 : mob.Map.MapID));
}
this.m_Stream.Write((int)0);
}
}
public class AckGuildsLocations : ProtocolExtension
{
public AckGuildsLocations() : base(0x02, 5)
{
m_Stream.Write((byte)0);
m_Stream.Write((int)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((int)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((int)0);
}
}
}