Resolve Eve state refs through Verse client

This commit is contained in:
Meta Vens 2026-06-22 14:48:38 +01:00
commit 9d8090fe0f
5 changed files with 78 additions and 8 deletions

View file

@ -4611,7 +4611,8 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root)
!eveUnitySurfaceHost.Contains("ContainsStateRefs(surface)", StringComparison.Ordinal) ||
!eveUnitySurfaceHost.Contains("prop.Key.EndsWith(\"Ref\", StringComparison.Ordinal)", StringComparison.Ordinal) ||
!eveUnitySurfaceHost.Contains("CreateDefaultStateRefResolver()", StringComparison.Ordinal) ||
!eveUnitySurfaceHost.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver(stateBoot.StateFilePath)", StringComparison.Ordinal) ||
!eveUnitySurfaceHost.Contains("AetheriaRuntimeVerseClient.CreateEveSurfaceStateRefResolver(", StringComparison.Ordinal) ||
!eveUnitySurfaceHost.Contains("\"unity-eve-surface-host\"", StringComparison.Ordinal) ||
!runtimeEveSurfaceAdapter.Contains("public static EveSurfaceDocument ResolveStateRefs(", StringComparison.Ordinal) ||
!runtimeEveSurfaceAdapter.Contains("ResolvePropRefs(props, stateRefResolver)", StringComparison.Ordinal) ||
!runtimeEveSurfaceAdapter.Contains("ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", stateRefResolver)", StringComparison.Ordinal) ||
@ -8130,6 +8131,9 @@ static void RequireAetheriaRuntimeVerseClientContract(string root)
"GetPlayerSettingsAsync()",
"GetVerseHostSettingsAsync()",
"GetLoadoutTemplatesAsync()",
"CreateEveSurfaceStateRefResolver(",
"AetheriaRuntimeStateReader.TryResolveDaemonStateRef(",
"AetheriaRuntimeStateReader.TryResolveDaemonItemStatRef(",
"SubmitDaemonCommandAsync(",
"SubmitEveCommandAsync(",
"AetheriaRuntimeVerseRecordKeys.DaemonCommand(command.CommandId)",
@ -10161,6 +10165,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
var actionGameManagerPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "ActionGameManager.cs");
var mainMenuPath = Path.Combine(root, "Assets", "Scripts", "UI", "MainMenu.cs");
var eveSurfacePresenterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveSurfacePresenter.cs");
var eveUnitySurfaceHostPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveUnitySurfaceHost.cs");
var requiredPaths = new[]
{
@ -10169,7 +10174,8 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
unityPackageProjectPath,
actionGameManagerPath,
mainMenuPath,
eveSurfacePresenterPath
eveSurfacePresenterPath,
eveUnitySurfaceHostPath
};
var missingPaths = requiredPaths
@ -10190,6 +10196,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
var actionGameManager = File.ReadAllText(actionGameManagerPath);
var mainMenu = File.ReadAllText(mainMenuPath);
var eveSurfacePresenter = File.ReadAllText(eveSurfacePresenterPath);
var eveUnitySurfaceHost = File.ReadAllText(eveUnitySurfaceHostPath);
var requiredReaderSymbols = new[]
{
@ -10374,10 +10381,18 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"Aetheria Eve surface presenter no longer routes daemon surface lookup through the shared runtime Verse client.");
}
if (!eveSurfacePresenter.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver(statePath)", StringComparison.Ordinal))
if (!eveSurfacePresenter.Contains("client.CreateEveSurfaceStateRefResolver()", StringComparison.Ordinal) ||
!eveSurfacePresenter.Contains("ResolveVerseClient(statePath).CreateEveSurfaceStateRefResolver()", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Aetheria Eve surface presenter no longer resolves provider state refs through the shared runtime state reader.");
"Aetheria Eve surface presenter no longer resolves provider state refs through the shared runtime Verse client.");
}
if (eveSurfacePresenter.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver", StringComparison.Ordinal) ||
eveUnitySurfaceHost.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Unity Eve surface lowering still resolves state refs through the file reader instead of AetheriaRuntimeVerseClient.");
}
var forbiddenDirectStoreSymbols = new Dictionary<string, string[]>

View file

@ -129,7 +129,7 @@ namespace GameCult.Aetheria.EveRuntime
? null
: AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(
surface,
AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver(statePath));
client.CreateEveSurfaceStateRefResolver());
}
private global::Aetheria.State.Documents.EveSurfaceState? ReadDaemonSurfaceState(AetheriaRuntimeVerseClient client)
@ -206,7 +206,7 @@ namespace GameCult.Aetheria.EveRuntime
surface,
request => EmitCommand(statePath, request),
RootOnlyChrome,
AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver(statePath));
ResolveVerseClient(statePath).CreateEveSurfaceStateRefResolver());
_mountedStatePath = statePath;
_mountedSurfaceId = surface.Surface.Id;
_mountedSurfaceVersion = surface.Version;

