From 3abf7bb00bc834be650f784a322870510245fefa Mon Sep 17 00:00:00 2001 From: Haselnussbomber Date: Tue, 27 Jan 2026 17:35:55 +0100 Subject: [PATCH] Rework NetworkMonitorWidget, remove GameNetwork (#2593) * Rework NetworkMonitorWidget, remove GameNetwork * Rework packet filtering --- Dalamud/Game/Network/GameNetwork.cs | 147 -------- .../Network/GameNetworkAddressResolver.cs | 20 - .../Game/Network/Internal/NetworkHandlers.cs | 5 +- .../Game/Network/NetworkMessageDirection.cs | 17 - .../Data/Widgets/NetworkMonitorWidget.cs | 341 +++++++++++------- Dalamud/Plugin/Services/IGameNetwork.cs | 27 -- 6 files changed, 212 insertions(+), 345 deletions(-) delete mode 100644 Dalamud/Game/Network/GameNetwork.cs delete mode 100644 Dalamud/Game/Network/GameNetworkAddressResolver.cs delete mode 100644 Dalamud/Game/Network/NetworkMessageDirection.cs delete mode 100644 Dalamud/Plugin/Services/IGameNetwork.cs diff --git a/Dalamud/Game/Network/GameNetwork.cs b/Dalamud/Game/Network/GameNetwork.cs deleted file mode 100644 index b8c91b235..000000000 --- a/Dalamud/Game/Network/GameNetwork.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System.Runtime.InteropServices; - -using Dalamud.Configuration.Internal; -using Dalamud.Hooking; -using Dalamud.Utility; - -using FFXIVClientStructs.FFXIV.Client.Network; - -using Serilog; - -namespace Dalamud.Game.Network; - -/// -/// This class handles interacting with game network events. -/// -[ServiceManager.EarlyLoadedService] -internal sealed unsafe class GameNetwork : IInternalDisposableService -{ - private readonly GameNetworkAddressResolver address; - private readonly Hook processZonePacketDownHook; - private readonly Hook processZonePacketUpHook; - - private readonly HitchDetector hitchDetectorUp; - private readonly HitchDetector hitchDetectorDown; - - [ServiceManager.ServiceDependency] - private readonly DalamudConfiguration configuration = Service.Get(); - - [ServiceManager.ServiceConstructor] - private unsafe GameNetwork(TargetSigScanner sigScanner) - { - this.hitchDetectorUp = new HitchDetector("GameNetworkUp", this.configuration.GameNetworkUpHitch); - this.hitchDetectorDown = new HitchDetector("GameNetworkDown", this.configuration.GameNetworkDownHitch); - - this.address = new GameNetworkAddressResolver(); - this.address.Setup(sigScanner); - - var onReceivePacketAddress = (nint)PacketDispatcher.StaticVirtualTablePointer->OnReceivePacket; - - Log.Verbose("===== G A M E N E T W O R K ====="); - Log.Verbose($"OnReceivePacket address {Util.DescribeAddress(onReceivePacketAddress)}"); - Log.Verbose($"ProcessZonePacketUp address {Util.DescribeAddress(this.address.ProcessZonePacketUp)}"); - - this.processZonePacketDownHook = Hook.FromAddress(onReceivePacketAddress, this.ProcessZonePacketDownDetour); - this.processZonePacketUpHook = Hook.FromAddress(this.address.ProcessZonePacketUp, this.ProcessZonePacketUpDetour); - - this.processZonePacketDownHook.Enable(); - this.processZonePacketUpHook.Enable(); - } - - /// - /// The delegate type of a network message event. - /// - /// The pointer to the raw data. - /// The operation ID code. - /// The source actor ID. - /// The taret actor ID. - /// The direction of the packed. - public delegate void OnNetworkMessageDelegate(nint dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction); - - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate byte ProcessZonePacketUpDelegate(IntPtr a1, IntPtr dataPtr, IntPtr a3, byte a4); - - /// - /// Event that is called when a network message is sent/received. - /// - public event OnNetworkMessageDelegate? NetworkMessage; - - /// - void IInternalDisposableService.DisposeService() - { - this.processZonePacketDownHook.Dispose(); - this.processZonePacketUpHook.Dispose(); - } - - private void ProcessZonePacketDownDetour(PacketDispatcher* dispatcher, uint targetId, IntPtr dataPtr) - { - this.hitchDetectorDown.Start(); - - // Go back 0x10 to get back to the start of the packet header - dataPtr -= 0x10; - - foreach (var d in Delegate.EnumerateInvocationList(this.NetworkMessage)) - { - try - { - d.Invoke( - dataPtr + 0x20, - (ushort)Marshal.ReadInt16(dataPtr, 0x12), - 0, - targetId, - NetworkMessageDirection.ZoneDown); - } - catch (Exception ex) - { - string header; - try - { - var data = new byte[32]; - Marshal.Copy(dataPtr, data, 0, 32); - header = BitConverter.ToString(data); - } - catch (Exception) - { - header = "failed"; - } - - Log.Error(ex, "Exception on ProcessZonePacketDown hook. Header: " + header); - } - } - - this.processZonePacketDownHook.Original(dispatcher, targetId, dataPtr + 0x10); - this.hitchDetectorDown.Stop(); - } - - private byte ProcessZonePacketUpDetour(IntPtr a1, IntPtr dataPtr, IntPtr a3, byte a4) - { - this.hitchDetectorUp.Start(); - - try - { - // Call events - // TODO: Implement actor IDs - this.NetworkMessage?.Invoke(dataPtr + 0x20, (ushort)Marshal.ReadInt16(dataPtr), 0x0, 0x0, NetworkMessageDirection.ZoneUp); - } - catch (Exception ex) - { - string header; - try - { - var data = new byte[32]; - Marshal.Copy(dataPtr, data, 0, 32); - header = BitConverter.ToString(data); - } - catch (Exception) - { - header = "failed"; - } - - Log.Error(ex, "Exception on ProcessZonePacketUp hook. Header: " + header); - } - - this.hitchDetectorUp.Stop(); - - return this.processZonePacketUpHook.Original(a1, dataPtr, a3, a4); - } -} diff --git a/Dalamud/Game/Network/GameNetworkAddressResolver.cs b/Dalamud/Game/Network/GameNetworkAddressResolver.cs deleted file mode 100644 index 48abc2d97..000000000 --- a/Dalamud/Game/Network/GameNetworkAddressResolver.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Dalamud.Plugin.Services; - -namespace Dalamud.Game.Network; - -/// -/// The address resolver for the class. -/// -internal sealed class GameNetworkAddressResolver : BaseAddressResolver -{ - /// - /// Gets the address of the ProcessZonePacketUp method. - /// - public IntPtr ProcessZonePacketUp { get; private set; } - - /// - protected override void Setup64Bit(ISigScanner sig) - { - this.ProcessZonePacketUp = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 4C 89 64 24 ?? 55 41 56 41 57 48 8B EC 48 83 EC 70"); // unnamed in cs - } -} diff --git a/Dalamud/Game/Network/Internal/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs index 5ca7da54a..d3a53b4f2 100644 --- a/Dalamud/Game/Network/Internal/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -55,10 +55,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService private bool disposing; [ServiceManager.ServiceConstructor] - private NetworkHandlers( - GameNetwork gameNetwork, - TargetSigScanner sigScanner, - HappyHttpClient happyHttpClient) + private NetworkHandlers(TargetSigScanner sigScanner, HappyHttpClient happyHttpClient) { this.uploader = new UniversalisMarketBoardUploader(happyHttpClient); diff --git a/Dalamud/Game/Network/NetworkMessageDirection.cs b/Dalamud/Game/Network/NetworkMessageDirection.cs deleted file mode 100644 index 87cce5173..000000000 --- a/Dalamud/Game/Network/NetworkMessageDirection.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Dalamud.Game.Network; - -/// -/// This represents the direction of a network message. -/// -public enum NetworkMessageDirection -{ - /// - /// A zone down message. - /// - ZoneDown, - - /// - /// A zone up message. - /// - ZoneUp, -} diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs index ae173578a..922b72717 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs @@ -1,44 +1,51 @@ using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; +using System.Threading; using Dalamud.Bindings.ImGui; -using Dalamud.Game.Network; -using Dalamud.Interface.Utility; +using Dalamud.Game; +using Dalamud.Hooking; +using Dalamud.Interface.Components; using Dalamud.Interface.Utility.Raii; -using Dalamud.Memory; -using ImGuiTable = Dalamud.Interface.Utility.ImGuiTable; +using FFXIVClientStructs.FFXIV.Application.Network; +using FFXIVClientStructs.FFXIV.Client.Game; +using FFXIVClientStructs.FFXIV.Client.Game.Object; +using FFXIVClientStructs.FFXIV.Client.Game.UI; +using FFXIVClientStructs.FFXIV.Client.Network; namespace Dalamud.Interface.Internal.Windows.Data.Widgets; /// /// Widget to display the current packets. /// -internal class NetworkMonitorWidget : IDataWindowWidget +internal unsafe class NetworkMonitorWidget : IDataWindowWidget { private readonly ConcurrentQueue packets = new(); + private Hook? hookDown; + private Hook? hookUp; + private bool trackNetwork; - private int trackedPackets; - private Regex? trackedOpCodes; + private int trackedPackets = 20; + private ulong nextPacketIndex; private string filterString = string.Empty; - private Regex? untrackedOpCodes; - private string negativeFilterString = string.Empty; + private bool filterRecording = true; + private bool autoScroll = true; + private bool autoScrollPending; /// Finalizes an instance of the class. ~NetworkMonitorWidget() { - if (this.trackNetwork) - { - this.trackNetwork = false; - var network = Service.GetNullable(); - if (network != null) - { - network.NetworkMessage -= this.OnNetworkMessage; - } - } + this.hookDown?.Dispose(); + this.hookUp?.Dispose(); + } + + private delegate byte ZoneClientSendPacketDelegate(ZoneClient* thisPtr, nint packet, uint a3, uint a4, byte a5); + + private enum NetworkMessageDirection + { + ZoneDown, + ZoneUp, } /// @@ -53,31 +60,36 @@ internal class NetworkMonitorWidget : IDataWindowWidget /// public void Load() { - this.trackNetwork = false; - this.trackedPackets = 20; - this.trackedOpCodes = null; - this.filterString = string.Empty; - this.packets.Clear(); + this.hookDown = Hook.FromAddress( + (nint)PacketDispatcher.StaticVirtualTablePointer->OnReceivePacket, + this.OnReceivePacketDetour); + + // TODO: switch to ZoneClient.SendPacket from CS + if (Service.Get().TryScanText("E8 ?? ?? ?? ?? 4C 8B 44 24 ?? E9", out var address)) + this.hookUp = Hook.FromAddress(address, this.SendPacketDetour); + this.Ready = true; } /// public void Draw() { - var network = Service.Get(); if (ImGui.Checkbox("Track Network Packets"u8, ref this.trackNetwork)) { if (this.trackNetwork) { - network.NetworkMessage += this.OnNetworkMessage; + this.nextPacketIndex = 0; + this.hookDown?.Enable(); + this.hookUp?.Enable(); } else { - network.NetworkMessage -= this.OnNetworkMessage; + this.hookDown?.Disable(); + this.hookUp?.Disable(); } } - ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X / 2); + ImGui.SetNextItemWidth(-1); if (ImGui.DragInt("Stored Number of Packets"u8, ref this.trackedPackets, 0.1f, 1, 512)) { this.trackedPackets = Math.Clamp(this.trackedPackets, 1, 512); @@ -88,131 +100,200 @@ internal class NetworkMonitorWidget : IDataWindowWidget this.packets.Clear(); } - this.DrawFilterInput(); - this.DrawNegativeFilterInput(); + ImGui.SameLine(); + ImGui.Checkbox("Auto-Scroll"u8, ref this.autoScroll); - ImGuiTable.DrawTable(string.Empty, this.packets, this.DrawNetworkPacket, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg, "Direction", "OpCode", "Hex", "Target", "Source", "Data"); - } + ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - (ImGui.GetStyle().ItemInnerSpacing.X + ImGui.GetFrameHeight()) * 2); + ImGui.InputTextWithHint("##Filter"u8, "Filter OpCodes..."u8, ref this.filterString, 1024, ImGuiInputTextFlags.AutoSelectAll); + ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); + ImGui.Checkbox("##FilterRecording"u8, ref this.filterRecording); + if (ImGui.IsItemHovered()) + ImGui.SetTooltip("Apply filter to incoming packets.\nUncheck to record all packets and filter the table instead."u8); + ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); + ImGuiComponents.HelpMarker("Enter OpCodes in a comma-separated list.\nRanges are supported. Exclude OpCodes with exclamation mark.\nExample: -400,!50-100,650,700-980,!941"); - private void DrawNetworkPacket(NetworkPacketData data) - { - ImGui.TableNextColumn(); - ImGui.Text(data.Direction.ToString()); + using var table = ImRaii.Table("NetworkMonitorTableV2"u8, 6, ImGuiTableFlags.Borders | ImGuiTableFlags.ScrollY | ImGuiTableFlags.RowBg | ImGuiTableFlags.NoSavedSettings); + if (!table) return; - ImGui.TableNextColumn(); - ImGui.Text(data.OpCode.ToString()); + ImGui.TableSetupColumn("Index"u8, ImGuiTableColumnFlags.WidthFixed, 50); + ImGui.TableSetupColumn("Time"u8, ImGuiTableColumnFlags.WidthFixed, 100); + ImGui.TableSetupColumn("Direction"u8, ImGuiTableColumnFlags.WidthFixed, 100); + ImGui.TableSetupColumn("OpCode"u8, ImGuiTableColumnFlags.WidthFixed, 100); + ImGui.TableSetupColumn("OpCode (Hex)"u8, ImGuiTableColumnFlags.WidthFixed, 100); + ImGui.TableSetupColumn("Target EntityId"u8, ImGuiTableColumnFlags.WidthStretch); + ImGui.TableSetupScrollFreeze(0, 1); + ImGui.TableHeadersRow(); - ImGui.TableNextColumn(); - ImGui.Text($"0x{data.OpCode:X4}"); + var autoScrollDisabled = false; - ImGui.TableNextColumn(); - ImGui.Text(data.TargetActorId > 0 ? $"0x{data.TargetActorId:X}" : string.Empty); - - ImGui.TableNextColumn(); - ImGui.Text(data.SourceActorId > 0 ? $"0x{data.SourceActorId:X}" : string.Empty); - - ImGui.TableNextColumn(); - if (data.Data.Count > 0) + foreach (var packet in this.packets) { - ImGui.Text(string.Join(" ", data.Data.Select(b => b.ToString("X2")))); + if (!this.filterRecording && !this.IsFiltered(packet.OpCode)) + continue; + + ImGui.TableNextColumn(); + ImGui.Text(packet.Index.ToString()); + + ImGui.TableNextColumn(); + ImGui.Text(packet.Time.ToLongTimeString()); + + ImGui.TableNextColumn(); + ImGui.Text(packet.Direction.ToString()); + + ImGui.TableNextColumn(); + using (ImRaii.PushId(packet.Index.ToString())) + { + if (ImGui.SmallButton("X")) + { + if (!string.IsNullOrEmpty(this.filterString)) + this.filterString += ","; + + this.filterString += $"!{packet.OpCode}"; + } + } + + if (ImGui.IsItemHovered()) + ImGui.SetTooltip("Filter OpCode"u8); + + autoScrollDisabled |= ImGui.IsItemHovered(); + + ImGui.SameLine(); + WidgetUtil.DrawCopyableText(packet.OpCode.ToString()); + autoScrollDisabled |= ImGui.IsItemHovered(); + + ImGui.TableNextColumn(); + WidgetUtil.DrawCopyableText($"0x{packet.OpCode:X3}"); + autoScrollDisabled |= ImGui.IsItemHovered(); + + ImGui.TableNextColumn(); + if (packet.TargetEntityId > 0) + { + WidgetUtil.DrawCopyableText($"{packet.TargetEntityId:X}"); + + var name = !string.IsNullOrEmpty(packet.TargetName) + ? packet.TargetName + : GetTargetName(packet.TargetEntityId); + + if (!string.IsNullOrEmpty(name)) + { + ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); + ImGui.Text($"({name})"); + } + } } - else + + if (this.autoScroll && this.autoScrollPending && !autoScrollDisabled) { - ImGui.Dummy(ImGui.GetContentRegionAvail() with { Y = 0 }); + ImGui.SetScrollHereY(); + this.autoScrollPending = false; } } - private void DrawFilterInput() + private static string GetTargetName(uint targetId) { - var invalidRegEx = this.filterString.Length > 0 && this.trackedOpCodes == null; - using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, invalidRegEx); - using var color = ImRaii.PushColor(ImGuiCol.Border, 0xFF0000FF, invalidRegEx); - ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); - if (!ImGui.InputTextWithHint("##Filter"u8, "Regex Filter OpCodes..."u8, ref this.filterString, 1024)) - { + if (targetId == PlayerState.Instance()->EntityId) + return "Local Player"; + + var cachedName = NameCache.Instance()->GetNameByEntityId(targetId); + if (cachedName.HasValue) + return cachedName.ToString(); + + var obj = GameObjectManager.Instance()->Objects.GetObjectByEntityId(targetId); + if (obj != null) + return obj->NameString; + + return string.Empty; + } + + private void OnReceivePacketDetour(PacketDispatcher* thisPtr, uint targetId, nint packet) + { + var opCode = *(ushort*)(packet + 2); + var targetName = GetTargetName(targetId); + this.RecordPacket(new NetworkPacketData(Interlocked.Increment(ref this.nextPacketIndex), DateTime.Now, opCode, NetworkMessageDirection.ZoneDown, targetId, targetName)); + this.hookDown.OriginalDisposeSafe(thisPtr, targetId, packet); + } + + private byte SendPacketDetour(ZoneClient* thisPtr, nint packet, uint a3, uint a4, byte a5) + { + var opCode = *(ushort*)packet; + this.RecordPacket(new NetworkPacketData(Interlocked.Increment(ref this.nextPacketIndex), DateTime.Now, opCode, NetworkMessageDirection.ZoneUp, 0, string.Empty)); + return this.hookUp.OriginalDisposeSafe(thisPtr, packet, a3, a4, a5); + } + + private void RecordPacket(NetworkPacketData packet) + { + if (this.filterRecording && !this.IsFiltered(packet.OpCode)) return; + + this.packets.Enqueue(packet); + + while (this.packets.Count > this.trackedPackets) + { + this.packets.TryDequeue(out _); } - if (this.filterString.Length == 0) - { - this.trackedOpCodes = null; - } - else - { - try - { - this.trackedOpCodes = new Regex(this.filterString, RegexOptions.Compiled | RegexOptions.ExplicitCapture); - } - catch - { - this.trackedOpCodes = null; - } - } + this.autoScrollPending = true; } - private void DrawNegativeFilterInput() + private bool IsFiltered(ushort opcode) { - var invalidRegEx = this.negativeFilterString.Length > 0 && this.untrackedOpCodes == null; - using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, invalidRegEx); - using var color = ImRaii.PushColor(ImGuiCol.Border, 0xFF0000FF, invalidRegEx); - ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); - if (!ImGui.InputTextWithHint("##NegativeFilter"u8, "Regex Filter Against OpCodes..."u8, ref this.negativeFilterString, 1024)) - { - return; - } + var filterString = this.filterString.Replace(" ", string.Empty); - if (this.negativeFilterString.Length == 0) + if (filterString.Length == 0) + return true; + + try { - this.untrackedOpCodes = null; + var offset = 0; + var included = false; + var hasInclude = false; + + while (filterString.Length - offset > 0) + { + var remaining = filterString[offset..]; + + // find the end of the current entry + var entryEnd = remaining.IndexOf(','); + if (entryEnd == -1) + entryEnd = remaining.Length; + + var entry = filterString[offset..(offset + entryEnd)]; + var dash = entry.IndexOf('-'); + var isExcluded = entry.StartsWith('!'); + var startOffset = isExcluded ? 1 : 0; + + var entryMatch = dash == -1 + ? ushort.Parse(entry[startOffset..]) == opcode + : ((dash - startOffset == 0 || opcode >= ushort.Parse(entry[startOffset..dash])) + && (entry[(dash + 1)..].Length == 0 || opcode <= ushort.Parse(entry[(dash + 1)..]))); + + if (isExcluded) + { + if (entryMatch) + return false; + } + else + { + hasInclude = true; + included |= entryMatch; + } + + if (entryEnd == filterString.Length) + break; + + offset += entryEnd + 1; + } + + return !hasInclude || included; } - else + catch (Exception ex) { - try - { - this.untrackedOpCodes = new Regex(this.negativeFilterString, RegexOptions.Compiled | RegexOptions.ExplicitCapture); - } - catch - { - this.untrackedOpCodes = null; - } + Serilog.Log.Error(ex, "Invalid filter string"); + return false; } } - private void OnNetworkMessage(nint dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction) - { - if ((this.trackedOpCodes == null || this.trackedOpCodes.IsMatch(this.OpCodeToString(opCode))) - && (this.untrackedOpCodes == null || !this.untrackedOpCodes.IsMatch(this.OpCodeToString(opCode)))) - { - this.packets.Enqueue(new NetworkPacketData(this, opCode, direction, sourceActorId, targetActorId, dataPtr)); - while (this.packets.Count > this.trackedPackets) - { - this.packets.TryDequeue(out _); - } - } - } - - private int GetSizeFromOpCode(ushort opCode) - => 0; - - /// Add known packet-name -> packet struct size associations here to copy the byte data for such packets. > - private int GetSizeFromName(string name) - => name switch - { - _ => 0, - }; - - /// The filter should find opCodes by number (decimal and hex) and name, if existing. - private string OpCodeToString(ushort opCode) - => $"{opCode}\0{opCode:X}"; - #pragma warning disable SA1313 - private readonly record struct NetworkPacketData(ushort OpCode, NetworkMessageDirection Direction, uint SourceActorId, uint TargetActorId) + private readonly record struct NetworkPacketData(ulong Index, DateTime Time, ushort OpCode, NetworkMessageDirection Direction, uint TargetEntityId, string TargetName); #pragma warning restore SA1313 - { - public readonly IReadOnlyList Data = []; - - public NetworkPacketData(NetworkMonitorWidget widget, ushort opCode, NetworkMessageDirection direction, uint sourceActorId, uint targetActorId, nint dataPtr) - : this(opCode, direction, sourceActorId, targetActorId) - => this.Data = MemoryHelper.Read(dataPtr, widget.GetSizeFromOpCode(opCode), false); - } } diff --git a/Dalamud/Plugin/Services/IGameNetwork.cs b/Dalamud/Plugin/Services/IGameNetwork.cs deleted file mode 100644 index 4abf20834..000000000 --- a/Dalamud/Plugin/Services/IGameNetwork.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Dalamud.Game.Network; - -namespace Dalamud.Plugin.Services; - -/// -/// This class handles interacting with game network events. -/// -[Obsolete("Will be removed in a future release. Use packet handler hooks instead.", true)] -public interface IGameNetwork : IDalamudService -{ - // TODO(v9): we shouldn't be passing pointers to the actual data here - - /// - /// The delegate type of a network message event. - /// - /// The pointer to the raw data. - /// The operation ID code. - /// The source actor ID. - /// The taret actor ID. - /// The direction of the packed. - public delegate void OnNetworkMessageDelegate(nint dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction); - - /// - /// Event that is called when a network message is sent/received. - /// - public event OnNetworkMessageDelegate NetworkMessage; -}