From cc058fc937f84bc1ae26ee7299b593d42c376e57 Mon Sep 17 00:00:00 2001 From: Samuel Voeller <12182390+xCykrix@users.noreply.github.com> Date: Thu, 18 Jul 2024 13:09:10 -0400 Subject: [PATCH] chore!: cleanup namespaces and adjustments to layout --- ICoreManager.cs | 3 +- .../Base}/IManagerController.cs | 2 +- {Module => Managers/Base}/Manager.cs | 2 +- Managers/IActionManager.cs | 3 +- Managers/IChatMessageManager.cs | 218 +++++++++--------- Managers/IMovementManager.cs | 3 +- Managers/ITerritoryManager.cs | 3 +- Module/IModuleController.cs | 4 +- 8 files changed, 119 insertions(+), 119 deletions(-) rename {Module => Managers/Base}/IManagerController.cs (93%) rename {Module => Managers/Base}/Manager.cs (80%) diff --git a/ICoreManager.cs b/ICoreManager.cs index 743371a..f983e17 100644 --- a/ICoreManager.cs +++ b/ICoreManager.cs @@ -4,8 +4,9 @@ using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Plugin.Services; -using DalamudSystem.Manager; using DalamudSystem.Managers; +using DalamudSystem.Managers.Base; +using DalamudSystem.Module; namespace DalamudSystem; diff --git a/Module/IManagerController.cs b/Managers/Base/IManagerController.cs similarity index 93% rename from Module/IManagerController.cs rename to Managers/Base/IManagerController.cs index a2547d2..648e480 100644 --- a/Module/IManagerController.cs +++ b/Managers/Base/IManagerController.cs @@ -1,5 +1,5 @@ -namespace DalamudSystem.Manager; +namespace DalamudSystem.Managers.Base; public static class IManagerController { diff --git a/Module/Manager.cs b/Managers/Base/Manager.cs similarity index 80% rename from Module/Manager.cs rename to Managers/Base/Manager.cs index feaf85d..cbc40cf 100644 --- a/Module/Manager.cs +++ b/Managers/Base/Manager.cs @@ -1,5 +1,5 @@ -namespace DalamudSystem.Manager; +namespace DalamudSystem.Managers.Base; public abstract class IManager(string? ManagerName) : IDisposable { diff --git a/Managers/IActionManager.cs b/Managers/IActionManager.cs index c71edf2..941a979 100644 --- a/Managers/IActionManager.cs +++ b/Managers/IActionManager.cs @@ -1,7 +1,8 @@ +using DalamudSystem.Managers.Base; using FFXIVClientStructs.FFXIV.Client.Game; -namespace DalamudSystem.Manager; +namespace DalamudSystem.Managers; public unsafe class IActionManager : IManager, IDisposable { diff --git a/Managers/IChatMessageManager.cs b/Managers/IChatMessageManager.cs index 337eb7e..5441e22 100644 --- a/Managers/IChatMessageManager.cs +++ b/Managers/IChatMessageManager.cs @@ -1,144 +1,142 @@ -using DalamudSystem.Manager; +using DalamudSystem.Managers.Base; using FFXIVClientStructs.FFXIV.Client.System.Memory; using FFXIVClientStructs.FFXIV.Client.System.String; using System.Runtime.InteropServices; using System.Text; using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework; -namespace DalamudSystem.Managers -{ +namespace DalamudSystem.Managers; - /// - /// Class used to send chat messages to the client. - /// - /// This class is UNSTABLE and DANGEROUS to use. Please use with extreme caution. - /// - public unsafe class IChatMessageManager : IManager, IDisposable +/// +/// Class used to send chat messages to the client. +/// +/// This class is UNSTABLE and DANGEROUS to use. Please use with extreme caution. +/// +public unsafe class IChatMessageManager : IManager, IDisposable +{ + #region Memory Scanner Magic - Finds and Exposes Additional APIs that Dalamud does not provide. + private static class SignatureTable { - #region Memory Scanner Magic - Finds and Exposes Additional APIs that Dalamud does not provide. - private static class SignatureTable - { - internal const string SendChat = "48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9"; - internal const string SanitizeString = "E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 0F B6 F0 E8 ?? ?? ?? ?? 48 8D 4D C0"; - } + internal const string SendChat = "48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9"; + internal const string SanitizeString = "E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 0F B6 F0 E8 ?? ?? ?? ?? 48 8D 4D C0"; + } - private delegate void ProcessChatBoxDelegate(IntPtr ui, IntPtr message, IntPtr unused, byte a4); - private ProcessChatBoxDelegate? ProcessChatBox { get; } + private delegate void ProcessChatBoxDelegate(IntPtr ui, IntPtr message, IntPtr unused, byte a4); + private ProcessChatBoxDelegate? ProcessChatBox { get; } - private readonly unsafe delegate* unmanaged _sanitize = null!; + private readonly unsafe delegate* unmanaged _sanitize = null!; - internal IChatMessageManager() : base(nameof(IChatMessageManager)) - { - if (ICoreManager.SigScanner.TryScanText(SignatureTable.SendChat, out var processChatBoxPtr)) - { - this.ProcessChatBox = Marshal.GetDelegateForFunctionPointer(processChatBoxPtr); - } - - if (ICoreManager.SigScanner.TryScanText(SignatureTable.SanitizeString, out var SanitizePtr)) - { - this._sanitize = (delegate* unmanaged)SanitizePtr; - } - } - #endregion - - /// - /// This method is more inherintly safe but is limited on validation that can be provided. Please use InvokeChatCommand when possible to better protect the players. - /// - /// String to send to current chat. - /// If memory address lookup failed. - /// If the message is empty, exceeds 500 bytes, or does not match sanitization. - public void InvokeChatMessage(string ChatMessage) + internal IChatMessageManager() : base(nameof(IChatMessageManager)) + { + if (ICoreManager.SigScanner.TryScanText(SignatureTable.SendChat, out var processChatBoxPtr)) { - if (ProcessChatBox == null) throw new InvalidOperationException("Could not find signature for chat process box. Please report this to DalamudSystem repo."); - - ChatMessage = ChatMessage.Trim(); - var bytes = Encoding.UTF8.GetBytes(ChatMessage); - if (bytes.Length == 0 || bytes.Length > 500) throw new ArgumentException($"Attempted to invoke a 'Text Message' but the 'ChatMessage' was invalid: {ChatMessage}"); - if (ChatMessage.Length != SanitizeText(ChatMessage).Length) throw new ArgumentException($"Attempted to invoke a 'Text Command' but the 'ChatMessage' contained illegal characters: Provided = '{ChatMessage}' | Parsed = '{SanitizeText(ChatMessage)}'"); - - var ui = (IntPtr)Framework.Instance()->GetUIModule(); - using var payload = new ChatPayload(bytes); - var memstore = Marshal.AllocHGlobal(400); - Marshal.StructureToPtr(payload, memstore, false); - this.ProcessChatBox(ui, memstore, IntPtr.Zero, 0); - Marshal.FreeHGlobal(memstore); + this.ProcessChatBox = Marshal.GetDelegateForFunctionPointer(processChatBoxPtr); } - /// - /// This method is considered better to use over InvokeChatMessage. Sending to chat is preferred to use client commands within validation bounds. - /// - /// - /// If memory address lookup failed or no prefix is provided to the ChatMessage. - /// If the message is empty, exceeds 500 bytes, or does not match sanitization. - public void InvokeChatCommand(string ChatMessage) + if (ICoreManager.SigScanner.TryScanText(SignatureTable.SanitizeString, out var SanitizePtr)) { - ChatMessage = ChatMessage.Trim(); - if (!ChatMessage.StartsWith("/")) throw new InvalidOperationException($"Attempted to invoke a 'Slash Command' but was improperly prefixed with '/': {ChatMessage}"); - InvokeChatMessage(ChatMessage); + this._sanitize = (delegate* unmanaged)SanitizePtr; } + } + #endregion - /// - /// Internal method to call SQEX built-in sanitization functions. - /// - /// - /// - /// - private unsafe string SanitizeText(string text) - { - if (_sanitize == null) throw new InvalidOperationException("Could not find signature for chat sanitization. Please report this to DalamudSystem repo."); + /// + /// This method is more inherintly safe but is limited on validation that can be provided. Please use InvokeChatCommand when possible to better protect the players. + /// + /// String to send to current chat. + /// If memory address lookup failed. + /// If the message is empty, exceeds 500 bytes, or does not match sanitization. + public void InvokeChatMessage(string ChatMessage) + { + if (ProcessChatBox == null) throw new InvalidOperationException("Could not find signature for chat process box. Please report this to DalamudSystem repo."); + + ChatMessage = ChatMessage.Trim(); + var bytes = Encoding.UTF8.GetBytes(ChatMessage); + if (bytes.Length == 0 || bytes.Length > 500) throw new ArgumentException($"Attempted to invoke a 'Text Message' but the 'ChatMessage' was invalid: {ChatMessage}"); + if (ChatMessage.Length != SanitizeText(ChatMessage).Length) throw new ArgumentException($"Attempted to invoke a 'Text Command' but the 'ChatMessage' contained illegal characters: Provided = '{ChatMessage}' | Parsed = '{SanitizeText(ChatMessage)}'"); + + var ui = (IntPtr)Framework.Instance()->GetUIModule(); + using var payload = new ChatPayload(bytes); + var memstore = Marshal.AllocHGlobal(400); + Marshal.StructureToPtr(payload, memstore, false); + this.ProcessChatBox(ui, memstore, IntPtr.Zero, 0); + Marshal.FreeHGlobal(memstore); + } - // Convert to UTF8 - var utf8Text = Utf8String.FromString(text); - _sanitize(utf8Text, 0x27F, IntPtr.Zero); + /// + /// This method is considered better to use over InvokeChatMessage. Sending to chat is preferred to use client commands within validation bounds. + /// + /// + /// If memory address lookup failed or no prefix is provided to the ChatMessage. + /// If the message is empty, exceeds 500 bytes, or does not match sanitization. + public void InvokeChatCommand(string ChatMessage) + { + ChatMessage = ChatMessage.Trim(); + if (!ChatMessage.StartsWith("/")) throw new InvalidOperationException($"Attempted to invoke a 'Slash Command' but was improperly prefixed with '/': {ChatMessage}"); + InvokeChatMessage(ChatMessage); + } - // PConvert utf8Text to String and Dtor(?) - var sanitized = utf8Text->ToString(); - utf8Text->Dtor(); - - // Clean Memory - IMemorySpace.Free(utf8Text); + /// + /// Internal method to call SQEX built-in sanitization functions. + /// + /// + /// + /// + private unsafe string SanitizeText(string text) + { + if (_sanitize == null) throw new InvalidOperationException("Could not find signature for chat sanitization. Please report this to DalamudSystem repo."); - // Return Result - return sanitized; - } + // Convert to UTF8 + var utf8Text = Utf8String.FromString(text); + _sanitize(utf8Text, 0x27F, IntPtr.Zero); - // ChatPayload Struct - [StructLayout(LayoutKind.Explicit)] - private readonly struct ChatPayload : IDisposable - { - [FieldOffset(0)] - private readonly IntPtr textPtr; + // PConvert utf8Text to String and Dtor(?) + var sanitized = utf8Text->ToString(); + utf8Text->Dtor(); - [FieldOffset(16)] - private readonly ulong textLen; + // Clean Memory + IMemorySpace.Free(utf8Text); - [FieldOffset(8)] - private readonly ulong unk1; + // Return Result + return sanitized; + } + + // ChatPayload Struct + [StructLayout(LayoutKind.Explicit)] + private readonly struct ChatPayload : IDisposable + { + [FieldOffset(0)] + private readonly IntPtr textPtr; + + [FieldOffset(16)] + private readonly ulong textLen; - [FieldOffset(24)] - private readonly ulong unk2; + [FieldOffset(8)] + private readonly ulong unk1; - internal ChatPayload(byte[] stringBytes) - { - this.textPtr = Marshal.AllocHGlobal(stringBytes.Length + 30); - Marshal.Copy(stringBytes, 0, this.textPtr, stringBytes.Length); - Marshal.WriteByte(this.textPtr + stringBytes.Length, 0); + [FieldOffset(24)] + private readonly ulong unk2; - this.textLen = (ulong)(stringBytes.Length + 1); + internal ChatPayload(byte[] stringBytes) + { + this.textPtr = Marshal.AllocHGlobal(stringBytes.Length + 30); + Marshal.Copy(stringBytes, 0, this.textPtr, stringBytes.Length); + Marshal.WriteByte(this.textPtr + stringBytes.Length, 0); - this.unk1 = 64; - this.unk2 = 0; - } + this.textLen = (ulong)(stringBytes.Length + 1); - public void Dispose() - { - Marshal.FreeHGlobal(this.textPtr); - } + this.unk1 = 64; + this.unk2 = 0; } - public override void Dispose() + public void Dispose() { - GC.SuppressFinalize(this); + Marshal.FreeHGlobal(this.textPtr); } } + + public override void Dispose() + { + GC.SuppressFinalize(this); + } } diff --git a/Managers/IMovementManager.cs b/Managers/IMovementManager.cs index 40ec99c..89571d2 100644 --- a/Managers/IMovementManager.cs +++ b/Managers/IMovementManager.cs @@ -1,8 +1,9 @@ +using DalamudSystem.Managers.Base; using System.Numerics; -namespace DalamudSystem.Manager; +namespace DalamudSystem.Managers; public class IMovementManager : IManager, IDisposable { diff --git a/Managers/ITerritoryManager.cs b/Managers/ITerritoryManager.cs index 056cf2f..a329dc0 100644 --- a/Managers/ITerritoryManager.cs +++ b/Managers/ITerritoryManager.cs @@ -1,8 +1,9 @@ using Dalamud.Plugin.Services; +using DalamudSystem.Managers.Base; using Lumina.Excel.GeneratedSheets; -namespace DalamudSystem.Manager; +namespace DalamudSystem.Managers; public class ITerritoryManager : IManager, IDisposable { diff --git a/Module/IModuleController.cs b/Module/IModuleController.cs index 9083b4c..c425551 100644 --- a/Module/IModuleController.cs +++ b/Module/IModuleController.cs @@ -1,7 +1,5 @@ -using DalamudSystem.Module; - -namespace DalamudSystem.Manager; +namespace DalamudSystem.Module; public static class IModuleController {