Give packs an identity so create can refuse missing deps and load in a stable order.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -51,9 +51,9 @@ internal sealed class ModContent
|
||||
return true;
|
||||
}
|
||||
|
||||
public IReadOnlyList<ModPackInfo> ListPacks()
|
||||
public IReadOnlyList<ModPackInfo> ListPacks(string locale)
|
||||
{
|
||||
var packs = new List<ModPackInfo> { new(CatalogLoader.CorePackId, Required: true) };
|
||||
var packs = new List<ModPackInfo> { Describe(CatalogLoader.CorePackId, required: true, locale) };
|
||||
if (!Directory.Exists(Root))
|
||||
{
|
||||
return packs;
|
||||
@@ -67,7 +67,7 @@ internal sealed class ModContent
|
||||
continue;
|
||||
}
|
||||
|
||||
packs.Add(new ModPackInfo(id, Required: false));
|
||||
packs.Add(Describe(id, required: false, locale));
|
||||
}
|
||||
|
||||
return packs;
|
||||
@@ -76,6 +76,30 @@ internal sealed class ModContent
|
||||
public IReadOnlyList<string> NormalizePackIds(IReadOnlyList<string>? extraModIds) =>
|
||||
CatalogLoader.NormalizePackOrder(extraModIds ?? []);
|
||||
|
||||
/// <summary>
|
||||
/// Player extras plus <c>core</c>, reordered so each pack's <c>requires</c> load first.
|
||||
/// Missing dependencies and cycles throw <see cref="PackDependencyException"/>.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> ResolveSelectedPacks(IReadOnlyList<string>? extraModIds)
|
||||
{
|
||||
var selected = NormalizePackIds(extraModIds);
|
||||
var manifests = new Dictionary<string, PackManifest>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var packId in selected)
|
||||
{
|
||||
manifests[packId] = ReadManifest(packId);
|
||||
}
|
||||
|
||||
return PackLoadOrder.Resolve(selected, manifests);
|
||||
}
|
||||
|
||||
public PackManifest ReadManifest(string packId)
|
||||
{
|
||||
var jsonc = Path.Combine(PackPath(packId), "pack.jsonc");
|
||||
var json = Path.Combine(PackPath(packId), "pack.json");
|
||||
var path = File.Exists(jsonc) ? jsonc : File.Exists(json) ? json : null;
|
||||
return path is null ? PackManifest.Empty : PackManifest.Parse(packId, File.ReadAllText(path));
|
||||
}
|
||||
|
||||
public IReadOnlyList<ContentDocument> ReadDocuments(IReadOnlyList<string> packIds)
|
||||
{
|
||||
var documents = new List<ContentDocument>();
|
||||
@@ -136,7 +160,50 @@ internal sealed class ModContent
|
||||
|
||||
public DefCatalog LoadCatalog(IReadOnlyList<string> packIds) => LoadCatalog(packIds, _logger);
|
||||
|
||||
private ModPackInfo Describe(string packId, bool required, string locale)
|
||||
{
|
||||
PackManifest manifest;
|
||||
try
|
||||
{
|
||||
manifest = PackExists(packId) ? ReadManifest(packId) : PackManifest.Empty;
|
||||
}
|
||||
catch (ContentLoadException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Could not read pack.jsonc for {PackId}.", packId);
|
||||
manifest = PackManifest.Empty;
|
||||
}
|
||||
|
||||
return new ModPackInfo(packId, required, ReadPackLabel(packId, locale), manifest.Version, manifest.Requires);
|
||||
}
|
||||
|
||||
private string ReadPackLabel(string packId, string locale)
|
||||
{
|
||||
var jsonc = Path.Combine(PackPath(packId), "localizations", $"{locale}.jsonc");
|
||||
var json = Path.Combine(PackPath(packId), "localizations", $"{locale}.json");
|
||||
var path = File.Exists(jsonc) ? jsonc : File.Exists(json) ? json : null;
|
||||
if (path is null)
|
||||
{
|
||||
return packId;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var table = PackManifest.ReadLocaleTable(File.ReadAllText(path), $"{packId}:localizations/{locale}");
|
||||
return table.TryGetValue(packId, out var label) ? label : packId;
|
||||
}
|
||||
catch (ContentLoadException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Could not read pack label for {PackId}.", packId);
|
||||
return packId;
|
||||
}
|
||||
}
|
||||
|
||||
private string PackPath(string packId) => Path.Combine(Root, packId);
|
||||
}
|
||||
|
||||
internal sealed record ModPackInfo(string Id, bool Required);
|
||||
internal sealed record ModPackInfo(
|
||||
string Id,
|
||||
bool Required,
|
||||
string Label,
|
||||
string Version,
|
||||
IReadOnlyList<string> Requires);
|
||||
|
||||
Reference in New Issue
Block a user