using System; using System.IO; using System.Runtime.InteropServices; using S3.Core; namespace S3.Modules.Popout; /// /// Preloads the native S3Native.dll from the mod folder before any P/Invoke. /// /// S³ is a pure-UMM install: there is no winhttp proxy and Unity never calls /// UnityPluginLoad for our plugin. By loading the DLL ourselves via its full path, /// every [DllImport("S3Native")] in then binds to it by name. /// The native renderer lazily initializes its D3D device from the supplied texture, /// so the missing UnityPluginLoad is fine — that lazy path becomes the normal one. /// internal static class NativeLoader { [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] private static extern IntPtr LoadLibrary(string lpFileName); private static bool _loaded; public static bool EnsureLoaded() { if (_loaded) return true; string dll = Path.Combine(Main.ModEntry.Path, "S3Native.dll"); if (!File.Exists(dll)) { Log.Error($"[popout] native DLL not found: {dll}"); return false; } IntPtr handle = LoadLibrary(dll); if (handle == IntPtr.Zero) { Log.Error($"[popout] LoadLibrary failed (Win32 error {Marshal.GetLastWin32Error()}): {dll}"); return false; } _loaded = true; Log.Info($"[popout] native S3Native.dll loaded from {dll}"); return true; } }