mirror of
https://github.com/ACEmulator/ACE
synced 2026-08-17 12:26:06 -04:00
161 lines
7.1 KiB
C#
161 lines
7.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
using ACE.Entity.Enum;
|
|
using ACE.Server.Entity;
|
|
using ACE.Server.Network.Enum;
|
|
using log4net;
|
|
|
|
namespace ACE.Server.Network.Structure
|
|
{
|
|
/// <summary>
|
|
/// The raw movement commands sent by client
|
|
/// </summary>
|
|
public class RawMotionState
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
public static RawMotionState None = new RawMotionState();
|
|
|
|
public MoveToState MoveToState;
|
|
|
|
public uint PackedFlags;
|
|
|
|
public RawMotionFlags Flags; // stored as the first 11 bits of PackedFlags
|
|
public ushort CommandListLength; // starts at bit 12 of PackedFlags
|
|
|
|
// choose valid sections by masking against Flags
|
|
public HoldKey CurrentHoldKey; // 0x1 - walk/run
|
|
public MotionStance CurrentStyle; // 0x2 - current stance
|
|
public MotionCommand ForwardCommand; // 0x4 - forward movement or motion command (default invalid or ready?)
|
|
public HoldKey ForwardHoldKey; // 0x8 - whether forward/back key is being held
|
|
public float ForwardSpeed; // 0x10 - forward/back movement speed
|
|
public MotionCommand SidestepCommand; // 0x20 - sidestep movement command
|
|
public HoldKey SidestepHoldKey; // 0x40 - indicates whether a sidestep key is being held
|
|
public float SidestepSpeed; // 0x80 - sidestep movement speed
|
|
public MotionCommand TurnCommand; // 0x100 - turn command - this is always sent as 1 direction in RawMotion,
|
|
// with a negative speed for the opposite direction. A negative speed
|
|
// is then in turn translated to the opposite Motion in InterpretedMotionState.
|
|
public HoldKey TurnHoldKey; // 0x200 - whether turn key is being held, or mouselook in progress
|
|
public float TurnSpeed; // 0x400 - turn movement speed - somewhat static
|
|
|
|
// commands: list of length commandListLength
|
|
public List<MotionItem> Commands;
|
|
|
|
public RawMotionState() { }
|
|
|
|
public RawMotionState(MoveToState moveToState, BinaryReader reader)
|
|
{
|
|
MoveToState = moveToState;
|
|
|
|
PackedFlags = reader.ReadUInt32();
|
|
|
|
// security vulnerability here:
|
|
// untrusted client input sending command list length
|
|
Flags = (RawMotionFlags)(PackedFlags & 0x7FF);
|
|
CommandListLength = (ushort)(PackedFlags >> 11);
|
|
|
|
if ((Flags & RawMotionFlags.CurrentHoldKey) != 0)
|
|
CurrentHoldKey = (HoldKey)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.CurrentStyle) != 0)
|
|
CurrentStyle = (MotionStance)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.ForwardCommand) != 0)
|
|
ForwardCommand = (MotionCommand)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.ForwardHoldKey) != 0)
|
|
ForwardHoldKey = (HoldKey)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.ForwardSpeed) != 0)
|
|
ForwardSpeed = reader.ReadSingle();
|
|
if ((Flags & RawMotionFlags.SideStepCommand) != 0)
|
|
SidestepCommand = (MotionCommand)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.SideStepHoldKey) != 0)
|
|
SidestepHoldKey = (HoldKey)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.SideStepSpeed) != 0)
|
|
SidestepSpeed = reader.ReadSingle();
|
|
if ((Flags & RawMotionFlags.TurnCommand) != 0)
|
|
TurnCommand = (MotionCommand)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.TurnHoldKey) != 0)
|
|
TurnHoldKey = (HoldKey)reader.ReadUInt32();
|
|
if ((Flags & RawMotionFlags.TurnSpeed) != 0)
|
|
TurnSpeed = reader.ReadSingle();
|
|
|
|
// cases where this is > 1?
|
|
if (CommandListLength > 0)
|
|
{
|
|
Commands = new List<MotionItem>();
|
|
for (var i = 0; i < CommandListLength; i++)
|
|
{
|
|
var motionItem = new MotionItem(moveToState.WorldObject, reader);
|
|
if (SoulEmote.SoulEmotes.Contains(motionItem.MotionCommand) && motionItem.Speed == 1.0f)
|
|
Commands.Add(motionItem);
|
|
else
|
|
log.Error($"RawMotionState reader - received non-standard action {motionItem.MotionCommand}, Speed: {motionItem.Speed} for {moveToState.WorldObject?.Name}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public string ToString(bool showFlags)
|
|
{
|
|
var sb = new StringBuilder();
|
|
|
|
if (showFlags)
|
|
sb.AppendLine($"Flags: {Flags}");
|
|
|
|
if ((Flags & RawMotionFlags.CurrentHoldKey) != 0)
|
|
sb.AppendLine($"CurrentHoldKey: {CurrentHoldKey}");
|
|
if ((Flags & RawMotionFlags.CurrentStyle) != 0)
|
|
sb.AppendLine($"CurrentStyle: {CurrentStyle}");
|
|
if ((Flags & RawMotionFlags.ForwardCommand) != 0)
|
|
sb.AppendLine($"ForwardCommand: {ForwardCommand}");
|
|
if ((Flags & RawMotionFlags.ForwardHoldKey) != 0)
|
|
sb.AppendLine($"ForwardHoldKey: {ForwardHoldKey}");
|
|
if ((Flags & RawMotionFlags.ForwardSpeed) != 0)
|
|
sb.AppendLine($"ForwardSpeed: {ForwardSpeed}");
|
|
if ((Flags & RawMotionFlags.SideStepCommand) != 0)
|
|
sb.AppendLine($"SidestepCommand: {SidestepCommand}");
|
|
if ((Flags & RawMotionFlags.SideStepHoldKey) != 0)
|
|
sb.AppendLine($"SidestepHoldKey: {SidestepHoldKey}");
|
|
if ((Flags & RawMotionFlags.SideStepSpeed) != 0)
|
|
sb.AppendLine($"SidestepSpeed: {SidestepSpeed}");
|
|
if ((Flags & RawMotionFlags.TurnCommand) != 0)
|
|
sb.AppendLine($"TurnCommand: {TurnCommand}");
|
|
if ((Flags & RawMotionFlags.TurnHoldKey) != 0)
|
|
sb.AppendLine($"TurnHoldKey: {TurnHoldKey}");
|
|
if ((Flags & RawMotionFlags.TurnSpeed) != 0)
|
|
sb.AppendLine($"TurnSpeed: {TurnSpeed}");
|
|
|
|
if (CommandListLength > 0)
|
|
{
|
|
sb.AppendLine($"CommandListLength: {CommandListLength}");
|
|
foreach (var command in Commands)
|
|
sb.Append(command);
|
|
}
|
|
|
|
sb.AppendLine("---");
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return ToString(true);
|
|
}
|
|
|
|
public bool HasMovement()
|
|
{
|
|
return (Flags & (RawMotionFlags.ForwardCommand | RawMotionFlags.TurnCommand | RawMotionFlags.SideStepCommand)) != 0;
|
|
}
|
|
|
|
public bool HasSoulEmote(bool checkForward = true)
|
|
{
|
|
if (checkForward && (Flags & RawMotionFlags.ForwardCommand) != 0 && SoulEmote.SoulEmotes.Contains(ForwardCommand))
|
|
return true;
|
|
|
|
if (CommandListLength > 0 && SoulEmote.SoulEmotes.Contains(Commands[0].MotionCommand))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|