feat(launcher): stabilize prepared content updates
This commit is contained in:
parent
f160f3fee1
commit
af9327a17b
42 changed files with 3706 additions and 147 deletions
|
|
@ -27,6 +27,12 @@ internal sealed class HeadlessContentDescriptor
|
|||
|
||||
[JsonRequired]
|
||||
public string PreparedAssetPath { get; init; } = string.Empty;
|
||||
|
||||
public string? PreparedAssetOverlayPath { get; init; }
|
||||
|
||||
public uint? PreparedAssetBaseRecipeVersion { get; init; }
|
||||
|
||||
public uint? PreparedAssetEffectiveRecipeVersion { get; init; }
|
||||
}
|
||||
|
||||
// MF-1 (Campaign OP OP7 review fix, 2026-08-11): record, not class — the
|
||||
|
|
|
|||
|
|
@ -173,6 +173,18 @@ internal static class HeadlessConfigurationLoader
|
|||
throw new HeadlessConfigurationException(
|
||||
"process.content requires non-empty datDirectory and preparedAssetPath.");
|
||||
}
|
||||
|
||||
bool hasOverlay = !string.IsNullOrWhiteSpace(
|
||||
content.PreparedAssetOverlayPath);
|
||||
bool hasBaseRecipe = content.PreparedAssetBaseRecipeVersion is > 0;
|
||||
bool hasEffectiveRecipe =
|
||||
content.PreparedAssetEffectiveRecipeVersion is > 0;
|
||||
if (hasOverlay != hasBaseRecipe || hasOverlay != hasEffectiveRecipe)
|
||||
{
|
||||
throw new HeadlessConfigurationException(
|
||||
"process.content overlay path, base recipe, and effective recipe "
|
||||
+ "must be supplied together.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateSession(
|
||||
|
|
|
|||
|
|
@ -43,15 +43,56 @@ internal sealed class ProductionHeadlessProcessContentFactory
|
|||
string datDirectory = Path.GetFullPath(descriptor.DatDirectory);
|
||||
string preparedAssetPath =
|
||||
Path.GetFullPath(descriptor.PreparedAssetPath);
|
||||
string? overlayPath = string.IsNullOrWhiteSpace(
|
||||
descriptor.PreparedAssetOverlayPath)
|
||||
? null
|
||||
: Path.GetFullPath(descriptor.PreparedAssetOverlayPath);
|
||||
IDatReaderWriter? dats = null;
|
||||
IPreparedAssetSource? prepared = null;
|
||||
try
|
||||
{
|
||||
dats = RuntimeDatCollectionFactory.OpenReadOnly(datDirectory);
|
||||
prepared = new PakPreparedAssetSource(
|
||||
preparedAssetPath,
|
||||
dats,
|
||||
diagnostic);
|
||||
if (overlayPath is null)
|
||||
{
|
||||
prepared = new PakPreparedAssetSource(
|
||||
preparedAssetPath,
|
||||
dats,
|
||||
diagnostic);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (descriptor.PreparedAssetBaseRecipeVersion is not > 0
|
||||
|| descriptor.PreparedAssetEffectiveRecipeVersion
|
||||
!= AcDream.Content.Pak.PakFormat.CurrentBakeToolVersion)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
"Layered prepared content does not match the client's recipe.");
|
||||
}
|
||||
|
||||
var baseSource = new PakPreparedAssetSource(
|
||||
preparedAssetPath,
|
||||
PreparedAssetCatalogIdentity.From(
|
||||
dats,
|
||||
descriptor.PreparedAssetBaseRecipeVersion.Value),
|
||||
diagnostic);
|
||||
try
|
||||
{
|
||||
var overlaySource = new PakPreparedAssetSource(
|
||||
overlayPath,
|
||||
PreparedAssetCatalogIdentity.From(
|
||||
dats,
|
||||
descriptor.PreparedAssetEffectiveRecipeVersion.Value),
|
||||
diagnostic);
|
||||
prepared = new LayeredPreparedAssetSource(
|
||||
baseSource,
|
||||
overlaySource);
|
||||
}
|
||||
catch
|
||||
{
|
||||
baseSource.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
MagicCatalog magic = MagicCatalog.Load(dats);
|
||||
Region region = dats.Get<Region>(0x13000000u)
|
||||
?? throw new InvalidOperationException(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue