diff --git a/plugins/script_loader/dotnet/AssemblyLoader/Program.cs b/plugins/script_loader/dotnet/AssemblyLoader/Program.cs index 64662234a..9d6446563 100644 --- a/plugins/script_loader/dotnet/AssemblyLoader/Program.cs +++ b/plugins/script_loader/dotnet/AssemblyLoader/Program.cs @@ -8,20 +8,24 @@ namespace ImHex public class EntryPoint { - public static int ExecuteScript(IntPtr arg, int argLength) + private static void Log(string message) + { + Console.WriteLine($"[.NET Script] {message}"); + } + public static int ExecuteScript(IntPtr argument, int argumentLength) { try { - return ExecuteScript(Marshal.PtrToStringUTF8(arg, argLength)); + return ExecuteScript(Marshal.PtrToStringUTF8(argument, argumentLength)); } catch (Exception e) { - Console.WriteLine("[.NET Script] Exception in AssemblyLoader: " + e.ToString()); + Log($"Exception in AssemblyLoader: {e}"); return 1; } } - private static List loadedPlugins = new(); + private static readonly List LoadedPlugins = new(); private static int ExecuteScript(string args) { // Parse input in the form of "execType||path" @@ -34,7 +38,7 @@ namespace ImHex string? basePath = Path.GetDirectoryName(path); if (basePath == null) { - Console.WriteLine("[.NET Script] Failed to get base path"); + Log("Failed to get base path"); return 1; } @@ -47,20 +51,19 @@ namespace ImHex if (type is "LOAD") { // If the script has been loaded already, don't do it again - if (loadedPlugins.Contains(path)) + if (LoadedPlugins.Contains(path)) { return 0; } // Check if the plugin is already loaded - loadedPlugins.Add(path); + LoadedPlugins.Add(path); } // Load all assemblies in the parent folder - foreach (var file in Directory.GetFiles(basePath, "*.dll")) - { + foreach (var file in Directory.GetFiles(basePath, "*.dll")) { // Skip main Assembly - if (file.EndsWith("Main.dll")) + if (new FileInfo(file).Name == "Main.dll") { continue; } @@ -72,7 +75,7 @@ namespace ImHex } catch (Exception e) { - Console.WriteLine("[.NET Script] Failed to load assembly: " + file + " - " + e); + Log($"Failed to load assembly: {file} - {e}"); } } @@ -83,7 +86,7 @@ namespace ImHex var libraryModule = Array.Find(context.Assemblies.ToArray(), module => module.GetName().Name == "ImHexLibrary"); if (libraryModule == null) { - Console.WriteLine("[.NET Script] Refusing to load non-ImHex script"); + Log("Refusing to load non-ImHex script"); return 1; } else @@ -92,7 +95,7 @@ namespace ImHex var libraryType = libraryModule.GetType("Library"); if (libraryType == null) { - Console.WriteLine("[.NET Script] Failed to find Library type in ImHexLibrary"); + Log("Failed to find Library type in ImHexLibrary"); return 1; } @@ -100,7 +103,7 @@ namespace ImHex var initMethod = libraryType.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public); if (initMethod == null) { - Console.WriteLine("[.NET Script] Failed to find Initialize method"); + Log("Failed to find Initialize method"); return 1; } @@ -108,13 +111,20 @@ namespace ImHex initMethod.Invoke(null, null); } - // Find a class named "Script" - var entryPointType = assembly.GetType("Script"); - if (entryPointType == null) + // Find classes derived from IScript + var entryPointTypes = Array.FindAll(assembly.GetTypes(), t => t.GetInterface("IScript") != null); + + if (entryPointTypes.Length == 0) { - Console.WriteLine("[.NET Script] Failed to find Script type"); + Log("Failed to find Script entrypoint"); + return 1; + } else if (entryPointTypes.Length > 1) + { + Log("Found multiple Script entrypoints"); return 1; } + + var entryPointType = entryPointTypes[0]; if (type is "EXEC" or "LOAD") { @@ -140,7 +150,7 @@ namespace ImHex } catch (Exception e) { - Console.WriteLine("[.NET Script] Exception in AssemblyLoader: " + e); + Log($"Exception in AssemblyLoader: {e}"); return 3; } finally diff --git a/plugins/script_loader/templates/CSharp/ImHexLibrary/Library.cs b/plugins/script_loader/templates/CSharp/ImHexLibrary/Library.cs index 919d9d8d4..9f85b3e37 100644 --- a/plugins/script_loader/templates/CSharp/ImHexLibrary/Library.cs +++ b/plugins/script_loader/templates/CSharp/ImHexLibrary/Library.cs @@ -1,9 +1,16 @@ using ImHex; -public class Library +public static class Library { public static void Initialize() { Logger.RedirectConsole(); } +} + +public interface IScript { + + static void Main() { } + static void OnLoad() { } + } \ No newline at end of file diff --git a/plugins/script_loader/templates/CSharp/ImHexLibrary/Logger.cs b/plugins/script_loader/templates/CSharp/ImHexLibrary/Logger.cs index 6adbb7599..c750f7040 100644 --- a/plugins/script_loader/templates/CSharp/ImHexLibrary/Logger.cs +++ b/plugins/script_loader/templates/CSharp/ImHexLibrary/Logger.cs @@ -5,7 +5,7 @@ using System.Text; namespace ImHex { - public partial class Logger + public static partial class Logger { [LibraryImport("ImHex")] private static partial void logPrintV1(byte[] message); diff --git a/plugins/script_loader/templates/CSharp/ImHexLibrary/Memory.cs b/plugins/script_loader/templates/CSharp/ImHexLibrary/Memory.cs index e66b99e27..bfdc50dc7 100644 --- a/plugins/script_loader/templates/CSharp/ImHexLibrary/Memory.cs +++ b/plugins/script_loader/templates/CSharp/ImHexLibrary/Memory.cs @@ -33,8 +33,8 @@ namespace ImHex } public partial class Memory { - private static List _registeredProviders = new(); - private static List _registeredDelegates = new(); + private static readonly List RegisteredProviders = new(); + private static readonly List RegisteredDelegates = new(); private delegate void DataAccessDelegate(UInt64 address, IntPtr buffer, UInt64 size); private delegate UInt64 GetSizeDelegate(); @@ -95,20 +95,20 @@ namespace ImHex public static void RegisterProvider() where T : IProvider, new() { - _registeredProviders.Add(new T()); + RegisteredProviders.Add(new T()); - ref var provider = ref CollectionsMarshal.AsSpan(_registeredProviders)[^1]; + ref var provider = ref CollectionsMarshal.AsSpan(RegisteredProviders)[^1]; - _registeredDelegates.Add(new DataAccessDelegate(provider.readRaw)); - _registeredDelegates.Add(new DataAccessDelegate(provider.writeRaw)); - _registeredDelegates.Add(new GetSizeDelegate(provider.getSize)); + RegisteredDelegates.Add(new DataAccessDelegate(provider.readRaw)); + RegisteredDelegates.Add(new DataAccessDelegate(provider.writeRaw)); + RegisteredDelegates.Add(new GetSizeDelegate(provider.getSize)); registerProviderV1( Encoding.UTF8.GetBytes(provider.getTypeName()), Encoding.UTF8.GetBytes(provider.getName()), - Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^3]), - Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^2]), - Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^1]) + Marshal.GetFunctionPointerForDelegate(RegisteredDelegates[^3]), + Marshal.GetFunctionPointerForDelegate(RegisteredDelegates[^2]), + Marshal.GetFunctionPointerForDelegate(RegisteredDelegates[^1]) ); } diff --git a/plugins/script_loader/templates/CSharp/ImHexLibrary/UI.cs b/plugins/script_loader/templates/CSharp/ImHexLibrary/UI.cs index a12b7ac6c..ab28d3dd7 100644 --- a/plugins/script_loader/templates/CSharp/ImHexLibrary/UI.cs +++ b/plugins/script_loader/templates/CSharp/ImHexLibrary/UI.cs @@ -8,7 +8,7 @@ namespace ImHex private delegate void DrawContentDelegate(); private delegate void ActionDelegate(); - private static List _registeredDelegates = new(); + private static readonly List RegisteredDelegates = new(); [LibraryImport("ImHex")] private static partial void showMessageBoxV1(byte[] message); @@ -48,22 +48,17 @@ namespace ImHex public static string? ShowInputTextBox(string title, string message, int maxSize) { - unsafe - { - var buffer = new byte[maxSize]; - GCHandle pinnedArray = GCHandle.Alloc(buffer, GCHandleType.Pinned); - showInputTextBoxV1(Encoding.UTF8.GetBytes(title), Encoding.UTF8.GetBytes(message), pinnedArray.AddrOfPinnedObject(), maxSize); - pinnedArray.Free(); + var buffer = new byte[maxSize]; + GCHandle pinnedArray = GCHandle.Alloc(buffer, GCHandleType.Pinned); + showInputTextBoxV1(Encoding.UTF8.GetBytes(title), Encoding.UTF8.GetBytes(message), pinnedArray.AddrOfPinnedObject(), maxSize); + pinnedArray.Free(); - if (buffer.Length == 0 || buffer[0] == '\x00') - { - return null; - } - else - { - return Encoding.UTF8.GetString(buffer); - } + if (buffer.Length == 0 || buffer[0] == '\x00') + { + return null; } + + return Encoding.UTF8.GetString(buffer); } public enum ToastType @@ -85,22 +80,22 @@ namespace ImHex public static void RegisterView(byte[] icon, string name, Action function) { - _registeredDelegates.Add(new DrawContentDelegate(function)); + RegisteredDelegates.Add(new DrawContentDelegate(function)); registerViewV1( icon, Encoding.UTF8.GetBytes(name), - Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^1]) + Marshal.GetFunctionPointerForDelegate(RegisteredDelegates[^1]) ); } public static void AddMenuItem(byte[] icon, string menuName, string itemName, Action function) { - _registeredDelegates.Add(new ActionDelegate(function)); + RegisteredDelegates.Add(new ActionDelegate(function)); addMenuItemV1( icon, Encoding.UTF8.GetBytes(menuName), Encoding.UTF8.GetBytes(itemName), - Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^1]) + Marshal.GetFunctionPointerForDelegate(RegisteredDelegates[^1]) ); } diff --git a/plugins/script_loader/templates/CSharp/ImHexScript/Program.cs b/plugins/script_loader/templates/CSharp/ImHexScript/Program.cs index d7fb00686..b5a79e56f 100644 --- a/plugins/script_loader/templates/CSharp/ImHexScript/Program.cs +++ b/plugins/script_loader/templates/CSharp/ImHexScript/Program.cs @@ -1,7 +1,7 @@ using ImHex; using ImGuiNET; -class Script { +class Script : IScript { public static void OnLoad() {