Create minimal API endpoints from explored/understood code
This commit is contained in:
parent
0f5555ab4c
commit
05e196b4c1
7 changed files with 414 additions and 3 deletions
88
CLre/API/App/Client.cs
Normal file
88
CLre/API/App/Client.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace CLre.API.App
|
||||
{
|
||||
public static class Client
|
||||
{
|
||||
public static event EventHandler<SetupEventArgs> InitStart
|
||||
{
|
||||
add => FrontEnd_SetupContainer_Patch.preSetup += value;
|
||||
remove => FrontEnd_SetupContainer_Patch.preSetup -= value;
|
||||
}
|
||||
|
||||
public static event EventHandler<SetupEventArgs> LogInitComplete
|
||||
{
|
||||
add => FrontEnd_SetupContainer_Patch.postSyncSetup += value;
|
||||
remove => FrontEnd_SetupContainer_Patch.postSyncSetup -= value;
|
||||
}
|
||||
|
||||
public static event EventHandler<SetupEventArgs> AsynchronousInitComplete
|
||||
{
|
||||
add => FrontEndGuiEngine_SetMainMenuEnabled_Patch.preMenuEnabled += value;
|
||||
remove => FrontEndGuiEngine_SetMainMenuEnabled_Patch.preMenuEnabled -= value;
|
||||
}
|
||||
|
||||
public static event EventHandler<SetupEventArgs> InitComplete
|
||||
{
|
||||
add => FrontEndGuiEngine_SetMainMenuEnabled_Patch.postMenuEnabled += value;
|
||||
remove => FrontEndGuiEngine_SetMainMenuEnabled_Patch.postMenuEnabled -= value;
|
||||
}
|
||||
|
||||
public static string Version
|
||||
{
|
||||
get => Game.Utilities.VersionReader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public struct SetupEventArgs {}
|
||||
|
||||
[HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "SetupContainer")]
|
||||
class FrontEnd_SetupContainer_Patch
|
||||
{
|
||||
internal static event EventHandler<SetupEventArgs> postSyncSetup;
|
||||
|
||||
internal static event EventHandler<SetupEventArgs> preSetup;
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static void BeforeMethodCall(FrontEnd.MainFrontEnd __instance)
|
||||
{
|
||||
if (preSetup != null) preSetup(__instance, new SetupEventArgs { });
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
public static void AfterMethodCall(FrontEnd.MainFrontEnd __instance)
|
||||
{
|
||||
if (postSyncSetup != null) postSyncSetup(__instance, new SetupEventArgs { });
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch]
|
||||
class FrontEndGuiEngine_SetMainMenuEnabled_Patch
|
||||
{
|
||||
internal static event EventHandler<SetupEventArgs> preMenuEnabled;
|
||||
|
||||
internal static event EventHandler<SetupEventArgs> postMenuEnabled;
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static void BeforeMethodCall(object __instance, bool enabled)
|
||||
{
|
||||
if (!enabled) return;
|
||||
if (preMenuEnabled != null) preMenuEnabled(__instance, new SetupEventArgs { });
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
public static void AfterMethodCall(object __instance, bool enabled)
|
||||
{
|
||||
if (!enabled) return;
|
||||
if (postMenuEnabled != null) postMenuEnabled(__instance, new SetupEventArgs { });
|
||||
}
|
||||
|
||||
[HarmonyTargetMethod]
|
||||
public static MethodBase ReflectToGetMethodBase()
|
||||
{
|
||||
return AccessTools.Method("FrontEnd.FrontEndGuiEngine:SetMainMenuEnabled");
|
||||
}
|
||||
}
|
||||
}
|
144
CLre/API/Engines/FrontEndEngines.cs
Normal file
144
CLre/API/Engines/FrontEndEngines.cs
Normal file
|
@ -0,0 +1,144 @@
|
|||
using HarmonyLib;
|
||||
using Svelto.DataStructures;
|
||||
using Svelto.ECS;
|
||||
|
||||
namespace CLre.API.Engines
|
||||
{
|
||||
/// <summary>
|
||||
/// Engine to be registered before vanilla engines are built.
|
||||
/// This should be called by any other constructor because this alerts CLre of its existence.
|
||||
/// </summary>
|
||||
public abstract class FrontEndEnginePreBuild : ICLreEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Construct a new instance of a FrontEndEngine.
|
||||
/// This should be called by any other constructor because this alerts CLre of its existence.
|
||||
/// </summary>
|
||||
public FrontEndEnginePreBuild()
|
||||
{
|
||||
MainFrontEnd_BuildEngines_Patch.beforeBuildEngines.Add(this);
|
||||
}
|
||||
|
||||
public abstract void Ready();
|
||||
public abstract IEntitiesDB entitiesDB { get; set; }
|
||||
public abstract IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Engine to be registered before obsolete vanilla engines are built.
|
||||
/// This should be called by any other constructor because this alerts CLre of its existence.
|
||||
/// </summary>
|
||||
public abstract class FrontEndObsoleteEnginePreBuild : ICLreEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Construct a new instance of a FrontEndEngine.
|
||||
/// This should be called by any other constructor because this alerts CLre of its existence.
|
||||
/// </summary>
|
||||
public FrontEndObsoleteEnginePreBuild()
|
||||
{
|
||||
MainFrontEnd_BuildObsoleteEngines_Patch.beforeBuildEngines.Add(this);
|
||||
}
|
||||
|
||||
public abstract void Ready();
|
||||
public abstract IEntitiesDB entitiesDB { get; set; }
|
||||
public abstract IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Engine to be registered after vanilla engines are built.
|
||||
/// </summary>
|
||||
public abstract class FrontEndEnginePostBuild : ICLreEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Construct a new instance of a FrontEndEngine.
|
||||
/// This should be called by any other constructor because this alerts CLre of its existence.
|
||||
/// </summary>
|
||||
public FrontEndEnginePostBuild()
|
||||
{
|
||||
MainFrontEnd_BuildEngines_Patch.afterBuildEngines.Add(this);
|
||||
}
|
||||
|
||||
public abstract void Ready();
|
||||
public abstract IEntitiesDB entitiesDB { get; set; }
|
||||
public abstract IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Engine to be registered after vanilla obsolete engines are built.
|
||||
/// </summary>
|
||||
public abstract class FrontEndObsoleteEnginePostBuild : ICLreEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Construct a new instance of a FrontEndEngine.
|
||||
/// This should be called by any other constructor because this alerts CLre of its existence.
|
||||
/// </summary>
|
||||
public FrontEndObsoleteEnginePostBuild()
|
||||
{
|
||||
MainFrontEnd_BuildObsoleteEngines_Patch.afterBuildEngines.Add(this);
|
||||
}
|
||||
|
||||
public abstract void Ready();
|
||||
public abstract IEntitiesDB entitiesDB { get; set; }
|
||||
public abstract IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "BuildEngines")]
|
||||
class MainFrontEnd_BuildEngines_Patch
|
||||
{
|
||||
internal static FasterList<FrontEndEnginePreBuild> beforeBuildEngines = new FasterList<FrontEndEnginePreBuild>();
|
||||
|
||||
internal static FasterList<FrontEndEnginePostBuild> afterBuildEngines = new FasterList<FrontEndEnginePostBuild>();
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static void BeforeMethodCall(FrontEnd.MainFrontEnd __instance)
|
||||
{
|
||||
IEntityFactory factory = AccessTools.Field(typeof(FrontEnd.MainFrontEnd), "_entityFactory").GetValue(__instance) as IEntityFactory;
|
||||
foreach (ICLreEngine e in beforeBuildEngines)
|
||||
{
|
||||
e.entityFactory = factory;
|
||||
__instance.AddEngine(e);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
public static void AfterMethodCall(FrontEnd.MainFrontEnd __instance)
|
||||
{
|
||||
IEntityFactory factory = AccessTools.Field(typeof(FrontEnd.MainFrontEnd), "_entityFactory").GetValue(__instance) as IEntityFactory;
|
||||
foreach (ICLreEngine e in afterBuildEngines)
|
||||
{
|
||||
e.entityFactory = factory;
|
||||
__instance.AddEngine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "BuildObsoleteEngines")]
|
||||
class MainFrontEnd_BuildObsoleteEngines_Patch
|
||||
{
|
||||
internal static FasterList<FrontEndObsoleteEnginePreBuild> beforeBuildEngines = new FasterList<FrontEndObsoleteEnginePreBuild>();
|
||||
|
||||
internal static FasterList<FrontEndObsoleteEnginePostBuild> afterBuildEngines = new FasterList<FrontEndObsoleteEnginePostBuild>();
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static void BeforeMethodCall(FrontEnd.MainFrontEnd __instance)
|
||||
{
|
||||
IEntityFactory factory = AccessTools.Field(typeof(FrontEnd.MainFrontEnd), "_entityFactory").GetValue(__instance) as IEntityFactory;
|
||||
foreach (ICLreEngine e in beforeBuildEngines)
|
||||
{
|
||||
e.entityFactory = factory;
|
||||
__instance.AddEngine(e);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
public static void AfterMethodCall(FrontEnd.MainFrontEnd __instance)
|
||||
{
|
||||
IEntityFactory factory = AccessTools.Field(typeof(FrontEnd.MainFrontEnd), "_entityFactory").GetValue(__instance) as IEntityFactory;
|
||||
foreach (ICLreEngine e in afterBuildEngines)
|
||||
{
|
||||
e.entityFactory = factory;
|
||||
__instance.AddEngine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
CLre/API/Engines/GameEngines.cs
Normal file
60
CLre/API/Engines/GameEngines.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
using HarmonyLib;
|
||||
using Svelto.DataStructures;
|
||||
using Svelto.ECS;
|
||||
|
||||
namespace CLre.API.Engines
|
||||
{
|
||||
public abstract class GameObsoleteEnginePreBuild : ICLreEngine
|
||||
{
|
||||
public GameObsoleteEnginePreBuild()
|
||||
{
|
||||
MainLevel_BuildDeprecatedEngines_Patch.beforeBuildEngines.Add(this);
|
||||
}
|
||||
|
||||
public abstract void Ready();
|
||||
public abstract IEntitiesDB entitiesDB { get; set; }
|
||||
public abstract IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
|
||||
public abstract class GameObsoleteEnginePostBuild : ICLreEngine
|
||||
{
|
||||
public GameObsoleteEnginePostBuild()
|
||||
{
|
||||
MainLevel_BuildDeprecatedEngines_Patch.afterBuildEngines.Add(this);
|
||||
}
|
||||
|
||||
public abstract void Ready();
|
||||
public abstract IEntitiesDB entitiesDB { get; set; }
|
||||
public abstract IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(GameFramework.MainLevel), "BuildDeprecatedEngines")]
|
||||
class MainLevel_BuildDeprecatedEngines_Patch
|
||||
{
|
||||
internal static FasterList<GameObsoleteEnginePreBuild> beforeBuildEngines = new FasterList<GameObsoleteEnginePreBuild>();
|
||||
|
||||
internal static FasterList<GameObsoleteEnginePostBuild> afterBuildEngines = new FasterList<GameObsoleteEnginePostBuild>();
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static void BeforeMethodCall(GameFramework.MainLevel __instance)
|
||||
{
|
||||
IEntityFactory factory = AccessTools.Field(typeof(GameFramework.MainLevel), "_entityFactory").GetValue(__instance) as IEntityFactory;
|
||||
foreach (ICLreEngine e in beforeBuildEngines)
|
||||
{
|
||||
e.entityFactory = factory;
|
||||
__instance.AddEngine(e);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
public static void AfterMethodCall(GameFramework.MainLevel __instance)
|
||||
{
|
||||
IEntityFactory factory = AccessTools.Field(typeof(GameFramework.MainLevel), "_entityFactory").GetValue(__instance) as IEntityFactory;
|
||||
foreach (ICLreEngine e in afterBuildEngines)
|
||||
{
|
||||
e.entityFactory = factory;
|
||||
__instance.AddEngine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
CLre/API/Engines/ICLreEngine.cs
Normal file
9
CLre/API/Engines/ICLreEngine.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using Svelto.ECS;
|
||||
|
||||
namespace CLre.API.Engines
|
||||
{
|
||||
public interface ICLreEngine : IQueryingEntitiesEngine
|
||||
{
|
||||
IEntityFactory entityFactory { get; set; }
|
||||
}
|
||||
}
|
100
CLre/API/Utility/Logging.cs
Normal file
100
CLre/API/Utility/Logging.cs
Normal file
|
@ -0,0 +1,100 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CLre.API.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class to access Cardlife's built-in logging capabilities.
|
||||
/// The log is saved to outputLog#.Log
|
||||
/// </summary>
|
||||
public static class Logging
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Log(string msg)
|
||||
{
|
||||
Svelto.Console.Log(msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a regular message to Cardlife's log
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to log</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Log(object obj)
|
||||
{
|
||||
Svelto.Console.Log(obj.ToString());
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LogError(string msg, Dictionary<string, string> extraData = null)
|
||||
{
|
||||
Svelto.Console.LogError(msg, extraData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write an error message to Cardlife's log
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to log</param>
|
||||
/// <param name="extraData">The extra data to pass to the ILogger</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LogError(object obj, Dictionary<string, string> extraData = null)
|
||||
{
|
||||
Svelto.Console.LogError(obj.ToString(), extraData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write an exception to Cardlife's log and to the screen and exit game
|
||||
/// </summary>
|
||||
/// <param name="e">The exception to log</param>
|
||||
/// <param name="extraData">The extra data to pass to the ILogger.
|
||||
/// This is automatically populated with "OuterException#" and "OuterStacktrace#" entries</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LogException(Exception e, string msg = null, Dictionary<string, string> extraData = null)
|
||||
{
|
||||
Svelto.Console.LogException(msg, e, extraData);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LogWarning(string msg)
|
||||
{
|
||||
Svelto.Console.LogWarning(msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a warning message to Cardlife's log
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to log</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LogWarning(object obj)
|
||||
{
|
||||
Svelto.Console.LogWarning(obj.ToString());
|
||||
}
|
||||
|
||||
// descriptive logging
|
||||
|
||||
/// <summary>
|
||||
/// Write a descriptive message to Cardlife's log only when the API is a Debug build
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to log</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void MetaDebugLog(object obj)
|
||||
{
|
||||
#if DEBUG
|
||||
MetaLog($"[MetaDebug]{obj.ToString()}");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a descriptive message to Cardlife's log including the calling method's name
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to log</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void MetaLog(object obj)
|
||||
{
|
||||
var method = (new StackTrace()).GetFrame(1).GetMethod();
|
||||
Log($"[{method.DeclaringType.FullName}.{method.Name}] {obj.ToString()}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,9 +3,12 @@ using System.Reflection;
|
|||
|
||||
using IllusionPlugin;
|
||||
|
||||
namespace HelloModdingWorld
|
||||
using CLre.API.Utility;
|
||||
using Logging = CLre.API.Utility.Logging;
|
||||
|
||||
namespace CLre
|
||||
{
|
||||
public class MyPlugin : IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin'
|
||||
public class CLre : IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin'
|
||||
{
|
||||
public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;
|
||||
|
||||
|
@ -19,7 +22,7 @@ namespace HelloModdingWorld
|
|||
// called when Cardlife starts up
|
||||
public override void OnApplicationStart()
|
||||
{
|
||||
File.WriteAllText(Name + ".log", "CLre was loaded and started up");
|
||||
Logging.MetaLog($"{Name} has been loaded.");
|
||||
}
|
||||
}
|
||||
}
|
7
CLre/Fixes/EnchantmentTableFloatParseFix.cs
Normal file
7
CLre/Fixes/EnchantmentTableFloatParseFix.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace CLre.Fixes
|
||||
{
|
||||
public class EnchantmentTableFloatParseFix
|
||||
{
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue