first commit
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.Data;
|
||||
using ClassicAssist.Data.Macros;
|
||||
using ClassicAssist.Misc;
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.Shared.UO;
|
||||
using ClassicAssist.UO.Network.Packets;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network
|
||||
{
|
||||
public static class ActionPacketQueue
|
||||
{
|
||||
private const int DRAG_DROP_DISTANCE = 3;
|
||||
|
||||
private static readonly ThreadPriorityQueue<BaseQueueItem> _actionPacketQueue =
|
||||
new ThreadPriorityQueue<BaseQueueItem>( ProcessActionPacketQueue );
|
||||
|
||||
private static readonly object _actionPacketQueueLock = new object();
|
||||
|
||||
private static void ProcessActionPacketQueue( BaseQueueItem queueItem )
|
||||
{
|
||||
// Lock here so wait don't set the WaitHandle before we've called ToTask(?)
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
if ( queueItem is PacketQueueItem actionQueueItem )
|
||||
{
|
||||
if ( actionQueueItem.DelaySend )
|
||||
{
|
||||
while ( Engine.LastActionPacket +
|
||||
TimeSpan.FromMilliseconds( Options.CurrentOptions.ActionDelayMS ) > DateTime.Now )
|
||||
{
|
||||
Thread.Sleep( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
byte[] data = actionQueueItem.Packet;
|
||||
int length = actionQueueItem.Length;
|
||||
|
||||
Engine.LastActionPacket = DateTime.Now;
|
||||
Engine.SendPacketToServer( data, length );
|
||||
|
||||
actionQueueItem.WaitHandle.Set();
|
||||
}
|
||||
else if ( queueItem is ActionQueueItem actionItem )
|
||||
{
|
||||
if ( actionItem.DelaySend )
|
||||
{
|
||||
while ( Engine.LastActionPacket +
|
||||
TimeSpan.FromMilliseconds( Options.CurrentOptions.ActionDelayMS ) > DateTime.Now )
|
||||
{
|
||||
Thread.Sleep( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
bool? result = actionItem.Action?.Invoke( actionItem.CheckRange );
|
||||
|
||||
if ( result.HasValue && result.Value )
|
||||
{
|
||||
Engine.LastActionPacket = DateTime.Now;
|
||||
}
|
||||
|
||||
actionItem.WaitHandle.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public static Task EnqueueActionPacket( byte[] packet, int length, QueuePriority priority, bool delaySend )
|
||||
{
|
||||
return EnqueueActionPacket( new PacketQueueItem( packet, length, delaySend ), priority );
|
||||
}
|
||||
|
||||
public static Task EnqueueActionPacket( BasePacket packet, QueuePriority priority = QueuePriority.Low,
|
||||
bool delaySend = true )
|
||||
{
|
||||
byte[] data = packet.ToArray();
|
||||
|
||||
return EnqueueActionPacket( new PacketQueueItem( data, data.Length, delaySend ), priority );
|
||||
}
|
||||
|
||||
public static Task EnqueueActionPacket( PacketQueueItem packetQueueItem, QueuePriority priority )
|
||||
{
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
_actionPacketQueue.Enqueue( packetQueueItem, priority );
|
||||
|
||||
return packetQueueItem.WaitHandle.ToTask();
|
||||
}
|
||||
}
|
||||
|
||||
public static Task EnqueueDragDropGround( int serial, int amount, int x, int y, int z,
|
||||
QueuePriority priority = QueuePriority.Low, bool delaySend = true )
|
||||
{
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
byte[] dragPacket = new DragItem( serial, amount ).ToArray();
|
||||
byte[] dropItem = new DropItem( serial, -1, x, y, z ).ToArray();
|
||||
|
||||
PacketQueueItem dragPacketQueueItem = new PacketQueueItem( dragPacket, dragPacket.Length, delaySend );
|
||||
_actionPacketQueue.Enqueue( dragPacketQueueItem, priority );
|
||||
|
||||
PacketQueueItem dropPacketQueueItem = new PacketQueueItem( dropItem, dropItem.Length, delaySend );
|
||||
_actionPacketQueue.Enqueue( dropPacketQueueItem, priority );
|
||||
|
||||
return new[] { dragPacketQueueItem.WaitHandle, dropPacketQueueItem.WaitHandle }.ToTask();
|
||||
}
|
||||
}
|
||||
|
||||
public static Task EnqueueActionPackets( IEnumerable<BasePacket> packets,
|
||||
QueuePriority priority = QueuePriority.Low, bool delaySend = true )
|
||||
{
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
List<EventWaitHandle> handles = new List<EventWaitHandle>();
|
||||
|
||||
foreach ( BasePacket packet in packets )
|
||||
{
|
||||
byte[] data = packet.ToArray();
|
||||
|
||||
PacketQueueItem packetQueueItem = new PacketQueueItem( data, data.Length, delaySend );
|
||||
handles.Add( packetQueueItem.WaitHandle );
|
||||
|
||||
_actionPacketQueue.Enqueue( packetQueueItem, priority );
|
||||
}
|
||||
|
||||
return handles.ToTask();
|
||||
}
|
||||
}
|
||||
|
||||
public static Task EnqueueDragDrop( int serial, int amount, int containerSerial,
|
||||
QueuePriority priority = QueuePriority.Low, bool checkRange = false, bool checkExisting = false, bool delaySend = true, int x = -1,
|
||||
int y = -1 )
|
||||
{
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
if ( checkExisting && _actionPacketQueue.Contains( e => e is ActionQueueItem aqi && aqi.Serial == serial ) )
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
ActionQueueItem actionQueueItem = new ActionQueueItem( check =>
|
||||
{
|
||||
if ( check )
|
||||
{
|
||||
Item item = Engine.Items.GetItem( serial );
|
||||
|
||||
if ( item == null || item.Distance >= DRAG_DROP_DISTANCE )
|
||||
{
|
||||
if ( !MacroManager.QuietMode )
|
||||
{
|
||||
Commands.SystemMessage( Strings.Item_out_of_range___ );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Engine.SendPacketToServer( new DragItem( serial, amount ) );
|
||||
Thread.Sleep( 50 );
|
||||
Engine.SendPacketToServer( new DropItem( serial, containerSerial, x, y, 0 ) );
|
||||
|
||||
return true;
|
||||
} ) { CheckRange = checkRange, DelaySend = delaySend, Serial = serial };
|
||||
|
||||
_actionPacketQueue.Enqueue( actionQueueItem, priority );
|
||||
|
||||
return actionQueueItem.WaitHandle.ToTask();
|
||||
}
|
||||
}
|
||||
|
||||
public static int Count()
|
||||
{
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
return _actionPacketQueue.Count();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
lock ( _actionPacketQueueLock )
|
||||
{
|
||||
_actionPacketQueue.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace ClassicAssist.UO.Network
|
||||
{
|
||||
public abstract class BaseQueueItem
|
||||
{
|
||||
protected BaseQueueItem()
|
||||
{
|
||||
WaitHandle = new AutoResetEvent( false );
|
||||
}
|
||||
|
||||
public bool DelaySend { get; set; }
|
||||
public EventWaitHandle WaitHandle { get; set; }
|
||||
}
|
||||
|
||||
public class PacketQueueItem : BaseQueueItem
|
||||
{
|
||||
public PacketQueueItem( byte[] packet, int length, bool delaySend )
|
||||
{
|
||||
Packet = packet;
|
||||
Length = length;
|
||||
DelaySend = delaySend;
|
||||
}
|
||||
|
||||
public int Length { get; set; }
|
||||
public byte[] Packet { get; set; }
|
||||
}
|
||||
|
||||
public class ActionQueueItem : BaseQueueItem
|
||||
{
|
||||
public ActionQueueItem( Func<bool, bool> action )
|
||||
{
|
||||
Action = action;
|
||||
}
|
||||
|
||||
public Func<bool, bool> Action { get; set; }
|
||||
public int Serial { get; set; }
|
||||
public bool CheckRange { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.Data;
|
||||
using ClassicAssist.Data.Filters;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network
|
||||
{
|
||||
public static class IncomingPacketFilters
|
||||
{
|
||||
public delegate bool OnReceive( ref byte[] packet, ref int length );
|
||||
|
||||
private static readonly Dictionary<byte, OnReceive> _filters = new Dictionary<byte, OnReceive>();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Register( 0x1C, OnASCIIMessage );
|
||||
Register( 0x20, OnMobileUpdate );
|
||||
Register( 0x77, OnMobileMoving );
|
||||
Register( 0x78, OnMobileIncoming );
|
||||
Register( 0xC1, OnLocalizedMessage );
|
||||
Register( 0xCC, OnLocalizedMessageAffix );
|
||||
Register( 0xF3, OnSAWorldItem );
|
||||
}
|
||||
|
||||
private static bool OnASCIIMessage( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, false );
|
||||
|
||||
JournalEntry journalEntry = new JournalEntry
|
||||
{
|
||||
Serial = reader.ReadInt32(),
|
||||
ID = reader.ReadInt16(),
|
||||
SpeechType = (JournalSpeech) reader.ReadByte(),
|
||||
SpeechHue = reader.ReadInt16(),
|
||||
SpeechFont = reader.ReadInt16(),
|
||||
Name = reader.ReadString( 30 ),
|
||||
Text = reader.ReadString()
|
||||
};
|
||||
|
||||
bool block = RepeatedMessagesFilter.CheckMessage( journalEntry );
|
||||
|
||||
if ( block && RepeatedMessagesFilter.FilterOptions.SendToJournal )
|
||||
{
|
||||
IncomingPacketHandlers.AddToJournal( journalEntry );
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
private static bool OnMobileUpdate( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, true );
|
||||
int serial = reader.ReadInt32();
|
||||
int id = reader.ReadInt16();
|
||||
reader.ReadByte(); // BYTE 0x00;
|
||||
int hue = reader.ReadUInt16();
|
||||
int status = reader.ReadByte();
|
||||
int x = reader.ReadInt16();
|
||||
int y = reader.ReadInt16();
|
||||
reader.ReadInt16(); // WORD 0x00;
|
||||
//TODO Removed & 0x07 to not strip running flag, think of better solution
|
||||
int direction = reader.ReadByte();
|
||||
int z = reader.ReadSByte();
|
||||
|
||||
Mobile mobile = new Mobile( serial )
|
||||
{
|
||||
ID = id,
|
||||
Hue = hue,
|
||||
Status = (MobileStatus) status,
|
||||
X = x,
|
||||
Y = y,
|
||||
Direction = (Direction) direction,
|
||||
Z = z
|
||||
};
|
||||
|
||||
if ( !Engine.RehueList.CheckMobileUpdate( mobile ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Engine.IncomingQueue.Enqueue( new Packet( packet, length ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool OnSAWorldItem( ref byte[] packet, ref int length )
|
||||
{
|
||||
if ( !Engine.RehueList.CheckSAWorldItem( ref packet, ref length ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Will need to send to handler ourselves because we won't see packet again
|
||||
PacketHandler handler = IncomingPacketHandlers.GetHandler( 0xF3 );
|
||||
handler?.OnReceive( new PacketReader( packet, length, true ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool OnMobileMoving( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, true );
|
||||
int serial = reader.ReadInt32();
|
||||
int id = reader.ReadInt16();
|
||||
int x = reader.ReadInt16();
|
||||
int y = reader.ReadInt16();
|
||||
int z = reader.ReadSByte();
|
||||
//TODO Removed & 0x07 to not strip running flag, think of better solution
|
||||
int direction = reader.ReadByte();
|
||||
int hue = reader.ReadUInt16();
|
||||
int status = reader.ReadByte();
|
||||
int notoriety = reader.ReadByte();
|
||||
|
||||
Mobile mobile = new Mobile( serial )
|
||||
{
|
||||
ID = id,
|
||||
X = x,
|
||||
Y = y,
|
||||
Z = z,
|
||||
Direction = (Direction) direction,
|
||||
Hue = hue,
|
||||
Status = (MobileStatus) status,
|
||||
Notoriety = (Notoriety) notoriety
|
||||
};
|
||||
|
||||
if ( !Engine.RehueList.CheckMobileMoving( mobile ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Engine.IncomingQueue.Enqueue( new Packet( packet, length ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool OnMobileIncoming( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, false );
|
||||
|
||||
int serial = reader.ReadInt32();
|
||||
ItemCollection container = new ItemCollection( serial );
|
||||
|
||||
Mobile mobile = serial == Engine.Player?.Serial ? Engine.Player : Engine.GetOrCreateMobile( serial );
|
||||
|
||||
mobile.ID = reader.ReadInt16();
|
||||
mobile.X = reader.ReadInt16();
|
||||
mobile.Y = reader.ReadInt16();
|
||||
mobile.Z = reader.ReadSByte();
|
||||
//TODO Removed & 0x07 to not strip running flag, think of better solution
|
||||
mobile.Direction = (Direction) reader.ReadByte();
|
||||
mobile.Hue = reader.ReadUInt16();
|
||||
mobile.Status = (MobileStatus) reader.ReadByte();
|
||||
mobile.Notoriety = (Notoriety) reader.ReadByte();
|
||||
|
||||
bool useNewIncoming = Engine.ClientVersion == null || Engine.ClientVersion >= new Version( 7, 0, 33, 1 );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
int itemSerial = reader.ReadInt32();
|
||||
|
||||
if ( itemSerial == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Item item = Engine.GetOrCreateItem( itemSerial );
|
||||
item.Owner = serial;
|
||||
item.ID = reader.ReadUInt16();
|
||||
item.Layer = (Layer) reader.ReadByte();
|
||||
|
||||
if ( useNewIncoming )
|
||||
{
|
||||
item.Hue = reader.ReadUInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( item.ID & 0x8000 ) != 0 )
|
||||
{
|
||||
item.ID ^= 0x8000;
|
||||
item.Hue = reader.ReadUInt16();
|
||||
}
|
||||
}
|
||||
|
||||
container.Add( item );
|
||||
}
|
||||
|
||||
mobile.Equipment.Clear();
|
||||
mobile.Equipment.Add( container.GetItems() );
|
||||
|
||||
foreach ( Item item in container.GetItems() )
|
||||
{
|
||||
mobile.SetLayer( item.Layer, item.Serial );
|
||||
}
|
||||
|
||||
if ( !Engine.RehueList.CheckMobileIncoming( mobile, container ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Engine.IncomingQueue.Enqueue( new Packet( packet, length ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool OnLocalizedMessage( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, false );
|
||||
|
||||
JournalEntry journalEntry = new JournalEntry
|
||||
{
|
||||
Serial = reader.ReadInt32(),
|
||||
ID = reader.ReadInt16(),
|
||||
SpeechType = (JournalSpeech) reader.ReadByte(),
|
||||
SpeechHue = reader.ReadInt16(),
|
||||
SpeechFont = reader.ReadInt16(),
|
||||
Cliloc = reader.ReadInt32(),
|
||||
Name = reader.ReadString( 30 ),
|
||||
Arguments = reader.ReadUnicodeString( (int) reader.Size - 50 ).Split( '\t' )
|
||||
};
|
||||
|
||||
journalEntry.Text = Cliloc.GetLocalString( journalEntry.Cliloc, journalEntry.Arguments );
|
||||
|
||||
bool block = RepeatedMessagesFilter.CheckMessage( journalEntry );
|
||||
|
||||
if ( block && RepeatedMessagesFilter.FilterOptions.SendToJournal )
|
||||
{
|
||||
IncomingPacketHandlers.AddToJournal( journalEntry );
|
||||
}
|
||||
|
||||
return block || ClilocFilter.CheckMessage( journalEntry );
|
||||
}
|
||||
|
||||
private static bool OnLocalizedMessageAffix( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, false );
|
||||
|
||||
int serial = reader.ReadInt32();
|
||||
int graphic = reader.ReadInt16();
|
||||
JournalSpeech messageType = (JournalSpeech) reader.ReadByte();
|
||||
int hue = reader.ReadInt16();
|
||||
int font = reader.ReadInt16();
|
||||
int cliloc = reader.ReadInt32();
|
||||
MessageAffixType affixType = (MessageAffixType) reader.ReadByte();
|
||||
string name = reader.ReadString( 30 );
|
||||
string affix = reader.ReadString();
|
||||
string[] arguments = reader.ReadUnicodeString()
|
||||
.Split( new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
|
||||
JournalEntry journalEntry = new JournalEntry
|
||||
{
|
||||
Serial = serial,
|
||||
ID = graphic,
|
||||
SpeechType = messageType,
|
||||
SpeechHue = hue,
|
||||
SpeechFont = font,
|
||||
Cliloc = cliloc,
|
||||
Name = name,
|
||||
Arguments = arguments
|
||||
};
|
||||
|
||||
string text = Cliloc.GetLocalString( journalEntry.Cliloc, journalEntry.Arguments );
|
||||
|
||||
if ( affixType.HasFlag( MessageAffixType.Prepend ) )
|
||||
{
|
||||
journalEntry.Text = $"{affix}{text}";
|
||||
}
|
||||
else if ( affixType.HasFlag( MessageAffixType.Append ) )
|
||||
{
|
||||
journalEntry.Text = $"{text}{affix}";
|
||||
}
|
||||
|
||||
bool block = RepeatedMessagesFilter.CheckMessage( journalEntry );
|
||||
|
||||
if ( block && RepeatedMessagesFilter.FilterOptions.SendToJournal )
|
||||
{
|
||||
IncomingPacketHandlers.AddToJournal( journalEntry );
|
||||
}
|
||||
|
||||
return block || ClilocFilter.CheckMessageAffix( journalEntry, affixType, affix );
|
||||
}
|
||||
|
||||
private static void Register( byte packetId, OnReceive action )
|
||||
{
|
||||
if ( !_filters.ContainsKey( packetId ) )
|
||||
{
|
||||
_filters.Add( packetId, action );
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckPacket( ref byte[] data, ref int length )
|
||||
{
|
||||
if ( _filters.ContainsKey( data[0] ) && _filters.TryGetValue( data[0], out OnReceive onReceive ) )
|
||||
{
|
||||
return onReceive.Invoke( ref data, ref length );
|
||||
}
|
||||
|
||||
foreach ( DynamicFilterEntry dynamicFilterEntry in DynamicFilterEntry.Filters.Where( e => e.Enabled ) )
|
||||
{
|
||||
bool result = dynamicFilterEntry.CheckPacket( ref data, ref length, PacketDirection.Incoming );
|
||||
|
||||
if ( result )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ClassicAssist.Data;
|
||||
using ClassicAssist.Data.Abilities;
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
using UOC = ClassicAssist.Shared.UO.Commands;
|
||||
|
||||
namespace ClassicAssist.UO.Network
|
||||
{
|
||||
public static class OutgoingPacketFilters
|
||||
{
|
||||
public delegate bool OnReceive( ref byte[] packet, ref int length );
|
||||
|
||||
private static readonly Dictionary<byte, OnReceive> _filters = new Dictionary<byte, OnReceive>();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Register( 0x05, OnAttackRequested );
|
||||
Register( 0x06, OnUseRequest );
|
||||
Register( 0x80, OnAccountLoginRequest );
|
||||
Register( 0x91, OnGameServerLogin );
|
||||
}
|
||||
|
||||
private static bool OnUseRequest( ref byte[] packet, ref int length )
|
||||
{
|
||||
if ( !Options.CurrentOptions.CheckHandsPotions )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int serial = ( packet[1] << 24 ) | ( packet[2] << 16 ) | ( packet[3] << 8 ) | packet[4];
|
||||
|
||||
return AbilitiesManager.GetInstance().CheckHands( serial );
|
||||
}
|
||||
|
||||
private static bool OnGameServerLogin( ref byte[] packet, ref int length )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, length, true );
|
||||
|
||||
_ = reader.ReadInt32();
|
||||
|
||||
string username = reader.ReadString( 30 );
|
||||
string password = reader.ReadString( 30 );
|
||||
|
||||
if ( !AssistantOptions.SavePasswords )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !AssistantOptions.SavedPasswords.ContainsKey( username ) ||
|
||||
AssistantOptions.SavePasswordsOnlyBlank && !string.IsNullOrEmpty( password ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string storedPassword = AssistantOptions.SavedPasswords[username];
|
||||
byte[] passwordBytes = Encoding.ASCII.GetBytes( storedPassword );
|
||||
byte[] buffer = new byte[30];
|
||||
|
||||
Buffer.BlockCopy( passwordBytes, 0, buffer, 0, passwordBytes.Length );
|
||||
Buffer.BlockCopy( buffer, 0, packet, 35, buffer.Length );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool OnAccountLoginRequest( ref byte[] packet, ref int packetLength )
|
||||
{
|
||||
PacketReader reader = new PacketReader( packet, packetLength, true );
|
||||
|
||||
string username = reader.ReadString( 30 );
|
||||
string password = reader.ReadString( 30 );
|
||||
|
||||
if ( !AssistantOptions.SavePasswords )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( AssistantOptions.SavedPasswords.ContainsKey( username ) &&
|
||||
( !AssistantOptions.SavePasswordsOnlyBlank || string.IsNullOrEmpty( password ) ) )
|
||||
{
|
||||
string storedPassword = AssistantOptions.SavedPasswords[username];
|
||||
byte[] passwordBytes = Encoding.ASCII.GetBytes( storedPassword );
|
||||
byte[] buffer = new byte[30];
|
||||
|
||||
Buffer.BlockCopy( passwordBytes, 0, buffer, 0, passwordBytes.Length );
|
||||
Buffer.BlockCopy( buffer, 0, packet, 31, buffer.Length );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( string.IsNullOrEmpty( password ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( AssistantOptions.SavedPasswords.ContainsKey( username ) )
|
||||
{
|
||||
AssistantOptions.SavedPasswords.Remove( username );
|
||||
}
|
||||
|
||||
AssistantOptions.SavedPasswords.Add( username, password );
|
||||
AssistantOptions.OnPasswordsChanged();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool OnAttackRequested( ref byte[] packet, ref int length )
|
||||
{
|
||||
int serial = ( packet[1] << 24 ) | ( packet[2] << 16 ) | ( packet[3] << 8 ) | packet[4];
|
||||
|
||||
bool block = Options.CurrentOptions.PreventAttackingFriendsInWarMode &&
|
||||
Options.CurrentOptions.Friends.Any( fe => fe.Serial == serial );
|
||||
|
||||
if ( block )
|
||||
{
|
||||
UOC.SystemMessage( Strings.Attack_request_blocked___ );
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
private static void Register( byte packetId, OnReceive action )
|
||||
{
|
||||
if ( !_filters.ContainsKey( packetId ) )
|
||||
{
|
||||
_filters.Add( packetId, action );
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckPacket( ref byte[] data, ref int length )
|
||||
{
|
||||
if ( _filters.ContainsKey( data[0] ) && _filters.TryGetValue( data[0], out OnReceive onReceive ) )
|
||||
{
|
||||
return onReceive.Invoke( ref data, ref length );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.Data.Abilities;
|
||||
using ClassicAssist.Data.Counters;
|
||||
using ClassicAssist.Data.Macros.Commands;
|
||||
using ClassicAssist.Data.Targeting;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
using ClassicAssist.UO.Objects.Gumps;
|
||||
|
||||
namespace ClassicAssist.UO.Network
|
||||
{
|
||||
public static class OutgoingPacketHandlers
|
||||
{
|
||||
public delegate void dGump( uint gumpId, int serial, Gump gump );
|
||||
|
||||
public delegate void dMenuClick( int serial, int gumpId, int index, int id, int hue );
|
||||
|
||||
public delegate void dTargetSentEvent( TargetType targetType, int senderSerial, int flags, int serial, int x,
|
||||
int y, int z, int id );
|
||||
|
||||
private static PacketHandler[] _handlers;
|
||||
private static PacketHandler[] _extendedHandlers;
|
||||
public static event dTargetSentEvent TargetSentEvent;
|
||||
public static event dGump GumpEvent;
|
||||
|
||||
public static event dMenuClick MenuClickedEvent;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
_handlers = new PacketHandler[0x100];
|
||||
_extendedHandlers = new PacketHandler[0x100];
|
||||
|
||||
Register( 0x02, 7, OnMoveRequested );
|
||||
Register( 0x06, 5, OnUseRequest );
|
||||
Register( 0x07, 7, OnLiftRequest );
|
||||
Register( 0x08, 15, OnDropRequest );
|
||||
Register( 0x13, 10, OnEquipRequest );
|
||||
Register( 0x6C, 19, OnTargetSent );
|
||||
Register( 0x7D, 13, OnMenuResponse );
|
||||
Register( 0xA0, 3, OnPlayServer );
|
||||
Register( 0xB1, 0, OnGumpButtonPressed );
|
||||
Register( 0xBD, 0, OnClientVersion );
|
||||
Register( 0xBF, 0, OnExtendedCommand );
|
||||
Register( 0xD7, 0, OnEncodedCommand );
|
||||
Register( 0xEF, 31, OnNewClientVersion );
|
||||
RegisterExtended( 0x1C, 0, OnSpellCast );
|
||||
}
|
||||
|
||||
private static void OnSpellCast( PacketReader reader )
|
||||
{
|
||||
int type = reader.ReadInt16();
|
||||
|
||||
if ( type == 0 )
|
||||
{
|
||||
reader.Seek( 4, SeekOrigin.Current );
|
||||
}
|
||||
|
||||
Engine.LastSpellID = reader.ReadInt16();
|
||||
}
|
||||
|
||||
private static void OnExtendedCommand( PacketReader reader )
|
||||
{
|
||||
int command = reader.ReadInt16();
|
||||
|
||||
PacketHandler handler = GetExtendedHandler( command );
|
||||
handler?.OnReceive( reader );
|
||||
}
|
||||
|
||||
private static void OnMenuResponse( PacketReader reader )
|
||||
{
|
||||
int serial = reader.ReadInt32();
|
||||
int gumpId = reader.ReadInt16();
|
||||
int index = reader.ReadInt16();
|
||||
int id = reader.ReadInt16();
|
||||
int hue = reader.ReadInt16();
|
||||
|
||||
Engine.Menus.Remove( gumpId );
|
||||
|
||||
MenuClickedEvent?.Invoke( serial, gumpId, index, id, hue );
|
||||
}
|
||||
|
||||
private static void OnPlayServer( PacketReader reader )
|
||||
{
|
||||
int index = reader.ReadInt16();
|
||||
|
||||
Engine.CurrentShard = Engine.Shards.FirstOrDefault( i => i.Index == index );
|
||||
}
|
||||
|
||||
private static void OnClientVersion( PacketReader reader )
|
||||
{
|
||||
string version = reader.ReadString();
|
||||
|
||||
Engine.ClientVersion = Version.Parse( version );
|
||||
}
|
||||
|
||||
private static void OnEquipRequest( PacketReader reader )
|
||||
{
|
||||
AbilitiesManager manager = AbilitiesManager.GetInstance();
|
||||
manager.ResendGump( manager.Enabled );
|
||||
}
|
||||
|
||||
private static void OnLiftRequest( PacketReader reader )
|
||||
{
|
||||
Engine.LastActionPacket = DateTime.Now;
|
||||
Engine.Player.Holding = reader.ReadInt32();
|
||||
Engine.Player.HoldingAmount = reader.ReadUInt16();
|
||||
CountersManager.GetInstance().RecountAll?.Invoke();
|
||||
}
|
||||
|
||||
private static void OnDropRequest( PacketReader reader )
|
||||
{
|
||||
Engine.LastActionPacket = DateTime.Now;
|
||||
}
|
||||
|
||||
private static void OnEncodedCommand( PacketReader reader )
|
||||
{
|
||||
int serial = reader.ReadInt32();
|
||||
|
||||
int command = reader.ReadInt16();
|
||||
|
||||
switch ( command )
|
||||
{
|
||||
case 0x19:
|
||||
{
|
||||
reader.ReadByte();
|
||||
|
||||
int abilityIndex = reader.ReadInt32();
|
||||
|
||||
AbilitiesManager.GetInstance().CheckAbility( abilityIndex );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnUseRequest( PacketReader reader )
|
||||
{
|
||||
Engine.LastActionPacket = DateTime.Now;
|
||||
|
||||
int serial = reader.ReadInt32();
|
||||
|
||||
if ( Engine.Player != null )
|
||||
{
|
||||
Engine.Player.LastObjectSerial = serial;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnMoveRequested( PacketReader reader )
|
||||
{
|
||||
Direction direction = (Direction) ( reader.ReadByte() & 0x07 );
|
||||
int sequence = reader.ReadByte();
|
||||
|
||||
Engine.SetSequence( sequence, direction );
|
||||
}
|
||||
|
||||
private static void OnGumpButtonPressed( PacketReader reader )
|
||||
{
|
||||
int senderSerial = reader.ReadInt32();
|
||||
uint gumpId = reader.ReadUInt32();
|
||||
int buttonId = reader.ReadInt32();
|
||||
|
||||
Engine.GumpList.TryRemove( gumpId, out _ );
|
||||
|
||||
if ( Engine.Gumps.GetGump( gumpId, out Gump gump ) )
|
||||
{
|
||||
GumpEvent?.Invoke( gumpId, senderSerial, gump );
|
||||
}
|
||||
|
||||
Engine.Gumps.Remove( gumpId, buttonId );
|
||||
}
|
||||
|
||||
private static void OnTargetSent( PacketReader reader )
|
||||
{
|
||||
if ( Engine.Player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TargetType targetType = (TargetType) reader.ReadByte();
|
||||
|
||||
Engine.Player.LastTargetType = targetType;
|
||||
|
||||
int senderSerial = reader.ReadInt32(); // sender serial
|
||||
int flags = reader.ReadByte();
|
||||
int serial = reader.ReadInt32();
|
||||
int x = reader.ReadInt16();
|
||||
int y = reader.ReadInt16();
|
||||
int z = reader.ReadInt16();
|
||||
int id = reader.ReadInt16();
|
||||
|
||||
if ( targetType == TargetType.Object && flags != 0x03 && serial != 0 )
|
||||
{
|
||||
Engine.Player.LastTargetSerial = serial;
|
||||
Engine.Player.LastTargetType = targetType;
|
||||
|
||||
switch ( (TargetFlags) flags )
|
||||
{
|
||||
case TargetFlags.Harmful when Engine.Mobiles.GetMobile( serial, out Mobile enemyMobile ) &&
|
||||
AliasCommands.GetAlias( "enemy" ) != serial:
|
||||
TargetManager.GetInstance().SetEnemy( enemyMobile );
|
||||
break;
|
||||
case TargetFlags.Beneficial when Engine.Mobiles.GetMobile( serial, out Mobile friendMobile ) &&
|
||||
MobileCommands.InFriendList( serial ) &&
|
||||
AliasCommands.GetAlias( "friend" ) != serial:
|
||||
TargetManager.GetInstance().SetFriend( friendMobile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Engine.TargetExists = false;
|
||||
|
||||
TargetSentEvent?.Invoke( targetType, senderSerial, flags, serial, x, y, z, id );
|
||||
}
|
||||
|
||||
private static void OnNewClientVersion( PacketReader reader )
|
||||
{
|
||||
reader.ReadInt32();
|
||||
Engine.ClientVersion = new Version( reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(),
|
||||
reader.ReadInt32() );
|
||||
}
|
||||
|
||||
private static void Register( int packetId, int length, OnPacketReceive onReceive )
|
||||
{
|
||||
_handlers[packetId] = new PacketHandler( packetId, length, onReceive );
|
||||
}
|
||||
|
||||
private static void RegisterExtended( int packetId, int length, OnPacketReceive onReceive )
|
||||
{
|
||||
_extendedHandlers[packetId] = new PacketHandler( packetId, length, onReceive );
|
||||
}
|
||||
|
||||
internal static PacketHandler GetHandler( int packetId )
|
||||
{
|
||||
return _handlers[packetId];
|
||||
}
|
||||
|
||||
private static PacketHandler GetExtendedHandler( int packetId )
|
||||
{
|
||||
return _extendedHandlers[packetId];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClassicAssist.UO.Network.PacketFilter
|
||||
{
|
||||
public class PacketFilter
|
||||
{
|
||||
private List<PacketFilterInfo> _filters = new List<PacketFilterInfo>();
|
||||
|
||||
public void Add( byte packet, PacketFilterCondition[] constraints )
|
||||
{
|
||||
Add( new PacketFilterInfo( packet, constraints ) );
|
||||
}
|
||||
|
||||
public void Add( PacketFilterInfo pfi )
|
||||
{
|
||||
if ( _filters == null )
|
||||
{
|
||||
_filters = new List<PacketFilterInfo>();
|
||||
}
|
||||
|
||||
_filters.Add( pfi );
|
||||
}
|
||||
|
||||
public void Remove( PacketFilterInfo pfi )
|
||||
{
|
||||
if ( _filters == null )
|
||||
{
|
||||
_filters = new List<PacketFilterInfo>();
|
||||
}
|
||||
|
||||
if ( _filters.Contains( pfi ) )
|
||||
{
|
||||
_filters.Remove( pfi );
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove( byte packet, PacketFilterCondition[] constraints )
|
||||
{
|
||||
if ( _filters == null )
|
||||
{
|
||||
_filters = new List<PacketFilterInfo>();
|
||||
}
|
||||
|
||||
for ( int i = 0; i < _filters.Count; i++ )
|
||||
{
|
||||
if ( _filters[i].PacketID != packet )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( constraints == null && _filters[i].GetConditions() == null )
|
||||
{
|
||||
_filters.Remove( _filters[i] );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove = true;
|
||||
|
||||
if ( constraints == null || _filters[i].GetConditions() == null ||
|
||||
_filters[i].GetConditions().Length != constraints.Length )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( int x = 0; x < _filters[i].GetConditions().Length; x++ )
|
||||
{
|
||||
if ( !_filters[i].GetConditions()[x].Equals( constraints[x] ) )
|
||||
{
|
||||
remove = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !remove )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_filters.Remove( _filters[i] );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Contains( PacketFilterInfo pfi )
|
||||
{
|
||||
return _filters != null && _filters.Contains( pfi );
|
||||
}
|
||||
|
||||
public int Count()
|
||||
{
|
||||
return _filters?.Count ?? 0;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_filters?.Clear();
|
||||
}
|
||||
|
||||
public bool MatchFilter( byte[] packet )
|
||||
{
|
||||
return MatchFilter( packet, out PacketFilterInfo _ );
|
||||
}
|
||||
|
||||
public bool MatchFilter( byte[] packet, out PacketFilterInfo pfi )
|
||||
{
|
||||
pfi = null;
|
||||
|
||||
if ( _filters == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
for ( int i = 0; i < _filters.Count; i++ )
|
||||
{
|
||||
if ( packet[0] == _filters[i].PacketID )
|
||||
{
|
||||
if ( _filters[i].GetConditions() == null )
|
||||
{
|
||||
// No condition so just match packetid
|
||||
result = true;
|
||||
pfi = _filters[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( PacketFilterCondition fc in _filters[i].GetConditions() )
|
||||
{
|
||||
if ( fc.Position + fc.Length > packet.Length )
|
||||
{
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] tmp = new byte[fc.Length];
|
||||
Buffer.BlockCopy( packet, fc.Position, tmp, 0, fc.Length );
|
||||
|
||||
if ( !tmp.SequenceEqual( fc.GetBytes() ) )
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
result = true;
|
||||
pfi = _filters?[i] ?? null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( result )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !result )
|
||||
{
|
||||
pfi = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int MatchFilterAll( byte[] packet, out PacketFilterInfo[] pfis )
|
||||
{
|
||||
List<PacketFilterInfo> pfiList = new List<PacketFilterInfo>();
|
||||
pfis = null;
|
||||
|
||||
if ( _filters == null )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < _filters.Count; i++ )
|
||||
{
|
||||
if ( packet[0] != _filters[i].PacketID )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( _filters[i].GetConditions() == null )
|
||||
{
|
||||
// No condition so just match packetid
|
||||
pfiList.Add( _filters[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( PacketFilterCondition fc in _filters[i].GetConditions() )
|
||||
{
|
||||
if ( fc.Position + fc.Length > packet.Length )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] tmp = new byte[fc.Length];
|
||||
Buffer.BlockCopy( packet, fc.Position, tmp, 0, fc.Length );
|
||||
|
||||
if ( !tmp.SequenceEqual( fc.GetBytes() ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pfiList.Add( _filters[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pfis = pfiList.ToArray();
|
||||
|
||||
return pfiList.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClassicAssist.UO.Network.PacketFilter
|
||||
{
|
||||
public class PacketFilterCondition
|
||||
{
|
||||
private readonly byte[] _bytes;
|
||||
|
||||
public PacketFilterCondition( int position, byte[] bytes, int length )
|
||||
{
|
||||
Position = position;
|
||||
_bytes = bytes;
|
||||
Length = length;
|
||||
}
|
||||
|
||||
public int Length { get; }
|
||||
public int Position { get; }
|
||||
|
||||
public override bool Equals( object obj )
|
||||
{
|
||||
if ( !( obj is PacketFilterCondition pfc ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Position == pfc.Position && Length == pfc.Length && _bytes.SequenceEqual( pfc.GetBytes() );
|
||||
}
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
return _bytes;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = -285373213;
|
||||
hashCode = hashCode * -1521134295 + Position.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<byte[]>.Default.GetHashCode( _bytes );
|
||||
hashCode = hashCode * -1521134295 + Length.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace ClassicAssist.UO.Network.PacketFilter
|
||||
{
|
||||
public class PacketFilterConditions
|
||||
{
|
||||
public static PacketFilterCondition IntAtPositionCondition( int value, int position )
|
||||
{
|
||||
byte[] valueBytes = { (byte) ( value >> 24 ), (byte) ( value >> 16 ), (byte) ( value >> 8 ), (byte) value };
|
||||
|
||||
return new PacketFilterCondition( position, valueBytes, 4 );
|
||||
}
|
||||
|
||||
public static PacketFilterCondition UIntAtPositionCondition( uint value, int position )
|
||||
{
|
||||
byte[] valueBytes = { (byte) ( value >> 24 ), (byte) ( value >> 16 ), (byte) ( value >> 8 ), (byte) value };
|
||||
|
||||
return new PacketFilterCondition( position, valueBytes, 4 );
|
||||
}
|
||||
|
||||
public static PacketFilterCondition ShortAtPositionCondition( int value, int position )
|
||||
{
|
||||
byte[] valueBytes = { (byte) ( value >> 8 ), (byte) value };
|
||||
|
||||
return new PacketFilterCondition( position, valueBytes, 2 );
|
||||
}
|
||||
|
||||
public static PacketFilterCondition ByteAtPositionCondition( int value, int position )
|
||||
{
|
||||
byte[] valueBytes = { (byte) value };
|
||||
|
||||
return new PacketFilterCondition( position, valueBytes, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ClassicAssist.UO.Network.PacketFilter
|
||||
{
|
||||
public class PacketFilterInfo
|
||||
{
|
||||
private PacketFilterCondition[] _conditions;
|
||||
|
||||
public PacketFilterInfo( int packetId, Action<byte[], PacketFilterInfo> onMatch = null )
|
||||
{
|
||||
PacketID = packetId;
|
||||
_conditions = null;
|
||||
Action = onMatch;
|
||||
}
|
||||
|
||||
public PacketFilterInfo( int packetid, PacketFilterCondition[] conditions,
|
||||
Action<byte[], PacketFilterInfo> onMatch = null )
|
||||
{
|
||||
PacketID = packetid;
|
||||
_conditions = conditions;
|
||||
Action = onMatch;
|
||||
}
|
||||
|
||||
public Action<byte[], PacketFilterInfo> Action { get; set; }
|
||||
|
||||
public int PacketID { get; set; }
|
||||
|
||||
public override bool Equals( object obj )
|
||||
{
|
||||
if ( !( obj is PacketFilterInfo pfi ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disabled because won't remove filter as Action == null in Remove methods.
|
||||
//if ( Action != pfi.Action )
|
||||
// return false;
|
||||
|
||||
if ( GetConditions() == null && pfi.GetConditions() != null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pfi.GetConditions() == null && GetConditions() != null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( GetConditions() == null && pfi.GetConditions() == null )
|
||||
{
|
||||
return PacketID == pfi.PacketID;
|
||||
}
|
||||
|
||||
return PacketID == pfi.PacketID && GetConditions().SequenceEqual( pfi.GetConditions() );
|
||||
}
|
||||
|
||||
public PacketFilterCondition[] GetConditions()
|
||||
{
|
||||
return _conditions;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = -1985156662;
|
||||
hashCode = hashCode * -1521134295 +
|
||||
EqualityComparer<PacketFilterCondition[]>.Default.GetHashCode( _conditions );
|
||||
hashCode = hashCode * -1521134295 + PacketID.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 +
|
||||
EqualityComparer<Action<byte[], PacketFilterInfo>>.Default.GetHashCode( Action );
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public void SetConditions( PacketFilterCondition[] value )
|
||||
{
|
||||
_conditions = value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat( "PacketID: 0x{0:X}\r\n", PacketID );
|
||||
|
||||
if ( _conditions == null )
|
||||
{
|
||||
sb.AppendLine( "No conditions." );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( PacketFilterCondition pfc in _conditions )
|
||||
{
|
||||
sb.Append( pfc );
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace ClassicAssist.UO.Network.PacketFilter
|
||||
{
|
||||
public class PacketWaitEntries
|
||||
{
|
||||
public delegate void dWaitEntryAddedRemoved( PacketWaitEntry entry );
|
||||
|
||||
private readonly List<PacketWaitEntry> _waitEntries = new List<PacketWaitEntry>();
|
||||
private readonly object _waitEntryLock = new object();
|
||||
|
||||
public event dWaitEntryAddedRemoved WaitEntryAddedEvent;
|
||||
public event dWaitEntryAddedRemoved WaitEntryRemovedEvent;
|
||||
|
||||
public PacketWaitEntry Add( PacketFilterInfo pfi, PacketDirection direction, bool autoRemove = false,
|
||||
bool filteredOnly = false )
|
||||
{
|
||||
PacketWaitEntry we = new PacketWaitEntry
|
||||
{
|
||||
PFI = pfi,
|
||||
Lock = new AutoResetEvent( false ),
|
||||
PacketDirection = direction,
|
||||
AutoRemove = autoRemove,
|
||||
MatchFilteredOnly = filteredOnly
|
||||
};
|
||||
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
_waitEntries.Add( we );
|
||||
WaitEntryAddedEvent?.Invoke( we );
|
||||
}
|
||||
|
||||
return we;
|
||||
}
|
||||
|
||||
public bool CheckWait( byte[] packet, PacketDirection direction, bool filteredPacket = false )
|
||||
{
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
if ( _waitEntries.Count == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
List<PacketWaitEntry> matchedEntries = new List<PacketWaitEntry>();
|
||||
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
foreach ( PacketWaitEntry t in _waitEntries.Where( t => packet[0] == t.PFI.PacketID ).Where( t =>
|
||||
direction == t.PacketDirection &&
|
||||
( filteredPacket ? t.MatchFilteredOnly : !t.MatchFilteredOnly ) ) )
|
||||
{
|
||||
if ( t.PFI.GetConditions() == null )
|
||||
{
|
||||
// No condition so just match packetid
|
||||
matchedEntries.Add( t );
|
||||
}
|
||||
else
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
foreach ( PacketFilterCondition fc in t.PFI.GetConditions() )
|
||||
{
|
||||
if ( fc.Position + fc.Length > packet.Length )
|
||||
{
|
||||
result = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
byte[] tmp = new byte[fc.Length];
|
||||
Buffer.BlockCopy( packet, fc.Position, tmp, 0, fc.Length );
|
||||
|
||||
if ( !tmp.SequenceEqual( fc.GetBytes() ) )
|
||||
{
|
||||
result = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
if ( result )
|
||||
{
|
||||
matchedEntries.Add( t );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( matchedEntries.Count == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List<PacketWaitEntry> removeList = new List<PacketWaitEntry>();
|
||||
|
||||
foreach ( PacketWaitEntry entry in matchedEntries )
|
||||
{
|
||||
entry.Packet = new byte[packet.Length];
|
||||
Buffer.BlockCopy( packet, 0, entry.Packet, 0, packet.Length );
|
||||
entry.Lock.Set();
|
||||
entry.PFI.Action?.Invoke( packet, entry.PFI );
|
||||
|
||||
if ( entry.AutoRemove )
|
||||
{
|
||||
removeList.Add( entry );
|
||||
}
|
||||
}
|
||||
|
||||
removeList.ForEach( Remove );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
foreach ( PacketWaitEntry we in _waitEntries )
|
||||
{
|
||||
we.Lock.Set();
|
||||
}
|
||||
|
||||
_waitEntries?.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public PacketWaitEntry[] GetEntries()
|
||||
{
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
return _waitEntries?.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove( PacketWaitEntry we )
|
||||
{
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
_waitEntries.Remove( we );
|
||||
WaitEntryRemovedEvent?.Invoke( we );
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRange( IEnumerable<PacketWaitEntry> wes )
|
||||
{
|
||||
lock ( _waitEntryLock )
|
||||
{
|
||||
foreach ( PacketWaitEntry we in wes )
|
||||
{
|
||||
_waitEntries.Remove( we );
|
||||
WaitEntryRemovedEvent?.Invoke( we );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace ClassicAssist.UO.Network.PacketFilter
|
||||
{
|
||||
public class PacketWaitEntry
|
||||
{
|
||||
public bool AutoRemove { get; set; }
|
||||
public AutoResetEvent Lock { get; set; }
|
||||
public bool MatchFilteredOnly { get; set; } = false;
|
||||
public byte[] Packet { get; set; }
|
||||
public PacketDirection PacketDirection { get; set; }
|
||||
public PacketFilterInfo PFI { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network
|
||||
{
|
||||
internal delegate void OnPacketReceive( PacketReader reader );
|
||||
|
||||
internal class PacketHandler
|
||||
{
|
||||
public PacketHandler( int packetId, int length, OnPacketReceive onReceive )
|
||||
{
|
||||
PacketID = packetId;
|
||||
Length = length;
|
||||
OnReceive = onReceive;
|
||||
}
|
||||
|
||||
public int Length { get; set; }
|
||||
public int PacketID { get; set; }
|
||||
internal OnPacketReceive OnReceive { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class AcceptPartyInvitation : BasePacket
|
||||
{
|
||||
public AcceptPartyInvitation( int partyLeaderSerial )
|
||||
{
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 10 );
|
||||
_writer.Write( (short) 0x06 );
|
||||
_writer.Write( (byte) 0x08 );
|
||||
_writer.Write( partyLeaderSerial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class AttackRequest : BasePacket
|
||||
{
|
||||
public AttackRequest( int serial )
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0x05 );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public abstract class BasePacket
|
||||
{
|
||||
protected PacketWriter _writer;
|
||||
|
||||
protected BasePacket()
|
||||
{
|
||||
}
|
||||
|
||||
protected BasePacket( int length )
|
||||
{
|
||||
_writer = new PacketWriter( length );
|
||||
}
|
||||
|
||||
protected BasePacket( PacketDirection direction )
|
||||
{
|
||||
Direction = direction;
|
||||
}
|
||||
|
||||
public PacketDirection Direction { get; set; } = PacketDirection.Any;
|
||||
|
||||
public virtual byte[] ToArray()
|
||||
{
|
||||
return _writer?.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class BatchQueryProperties : BasePacket
|
||||
{
|
||||
public BatchQueryProperties( int serial )
|
||||
{
|
||||
_writer = new PacketWriter();
|
||||
_writer.Write( (byte) 0xD6 );
|
||||
_writer.Write( (short) 7 );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
|
||||
public BatchQueryProperties( IReadOnlyCollection<int> serials )
|
||||
{
|
||||
_writer = new PacketWriter();
|
||||
_writer.Write( (byte) 0xD6 );
|
||||
_writer.Write( (short) ( 3 + serials.Count * 4 ) );
|
||||
|
||||
foreach ( int serial in serials )
|
||||
{
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class CancelTargetCursor : BasePacket
|
||||
{
|
||||
public CancelTargetCursor( uint senderSerial )
|
||||
{
|
||||
_writer = new PacketWriter( 19 );
|
||||
_writer.Write( (byte) 0x6C );
|
||||
_writer.Write( (byte) 0 );
|
||||
_writer.Write( senderSerial );
|
||||
_writer.Write( (byte) 3 );
|
||||
_writer.Fill();
|
||||
}
|
||||
|
||||
public CancelTargetCursor( int senderSerial )
|
||||
{
|
||||
_writer = new PacketWriter( 19 );
|
||||
_writer.Write( (byte) 0x6C );
|
||||
_writer.Write( (byte) 0 );
|
||||
_writer.Write( senderSerial );
|
||||
_writer.Write( (byte) 3 );
|
||||
_writer.Fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using ClassicAssist.Data.Spells;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class CastSpell : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public CastSpell()
|
||||
{
|
||||
}
|
||||
|
||||
public CastSpell( int id )
|
||||
{
|
||||
_writer = new PacketWriter( 9 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 9 );
|
||||
_writer.Write( (short) 0x1C );
|
||||
_writer.Write( (short) 0x02 );
|
||||
_writer.Write( (short) id );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xBF || packet[4] != 0x1C || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int spellId = ( packet[7] << 8 ) | packet[8];
|
||||
|
||||
SpellManager manager = SpellManager.GetInstance();
|
||||
|
||||
SpellData sd = manager.GetSpellData( spellId ) ?? manager.GetMasteryData( spellId );
|
||||
|
||||
return sd != null ? $"Cast(\"{sd.Name}\")\r\n" : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ChangeCombatant : BasePacket
|
||||
{
|
||||
public ChangeCombatant( int serial ) : base( PacketDirection.Incoming )
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0xAA );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using ClassicAssist.Data.Skills;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ChangeSkillLock : BasePacket
|
||||
{
|
||||
public ChangeSkillLock( SkillEntry skill, LockStatus lockStatus )
|
||||
{
|
||||
_writer = new PacketWriter( 6 );
|
||||
_writer.Write( (byte) 0x3A );
|
||||
_writer.Write( (short) 6 );
|
||||
_writer.Write( (byte) 0 );
|
||||
_writer.Write( (byte) skill.Skill.ID );
|
||||
_writer.Write( (byte) lockStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ChangeStatLock : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public ChangeStatLock()
|
||||
{
|
||||
}
|
||||
|
||||
public ChangeStatLock( StatType stat, LockStatus lockStatus )
|
||||
{
|
||||
_writer = new PacketWriter( 7 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 7 );
|
||||
_writer.Write( (short) 0x1A );
|
||||
_writer.Write( (byte) stat );
|
||||
_writer.Write( (byte) lockStatus );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( direction != PacketDirection.Outgoing || packet[0] != 0xBF || packet[4] != 0x1A )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StatType stat = (StatType) packet[5];
|
||||
LockStatus lockStatus = (LockStatus) packet[6];
|
||||
|
||||
return $"SetStatus(\"{stat.ToString().ToLower()}\", \"{lockStatus.ToString().ToLower()}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ClearWeaponAbility : BasePacket
|
||||
{
|
||||
public ClearWeaponAbility()
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 5 );
|
||||
_writer.Write( (short) 0x21 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class CloseClientGump : BasePacket
|
||||
{
|
||||
public CloseClientGump( uint gumpID )
|
||||
{
|
||||
_writer = new PacketWriter( 13 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 13 );
|
||||
_writer.Write( (short) 0x04 );
|
||||
_writer.Write( gumpID );
|
||||
_writer.Fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class CompressedGump : IMacroCommandParser
|
||||
{
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xDD || direction != PacketDirection.Incoming )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int serial = ( packet[7] << 24 ) | ( packet[8] << 16 ) | ( packet[9] << 8 ) | packet[10];
|
||||
|
||||
return $"WaitForGump(0x{serial:x}, 5000)\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ContainerContentUpdate : BasePacket
|
||||
{
|
||||
public ContainerContentUpdate( int serial, int id, Direction direction, int amount, int x, int y, int grid,
|
||||
int parentSerial, int hue ) : base( PacketDirection.Incoming )
|
||||
{
|
||||
bool isNew = Engine.ClientVersion == null || Engine.ClientVersion >= new Version( 6, 0, 1, 7 );
|
||||
|
||||
_writer = new PacketWriter( isNew ? 21 : 20 );
|
||||
_writer.Write( (byte) 0x25 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) id );
|
||||
_writer.Write( (byte) direction );
|
||||
_writer.Write( (short) amount );
|
||||
_writer.Write( (short) x );
|
||||
_writer.Write( (short) y );
|
||||
|
||||
if ( isNew )
|
||||
{
|
||||
_writer.Write( (byte) grid );
|
||||
}
|
||||
|
||||
_writer.Write( parentSerial );
|
||||
_writer.Write( (short) hue );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ContainerContentsPacket : BasePacket
|
||||
{
|
||||
public ContainerContentsPacket( ItemCollection collection )
|
||||
{
|
||||
_writer = new PacketWriter( 5 + collection.GetTotalItemCount() * 20 );
|
||||
|
||||
_writer.Write( (byte) 0x3C );
|
||||
_writer.Write( (short) ( collection.GetTotalItemCount() * 20 ) );
|
||||
_writer.Write( (short) collection.GetTotalItemCount() );
|
||||
|
||||
foreach ( Item item in collection.GetItems() )
|
||||
{
|
||||
_writer.Write( item.Serial );
|
||||
_writer.Write( (short) item.ID );
|
||||
_writer.Write( (byte) 0 ); // itemid offset
|
||||
_writer.Write( (short) item.Count );
|
||||
_writer.Write( (short) item.X );
|
||||
_writer.Write( (short) item.Y );
|
||||
_writer.Write( (byte) item.Grid );
|
||||
_writer.Write( collection.Serial );
|
||||
_writer.Write( (short) item.Hue );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ContextMenuClick : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public ContextMenuClick()
|
||||
{
|
||||
}
|
||||
|
||||
public ContextMenuClick( int serial, int index )
|
||||
{
|
||||
_writer = new PacketWriter( 11 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 11 );
|
||||
_writer.Write( (short) 0x15 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) index );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xBF || packet[4] != 0x15 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
PacketReader reader = new PacketReader( packet, length, false );
|
||||
|
||||
reader.ReadInt16();
|
||||
|
||||
int serial = reader.ReadInt32();
|
||||
int index = reader.ReadInt16();
|
||||
|
||||
return $"WaitForContext(0x{serial:x}, {index}, 5000)\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ContextMenuRequest : BasePacket
|
||||
{
|
||||
public ContextMenuRequest( int serial )
|
||||
{
|
||||
_writer = new PacketWriter( 9 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 9 );
|
||||
_writer.Write( (short) 0x13 );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class DisarmRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public DisarmRequest()
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 5 );
|
||||
_writer.Write( (short) 0x09 );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( direction == PacketDirection.Outgoing && packet[0] == 0xBF && packet[4] == 0x09 )
|
||||
{
|
||||
return "SetAbility(\"Disarm\")\r\n";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class DisplayQuestPointer : BasePacket
|
||||
{
|
||||
public DisplayQuestPointer( bool active, int x, int y, int serial = 0 )
|
||||
{
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0xBA );
|
||||
_writer.Write( (byte) ( active ? 1 : 0 ) );
|
||||
_writer.Write( (short) x );
|
||||
_writer.Write( (short) y );
|
||||
|
||||
if ( Engine.ClientVersion >= new Version( 7, 0, 9, 0 ) )
|
||||
{
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class DragItem : BasePacket
|
||||
{
|
||||
public DragItem( int serial, int amount, bool checkAmount = false )
|
||||
{
|
||||
if ( checkAmount && amount == -1 )
|
||||
{
|
||||
Item item = Engine.Items.GetItem( serial );
|
||||
|
||||
if ( item != null )
|
||||
{
|
||||
amount = item.Count;
|
||||
}
|
||||
}
|
||||
|
||||
_writer = new PacketWriter( 7 );
|
||||
_writer.Write( (byte) 0x07 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) amount );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class DropItem : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public DropItem()
|
||||
{
|
||||
}
|
||||
|
||||
public DropItem( int serial, int containerSerial, int x, int y, int z )
|
||||
{
|
||||
_writer = new PacketWriter( 15 );
|
||||
_writer.Write( (byte) 0x08 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) x );
|
||||
_writer.Write( (short) y );
|
||||
_writer.Write( (sbyte) z );
|
||||
|
||||
if ( Engine.ClientVersion == null || Engine.ClientVersion >= new Version( 6, 0, 1, 7 ) )
|
||||
{
|
||||
_writer.Write( (byte) 0 );
|
||||
}
|
||||
|
||||
_writer.Write( containerSerial );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x08 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int serial = ( packet[1] << 24 ) | ( packet[2] << 16 ) | ( packet[3] << 8 ) | packet[4];
|
||||
int containerSerial = ( packet[11] << 24 ) | ( packet[12] << 16 ) | ( packet[13] << 8 ) | packet[14];
|
||||
|
||||
if ( serial == 0 || containerSerial == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $"MoveItem(0x{serial:x}, 0x{containerSerial:x})\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class EquipLastWeapon : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public EquipLastWeapon()
|
||||
{
|
||||
if ( Engine.Player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0xD7 );
|
||||
_writer.Write( (short) 10 ); // size
|
||||
_writer.Write( Engine.Player.Serial );
|
||||
_writer.Write( (short) 0x1E );
|
||||
_writer.Write( (byte) 0x0A );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xD7 || packet[8] != 0x1E || packet[9] != 0x0A || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return "EquipLastWeapon()\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class EquipRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public EquipRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public EquipRequest( int serial, Layer layer, int containerSerial )
|
||||
{
|
||||
_writer = new PacketWriter( 10 );
|
||||
|
||||
_writer.Write( (byte) 0x13 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (byte) layer );
|
||||
_writer.Write( containerSerial );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x13 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int serial = ( packet[1] << 24 ) | ( packet[2] << 16 ) | ( packet[3] << 8 ) | packet[4];
|
||||
Layer layer = (Layer) packet[5];
|
||||
|
||||
return $"EquipItem(0x{serial:x}, \"{layer.ToString()}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class GuildButtonRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public GuildButtonRequest()
|
||||
{
|
||||
if ( Engine.Player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0xD7 );
|
||||
_writer.Write( (short) 10 ); // size
|
||||
_writer.Write( Engine.Player.Serial );
|
||||
_writer.Write( (short) 0x28 );
|
||||
_writer.Write( (byte) 0x0A );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xD7 || packet[8] != 0x28 || packet[9] != 0x0A || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return "OpenGuildGump()\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class GumpButtonClick : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public GumpButtonClick()
|
||||
{
|
||||
}
|
||||
|
||||
public GumpButtonClick( int gumpID, int serial, int buttonID, IReadOnlyCollection<int> switches = null )
|
||||
{
|
||||
//TODO switches etc
|
||||
_writer = new PacketWriter( 23 + ( switches?.Count * 4 ?? 0 ) );
|
||||
_writer.Write( (byte) 0xB1 );
|
||||
_writer.Write( (short) ( 23 + ( switches?.Count * 4 ?? 0 ) ) );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( gumpID );
|
||||
_writer.Write( buttonID );
|
||||
|
||||
if ( switches != null )
|
||||
{
|
||||
_writer.Write( switches.Count );
|
||||
|
||||
foreach ( int @switch in switches )
|
||||
{
|
||||
_writer.Write( @switch );
|
||||
}
|
||||
}
|
||||
|
||||
_writer.Fill();
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xB1 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
uint gumpId = (uint) ( ( packet[7] << 24 ) | ( packet[8] << 16 ) | ( packet[9] << 8 ) | packet[10] );
|
||||
int buttonId = ( packet[11] << 24 ) | ( packet[12] << 16 ) | ( packet[13] << 8 ) | packet[14];
|
||||
|
||||
return $"ReplyGump(0x{gumpId:x}, {buttonId})\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public interface IMacroCommandParser
|
||||
{
|
||||
string Parse( byte[] packet, int length, PacketDirection direction );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class InvokeVirtue : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public InvokeVirtue()
|
||||
{
|
||||
}
|
||||
|
||||
public InvokeVirtue( Virtues virtue )
|
||||
{
|
||||
_writer = new PacketWriter( 6 );
|
||||
_writer.Write( (byte) 0x12 );
|
||||
_writer.Write( (short) 6 );
|
||||
_writer.Write( (byte) 0xF4 );
|
||||
_writer.Write( (byte) virtue );
|
||||
_writer.Write( (byte) 0 );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x12 || packet[3] != 0xF4 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $"InvokeVirtue(\"{(Virtues) packet[4]}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ItemListMenu : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x7C || direction != PacketDirection.Incoming )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int gumpId = ( packet[7] << 8 ) | packet[8];
|
||||
return $"WaitForMenu(0x{gumpId:x}, 5000)\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class LookRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public LookRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public LookRequest( int serial )
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0x09 );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
//if ( basePacket[0] != 0x09 || direction != PacketDirection.Outgoing )
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//int serial = ( basePacket[1] << 24 ) | ( basePacket[2] << 16 ) | ( basePacket[3] << 8 ) | basePacket[4];
|
||||
|
||||
//return $"ClickObject(0x{serial:x})\r\nPause({Options.CurrentOptions.ActionDelayMS})\r\n";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MenuButtonClick : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public MenuButtonClick()
|
||||
{
|
||||
}
|
||||
|
||||
public MenuButtonClick( int gumpId, int serial, int index, int id = 0, int hue = 0 )
|
||||
{
|
||||
if ( serial == -1 )
|
||||
{
|
||||
if ( !Engine.Menus.GetMenu( gumpId, out Menu menu ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
serial = menu.Serial;
|
||||
}
|
||||
|
||||
_writer = new PacketWriter( 13 );
|
||||
_writer.Write( (byte) 0x7D );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) gumpId );
|
||||
_writer.Write( (short) index );
|
||||
_writer.Write( (short) id );
|
||||
_writer.Write( (short) hue );
|
||||
|
||||
Engine.Menus?.Remove( gumpId );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x7D || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int gumpId = ( packet[5] << 8 ) | packet[6];
|
||||
int index = ( packet[7] << 8 ) | packet[8];
|
||||
int id = ( packet[9] << 8 ) | packet[10];
|
||||
int hue = ( packet[11] << 8 ) | packet[12];
|
||||
|
||||
return $"ReplyMenu(0x{gumpId:x}, {index}, 0x{id:x}, {hue})\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MobileIncoming : BasePacket
|
||||
{
|
||||
public MobileIncoming( Mobile mobile, ItemCollection equipment, int overrideHue = 0 )
|
||||
{
|
||||
bool useNewIncoming = Engine.ClientVersion == null || Engine.ClientVersion >= new Version( 7, 0, 33, 1 );
|
||||
|
||||
int len = 23 + equipment.Count() * 9;
|
||||
|
||||
_writer = new PacketWriter( len );
|
||||
_writer.Write( (byte) 0x78 );
|
||||
_writer.Write( (short) len );
|
||||
_writer.Write( mobile.Serial );
|
||||
_writer.Write( (short) mobile.ID );
|
||||
_writer.Write( (short) mobile.X );
|
||||
_writer.Write( (short) mobile.Y );
|
||||
_writer.Write( (sbyte) mobile.Z );
|
||||
_writer.Write( (byte) mobile.Direction );
|
||||
_writer.Write( (short) ( overrideHue > 0 ? overrideHue : mobile.Hue ) );
|
||||
_writer.Write( (byte) mobile.Status );
|
||||
_writer.Write( (byte) mobile.Notoriety );
|
||||
|
||||
foreach ( Item item in equipment.GetItems() )
|
||||
{
|
||||
_writer.Write( item.Serial );
|
||||
_writer.Write( (short) ( useNewIncoming ? item.ID : item.ID | 0x8000 ) );
|
||||
_writer.Write( (byte) item.Layer );
|
||||
_writer.Write( (short) ( overrideHue > 0 ? overrideHue : item.Hue ) );
|
||||
}
|
||||
|
||||
_writer.Write( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MobileMoving : BasePacket
|
||||
{
|
||||
public MobileMoving( Mobile mobile, int hueOverride = 0 )
|
||||
{
|
||||
_writer = new PacketWriter( 17 );
|
||||
_writer.Write( (byte) 0x77 );
|
||||
_writer.Write( mobile.Serial );
|
||||
_writer.Write( (short) mobile.ID );
|
||||
_writer.Write( (short) mobile.X );
|
||||
_writer.Write( (short) mobile.Y );
|
||||
_writer.Write( (sbyte) mobile.Z );
|
||||
_writer.Write( (byte) mobile.Direction );
|
||||
_writer.Write( (short) ( hueOverride > 0 ? hueOverride : mobile.Hue ) );
|
||||
_writer.Write( (byte) mobile.Status );
|
||||
_writer.Write( (byte) mobile.Notoriety );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MobileQuery : BasePacket
|
||||
{
|
||||
public MobileQuery( int serial, MobileQueryType queryType = MobileQueryType.StatsRequest )
|
||||
{
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0x34 );
|
||||
_writer.Write( 0xEDEDEDED );
|
||||
_writer.Write( (byte) queryType );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MobileUpdate : BasePacket
|
||||
{
|
||||
public MobileUpdate( int serial, int id, int hue, MobileStatus flags, int x, int y, int z, Direction direction )
|
||||
{
|
||||
_writer = new PacketWriter( 19 );
|
||||
_writer.Write( (byte) 0x20 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) id );
|
||||
_writer.Write( (byte) 0 );
|
||||
_writer.Write( (short) hue );
|
||||
_writer.Write( (byte) flags );
|
||||
_writer.Write( (short) x );
|
||||
_writer.Write( (short) y );
|
||||
_writer.Write( (short) 0 );
|
||||
_writer.Write( (byte) direction );
|
||||
_writer.Write( (sbyte) z );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MovementRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x02 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Direction d = (Direction) packet[1];
|
||||
|
||||
return $"Walk(\"{d.ToString()}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class MultiTarget : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x99 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return direction == PacketDirection.Incoming ? "WaitForTarget(5000)\r\n" : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class Ping : BasePacket
|
||||
{
|
||||
public Ping( byte value ) : base( 2 )
|
||||
{
|
||||
_writer.Write( (byte) 0x73 );
|
||||
_writer.Write( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class PlaySound : BasePacket
|
||||
{
|
||||
public PlaySound( int id )
|
||||
{
|
||||
_writer = new PacketWriter( 12 );
|
||||
_writer.Write( (byte) 0x54 );
|
||||
_writer.Write( (byte) 0x01 );
|
||||
_writer.Write( (short) id );
|
||||
_writer.Write( (short) 0 );
|
||||
_writer.Write( (short) ( Engine.Player?.X ?? 0 ) );
|
||||
_writer.Write( (short) ( Engine.Player?.Y ?? 0 ) );
|
||||
_writer.Write( (short) ( Engine.Player?.Z ?? 0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class QueryProperties : BasePacket
|
||||
{
|
||||
public QueryProperties( int serial )
|
||||
{
|
||||
_writer = new PacketWriter( 9 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 9 );
|
||||
_writer.Write( (short) 0x10 );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class QuestsButtonRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public QuestsButtonRequest()
|
||||
{
|
||||
if ( Engine.Player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0xD7 );
|
||||
_writer.Write( (short) 10 ); // size
|
||||
_writer.Write( Engine.Player.Serial );
|
||||
_writer.Write( (short) 0x32 );
|
||||
_writer.Write( (byte) 0x0A );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xD7 || packet[8] != 0x32 || packet[9] != 0x0A || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return "OpenQuestsGump()\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class RejectPartyInvitation : BasePacket
|
||||
{
|
||||
public RejectPartyInvitation( int partyLeaderSerial )
|
||||
{
|
||||
_writer = new PacketWriter( 10 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 10 );
|
||||
_writer.Write( (short) 0x06 );
|
||||
_writer.Write( (byte) 0x09 );
|
||||
_writer.Write( partyLeaderSerial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class RemoveObject : BasePacket
|
||||
{
|
||||
public RemoveObject( int serial )
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0x1D );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class RenameRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public RenameRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public RenameRequest( int serial, string name )
|
||||
{
|
||||
_writer = new PacketWriter( 35 );
|
||||
_writer.Write( (byte) 0x75 );
|
||||
_writer.Write( serial );
|
||||
_writer.WriteAsciiFixed( name, 30 );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x75 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
PacketReader reader = new PacketReader( packet, length, true );
|
||||
|
||||
int serial = reader.ReadInt32();
|
||||
string name = reader.ReadString( 30 );
|
||||
|
||||
return $"Rename(0x{serial:x}, \"{name}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class Resync : BasePacket
|
||||
{
|
||||
public Resync()
|
||||
{
|
||||
_writer = new PacketWriter( 3 );
|
||||
_writer.Write( (byte) 0x22 );
|
||||
_writer.Write( (short) 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.IO;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class SAWorldItem : BasePacket
|
||||
{
|
||||
public SAWorldItem( byte[] packet, int length, int hueOverride )
|
||||
{
|
||||
_writer = new PacketWriter( length );
|
||||
_writer.Write( packet, 0, length );
|
||||
|
||||
if ( hueOverride <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_writer.Seek( 21, SeekOrigin.Begin );
|
||||
_writer.Write( (short) hueOverride );
|
||||
_writer.Seek( 0, SeekOrigin.End );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class SetWeaponAbility : BasePacket
|
||||
{
|
||||
public SetWeaponAbility( int abilityIndex )
|
||||
{
|
||||
_writer = new PacketWriter( 15 );
|
||||
|
||||
_writer.Write( (byte) 0xD7 );
|
||||
_writer.Write( (short) 15 );
|
||||
_writer.Write( Engine.Player?.Serial ?? 0 );
|
||||
_writer.Write( (short) 0x19 );
|
||||
_writer.Write( (byte) 0 );
|
||||
_writer.Write( abilityIndex );
|
||||
_writer.Write( (byte) 0x0A );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class StunRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public StunRequest()
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 5 );
|
||||
_writer.Write( (short) 0x0A );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( direction == PacketDirection.Outgoing && packet[0] == 0xBF && packet[4] == 0x0A )
|
||||
{
|
||||
return "SetAbility(\"Stun\")\r\n";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.Data;
|
||||
using ClassicAssist.Data.Macros.Commands;
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.Shared.UO;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class Target : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public Target()
|
||||
{
|
||||
}
|
||||
|
||||
public Target( int senderSerial, Entity entity, bool cancelClientCursor ) : this( TargetType.Object,
|
||||
senderSerial, TargetFlags.None, entity.Serial, -1, -1, -1, entity.ID, cancelClientCursor )
|
||||
{
|
||||
}
|
||||
|
||||
public Target( TargetType targetType, int senderSerial, TargetFlags flags, int targetSerial, int x, int y,
|
||||
int z, int id, bool cancelClientCursor )
|
||||
{
|
||||
if ( senderSerial == -1 )
|
||||
{
|
||||
senderSerial = Engine.TargetSerial;
|
||||
}
|
||||
|
||||
if ( targetSerial > 0 )
|
||||
{
|
||||
Engine.Player.LastTargetSerial = targetSerial;
|
||||
Engine.Player.LastTargetType = targetType;
|
||||
}
|
||||
|
||||
if ( Engine.TargetFlags == TargetFlags.Harmful &&
|
||||
Options.CurrentOptions.PreventTargetingFriendsWithHarmful &&
|
||||
MobileCommands.InFriendList( targetSerial ) )
|
||||
{
|
||||
Commands.SystemMessage( Strings.Target_blocked____try_again___ );
|
||||
Commands.ResendTargetToClient();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_writer = new PacketWriter( 19 );
|
||||
_writer.Write( (byte) 0x6C );
|
||||
_writer.Write( (byte) targetType );
|
||||
_writer.Write( senderSerial );
|
||||
_writer.Write( (byte) flags );
|
||||
_writer.Write( targetSerial );
|
||||
_writer.Write( (short) x );
|
||||
_writer.Write( (short) y );
|
||||
_writer.Write( (short) z );
|
||||
_writer.Write( (short) id );
|
||||
|
||||
Engine.TargetExists = false;
|
||||
|
||||
if ( cancelClientCursor )
|
||||
{
|
||||
Engine.SendPacketToClient( new Target( targetType, senderSerial, TargetFlags.Cancel, targetSerial, x, y,
|
||||
z, id, false ) );
|
||||
Engine.AddSendPreFilter( new PacketFilterInfo( 0x6C,
|
||||
new[] { PacketFilterConditions.IntAtPositionCondition( senderSerial, 2 ) },
|
||||
( p, pfi ) => { Engine.RemoveSendPreFilter( pfi ); } ) );
|
||||
}
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x6C )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( direction == PacketDirection.Incoming )
|
||||
{
|
||||
return "WaitForTarget(5000)\r\n";
|
||||
}
|
||||
|
||||
if ( packet[1] == 0 )
|
||||
{
|
||||
uint serial = (uint) ( ( packet[7] << 24 ) | ( packet[8] << 16 ) | ( packet[9] << 8 ) | packet[10] );
|
||||
|
||||
return $"Target(0x{serial:x})\r\n";
|
||||
}
|
||||
|
||||
int x = ( packet[11] << 8 ) | packet[12];
|
||||
int y = ( packet[13] << 8 ) | packet[14];
|
||||
int z = (sbyte) ( packet[15] << 8 ) | (sbyte) packet[16];
|
||||
int id = ( packet[17] << 8 ) | packet[18];
|
||||
|
||||
return id == 0 ? $"TargetXYZ({x}, {y}, {z})\r\n" : $"TargetXYZ({x}, {y}, {z}, {id})\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class TargetByResource : BasePacket
|
||||
{
|
||||
public TargetByResource( int serial, int resourceType )
|
||||
{
|
||||
_writer = new PacketWriter( 11 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 11 );
|
||||
_writer.Write( (short) 0x30 );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (short) resourceType );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class ToggleGargoyleFlying : BasePacket
|
||||
{
|
||||
public ToggleGargoyleFlying()
|
||||
{
|
||||
_writer = new PacketWriter( 11 );
|
||||
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 11 );
|
||||
_writer.Write( (short) 0x32 );
|
||||
_writer.Write( (short) 1 );
|
||||
_writer.Write( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UnicodePromptCancel : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public UnicodePromptCancel()
|
||||
{
|
||||
}
|
||||
|
||||
public UnicodePromptCancel( int senderSerial, int promptId )
|
||||
{
|
||||
_writer = new PacketWriter( 20 );
|
||||
_writer.Write( (byte) 0xC2 );
|
||||
_writer.Write( (short) 20 );
|
||||
_writer.Write( senderSerial );
|
||||
_writer.Write( promptId );
|
||||
_writer.Write( 0 );
|
||||
_writer.WriteAsciiFixed( Strings.UO_LOCALE, 4 );
|
||||
_writer.Fill();
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xC2 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return packet[14] != 0x00 ? null : "CancelPrompt()\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UnicodePromptRequest : BasePacket, IMacroCommandParser
|
||||
{
|
||||
// ReSharper disable once EmptyConstructor
|
||||
public UnicodePromptRequest()
|
||||
{
|
||||
// TODO
|
||||
// byte[] packet = new byte[] { 0xC2, 0x00, 0x15, 0x00, 0x00, 0x04, 0x82, 0x00, 0x00, 0x04, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] == 0xC2 && direction == PacketDirection.Incoming )
|
||||
{
|
||||
return "WaitForPrompt(5000)\r\n";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Text;
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UnicodePromptResponse : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public UnicodePromptResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public UnicodePromptResponse( int senderSerial, int promptId, string text )
|
||||
{
|
||||
byte[] textBytes = Encoding.Unicode.GetBytes( text );
|
||||
|
||||
int len = 19 + textBytes.Length;
|
||||
|
||||
_writer = new PacketWriter( len );
|
||||
_writer.Write( (byte) 0xC2 );
|
||||
_writer.Write( (short) len );
|
||||
_writer.Write( senderSerial );
|
||||
_writer.Write( promptId );
|
||||
_writer.Write( 1 );
|
||||
_writer.WriteAsciiFixed( Strings.UO_LOCALE, 4 );
|
||||
_writer.Write( textBytes, 0, textBytes.Length );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0xC2 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( packet[14] == 0x00 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string text = Encoding.Unicode.GetString( packet, 19, packet.Length - 20 ).Trim( '\0' );
|
||||
|
||||
return $"PromptMsg(\"{text}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Text;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UnicodeText : BasePacket
|
||||
{
|
||||
public UnicodeText( int serial, int graphic, JournalSpeech speechType, int hue, int font, string lang,
|
||||
string name, string text )
|
||||
{
|
||||
byte[] textBytes = Encoding.BigEndianUnicode.GetBytes( text );
|
||||
int len = 48 + textBytes.Length;
|
||||
|
||||
_writer = new PacketWriter( len );
|
||||
_writer.Write( (byte) 0xAE );
|
||||
_writer.Write( (short) len );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( (ushort) graphic );
|
||||
_writer.Write( (byte) speechType );
|
||||
_writer.Write( (short) hue );
|
||||
_writer.Write( (short) font );
|
||||
_writer.WriteAsciiFixed( lang, 4 );
|
||||
_writer.WriteAsciiFixed( name, 30 );
|
||||
_writer.Write( textBytes, 0, textBytes.Length );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UseObject : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public UseObject()
|
||||
{
|
||||
}
|
||||
|
||||
public UseObject( int serial )
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0x06 );
|
||||
_writer.Write( serial );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x06 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int serial = ( packet[1] << 24 ) | ( packet[2] << 16 ) | ( packet[3] << 8 ) | packet[4];
|
||||
|
||||
return $"UseObject(0x{serial:x})\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network.PacketFilter;
|
||||
using static System.Text.Encoding;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UseSkill : BasePacket, IMacroCommandParser
|
||||
{
|
||||
public UseSkill()
|
||||
{
|
||||
}
|
||||
|
||||
public UseSkill( int index )
|
||||
{
|
||||
string args = $"{index} 0";
|
||||
|
||||
_writer = new PacketWriter( 5 + args.Length );
|
||||
_writer.Write( (byte) 0x12 );
|
||||
_writer.Write( (short) ( 5 + args.Length ) );
|
||||
_writer.Write( (byte) 0x24 );
|
||||
_writer.WriteAsciiFixed( args, args.Length );
|
||||
_writer.Write( (byte) 0 );
|
||||
}
|
||||
|
||||
public string Parse( byte[] packet, int length, PacketDirection direction )
|
||||
{
|
||||
if ( packet[0] != 0x12 || packet[3] != 0x24 || direction != PacketDirection.Outgoing )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int len = packet.Length - 4;
|
||||
byte[] skillPart = new byte[len];
|
||||
Buffer.BlockCopy( packet, 4, skillPart, 0, len );
|
||||
string skill = ASCII.GetString( skillPart );
|
||||
|
||||
if ( !int.TryParse( skill.Substring( 0, skill.IndexOf( ' ' ) ), out int id ) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string skillName = Skills.GetSkillName( id );
|
||||
|
||||
return string.IsNullOrEmpty( skillName ) ? null : $"UseSkill(\"{skillName}\")\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#region License
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class UseTargetedItem : BasePacket
|
||||
{
|
||||
public UseTargetedItem( int serial, int targetSerial )
|
||||
{
|
||||
_writer = new PacketWriter( 13 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 13 );
|
||||
_writer.Write( (short) 0x2C );
|
||||
_writer.Write( serial );
|
||||
_writer.Write( targetSerial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ClassicAssist.Data.Vendors;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class VendorBuy : BasePacket
|
||||
{
|
||||
public VendorBuy( IReadOnlyCollection<ShopListEntry> entries )
|
||||
{
|
||||
int len = 8 + entries.Count * 7;
|
||||
|
||||
_writer = new PacketWriter( len );
|
||||
_writer.Write( (byte) 0x3B );
|
||||
_writer.Write( (short) len );
|
||||
_writer.Write( entries.FirstOrDefault()?.VendorSerial ?? 0 );
|
||||
_writer.Write( (byte) 2 ); // item list
|
||||
|
||||
foreach ( ShopListEntry entry in entries )
|
||||
{
|
||||
_writer.Write( (byte) Layer.ShopBuy );
|
||||
_writer.Write( entry.Item.Serial );
|
||||
_writer.Write( (short) entry.Amount );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public class WarMode : BasePacket
|
||||
{
|
||||
public WarMode( bool onOff )
|
||||
{
|
||||
_writer = new PacketWriter( 5 );
|
||||
_writer.Write( (byte) 0x72 );
|
||||
_writer.Write( onOff );
|
||||
_writer.Write( (byte) 0x00 );
|
||||
_writer.Write( (byte) 0x32 );
|
||||
_writer.Write( (byte) 0x00 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.UO.Network.Packets
|
||||
{
|
||||
public enum BoatSpeed : byte
|
||||
{
|
||||
Stop,
|
||||
OneTile,
|
||||
Normal
|
||||
}
|
||||
|
||||
public class WheelBoatMoving : BasePacket
|
||||
{
|
||||
public WheelBoatMoving( Direction direction, BoatSpeed speed )
|
||||
{
|
||||
_writer = new PacketWriter( 12 );
|
||||
_writer.Write( (byte) 0xBF );
|
||||
_writer.Write( (short) 12 );
|
||||
_writer.Write( (short) 0x33 );
|
||||
_writer.Write( Engine.Player.Serial );
|
||||
_writer.Write( (byte) direction );
|
||||
_writer.Write( (byte) direction );
|
||||
_writer.Write( (byte) speed );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user