feat(launcher): stabilize prepared content updates
Some checks failed
CI / linux-portable (push) Failing after 3m12s
CI / windows-gate (push) Failing after 6m35s
CI / release (push) Has been skipped

This commit is contained in:
Erik 2026-08-25 19:17:13 +02:00
parent f160f3fee1
commit af9327a17b
42 changed files with 3706 additions and 147 deletions

View file

@ -51,6 +51,9 @@ internal sealed record ContentEffectsAudioResult(
internal sealed record ContentEffectsAudioDependencies(
string DatDirectory,
string PreparedAssetPath,
string? PreparedAssetOverlayPath,
uint? PreparedAssetBaseRecipeVersion,
uint? PreparedAssetEffectiveRecipeVersion,
ResidencyBudgetOptions ResidencyBudgets,
PhysicsDataCache PhysicsDataCache,
bool DumpMotionEnabled,
@ -99,6 +102,9 @@ internal interface IContentEffectsAudioCompositionFactory
IDatReaderWriter OpenDatCollection(string datDirectory);
IPreparedAssetSource OpenPreparedAssetSource(
string path,
string? overlayPath,
uint? baseRecipeVersion,
uint? effectiveRecipeVersion,
IDatReaderWriter dats,
Action<string> diagnostic);
MagicCatalog LoadMagicCatalog(IDatReaderWriter dats);
@ -169,9 +175,54 @@ internal sealed class RetailContentEffectsAudioCompositionFactory
public IPreparedAssetSource OpenPreparedAssetSource(
string path,
string? overlayPath,
uint? baseRecipeVersion,
uint? effectiveRecipeVersion,
IDatReaderWriter dats,
Action<string> diagnostic) =>
new PakPreparedAssetSource(path, dats, diagnostic);
Action<string> diagnostic)
{
if (string.IsNullOrWhiteSpace(overlayPath))
{
return new PakPreparedAssetSource(path, dats, diagnostic);
}
if (baseRecipeVersion is not > 0
|| effectiveRecipeVersion is not > 0)
{
throw new InvalidDataException(
"Layered prepared content is missing its recipe identities.");
}
if (effectiveRecipeVersion
!= AcDream.Content.Pak.PakFormat.CurrentBakeToolVersion)
{
throw new InvalidDataException(
$"Prepared content recipe {effectiveRecipeVersion} does not "
+ $"match client recipe "
+ $"{AcDream.Content.Pak.PakFormat.CurrentBakeToolVersion}.");
}
PakPreparedAssetSource? baseSource = null;
PakPreparedAssetSource? overlaySource = null;
try
{
baseSource = new PakPreparedAssetSource(
path,
PreparedAssetCatalogIdentity.From(dats, baseRecipeVersion.Value),
diagnostic);
overlaySource = new PakPreparedAssetSource(
overlayPath,
PreparedAssetCatalogIdentity.From(dats, effectiveRecipeVersion.Value),
diagnostic);
return new LayeredPreparedAssetSource(baseSource, overlaySource);
}
catch
{
overlaySource?.Dispose();
baseSource?.Dispose();
throw;
}
}
public MagicCatalog LoadMagicCatalog(IDatReaderWriter dats) =>
MagicCatalog.Load(dats);
@ -370,6 +421,9 @@ internal sealed class ContentEffectsAudioCompositionPhase :
"prepared asset source",
() => _factory.OpenPreparedAssetSource(
_dependencies.PreparedAssetPath,
_dependencies.PreparedAssetOverlayPath,
_dependencies.PreparedAssetBaseRecipeVersion,
_dependencies.PreparedAssetEffectiveRecipeVersion,
dats,
_dependencies.Error),
static value => value.Dispose()).Publish(