diff --git a/.gitignore b/.gitignore index 4ce6fdd..b289c4e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ *.userprefs # Build results +__BUILD/ [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ @@ -337,4 +338,4 @@ ASALocalRun/ .localhistory/ # BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file +healthchecksdb diff --git a/Centrifuge.UnityInterop/Bridges/SceneManagerBridge.cs b/Centrifuge.UnityInterop/Bridges/SceneManagerBridge.cs index 0be1af3..14bb334 100644 --- a/Centrifuge.UnityInterop/Bridges/SceneManagerBridge.cs +++ b/Centrifuge.UnityInterop/Bridges/SceneManagerBridge.cs @@ -32,20 +32,20 @@ public static void AttachSceneLoadedEventHandler(object target) { Integrity.EnsureNotNull(target); Integrity.EnsureNull(SceneLoadedEventHandlerDelegate); - + var actualDelegateType = GenericDelegateType.MakeGenericType(new[] { SceneType, LoadSceneModeType }); - + SceneLoadedEventHandlerDelegate = Delegate.CreateDelegate( actualDelegateType, target, Resources.Proxy.SceneLoadProxyMethodName, false, true ); - + PreviousSceneLoadedAttachTarget = target; - + var ev = SceneManagerType.GetEvent( Resources.UnityEngine.SceneLoadedEventName, BindingFlags.Public | BindingFlags.Static ); - + ev.AddEventHandler(null, SceneLoadedEventHandlerDelegate); } diff --git a/Centrifuge.UnityInterop/Builders/ManagerProxyBuilder.cs b/Centrifuge.UnityInterop/Builders/ManagerProxyBuilder.cs index 8a85f72..ac7158f 100644 --- a/Centrifuge.UnityInterop/Builders/ManagerProxyBuilder.cs +++ b/Centrifuge.UnityInterop/Builders/ManagerProxyBuilder.cs @@ -1,156 +1,206 @@ -using Centrifuge.UnityInterop.Bridges; -using System; +using System; +using System.IO; +using System.Linq; using System.Reflection; -using System.Reflection.Emit; +using Centrifuge.UnityInterop.Bridges; +using Mono.Cecil; +using Mono.Cecil.Cil; +using FieldAttributes = Mono.Cecil.FieldAttributes; +using MethodAttributes = Mono.Cecil.MethodAttributes; +using ParameterAttributes = Mono.Cecil.ParameterAttributes; +using TypeAttributes = Mono.Cecil.TypeAttributes; namespace Centrifuge.UnityInterop.Builders { public class ManagerProxyBuilder { - private AssemblyName ProxyAssemblyName { get; } - private AssemblyBuilder ProxyAssemblyBuilder { get; } - private ModuleBuilder ProxyModuleBuilder { get; } - private TypeBuilder ProxyTypeBuilder { get; } + private FieldDefinition ManagerFieldDefinition { get; } + + private AssemblyNameDefinition ProxyAssemblyNameDefinition { get; } + private AssemblyDefinition ProxyAssemblyDefinition { get; } + private ModuleDefinition ProxyMainModule { get; } + private TypeDefinition ProxyTypeDefinition { get; } public ManagerProxyBuilder() { - ProxyAssemblyName = new AssemblyName(Resources.Proxy.AssemblyName); - ProxyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(ProxyAssemblyName, AssemblyBuilderAccess.Run); - ProxyModuleBuilder = ProxyAssemblyBuilder.DefineDynamicModule(Resources.Proxy.ModuleName); - ProxyTypeBuilder = ProxyModuleBuilder.DefineType( + ProxyAssemblyNameDefinition = new AssemblyNameDefinition(Resources.Proxy.AssemblyName, new Version(1, 0)); + + ProxyAssemblyDefinition = + AssemblyDefinition.CreateAssembly(ProxyAssemblyNameDefinition, Resources.Proxy.AssemblyName, + ModuleKind.Dll); + ProxyMainModule = ProxyAssemblyDefinition.MainModule; + ProxyMainModule.RuntimeVersion = ".NETStandard,Version=v2.0"; + + ProxyTypeDefinition = new TypeDefinition( + Resources.Proxy.AssemblyName, Resources.Proxy.ManagerTypeName, - TypeAttributes.Class | - TypeAttributes.Public | - TypeAttributes.AnsiClass | - TypeAttributes.BeforeFieldInit, - MonoBehaviourBridge.MonoBehaviourType + TypeAttributes.Class | + TypeAttributes.Public | + TypeAttributes.AnsiClass | + TypeAttributes.BeforeFieldInit, + ProxyMainModule.ImportReference(MonoBehaviourBridge.MonoBehaviourType) ); - BuildManagerField(); + ManagerFieldDefinition = BuildManagerField(); BuildLoggerProxy(); BuildSceneLoadProxy(); BuildAwakeMethod(); BuildUpdateMethod(); + + ProxyMainModule.Types.Add(ProxyTypeDefinition); } - public Type Build() + public Type WriteDynamicAssemblyAndLoadProxyType() { - return ProxyTypeBuilder.CreateType(); + var asmLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + var targetAsmPath = Path.Combine(asmLocation!, Resources.Proxy.AssemblyFileName); + + if (File.Exists(targetAsmPath)) + { + File.Delete(targetAsmPath); + } + + ProxyAssemblyDefinition.Write(targetAsmPath); + + var asm = Assembly.LoadFrom(targetAsmPath); + return asm.GetTypes().First(); } - private void BuildManagerField() + private FieldDefinition BuildManagerField() { - ProxyTypeBuilder.DefineField( + var def = new FieldDefinition( Resources.Proxy.ManagerFieldName, - ReactorBridge.ReactorManagerType, - FieldAttributes.Public - ); + FieldAttributes.Public, + ProxyMainModule.ImportReference(ReactorBridge.ReactorManagerType)); + + ProxyTypeDefinition.Fields.Add(def); + + return def; } private void BuildLoggerProxy() { - var proxyMethod = ProxyTypeBuilder.DefineMethod( + var methodDef = new MethodDefinition( Resources.Proxy.LogProxyMethodName, - MethodAttributes.Public | - MethodAttributes.HideBySig, - CallingConventions.HasThis, - typeof(void), - new[] { typeof(string), typeof(string), ApplicationBridge.LogTypeType } - ); + MethodAttributes.Public | + MethodAttributes.HideBySig, + ProxyMainModule.ImportReference(typeof(void))); + + methodDef.CallingConvention = MethodCallingConvention.Default; + methodDef.Parameters.Add( + new ParameterDefinition("msg", ParameterAttributes.None, + ProxyMainModule.ImportReference(typeof(string)))); + + methodDef.Parameters.Add( + new ParameterDefinition("state", ParameterAttributes.None, + ProxyMainModule.ImportReference(typeof(string)))); - var loggerMethod = ReactorBridge.ReactorUnityLogType.GetMethod( + methodDef.Parameters.Add( + new ParameterDefinition("logType", ParameterAttributes.None, + ProxyMainModule.ImportReference(ApplicationBridge.LogTypeType))); + + + var loggerMethod = ProxyMainModule.ImportReference(ReactorBridge.ReactorUnityLogType.GetMethod( Resources.ReactorManager.UnityLogMethodName, - new[] { typeof(string), typeof(string), typeof(int) } - ); + new[] {typeof(string), typeof(string), typeof(int)} + )); - var propertyGetMethod = ReactorBridge.ReactorManagerType.GetProperty( + var propertyGetMethod = ProxyMainModule.ImportReference(ReactorBridge.ReactorManagerType.GetProperty( Resources.ReactorManager.UnityLogPropertyName, BindingFlags.Instance | BindingFlags.Public - ).GetGetMethod(); + ).GetGetMethod()); - var ilGen = proxyMethod.GetILGenerator(); + var ilGen = methodDef.Body.GetILProcessor(); ilGen.Emit(OpCodes.Ldarg_0); - ilGen.Emit(OpCodes.Ldfld, ProxyTypeBuilder.GetField(Resources.Proxy.ManagerFieldName)); + ilGen.Emit(OpCodes.Ldfld, ManagerFieldDefinition); ilGen.Emit(OpCodes.Callvirt, propertyGetMethod); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Ldarg_3); ilGen.Emit(OpCodes.Callvirt, loggerMethod); ilGen.Emit(OpCodes.Ret); + + ProxyTypeDefinition.Methods.Add(methodDef); } private void BuildSceneLoadProxy() { - var proxyMethod = ProxyTypeBuilder.DefineMethod( + var methodDef = new MethodDefinition( Resources.Proxy.SceneLoadProxyMethodName, - MethodAttributes.Public | - MethodAttributes.HideBySig, - CallingConventions.HasThis, - typeof(void), - new[] { SceneManagerBridge.SceneType, SceneManagerBridge.LoadSceneModeType } - ); - - var assetLoadHookMethod = ReactorBridge.ReactorManagerType.GetMethod( + MethodAttributes.Public | + MethodAttributes.HideBySig, + ProxyMainModule.ImportReference(typeof(void))); + + methodDef.Parameters.Add( + new ParameterDefinition(ProxyMainModule.ImportReference(SceneManagerBridge.SceneType)) + ); + + methodDef.Parameters.Add( + new ParameterDefinition(ProxyMainModule.ImportReference(SceneManagerBridge.LoadSceneModeType)) + ); + + var assetLoadHookMethod = ProxyMainModule.ImportReference(ReactorBridge.ReactorManagerType.GetMethod( Resources.ReactorManager.CallAssetLoadHooksMethodName, BindingFlags.Instance | BindingFlags.Public - ); - - var ilGen = proxyMethod.GetILGenerator(); - + )); + + var ilGen = methodDef.Body.GetILProcessor(); + ilGen.Emit(OpCodes.Ldarg_0); - ilGen.Emit(OpCodes.Ldfld, ProxyTypeBuilder.GetField(Resources.Proxy.ManagerFieldName)); + ilGen.Emit(OpCodes.Ldfld, ManagerFieldDefinition); ilGen.Emit(OpCodes.Callvirt, assetLoadHookMethod); ilGen.Emit(OpCodes.Ret); + + ProxyTypeDefinition.Methods.Add(methodDef); } private void BuildAwakeMethod() { - var methodBuilder = ProxyTypeBuilder.DefineMethod( + var methodDef = new MethodDefinition( Resources.Proxy.AwakeMethodName, - MethodAttributes.Public | - MethodAttributes.HideBySig, - CallingConventions.HasThis - ); + MethodAttributes.Public | + MethodAttributes.HideBySig, + ProxyMainModule.ImportReference(typeof(void))); - var ilGen = methodBuilder.GetILGenerator(); + var ilGen = methodDef.Body.GetILProcessor(); // UnityEngine.DontDestroyOnLoad ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit( OpCodes.Call, - MonoBehaviourBridge.MonoBehaviourType.GetProperty( + ProxyMainModule.ImportReference(MonoBehaviourBridge.MonoBehaviourType.GetProperty( Resources.UnityEngine.MonoBehaviourGameObjectFieldName, BindingFlags.Public | BindingFlags.Instance - ).GetGetMethod() + ).GetGetMethod()) ); ilGen.Emit( OpCodes.Call, - GameObjectBridge.ObjectType.GetMethod( + ProxyMainModule.ImportReference(GameObjectBridge.ObjectType.GetMethod( Resources.UnityEngine.ObjectDontDestroyOnLoadMethodName, BindingFlags.Public | BindingFlags.Static - ) + )) ); // ApplicationBridge.AttachLoggingEventHandler(this); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit( OpCodes.Call, - typeof(ApplicationBridge).GetMethod( + ProxyMainModule.ImportReference(typeof(ApplicationBridge).GetMethod( nameof(ApplicationBridge.AttachLoggingEventHandler), BindingFlags.Public | BindingFlags.Static - ) + )) ); // SceneManagerBridge.AttachSceneLoadedEventHandler(this); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit( OpCodes.Call, - typeof(SceneManagerBridge).GetMethod( + ProxyMainModule.ImportReference(typeof(SceneManagerBridge).GetMethod( nameof(SceneManagerBridge.AttachSceneLoadedEventHandler), BindingFlags.Public | BindingFlags.Static - ) + )) ); // ------------------------------------------- @@ -158,41 +208,45 @@ private void BuildAwakeMethod() ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit( OpCodes.Newobj, - ReactorBridge.ReactorManagerType.GetConstructor(new Type[] { }) + ProxyMainModule.ImportReference(ReactorBridge.ReactorManagerType.GetConstructor(new Type[] { })) ); ilGen.Emit( OpCodes.Stfld, - ProxyTypeBuilder.GetField(Resources.Proxy.ManagerFieldName) + ManagerFieldDefinition ); ilGen.Emit(OpCodes.Ret); + + ProxyTypeDefinition.Methods.Add(methodDef); } private void BuildUpdateMethod() { - var methodBuilder = ProxyTypeBuilder.DefineMethod( + var methodDef = new MethodDefinition( Resources.Proxy.UpdateMethodName, - MethodAttributes.Public | - MethodAttributes.HideBySig, - CallingConventions.HasThis + MethodAttributes.Public | + MethodAttributes.HideBySig, + ProxyMainModule.ImportReference(typeof(void)) ); - var ilGen = methodBuilder.GetILGenerator(); + var ilGen = methodDef.Body.GetILProcessor(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit( OpCodes.Ldfld, - ProxyTypeBuilder.GetField(Resources.Proxy.ManagerFieldName) + ManagerFieldDefinition ); ilGen.Emit( OpCodes.Callvirt, - ReactorBridge.ReactorManagerType.GetMethod( + ProxyMainModule.ImportReference(ReactorBridge.ReactorManagerType.GetMethod( Resources.ReactorManager.UpdateMethodName, BindingFlags.Instance | BindingFlags.Public - ) + )) ); ilGen.Emit(OpCodes.Ret); + + ProxyTypeDefinition.Methods.Add(methodDef); } } -} +} \ No newline at end of file diff --git a/Centrifuge.UnityInterop/Centrifuge.UnityInterop.csproj b/Centrifuge.UnityInterop/Centrifuge.UnityInterop.csproj index 3e536eb..b124bb6 100644 --- a/Centrifuge.UnityInterop/Centrifuge.UnityInterop.csproj +++ b/Centrifuge.UnityInterop/Centrifuge.UnityInterop.csproj @@ -1,25 +1,37 @@  - - net35 - Centrifuge.UnityInterop - Centrifuge Project - Centrifuge.UnityInterop - Unity glue code for Centrifuge Mod Loader. - Copyright 2019 © Centrifuge Project - bin\$(Configuration)\ - 1.0.0 - 2.2.0 - 2.2.0 - 8.0 - true - + + net35;netstandard20 + Centrifuge.UnityInterop + Centrifuge Project + Centrifuge.UnityInterop + Unity glue code for Centrifuge Mod Loader. + Copyright 2020 © Centrifuge Project + ..\__BUILD\$(Configuration) + 1.0.0 + 3.0.0 + 3.0.0 + 8.0 + true + + + + true + + + + + + + + + - - full - false - - - - pdbonly - + + full + false + + + + pdbonly + \ No newline at end of file diff --git a/Centrifuge.UnityInterop/Resources.cs b/Centrifuge.UnityInterop/Resources.cs index bb3348e..ad34dce 100644 --- a/Centrifuge.UnityInterop/Resources.cs +++ b/Centrifuge.UnityInterop/Resources.cs @@ -37,6 +37,7 @@ internal static class UnityEngine internal static class Proxy { + internal const string AssemblyFileName = "Centrifuge.DynProxy.dll"; internal const string AssemblyName = "Centrifuge.UnityInterop.DynamicProxyAssembly"; internal const string ManagerFieldName = "Manager"; diff --git a/Centrifuge/Bootstrap.cs b/Centrifuge/Bootstrap.cs index 8af32ea..bbc6da7 100644 --- a/Centrifuge/Bootstrap.cs +++ b/Centrifuge/Bootstrap.cs @@ -66,7 +66,13 @@ public static void Initialize() Assembly.LoadFrom(reactorPath); EarlyLog.Info("Building manager proxy component for Unity Engine..."); - proxyType = new ManagerProxyBuilder().Build(); + proxyType = new ManagerProxyBuilder().WriteDynamicAssemblyAndLoadProxyType(); + + if (proxyType == null) + { + EarlyLog.Info("Failed."); + return; + } } catch (ReflectionTypeLoadException rtle) { diff --git a/Centrifuge/Centrifuge.csproj b/Centrifuge/Centrifuge.csproj index 791858c..93cfb32 100644 --- a/Centrifuge/Centrifuge.csproj +++ b/Centrifuge/Centrifuge.csproj @@ -1,25 +1,32 @@  - net35 + net35;netstandard20 Centrifuge Centrifuge Project Centrifuge Centrifuge Bootstrapper module - Copyright 2019 © Centrifuge Project - 2.0.0 - 2.2.0 - 2.1.0 + Copyright 2020 © Centrifuge Project + 3.0.0 + 3.0.0 + 3.0.0 8.0 true - bin\$(Configuration)\ + ..\__BUILD\$(Configuration) + + + true + + full false + pdbonly + diff --git a/Reactor.API/Configuration/Section.cs b/Reactor.API/Configuration/Section.cs index 9794114..442db92 100644 --- a/Reactor.API/Configuration/Section.cs +++ b/Reactor.API/Configuration/Section.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Reactor.API.Configuration { @@ -70,6 +71,9 @@ public T GetItem(string key) try { + if (this[key] is JToken jToken) + return jToken.ToObject(); + return (T)Convert.ChangeType(this[key], typeof(T)); } catch (JsonException je) @@ -95,4 +99,4 @@ public bool ContainsKey(string key) } } } -} +} \ No newline at end of file diff --git a/Reactor.API/Logging/Base/Sink.cs b/Reactor.API/Logging/Base/Sink.cs index 6964399..3d850b6 100644 --- a/Reactor.API/Logging/Base/Sink.cs +++ b/Reactor.API/Logging/Base/Sink.cs @@ -4,6 +4,7 @@ public abstract class Sink { public bool Active { get; set; } = true; + public abstract void Write(string message, params object[] args); public abstract void Write(LogLevel logLevel, string message, params object[] args); } diff --git a/Reactor.API/Logging/Log.cs b/Reactor.API/Logging/Log.cs index a38261d..e888da5 100644 --- a/Reactor.API/Logging/Log.cs +++ b/Reactor.API/Logging/Log.cs @@ -26,6 +26,11 @@ internal Log() Template = "{Message}"; } + public void Raw(string message) + { + PushRawToAllActiveSinks(message); + } + public void Info(string message) { EnsureNotClosed(); @@ -167,6 +172,12 @@ public void Close() HasBeenClosed = true; } + private void PushRawToAllActiveSinks(string message, params object[] sinkArgs) + { + foreach (var sink in Sinks.Where(x => x.Active)) + sink.Write(message, sinkArgs); + } + private void DecorateAndPushToAllActiveSinks(LogLevel logLevel, string message, params object[] sinkArgs) { foreach (var sink in Sinks.Where(x => x.Active)) diff --git a/Reactor.API/Logging/Sinks/ConsoleSink.cs b/Reactor.API/Logging/Sinks/ConsoleSink.cs index b08213f..929e764 100644 --- a/Reactor.API/Logging/Sinks/ConsoleSink.cs +++ b/Reactor.API/Logging/Sinks/ConsoleSink.cs @@ -6,7 +6,7 @@ namespace Reactor.API.Logging.Sinks { public class ConsoleSink : Sink { - public override void Write(LogLevel logLevel, string message, params object[] args) + public override void Write(string message, params object[] args) { Console.WriteLine(message); @@ -18,7 +18,7 @@ public override void Write(LogLevel logLevel, string message, params object[] ar Formatting.ReflectionTypeLoadExceptionForLogging(rtle) ); } - else if(args[0] is Exception e) + else if (args[0] is Exception e) { Console.WriteLine( Formatting.ExceptionForLogging(e, true) @@ -26,5 +26,8 @@ public override void Write(LogLevel logLevel, string message, params object[] ar } } } + + public override void Write(LogLevel logLevel, string message, params object[] args) + => Write(message); } } diff --git a/Reactor.API/Logging/Sinks/StreamSink.cs b/Reactor.API/Logging/Sinks/StreamSink.cs index 30b5c1d..5e73ed3 100644 --- a/Reactor.API/Logging/Sinks/StreamSink.cs +++ b/Reactor.API/Logging/Sinks/StreamSink.cs @@ -14,7 +14,7 @@ public StreamSink(Stream stream) StreamWriter = new StreamWriter(stream) { AutoFlush = true }; } - public override void Write(LogLevel logLevel, string message, params object[] args) + public override void Write(string message, params object[] args) { StreamWriter.WriteLine(message); @@ -35,6 +35,9 @@ public override void Write(LogLevel logLevel, string message, params object[] ar } } + public override void Write(LogLevel logLevel, string message, params object[] args) + => Write(message, args); + public void Dispose() { StreamWriter.Dispose(); diff --git a/Reactor.API/Reactor.API.csproj b/Reactor.API/Reactor.API.csproj index 0a56a6a..0357216 100644 --- a/Reactor.API/Reactor.API.csproj +++ b/Reactor.API/Reactor.API.csproj @@ -1,62 +1,63 @@  - - net35 - - true - 8.0 - bin\$(Configuration)\ - - - - full - false - - - - pdbonly - - - - Reactor.API - Reactor.API - Centrifuge Project - Centrifuge Reactor API component. Doing the heavy lifting so you don't have to. - Copyright 2019 © Centrifuge Project - Reactor.API - - 1.0.0 - 2.2.0 - - - - Centrifuge.Mod.SDK - MIT - 2.3.0 - https://github.com/Ciastex/Centrifuge - https://github.com/Ciastex/Centrifuge - Git - Ciastex - Game Modding, Unity Engine, Unity3D, SDK, CIL, Mono, Modding Toolkit - true - - - - - - - - - - - - - - - - - - - all - - + + net35;netstandard20 + Reactor.API + Reactor.API + Centrifuge Project + Centrifuge Reactor API component. Doing the heavy lifting so you don't have to. + Copyright 2020 © Centrifuge Project + Reactor.API + 1.0.0 + 3.1.0 + true + 8.0 + ..\__BUILD\$(Configuration) + + + + Centrifuge.Mod.SDK + MIT + 3.1.0 + https://github.com/Ciastex/Centrifuge + https://github.com/Ciastex/Centrifuge + Git + Ciastex + Game Modding, Unity Engine, Unity3D, SDK, CIL, Mono, Modding Toolkit + true + + + + true + + + + full + false + + + + pdbonly + + + + + + + + + + + + + + + + + + + + + all + + \ No newline at end of file diff --git a/Reactor.API/Runtime/Patching/GameCodeTranspiler.cs b/Reactor.API/Runtime/Patching/GameCodeTranspiler.cs index ee98981..d5741ed 100644 --- a/Reactor.API/Runtime/Patching/GameCodeTranspiler.cs +++ b/Reactor.API/Runtime/Patching/GameCodeTranspiler.cs @@ -1,9 +1,9 @@ -using Harmony; +using HarmonyLib; namespace Reactor.API.Runtime.Patching { public abstract class GameCodeTranspiler { - public abstract void Apply(HarmonyInstance harmonyInstance); + public abstract void Apply(Harmony harmony); } } diff --git a/Reactor.API/Runtime/Patching/RuntimePatcher.cs b/Reactor.API/Runtime/Patching/RuntimePatcher.cs index e15a2c3..f26e559 100644 --- a/Reactor.API/Runtime/Patching/RuntimePatcher.cs +++ b/Reactor.API/Runtime/Patching/RuntimePatcher.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using Reactor.API.Logging; using System; using System.Reflection; @@ -9,11 +9,11 @@ public static class RuntimePatcher { private static Log Log => LogManager.GetForInternalAssembly(); - public static HarmonyInstance HarmonyInstance { get; } + public static Harmony HarmonyInstance { get; } static RuntimePatcher() { - HarmonyInstance = HarmonyInstance.Create(Defaults.ReactorModLoaderNamespace); + HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), Defaults.ReactorModLoaderNamespace); } public static void RunTranspilers() diff --git a/Reactor/HarmonyXLog.cs b/Reactor/HarmonyXLog.cs new file mode 100644 index 0000000..5696276 --- /dev/null +++ b/Reactor/HarmonyXLog.cs @@ -0,0 +1,45 @@ +using HarmonyLib.Tools; +using Reactor.API.Logging; +using System.IO; +using System.Text; + +namespace Reactor +{ + public class HarmonyXLog : TextWriter + { + private Log Log { get; } = LogManager.GetForCurrentAssembly(); + + public bool IsEnabled => Manager.Settings.GetItem(Resources.InterceptHarmonyXLogsSettingsKey); + public override Encoding Encoding => Encoding.UTF8; + + internal HarmonyXLog() + { + Logger.ChannelFilter = Logger.LogChannel.All; + + HarmonyFileLog.Writer = this; + Logger.MessageReceived += Logger_MessageReceived; + } + + private void Logger_MessageReceived(object sender, Logger.LogEventArgs e) + { + if (!IsEnabled) + return; + + switch (e.LogChannel) + { + case Logger.LogChannel.Warn: + Log.Warning(e.Message); + break; + case Logger.LogChannel.IL: + Log.Debug(e.Message); + break; + case Logger.LogChannel.Error: + Log.Error(e.Message); + break; + default: + Log.Info(e.Message); + break; + } + } + } +} diff --git a/Reactor/Manager.cs b/Reactor/Manager.cs index 352cfbb..30ca2cb 100644 --- a/Reactor/Manager.cs +++ b/Reactor/Manager.cs @@ -22,6 +22,7 @@ public class Manager : IManager internal static Settings Settings { get; private set; } public UnityLog UnityLog { get; } + public HarmonyXLog HarmonyXLog { get; } public IHotkeyManager Hotkeys { get; private set; } public IMessenger Messenger { get; private set; } @@ -34,6 +35,7 @@ public Manager() InitializeSettings(); UnityLog = new UnityLog(); + HarmonyXLog = new HarmonyXLog(); Hotkeys = new HotkeyManager(); Messenger = new Messenger(); @@ -65,6 +67,7 @@ private void InitializeSettings() { Settings = new Settings("reactor"); Settings.GetOrCreate(Resources.InterceptUnityLogsSettingsKey, true); + Settings.GetOrCreate(Resources.InterceptHarmonyXLogsSettingsKey, true); Settings.SaveIfDirty(); } diff --git a/Reactor/Reactor.csproj b/Reactor/Reactor.csproj index 7cbbbfc..408f262 100644 --- a/Reactor/Reactor.csproj +++ b/Reactor/Reactor.csproj @@ -1,35 +1,42 @@  - - net35 - Reactor - Centrifuge Project - Reactor - Centrifuge Reactor Mod Loader Module - Copyright 2019 © Centrifuge Project - 1.0.0 - 2.2.1 - 2.2.1 - 8.0 - bin\$(Configuration)\ - true - + + net35;netstandard20 + Reactor + Centrifuge Project + Reactor + Centrifuge Reactor Mod Loader Module + Copyright 2020 © Centrifuge Project + 1.0.0 + 3.1.0 + 3.1.0 + 8.0 + ..\__BUILD\$(Configuration) + true + - - full - false - - - - pdbonly - - - - - - - - - - - + + true + + + + full + false + + + + pdbonly + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Reactor/Resources.cs b/Reactor/Resources.cs index afce299..c2b4023 100644 --- a/Reactor/Resources.cs +++ b/Reactor/Resources.cs @@ -3,5 +3,6 @@ internal class Resources { internal const string InterceptUnityLogsSettingsKey = "InterceptUnityLogs"; + internal const string InterceptHarmonyXLogsSettingsKey = "InterceptHarmonyXLogs"; } } diff --git a/Reactor/UnityLog.cs b/Reactor/UnityLog.cs index eb8df5e..9290091 100644 --- a/Reactor/UnityLog.cs +++ b/Reactor/UnityLog.cs @@ -6,7 +6,7 @@ namespace Reactor { public class UnityLog { - private Log Log => LogManager.GetForInternalAssembly(); + private Log Log { get; } = LogManager.GetForInternalAssembly(); private bool Enabled { get; } = Manager.Settings.GetItem(Resources.InterceptUnityLogsSettingsKey); diff --git a/Spindle/Spindle.csproj b/Spindle/Spindle.csproj index dce4fcb..ff8fcd7 100644 --- a/Spindle/Spindle.csproj +++ b/Spindle/Spindle.csproj @@ -1,40 +1,48 @@  - - Exe - net35 - true - Spindle - Centrifuge Project - Spindle - Centrifuge Patcher for Unity Engine - Copyright 2019 © Centrifuge Project - 2.1.0 - 2.1.0 - bin\$(Configuration)\ - 2.2.0 - 8.0 - + + Exe + net35;netstandard20 + true + Spindle + Centrifuge Project + Spindle + Centrifuge Patcher for Unity Engine + Copyright 2019 © Centrifuge Project + 2.1.0 + 2.1.0 + ..\__BUILD\$(Configuration) + 2.2.0 + 8.0 + - - full - false - - - - pdbonly - - - - - - - - - PreserveNewest - - - - PreserveNewest - - + + true + + + + full + false + + + + pdbonly + + + + + + + + + + + + + PreserveNewest + + + + PreserveNewest + + \ No newline at end of file diff --git a/prep_release.sh b/prep_release.sh new file mode 100644 index 0000000..dd33112 --- /dev/null +++ b/prep_release.sh @@ -0,0 +1,41 @@ +#!/bin/bash +net35_bin="./__BUILD/Release/net35" +net35_art="./__BUILD/artifact/net35" + +std20_bin="./__BUILD/Release/netstandard20" +std20_art="./__BUILD/artifact/netstandard20" + +rm -rf $net35_art 2> /dev/null +rm -rf $std20_art 2> /dev/null + +mkdir -p $net35_art/Centrifuge +mkdir -p $net35_art/Managed +mkdir -p $std20_art/Centrifuge +mkdir -p $std20_art/Managed + +cp $net35_bin/Reactor.dll $net35_art/Centrifuge/ +cp $net35_bin/Reactor.API.dll $net35_art/Centrifuge/ +cp $net35_bin/Centrifuge.dll $net35_art/Managed/ +cp $net35_bin/Centrifuge.UnityInterop.dll $net35_art/Managed/ +cp $net35_bin/0Harmony.dll $net35_art/Managed/ +cp $net35_bin/Newtonsoft.Json.dll $net35_art/Managed/ +cp $net35_bin/Mono.Cecil.dll $net35_art/Managed/ +cp $net35_bin/MonoMod.RuntimeDetour.dll $net35_art/Managed/ +cp $net35_bin/MonoMod.Utils.dll $net35_art/Managed/ +cp $net35_bin/Spindle.exe $net35_art/Managed/ +cp $net35_bin/install_windows.bat $net35_art/Managed/ +cp $net35_bin/install_linux.sh $net35_art/Managed/ + +cp $std20_bin/Reactor.dll $std20_art/Centrifuge/ +cp $std20_bin/Reactor.API.dll $std20_art/Centrifuge/ +cp $std20_bin/Centrifuge.dll $std20_art/Managed/ +cp $std20_bin/Centrifuge.UnityInterop.dll $std20_art/Managed/ +cp $std20_bin/0Harmony.dll $std20_art/Managed/ +cp $std20_bin/Newtonsoft.Json.dll $std20_art/Managed/ +cp $std20_bin/Mono.Cecil.dll $std20_art/Managed/ +cp $std20_bin/MonoMod.RuntimeDetour.dll $std20_art/Managed/ +cp $std20_bin/MonoMod.Utils.dll $std20_art/Managed/ +cp $std20_bin/Spindle.dll $std20_art/Managed/Spindle.exe +cp $std20_bin/install_windows.bat $std20_art/Managed/ +cp $std20_bin/install_linux.sh $std20_art/Managed/ +cp $std20_bin/System.* $std20_art/Managed/ \ No newline at end of file