Files
LegacyWeaveLoader/LegacyForge.Core/ModManager.cs
Jacobwasbeast de22a24100 Initial commit: LegacyForge mod loader for Minecraft Legacy Edition
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
2026-03-06 15:11:53 -06:00

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 ?? "");
}
}
}