Files
CVRManager/Services/AvailableModsService.cs
T
Exterrata 9bb4f85802 CVR Manager 1.0.0
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 02:46:35 -04:00

70 lines
2.8 KiB
C#

using CVRManager.Models;
namespace CVRManager.Services;
public record RepoOffer(string Repo, string Asset, List<ReleaseInfo> Releases);
public class AvailableEntry
{
public string Key { get; init; } = "";
public HashSet<string> Keys { get; } = new();
public string Name { get; set; } = "";
public CvrmgMod? Cvrmg { get; set; }
public List<RepoOffer> Repos { get; } = new();
}
public static class AvailableModsService
{
public static async Task<List<AvailableEntry>> BuildAsync(
CvrmgService cvrmg, ModImportService importer, IReadOnlyList<SourceDef> sources, bool force, Action<string> log, CancellationToken ct)
{
if (force) importer.Invalidate();
var byKey = new Dictionary<string, AvailableEntry>();
var entries = new List<AvailableEntry>();
if (sources.Any(s => s.Kind == "cvrmg"))
{
try
{
foreach (var m in await cvrmg.GetAllAsync(ct, force))
{
var e = new AvailableEntry { Key = CvrmgService.Normalize(m.Name), Name = m.Name, Cvrmg = m };
foreach (var n in new[] { m.Name }.Concat(m.Aliases)) e.Keys.Add(CvrmgService.Normalize(n));
e.Keys.RemoveWhere(k => k.Length == 0);
if (e.Keys.Count == 0) continue;
entries.Add(e);
foreach (var k in e.Keys) byKey.TryAdd(k, e);
}
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
log($"CVRMG could not be loaded: {ex.Message}");
}
}
foreach (var src in sources.Where(s => s.Kind == "github" && s.Repo.Length > 0))
{
var releases = await importer.ReleasesAsync(src.Repo, log, ct, force);
var assets = new Dictionary<string, string>();
foreach (var r in releases)
foreach (var a in r.Assets.Where(a => a.Name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)))
assets.TryAdd(CvrmgService.Normalize(Path.GetFileNameWithoutExtension(a.Name)), a.Name);
foreach (var (key, asset) in assets)
{
if (key.Length == 0) continue;
if (!byKey.TryGetValue(key, out var entry))
{
entry = new AvailableEntry { Key = key, Name = Path.GetFileNameWithoutExtension(asset) };
entry.Keys.Add(key);
byKey[key] = entry;
entries.Add(entry);
}
if (entry.Repos.All(o => !o.Repo.Equals(src.Repo, StringComparison.OrdinalIgnoreCase)))
entry.Repos.Add(new RepoOffer(src.Repo, asset, ModImportService.FilterReleases(releases, asset)));
}
}
return entries;
}
}