diff --git a/CringeLauncher/Patches/DarkTardMissingNamespacePatch.cs b/CringeLauncher/Patches/DarkTardMissingNamespacePatch.cs index 7c57e5b..219a68e 100644 --- a/CringeLauncher/Patches/DarkTardMissingNamespacePatch.cs +++ b/CringeLauncher/Patches/DarkTardMissingNamespacePatch.cs @@ -7,7 +7,7 @@ namespace CringeLauncher.Patches; [HarmonyPatch(typeof(MyScriptManager), nameof(MyScriptManager.Init))] public static class DarkTardMissingNamespacePatch { - private static void Postfix(Dictionary ___m_compatibilityChanges) + private static void Prefix(Dictionary ___m_compatibilityChanges) { ___m_compatibilityChanges["using System.Runtime.Remoting.Metadata.W3cXsd2001;"] = ""; ___m_compatibilityChanges["using System.IO.Ports;"] = ""; diff --git a/PluginLoader/Compiler/RoslynCompiler.cs b/PluginLoader/Compiler/RoslynCompiler.cs index e5a2202..78ad4c4 100644 --- a/PluginLoader/Compiler/RoslynCompiler.cs +++ b/PluginLoader/Compiler/RoslynCompiler.cs @@ -35,7 +35,7 @@ public class RoslynCompiler RoslynReferences.EnumerateAllReferences(), new( OutputKind.DynamicallyLinkedLibrary, - optimizationLevel: debugBuild ? OptimizationLevel.Debug : OptimizationLevel.Release)); + optimizationLevel: debugBuild ? OptimizationLevel.Debug : OptimizationLevel.Release, allowUnsafe: true)); using (var pdb = new MemoryStream()) using (var ms = new MemoryStream()) diff --git a/PluginLoader/Compiler/RoslynReferences.cs b/PluginLoader/Compiler/RoslynReferences.cs index eb78dcd..1983534 100644 --- a/PluginLoader/Compiler/RoslynReferences.cs +++ b/PluginLoader/Compiler/RoslynReferences.cs @@ -43,6 +43,12 @@ public static class RoslynReferences AddAssemblyReference(a); sb.AppendLine(a.FullName); } + + foreach(var a in GetOtherReferences()) + { + AddAssemblyReference(a); + sb.AppendLine(a.FullName); + } sb.AppendLine(line); while (loadedAssemblies.Count > 0) @@ -77,6 +83,14 @@ public static class RoslynReferences LogFile.WriteLine(sb.ToString(), false); } + + /// + /// This method is used to load references that otherwise would not exist or be optimized out + /// + private static IEnumerable GetOtherReferences() + { + yield return typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly; + } private static bool ContainsReference(AssemblyName name) { diff --git a/PluginLoader/Data/GitHubPlugin.cs b/PluginLoader/Data/GitHubPlugin.cs index 4a2ada8..dbc407e 100644 --- a/PluginLoader/Data/GitHubPlugin.cs +++ b/PluginLoader/Data/GitHubPlugin.cs @@ -68,12 +68,12 @@ public class GitHubPlugin : PluginData return sb.ToString(); } - public override Assembly GetAssembly() + public override Assembly? GetAssembly() { if (!Directory.Exists(cacheDir)) Directory.CreateDirectory(cacheDir); - Assembly a; + Assembly? a; var dllFile = Path.Combine(cacheDir, pluginFile); var commitFile = Path.Combine(cacheDir, commitHashFile); diff --git a/PluginLoader/Data/LocalFolderPlugin.cs b/PluginLoader/Data/LocalFolderPlugin.cs index ea55c25..13bbdb1 100644 --- a/PluginLoader/Data/LocalFolderPlugin.cs +++ b/PluginLoader/Data/LocalFolderPlugin.cs @@ -38,7 +38,7 @@ public class LocalFolderPlugin : PluginData public Config FolderSettings { get; } - public override Assembly GetAssembly() + public override Assembly? GetAssembly() { if (Directory.Exists(Id)) { diff --git a/PluginLoader/Data/LocalPlugin.cs b/PluginLoader/Data/LocalPlugin.cs index 69b8ac9..135d39b 100644 --- a/PluginLoader/Data/LocalPlugin.cs +++ b/PluginLoader/Data/LocalPlugin.cs @@ -30,14 +30,26 @@ public class LocalPlugin : PluginData } } - public override Assembly GetAssembly() + public override Assembly? GetAssembly() { - if (File.Exists(Id)) + if (!File.Exists(Id)) return null; + //prevent random unloading if being used by another process + int maxRetries = 10; + while (maxRetries > 0) { - AppDomain.CurrentDomain.AssemblyResolve += LoadFromSameFolder; - var a = Assembly.LoadFile(Id); - Version = a.GetName().Version; - return a; + try + { + AppDomain.CurrentDomain.AssemblyResolve += LoadFromSameFolder; + var a = Assembly.LoadFile(Id); + Version = a?.GetName()?.Version ?? Version; + return a; + } + catch (IOException) + { + LogFile.WriteLine($"Waiting to load {Id} because it's being used by another process"); + Thread.Sleep(250); + maxRetries--; + } } return null; @@ -55,27 +67,28 @@ public class LocalPlugin : PluginData Process.Start("explorer.exe", $"/select, \"{file}\""); } - private Assembly LoadFromSameFolder(object sender, ResolveEventArgs args) + private Assembly? LoadFromSameFolder(object sender, ResolveEventArgs args) { - if (args.RequestingAssembly.IsDynamic) + if (args.RequestingAssembly?.IsDynamic ?? false) return null; if (args.Name.Contains("0Harmony") || args.Name.Contains("SEPluginManager")) return null; - var location = args.RequestingAssembly.Location; + var location = args.RequestingAssembly?.Location; if (string.IsNullOrWhiteSpace(location) || !Path.GetFullPath(location) - .StartsWith(Path.GetDirectoryName(Id), + .StartsWith(Path.GetDirectoryName(Id)!, StringComparison.OrdinalIgnoreCase)) return null; - var folderPath = Path.GetDirectoryName(location); + var folderPath = Path.GetDirectoryName(Id); + if (string.IsNullOrEmpty(folderPath)) return null; var assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll"); if (!File.Exists(assemblyPath)) return null; var assembly = Assembly.LoadFile(assemblyPath); - LogFile.WriteLine("Resolving " + assembly.GetName().Name + " for " + args.RequestingAssembly.FullName); + LogFile.WriteLine("Resolving " + assembly.GetName().Name + " for " + args.RequestingAssembly?.FullName); var main = Main.Instance; if (!main.Config.IsEnabled(assemblyPath)) diff --git a/PluginLoader/Data/ModPlugin.cs b/PluginLoader/Data/ModPlugin.cs index 0b3cc02..b3bc6e0 100644 --- a/PluginLoader/Data/ModPlugin.cs +++ b/PluginLoader/Data/ModPlugin.cs @@ -58,12 +58,12 @@ public class ModPlugin : PluginData, ISteamItem } } - public override Assembly GetAssembly() + public override Assembly? GetAssembly() { return null; } - public override bool TryLoadAssembly(out Assembly a) + public override bool TryLoadAssembly(out Assembly? a) { a = null; return false; diff --git a/PluginLoader/Data/PluginData.cs b/PluginLoader/Data/PluginData.cs index 9d1ab20..246266f 100644 --- a/PluginLoader/Data/PluginData.cs +++ b/PluginLoader/Data/PluginData.cs @@ -72,9 +72,9 @@ public abstract class PluginData : IEquatable Id == other.Id; } - public abstract Assembly GetAssembly(); + public abstract Assembly? GetAssembly(); - public virtual bool TryLoadAssembly(out Assembly a) + public virtual bool TryLoadAssembly(out Assembly? a) { if (Status == PluginStatus.Error) { diff --git a/PluginLoader/Data/SteamPlugin.cs b/PluginLoader/Data/SteamPlugin.cs index c8e08cd..6cdf2b5 100644 --- a/PluginLoader/Data/SteamPlugin.cs +++ b/PluginLoader/Data/SteamPlugin.cs @@ -53,7 +53,7 @@ public abstract class SteamPlugin : PluginData, ISteamItem } } - public override Assembly GetAssembly() + public override Assembly? GetAssembly() { if (Status == PluginStatus.PendingUpdate) { diff --git a/PluginLoader/Main.cs b/PluginLoader/Main.cs index 866ad1a..1401597 100644 --- a/PluginLoader/Main.cs +++ b/PluginLoader/Main.cs @@ -82,7 +82,7 @@ public class Main : IHandleInputPlugin sw.Stop(); // FIXME: It can potentially run in the background speeding up the game's startup - ReportEnabledPlugins(); + //ReportEnabledPlugins(); LogFile.WriteLine($"Finished startup. Took {sw.ElapsedMilliseconds}ms"); @@ -220,6 +220,11 @@ public class Main : IHandleInputPlugin return typeof(Harmony).Assembly; } + if (args.Name.Contains("MonoMod.RuntimeDetour")) + { + return typeof(MonoMod.RuntimeDetour.NativeHook).Assembly; + } + if (args.Name.Contains("SEPluginManager")) { if (assembly != null) diff --git a/PluginLoader/PluginInstance.cs b/PluginLoader/PluginInstance.cs index 48b457c..899e653 100644 --- a/PluginLoader/PluginInstance.cs +++ b/PluginLoader/PluginInstance.cs @@ -11,13 +11,13 @@ namespace PluginLoader; public class PluginInstance { private readonly PluginData data; - private readonly Assembly mainAssembly; + private readonly Assembly? mainAssembly; private readonly Type mainType; private IHandleInputPlugin inputPlugin; private MethodInfo openConfigDialog; private IPlugin plugin; - private PluginInstance(PluginData data, Assembly mainAssembly, Type mainType) + private PluginInstance(PluginData data, Assembly? mainAssembly, Type mainType) { this.data = data; this.mainAssembly = mainAssembly;