diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d41535 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ +.idea/ +*DotSettings.user \ No newline at end of file diff --git a/HookInitializer.cs b/HookInitializer.cs new file mode 100644 index 0000000..70e64b5 --- /dev/null +++ b/HookInitializer.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Loader; +using Barotrauma; +using HarmonyLib; + + +[SuppressMessage("ReSharper", "UnusedType.Global")] +[SuppressMessage("ReSharper", "CheckNamespace")] +[SuppressMessage("ReSharper", "UnusedMember.Global")] +internal class StartupHook +{ + public static void Initialize() + { + if (Assembly.GetEntryAssembly()?.GetName().Name != "DedicatedServer") return; + + AssemblyLoadContext.Default.Resolving += SharedHostPolicy.SharedAssemblyResolver.LoadAssemblyFromSharedLocation; + TraumaWeaver.Utils.AssemblyLoadPathHelper("0Harmony.dll"); + TraumaWeaver.Utils.AssemblyLoadPathHelper("Mono.Cecil.dll"); + TraumaWeaver.Utils.AssemblyLoadPathHelper("MonoMod.RuntimeDetour.dll"); + TraumaWeaver.Utils.AssemblyLoadPathHelper("MonoMod.Utils.dll"); + TraumaWeaver.MainPatcher.doHarmony(); + } +} + +namespace TraumaWeaver +{ + + public static class MainPatcher + { + public static void doHarmony() + { + var harmony = new Harmony("TraumaWeaverLoader"); + + + harmony.Patch(AccessTools.Method(typeof(Program), nameof(Program.Main)), + transpiler: new HarmonyMethod(typeof(Patches), nameof(Patches.MainTranspiler))); + } + } + public static class Utils + { + public static Assembly AssemblyLoadPathHelper(string assemblyName) + { + return AssemblyLoadContext.Default.LoadFromAssemblyPath(Directory.GetCurrentDirectory() + "/" + assemblyName); + } + } + + public class Hooks + { + public static void onMain() + { + Console.WriteLine("TraumaWeaver " + Assembly.GetExecutingAssembly().GetName().Version + " Loaded"); + Console.WriteLine("Loading mods..."); + DirectoryInfo serverDllMods = Directory.CreateDirectory("ServerDllMods"); + var mods = serverDllMods.EnumerateFiles(); + foreach (FileInfo mod in mods) + { + Console.WriteLine($"Loading {mod.Name}"); + try + { + Assembly modAssembly = Assembly.LoadFrom(mod.FullName); + modAssembly.GetTypes().Find(e => e.Name == "Mod").GetMethod("ModMain")?.Invoke(null, null); + } + catch (Exception e) + { + Console.WriteLine($"Could not load {mod.FullName}\nException:\n{e}"); + } + } + } + } + + public class Patches + { + public static IEnumerable MainTranspiler(IEnumerable instructions) + { + var found = false; + foreach (CodeInstruction instruction in instructions) + { + if (instruction.Calls(AccessTools.Method(typeof(AppDomain), "get_CurrentDomain")) && !found) + { + yield return new CodeInstruction(OpCodes.Call, typeof(Hooks).GetMethod(nameof(Hooks.onMain))); + found = true; + } + yield return instruction; + } + if (!found) + { + Console.WriteLine("Cannot find Program.Main"); + } + } + } +} + +namespace SharedHostPolicy +{ + internal static class SharedAssemblyResolver + { + public static Assembly LoadAssemblyFromSharedLocation(AssemblyLoadContext context, AssemblyName assemblyName) + { + string sharedAssemblyPath = Directory.GetCurrentDirectory(); // find assemblyName in shared location... + return sharedAssemblyPath != null ? AssemblyLoadContext.Default.LoadFromAssemblyPath(sharedAssemblyPath) : null; + } + } +} \ No newline at end of file diff --git a/IMod.cs b/IMod.cs new file mode 100644 index 0000000..85ed212 --- /dev/null +++ b/IMod.cs @@ -0,0 +1,8 @@ +using System; +namespace TraumaWeaver +{ + public interface IMod + { + static string ModMain() => throw new NotImplementedException(); + } +} diff --git a/TraumaWeaver.csproj b/TraumaWeaver.csproj new file mode 100644 index 0000000..e678133 --- /dev/null +++ b/TraumaWeaver.csproj @@ -0,0 +1,21 @@ + + + + Library + netcoreapp3.1 + true + + + + + + + + + + ..\HolyTraumaGrail\bin\Debug\netcoreapp3.1\DedicatedServer-nstrip.dll + False + + + + diff --git a/TraumaWeaver.sln b/TraumaWeaver.sln new file mode 100644 index 0000000..3726d28 --- /dev/null +++ b/TraumaWeaver.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraumaWeaver", "TraumaWeaver.csproj", "{9531E183-CFA3-46DF-99A6-6D8311417709}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9531E183-CFA3-46DF-99A6-6D8311417709}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9531E183-CFA3-46DF-99A6-6D8311417709}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9531E183-CFA3-46DF-99A6-6D8311417709}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9531E183-CFA3-46DF-99A6-6D8311417709}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/global.json b/global.json new file mode 100644 index 0000000..5898a04 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "3.1.0", + "rollForward": "latestMinor", + "allowPrerelease": false + } +} \ No newline at end of file