### Summary
- Removes Fastwalk system
- Removed the following settings:
- `movement.enableFastWalkPrevention`
- `movement.fastwalkExemptionLevel`
- Adds movement throttle system.
- Adds the following settings:
- `movement.throttleReset` - Default value is `1000` (1 second).
- `movement.throttleThreshold` - Default value is `400` (400ms).
### Movement Throttling
This new system will trigger if a player requests 400ms (configurable) worth of movements quicker than wall clock time. When this happens, the player is throttled (all incoming packets to the server are halted) until wall clock time catches up with the requests. Upon each throttle, the player receives enough credit to handle up to 400ms of "lag" as a grace/catch-up.
### Developer Notes
We use two throttle queues to prevent an infinite loop.
68 lines
1.8 KiB
C#
68 lines
1.8 KiB
C#
namespace Server.Network
|
|
{
|
|
public sealed class SpeedControl : Packet
|
|
{
|
|
public static readonly Packet WalkSpeed = SetStatic(new SpeedControl(2));
|
|
public static readonly Packet MountSpeed = SetStatic(new SpeedControl(1));
|
|
public static readonly Packet Disable = SetStatic(new SpeedControl(0));
|
|
|
|
public SpeedControl(int speedControl) : base(0xBF)
|
|
{
|
|
EnsureCapacity(6);
|
|
|
|
Stream.Write((short)0x26);
|
|
Stream.Write((byte)speedControl);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Causes the client to walk in a given direction. It does not send a movement request.
|
|
/// </summary>
|
|
public sealed class MovePlayer : Packet
|
|
{
|
|
public MovePlayer(Direction d) : base(0x97, 2)
|
|
{
|
|
Stream.Write((byte)d);
|
|
|
|
// @4C63B0
|
|
}
|
|
}
|
|
|
|
public sealed class MovementRej : Packet
|
|
{
|
|
public MovementRej(int seq, Mobile m) : base(0x21, 8)
|
|
{
|
|
Stream.Write((byte)seq);
|
|
Stream.Write((short)m.X);
|
|
Stream.Write((short)m.Y);
|
|
Stream.Write((byte)m.Direction);
|
|
Stream.Write((sbyte)m.Z);
|
|
}
|
|
}
|
|
|
|
public sealed class MovementAck : Packet
|
|
{
|
|
private static readonly MovementAck[] m_Cache = new MovementAck[8 * 256];
|
|
|
|
private MovementAck(int seq, int noto) : base(0x22, 3)
|
|
{
|
|
Stream.Write((byte)seq);
|
|
Stream.Write((byte)noto);
|
|
}
|
|
|
|
public static MovementAck Instantiate(int seq, Mobile m)
|
|
{
|
|
var noto = Notoriety.Compute(m, m);
|
|
|
|
var p = m_Cache[noto * seq];
|
|
|
|
if (p == null)
|
|
{
|
|
m_Cache[noto * seq] = p = new MovementAck(seq, noto);
|
|
p.SetStatic();
|
|
}
|
|
|
|
return p;
|
|
}
|
|
}
|
|
}
|