From 91f3de17a0a5defb28a05187a6542468588924de Mon Sep 17 00:00:00 2001 From: Paul Hebble Date: Wed, 17 Mar 2021 17:57:20 -0500 Subject: [PATCH] Netkan errors and warnings for Harmony bundlers --- Netkan/CKAN-netkan.csproj | 1 + Netkan/Validators/CkanValidator.cs | 1 + Netkan/Validators/HarmonyValidator.cs | 60 +++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 Netkan/Validators/HarmonyValidator.cs diff --git a/Netkan/CKAN-netkan.csproj b/Netkan/CKAN-netkan.csproj index adfee6dbdf..4b5880d5d5 100644 --- a/Netkan/CKAN-netkan.csproj +++ b/Netkan/CKAN-netkan.csproj @@ -127,6 +127,7 @@ + diff --git a/Netkan/Validators/CkanValidator.cs b/Netkan/Validators/CkanValidator.cs index 6b63f4e97e..fd9d106396 100644 --- a/Netkan/Validators/CkanValidator.cs +++ b/Netkan/Validators/CkanValidator.cs @@ -20,6 +20,7 @@ public CkanValidator(IHttpService downloader, IModuleService moduleService) new MatchesKnownGameVersionsValidator(), new ObeysCKANSchemaValidator(), new KindValidator(), + new HarmonyValidator(downloader, moduleService), new ModuleManagerDependsValidator(downloader, moduleService), new PluginCompatibilityValidator(downloader, moduleService), new CraftsInShipsValidator(downloader, moduleService), diff --git a/Netkan/Validators/HarmonyValidator.cs b/Netkan/Validators/HarmonyValidator.cs new file mode 100644 index 0000000000..4e009c9aea --- /dev/null +++ b/Netkan/Validators/HarmonyValidator.cs @@ -0,0 +1,60 @@ +using System; +using System.Linq; + +using Newtonsoft.Json.Linq; +using ICSharpCode.SharpZipLib.Zip; +using log4net; + +using CKAN.Games; +using CKAN.NetKAN.Model; +using CKAN.NetKAN.Services; + +namespace CKAN.NetKAN.Validators +{ + internal sealed class HarmonyValidator : IValidator + { + public HarmonyValidator(IHttpService http, IModuleService moduleService) + { + _http = http; + _moduleService = moduleService; + } + + public void Validate(Metadata metadata) + { + JObject json = metadata.Json(); + CkanModule mod = CkanModule.FromJson(json.ToString()); + // The Harmony2 module is allowed to install a Harmony DLL; + // anybody else must have "provides":["Harmony1"] to do so + if (!mod.IsDLC && mod.identifier != "Harmony2") + { + // Need to peek at the mod's files + var package = _http.DownloadModule(metadata); + if (!string.IsNullOrEmpty(package)) + { + ZipFile zip = new ZipFile(package); + GameInstance inst = new GameInstance(new KerbalSpaceProgram(), "/", "dummy", new NullUser()); + + var harmonyDLLs = _moduleService.GetPlugins(mod, zip, inst) + .Select(instF => instF.source.Name) + .Where(f => f.IndexOf("Harmony", StringComparison.InvariantCultureIgnoreCase) != -1) + .ToList(); + bool bundlesHarmony = harmonyDLLs.Any(); + bool providesHarmony1 = mod.ProvidesList.Contains("Harmony1"); + if (bundlesHarmony && !providesHarmony1) + { + throw new Kraken($"Harmony DLL found at {string.Join(", ", harmonyDLLs)}, but Harmony1 is not in the provides list"); + } + else if (providesHarmony1 && !bundlesHarmony) + { + Log.Warn("Harmony1 provided by module that doesn't install a Harmony DLL, consider removing from provides list"); + } + } + } + } + + private readonly IHttpService _http; + private readonly IModuleService _moduleService; + + private static readonly ILog Log = LogManager.GetLogger(typeof(HarmonyValidator)); + } +}