diff --git a/CLre/CLre.cs b/CLre/CLre.cs
index ca7866d..9b54a49 100644
--- a/CLre/CLre.cs
+++ b/CLre/CLre.cs
@@ -1,28 +1,77 @@
-using System.IO;
+using System;
+using System.Diagnostics;
+using System.Linq;
using System.Reflection;
-
-using IllusionPlugin;
-
-using CLre.API.Utility;
-using Logging = CLre.API.Utility.Logging;
+using System.Text;
+using HarmonyLib;
+using Svelto.ECS;
+using UnityEngine;
namespace CLre
{
- public class CLre : IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin'
+ public class CLre : IllusionPlugin.IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin'
{
public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;
public override string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ private Harmony harmonyInstance = null;
// called when Cardlife shuts down
public override void OnApplicationQuit()
{
+ harmonyInstance.UnpatchAll();
}
// called when Cardlife starts up
public override void OnApplicationStart()
{
- Logging.MetaLog($"{Name} has been loaded.");
+#if DEBUG
+ FileLog.Reset();
+ Harmony.DEBUG = true;
+ Stopwatch startup = Stopwatch.StartNew();
+#endif
+ // init all Harmony patches in project
+ harmonyInstance = new Harmony(Name);
+ harmonyInstance.PatchAll();
+
+ // patches for bugs
+ Fixes.InitLogSooner.Init();
+
+ // misc
+ LogIPAPlugins();
+
+ // Log info
+ API.Utility.Logging.MetaLog($"{Name} init complete.");
+
+#if DEBUG
+ API.App.Client.InitComplete += (_, __) =>
+ {
+ startup.Stop();
+ API.Utility.Logging.MetaLog($"Startup took {startup.ElapsedMilliseconds}ms");
+ API.Utility.Logging.Log(
+ $"EAC has detected code mods? {EasyAntiCheat.Client.Hydra.Runtime.Integrity.Violated}" +
+ (EasyAntiCheat.Client.Hydra.Runtime.Integrity.Violated
+ ? EasyAntiCheat.Client.Hydra.Runtime.Integrity.ViolationMessage
+ : ""));
+ };
+#endif
+ }
+
+ private static void LogIPAPlugins()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("Running on Unity {0}\n", Application.unityVersion);
+ sb.AppendFormat("Running on CardLife {0} (aka {1})\n", API.App.Client.Version, Application.version);
+ sb.AppendFormat("-----------------------------\n");
+ sb.AppendFormat("Loading plugins from {0} and found {1}\n", System.IO.Path.Combine(Environment.CurrentDirectory, "Plugins"), IllusionInjector.PluginManager.Plugins.Count());
+ sb.AppendFormat("-----------------------------\n");
+ foreach (IllusionPlugin.IPlugin plugin in IllusionInjector.PluginManager.Plugins)
+ {
+
+ sb.AppendFormat(" {0}: {1}\n", plugin.Name, plugin.Version);
+ }
+ sb.AppendFormat("-----------------------------\n");
+ API.Utility.Logging.Log(sb.ToString());
}
}
}
diff --git a/CLre/CLre.csproj b/CLre/CLre.csproj
index 81c676d..c0c3eee 100644
--- a/CLre/CLre.csproj
+++ b/CLre/CLre.csproj
@@ -4,7 +4,7 @@
net472
true
0.0.1
- Me
+ NGnius
MIT
https://git.exmods.org/NGnius/CLre
en-CA
diff --git a/CLre/Fixes/EnchantmentTableFloatParseFix.cs b/CLre/Fixes/EnchantmentTableFloatParseFix.cs
index f9a3315..857015e 100644
--- a/CLre/Fixes/EnchantmentTableFloatParseFix.cs
+++ b/CLre/Fixes/EnchantmentTableFloatParseFix.cs
@@ -1,7 +1,32 @@
+using System;
+using System.Globalization;
+using System.Reflection;
+using HarmonyLib;
+
namespace CLre.Fixes
{
public class EnchantmentTableFloatParseFix
{
}
+
+ [HarmonyPatch]
+ class Float_TryParse_Patch
+ {
+ [HarmonyPostfix]
+ public static void BeforeMethodCall(string s, ref float result, ref bool __result)
+ {
+ if (__result) return;
+ __result = float.TryParse(s,
+ NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign |
+ NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent,
+ NumberFormatInfo.InvariantInfo, out result);
+ }
+
+ [HarmonyTargetMethod]
+ public static MethodBase Target()
+ {
+ return AccessTools.Method(typeof(float), "TryParse", new []{typeof(string), typeof(float).MakeByRefType()});
+ }
+ }
}
\ No newline at end of file
diff --git a/CLre/Fixes/InitLogSooner.cs b/CLre/Fixes/InitLogSooner.cs
new file mode 100644
index 0000000..6db1cb6
--- /dev/null
+++ b/CLre/Fixes/InitLogSooner.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using HarmonyLib;
+
+namespace CLre.Fixes
+{
+ public static class InitLogSooner
+ {
+ public static int millisecondsTimeout = 5000;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Init()
+ {
+ try
+ {
+ CustomLoggerThread_CreateGameObject_Patch.allowed = true;
+ CustomLoggerThread.CreateGameObject();
+ CustomLoggerThread_CreateGameObject_Patch.allowed = false;
+ API.Utility.Logging.Log($"Completed early log init");
+ //System.IO.File.WriteAllText("InitLogSooner.log", $"Done at " + System.DateTime.Now.ToString());
+ }
+ catch (Exception e)
+ {
+ API.App.Client.LogInitComplete += (_, __) =>
+ {
+ API.Utility.Logging.Log($"Failed to initialise log sooner, reason:\n" + e);
+ };
+ System.IO.File.WriteAllText("InitLogSooner.log", e.ToString());
+ }
+
+ }
+
+ [HarmonyPatch(typeof(CustomLoggerThread), "CreateGameObject")]
+ class CustomLoggerThread_CreateGameObject_Patch
+ {
+ internal static bool allowed = false;
+
+ public static bool Prefix()
+ {
+ return allowed;
+ }
+ }
+
+ [HarmonyPatch(typeof(CustomLoggerThread), "StartQueue")]
+ class CustomLoggerThread_StartQueue_Patch
+ {
+ internal static volatile bool IsLogStarted = false;
+
+ private delegate void Flusher();
+
+ public static bool Prefix()
+ {
+ // setup thru reflection
+ FieldInfo quitThreadField = AccessTools.Field(typeof(CustomLoggerThread), "_quitThread");
+
+ MethodInfo flushLoggerMethod = AccessTools.Method(typeof(CustomLoggerThread), "FlushLogger");
+ Flusher flushLogger = (Flusher) Delegate.CreateDelegate(typeof(Action), null, flushLoggerMethod);
+
+ MethodInfo forceFlushMethod = AccessTools.Method("CustomLogger:ForceFlush");
+ Flusher forceFlush = (Flusher) Delegate.CreateDelegate(typeof(Action), null, forceFlushMethod);
+
+ Thread.MemoryBarrier();
+ IsLogStarted = true;
+ while (!(bool) quitThreadField.GetValue(null))
+ {
+ flushLogger();
+ forceFlush();
+ Thread.Sleep(millisecondsTimeout);
+ }
+
+ IsLogStarted = false;
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CLre/Fixes/StartupSpeedup.cs b/CLre/Fixes/StartupSpeedup.cs
new file mode 100644
index 0000000..3fb94ca
--- /dev/null
+++ b/CLre/Fixes/StartupSpeedup.cs
@@ -0,0 +1,57 @@
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using HarmonyLib;
+
+namespace CLre.Fixes
+{
+ public class StartupSpeedup
+ {
+
+ }
+
+ [HarmonyPatch(typeof(FrontEnd.FrontEndContextRoot), "WaitForFrameworkInitialization")]
+ //[HarmonyPatch]
+ class Speedup_Benchmark3
+ {
+ internal static Stopwatch test = null;
+
+ public static void Prefix()
+ {
+ test = Stopwatch.StartNew();
+ }
+ }
+
+ [HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "RequestPlayerId")]
+ //[HarmonyPatch]
+ class Speedup_Benchmark
+ {
+ internal static Stopwatch test = null;
+
+ public static void Prefix()
+ {
+ test.Stop();
+ long elapsed = test.ElapsedMilliseconds;
+ API.Utility.Logging.Log($"OnContextInitialized completed in ~{elapsed}ms");
+ }
+ }
+
+ [HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "RegisterCustomHtmlElementTypes")]
+ class Speedup_Benchmark2
+ {
+
+ public static void Prefix()
+ {
+ if (Speedup_Benchmark3.test != null)
+ {
+ Speedup_Benchmark3.test.Stop();
+ long elapsed = Speedup_Benchmark3.test.ElapsedMilliseconds;
+ API.App.Client.LogInitComplete += (_, __) =>
+ {
+ API.Utility.Logging.Log($"Scene loaded in ~{elapsed}ms");
+ };
+ }
+ Speedup_Benchmark.test = Stopwatch.StartNew();
+ }
+ }
+}
\ No newline at end of file