mirror of
https://github.com/Jacobwasbeast/LegacyWeaveLoader.git
synced 2026-05-21 21:24:30 +00:00
SKSE-style external mod loader with zero game source modifications. - LegacyForge.Launcher: C# console app that injects runtime DLL into game process - LegacyForgeRuntime: C++ DLL with PDB symbol resolution, MinHook function hooking, and .NET CoreCLR hosting - LegacyForge.Core: C# mod discovery and lifecycle management - LegacyForge.API: Fabric-style mod API with namespaced string IDs, fluent property builders, and event system - ExampleMod: Sample mod demonstrating block/item registration
76 lines
1.9 KiB
C#
76 lines
1.9 KiB
C#
using LegacyForge.API;
|
|
|
|
namespace LegacyForge.Core;
|
|
|
|
/// <summary>
|
|
/// Manages the lifecycle of all loaded mods.
|
|
/// Catches exceptions from individual mods to prevent one broken mod from crashing the game.
|
|
/// </summary>
|
|
internal class ModManager
|
|
{
|
|
private readonly List<ModDiscovery.DiscoveredMod> _mods = new();
|
|
|
|
internal int ModCount => _mods.Count;
|
|
|
|
internal void AddMods(IEnumerable<ModDiscovery.DiscoveredMod> mods)
|
|
{
|
|
_mods.AddRange(mods);
|
|
}
|
|
|
|
internal void PreInit()
|
|
{
|
|
Logger.Info("--- PreInit phase ---");
|
|
foreach (var mod in _mods)
|
|
SafeCall(mod, "OnPreInit", () => mod.Instance.OnPreInit());
|
|
}
|
|
|
|
internal void Init()
|
|
{
|
|
Logger.Info("--- Initialize phase ---");
|
|
foreach (var mod in _mods)
|
|
SafeCall(mod, "OnInitialize", () => mod.Instance.OnInitialize());
|
|
}
|
|
|
|
internal void PostInit()
|
|
{
|
|
Logger.Info("--- PostInitialize phase ---");
|
|
foreach (var mod in _mods)
|
|
SafeCall(mod, "OnPostInitialize", () => mod.Instance.OnPostInitialize());
|
|
}
|
|
|
|
internal void Tick()
|
|
{
|
|
foreach (var mod in _mods)
|
|
{
|
|
try
|
|
{
|
|
mod.Instance.OnTick();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error($"[{mod.Metadata.Id}] OnTick error: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void Shutdown()
|
|
{
|
|
Logger.Info("--- Shutdown phase ---");
|
|
foreach (var mod in _mods)
|
|
SafeCall(mod, "OnShutdown", () => mod.Instance.OnShutdown());
|
|
}
|
|
|
|
private static void SafeCall(ModDiscovery.DiscoveredMod mod, string phase, Action action)
|
|
{
|
|
try
|
|
{
|
|
action();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error($"[{mod.Metadata.Id}] {phase} failed: {ex.Message}");
|
|
Logger.Debug(ex.StackTrace ?? "");
|
|
}
|
|
}
|
|
}
|