TechbloxModdingAPI/TechbloxModdingAPI/Main.cs
NorbiPeti e8515ef42b
Fix events not firing and event exception handling
Copying to Plugins folder on build
Registering deterministic game engines automatically
Each event handler is wrapped so if one fails it will still trigger the rest
2021-05-23 20:53:55 +02:00

117 lines
4.3 KiB
C#

using System;
using System.Reflection;
using HarmonyLib;
using RobocraftX;
using RobocraftX.Schedulers;
using RobocraftX.Services;
using Svelto.Context;
using Svelto.Tasks.ExtraLean;
using TechbloxModdingAPI.App;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Events;
using TechbloxModdingAPI.Tasks;
using TechbloxModdingAPI.Utility;
namespace TechbloxModdingAPI
{
/// <summary>
/// The main class of the TechbloxModdingAPI.
/// Use this to initialize the API before calling it.
/// </summary>
public static class Main
{
private static Harmony harmony;
public static bool IsInitialized {
get { return harmony != null; }
}
private static int referenceCount = 0;
/// <summary>
/// Initializes the TechbloxModdingAPI.
/// Call this as soon as possible after Techblox starts up.
/// Ideally, this should be called from your main Plugin class's OnApplicationStart() method.
/// </summary>
public static void Init()
{
referenceCount++;
if (referenceCount > 1) { return; }
if (IsInitialized)
{
Logging.LogWarning("TechbloxModdingAPI.Main.Init() called but API is already initialized!");
return;
}
Logging.MetaDebugLog($"Patching Techblox");
var currentAssembly = Assembly.GetExecutingAssembly();
harmony = new Harmony(currentAssembly.GetName().Name);
try
{
harmony.PatchAll(currentAssembly);
}
catch (Exception e)
{ //Can't use ErrorBuilder or Logging.LogException (which eventually uses ErrorBuilder) yet
Logging.Log(e.ToString());
Logging.LogWarning("Failed to patch Techblox. Attempting to patch to display error...");
harmony.Patch(AccessTools.Method(typeof(FullGameCompositionRoot), "OnContextInitialized")
.MakeGenericMethod(typeof(UnityContext<FullGameCompositionRoot>)),
new HarmonyMethod(((Action) OnPatchError).Method)); //Can't use lambdas here :(
return;
}
// init utility
Logging.MetaDebugLog($"Initializing Utility");
Utility.GameState.Init();
// init block implementors
Logging.MetaDebugLog($"Initializing Blocks");
// init inventory
Inventory.Hotbar.Init();
// init input
Input.FakeInput.Init();
// init object-oriented classes
Player.Init();
FlyCam.Init();
Block.Init();
BlockGroup.Init();
Wire.Init();
Logging.MetaDebugLog($"Initializing Client");
GameClient.Init();
Client.Init();
Game.Init();
// init UI
Interface.IMGUI.Constants.Init();
Interface.IMGUI.IMGUIManager.Init();
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} initialized");
}
/// <summary>
/// Shuts down & cleans up the TechbloxModdingAPI.
/// Call this as late as possible before Techblox quits.
/// Ideally, this should be called from your main Plugin class's OnApplicationQuit() method.
/// </summary>
public static void Shutdown()
{
if (referenceCount > 0) { referenceCount--; }
if (referenceCount == 0)
{
if (!IsInitialized)
{
Logging.LogWarning("TechbloxModdingAPI.Main.Shutdown() called but API is not initialized!");
return;
}
Scheduler.Dispose();
var currentAssembly = Assembly.GetExecutingAssembly();
harmony.UnpatchAll(currentAssembly.GetName().Name);
harmony = null;
Logging.MetaLog($"{currentAssembly.GetName().Name} v{currentAssembly.GetName().Version} shutdown");
}
}
private static void OnPatchError()
{
ErrorBuilder.DisplayMustQuitError("Failed to patch Techblox!\n" +
"Make sure you're using the latest version of TechbloxModdingAPI or disable mods if the API isn't released yet.");
}
}
}