Files
abysmal-isle/Server/Network/PacketThrottles.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

203 lines
4.6 KiB
C#

using System;
using Server.Commands;
namespace Server.Network
{
public static class PacketThrottles
{
private static readonly int[] _Delays = new int[Byte.MaxValue];
private static readonly bool[] _Reserved = new bool[Byte.MaxValue];
static PacketThrottles()
{
_Delays[0x03] = 5; // speech
_Delays[0xAD] = 5; // speech
_Delays[0x32] = 5; // fly toggle
_Delays[0x72] = 5; // war toggle
_Delays[0x3B] = 100; // vendor buy response
_Delays[0x9F] = 100; // vendor sell response
_Delays[0xB8] = 100; // profile request
_Delays[0x6F] = 100; // trade request
_Delays[0x75] = 100; // rename request
_Delays[0x9B] = 100; // help request
_Delays[0xEC] = 100; // equip macro
_Delays[0xED] = 100; // unequip macro
#region Reserved
// Reserved packets cannot be overridden by this throttle system
_Reserved[0x02] = true; // movement request, see: PlayerMobile
_Reserved[0x80] = true; // login request, see: AccountAttackLimiter
_Reserved[0x91] = true; // login request, see: AccountAttackLimiter
_Reserved[0xCF] = true; // login request, see: AccountAttackLimiter
#endregion
}
public static void Configure()
{
EventSink.WorldLoad += () => Persistence.Deserialize("Saves/PacketThrottles.bin", Load);
EventSink.WorldSave += e => Persistence.Serialize("Saves/PacketThrottles.bin", Save);
CommandSystem.Register("GetThrottle", AccessLevel.Administrator, new CommandEventHandler(GetThrottle));
CommandSystem.Register("SetThrottle", AccessLevel.Administrator, new CommandEventHandler(SetThrottle));
}
public static void Initialize()
{
for (byte i = 0; i < Byte.MaxValue; i++)
{
if (!_Reserved[i] && _Delays[i] > 0)
{
PacketHandlers.RegisterThrottler(i, HandleThrottle);
}
}
}
private static void GetThrottle(CommandEventArgs e)
{
if (e.Length != 1)
{
e.Mobile.SendMessage("Usage: {0}GetThrottle <packetID>", CommandSystem.Prefix);
return;
}
var packetID = e.GetInt32(0);
if (packetID < Byte.MinValue || packetID > Byte.MaxValue)
{
e.Mobile.SendMessage("Usage: PacketID must be between {0} and {1} inclusive", Byte.MinValue, Byte.MaxValue);
return;
}
if (_Reserved[packetID])
{
e.Mobile.SendMessage("Packet 0x{0:X2} throttle is protected.");
}
else
{
e.Mobile.SendMessage("Packet 0x{0:X2} throttle is {1}ms", packetID, _Delays[packetID]);
}
}
private static void SetThrottle(CommandEventArgs e)
{
if (e.Length < 2)
{
e.Mobile.SendMessage("Usage: {0}SetThrottle <packetID> <delayMS>", CommandSystem.Prefix);
return;
}
var packetID = e.GetInt32(0);
var delay = e.GetInt32(1);
if (packetID < Byte.MinValue || packetID > Byte.MaxValue)
{
e.Mobile.SendMessage("Usage: PacketID must be between {0} and {1} inclusive", Byte.MinValue, Byte.MaxValue);
return;
}
if (_Reserved[packetID])
{
e.Mobile.SendMessage("Packet 0x{0:X2} throttle is protected and can not be set");
return;
}
if (delay < 0 || delay > 5000)
{
e.Mobile.SendMessage("Usage: Delay must be between 0 and 5000 inclusive");
return;
}
SetThrottle((byte)packetID, delay);
if (delay > 0)
{
e.Mobile.SendMessage("Packet 0x{0:X} throttle is {1}ms", packetID, _Delays[packetID]);
}
else
{
e.Mobile.SendMessage("Packet 0x{0:X} throttle has been removed", packetID, _Delays[packetID]);
}
}
public static int GetThrottle(byte packetID)
{
if (!_Reserved[packetID])
{
return _Delays[packetID];
}
return 0;
}
public static void SetThrottle(byte packetID, int delay)
{
if (_Reserved[packetID])
{
return;
}
delay = Math.Max(0, Math.Min(5000, delay));
var oldDelay = _Delays[packetID];
if (oldDelay <= 0 && delay > 0)
{
PacketHandlers.RegisterThrottler(packetID, HandleThrottle);
}
else if (oldDelay > 0 && delay <= 0)
{
PacketHandlers.RegisterThrottler(packetID, null);
}
_Delays[packetID] = delay;
}
private static bool HandleThrottle(byte packetID, NetState ns, out bool drop)
{
drop = false;
if (ns.Mobile == null || ns.Mobile.AccessLevel >= AccessLevel.Counselor)
{
return true;
}
if (ns.IsThrottled(packetID, _Delays[packetID]))
{
drop = true;
return false;
}
return true;
}
private static void Save(GenericWriter writer)
{
writer.WriteEncodedInt(0);
for (var i = 0; i < _Delays.Length; i++)
{
writer.WriteEncodedInt(_Delays[i]);
}
}
private static void Load(GenericReader reader)
{
reader.ReadEncodedInt();
for (var i = 0; i < _Delays.Length; i++)
{
_Delays[i] = reader.ReadEncodedInt();
}
}
}
}