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 = reader.ReadUInt32(); } if ((Flags & RawMotionFlags.TurnSpeed) != 0) { TurnSpeed = reader.ReadSingle(); } if (CommandListLength > 0) { Commands = new List <MotionItem>(); for (var i = 0; i < CommandListLength; i++) { Commands.Add(new MotionItem(moveToState.WorldObject, reader)); } } }
/// <summary> /// Converts a MoveToState packet from the client -> MovementData packet to send to other clients /// This is effectively a shortcut for converting RawMotionState -> InterpretedMotionState /// </summary> public MovementData(Creature creature, MoveToState state) { WorldObject = creature; var rawState = state.RawMotionState; // keeping most of this existing logic, ported from ConvertToClientAccepted if ((rawState.Flags & RawMotionFlags.CurrentStyle) != 0) { CurrentStyle = rawState.CurrentStyle; } // only using primary hold key? var holdKey = rawState.CurrentHoldKey; var speed = holdKey == HoldKey.Run ? creature.GetRunRate() : 1.0f; var interpState = new InterpretedMotionState(this); // move forwards / backwards / animation if ((rawState.Flags & RawMotionFlags.ForwardCommand) != 0 && !state.StandingLongJump) { if (rawState.ForwardCommand == MotionCommand.WalkForward || rawState.ForwardCommand == MotionCommand.WalkBackwards) { interpState.ForwardCommand = MotionCommand.WalkForward; if (rawState.ForwardCommand == MotionCommand.WalkForward && holdKey == HoldKey.Run) { interpState.ForwardCommand = MotionCommand.RunForward; } interpState.ForwardSpeed = speed; if (rawState.ForwardCommand == MotionCommand.WalkBackwards) { interpState.ForwardSpeed *= -0.65f; } } else { interpState.ForwardCommand = rawState.ForwardCommand; } } // sidestep if ((rawState.Flags & RawMotionFlags.SideStepCommand) != 0 && !state.StandingLongJump) { interpState.SidestepCommand = MotionCommand.SideStepRight; interpState.SidestepSpeed = speed * 3.12f / 1.25f * 0.5f; if (rawState.SidestepCommand == MotionCommand.SideStepLeft) { interpState.SidestepSpeed *= -1; } Math.Clamp(interpState.SidestepSpeed, -3, 3); } // rotate if ((rawState.Flags & RawMotionFlags.TurnCommand) != 0) { interpState.TurnCommand = MotionCommand.TurnRight; interpState.TurnSpeed = holdKey == HoldKey.Run ? 1.5f : 1.0f; if (rawState.TurnCommand == MotionCommand.TurnLeft) { interpState.TurnSpeed *= -1; } } // contact/sticky? // this alone isn't enough for standing long jump, // and observing clients seems to show a buggy shallow arc jump // without the above exclusions of ForwardCommand / SidestepCommand if (state.StandingLongJump) { MotionFlags |= MotionFlags.StandingLongJump; } interpState.Commands = rawState.Commands; interpState.Flags = interpState.BuildMovementFlags(); // this is a hack to make walking work correctly - investigate this // wouldn't all of these be autonomous? // walk backwards? //if (holdKey != HoldKey.Invalid || rawState.ForwardCommand == MotionCommand.WalkForward) IsAutonomous = true; Invalid = new MovementInvalid(this, interpState); }