Keep pinned Eve asset catalogs stable

This commit is contained in:
Meta Vens 2026-08-19 09:50:50 +02:00
commit 47122fa53e
3 changed files with 64 additions and 11 deletions

View file

@ -1471,7 +1471,7 @@ namespace GameCult.Eve.UnityScene
var pending = candidate.ObserveCatalog(catalog);
if (requiredCatalogVersion > 0 && catalog.Version == requiredCatalogVersion)
requiredCatalog.TrySetResult(catalog);
if (pending != null)
if (pending != null && requiredCatalogVersion <= 0)
QueueAssetCatalogUpdate(candidate.SourceIdentity, pending);
});
candidate.CatalogWatch = watch;
@ -1508,7 +1508,7 @@ namespace GameCult.Eve.UnityScene
previous.TransferSharedBundlesTo(candidate);
_assetGeneration = candidate;
var pendingCatalog = candidate.ActivateCatalogObservation();
if (pendingCatalog != null)
if (pendingCatalog != null && candidate.Source.RequiredCatalogVersion <= 0)
QueueAssetCatalogUpdate(candidate.SourceIdentity, pendingCatalog);
if (surface != null)
_baseSurface = surface;
@ -1624,9 +1624,15 @@ namespace GameCult.Eve.UnityScene
private void QueueAssetCatalogUpdate(string sourceIdentity, EveAssetCatalogDocument catalog)
{
if (catalog == null) throw new ArgumentNullException(nameof(catalog));
if (_assetGeneration.Source.RequiredCatalogVersion > 0)
{
_pendingAssetCatalog = null;
return;
}
_pendingAssetCatalog = new PendingAssetCatalogUpdate(
sourceIdentity,
catalog ?? throw new ArgumentNullException(nameof(catalog)));
catalog);
if (_assetCatalogUpdateRunning) return;
_assetCatalogUpdateRunning = true;
_ = DrainAssetCatalogUpdatesAsync();
@ -1641,6 +1647,8 @@ namespace GameCult.Eve.UnityScene
var update = _pendingAssetCatalog;
_pendingAssetCatalog = null;
if (update == null) break;
if (_assetGeneration.Source.RequiredCatalogVersion > 0)
continue;
if (!string.Equals(update.SourceIdentity, CurrentAssetSourceIdentity, StringComparison.Ordinal))
continue;
if (update.Catalog.Version == CurrentAssetCatalogVersion)
@ -1649,7 +1657,8 @@ namespace GameCult.Eve.UnityScene
try
{
if (!string.Equals(update.SourceIdentity, CurrentAssetSourceIdentity, StringComparison.Ordinal) ||
update.Catalog.Version == CurrentAssetCatalogVersion)
update.Catalog.Version == CurrentAssetCatalogVersion ||
_assetGeneration.Source.RequiredCatalogVersion > 0)
continue;
var currentSource = _assetGeneration.Source;
var source = new AssetSource(
@ -1657,9 +1666,10 @@ namespace GameCult.Eve.UnityScene
currentSource.ProviderId,
currentSource.ManifestRecordRef,
currentSource.RendezvousEndpoints,
update.Catalog.Version);
0);
var candidate = await BuildAssetGenerationAsync(source, _lifetime.Token);
if (!string.Equals(update.SourceIdentity, CurrentAssetSourceIdentity, StringComparison.Ordinal))
if (!string.Equals(update.SourceIdentity, CurrentAssetSourceIdentity, StringComparison.Ordinal) ||
_assetGeneration.Source.RequiredCatalogVersion > 0)
{
candidate.Dispose();
continue;

View file

@ -656,6 +656,46 @@ namespace GameCult.Eve.UnityScene.Tests
((IDisposable)candidate).Dispose();
}
[Test]
public void PinnedSurfaceCatalogDoesNotAutoAdvanceWithoutANewerBaseSurface()
{
var transportType = typeof(EveUnityCultMeshLiveProviderTransport);
var generationField = transportType.GetField(
"_assetGeneration",
BindingFlags.Instance | BindingFlags.NonPublic)!;
var pendingField = transportType.GetField(
"_pendingAssetCatalog",
BindingFlags.Instance | BindingFlags.NonPublic)!;
var queue = transportType.GetMethod(
"QueueAssetCatalogUpdate",
BindingFlags.Instance | BindingFlags.NonPublic)!;
using var transport = new EveUnityCultMeshLiveProviderTransport(
Path.Combine(Path.GetTempPath(), $"eve-pinned-catalog-{Guid.NewGuid():N}.cc"),
"cultnet+tcp://127.0.0.1:1",
"verse-a",
"authority-a",
"provider-a",
"surface-a");
var initial = (IDisposable)generationField.GetValue(transport)!;
var committed = CreateAssetGeneration(
"verse-a", "authority-a", "provider-a", "catalog-a", "source-a", 41, 41);
initial.Dispose();
generationField.SetValue(transport, committed);
var catalog42 = new EveAssetCatalogDocument(
"provider-a",
"catalog-a",
42,
DateTimeOffset.UtcNow.ToString("O"),
Array.Empty<EveAssetCatalogEntry>());
queue.Invoke(transport, new object[] { "source-a", catalog42 });
Assert.That(GenerationProperty<long>(generationField.GetValue(transport)!, "CatalogVersion"), Is.EqualTo(41));
var committedSource = GenerationProperty<object>(generationField.GetValue(transport)!, "Source");
Assert.That(GenerationProperty<long>(committedSource, "RequiredCatalogVersion"), Is.EqualTo(41));
Assert.That(pendingField.GetValue(transport), Is.Null);
}
[Test]
public void CrossTargetAssetsUseConfiguredRemoteTrust()
{
@ -685,7 +725,8 @@ namespace GameCult.Eve.UnityScene.Tests
string verseId,
string authorityRuntimeId,
string providerId,
string manifestRecordRef)
string manifestRecordRef,
long requiredCatalogVersion = 0)
{
var type = typeof(EveUnityCultMeshLiveProviderTransport).GetNestedType(
"AssetSource",
@ -699,7 +740,8 @@ namespace GameCult.Eve.UnityScene.Tests
new CultMeshSessionTarget(verseId, authorityRuntimeId),
providerId,
manifestRecordRef,
Array.Empty<string>()
Array.Empty<string>(),
requiredCatalogVersion
},
null)!;
}
@ -710,7 +752,8 @@ namespace GameCult.Eve.UnityScene.Tests
string providerId,
string manifestRecordRef,
string sourceIdentity,
long catalogVersion)
long catalogVersion,
long requiredCatalogVersion = 0)
{
var type = typeof(EveUnityCultMeshLiveProviderTransport).GetNestedType(
"AssetGeneration",
@ -721,7 +764,7 @@ namespace GameCult.Eve.UnityScene.Tests
null,
new[]
{
CreateAssetSource(verseId, authorityRuntimeId, providerId, manifestRecordRef),
CreateAssetSource(verseId, authorityRuntimeId, providerId, manifestRecordRef, requiredCatalogVersion),
sourceIdentity,
catalogVersion,
null

View file

@ -1,7 +1,7 @@
{
"name": "org.gamecult.eve.unity-scene",
"displayName": "Eve Unity Scene Lowering",
"version": "0.3.131",
"version": "0.3.132",
"unity": "6000.0",
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
"dependencies": {