Skip to content

Commit

Permalink
ModLoader: Validate dependencies using the new 0.3.0 shared dependenc…
Browse files Browse the repository at this point in the history
…y field
  • Loading branch information
MeFisto94 committed Sep 26, 2024
1 parent 084af69 commit 5d043bb
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 12 deletions.
30 changes: 19 additions & 11 deletions EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using NLog;
using NLog.Config;
using NLog.Targets;
using Semver;

namespace Andraste.Payload
{
Expand Down Expand Up @@ -52,8 +53,9 @@ public abstract class EntryPoint : IEntryPoint
private bool _ready;

protected readonly Dictionary<string, IFeatureParser> FeatureParser = new Dictionary<string, IFeatureParser>();
protected readonly Dictionary<string, SemVersion> BuiltInDependencies = new Dictionary<string, SemVersion>();
public readonly ManagerContainer Container;
private readonly ModLoader _modLoader;
protected readonly ModLoader ModLoader;

protected EntryPoint(RemoteHooking.IContext context, string profileFolder)
{
Expand All @@ -62,7 +64,7 @@ protected EntryPoint(RemoteHooking.IContext context, string profileFolder)
FrameworkFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
ProfileFolder = profileFolder;
Container = new ManagerContainer();
_modLoader = new ModLoader(this);
ModLoader = new ModLoader(this);
}

public virtual void Run(RemoteHooking.IContext context, string profileFolder)
Expand Down Expand Up @@ -90,7 +92,7 @@ public virtual void Run(RemoteHooking.IContext context, string profileFolder)

Logger.Trace("Internal Initialization done, calling Pre-Wakeup");
PreWakeup();
_modLoader.EmitGenericEvent(EGenericEvent.EPreWakeup);
ModLoader.EmitGenericEvent(EGenericEvent.EPreWakeup);

Logger.Trace("Loading the Managers");
Container.Load();
Expand All @@ -102,7 +104,7 @@ public virtual void Run(RemoteHooking.IContext context, string profileFolder)
RemoteHooking.WakeUpProcess();
Logger.Trace("Calling Post-Wakeup");
PostWakeup();
_modLoader.EmitGenericEvent(EGenericEvent.EPostWakeup);
ModLoader.EmitGenericEvent(EGenericEvent.EPostWakeup);

while (IsRunning)
{
Expand All @@ -121,7 +123,7 @@ public virtual void Run(RemoteHooking.IContext context, string profileFolder)
{
Logger.Error(ex, "Exception in ApplicationReady");
}
_modLoader.EmitGenericEvent(EGenericEvent.EApplicationReady);
ModLoader.EmitGenericEvent(EGenericEvent.EApplicationReady);
}

Thread.Sleep(100);
Expand All @@ -133,7 +135,7 @@ public virtual void Run(RemoteHooking.IContext context, string profileFolder)
protected virtual void Shutdown()
{
Logger.Info("Shutting down and exiting CLR");
_modLoader?.UnloadPlugins();
ModLoader?.UnloadPlugins();
Container.Unload();
UnregisterExceptionHandlers();
LogManager.Flush();
Expand All @@ -148,9 +150,9 @@ protected virtual void Shutdown()
/// </summary>
protected virtual void ImplementMods()
{
_modLoader.ImplementVfs();
_modLoader.ImplementPlugins();
_modLoader.LoadPlugins();
ModLoader.ImplementVfs();
ModLoader.ImplementPlugins();
ModLoader.LoadPlugins();
}

/// <summary>
Expand All @@ -161,13 +163,14 @@ protected virtual void ImplementMods()
protected virtual void LoadMods()
{
DiscoverMods();
ValidateDependencies();
LoadFeatureParsers();
ParseModFeatures();
}

protected virtual void ParseModFeatures()
{
foreach (var mods in _modLoader.EnabledMods)
foreach (var mods in ModLoader.EnabledMods)
{
Logger.Info($"Enabled Mod {mods.ModInformation.Slug}");
var conf = mods.ModInformation.Configurations[mods.ModSetting.ActiveConfiguration];
Expand All @@ -188,7 +191,12 @@ protected virtual void ParseModFeatures()

protected virtual void DiscoverMods()
{
_modLoader.EnabledMods = _modLoader.DiscoverMods(ProfileFolder);
ModLoader.EnabledMods = ModLoader.DiscoverMods(ProfileFolder);
}

protected virtual void ValidateDependencies()
{
ModLoader.ValidateDependencies(BuiltInDependencies);
}

protected virtual void LoadFeatureParsers()
Expand Down
40 changes: 39 additions & 1 deletion ModManagement/ModLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
using System.Text.Json;
using Andraste.Payload.VFS;
using Andraste.Shared.ModManagement;
using Andraste.Shared.ModManagement.DependencyResolution;
using Andraste.Shared.ModManagement.Json;
using Andraste.Shared.ModManagement.Json.Features;
using Andraste.Shared.ModManagement.Json.Features.Plugin;
using Andraste.Shared.ModManagement.Json.Features.Vfs;
using NLog;
using Semver;

namespace Andraste.Payload.ModManagement
{
Expand Down Expand Up @@ -201,5 +203,41 @@ public void EmitGenericEvent(EGenericEvent genericEvent)
}
}
}

public void ValidateDependencies(Dictionary<string, SemVersion> builtInDependencies)
{
var availableMods = EnabledMods.ToDictionary(mod => mod.ModInformation.Slug, mod => mod.ModInformation.SemanticVersion);
foreach (var dependency in builtInDependencies)
{
availableMods.Add(dependency.Key, dependency.Value);
}

var requirements = EnabledMods.SelectMany(mod =>
{
if (mod.ModInformation.Dependencies == null)
{
return Enumerable.Empty<IDependencyVersionRequirement>();
}

return mod.ModInformation.Dependencies.Select(dependency =>
DependencyResolver.ParseDependency(mod.ModInformation.Slug, dependency));
}).ToList();

// Some old (pre andraste 0.3.0) mods don't have a SemanticVersion
var results = DependencyResolver.ValidateRequirementsSimple(availableMods, requirements);
if (results.Count == 0)
{
return;
}

Logger.Warn("Found {} dependency constraint violation(s)", results.Count);
EnabledMods.RemoveAll(mod => results.Any(result => result.SourceSlug == mod.ModInformation.Slug));

foreach (var violation in results)
{
Logger.Warn("Disabled {}, because the dependency on {} couldn't be solved. Type: {}, Message: {}",
violation.SourceSlug, violation.TargetSlug, violation.ViolationType, violation.Message ?? "");
}
}
}
}

0 comments on commit 5d043bb

Please sign in to comment.