From 03b1e082ea3188f04a9e3ee0a65f75bb1b3f1314 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 28 Jun 2026 01:58:58 +0100 Subject: [PATCH] Route catalog reads through managed document --- Aetheria.State.Verify/Program.cs | 17 ++++++++++++----- Assets/Scripts/Gameplay/ActionBarSlot.cs | 2 +- .../Gameplay/AetheriaUnityGameplayBootShell.cs | 4 +++- .../Scripts/Tests/DaemonRuntimeDocumentTests.cs | 7 +++++++ Assets/Scripts/UI/HUD/SchematicDisplay.cs | 2 +- Assets/Scripts/UI/MainMenu.cs | 2 +- Assets/Scripts/UI/Menu/InventoryMenu.cs | 2 +- Assets/Scripts/UI/Menu/InventoryPanel.cs | 2 +- Assets/Scripts/UI/Menu/SectorRenderer.cs | 2 +- Assets/Scripts/UI/Menu/TradeMenu.cs | 2 +- Assets/Scripts/Zone Display/ZoneRenderer.cs | 2 +- .../Runtime/AetheriaClient.cs | 2 +- .../Runtime/AetheriaClientState.cs | 5 +++++ .../Runtime/AetheriaRuntimeCatalogSnapshot.cs | 2 ++ .../Runtime/AetheriaRuntimeVerseClient.cs | 5 +++++ 15 files changed, 43 insertions(+), 15 deletions(-) diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 5a0191415..15bf78f33 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -4491,7 +4491,7 @@ static void RequireSectorMapZoneDetailsUseEveSurface(string root) ".LatestAsync()", ".Details", ".Zone(zoneIndex)", - "OpenRuntimeCatalog()", + ".Catalog", ".Settings", ".Player", ".Latest()", @@ -4534,6 +4534,7 @@ static void RequireSectorMapZoneDetailsUseEveSurface(string root) "Properties.AddProperty(\"Ships\"", "GameManager.Settings.ZoneSettings.ZoneRadius.Evaluate(", "GameManager.Settings.ZoneSettings.ZoneMass.Evaluate(", + "OpenRuntimeCatalog()", "ProjectZoneBodies(", "ProjectZoneEntities(", "new AetheriaRuntimeZoneDetailsBodyProjection(", @@ -7305,7 +7306,8 @@ static void RequireClientTargetBootAuthority(string root) "stateBoot.StateFileExists", "private static AetheriaRuntimeCatalogSnapshot _runtimeCatalog", "FindTypedRuntimeItem(", - "_runtimeCatalog?.FindItem(" + "_runtimeCatalog?.FindItem(", + ".OpenRuntimeCatalog()" }; var actionGameManagerBootHits = forbiddenActionGameManagerBootSymbols .Where(symbol => actionGameManager.Contains(symbol, StringComparison.Ordinal)) @@ -7328,7 +7330,9 @@ static void RequireClientTargetBootAuthority(string root) "!stateBoot.SupportsLocalStateFileRead", "stateBoot.StateFileExists", "AetheriaUnityRuntimeClientProvider.ResolveClient(stateBoot.StateFilePath, stateBoot.RuntimeId)", - ".OpenRuntimeCatalog()", + ".Aetheria()", + ".Catalog", + ".Latest()", "new ItemManager(", "new AetheriaUnityLoadoutItemProjector(itemManager, runtimeCatalog)", "ZoneRenderer.SetDroppedPickupItemProjector(loadoutItemProjector.CreateLoadoutItem)", @@ -11429,7 +11433,8 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root) !sectorRenderer.Contains(".LatestAsync()", StringComparison.Ordinal) || !sectorRenderer.Contains(".Details", StringComparison.Ordinal) || !sectorRenderer.Contains(".Zone(zoneIndex)", StringComparison.Ordinal) || - !sectorRenderer.Contains("OpenRuntimeCatalog()", StringComparison.Ordinal) || + !sectorRenderer.Contains(".Catalog", StringComparison.Ordinal) || + !sectorRenderer.Contains(".Latest()", StringComparison.Ordinal) || !sectorRenderer.Contains(".Settings", StringComparison.Ordinal) || !sectorRenderer.Contains(".Player", StringComparison.Ordinal) || !sectorMap.Contains("private AetheriaClient _client", StringComparison.Ordinal) || @@ -12853,7 +12858,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "public AetheriaUnityGameplayBootResult Boot()", "AetheriaRuntimeStateBoot.Inspect(AetheriaUnityRuntimePaths.GameDataDirectory)", "AetheriaUnityRuntimeClientProvider.ResolveClient(stateBoot.StateFilePath, stateBoot.RuntimeId)", - "OpenRuntimeCatalog()", + ".Aetheria()", + ".Catalog", + ".Latest()", "new ItemManager(", "new AetheriaUnityLoadoutItemProjector(itemManager, runtimeCatalog)", "ZoneRenderer.SetDroppedPickupItemProjector(loadoutItemProjector.CreateLoadoutItem)", diff --git a/Assets/Scripts/Gameplay/ActionBarSlot.cs b/Assets/Scripts/Gameplay/ActionBarSlot.cs index 29b8ba55c..a74bdf7d0 100644 --- a/Assets/Scripts/Gameplay/ActionBarSlot.cs +++ b/Assets/Scripts/Gameplay/ActionBarSlot.cs @@ -85,7 +85,7 @@ public abstract class ActionBarBinding try { - _catalog ??= Client.OpenRuntimeCatalog(); + _catalog ??= Client.Aetheria().Catalog.Latest(); return _catalog?.FindItem(item.ItemKey); } catch (Exception ex) diff --git a/Assets/Scripts/Gameplay/AetheriaUnityGameplayBootShell.cs b/Assets/Scripts/Gameplay/AetheriaUnityGameplayBootShell.cs index 4c2f55c8d..465ab480f 100644 --- a/Assets/Scripts/Gameplay/AetheriaUnityGameplayBootShell.cs +++ b/Assets/Scripts/Gameplay/AetheriaUnityGameplayBootShell.cs @@ -35,7 +35,9 @@ public sealed class AetheriaUnityGameplayBootShell } var runtimeCatalog = AetheriaUnityRuntimeClientProvider.ResolveClient(stateBoot.StateFilePath, stateBoot.RuntimeId) - .OpenRuntimeCatalog(); + .Aetheria() + .Catalog + .Latest(); if (runtimeCatalog == null) throw new InvalidOperationException("Aetheria typed runtime catalog is required before gameplay boot."); diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index 9f7896739..b6b766b80 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -168,6 +168,7 @@ public class DaemonRuntimeDocumentTests var currentEntity = client.Aetheria().Current.Entity.LatestAsync().GetAwaiter().GetResult(); var latestFrame = client.Aetheria().LatestFrame.LatestAsync().GetAwaiter().GetResult(); + var catalog = client.Aetheria().Catalog.LatestAsync().GetAwaiter().GetResult(); var playerSettings = client.Aetheria().Settings.Player.LatestAsync().GetAwaiter().GetResult(); var verseHostSettings = client.Aetheria().Settings.VerseHost.LatestAsync().GetAwaiter().GetResult(); var currentEntityByType = client.Aetheria() @@ -217,6 +218,7 @@ public class DaemonRuntimeDocumentTests Assert.AreEqual("aetheria.current.entity", client.State.Current.Entity.DocumentId); Assert.AreSame(client.State.Current.Entity, client.State.Document()); + Assert.AreSame(client.State.Catalog, client.Document()); Assert.AreSame(client.State.ZoneRender, client.Document()); Assert.AreSame(client.State.LatestFrame, client.Document()); Assert.AreSame(client.State.Settings.Player, client.Document()); @@ -240,6 +242,8 @@ public class DaemonRuntimeDocumentTests Assert.AreEqual(AetheriaRuntimeDaemonSchemas.Frame, latestFrame.Schema); Assert.AreEqual(frame.FrameId, latestFrame.FrameId); Assert.AreEqual(frame.FrameId, latestFrameByType.FrameId); + Assert.AreEqual(AetheriaRuntimeCatalogSnapshot.SchemaId, client.State.Catalog.Sources.Last().SchemaId); + Assert.GreaterOrEqual(catalog.Items.Count, 0); Assert.AreEqual(AetheriaRuntimePlayerSettingsDocument.SchemaId, playerSettings.Schema); Assert.AreEqual(AetheriaRuntimeVerseHostSettingsDocument.SchemaId, verseHostSettings.Schema); Assert.AreEqual(AetheriaRuntimeDaemonSchemas.ObjectsViewport, objectsViewport.Schema); @@ -278,7 +282,10 @@ public class DaemonRuntimeDocumentTests var player = client.Aetheria().Settings.Player.LatestAsync().GetAwaiter().GetResult(); var verseHost = client.Aetheria().Settings.VerseHost.LatestAsync().GetAwaiter().GetResult(); + var catalog = client.Aetheria().Catalog.LatestAsync().GetAwaiter().GetResult(); + Assert.AreEqual(AetheriaRuntimeCatalogSnapshot.SchemaId, client.State.Catalog.Sources.Last().SchemaId); + Assert.IsNotNull(catalog); Assert.AreEqual(AetheriaRuntimePlayerSettingsDocument.SchemaId, player.Schema); Assert.AreEqual(AetheriaRuntimeVerseHostSettingsDocument.SchemaId, verseHost.Schema); Assert.AreEqual("", player.PlayerName); diff --git a/Assets/Scripts/UI/HUD/SchematicDisplay.cs b/Assets/Scripts/UI/HUD/SchematicDisplay.cs index 31388e099..363d47a7f 100644 --- a/Assets/Scripts/UI/HUD/SchematicDisplay.cs +++ b/Assets/Scripts/UI/HUD/SchematicDisplay.cs @@ -329,7 +329,7 @@ public class SchematicDisplay : MonoBehaviour try { - _catalog = ResolveClient().OpenRuntimeCatalog(); + _catalog = ResolveClient().Aetheria().Catalog.Latest(); } catch (Exception ex) { diff --git a/Assets/Scripts/UI/MainMenu.cs b/Assets/Scripts/UI/MainMenu.cs index 14cae9e43..f1dd430e1 100644 --- a/Assets/Scripts/UI/MainMenu.cs +++ b/Assets/Scripts/UI/MainMenu.cs @@ -226,7 +226,7 @@ public class MainMenu : MonoBehaviour try { - _catalog = ResolveClient(stateBoot).OpenRuntimeCatalog(); + _catalog = ResolveClient(stateBoot).Aetheria().Catalog.Latest(); return _catalog; } catch (Exception ex) diff --git a/Assets/Scripts/UI/Menu/InventoryMenu.cs b/Assets/Scripts/UI/Menu/InventoryMenu.cs index 518b1eaa4..596021ec4 100644 --- a/Assets/Scripts/UI/Menu/InventoryMenu.cs +++ b/Assets/Scripts/UI/Menu/InventoryMenu.cs @@ -1038,7 +1038,7 @@ public class InventoryMenu : MonoBehaviour try { - _catalog = ResolveClient().OpenRuntimeCatalog(); + _catalog = ResolveClient().Aetheria().Catalog.Latest(); } catch (Exception ex) { diff --git a/Assets/Scripts/UI/Menu/InventoryPanel.cs b/Assets/Scripts/UI/Menu/InventoryPanel.cs index abba097b8..911181404 100644 --- a/Assets/Scripts/UI/Menu/InventoryPanel.cs +++ b/Assets/Scripts/UI/Menu/InventoryPanel.cs @@ -1530,7 +1530,7 @@ private void Update() try { - _catalog = ResolveClient().OpenRuntimeCatalog(); + _catalog = ResolveClient().Aetheria().Catalog.Latest(); } catch (Exception ex) { diff --git a/Assets/Scripts/UI/Menu/SectorRenderer.cs b/Assets/Scripts/UI/Menu/SectorRenderer.cs index 60476e4da..92b303bb4 100644 --- a/Assets/Scripts/UI/Menu/SectorRenderer.cs +++ b/Assets/Scripts/UI/Menu/SectorRenderer.cs @@ -227,7 +227,7 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS try { - _catalog = ResolveClient().OpenRuntimeCatalog(); + _catalog = ResolveClient().Aetheria().Catalog.Latest(); } catch (Exception ex) { diff --git a/Assets/Scripts/UI/Menu/TradeMenu.cs b/Assets/Scripts/UI/Menu/TradeMenu.cs index 7278658e1..fcf2bf1cf 100644 --- a/Assets/Scripts/UI/Menu/TradeMenu.cs +++ b/Assets/Scripts/UI/Menu/TradeMenu.cs @@ -650,7 +650,7 @@ public class TradeMenu : MonoBehaviour try { - _catalog = ResolveClient().OpenRuntimeCatalog(); + _catalog = ResolveClient().Aetheria().Catalog.Latest(); } catch (Exception ex) { diff --git a/Assets/Scripts/Zone Display/ZoneRenderer.cs b/Assets/Scripts/Zone Display/ZoneRenderer.cs index 896f82693..080840c7d 100644 --- a/Assets/Scripts/Zone Display/ZoneRenderer.cs +++ b/Assets/Scripts/Zone Display/ZoneRenderer.cs @@ -1182,7 +1182,7 @@ public class ZoneRenderer : MonoBehaviour try { - _catalog = ResolveClient().OpenRuntimeCatalog(); + _catalog = ResolveClient().Aetheria().Catalog.Latest(); } catch (Exception ex) { diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs index cc40ace39..f74a45570 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClient.cs @@ -137,7 +137,7 @@ namespace GameCult.Aetheria.State.Verse public AetheriaRuntimeCatalogSnapshot OpenRuntimeCatalog() { ThrowIfDisposed(); - return _verse.OpenRuntimeCatalog(); + return State.Catalog.Latest(); } public async Task PlayerSettingsAsync() diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs index 03b8d2de6..8984138f8 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -15,6 +15,7 @@ namespace GameCult.Aetheria.State.Verse internal AetheriaClientState( CultMeshDocumentHandle latestFrame, CultMeshDocumentHandle latestSoaView, + CultMeshDocumentHandle catalog, CultMeshDocumentHandle playerSettings, CultMeshDocumentHandle verseHostSettings, CultMeshDocumentHandle currentZone, @@ -38,6 +39,7 @@ namespace GameCult.Aetheria.State.Verse { LatestFrame = latestFrame ?? throw new ArgumentNullException(nameof(latestFrame)); LatestSoaView = latestSoaView ?? throw new ArgumentNullException(nameof(latestSoaView)); + Catalog = catalog ?? throw new ArgumentNullException(nameof(catalog)); Settings = new AetheriaClientSettingsState(playerSettings, verseHostSettings); Current = new AetheriaClientCurrentState(currentZone, currentEntity, currentDocking); ZoneContacts = zoneContacts ?? throw new ArgumentNullException(nameof(zoneContacts)); @@ -62,6 +64,7 @@ namespace GameCult.Aetheria.State.Verse _documents = CultMesh.Documents( LatestFrame, LatestSoaView, + Catalog, Settings.Player, Settings.VerseHost, Current.Zone, @@ -79,6 +82,8 @@ namespace GameCult.Aetheria.State.Verse public CultMeshDocumentHandle LatestSoaView { get; } + public CultMeshDocumentHandle Catalog { get; } + public AetheriaClientSettingsState Settings { get; } public AetheriaClientCurrentState Current { get; } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs index c3a5ac57e..677646bc8 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs @@ -8,6 +8,8 @@ namespace GameCult.Aetheria.State.Verse { public sealed class AetheriaRuntimeCatalogSnapshot { + public const string SchemaId = "gamecult.aetheria.runtime_catalog.v1"; + private readonly Dictionary _itemsByKey; private readonly Dictionary _corporationsByKey; private readonly Dictionary _nameFilesByKey; diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs index cf9c91707..8d52367a3 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeVerseClient.cs @@ -734,6 +734,11 @@ namespace GameCult.Aetheria.State.Verse AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest), Document( AetheriaRuntimeVerseRecordKeys.DaemonSoaViewLatest), + CatalogDocument( + "aetheria.catalog.runtime", + () => Task.FromResult(OpenRuntimeCatalog()), + AetheriaRuntimeCatalogSnapshot.SchemaId, + CultMesh.ProjectionSource("catalog:aetheria.runtime")), CatalogDocument( "aetheria.settings.player", () => Task.FromResult(AetheriaRuntimePlayerSettingsDocument.FromSnapshot(