From b4f0d43b463c754b8388ee1de256ae236f6555d2 Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Thu, 5 Sep 2024 15:03:53 +0200 Subject: [PATCH] add GitHub as source & allow inheritance --- ModpackUpdater.Manager/ModpackInstaller.cs | 50 +++++++++++++++---- .../ModpackUpdater.Manager.csproj | 1 + ModpackUpdater.Model/InstallAction.cs | 31 +++++++++++- ModpackUpdater.Model/SourceType.cs | 7 +++ 4 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 ModpackUpdater.Model/SourceType.cs diff --git a/ModpackUpdater.Manager/ModpackInstaller.cs b/ModpackUpdater.Manager/ModpackInstaller.cs index 3da59dd..458b9dd 100644 --- a/ModpackUpdater.Manager/ModpackInstaller.cs +++ b/ModpackUpdater.Manager/ModpackInstaller.cs @@ -1,5 +1,9 @@ using ModpackUpdater.Model; +using Newtonsoft.Json; +using Octokit; using System.IO.Compression; +using System.Text.RegularExpressions; +using FileMode = System.IO.FileMode; namespace ModpackUpdater.Manager; @@ -18,22 +22,23 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf public delegate void CheckingProgressUpdatedEventHandler(int toCheck, int processed); - private readonly HttpClient httpClient = new(); + private readonly HttpClient http = new(); + private readonly GitHubClient github = new(new ProductHeaderValue("MinecraftModpackUpdater")); ~ModpackInstaller() { - httpClient.Dispose(); + http.Dispose(); } private async Task DownloadUpdateInfos() { - var content = await httpClient.GetStringAsync(updateConfig.UpdateUrl); + var content = await http.GetStringAsync(updateConfig.UpdateUrl); return UpdateInfos.Parse(content); } private async Task DownloadInstallInfos() { - var content = await httpClient.GetStringAsync(updateConfig.InstallUrl); + var content = await http.GetStringAsync(updateConfig.InstallUrl); return InstallInfos.Parse(content); } @@ -56,10 +61,11 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf return result; } + installInfos = await DownloadInstallInfos(); + + // Check install actions if (!exists) { - installInfos = await DownloadInstallInfos(); - if (installInfos is not null && installInfos.Actions.Count != 0) { var actions = installInfos.Actions.Where(n => n.Side.IsSide(options.Side) && (!n.IsExtra || options.IncludeExtras)); @@ -75,6 +81,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf result.HasError = true; } + // Check update actions if (exists || options.AllowUpdaterAfterInstall) { updateInfos = await DownloadUpdateInfos(); @@ -97,6 +104,11 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf foreach (var action in checkingVersion.Actions) { + // Resolve inherits + if (!string.IsNullOrWhiteSpace(action.InheritFrom) && installInfos.Actions.FirstOrDefault(a => a.Name == action.InheritFrom) is InstallAction iaction) + JsonConvert.PopulateObject(JsonConvert.SerializeObject(iaction), action); + + // Check & add if (action.Side.IsSide(options.Side) && (!action.IsExtra || options.IncludeExtras) && !result.Actions.Any(n => n.DestPath == action.DestPath)) actionsToAdd.Add(action); } @@ -116,19 +128,20 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf public async Task Install(UpdateCheckResult checkResult) { - int processed = 0; + var processed = 0; var localZipCache = new List(); foreach (InstallAction iaction in checkResult.Actions) { - string destFilePath = Path.Combine(modpackInfo.LocaLPath, iaction.DestPath); + var destFilePath = Path.Combine(modpackInfo.LocaLPath, iaction.DestPath); + var sourceUrl = await ResolveSourceUrl(iaction); if (iaction is UpdateAction uaction) { switch (uaction.Type) { case UpdateActionType.Update: - await InstallFile(destFilePath, uaction.DownloadUrl, uaction.IsZip, uaction.ZipPath, localZipCache); + await InstallFile(destFilePath, sourceUrl, uaction.IsZip, uaction.ZipPath, localZipCache); break; case UpdateActionType.Delete: { @@ -174,7 +187,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf } } else - await InstallFile(destFilePath, iaction.DownloadUrl, iaction.IsZip, iaction.ZipPath, localZipCache); + await InstallFile(destFilePath, sourceUrl, iaction.IsZip, iaction.ZipPath, localZipCache); processed += 1; InstallProgessUpdated?.Invoke(checkResult, processed); @@ -200,7 +213,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf { // Download var fsDestinationPath = isZip ? Path.Combine(Path.GetTempPath(), $"mc_update_file_{DateTime.Now.ToBinary()}.zip") : destFilePath; - var sRemote = await httpClient.GetStreamAsync(sourceUrl); + var sRemote = await http.GetStreamAsync(sourceUrl); var fs = new FileStream(fsDestinationPath, FileMode.Create, FileAccess.ReadWrite); await sRemote.CopyToAsync(fs); await fs.FlushAsync(); @@ -237,4 +250,19 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf Extensions.CopyDirectory(zipSrc, destFilePath, true); } } + + private async Task ResolveSourceUrl(InstallAction action) + { + if (action.SourceType == SourceType.GitHub) + { + var repo = await github.Repository.Get(action.SourceOwner, action.SourceName); + var release = await github.Repository.Release.Get(repo.Id, action.SourceTag); + var assets = await github.Repository.Release.GetAllAssets(repo.Id, release.Id); + + if (assets.FirstOrDefault(asset => Regex.IsMatch(asset.Name, action.SourceRegex)) is ReleaseAsset asset) + return asset.BrowserDownloadUrl; + } + + return action.SourceUrl; + } } \ No newline at end of file diff --git a/ModpackUpdater.Manager/ModpackUpdater.Manager.csproj b/ModpackUpdater.Manager/ModpackUpdater.Manager.csproj index 8c1955f..cd0e02a 100644 --- a/ModpackUpdater.Manager/ModpackUpdater.Manager.csproj +++ b/ModpackUpdater.Manager/ModpackUpdater.Manager.csproj @@ -6,6 +6,7 @@ + diff --git a/ModpackUpdater.Model/InstallAction.cs b/ModpackUpdater.Model/InstallAction.cs index 4343378..ce06a6d 100644 --- a/ModpackUpdater.Model/InstallAction.cs +++ b/ModpackUpdater.Model/InstallAction.cs @@ -1,11 +1,38 @@ -namespace ModpackUpdater.Model; +using Newtonsoft.Json; + +namespace ModpackUpdater.Model; public class InstallAction { + public string Name { get; set; } + + public string InheritFrom { get; set; } + public bool IsZip { get; set; } + public string ZipPath { get; set; } + public string DestPath { get; set; } - public string DownloadUrl { get; set; } + + public string SourceUrl { get; set; } + + public SourceType SourceType { get; set; } + + public string SourceOwner { get; set; } + + public string SourceName { get; set; } + + public string SourceRegex { get; set; } + + public string SourceTag { get; set; } + public Side Side { get; set; } = Side.Both; + public bool IsExtra { get; set; } + + [JsonProperty, Obsolete] + private string DownloadUrl + { + set => SourceUrl = value; + } } \ No newline at end of file diff --git a/ModpackUpdater.Model/SourceType.cs b/ModpackUpdater.Model/SourceType.cs new file mode 100644 index 0000000..37d8398 --- /dev/null +++ b/ModpackUpdater.Model/SourceType.cs @@ -0,0 +1,7 @@ +namespace ModpackUpdater.Model; + +public enum SourceType +{ + DirectLink, + GitHub, +}