View file

@ -227,7 +227,9 @@ namespace GameCult.Aetheria.EveRuntime
if (!stateBoot.SupportsLocalStateFileRead || !stateBoot.StateFileExists)
return _ => "";
return AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver(stateBoot.StateFilePath);
return AetheriaRuntimeVerseClient.CreateEveSurfaceStateRefResolver(
stateBoot.StateFilePath,
"unity-eve-surface-host");
}
}

View file

@ -8,7 +8,7 @@ using GameCult.Eve.Surface;
namespace GameCult.Aetheria.State.Verse
{
// Runtime shells acquire typed state through this port so the transport can move to the daemon without spelunking every consumer.
// Compatibility reader for file-backed tools and pure state-ref helpers; Unity shells should prefer AetheriaRuntimeVerseClient.
public static class AetheriaRuntimeStateReader
{
public static AetheriaRuntimeCatalogSnapshot OpenRuntimeCatalog(string stateFilePath)

View file

@ -210,6 +210,23 @@ namespace GameCult.Aetheria.State.Verse
return new AetheriaRuntimeVerseClient(fullPath, effectiveRuntimeId, node);
}
public static Func<string, string> CreateEveSurfaceStateRefResolver(
string statePath,
string runtimeId = DefaultRuntimeId)
{
if (string.IsNullOrWhiteSpace(statePath))
return _ => "";
using var client = OpenAsync(
statePath,
string.IsNullOrWhiteSpace(runtimeId) ? DefaultRuntimeId : runtimeId,
startServer: false,
pullOnOpen: true)
.GetAwaiter()
.GetResult();
return client.CreateEveSurfaceStateRefResolver();
}
public Task<AetheriaRuntimeDaemonProviderAdvertisementDocument?> GetProviderAdvertisementAsync()
{
ThrowIfDisposed();
@ -291,6 +308,42 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeDaemonSoaViewStore.GetViewPath(StatePath));
}
public Func<string, string> CreateEveSurfaceStateRefResolver()
{
ThrowIfDisposed();
var frame = GetLatestFrameAsync().GetAwaiter().GetResult();
var health = GetHealthAsync().GetAwaiter().GetResult();
var commandBoundary = GetCommandBoundaryAsync().GetAwaiter().GetResult();
AetheriaRuntimeCatalogSnapshot? catalog = null;
return stateRef =>
{
if (string.IsNullOrWhiteSpace(stateRef))
return "";
if (stateRef.StartsWith(AetheriaRuntimeDaemonStateRefs.Prefix + "/", StringComparison.Ordinal) &&
AetheriaRuntimeStateReader.TryResolveDaemonStateRef(
frame,
health,
commandBoundary,
stateRef,
out var daemonValue))
{
return daemonValue;
}
if (stateRef.StartsWith(AetheriaRuntimeDaemonItemStatQueries.StateRefPrefix + "/", StringComparison.Ordinal))
{
catalog ??= OpenRuntimeCatalog();
if (AetheriaRuntimeStateReader.TryResolveDaemonItemStatRef(frame, catalog, stateRef, out var itemValue))
return itemValue;
}
return "";
};
}
public async Task<AetheriaRuntimeDaemonFrameDocument?> GetLatestAuthoritativeRunFrameAsync()
{
ThrowIfDisposed();