From 58b907d39e02b58f85a47c2deed3af2dda21981b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 4 Mar 2022 12:32:25 -0800 Subject: [PATCH] fix: Fixes packet length checks (#953) Fixes an issue with DropReq where an old client was sending in 14 bytes, but the server was expecting 15 bytes. To fix this we introduced a new packet handler, `ContainerGridPacketHandler` and changed the code to determine the length of the packet dynamically using `GetLength(NetState)`. Also fixed throttling so dropped packets are properly skipped. --- ...ocket.cs => ContainerGridPacketHandler.cs} | 34 +- Projects/Server/Network/NetState/NetState.cs | 1764 ++++++++--------- Projects/Server/Network/PacketHandler.cs | 60 +- .../Network/Packets/IncomingAccountPackets.cs | 22 +- .../Network/Packets/IncomingEntityPackets.cs | 8 +- .../Packets/IncomingExtendedCommandPackets.cs | 104 +- .../Network/Packets/IncomingHousePackets.cs | 2 +- .../Network/Packets/IncomingItemPackets.cs | 19 +- .../Network/Packets/IncomingMessagePackets.cs | 4 +- .../Network/Packets/IncomingMobilePackets.cs | 8 +- .../Packets/IncomingMovementPackets.cs | 2 +- .../Server/Network/Packets/IncomingPackets.cs | 47 +- .../Network/Packets/IncomingPlayerPackets.cs | 62 +- .../Packets/IncomingTargetingPackets.cs | 2 +- .../Network/Packets/IncomingVendorPackets.cs | 5 +- .../UOContent/Engines/Chat/ChatPackets.cs | 4 +- .../Engines/ML Quests/Gumps/RaceChangeGump.cs | 2 +- .../Engines/UltimaStore/UltimaStorePackets.cs | 2 +- Projects/UOContent/Items/Books/BookPackets.cs | 6 +- .../Bulletin Boards/BulletinBoardPackets.cs | 2 +- .../Items/Games/Mahjong/MahjongPackets.cs | 2 +- .../UOContent/Items/Maps/MapItemPackets.cs | 2 +- Projects/UOContent/Misc/HardwareInfo.cs | 2 +- Projects/UOContent/Misc/PacketThrottles.cs | 6 +- .../Multis/Houses/HouseFoundation.cs | 2 +- Projects/UOContent/Network/ConnectUO.cs | 10 +- Projects/UOContent/Network/MapUO.cs | 4 +- .../UOContent/Network/ProtocolExtensions.cs | 6 +- Projects/UOContent/Network/UOGateway.cs | 8 +- .../UOContent/Skills/Tracking/Tracking.cs | 2 +- 30 files changed, 1077 insertions(+), 1126 deletions(-) rename Projects/Server/Network/{ISocket.cs => ContainerGridPacketHandler.cs} (52%) diff --git a/Projects/Server/Network/ISocket.cs b/Projects/Server/Network/ContainerGridPacketHandler.cs similarity index 52% rename from Projects/Server/Network/ISocket.cs rename to Projects/Server/Network/ContainerGridPacketHandler.cs index 75d3d8475..ccbf94603 100644 --- a/Projects/Server/Network/ISocket.cs +++ b/Projects/Server/Network/ContainerGridPacketHandler.cs @@ -1,8 +1,8 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * - * File: ISocket.cs * + * File: ContainerGridPacketHandler.cs * * * * 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 * @@ -13,32 +13,14 @@ * along with this program. If not, see . * *************************************************************************/ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; +namespace Server.Network; -namespace Server.Network +public class ContainerGridPacketHandler : PacketHandler { - public interface ISocket + public ContainerGridPacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) + : base(packetID, length, ingame, onReceive) { - public IntPtr Handle { get; } - - public EndPoint LocalEndPoint { get; } - - public EndPoint RemoteEndPoint { get; } - - public Task SendAsync(IList> buffer, SocketFlags flags); - - public int Send(IList> buffer, SocketFlags flags); - - public Task ReceiveAsync(IList> buffer, SocketFlags flags); - - public int Receive(IList> buffers, SocketFlags flags); - - public void Shutdown(SocketShutdown how); - - public void Close(); } + + public override int GetLength(NetState ns) => base.GetLength(ns) + (ns.ContainerGridLines ? 1 : 0); } diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 7adfa951e..d76846c0b 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -31,438 +31,426 @@ using Server.Items; using Server.Logging; using Server.Menus; -namespace Server.Network +namespace Server.Network; + +public delegate void NetStateCreatedCallback(NetState ns); + +public delegate void DecodePacket(CircularBuffer buffer, ref int length); +public delegate void EncodePacket(ReadOnlySpan inputBuffer, CircularBuffer outputBuffer, out int length); + +public partial class NetState : IComparable { - public delegate void NetStateCreatedCallback(NetState ns); + private static readonly ILogger logger = LogFactory.GetLogger(typeof(NetState)); - public delegate void DecodePacket(CircularBuffer buffer, ref int length); - public delegate void EncodePacket(ReadOnlySpan inputBuffer, CircularBuffer outputBuffer, out int length); + private const int RecvPipeSize = 1024 * 64; + private const int SendPipeSize = 1024 * 256; + private const int GumpCap = 512; + private const int HuePickerCap = 512; + private const int MenuCap = 512; + private const int PacketPerSecondThreshold = 3000; - public partial class NetState : IComparable + private static GCHandle[] _polledStates = new GCHandle[2048]; + private static readonly IPollGroup _pollGroup = PollGroup.Create(); + private static readonly Queue FlushPending = new(2048); + private static readonly Queue FlushedPartials = new(2048); + private static readonly ConcurrentQueue Disposed = new(); + + public static NetStateCreatedCallback CreatedCallback { get; set; } + + private readonly string _toString; + private ClientVersion _version; + private long _nextActivityCheck; + private bool _running = true; + private volatile DecodePacket _packetDecoder; + private volatile EncodePacket _packetEncoder; + private bool _flushQueued; + private readonly long[] _packetThrottles = new long[0x100]; + private readonly long[] _packetCounts = new long[0x100]; + private string _disconnectReason = string.Empty; + + internal int _authId; + internal int _seed; + internal ParserState _parserState = ParserState.AwaitingNextPacket; + internal ProtocolState _protocolState = ProtocolState.AwaitingSeed; + internal GCHandle _handle; + private bool _packetLogging; + + internal enum ParserState { - private static readonly ILogger logger = LogFactory.GetLogger(typeof(NetState)); + AwaitingNextPacket, + AwaitingPartialPacket, + ProcessingPacket, + Throttled, + Error + } - private const int RecvPipeSize = 1024 * 64; - private const int SendPipeSize = 1024 * 256; - private const int GumpCap = 512; - private const int HuePickerCap = 512; - private const int MenuCap = 512; - private const int PacketPerSecondThreshold = 3000; + internal enum ProtocolState + { + AwaitingSeed, // Based on the way the seed arrives, we know if this is a login server or a game server connection - private static GCHandle[] _polledStates = new GCHandle[2048]; - private static readonly IPollGroup _pollGroup = PollGroup.Create(); - private static readonly Queue FlushPending = new(2048); - private static readonly Queue FlushedPartials = new(2048); - private static readonly ConcurrentQueue Disposed = new(); + LoginServer_AwaitingLogin, + LoginServer_AwaitingServerSelect, + LoginServer_ServerSelectAck, - public static NetStateCreatedCallback CreatedCallback { get; set; } + GameServer_AwaitingGameServerLogin, + GameServer_LoggedIn, - private readonly string _toString; - private ClientVersion _version; - private long _nextActivityCheck; - private bool _running = true; - private volatile DecodePacket _packetDecoder; - private volatile EncodePacket _packetEncoder; - private bool _flushQueued; - private readonly long[] _packetThrottles = new long[0x100]; - private readonly long[] _packetCounts = new long[0x100]; - private string _disconnectReason = string.Empty; + Error + } - internal int _authId; - internal int _seed; - internal ParserState _parserState = ParserState.AwaitingNextPacket; - internal ProtocolState _protocolState = ProtocolState.AwaitingSeed; - internal GCHandle _handle; - private bool _packetLogging; + private static string _packetLoggingPath; - internal enum ParserState + public static void Configure() + { + _packetLoggingPath = ServerConfiguration.GetSetting("netstate.packetLoggingPath", Path.Combine(Core.BaseDirectory, "Packets")); + } + + public static void Initialize() + { + Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1.5), CheckAllAlive); + } + + public NetState(Socket connection) + { + Connection = connection; + Seeded = false; + Gumps = new List(); + HuePickers = new List(); + Menus = new List(); + Trades = new List(); + RecvPipe = new Pipe(GC.AllocateUninitializedArray(RecvPipeSize)); + SendPipe = new Pipe(GC.AllocateUninitializedArray(SendPipeSize)); + _nextActivityCheck = Core.TickCount + 30000; + ConnectedOn = Core.Now; + + try { - AwaitingNextPacket, - AwaitingPartialPacket, - ProcessingPacket, - Throttled, - Error + Address = Utility.Intern((Connection?.RemoteEndPoint as IPEndPoint)?.Address); + _toString = Address?.ToString() ?? "(error)"; + } + catch (Exception ex) + { + TraceException(ex); + Address = IPAddress.None; + _toString = "(error)"; } - internal enum ProtocolState + _handle = GCHandle.Alloc(this); + + try { - AwaitingSeed, // Based on the way the seed arrives, we know if this is a login server or a game server connection - - LoginServer_AwaitingLogin, - LoginServer_AwaitingServerSelect, - LoginServer_ServerSelectAck, - - GameServer_AwaitingGameServerLogin, - GameServer_LoggedIn, - - Error + _pollGroup.Add(connection, _handle); + } + catch (Exception ex) + { + TraceException(ex); + Disconnect("Unable to add socket to poll group"); } - private static string _packetLoggingPath; + CreatedCallback?.Invoke(this); + } - public static void Configure() + // Only use this for debugging. This will make your server very slow! + public bool PacketLogging + { + get => _packetLogging; + set { - _packetLoggingPath = ServerConfiguration.GetSetting("netstate.packetLoggingPath", Path.Combine(Core.BaseDirectory, "Packets")); - } + _packetLogging = value; - public static void Initialize() - { - Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1.5), CheckAllAlive); - } - - public NetState(Socket connection) - { - Connection = connection; - Seeded = false; - Gumps = new List(); - HuePickers = new List(); - Menus = new List(); - Trades = new List(); - RecvPipe = new Pipe(GC.AllocateUninitializedArray(RecvPipeSize)); - SendPipe = new Pipe(GC.AllocateUninitializedArray(SendPipeSize)); - _nextActivityCheck = Core.TickCount + 30000; - ConnectedOn = Core.Now; - - try + if (_packetLogging) { - Address = Utility.Intern((Connection?.RemoteEndPoint as IPEndPoint)?.Address); - _toString = Address?.ToString() ?? "(error)"; - } - catch (Exception ex) - { - TraceException(ex); - Address = IPAddress.None; - _toString = "(error)"; - } - - _handle = GCHandle.Alloc(this); - - try - { - _pollGroup.Add(connection, _handle); - } - catch (Exception ex) - { - TraceException(ex); - Disconnect("Unable to add socket to poll group"); - } - - CreatedCallback?.Invoke(this); - } - - // Only use this for debugging. This will make your server very slow! - public bool PacketLogging - { - get => _packetLogging; - set - { - _packetLogging = value; - - if (_packetLogging) - { - StartPacketLog(); - } + StartPacketLog(); } } + } - public DateTime ConnectedOn { get; } + public DateTime ConnectedOn { get; } - public TimeSpan ConnectedFor => Core.Now - ConnectedOn; + public TimeSpan ConnectedFor => Core.Now - ConnectedOn; - public IPAddress Address { get; } + public IPAddress Address { get; } - public DecodePacket PacketDecoder + public DecodePacket PacketDecoder + { + get => _packetDecoder; + set => _packetDecoder = value; + } + + public EncodePacket PacketEncoder + { + get => _packetEncoder; + set => _packetEncoder = value; + } + + public int CurrentPacket { get; internal set; } + + public bool SentFirstPacket { get; set; } + + public bool BlockAllPackets { get; set; } + + public List Trades { get; } + + public bool Seeded { get; set; } + + public Pipe RecvPipe { get; } + + public Pipe SendPipe { get; } + + public bool Running => _running; + + public Socket Connection { get; private set; } + + public bool CompressionEnabled { get; set; } + + public int Sequence { get; set; } + + public List Gumps { get; private set; } + + public List HuePickers { get; private set; } + + public List Menus { get; private set; } + + public CityInfo[] CityInfo { get; set; } + + public Mobile Mobile { get; set; } + + public ServerInfo[] ServerInfo { get; set; } + + public IAccount Account { get; set; } + + public int CompareTo(NetState other) => string.CompareOrdinal(_toString, other?._toString); + + private void SetPacketTime(int packetID) + { + if (packetID is >= 0 and < 0x100) { - get => _packetDecoder; - set => _packetDecoder = value; - } - - public EncodePacket PacketEncoder - { - get => _packetEncoder; - set => _packetEncoder = value; - } - - public int CurrentPacket { get; internal set; } - - public bool SentFirstPacket { get; set; } - - public bool BlockAllPackets { get; set; } - - public List Trades { get; } - - public bool Seeded { get; set; } - - public Pipe RecvPipe { get; } - - public Pipe SendPipe { get; } - - public bool Running => _running; - - public Socket Connection { get; private set; } - - public bool CompressionEnabled { get; set; } - - public int Sequence { get; set; } - - public List Gumps { get; private set; } - - public List HuePickers { get; private set; } - - public List Menus { get; private set; } - - public CityInfo[] CityInfo { get; set; } - - public Mobile Mobile { get; set; } - - public ServerInfo[] ServerInfo { get; set; } - - public IAccount Account { get; set; } - - public int CompareTo(NetState other) => string.CompareOrdinal(_toString, other?._toString); - - private void SetPacketTime(int packetID) - { - if (packetID is < 0 or >= 0x100) - { - return; - } - _packetThrottles[packetID] = Core.TickCount; } + } - public long GetPacketDelay(int packetID) + public long GetPacketTime(int packetID) => packetID is >= 0 and < 0x100 ? _packetThrottles[packetID] : 0; + + private void UpdatePacketCount(int packetID) + { + if (packetID is >= 0 and < 0x100) { - if (packetID is < 0 or >= 0x100) - { - return 0; - } - - return _packetThrottles[packetID]; - } - - private void UpdatePacketCount(int packetID) - { - if (packetID is < 0 or >= 0x100) - { - return; - } - _packetCounts[packetID]++; } + } - public int CheckPacketCounts() + public int CheckPacketCounts() + { + for (int i = 0; i < _packetCounts.Length; i++) { - for (int i = 0; i < _packetCounts.Length; i++) + long count = _packetCounts[i]; + _packetCounts[i] = 0; + + if (count > PacketPerSecondThreshold) { - long count = _packetCounts[i]; - _packetCounts[i] = 0; - - if (count > PacketPerSecondThreshold) - { - return i; - } - } - - return 0; - } - - public void ValidateAllTrades() - { - for (var i = Trades.Count - 1; i >= 0; --i) - { - if (i >= Trades.Count) - { - continue; - } - - var trade = Trades[i]; - - if (trade.From.Mobile.Deleted || trade.To.Mobile.Deleted || !trade.From.Mobile.Alive || - !trade.To.Mobile.Alive || !trade.From.Mobile.InRange(trade.To.Mobile, 2) || - trade.From.Mobile.Map != trade.To.Mobile.Map) - { - trade.Cancel(); - } + return i; } } - public void CancelAllTrades() + return 0; + } + + public void ValidateAllTrades() + { + for (var i = Trades.Count - 1; i >= 0; --i) { - for (var i = Trades.Count - 1; i >= 0; --i) + if (i >= Trades.Count) { - if (i < Trades.Count) - { - Trades[i].Cancel(); - } + continue; + } + + var trade = Trades[i]; + + if (trade.From.Mobile.Deleted || trade.To.Mobile.Deleted || !trade.From.Mobile.Alive || + !trade.To.Mobile.Alive || !trade.From.Mobile.InRange(trade.To.Mobile, 2) || + trade.From.Mobile.Map != trade.To.Mobile.Map) + { + trade.Cancel(); + } + } + } + + public void CancelAllTrades() + { + for (var i = Trades.Count - 1; i >= 0; --i) + { + if (i < Trades.Count) + { + Trades[i].Cancel(); + } + } + } + + public void RemoveTrade(SecureTrade trade) + { + Trades.Remove(trade); + } + + public SecureTrade FindTrade(Mobile m) + { + for (var i = 0; i < Trades.Count; ++i) + { + var trade = Trades[i]; + + if (trade.From.Mobile == m || trade.To.Mobile == m) + { + return trade; } } - public void RemoveTrade(SecureTrade trade) - { - Trades.Remove(trade); - } + return null; + } - public SecureTrade FindTrade(Mobile m) + public SecureTradeContainer FindTradeContainer(Mobile m) + { + for (var i = 0; i < Trades.Count; ++i) { - for (var i = 0; i < Trades.Count; ++i) + var trade = Trades[i]; + + var from = trade.From; + var to = trade.To; + + if (from.Mobile == Mobile && to.Mobile == m) { - var trade = Trades[i]; - - if (trade.From.Mobile == m || trade.To.Mobile == m) - { - return trade; - } + return from.Container; } - return null; - } - - public SecureTradeContainer FindTradeContainer(Mobile m) - { - for (var i = 0; i < Trades.Count; ++i) + if (from.Mobile == m && to.Mobile == Mobile) { - var trade = Trades[i]; - - var from = trade.From; - var to = trade.To; - - if (from.Mobile == Mobile && to.Mobile == m) - { - return from.Container; - } - - if (from.Mobile == m && to.Mobile == Mobile) - { - return to.Container; - } - } - - return null; - } - - public SecureTradeContainer AddTrade(NetState state) - { - var newTrade = new SecureTrade(Mobile, state.Mobile); - - Trades.Add(newTrade); - state.Trades.Add(newTrade); - - return newTrade.From.Container; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void LogInfo(string text) - { - logger.Information("Client: {0}: {1}", this, text); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void LogInfo(string format, params object[] args) - { - LogInfo(string.Format(format, args)); - } - - public void AddMenu(IMenu menu) - { - Menus ??= new List(); - - if (Menus.Count < MenuCap) - { - Menus.Add(menu); - } - else - { - LogInfo("Exceeded menu cap, disconnecting..."); - Disconnect("Exceeded menu cap."); + return to.Container; } } - public void RemoveMenu(IMenu menu) + return null; + } + + public SecureTradeContainer AddTrade(NetState state) + { + var newTrade = new SecureTrade(Mobile, state.Mobile); + + Trades.Add(newTrade); + state.Trades.Add(newTrade); + + return newTrade.From.Container; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void LogInfo(string text) + { + logger.Information("Client: {0}: {1}", this, text); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void LogInfo(string format, params object[] args) + { + LogInfo(string.Format(format, args)); + } + + public void AddMenu(IMenu menu) + { + Menus ??= new List(); + + if (Menus.Count < MenuCap) { - Menus?.Remove(menu); + Menus.Add(menu); } - - public void RemoveMenu(int index) + else { - Menus?.RemoveAt(index); + LogInfo("Exceeded menu cap, disconnecting..."); + Disconnect("Exceeded menu cap."); } + } - public void ClearMenus() + public void RemoveMenu(IMenu menu) + { + Menus?.Remove(menu); + } + + public void RemoveMenu(int index) + { + Menus?.RemoveAt(index); + } + + public void ClearMenus() + { + Menus?.Clear(); + } + + public void AddHuePicker(HuePicker huePicker) + { + HuePickers ??= new List(); + + if (HuePickers.Count < HuePickerCap) { - Menus?.Clear(); + HuePickers.Add(huePicker); } - - public void AddHuePicker(HuePicker huePicker) + else { - HuePickers ??= new List(); - - if (HuePickers.Count < HuePickerCap) - { - HuePickers.Add(huePicker); - } - else - { - LogInfo("Exceeded hue picker cap, disconnecting..."); - Disconnect("Exceeded hue picker cap."); - } + LogInfo("Exceeded hue picker cap, disconnecting..."); + Disconnect("Exceeded hue picker cap."); } + } - public void RemoveHuePicker(HuePicker huePicker) + public void RemoveHuePicker(HuePicker huePicker) + { + HuePickers?.Remove(huePicker); + } + + public void RemoveHuePicker(int index) + { + HuePickers?.RemoveAt(index); + } + + public void ClearHuePickers() + { + HuePickers?.Clear(); + } + + public void AddGump(Gump gump) + { + Gumps ??= new List(); + + if (Gumps.Count < GumpCap) { - HuePickers?.Remove(huePicker); + Gumps.Add(gump); } - - public void RemoveHuePicker(int index) + else { - HuePickers?.RemoveAt(index); + LogInfo("Exceeded gump cap, disconnecting..."); + Disconnect("Exceeded gump cap."); } + } - public void ClearHuePickers() - { - HuePickers?.Clear(); - } + public void RemoveGump(Gump gump) + { + Gumps?.Remove(gump); + } - public void AddGump(Gump gump) - { - Gumps ??= new List(); + public void RemoveGump(int index) + { + Gumps?.RemoveAt(index); + } - if (Gumps.Count < GumpCap) - { - Gumps.Add(gump); - } - else - { - LogInfo("Exceeded gump cap, disconnecting..."); - Disconnect("Exceeded gump cap."); - } - } + public void ClearGumps() + { + Gumps?.Clear(); + } - public void RemoveGump(Gump gump) - { - Gumps?.Remove(gump); - } + public void LaunchBrowser(string url) + { + this.SendMessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231); + this.SendLaunchBrowser(url); + } - public void RemoveGump(int index) - { - Gumps?.RemoveAt(index); - } + public override string ToString() => _toString; - public void ClearGumps() - { - Gumps?.Clear(); - } - - public void LaunchBrowser(string url) - { - this.SendMessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231); - this.SendLaunchBrowser(url); - } - - public override string ToString() => _toString; - - public bool GetSendBuffer(out CircularBuffer cBuffer) - { + public bool GetSendBuffer(out CircularBuffer cBuffer) + { #if THREADGUARD if (Thread.CurrentThread != Core.Thread) { @@ -473,630 +461,629 @@ namespace Server.Network return; } #endif - var result = SendPipe.Writer.TryGetMemory(); - cBuffer = new CircularBuffer(result.Buffer); + var result = SendPipe.Writer.TryGetMemory(); + cBuffer = new CircularBuffer(result.Buffer); - return !(result.IsClosed || result.Length <= 0); + return !(result.IsClosed || result.Length <= 0); + } + + public void Send(ReadOnlySpan span) + { + if (span == null || this.CannotSendPackets()) + { + return; } - public void Send(ReadOnlySpan span) + var length = span.Length; + if (length <= 0 || !GetSendBuffer(out var buffer)) { - if (span == null || this.CannotSendPackets()) + return; + } + + try + { + PacketSendProfile prof = null; + + if (Core.Profiling) { - return; + prof = PacketSendProfile.Acquire(span[0]); + prof.Start(); } - var length = span.Length; - if (length <= 0 || !GetSendBuffer(out var buffer)) + if (_packetEncoder != null) { - return; + _packetEncoder(span, buffer, out length); + } + else + { + buffer.CopyFrom(span); } - try + if (PacketLogging) { - PacketSendProfile prof = null; + LogPacket(span, ReadOnlySpan.Empty, span.Length, false); + } - if (Core.Profiling) + SendPipe.Writer.Advance((uint)length); + + if (!_flushQueued) + { + FlushPending.Enqueue(this); + _flushQueued = true; + } + + prof?.Finish(); + } + catch (Exception ex) + { +#if DEBUG + Console.WriteLine(ex); +#endif + TraceException(ex); + Disconnect("Exception while sending."); + } + } + + private void StartPacketLog() + { + try + { + var logDir = Path.Combine(_packetLoggingPath, _toString); + PathUtility.EnsureDirectory(logDir); + var logPath = Path.Combine(logDir, "packets.log"); + using var op = new StreamWriter(logPath, true); + + op.WriteLine(">>>>>>>>>> Logging started {0:yyyy/MM/dd HH:mm::ss} <<<<<<<<<<", Core.Now); + op.WriteLine(); + op.WriteLine(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + private void LogPacket(ReadOnlySpan first, ReadOnlySpan second, int totalLength, bool incoming) + { + try + { + var logDir = Path.Combine(_packetLoggingPath, _toString); + PathUtility.EnsureDirectory(logDir); + var logPath = Path.Combine(logDir, "packets.log"); + + const string incomingStr = "Client -> Server"; + const string outgoingStr = "Server -> Client"; + + using var sw = new StreamWriter(logPath, true); + sw.WriteLine($"{Core.Now:HH:mm:ss.ffff}: {(incoming ? incomingStr : outgoingStr)} 0x{first[0]:X2} (Length: {totalLength})"); + sw.FormatBuffer(first, second, totalLength); + sw.WriteLine(); + sw.WriteLine(); + } + catch + { + // ignored + } + } + + public void HandleReceive() + { + if (!_running) + { + return; + } + + ReceiveData(); + + var reader = RecvPipe.Reader; + + try + { + // Process as many packets as we can synchronously + while (_running && _parserState != ParserState.Error && _protocolState != ProtocolState.Error) + { + var result = reader.TryRead(); + var length = result.Length; + + if (length <= 0) { - prof = PacketSendProfile.Acquire(span[0]); - prof.Start(); + break; } - if (_packetEncoder != null) + var packetReader = new CircularBufferReader(result.Buffer); + var packetId = packetReader.ReadByte(); + int packetLength = length; + + // These can arrive at any time and are only informational + if (_protocolState != ProtocolState.AwaitingSeed && IncomingPackets.IsInfoPacket(packetId)) { - _packetEncoder(span, buffer, out length); + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); } else { - buffer.CopyFrom(span); - } - - if (PacketLogging) - { - LogPacket(span, ReadOnlySpan.Empty, span.Length, false); - } - - SendPipe.Writer.Advance((uint)length); - - if (!_flushQueued) - { - FlushPending.Enqueue(this); - _flushQueued = true; - } - - prof?.Finish(); - } - catch (Exception ex) - { -#if DEBUG - Console.WriteLine(ex); -#endif - TraceException(ex); - Disconnect("Exception while sending."); - } - } - - private void StartPacketLog() - { - try - { - var logDir = Path.Combine(_packetLoggingPath, _toString); - PathUtility.EnsureDirectory(logDir); - var logPath = Path.Combine(logDir, "packets.log"); - using var op = new StreamWriter(logPath, true); - - op.WriteLine(">>>>>>>>>> Logging started {0:yyyy/MM/dd HH:mm::ss} <<<<<<<<<<", Core.Now); - op.WriteLine(); - op.WriteLine(); - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - private void LogPacket(ReadOnlySpan first, ReadOnlySpan second, int totalLength, bool incoming) - { - try - { - var logDir = Path.Combine(_packetLoggingPath, _toString); - PathUtility.EnsureDirectory(logDir); - var logPath = Path.Combine(logDir, "packets.log"); - - const string incomingStr = "Client -> Server"; - const string outgoingStr = "Server -> Client"; - - using var sw = new StreamWriter(logPath, true); - sw.WriteLine($"{Core.Now:HH:mm:ss.ffff}: {(incoming ? incomingStr : outgoingStr)} 0x{first[0]:X2} (Length: {totalLength})"); - sw.FormatBuffer(first, second, totalLength); - sw.WriteLine(); - sw.WriteLine(); - } - catch - { - // ignored - } - } - - public void HandleReceive() - { - if (!_running) - { - return; - } - - ReceiveData(); - - var reader = RecvPipe.Reader; - - try - { - // Process as many packets as we can synchronously - while (_running && _parserState != ParserState.Error && _protocolState != ProtocolState.Error) - { - var result = reader.TryRead(); - var length = result.Length; - - if (length <= 0) + switch (_protocolState) { - break; - } - - var packetReader = new CircularBufferReader(result.Buffer); - var packetId = packetReader.ReadByte(); - int packetLength = length; - - // These can arrive at any time and are only informational - if (_protocolState != ProtocolState.AwaitingSeed && IncomingPackets.IsInfoPacket(packetId)) - { - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - } - else - { - switch (_protocolState) - { - case ProtocolState.AwaitingSeed: + case ProtocolState.AwaitingSeed: + { + if (packetId == 0xEF) { - if (packetId == 0xEF) + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) { - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.LoginServer_AwaitingLogin; - } + _protocolState = ProtocolState.LoginServer_AwaitingLogin; } - else if (length >= 4) - { - int seed = (packetId << 24) | (packetReader.ReadByte() << 16) | (packetReader.ReadByte() << 8) | packetReader.ReadByte(); - - if (seed == 0) - { - HandleError(0, 0); - return; - } - - _seed = seed; - packetLength = 4; - - _parserState = ParserState.AwaitingNextPacket; - _protocolState = ProtocolState.GameServer_AwaitingGameServerLogin; - } - else - { - _parserState = ParserState.AwaitingPartialPacket; - } - break; } - - case ProtocolState.LoginServer_AwaitingLogin: + else if (length >= 4) { - if (packetId != 0xCF && packetId != 0x80) + int seed = (packetId << 24) | (packetReader.ReadByte() << 16) | (packetReader.ReadByte() << 8) | packetReader.ReadByte(); + + if (seed == 0) { - LogInfo("Possible encrypted client detected, disconnecting..."); - HandleError(packetId, packetLength); + HandleError(0, 0); return; } - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.LoginServer_AwaitingServerSelect; - } - break; - } + _seed = seed; + packetLength = 4; - case ProtocolState.LoginServer_AwaitingServerSelect: - { - if (packetId != 0xA0) - { - HandleError(packetId, packetLength); - return; - } - - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.LoginServer_ServerSelectAck; - Disconnect(string.Empty); - } - break; - } - - case ProtocolState.LoginServer_ServerSelectAck: - { -#if STRICT_UO_PROTOCOL - HandleError(packetId, packetLength); -#else - // Reset the state because CUO/Orion do not reconnect _parserState = ParserState.AwaitingNextPacket; - _protocolState = ProtocolState.AwaitingSeed; -#endif + _protocolState = ProtocolState.GameServer_AwaitingGameServerLogin; + } + else + { + _parserState = ParserState.AwaitingPartialPacket; + } + break; + } + + case ProtocolState.LoginServer_AwaitingLogin: + { + if (packetId != 0xCF && packetId != 0x80) + { + LogInfo("Possible encrypted client detected, disconnecting..."); + HandleError(packetId, packetLength); return; } - case ProtocolState.GameServer_AwaitingGameServerLogin: + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) { - if (packetId != 0x91 && packetId != 0x80) - { - HandleError(packetId, packetLength); - return; - } + _protocolState = ProtocolState.LoginServer_AwaitingServerSelect; + } + break; + } - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - if (_parserState == ParserState.AwaitingNextPacket) - { - _protocolState = ProtocolState.GameServer_LoggedIn; - } - break; + case ProtocolState.LoginServer_AwaitingServerSelect: + { + if (packetId != 0xA0) + { + HandleError(packetId, packetLength); + return; } - case ProtocolState.GameServer_LoggedIn: + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) { - _parserState = ParserState.ProcessingPacket; - _parserState = HandlePacket(packetReader, packetId, length, out packetLength); - break; + _protocolState = ProtocolState.LoginServer_ServerSelectAck; + Disconnect(string.Empty); } - } - } + break; + } - if (_parserState == ParserState.AwaitingNextPacket) - { - reader.Advance((uint)packetLength); - } - else if (_parserState is ParserState.AwaitingPartialPacket or ParserState.Throttled) - { - break; - } - else - { - HandleError(packetId, packetLength); - break; + case ProtocolState.LoginServer_ServerSelectAck: + { +#if STRICT_UO_PROTOCOL + HandleError(packetId, packetLength); +#else + // Reset the state because CUO/Orion do not reconnect + _parserState = ParserState.AwaitingNextPacket; + _protocolState = ProtocolState.AwaitingSeed; +#endif + return; + } + + case ProtocolState.GameServer_AwaitingGameServerLogin: + { + if (packetId != 0x91 && packetId != 0x80) + { + HandleError(packetId, packetLength); + return; + } + + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + if (_parserState == ParserState.AwaitingNextPacket) + { + _protocolState = ProtocolState.GameServer_LoggedIn; + } + break; + } + + case ProtocolState.GameServer_LoggedIn: + { + _parserState = ParserState.ProcessingPacket; + _parserState = HandlePacket(packetReader, packetId, out packetLength); + break; + } } } - reader.Commit(); + if (_parserState is ParserState.AwaitingNextPacket or ParserState.Throttled) + { + reader.Advance((uint)packetLength); + } + else if (_parserState is ParserState.AwaitingPartialPacket) + { + break; + } + else if (_parserState is ParserState.Error) + { + HandleError(packetId, packetLength); + break; + } } - catch (Exception ex) - { + + reader.Commit(); + } + catch (Exception ex) + { #if DEBUG Console.WriteLine(ex); #endif - TraceException(ex); - Disconnect("Exception during HandleReceive"); - } + TraceException(ex); + Disconnect("Exception during HandleReceive"); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void HandleError(byte packetId, int packetLength) + { + var msg = + $"{this} entered bad state on packet 0x{packetId:X2} with length {packetLength} while in protocol state {_protocolState} and parser state {_parserState}"; + Disconnect(msg); + _parserState = ParserState.Error; + _protocolState = ProtocolState.Error; + } + + /* + * length is the total buffer length. We might be able to use packetReader.Capacity() instead. + * packetLength is the length of the packet that this function actually found. + */ + private ParserState HandlePacket(CircularBufferReader packetReader, byte packetId, out int packetLength) + { + PacketHandler handler = IncomingPackets.GetHandler(packetId); + int length = packetReader.Length; + + if (handler == null) + { + LogInfo($"Received unknown packet 0x{packetId:X2} while in state {_protocolState}"); + packetLength = 1; + return ParserState.Error; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void HandleError(byte packetId, int packetLength) + packetLength = handler.GetLength(this); + if (packetLength <= 0) { - var msg = - $"{this} entered bad state on packet 0x{packetId:X2} with length {packetLength} while in protocol state {_protocolState} and parser state {_parserState}"; - Disconnect(msg); - _parserState = ParserState.Error; - _protocolState = ProtocolState.Error; - } - - /* - * length is the total buffer length. We might be able to use packetReader.Capacity() instead. - * packetLength is the length of the packet that this function actually found. - */ - private ParserState HandlePacket(CircularBufferReader packetReader, byte packetId, int length, out int packetLength) - { - PacketHandler handler = GetHandler(packetId); - if (handler == null) - { - LogInfo($"received unknown packet 0x{packetId:X2} while in state {_protocolState}"); - packetLength = length; - return ParserState.Error; - } - - packetLength = handler.Length; - if (packetLength <= 0) - { - // Variable length packet. See if we have pulled in the length. - if (length < 3) - { - return ParserState.AwaitingPartialPacket; - } - - packetLength = packetReader.ReadUInt16(); - if (packetLength < 3) - { - return ParserState.Error; - } - } - - // Not enough data, let's wait for more to come in - if (length < packetLength) + // Variable length packet. See if we have pulled in the length. + if (length < 3) { return ParserState.AwaitingPartialPacket; } - if (handler.Ingame) + packetLength = packetReader.ReadUInt16(); + if (packetLength < 3) { - if (Mobile == null) - { - LogInfo($"received packet 0x{packetId:X2} before having been attached to a mobile"); - return ParserState.Error; - } - - if (Mobile.Deleted) - { - return ParserState.Error; - } + return ParserState.Error; } - - ThrottlePacketCallback throttler = handler.ThrottleCallback; - if (throttler != null) - { - if (!throttler(packetId, this, out bool drop)) - { - return drop ? ParserState.AwaitingNextPacket : ParserState.Throttled; - } - - SetPacketTime(packetId); - } - - PacketReceiveProfile prof = null; - - if (Core.Profiling) - { - prof = PacketReceiveProfile.Acquire(packetId); - prof?.Start(); - } - - UpdatePacketCount(packetId); - - if (PacketLogging) - { - LogPacket(packetReader.First, packetReader.Second, packetLength, true); - } - - handler.OnReceive(this, packetReader, ref packetLength); - - prof?.Finish(packetLength); - - return ParserState.AwaitingNextPacket; } - private bool Flush() + // Not enough data, let's wait for more to come in + if (length < packetLength) { - _flushQueued = false; + return ParserState.AwaitingPartialPacket; + } - if (Connection == null) + if (handler.Ingame) + { + if (Mobile == null) { - return true; + LogInfo($"received packet 0x{packetId:X2} before having been attached to a mobile"); + return ParserState.Error; } - SendPipe.Writer.Flush(); - - var reader = SendPipe.Reader; - var result = reader.TryRead(); - - if (result.IsClosed || result.Length == 0) + if (Mobile.Deleted) { - return true; + return ParserState.Error; + } + } + + ThrottlePacketCallback throttler = handler.ThrottleCallback; + if (throttler != null) + { + if (!throttler(packetId, this, out bool drop)) + { + return drop ? ParserState.Throttled : ParserState.AwaitingNextPacket; } - var bytesWritten = 0; + SetPacketTime(packetId); + } - try - { - bytesWritten = Connection.Send(result.Buffer, SocketFlags.None); - } - catch (SocketException ex) - { - // Socket exceptions are generally ok, just spammy + PacketReceiveProfile prof = null; + + if (Core.Profiling) + { + prof = PacketReceiveProfile.Acquire(packetId); + prof?.Start(); + } + + UpdatePacketCount(packetId); + + if (PacketLogging) + { + LogPacket(packetReader.First, packetReader.Second, packetLength, true); + } + + handler.OnReceive(this, packetReader, packetLength); + + prof?.Finish(packetLength); + + return ParserState.AwaitingNextPacket; + } + + private bool Flush() + { + _flushQueued = false; + + if (Connection == null) + { + return true; + } + + SendPipe.Writer.Flush(); + + var reader = SendPipe.Reader; + var result = reader.TryRead(); + + if (result.IsClosed || result.Length == 0) + { + return true; + } + + var bytesWritten = 0; + + try + { + bytesWritten = Connection.Send(result.Buffer, SocketFlags.None); + } + catch (SocketException ex) + { + // Socket exceptions are generally ok, just spammy #if DEBUG Console.WriteLine(ex); #endif - Disconnect(string.Empty); - } - catch (Exception ex) - { + Disconnect(string.Empty); + } + catch (Exception ex) + { #if DEBUG Console.WriteLine(ex); #endif - Disconnect($"Disconnected with error: {ex}"); - TraceException(ex); - } - - if (bytesWritten > 0) - { - _nextActivityCheck = Core.TickCount + 90000; - reader.Advance((uint)bytesWritten); - } - - return bytesWritten == result.Length; + Disconnect($"Disconnected with error: {ex}"); + TraceException(ex); } - private void DecodePacket(ArraySegment[] buffer, ref int length) + if (bytesWritten > 0) { - CircularBuffer cBuffer = new CircularBuffer(buffer); - _packetDecoder?.Invoke(cBuffer, ref length); + _nextActivityCheck = Core.TickCount + 90000; + reader.Advance((uint)bytesWritten); } - private void ReceiveData() + return bytesWritten == result.Length; + } + + private void DecodePacket(ArraySegment[] buffer, ref int length) + { + CircularBuffer cBuffer = new CircularBuffer(buffer); + _packetDecoder?.Invoke(cBuffer, ref length); + } + + private void ReceiveData() + { + var writer = RecvPipe.Writer; + var result = writer.TryGetMemory(); + + if (result.IsClosed || result.Length == 0) { - var writer = RecvPipe.Writer; - var result = writer.TryGetMemory(); + return; + } - if (result.IsClosed || result.Length == 0) - { - return; - } + var bytesWritten = 0; - var bytesWritten = 0; - - try - { - bytesWritten = Connection.Receive(result.Buffer, SocketFlags.None); - } - catch (SocketException ex) - { + try + { + bytesWritten = Connection.Receive(result.Buffer, SocketFlags.None); + } + catch (SocketException ex) + { #if DEBUG if (ex.ErrorCode != 54 && ex.ErrorCode != 89 && ex.ErrorCode != 995) { Console.WriteLine(ex); } #endif - Disconnect(string.Empty); - } - catch (Exception ex) - { + Disconnect(string.Empty); + } + catch (Exception ex) + { #if DEBUG Console.WriteLine(ex); #endif - Disconnect($"Disconnected with error: {ex}"); - TraceException(ex); - } - - if (bytesWritten <= 0) - { - Disconnect(string.Empty); - return; - } - - DecodePacket(result.Buffer, ref bytesWritten); - - writer.Advance((uint)bytesWritten); - _nextActivityCheck = Core.TickCount + 90000; + Disconnect($"Disconnected with error: {ex}"); + TraceException(ex); } - public static void FlushAll() + if (bytesWritten <= 0) { - while (FlushPending.Count != 0) + Disconnect(string.Empty); + return; + } + + DecodePacket(result.Buffer, ref bytesWritten); + + writer.Advance((uint)bytesWritten); + _nextActivityCheck = Core.TickCount + 90000; + } + + public static void FlushAll() + { + while (FlushPending.Count != 0) + { + FlushPending.Dequeue()?.Flush(); + } + } + + public static void Slice() + { + int count = _pollGroup.Poll(ref _polledStates); + + if (count > 0) + { + for (int i = 0; i < count; i++) { - FlushPending.Dequeue()?.Flush(); + (_polledStates[i].Target as NetState)?.HandleReceive(); + _polledStates[i] = default; } } - public static void Slice() + while (FlushPending.TryDequeue(out var ns)) { - int count = _pollGroup.Poll(ref _polledStates); - - if (count > 0) + if (!ns.Flush()) { - for (int i = 0; i < count; i++) - { - (_polledStates[i].Target as NetState)?.HandleReceive(); - _polledStates[i] = default; - } - } - - while (FlushPending.TryDequeue(out var ns)) - { - if (!ns.Flush()) - { - // Incomplete data, so we need to requeue - FlushedPartials.Enqueue(ns); - } - } - - var hasDisposes = !Disposed.IsEmpty; - while (Disposed.TryDequeue(out var ns)) - { - ns.Dispose(); - } - - if (hasDisposes) - { - _pollGroup.Poll(ref _polledStates); + // Incomplete data, so we need to requeue + FlushedPartials.Enqueue(ns); } } - public void CheckAlive(long curTicks) + var hasDisposes = !Disposed.IsEmpty; + while (Disposed.TryDequeue(out var ns)) { - if (Connection != null && _nextActivityCheck - curTicks < 0) - { - LogInfo("Disconnecting due to inactivity..."); - Disconnect("Disconnecting due to inactivity."); - } + ns.Dispose(); } - public static void CheckAllAlive() + if (hasDisposes) { - try - { - long curTicks = Core.TickCount; + _pollGroup.Poll(ref _polledStates); + } + } - foreach (var ns in TcpServer.Instances) - { - ns.CheckAlive(curTicks); - } - } - catch (Exception ex) + public void CheckAlive(long curTicks) + { + if (Connection != null && _nextActivityCheck - curTicks < 0) + { + LogInfo("Disconnecting due to inactivity..."); + Disconnect("Disconnecting due to inactivity."); + } + } + + public static void CheckAllAlive() + { + try + { + long curTicks = Core.TickCount; + + foreach (var ns in TcpServer.Instances) { - TraceException(ex); + ns.CheckAlive(curTicks); } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public PacketHandler GetHandler(int packetID) => IncomingPackets.GetHandler(packetID); - - public static void TraceException(Exception ex) + catch (Exception ex) { - try - { - using var op = new StreamWriter("network-errors.log", true); - op.WriteLine("# {0}", Core.Now); + TraceException(ex); + } + } - op.WriteLine(ex); + public static void TraceException(Exception ex) + { + try + { + using var op = new StreamWriter("network-errors.log", true); + op.WriteLine("# {0}", Core.Now); - op.WriteLine(); - op.WriteLine(); - } - catch - { - // ignored - } + op.WriteLine(ex); - Console.WriteLine(ex); + op.WriteLine(); + op.WriteLine(); + } + catch + { + // ignored } - public void Disconnect(string reason) + Console.WriteLine(ex); + } + + public void Disconnect(string reason) + { + if (!_running) { - if (!_running) - { - return; - } - - _running = false; - - try - { - if (_disconnectReason != string.Empty) - { - throw new Exception("Attempted to disconnect a netstate twice."); - } - } - catch (Exception ex) - { - TraceException(ex); - } - - _disconnectReason = reason; - Disposed.Enqueue(this); + return; } - public static void TraceDisconnect(string reason, string ip) + _running = false; + + try { - if (reason == string.Empty) + if (_disconnectReason != string.Empty) { - return; - } - - try - { - using StreamWriter op = new StreamWriter("network-disconnects.log", true); - op.WriteLine($"# {Core.Now}"); - - op.WriteLine($"NetState: {ip}"); - op.WriteLine(reason); - - op.WriteLine(); - op.WriteLine(); - } - catch (Exception ex) - { - TraceException(ex); + throw new Exception("Attempted to disconnect a netstate twice."); } } - - private void Dispose() + catch (Exception ex) { - TraceDisconnect(_disconnectReason, _toString); + TraceException(ex); + } - if (_running) - { - throw new Exception("Disconnected a NetState that is still running."); - } + _disconnectReason = reason; + Disposed.Enqueue(this); + } + + public static void TraceDisconnect(string reason, string ip) + { + if (reason == string.Empty) + { + return; + } + + try + { + using StreamWriter op = new StreamWriter("network-disconnects.log", true); + op.WriteLine($"# {Core.Now}"); + + op.WriteLine($"NetState: {ip}"); + op.WriteLine(reason); + + op.WriteLine(); + op.WriteLine(); + } + catch (Exception ex) + { + TraceException(ex); + } + } + + private void Dispose() + { + TraceDisconnect(_disconnectReason, _toString); + + if (_running) + { + throw new Exception("Disconnected a NetState that is still running."); + } #if THREADGUARD if (Thread.CurrentThread != Core.Thread) @@ -1109,46 +1096,45 @@ namespace Server.Network } #endif - TcpServer.Instances.Remove(this); - try - { - _pollGroup.Remove(Connection); - } - catch (Exception ex) - { - TraceException(ex); - } + TcpServer.Instances.Remove(this); + try + { + _pollGroup.Remove(Connection); + } + catch (Exception ex) + { + TraceException(ex); + } - Connection.Close(); - _handle.Free(); + Connection.Close(); + _handle.Free(); - var m = Mobile; - Mobile = null; + var m = Mobile; + Mobile = null; - if (m?.NetState == this) - { - m.NetState = null; - } + if (m?.NetState == this) + { + m.NetState = null; + } - var a = Account; + var a = Account; - Gumps.Clear(); - Menus.Clear(); - HuePickers.Clear(); - Account = null; - ServerInfo = null; - CityInfo = null; + Gumps.Clear(); + Menus.Clear(); + HuePickers.Clear(); + Account = null; + ServerInfo = null; + CityInfo = null; - var count = TcpServer.Instances.Count; + var count = TcpServer.Instances.Count; - if (a != null) - { - LogInfo("Disconnected. [{0} Online] [{1}]", count, a); - } - else - { - LogInfo("Disconnected. [{0} Online]", count); - } + if (a != null) + { + LogInfo("Disconnected. [{0} Online] [{1}]", count, a); + } + else + { + LogInfo("Disconnected. [{0} Online]", count); } } } diff --git a/Projects/Server/Network/PacketHandler.cs b/Projects/Server/Network/PacketHandler.cs index 664119b30..fdf13b589 100644 --- a/Projects/Server/Network/PacketHandler.cs +++ b/Projects/Server/Network/PacketHandler.cs @@ -1,27 +1,43 @@ -namespace Server.Network +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: PacketHandler.cs * + * * + * 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Network; + +public delegate void OnPacketReceive(NetState state, CircularBufferReader reader, int packetLength); + +public delegate bool ThrottlePacketCallback(int packetId, NetState state, out bool drop); + +public class PacketHandler { - public delegate void OnPacketReceive(NetState state, CircularBufferReader reader, ref int packetLength); + private int _length; - public delegate bool ThrottlePacketCallback(int packetId, NetState state, out bool drop); - - public class PacketHandler + public PacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) { - public PacketHandler(int packetID, int length, bool ingame, OnPacketReceive onReceive) - { - PacketID = packetID; - Length = length; - Ingame = ingame; - OnReceive = onReceive; - } - - public int PacketID { get; } - - public int Length { get; } - - public OnPacketReceive OnReceive { get; } - - public ThrottlePacketCallback ThrottleCallback { get; set; } - - public bool Ingame { get; } + _length = length; + PacketID = packetID; + Ingame = ingame; + OnReceive = onReceive; } + + public int PacketID { get; } + + public virtual int GetLength(NetState ns) => _length; + + public OnPacketReceive OnReceive { get; } + + public ThrottlePacketCallback ThrottleCallback { get; set; } + + public bool Ingame { get; } } diff --git a/Projects/Server/Network/Packets/IncomingAccountPackets.cs b/Projects/Server/Network/Packets/IncomingAccountPackets.cs index 41bf8919d..a29d6157c 100644 --- a/Projects/Server/Network/Packets/IncomingAccountPackets.cs +++ b/Projects/Server/Network/Packets/IncomingAccountPackets.cs @@ -55,7 +55,7 @@ public static class IncomingAccountPackets IncomingPackets.Register(0xF8, 106, false, CreateCharacter); } - public static void CreateCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CreateCharacter(NetState state, CircularBufferReader reader, int packetLength) { reader.Seek(9, SeekOrigin.Current); /* @@ -185,7 +185,7 @@ public static class IncomingAccountPackets } } - public static void DeleteCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DeleteCharacter(NetState state, CircularBufferReader reader, int packetLength) { reader.Seek(30, SeekOrigin.Current); var index = reader.ReadInt32(); @@ -193,24 +193,24 @@ public static class IncomingAccountPackets EventSink.InvokeDeleteRequest(state, index); } - public static void AccountID(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AccountID(NetState state, CircularBufferReader reader, int packetLength) { } - public static void AssistVersion(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AssistVersion(NetState state, CircularBufferReader reader, int packetLength) { var unk = reader.ReadInt32(); var av = reader.ReadAscii(); } - public static void ClientVersion(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ClientVersion(NetState state, CircularBufferReader reader, int packetLength) { var version = state.Version = new CV(reader.ReadAscii()); EventSink.InvokeClientVersionReceived(state, version); } - public static void ClientType(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ClientType(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadUInt16(); @@ -220,7 +220,7 @@ public static class IncomingAccountPackets EventSink.InvokeClientVersionReceived(state, version); } - public static void PlayCharacter(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PlayCharacter(NetState state, CircularBufferReader reader, int packetLength) { reader.Seek(4, SeekOrigin.Current); // 0xEDEDEDED @@ -359,7 +359,7 @@ public static class IncomingAccountPackets return authID; } - public static void GameLogin(NetState state, CircularBufferReader reader, ref int packetLength) + public static void GameLogin(NetState state, CircularBufferReader reader, int packetLength) { // TODO: Connection throttling @@ -413,7 +413,7 @@ public static class IncomingAccountPackets } } - public static void PlayServer(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PlayServer(NetState state, CircularBufferReader reader, int packetLength) { int index = reader.ReadInt16(); var info = state.ServerInfo; @@ -434,7 +434,7 @@ public static class IncomingAccountPackets } } - public static void LoginServerSeed(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LoginServerSeed(NetState state, CircularBufferReader reader, int packetLength) { state._seed = reader.ReadInt32(); state.Seeded = true; @@ -454,7 +454,7 @@ public static class IncomingAccountPackets state.Version = new ClientVersion(clientMaj, clientMin, clientRev, clientPat); } - public static void AccountLogin(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AccountLogin(NetState state, CircularBufferReader reader, int packetLength) { // TODO: Throttle Connection diff --git a/Projects/Server/Network/Packets/IncomingEntityPackets.cs b/Projects/Server/Network/Packets/IncomingEntityPackets.cs index bd2815eee..40fe5a252 100644 --- a/Projects/Server/Network/Packets/IncomingEntityPackets.cs +++ b/Projects/Server/Network/Packets/IncomingEntityPackets.cs @@ -27,7 +27,7 @@ public static class IncomingEntityPackets IncomingPackets.Register(0xD6, 0, true, BatchQueryProperties); } - public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ObjectHelpRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -56,7 +56,7 @@ public static class IncomingEntityPackets } } - public static void UseReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UseReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -100,7 +100,7 @@ public static class IncomingEntityPackets } } - public static void LookReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LookReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -149,7 +149,7 @@ public static class IncomingEntityPackets } } - public static void BatchQueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) + public static void BatchQueryProperties(NetState state, CircularBufferReader reader, int packetLength) { if (!ObjectPropertyList.Enabled) { diff --git a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs index e082c70e1..bda5b3917 100644 --- a/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs +++ b/Projects/Server/Network/Packets/IncomingExtendedCommandPackets.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: IncomingExtendedCommandPackets.cs * * * @@ -13,15 +13,13 @@ * along with this program. If not, see . * *************************************************************************/ -using System.Collections.Generic; using Server.ContextMenus; namespace Server.Network; public static class IncomingExtendedCommandPackets { - private static readonly PacketHandler[] m_ExtendedHandlersLow = new PacketHandler[0x100]; - private static readonly Dictionary m_ExtendedHandlersHigh = new(); + private static readonly PacketHandler[] _extendedHandlers = new PacketHandler[0x100]; // TODO: Change to outside configuration public static int[] ValidAnimations { get; set; } = @@ -61,50 +59,34 @@ public static class IncomingExtendedCommandPackets RegisterExtended(0x32, true, ToggleFlying); } - private static void UnhandledBF(NetState state, CircularBufferReader reader, ref int packetLength) + private static void UnhandledBF(NetState state, CircularBufferReader reader, int packetLength) { } - public static void Empty(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Empty(NetState state, CircularBufferReader reader, int packetLength) { } public static void RegisterExtended(int packetID, bool ingame, OnPacketReceive onReceive) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_ExtendedHandlersLow[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); - } - else - { - m_ExtendedHandlersHigh[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); + _extendedHandlers[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); } } - public static PacketHandler GetExtendedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - return m_ExtendedHandlersLow[packetID]; - } - - m_ExtendedHandlersHigh.TryGetValue(packetID, out var handler); - return handler; - } + public static PacketHandler GetExtendedHandler(int packetID) => + packetID is >= 0 and < 0x100 ? _extendedHandlers[packetID] : null; public static void RemoveExtendedHandler(int packetID) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_ExtendedHandlersLow[packetID] = null; - } - else - { - m_ExtendedHandlersHigh.Remove(packetID); + _extendedHandlers[packetID] = null; } } - public static void ExtendedCommand(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ExtendedCommand(NetState state, CircularBufferReader reader, int packetLength) { int packetId = reader.ReadUInt16(); @@ -130,18 +112,18 @@ public static class IncomingExtendedCommandPackets } else { - ph.OnReceive(state, reader, ref packetLength); + ph.OnReceive(state, reader, packetLength); } } - public static void ScreenSize(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ScreenSize(NetState state, CircularBufferReader reader, int packetLength) { var width = reader.ReadInt32(); var unk = reader.ReadInt32(); } // TODO: Move out of the core - public static void PartyMessage(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage(NetState state, CircularBufferReader reader, int packetLength) { if (state.Mobile == null) { @@ -151,25 +133,25 @@ public static class IncomingExtendedCommandPackets switch (reader.ReadByte()) { case 0x01: - PartyMessage_AddMember(state, reader, ref packetLength); + PartyMessage_AddMember(state, reader, packetLength); break; case 0x02: - PartyMessage_RemoveMember(state, reader, ref packetLength); + PartyMessage_RemoveMember(state, reader, packetLength); break; case 0x03: - PartyMessage_PrivateMessage(state, reader, ref packetLength); + PartyMessage_PrivateMessage(state, reader, packetLength); break; case 0x04: - PartyMessage_PublicMessage(state, reader, ref packetLength); + PartyMessage_PublicMessage(state, reader, packetLength); break; case 0x06: - PartyMessage_SetCanLoot(state, reader, ref packetLength); + PartyMessage_SetCanLoot(state, reader, packetLength); break; case 0x08: - PartyMessage_Accept(state, reader, ref packetLength); + PartyMessage_Accept(state, reader, packetLength); break; case 0x09: - PartyMessage_Decline(state, reader, ref packetLength); + PartyMessage_Decline(state, reader, packetLength); break; default: reader.Trace(state); @@ -177,17 +159,17 @@ public static class IncomingExtendedCommandPackets } } - public static void PartyMessage_AddMember(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_AddMember(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnAdd(state.Mobile); } - public static void PartyMessage_RemoveMember(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_RemoveMember(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnRemove(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); } - public static void PartyMessage_PrivateMessage(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_PrivateMessage(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnPrivateMessage( state.Mobile, @@ -196,27 +178,27 @@ public static class IncomingExtendedCommandPackets ); } - public static void PartyMessage_PublicMessage(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_PublicMessage(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnPublicMessage(state.Mobile, reader.ReadBigUniSafe()); } - public static void PartyMessage_SetCanLoot(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_SetCanLoot(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnSetCanLoot(state.Mobile, reader.ReadBoolean()); } - public static void PartyMessage_Accept(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_Accept(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnAccept(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); } - public static void PartyMessage_Decline(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PartyMessage_Decline(NetState state, CircularBufferReader reader, int packetLength) { PartyCommands.Handler?.OnDecline(state.Mobile, World.FindMobile((Serial)reader.ReadUInt32())); } - public static void Animate(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Animate(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -240,7 +222,7 @@ public static class IncomingExtendedCommandPackets } } - public static void CastSpell(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CastSpell(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -255,12 +237,12 @@ public static class IncomingExtendedCommandPackets EventSink.InvokeCastSpellRequest(from, spellID, spellbook); } - public static void ToggleFlying(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ToggleFlying(NetState state, CircularBufferReader reader, int packetLength) { state.Mobile?.ToggleFlying(); } - public static void StunRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void StunRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -272,7 +254,7 @@ public static class IncomingExtendedCommandPackets EventSink.InvokeStunRequest(from); } - public static void DisarmRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DisarmRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -284,7 +266,7 @@ public static class IncomingExtendedCommandPackets EventSink.InvokeDisarmRequest(from); } - public static void StatLockChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void StatLockChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -315,12 +297,12 @@ public static class IncomingExtendedCommandPackets } } - public static void CloseStatus(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CloseStatus(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); } - public static void Language(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Language(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -332,7 +314,7 @@ public static class IncomingExtendedCommandPackets from.Language = reader.ReadAscii(4); } - public static void QueryProperties(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryProperties(NetState state, CircularBufferReader reader, int packetLength) { if (!ObjectPropertyList.Enabled) { @@ -364,7 +346,7 @@ public static class IncomingExtendedCommandPackets } } - public static void ContextMenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ContextMenuResponse(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -420,7 +402,7 @@ public static class IncomingExtendedCommandPackets } } - public static void ContextMenuRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ContextMenuRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; var target = World.FindEntity((Serial)reader.ReadUInt32()); @@ -455,7 +437,7 @@ public static class IncomingExtendedCommandPackets } } - public static void BandageTarget(NetState state, CircularBufferReader reader, ref int packetLength) + public static void BandageTarget(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -490,21 +472,21 @@ public static class IncomingExtendedCommandPackets } } - public static void TargetedSpell(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetedSpell(NetState state, CircularBufferReader reader, int packetLength) { var spellId = (short)(reader.ReadInt16() - 1); // zero based; EventSink.InvokeTargetedSpell(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), spellId); } - public static void TargetedSkillUse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetedSkillUse(NetState state, CircularBufferReader reader, int packetLength) { var skillId = reader.ReadInt16(); EventSink.InvokeTargetedSkillUse(state.Mobile, World.FindEntity((Serial)reader.ReadUInt32()), skillId); } - public static void TargetByResourceMacro(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetByResourceMacro(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); diff --git a/Projects/Server/Network/Packets/IncomingHousePackets.cs b/Projects/Server/Network/Packets/IncomingHousePackets.cs index b5969f56c..1d9925537 100644 --- a/Projects/Server/Network/Packets/IncomingHousePackets.cs +++ b/Projects/Server/Network/Packets/IncomingHousePackets.cs @@ -22,7 +22,7 @@ public static class IncomingHousePackets IncomingPackets.Register(0xFB, 2, false, ShowPublicHouseContent); } - public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ShowPublicHouseContent(NetState state, CircularBufferReader reader, int packetLength) { var showPublicHouseContent = reader.ReadBoolean(); } diff --git a/Projects/Server/Network/Packets/IncomingItemPackets.cs b/Projects/Server/Network/Packets/IncomingItemPackets.cs index 0e3cf6601..06543cadf 100644 --- a/Projects/Server/Network/Packets/IncomingItemPackets.cs +++ b/Projects/Server/Network/Packets/IncomingItemPackets.cs @@ -24,13 +24,13 @@ public static class IncomingItemPackets public static void Configure() { IncomingPackets.Register(0x07, 7, true, LiftReq); - IncomingPackets.Register(0x08, 15, true, DropReq); + IncomingPackets.Register(new ContainerGridPacketHandler(0x08, 14, true, DropReq)); IncomingPackets.Register(0x13, 10, true, EquipReq); IncomingPackets.Register(0xEC, 0, false, EquipMacro); IncomingPackets.Register(0xED, 0, false, UnequipMacro); } - public static void LiftReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LiftReq(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); int amount = reader.ReadUInt16(); @@ -39,7 +39,7 @@ public static class IncomingItemPackets state.Mobile.Lift(item, amount, out _, out _); } - public static void EquipReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void EquipReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; var item = from.Holding; @@ -64,20 +64,17 @@ public static class IncomingItemPackets item.ClearBounce(); } - public static void DropReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DropReq(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadInt32(); // serial, ignored int x = reader.ReadInt16(); int y = reader.ReadInt16(); int z = reader.ReadSByte(); + if (state.ContainerGridLines) { reader.ReadByte(); // Grid Location? } - else - { - packetLength -= 1; - } Serial dest = (Serial)reader.ReadUInt32(); @@ -110,7 +107,7 @@ public static class IncomingItemPackets } } - public static void DropReq6017(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DropReq6017(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadInt32(); // serial, ignored int x = reader.ReadInt16(); @@ -148,7 +145,7 @@ public static class IncomingItemPackets } } - public static void EquipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + public static void EquipMacro(NetState state, CircularBufferReader reader, int packetLength) { int count = reader.ReadByte(); var serialList = new List(count); @@ -160,7 +157,7 @@ public static class IncomingItemPackets EventSink.InvokeEquipMacro(state.Mobile, serialList); } - public static void UnequipMacro(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UnequipMacro(NetState state, CircularBufferReader reader, int packetLength) { int count = reader.ReadByte(); var layers = new List(count); diff --git a/Projects/Server/Network/Packets/IncomingMessagePackets.cs b/Projects/Server/Network/Packets/IncomingMessagePackets.cs index 0f25bf85e..8bea6bb45 100644 --- a/Projects/Server/Network/Packets/IncomingMessagePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMessagePackets.cs @@ -46,7 +46,7 @@ public static class IncomingMessagePackets IncomingPackets.Register(0xAD, 0, true, UnicodeSpeech); } - public static void AsciiSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AsciiSpeech(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -73,7 +73,7 @@ public static class IncomingMessagePackets from.DoSpeech(text, Array.Empty(), type, Utility.ClipDyedHue(hue)); } - public static void UnicodeSpeech(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UnicodeSpeech(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/Server/Network/Packets/IncomingMobilePackets.cs b/Projects/Server/Network/Packets/IncomingMobilePackets.cs index 569fa430b..a612e4ea1 100644 --- a/Projects/Server/Network/Packets/IncomingMobilePackets.cs +++ b/Projects/Server/Network/Packets/IncomingMobilePackets.cs @@ -27,7 +27,7 @@ public static class IncomingMobilePackets IncomingPackets.Register(0x6F, 0, true, SecureTrade); } - public static void RenameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void RenameRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; var targ = World.FindMobile((Serial)reader.ReadUInt32()); @@ -38,7 +38,7 @@ public static class IncomingMobilePackets } } - public static void MobileNameRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MobileNameRequest(NetState state, CircularBufferReader reader, int packetLength) { var m = World.FindMobile((Serial)reader.ReadUInt32()); @@ -48,7 +48,7 @@ public static class IncomingMobilePackets } } - public static void ProfileReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ProfileReq(NetState state, CircularBufferReader reader, int packetLength) { int type = reader.ReadByte(); var serial = (Serial)reader.ReadUInt32(); @@ -88,7 +88,7 @@ public static class IncomingMobilePackets } } - public static void SecureTrade(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SecureTrade(NetState state, CircularBufferReader reader, int packetLength) { switch (reader.ReadByte()) { diff --git a/Projects/Server/Network/Packets/IncomingMovementPackets.cs b/Projects/Server/Network/Packets/IncomingMovementPackets.cs index 0a82df9a7..9a361bfa2 100644 --- a/Projects/Server/Network/Packets/IncomingMovementPackets.cs +++ b/Projects/Server/Network/Packets/IncomingMovementPackets.cs @@ -78,7 +78,7 @@ public static class IncomingMovementPackets ns.SendTimeSyncResponse(); } - public static void MovementReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MovementReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/Server/Network/Packets/IncomingPackets.cs b/Projects/Server/Network/Packets/IncomingPackets.cs index 71fbfd578..1eaec8c45 100644 --- a/Projects/Server/Network/Packets/IncomingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPackets.cs @@ -1,6 +1,6 @@ /************************************************************************* * ModernUO * - * Copyright (C) 2019-2021 - ModernUO Development Team * + * Copyright 2019-2022 - ModernUO Development Team * * Email: hi@modernuo.com * * File: IncomingPackets.cs * * * @@ -13,62 +13,43 @@ * along with this program. If not, see . * *************************************************************************/ -using System.Collections.Generic; using System.Runtime.CompilerServices; namespace Server.Network; public static class IncomingPackets { - private static readonly PacketHandler[] m_6017Handlers = new PacketHandler[0x100]; - - private static readonly EncodedPacketHandler[] m_EncodedHandlersLow = new EncodedPacketHandler[0x100]; - - private static readonly Dictionary m_EncodedHandlersHigh = - new(); + private static readonly EncodedPacketHandler[] _encodedHandlers = new EncodedPacketHandler[0x100]; public static PacketHandler[] Handlers { get; } = new PacketHandler[0x100]; - public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) => + Register(new PacketHandler(packetID, length, ingame, onReceive)); + + public static void Register(PacketHandler packetHandler) { - Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive); - m_6017Handlers[packetID] ??= new PacketHandler(packetID, length, ingame, onReceive); + Handlers[packetHandler.PacketID] = packetHandler; } public static PacketHandler GetHandler(int packetID) => Handlers[packetID]; public static void RegisterEncoded(int packetID, bool ingame, OnEncodedPacketReceive onReceive) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_EncodedHandlersLow[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); - } - else - { - m_EncodedHandlersHigh[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); + _encodedHandlers[packetID] = new EncodedPacketHandler(packetID, ingame, onReceive); } } - public static EncodedPacketHandler GetEncodedHandler(int packetID) - { - if (packetID >= 0 && packetID < 0x100) - { - return m_EncodedHandlersLow[packetID]; - } - - m_EncodedHandlersHigh.TryGetValue(packetID, out var handler); - return handler; - } + public static EncodedPacketHandler GetEncodedHandler(int packetID) => + packetID is >= 0 and < 0x100 ? _encodedHandlers[packetID] : null; public static void RemoveEncodedHandler(int packetID) { - if (packetID >= 0 && packetID < 0x100) + if (packetID is >= 0 and < 0x100) { - m_EncodedHandlersLow[packetID] = null; - } - else - { - m_EncodedHandlersHigh.Remove(packetID); + _encodedHandlers[packetID] = null; } } diff --git a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs index 2b7e14515..0a6f18c97 100644 --- a/Projects/Server/Network/Packets/IncomingPlayerPackets.cs +++ b/Projects/Server/Network/Packets/IncomingPlayerPackets.cs @@ -52,18 +52,18 @@ public static class IncomingPlayerPackets IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest); } - public static void DeathStatusResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DeathStatusResponse(NetState state, CircularBufferReader reader, int packetLength) { // Ignored } - public static void RequestScrollWindow(NetState state, CircularBufferReader reader, ref int packetLength) + public static void RequestScrollWindow(NetState state, CircularBufferReader reader, int packetLength) { int lastTip = reader.ReadInt16(); int type = reader.ReadByte(); } - public static void AttackReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AttackReq(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -80,7 +80,7 @@ public static class IncomingPlayerPackets } } - public static void HuePickerResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HuePickerResponse(NetState state, CircularBufferReader reader, int packetLength) { var serial = reader.ReadUInt32(); _ = reader.ReadInt16(); // Item ID @@ -97,7 +97,7 @@ public static class IncomingPlayerPackets } } - public static void SystemInfo(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SystemInfo(NetState state, CircularBufferReader reader, int packetLength) { int v1 = reader.ReadByte(); int v2 = reader.ReadUInt16(); @@ -113,7 +113,7 @@ public static class IncomingPlayerPackets var v8 = reader.ReadInt32(); } - public static void TextCommand(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TextCommand(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -208,7 +208,7 @@ public static class IncomingPlayerPackets } } - public static void AsciiPromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void AsciiPromptResponse(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -244,7 +244,7 @@ public static class IncomingPlayerPackets } } - public static void UnicodePromptResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UnicodePromptResponse(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -281,7 +281,7 @@ public static class IncomingPlayerPackets } } - public static void MenuResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MenuResponse(NetState state, CircularBufferReader reader, int packetLength) { var serial = reader.ReadUInt32(); int menuID = reader.ReadInt16(); // unused in our implementation @@ -311,33 +311,33 @@ public static class IncomingPlayerPackets } } - public static void Disconnect(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Disconnect(NetState state, CircularBufferReader reader, int packetLength) { var minusOne = reader.ReadInt32(); } - public static void ConfigurationFile(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ConfigurationFile(NetState state, CircularBufferReader reader, int packetLength) { } - public static void LogoutReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void LogoutReq(NetState state, CircularBufferReader reader, int packetLength) { state.SendLogoutAck(); } - public static void ChangeSkillLock(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ChangeSkillLock(NetState state, CircularBufferReader reader, int packetLength) { var s = state.Mobile.Skills[reader.ReadInt16()]; s?.SetLockNoRelay((SkillLock)reader.ReadByte()); } - public static void HelpRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HelpRequest(NetState state, CircularBufferReader reader, int packetLength) { EventSink.InvokeHelpRequest(state.Mobile); } - public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); var typeID = reader.ReadInt32(); @@ -479,13 +479,13 @@ public static class IncomingPlayerPackets } } - public static void SetWarMode(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SetWarMode(NetState state, CircularBufferReader reader, int packetLength) { state.Mobile?.DelayChangeWarmode(reader.ReadBoolean()); } // TODO: Throttle/make this more safe - public static void Resynchronize(NetState state, CircularBufferReader reader, ref int packetLength) + public static void Resynchronize(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -502,17 +502,17 @@ public static class IncomingPlayerPackets state.Sequence = 0; } - public static void PingReq(NetState state, CircularBufferReader reader, ref int packetLength) + public static void PingReq(NetState state, CircularBufferReader reader, int packetLength) { state.SendPingAck(reader.ReadByte()); } - public static void SetUpdateRange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void SetUpdateRange(NetState state, CircularBufferReader reader, int packetLength) { state.SendChangeUpdateRange(18); } - public static void MobileQuery(NetState state, CircularBufferReader reader, ref int packetLength) + public static void MobileQuery(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; if (from == null) @@ -549,7 +549,7 @@ public static class IncomingPlayerPackets } } - public static void CrashReport(NetState state, CircularBufferReader reader, ref int packetLength) + public static void CrashReport(NetState state, CircularBufferReader reader, int packetLength) { var clientMaj = reader.ReadByte(); var clientMin = reader.ReadByte(); @@ -593,11 +593,19 @@ public static class IncomingPlayerPackets EventSink.InvokeQuestGumpRequest(state.Mobile); } - public static void EncodedCommand(NetState state, CircularBufferReader reader, ref int packetLength) + public static void EncodedCommand(NetState state, CircularBufferReader reader, int packetLength) { var e = World.FindEntity((Serial)reader.ReadUInt32()); int packetId = reader.ReadUInt16(); + // We will add support if this is ever a real thing. + if (packetId > 0xFF) + { + var reason = $"Sent unsupported encoded packet (0xD7x{packetId:X4}"; + state.LogInfo(reason); + state.Disconnect(reason); + } + var ph = IncomingPackets.GetEncodedHandler(packetId); if (ph == null) @@ -608,15 +616,13 @@ public static class IncomingPlayerPackets if (ph.Ingame && state.Mobile == null) { - state.LogInfo( - "Sent in-game packet (0xD7x{0:X2}) before being attached to a mobile", - packetId - ); - state.Disconnect($"Sent in-game packet (0xD7x{packetId:X2}) before being attached to a mobile."); + var reason = $"Sent in-game packet (0xD7x{packetId:X4}) before being attached to a mobile."; + state.LogInfo(reason); + state.Disconnect(reason); } else if (ph.Ingame && state.Mobile.Deleted) { - state.Disconnect($"Sent in-game packet(0xD7x{packetId:X2}) but mobile is deleted."); + state.Disconnect($"Sent in-game packet(0xD7x{packetId:X4}) but mobile is deleted."); } else { diff --git a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs index 1d03d85e9..e4bcd7342 100644 --- a/Projects/Server/Network/Packets/IncomingTargetingPackets.cs +++ b/Projects/Server/Network/Packets/IncomingTargetingPackets.cs @@ -25,7 +25,7 @@ public static class IncomingTargetingPackets IncomingPackets.Register(0x6C, 19, true, TargetResponse); } - public static void TargetResponse(NetState state, CircularBufferReader reader, ref int packetLength) + public static void TargetResponse(NetState state, CircularBufferReader reader, int packetLength) { int type = reader.ReadByte(); var targetID = reader.ReadInt32(); diff --git a/Projects/Server/Network/Packets/IncomingVendorPackets.cs b/Projects/Server/Network/Packets/IncomingVendorPackets.cs index 0a11dd2d4..e2e12a689 100644 --- a/Projects/Server/Network/Packets/IncomingVendorPackets.cs +++ b/Projects/Server/Network/Packets/IncomingVendorPackets.cs @@ -14,6 +14,7 @@ *************************************************************************/ using System.Collections.Generic; +using System.IO; namespace Server.Network; @@ -25,7 +26,7 @@ public static class IncomingVendorPackets IncomingPackets.Register(0x9F, 0, true, VendorSellReply); } - public static void VendorBuyReply(NetState state, CircularBufferReader reader, ref int packetLength) + public static void VendorBuyReply(NetState state, CircularBufferReader reader, int packetLength) { var vendor = World.FindMobile((Serial)reader.ReadUInt32()); @@ -65,7 +66,7 @@ public static class IncomingVendorPackets state.SendEndVendorBuy(vendor.Serial); } - public static void VendorSellReply(NetState state, CircularBufferReader reader, ref int packetLength) + public static void VendorSellReply(NetState state, CircularBufferReader reader, int packetLength) { var serial = (Serial)reader.ReadUInt32(); var vendor = World.FindMobile(serial); diff --git a/Projects/UOContent/Engines/Chat/ChatPackets.cs b/Projects/UOContent/Engines/Chat/ChatPackets.cs index 01b47b471..a74d63c0e 100644 --- a/Projects/UOContent/Engines/Chat/ChatPackets.cs +++ b/Projects/UOContent/Engines/Chat/ChatPackets.cs @@ -27,7 +27,7 @@ namespace Server.Engines.Chat IncomingPackets.Register(0xB3, 0, true, ChatAction); } - public static void OpenChatWindowRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OpenChatWindowRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -48,7 +48,7 @@ namespace Server.Engines.Chat ChatUser.AddChatUser(from, chatName); } - public static void ChatAction(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ChatAction(NetState state, CircularBufferReader reader, int packetLength) { if (!ChatSystem.Enabled) { diff --git a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs index d5b6a0555..d19425fa8 100644 --- a/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs +++ b/Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs @@ -193,7 +193,7 @@ namespace Server.Engines.MLQuests.Gumps return false; } - private static void RaceChangeReply(NetState state, CircularBufferReader reader, ref int packetLength) + private static void RaceChangeReply(NetState state, CircularBufferReader reader, int packetLength) { if (!m_Pending.TryGetValue(state, out var raceChangeState)) { diff --git a/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs b/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs index cb40edc26..24a3ba797 100644 --- a/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs +++ b/Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs @@ -9,7 +9,7 @@ namespace Server.Engines.UltimaStore IncomingPackets.Register(0xFA, 1, true, UltimaStoreOpenRequest); } - public static void UltimaStoreOpenRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void UltimaStoreOpenRequest(NetState state, CircularBufferReader reader, int packetLength) { state.Mobile.SendMessage("Ultima Store is not currently available."); } diff --git a/Projects/UOContent/Items/Books/BookPackets.cs b/Projects/UOContent/Items/Books/BookPackets.cs index af59afa86..5eb43d5a1 100644 --- a/Projects/UOContent/Items/Books/BookPackets.cs +++ b/Projects/UOContent/Items/Books/BookPackets.cs @@ -29,7 +29,7 @@ namespace Server.Items IncomingPackets.Register(0x93, 99, true, OldHeaderChange); } - public static void OldHeaderChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OldHeaderChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -48,7 +48,7 @@ namespace Server.Items book.Author = Utility.FixHtml(author); } - public static void HeaderChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void HeaderChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; @@ -84,7 +84,7 @@ namespace Server.Items book.Author = Utility.FixHtml(author); } - public static void ContentChange(NetState state, CircularBufferReader reader, ref int packetLength) + public static void ContentChange(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs index 0eac35aab..2cca09634 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs @@ -48,7 +48,7 @@ namespace Server.Network return $"{seconds} second{(seconds == 1 ? "" : "s")}"; } - public static void BBClientRequest(NetState state, CircularBufferReader reader, ref int packetLength) + public static void BBClientRequest(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs index 601f676d4..fa958623e 100644 --- a/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs +++ b/Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs @@ -61,7 +61,7 @@ namespace Server.Engines.Mahjong RegisterSubCommand(0x18, MoveDealerIndicator); } - public static void OnPacket(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OnPacket(NetState state, CircularBufferReader reader, int packetLength) { var game = World.FindItem((Serial)reader.ReadUInt32()) as MahjongGame; diff --git a/Projects/UOContent/Items/Maps/MapItemPackets.cs b/Projects/UOContent/Items/Maps/MapItemPackets.cs index 2de7dd443..c98e34812 100644 --- a/Projects/UOContent/Items/Maps/MapItemPackets.cs +++ b/Projects/UOContent/Items/Maps/MapItemPackets.cs @@ -25,7 +25,7 @@ namespace Server.Network IncomingPackets.Register(0x56, 11, true, OnMapCommand); } - private static void OnMapCommand(NetState state, CircularBufferReader reader, ref int packetLength) + private static void OnMapCommand(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Misc/HardwareInfo.cs b/Projects/UOContent/Misc/HardwareInfo.cs index e3a651da7..20ef94ddc 100644 --- a/Projects/UOContent/Misc/HardwareInfo.cs +++ b/Projects/UOContent/Misc/HardwareInfo.cs @@ -141,7 +141,7 @@ namespace Server } } - public static void OnReceive(NetState state, CircularBufferReader reader, ref int packetLength) + public static void OnReceive(NetState state, CircularBufferReader reader, int packetLength) { reader.ReadByte(); // 1: <4.0.1a, 2>=4.0.1a diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs index dda06aab8..a49f62aca 100644 --- a/Projects/UOContent/Misc/PacketThrottles.cs +++ b/Projects/UOContent/Misc/PacketThrottles.cs @@ -38,8 +38,8 @@ namespace Server.Network } else { - Delays[0x03] = 5; // Speech - Delays[0xAD] = 5; // Speech + Delays[0x03] = 25; // Speech + Delays[0xAD] = 25; // Speech Delays[0x75] = 500; // Rename request } @@ -141,7 +141,7 @@ namespace Server.Network return true; } - if (Core.TickCount < ns.GetPacketDelay(packetID) + Delays[packetID]) + if (Core.TickCount < ns.GetPacketTime(packetID) + Delays[packetID]) { drop = true; return false; diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index bd63938ec..d8c1a7176 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -1766,7 +1766,7 @@ namespace Server.Multis context.Foundation.SendInfoTo(state); } - public static void QueryDesignDetails(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryDesignDetails(NetState state, CircularBufferReader reader, int packetLength) { var from = state.Mobile; diff --git a/Projects/UOContent/Network/ConnectUO.cs b/Projects/UOContent/Network/ConnectUO.cs index fb4a51e29..12745c420 100644 --- a/Projects/UOContent/Network/ConnectUO.cs +++ b/Projects/UOContent/Network/ConnectUO.cs @@ -70,7 +70,7 @@ namespace Server.Network } } - public static void PollInfo(NetState ns, CircularBufferReader reader, ref int packetLength) + public static void PollInfo(NetState state, CircularBufferReader reader, int packetLength) { var version = reader.ReadByte(); @@ -83,21 +83,21 @@ namespace Server.Network if (!span.SequenceEqual(_token)) { - ns.Disconnect("Invalid token sent for ConnectUO"); + state.Disconnect("Invalid token sent for ConnectUO"); return; } } } - ns.LogInfo($"ConnectUO (v{version}) is requesting stats."); + state.LogInfo($"ConnectUO (v{version}) is requesting stats."); if (version > ConnectUOProtocolVersion) { Utility.PushColor(ConsoleColor.Yellow); - ns.LogInfo("Warning! ConnectUO (v{version}) is newer than what is supported."); + state.LogInfo("Warning! ConnectUO (v{version}) is newer than what is supported."); Utility.PopColor(); } - ns.SendServerPollInfo(); + state.SendServerPollInfo(); } public static void SendServerPollInfo(this NetState ns) diff --git a/Projects/UOContent/Network/MapUO.cs b/Projects/UOContent/Network/MapUO.cs index b0ddf0d75..92769f92b 100644 --- a/Projects/UOContent/Network/MapUO.cs +++ b/Projects/UOContent/Network/MapUO.cs @@ -36,14 +36,14 @@ namespace Server.Network public static void Register(int cmd, bool ingame, OnPacketReceive onReceive) => _handlers[cmd] = new PacketHandler(cmd, 0, ingame, onReceive); - public static void QueryGuildMemberLocations(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryGuildMemberLocations(NetState state, CircularBufferReader reader, int packetLength) { Mobile from = state.Mobile; state.SendGuildMemberLocations(from, from.Guild as Guild, reader.ReadBoolean()); } - public static void QueryPartyMemberLocations(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QueryPartyMemberLocations(NetState state, CircularBufferReader reader, int packetLength) { Mobile from = state.Mobile; var party = Party.Get(from); diff --git a/Projects/UOContent/Network/ProtocolExtensions.cs b/Projects/UOContent/Network/ProtocolExtensions.cs index c012bdb11..5c2be60ac 100644 --- a/Projects/UOContent/Network/ProtocolExtensions.cs +++ b/Projects/UOContent/Network/ProtocolExtensions.cs @@ -21,11 +21,11 @@ namespace Server.Network { var packetHandlers = new PacketHandler[0x100]; - void DecodeBundledPacket(NetState state, CircularBufferReader reader, ref int packetLength) + void DecodeBundledPacket(NetState state, CircularBufferReader reader, int packetLength) { int cmd = reader.ReadByte(); - PacketHandler ph = cmd >= 0 && cmd < packetHandlers.Length ? packetHandlers[cmd] : null; + PacketHandler ph = packetHandlers[cmd]; if (ph == null) { @@ -43,7 +43,7 @@ namespace Server.Network } else { - ph.OnReceive(state, reader, ref packetLength); + ph.OnReceive(state, reader, packetLength); } } diff --git a/Projects/UOContent/Network/UOGateway.cs b/Projects/UOContent/Network/UOGateway.cs index 2980760e4..3d9721f37 100644 --- a/Projects/UOContent/Network/UOGateway.cs +++ b/Projects/UOContent/Network/UOGateway.cs @@ -33,9 +33,9 @@ namespace Server.Network } } - public static void QueryCompactShardStats(NetState ns, CircularBufferReader reader, ref int packetLength) + public static void QueryCompactShardStats(NetState state, CircularBufferReader reader, int packetLength) { - ns.SendCompactShardStats( + state.SendCompactShardStats( (uint)(Core.TickCount / 1000), TcpServer.Instances.Count - 1, // Shame if you modify this! World.Items.Count, @@ -44,10 +44,10 @@ namespace Server.Network ); } - public static void QueryExtendedShardStats(NetState ns, CircularBufferReader reader, ref int packetLength) + public static void QueryExtendedShardStats(NetState state, CircularBufferReader reader, int packetLength) { const long ticksInHour = 1000 * 60 * 60; - ns.SendExtendedShardStats( + state.SendExtendedShardStats( ServerList.ServerName, (int)(Core.TickCount / ticksInHour), TcpServer.Instances.Count - 1, // Shame if you modify this! diff --git a/Projects/UOContent/Skills/Tracking/Tracking.cs b/Projects/UOContent/Skills/Tracking/Tracking.cs index ee7bfa99a..8e691702a 100644 --- a/Projects/UOContent/Skills/Tracking/Tracking.cs +++ b/Projects/UOContent/Skills/Tracking/Tracking.cs @@ -19,7 +19,7 @@ namespace Server.SkillHandlers SkillInfo.Table[(int)SkillName.Tracking].Callback = OnUse; } - public static void QuestArrow(NetState state, CircularBufferReader reader, ref int packetLength) + public static void QuestArrow(NetState state, CircularBufferReader reader, int packetLength) { if (state.Mobile is PlayerMobile from) {