Collapse Eve surface projectors into typed documents
This commit is contained in:
parent
a45c704f43
commit
87ac49ab89
11 changed files with 624 additions and 667 deletions
|
|
@ -866,13 +866,13 @@ static async Task PublishStateSurfacesAsync(
|
|||
: playerSettings.LastUpdatedAtUtc;
|
||||
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaOperationsSurfaceProjector.Build(eveStatus, verseHost, runtimeSession))
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildOperationsSurface(eveStatus, verseHost, runtimeSession))
|
||||
.ConfigureAwait(false);
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.PlayerSettingsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaPlayerSettingsSurfaceProjector.Build(playerSettings, playerSettingsUpdatedAt))
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface(playerSettings, playerSettingsUpdatedAt))
|
||||
.ConfigureAwait(false);
|
||||
await node.MutableDocument<EveProviderAdvertisementState>(AetheriaStateNode.ProviderAdvertisementSurfaceKey)
|
||||
.ReplaceAsync(AetheriaProviderAdvertisementProjector.Build(verseHost, node.StatePath, updatedAtUtc))
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildProviderAdvertisement(verseHost, node.StatePath, updatedAtUtc))
|
||||
.ConfigureAwait(false);
|
||||
await node.FlushAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
|
|||
await node.FlushAsync();
|
||||
var runtimeCatalog = await node.RuntimeCatalog().LatestAsync().ConfigureAwait(false);
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.CatalogSurfaceKey)
|
||||
.ReplaceAsync(AetheriaCatalogSurfaceProjector.Build(runtimeCatalog, now));
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildCatalogSurface(runtimeCatalog, now));
|
||||
|
||||
var verseHostSettings = AetheriaVerseHostSettingsNormalizer.Normalize(new AetheriaVerseHostSettings
|
||||
{
|
||||
|
|
@ -103,9 +103,9 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
|
|||
});
|
||||
await node.MutableDocument<AetheriaVerseHostSettings>(AetheriaStateNode.VerseHostSettingsKey).ReplaceAsync(verseHostSettings);
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaOperationsSurfaceProjector.Build(verseHostSettings: verseHostSettings));
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildOperationsSurface(verseHostSettings: verseHostSettings));
|
||||
await node.MutableDocument<EveProviderAdvertisementState>(AetheriaStateNode.ProviderAdvertisementSurfaceKey)
|
||||
.ReplaceAsync(AetheriaProviderAdvertisementProjector.Build(verseHostSettings, statePath, now));
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildProviderAdvertisement(verseHostSettings, statePath, now));
|
||||
var daemonProvider = AetheriaRuntimeDaemonProviderAdvertisementDocument.Create(
|
||||
statePath,
|
||||
"smoke-daemon",
|
||||
|
|
@ -182,7 +182,7 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
|
|||
LastSeenAtUtc = now,
|
||||
Status = "running"
|
||||
});
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey).ReplaceAsync(AetheriaOperationsSurfaceProjector.Build(
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey).ReplaceAsync(AetheriaEveSurfaceDocuments.BuildOperationsSurface(
|
||||
verseHostSettings: verseHostSettings,
|
||||
runtimeSession: await node.MutableDocument<AetheriaRuntimeSession>(AetheriaStateNode.RuntimeSessionKey("smoke-runtime")).ReadAsync()));
|
||||
|
||||
|
|
@ -535,7 +535,7 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
|
|||
}
|
||||
});
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.PlayerSettingsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaPlayerSettingsSurfaceProjector.Build(
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface(
|
||||
await node.MutableDocument<AetheriaPlayerSettings>(AetheriaStateNode.PlayerSettingsKey).ReadAsync(),
|
||||
now));
|
||||
|
||||
|
|
@ -616,7 +616,7 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
|
|||
Status = eveCommandReport.RejectedCommands > 0 ? "rejected" : "ok"
|
||||
};
|
||||
await node.MutableDocument<AetheriaEveCommandAcceptanceStatus>(AetheriaStateNode.EveCommandAcceptanceStatusKey).ReplaceAsync(eveCommandStatus);
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey).ReplaceAsync(AetheriaOperationsSurfaceProjector.Build(
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey).ReplaceAsync(AetheriaEveSurfaceDocuments.BuildOperationsSurface(
|
||||
eveCommandStatus,
|
||||
verseHostSettings: await node.MutableDocument<AetheriaVerseHostSettings>(AetheriaStateNode.VerseHostSettingsKey).ReadAsync(),
|
||||
runtimeSession: await node.MutableDocument<AetheriaRuntimeSession>(AetheriaStateNode.RuntimeSessionKey("smoke-runtime")).ReadAsync()));
|
||||
|
|
@ -678,7 +678,7 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether
|
|||
}
|
||||
|
||||
if (catalogSurface?.Schema != "gamecult.eve.surface.v1" ||
|
||||
catalogSurface.Surface.Id != AetheriaCatalogSurfaceProjector.SurfaceId)
|
||||
catalogSurface.Surface.Id != AetheriaEveSurfaceDocuments.CatalogSurfaceId)
|
||||
{
|
||||
throw new InvalidOperationException("Eve catalog surface did not survive flush/reopen.");
|
||||
}
|
||||
|
|
@ -688,7 +688,7 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether
|
|||
eveCommandStatus.AppliedCatalogRefreshes != 1 ||
|
||||
eveCommandStatus.AppliedPlayerSettingsCommands != 2 ||
|
||||
!eveCommandStatus.LastRejectedReason.Contains("Unknown typed Eve command kind", StringComparison.Ordinal) ||
|
||||
operationsSurface?.Surface.Id != AetheriaOperationsSurfaceProjector.SurfaceId ||
|
||||
operationsSurface?.Surface.Id != AetheriaEveSurfaceDocuments.OperationsSurfaceId ||
|
||||
!operationsSurface.Surface.Root.Children.Any(child => child.Id == "aetheria.operations.eveCommandAcceptance") ||
|
||||
operationsSurface.Surface.Root.Children.Any(child => child.Id == "aetheria.operations.commitDrain") ||
|
||||
!operationsSurface.Surface.Root.Children.Any(child => child.Id == "aetheria.operations.runtimeSession"))
|
||||
|
|
@ -704,23 +704,23 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether
|
|||
$"children=[{string.Join(", ", operationsSurface?.Surface.Root.Children.Select(child => child.Id) ?? [])}].");
|
||||
}
|
||||
|
||||
if (advertisement?.ProviderId != AetheriaProviderAdvertisementProjector.ProviderId ||
|
||||
if (advertisement?.ProviderId != AetheriaEveSurfaceDocuments.ProviderId ||
|
||||
advertisement.Surfaces.Length < 7 ||
|
||||
!advertisement.Surfaces.Any(surface => surface.SurfaceId == AetheriaCatalogSurfaceProjector.SurfaceId) ||
|
||||
!advertisement.Surfaces.Any(surface => surface.SurfaceId == AetheriaOperationsSurfaceProjector.SurfaceId) ||
|
||||
!advertisement.Surfaces.Any(surface => surface.SurfaceId == AetheriaPlayerSettingsSurfaceProjector.SurfaceId) ||
|
||||
!advertisement.Surfaces.Any(surface => surface.SurfaceId == AetheriaEveSurfaceDocuments.CatalogSurfaceId) ||
|
||||
!advertisement.Surfaces.Any(surface => surface.SurfaceId == AetheriaEveSurfaceDocuments.OperationsSurfaceId) ||
|
||||
!advertisement.Surfaces.Any(surface => surface.SurfaceId == AetheriaEveSurfaceDocuments.PlayerSettingsSurfaceId) ||
|
||||
!advertisement.Surfaces.Any(surface =>
|
||||
surface.SurfaceId == AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId &&
|
||||
surface.Key == AetheriaProviderAdvertisementProjector.DaemonGameSurfaceKey) ||
|
||||
surface.Key == AetheriaEveSurfaceDocuments.DaemonGameSurfaceKey) ||
|
||||
!advertisement.Surfaces.Any(surface =>
|
||||
surface.SurfaceId == AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId &&
|
||||
surface.Key == AetheriaProviderAdvertisementProjector.DaemonGameTuiSurfaceKey) ||
|
||||
surface.Key == AetheriaEveSurfaceDocuments.DaemonGameTuiSurfaceKey) ||
|
||||
!advertisement.Surfaces.Any(surface =>
|
||||
surface.SurfaceId == AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId &&
|
||||
surface.Key == AetheriaProviderAdvertisementProjector.DaemonEditorSurfaceKey) ||
|
||||
surface.Key == AetheriaEveSurfaceDocuments.DaemonEditorSurfaceKey) ||
|
||||
!advertisement.Surfaces.Any(surface =>
|
||||
surface.SurfaceId == AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId &&
|
||||
surface.Key == AetheriaProviderAdvertisementProjector.DaemonEditorTuiSurfaceKey) ||
|
||||
surface.Key == AetheriaEveSurfaceDocuments.DaemonEditorTuiSurfaceKey) ||
|
||||
!advertisement.Schemas.Contains("aetheria.runtime_session.v1") ||
|
||||
!advertisement.Schemas.Contains(AetheriaRuntimeDaemonSchemas.ProviderAdvertisement) ||
|
||||
!advertisement.Schemas.Contains(AetheriaRuntimeDaemonSchemas.Frame) ||
|
||||
|
|
@ -776,7 +776,7 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether
|
|||
throw new InvalidOperationException("Player settings did not survive flush/reopen.");
|
||||
}
|
||||
|
||||
if (playerSettingsSurface?.Surface.Id != AetheriaPlayerSettingsSurfaceProjector.SurfaceId ||
|
||||
if (playerSettingsSurface?.Surface.Id != AetheriaEveSurfaceDocuments.PlayerSettingsSurfaceId ||
|
||||
!playerSettingsSurface.Surface.Root.Children.Any(child => child.Id == "aetheria.playerSettings.gameplay") ||
|
||||
!playerSettingsSurface.Surface.Root.Children.Any(child => child.Id == "aetheria.playerSettings.graphics"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ if (packageCorporation.Allegiances.Count == 0 || packageCorporation.Allegiances.
|
|||
}
|
||||
|
||||
if (surface?.Schema != "gamecult.eve.surface.v1" ||
|
||||
surface.Surface.Id != AetheriaCatalogSurfaceProjector.SurfaceId)
|
||||
surface.Surface.Id != AetheriaEveSurfaceDocuments.CatalogSurfaceId)
|
||||
{
|
||||
throw new InvalidOperationException("Runtime catalog client did not read the typed Eve surface.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ var items = node.Cache.GetAll<AetheriaItemDefinition>().ToArray();
|
|||
var corporations = node.Cache.GetAll<AetheriaCorporation>().ToArray();
|
||||
var nameFiles = node.Cache.GetAll<AetheriaNameFile>().ToArray();
|
||||
var catalog = await node.RuntimeCatalog().LatestAsync().ConfigureAwait(false);
|
||||
var surface = AetheriaCatalogSurfaceProjector.Build(catalog, DateTimeOffset.UtcNow.ToString("O"));
|
||||
var surface = AetheriaEveSurfaceDocuments.BuildCatalogSurface(catalog, DateTimeOffset.UtcNow.ToString("O"));
|
||||
var tradeValuePolicy = await node.MutableDocument<AetheriaTradeValuePolicy>(AetheriaStateNode.TradeValuePolicyKey).ReadAsync()
|
||||
?? throw new InvalidOperationException("Missing authored trade value policy document.");
|
||||
await RequireTradeValuePolicyEveCommandPersistsAsync();
|
||||
|
|
@ -522,7 +522,7 @@ if (surface.Schema != "gamecult.eve.surface.v1" ||
|
|||
}
|
||||
|
||||
if (publishedSurface.Schema != surface.Schema ||
|
||||
publishedSurface.Surface.Id != AetheriaCatalogSurfaceProjector.SurfaceId ||
|
||||
publishedSurface.Surface.Id != AetheriaEveSurfaceDocuments.CatalogSurfaceId ||
|
||||
publishedSurface.Surface.Root.Kind != "surface")
|
||||
{
|
||||
throw new InvalidOperationException("Published Aetheria catalog Eve surface is not the expected typed surface.");
|
||||
|
|
@ -725,18 +725,18 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
|
|||
"org.gamecult.aetheria.state",
|
||||
"Runtime",
|
||||
"AetheriaRuntimeCultCacheDocumentStore.cs");
|
||||
var playerSettingsSurfaceProjectorPath = Path.Combine(
|
||||
var playerSettingsSurfaceDocumentsPath = Path.Combine(
|
||||
root,
|
||||
"Aetheria.State",
|
||||
"AetheriaPlayerSettingsSurfaceProjector.cs");
|
||||
var catalogSurfaceProjectorPath = Path.Combine(
|
||||
"AetheriaEveSurfaceDocuments.cs");
|
||||
var catalogSurfaceDocumentsPath = Path.Combine(
|
||||
root,
|
||||
"Aetheria.State",
|
||||
"AetheriaCatalogSurfaceProjector.cs");
|
||||
var operationsSurfaceProjectorPath = Path.Combine(
|
||||
"AetheriaEveSurfaceDocuments.cs");
|
||||
var operationsSurfaceDocumentsPath = Path.Combine(
|
||||
root,
|
||||
"Aetheria.State",
|
||||
"AetheriaOperationsSurfaceProjector.cs");
|
||||
"AetheriaEveSurfaceDocuments.cs");
|
||||
|
||||
var manifest = File.Exists(manifestPath)
|
||||
? File.ReadAllText(manifestPath)
|
||||
|
|
@ -768,15 +768,15 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
|
|||
var runtimeCultCacheDocumentStore = File.Exists(runtimeCultCacheDocumentStorePath)
|
||||
? File.ReadAllText(runtimeCultCacheDocumentStorePath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaRuntimeCultCacheDocumentStore.cs is missing.");
|
||||
var playerSettingsSurfaceProjector = File.Exists(playerSettingsSurfaceProjectorPath)
|
||||
? File.ReadAllText(playerSettingsSurfaceProjectorPath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaPlayerSettingsSurfaceProjector.cs is missing.");
|
||||
var catalogSurfaceProjector = File.Exists(catalogSurfaceProjectorPath)
|
||||
? File.ReadAllText(catalogSurfaceProjectorPath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaCatalogSurfaceProjector.cs is missing.");
|
||||
var operationsSurfaceProjector = File.Exists(operationsSurfaceProjectorPath)
|
||||
? File.ReadAllText(operationsSurfaceProjectorPath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaOperationsSurfaceProjector.cs is missing.");
|
||||
var playerSettingsSurfaceDocuments = File.Exists(playerSettingsSurfaceDocumentsPath)
|
||||
? File.ReadAllText(playerSettingsSurfaceDocumentsPath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaEveSurfaceDocuments.cs is missing.");
|
||||
var catalogSurfaceDocuments = File.Exists(catalogSurfaceDocumentsPath)
|
||||
? File.ReadAllText(catalogSurfaceDocumentsPath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaEveSurfaceDocuments.cs is missing.");
|
||||
var operationsSurfaceDocuments = File.Exists(operationsSurfaceDocumentsPath)
|
||||
? File.ReadAllText(operationsSurfaceDocumentsPath)
|
||||
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaEveSurfaceDocuments.cs is missing.");
|
||||
|
||||
var requiredManifestSymbols = new[]
|
||||
{
|
||||
|
|
@ -899,12 +899,12 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
|
|||
"AetheriaRuntimeEveSurfaceStateProjector is dead conversion chaff; AetheriaRuntimeEveSurfaceAdapter owns runtime surface to Eve state lowering.");
|
||||
}
|
||||
|
||||
var surfaceCommandProjectors = string.Join(
|
||||
var surfaceCommandDocuments = string.Join(
|
||||
"\n",
|
||||
runtimeAdapter,
|
||||
playerSettingsSurfaceProjector,
|
||||
catalogSurfaceProjector,
|
||||
operationsSurfaceProjector);
|
||||
playerSettingsSurfaceDocuments,
|
||||
catalogSurfaceDocuments,
|
||||
operationsSurfaceDocuments);
|
||||
if (!runtimeCultCacheDocumentStore.Contains("CultMesh.OperationBindingRecord(command.Operation)", StringComparison.Ordinal) ||
|
||||
!runtimeCultCacheDocumentStore.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) ||
|
||||
!runtimeCultCacheDocumentStore.Contains("routeDescription).ToBinding()", StringComparison.Ordinal) ||
|
||||
|
|
@ -912,7 +912,7 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
|
|||
!runtimeAdapter.Contains("command.SchemaId", StringComparison.Ordinal) ||
|
||||
!runtimeAdapter.Contains("public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) ||
|
||||
!runtimeAdapter.Contains("global::Aetheria.State.Documents.EveSurfaceComponent ToEveSurfaceState(", StringComparison.Ordinal) ||
|
||||
!surfaceCommandProjectors.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) ||
|
||||
!surfaceCommandDocuments.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) ||
|
||||
runtimeCultCacheDocumentStore.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal) ||
|
||||
runtimeAdapter.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal))
|
||||
{
|
||||
|
|
@ -6767,9 +6767,9 @@ static void RequireNoDeadPopupShells(string root)
|
|||
|
||||
static void RequirePlayerSettingsEveSurface(string root)
|
||||
{
|
||||
var projectorPath = Path.Combine(root, "Aetheria.State", "AetheriaPlayerSettingsSurfaceProjector.cs");
|
||||
var surfaceDocumentsPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var bridgePath = Path.Combine(root, "Aetheria.State", "AetheriaEveCommandBridge.cs");
|
||||
var providerPath = Path.Combine(root, "Aetheria.State", "AetheriaProviderAdvertisementProjector.cs");
|
||||
var providerPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var daemonHostPath = Path.Combine(root, "Aetheria.State.Daemon", "Program.cs");
|
||||
var sharedCommandsPath = Path.Combine(
|
||||
root,
|
||||
|
|
@ -6784,13 +6784,13 @@ static void RequirePlayerSettingsEveSurface(string root)
|
|||
"Runtime",
|
||||
"AetheriaRuntimePlayerSettingsSurfaceBuilder.cs");
|
||||
|
||||
if (!File.Exists(projectorPath))
|
||||
if (!File.Exists(surfaceDocumentsPath))
|
||||
{
|
||||
throw new InvalidOperationException("Player settings Eve surface projector is missing.");
|
||||
throw new InvalidOperationException("Player settings Eve surface document is missing.");
|
||||
}
|
||||
|
||||
var projector = File.ReadAllText(projectorPath);
|
||||
var requiredProjectorSymbols = new[]
|
||||
var surfaceDocuments = File.ReadAllText(surfaceDocumentsPath);
|
||||
var requiredSurfaceDocumentSymbols = new[]
|
||||
{
|
||||
"AetheriaRuntimePlayerSettingsCommands.SurfaceId",
|
||||
"AetheriaRuntimePlayerSettingsSurfaceBuilder.Build",
|
||||
|
|
@ -6798,15 +6798,15 @@ static void RequirePlayerSettingsEveSurface(string root)
|
|||
"settings.ActiveRunKey"
|
||||
};
|
||||
|
||||
var missingProjectorSymbols = requiredProjectorSymbols
|
||||
.Where(symbol => !projector.Contains(symbol, StringComparison.Ordinal))
|
||||
var missingSurfaceDocumentSymbols = requiredSurfaceDocumentSymbols
|
||||
.Where(symbol => !surfaceDocuments.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
|
||||
if (missingProjectorSymbols.Length > 0)
|
||||
if (missingSurfaceDocumentSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Player settings Eve surface projector is missing required typed controls: " +
|
||||
string.Join(", ", missingProjectorSymbols));
|
||||
"Player settings Eve surface document is missing required typed controls: " +
|
||||
string.Join(", ", missingSurfaceDocumentSymbols));
|
||||
}
|
||||
|
||||
var bridge = File.Exists(bridgePath)
|
||||
|
|
@ -6828,7 +6828,7 @@ static void RequirePlayerSettingsEveSurface(string root)
|
|||
if (!bridge.Contains("AcceptedPlayerSettingsCommands", StringComparison.Ordinal) ||
|
||||
!bridge.Contains("ExecutePlayerSettingsCommandAsync", StringComparison.Ordinal) ||
|
||||
!bridge.Contains("MutableDocument<EveSurfaceState>(AetheriaStateNode.PlayerSettingsSurfaceKey)", StringComparison.Ordinal) ||
|
||||
!bridge.Contains(".ReplaceAsync(AetheriaPlayerSettingsSurfaceProjector.Build", StringComparison.Ordinal) ||
|
||||
!bridge.Contains(".ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface", StringComparison.Ordinal) ||
|
||||
!bridge.Contains("SetPlayerName", StringComparison.Ordinal) ||
|
||||
!bridge.Contains("command.PlayerSettings.PlayerName", StringComparison.Ordinal))
|
||||
{
|
||||
|
|
@ -6836,7 +6836,8 @@ static void RequirePlayerSettingsEveSurface(string root)
|
|||
"Eve command bridge no longer owns the typed player-settings surface mutation path.");
|
||||
}
|
||||
|
||||
if (!provider.Contains("AetheriaPlayerSettingsSurfaceProjector.SurfaceId", StringComparison.Ordinal) ||
|
||||
if (!provider.Contains("SurfaceId = PlayerSettingsSurfaceId", StringComparison.Ordinal) ||
|
||||
!provider.Contains("Key = PlayerSettingsSurfaceKey", StringComparison.Ordinal) ||
|
||||
!provider.Contains("AetheriaRuntimePlayerSettingsCommands.Refresh", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
|
|
@ -6844,8 +6845,8 @@ static void RequirePlayerSettingsEveSurface(string root)
|
|||
}
|
||||
|
||||
if (!daemonHost.Contains("MutableDocument<EveSurfaceState>(AetheriaStateNode.PlayerSettingsSurfaceKey)", StringComparison.Ordinal) ||
|
||||
!daemonHost.Contains(".ReplaceAsync(AetheriaPlayerSettingsSurfaceProjector.Build", StringComparison.Ordinal) ||
|
||||
!daemonHost.Contains("AetheriaPlayerSettingsSurfaceProjector.Build", StringComparison.Ordinal))
|
||||
!daemonHost.Contains(".ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface", StringComparison.Ordinal) ||
|
||||
!daemonHost.Contains("AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Aetheria.State.Daemon no longer republishes the provider-owned player-settings Eve surface.");
|
||||
|
|
@ -8600,8 +8601,8 @@ static void RequireVerseHostSettingsAuthority(string root)
|
|||
var verseDiscoveryHostPath = Path.Combine(root, "Aetheria.State", "AetheriaVerseDiscoveryHost.cs");
|
||||
var registryPath = Path.Combine(root, "Aetheria.State", "AetheriaDocumentRegistry.cs");
|
||||
var nodePath = Path.Combine(root, "Aetheria.State", "AetheriaStateNode.cs");
|
||||
var providerPath = Path.Combine(root, "Aetheria.State", "AetheriaProviderAdvertisementProjector.cs");
|
||||
var operationsPath = Path.Combine(root, "Aetheria.State", "AetheriaOperationsSurfaceProjector.cs");
|
||||
var providerPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var operationsPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var daemonHostPath = Path.Combine(root, "Aetheria.State.Daemon", "Program.cs");
|
||||
|
||||
var requiredFiles = new[]
|
||||
|
|
@ -8774,7 +8775,7 @@ static void RequireVerseHostSettingsAuthority(string root)
|
|||
"node.MutableDocument<AetheriaVerseHostSettings>(AetheriaStateNode.VerseHostSettingsKey).ReadAsync()",
|
||||
"node.MutableDocument<AetheriaVerseHostSettings>(AetheriaStateNode.VerseHostSettingsKey)",
|
||||
".ReplaceAsync(normalized)",
|
||||
"AetheriaProviderAdvertisementProjector.Build(verseHost, node.StatePath, updatedAtUtc)"
|
||||
"AetheriaEveSurfaceDocuments.BuildProviderAdvertisement(verseHost, node.StatePath, updatedAtUtc)"
|
||||
};
|
||||
var missingDaemonHostSymbols = requiredDaemonHostSymbols
|
||||
.Where(symbol => !daemonHost.Contains(symbol, StringComparison.Ordinal))
|
||||
|
|
@ -9407,7 +9408,7 @@ static void RequireVerseSettingsShellAndBridge(string root)
|
|||
var mainMenuPath = Path.Combine(root, "Assets", "Scripts", "UI", "MainMenu.cs");
|
||||
var commandBridgePath = Path.Combine(root, "Aetheria.State", "AetheriaEveCommandBridge.cs");
|
||||
var acceptanceStatusPath = Path.Combine(root, "Aetheria.State", "Documents", "AetheriaEveCommandAcceptanceStatus.cs");
|
||||
var operationsProjectorPath = Path.Combine(root, "Aetheria.State", "AetheriaOperationsSurfaceProjector.cs");
|
||||
var operationsSurfaceDocumentsPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var daemonHostPath = Path.Combine(root, "Aetheria.State.Daemon", "Program.cs");
|
||||
|
||||
var requiredFiles = new[]
|
||||
|
|
@ -9424,7 +9425,7 @@ static void RequireVerseSettingsShellAndBridge(string root)
|
|||
mainMenuPath,
|
||||
commandBridgePath,
|
||||
acceptanceStatusPath,
|
||||
operationsProjectorPath,
|
||||
operationsSurfaceDocumentsPath,
|
||||
daemonHostPath
|
||||
};
|
||||
|
||||
|
|
@ -9451,7 +9452,7 @@ static void RequireVerseSettingsShellAndBridge(string root)
|
|||
var mainMenu = File.ReadAllText(mainMenuPath);
|
||||
var commandBridge = File.ReadAllText(commandBridgePath);
|
||||
var acceptanceStatus = File.ReadAllText(acceptanceStatusPath);
|
||||
var operationsProjector = File.ReadAllText(operationsProjectorPath);
|
||||
var operationsSurfaceDocuments = File.ReadAllText(operationsSurfaceDocumentsPath);
|
||||
var daemonHost = File.ReadAllText(daemonHostPath);
|
||||
|
||||
var requiredUnityPackageProjectSymbols = new[]
|
||||
|
|
@ -9772,7 +9773,7 @@ static void RequireVerseSettingsShellAndBridge(string root)
|
|||
"node.MutableDocument<AetheriaVerseHostSettings>(AetheriaStateNode.VerseHostSettingsKey)",
|
||||
".ReplaceAsync(normalized)",
|
||||
"node.MutableDocument<EveProviderAdvertisementState>(AetheriaStateNode.ProviderAdvertisementSurfaceKey)",
|
||||
"AetheriaOperationsSurfaceProjector.Build(",
|
||||
"AetheriaEveSurfaceDocuments.BuildOperationsSurface(",
|
||||
"switch (command.Kind)"
|
||||
};
|
||||
var missingBridgeSymbols = requiredBridgeSymbols
|
||||
|
|
@ -9824,7 +9825,7 @@ static void RequireVerseSettingsShellAndBridge(string root)
|
|||
{
|
||||
["Aetheria daemon host"] = daemonHost,
|
||||
["Aetheria Eve command bridge"] = commandBridge,
|
||||
["operations projector"] = operationsProjector
|
||||
["operations surface document"] = operationsSurfaceDocuments
|
||||
};
|
||||
var pendingBeforeApplyUses = pendingBeforeApplyUseSources
|
||||
.Where(source => source.Value.Contains("PendingBeforeApply", StringComparison.Ordinal))
|
||||
|
|
@ -9837,8 +9838,8 @@ static void RequireVerseSettingsShellAndBridge(string root)
|
|||
string.Join(", ", pendingBeforeApplyUses));
|
||||
}
|
||||
|
||||
if (!operationsProjector.Contains("Verse Host Commands", StringComparison.Ordinal) ||
|
||||
!operationsProjector.Contains("AppliedVerseHostCommands", StringComparison.Ordinal))
|
||||
if (!operationsSurfaceDocuments.Contains("Verse Host Commands", StringComparison.Ordinal) ||
|
||||
!operationsSurfaceDocuments.Contains("AppliedVerseHostCommands", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Operations surface no longer projects Verse-host Eve command counts.");
|
||||
|
|
@ -10538,7 +10539,7 @@ static void RequireDaemonVersePublication(string root)
|
|||
var documentRegistryPath = Path.Combine(root, "Aetheria.State", "AetheriaDocumentRegistry.cs");
|
||||
var stateNodePath = Path.Combine(root, "Aetheria.State", "AetheriaStateNode.cs");
|
||||
var runtimeEveSurfaceAdapterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeEveSurfaceAdapter.cs");
|
||||
var providerAdvertisementPath = Path.Combine(root, "Aetheria.State", "AetheriaProviderAdvertisementProjector.cs");
|
||||
var providerAdvertisementPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var documentStorePath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeCultCacheDocumentStore.cs");
|
||||
var boundaryPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeStateBoundary.cs");
|
||||
var testsPath = Path.Combine(root, "Assets", "Scripts", "Tests", "DaemonRuntimeDocumentTests.cs");
|
||||
|
|
@ -11095,9 +11096,9 @@ static void RequireDaemonVersePublication(string root)
|
|||
"node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey)",
|
||||
"node.MutableDocument<EveSurfaceState>(AetheriaStateNode.PlayerSettingsSurfaceKey)",
|
||||
"node.MutableDocument<EveProviderAdvertisementState>(AetheriaStateNode.ProviderAdvertisementSurfaceKey)",
|
||||
"AetheriaProviderAdvertisementProjector.Build(verseHost, node.StatePath, updatedAtUtc)",
|
||||
"AetheriaOperationsSurfaceProjector.Build(eveStatus, verseHost, runtimeSession)",
|
||||
"AetheriaPlayerSettingsSurfaceProjector.Build(playerSettings, playerSettingsUpdatedAt)",
|
||||
"AetheriaEveSurfaceDocuments.BuildProviderAdvertisement(verseHost, node.StatePath, updatedAtUtc)",
|
||||
"AetheriaEveSurfaceDocuments.BuildOperationsSurface(eveStatus, verseHost, runtimeSession)",
|
||||
"AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface(playerSettings, playerSettingsUpdatedAt)",
|
||||
"Role = \"verse-daemon\"",
|
||||
"Console.CancelKeyPress",
|
||||
"Aetheria Verse daemon is running"
|
||||
|
|
@ -11701,13 +11702,13 @@ static void RequireUnityRuntimeCatalogClientUsesManagedDocument(string root)
|
|||
|
||||
static void RequireCatalogSurfaceUsesManagedRuntimeCatalog(string root)
|
||||
{
|
||||
var projectorPath = Path.Combine(root, "Aetheria.State", "AetheriaCatalogSurfaceProjector.cs");
|
||||
var surfaceDocumentsPath = Path.Combine(root, "Aetheria.State", "AetheriaEveSurfaceDocuments.cs");
|
||||
var bridgePath = Path.Combine(root, "Aetheria.State", "AetheriaEveCommandBridge.cs");
|
||||
var importPath = Path.Combine(root, "Aetheria.State.Import", "Program.cs");
|
||||
var legacySnapshotPath = Path.Combine(root, "Aetheria.State", "AetheriaCatalogSnapshot.cs");
|
||||
var projector = File.Exists(projectorPath)
|
||||
? File.ReadAllText(projectorPath)
|
||||
: throw new InvalidOperationException("Cannot verify catalog surface projector; AetheriaCatalogSurfaceProjector.cs is missing.");
|
||||
var surfaceDocuments = File.Exists(surfaceDocumentsPath)
|
||||
? File.ReadAllText(surfaceDocumentsPath)
|
||||
: throw new InvalidOperationException("Cannot verify catalog surface document; AetheriaEveSurfaceDocuments.cs is missing.");
|
||||
var bridge = File.Exists(bridgePath)
|
||||
? File.ReadAllText(bridgePath)
|
||||
: throw new InvalidOperationException("Cannot verify Eve command bridge catalog refresh; AetheriaEveCommandBridge.cs is missing.");
|
||||
|
|
@ -11715,25 +11716,26 @@ static void RequireCatalogSurfaceUsesManagedRuntimeCatalog(string root)
|
|||
? File.ReadAllText(importPath)
|
||||
: throw new InvalidOperationException("Cannot verify legacy catalog import; Aetheria.State.Import/Program.cs is missing.");
|
||||
|
||||
var requiredProjectorSymbols = new[]
|
||||
var requiredSurfaceDocumentSymbols = new[]
|
||||
{
|
||||
"Build(AetheriaRuntimeCatalogSnapshot catalog",
|
||||
"BuildCatalogSurface(",
|
||||
"AetheriaRuntimeCatalogSnapshot catalog",
|
||||
"item.ItemKey",
|
||||
"corporation.CorporationKey",
|
||||
"catalog.GetManufacturer(item)",
|
||||
"catalog.GetNameFile(corporation)"
|
||||
};
|
||||
var missingProjectorSymbols = requiredProjectorSymbols
|
||||
.Where(symbol => !projector.Contains(symbol, StringComparison.Ordinal))
|
||||
var missingSurfaceDocumentSymbols = requiredSurfaceDocumentSymbols
|
||||
.Where(symbol => !surfaceDocuments.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingProjectorSymbols.Length > 0)
|
||||
if (missingSurfaceDocumentSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Catalog Eve surface must project from the managed runtime catalog document: " +
|
||||
string.Join(", ", missingProjectorSymbols));
|
||||
"Catalog Eve surface must build from the managed runtime catalog document: " +
|
||||
string.Join(", ", missingSurfaceDocumentSymbols));
|
||||
}
|
||||
|
||||
if (projector.Contains("Build(AetheriaCatalogSnapshot catalog", StringComparison.Ordinal))
|
||||
if (surfaceDocuments.Contains("Build(AetheriaCatalogSnapshot catalog", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Catalog Eve surface still depends on the legacy authored catalog snapshot instead of the managed runtime catalog document.");
|
||||
|
|
@ -11748,7 +11750,7 @@ static void RequireCatalogSurfaceUsesManagedRuntimeCatalog(string root)
|
|||
var requiredBridgeSymbols = new[]
|
||||
{
|
||||
"var catalog = await node.RuntimeCatalog().LatestAsync().ConfigureAwait(false);",
|
||||
"AetheriaCatalogSurfaceProjector.Build(catalog, command.IssuedAtUtc)"
|
||||
"AetheriaEveSurfaceDocuments.BuildCatalogSurface(catalog, command.IssuedAtUtc)"
|
||||
};
|
||||
var missingBridgeSymbols = requiredBridgeSymbols
|
||||
.Where(symbol => !bridge.Contains(symbol, StringComparison.Ordinal))
|
||||
|
|
|
|||
|
|
@ -1,121 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Aetheria.State.Documents;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
|
||||
namespace Aetheria.State;
|
||||
|
||||
public static class AetheriaCatalogSurfaceProjector
|
||||
{
|
||||
public const string SurfaceKey = "eve:surface:aetheria.catalog.operator";
|
||||
public const string SurfaceId = AetheriaRuntimeCatalogCommands.SurfaceId;
|
||||
|
||||
public static EveSurfaceState Build(AetheriaRuntimeCatalogSnapshot catalog, string updatedAtUtc, long version = 1)
|
||||
{
|
||||
var tradeItems = catalog.TradeItems.Take(12).Select(item =>
|
||||
Row(
|
||||
$"item.{SafeId(item.ItemKey)}",
|
||||
("name", item.Name),
|
||||
("manufacturer", catalog.GetManufacturer(item)?.Name ?? "GameCult"),
|
||||
("price", item.Price.ToString("N0")),
|
||||
("size", item.ShapeWidth > 0 && item.ShapeHeight > 0 ? $"{item.ShapeWidth}x{item.ShapeHeight}" : "")))
|
||||
.ToArray();
|
||||
|
||||
var corporations = catalog.Corporations.Take(12).Select(corporation =>
|
||||
Row(
|
||||
$"corporation.{SafeId(corporation.CorporationKey)}",
|
||||
("name", corporation.Name),
|
||||
("short", corporation.ShortName),
|
||||
("names", catalog.GetNameFile(corporation)?.Name ?? ""),
|
||||
("influence", corporation.InfluenceDistance.ToString())))
|
||||
.ToArray();
|
||||
var refreshCommand = GameCult.Mesh.CultMesh.OperationBindingRecord(
|
||||
GameCult.Mesh.CultMesh.OperationBinding(
|
||||
AetheriaRuntimeCatalogCommands.Refresh,
|
||||
label: "Refresh",
|
||||
routeHint: new GameCult.Mesh.CultMeshRouteHint(
|
||||
GameCult.Mesh.CultMeshLocalityKind.Automatic,
|
||||
"cultmesh")));
|
||||
|
||||
return new EveSurfaceState
|
||||
{
|
||||
ProviderId = "aetheria",
|
||||
ProviderKind = "game.runtime",
|
||||
Title = "Aetheria Catalog",
|
||||
Version = version,
|
||||
UpdatedAtUtc = updatedAtUtc,
|
||||
Surface = new EveSurface
|
||||
{
|
||||
Id = SurfaceId,
|
||||
Root = Node(
|
||||
"aetheria.catalog.root",
|
||||
"surface",
|
||||
[],
|
||||
Node(
|
||||
"aetheria.catalog.summary",
|
||||
"grid",
|
||||
[("columns", "6")],
|
||||
Metric("summary.items", "Items", catalog.Items.Count.ToString()),
|
||||
Metric("summary.trade", "Trade Items", catalog.TradeItems.Count().ToString()),
|
||||
Metric("summary.equipment", "Equipment", catalog.EquipmentItems.Count().ToString()),
|
||||
Metric("summary.behaviors", "Behavior Kinds", catalog.Items.SelectMany(item => item.BehaviorKinds).Distinct().Count().ToString()),
|
||||
Metric("summary.corporations", "Corporations", catalog.Corporations.Count.ToString()),
|
||||
Metric("summary.nameFiles", "Name Files", catalog.NameFiles.Count.ToString())),
|
||||
Node(
|
||||
"aetheria.catalog.trade",
|
||||
"card",
|
||||
[("title", "Trade Catalog")],
|
||||
Node("aetheria.catalog.trade.rows", "inspector.kv", [], tradeItems)),
|
||||
Node(
|
||||
"aetheria.catalog.corporations",
|
||||
"card",
|
||||
[("title", "Corporations")],
|
||||
Node("aetheria.catalog.corporation.rows", "inspector.kv", [], corporations)))
|
||||
},
|
||||
Commands =
|
||||
[
|
||||
new EveCommandTemplate
|
||||
{
|
||||
Command = refreshCommand.OperationId,
|
||||
Label = refreshCommand.Label,
|
||||
Transport = refreshCommand.RouteDescription,
|
||||
SchemaId = refreshCommand.SchemaId,
|
||||
RouteKind = refreshCommand.RouteKind,
|
||||
RouteDescription = refreshCommand.RouteDescription
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Metric(string id, string label, string value)
|
||||
{
|
||||
return Node(id, "metric", [("label", label), ("value", value)]);
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Row(string id, params (string Key, string Value)[] props)
|
||||
{
|
||||
return Node(id, "row", props);
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Node(
|
||||
string id,
|
||||
string kind,
|
||||
(string Key, string Value)[] props,
|
||||
params EveSurfaceComponent[] children)
|
||||
{
|
||||
return new EveSurfaceComponent
|
||||
{
|
||||
Id = id,
|
||||
Kind = kind,
|
||||
Props = props.ToDictionary(prop => prop.Key, prop => prop.Value),
|
||||
Children = children
|
||||
};
|
||||
}
|
||||
|
||||
private static string SafeId(string value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value)
|
||||
? "empty"
|
||||
: new string(value.Select(character => char.IsLetterOrDigit(character) ? character : '.').ToArray());
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ public static class AetheriaEveCommandBridge
|
|||
case AetheriaRuntimeEveCommandKind.CatalogRefresh:
|
||||
var catalog = await node.RuntimeCatalog().LatestAsync().ConfigureAwait(false);
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.CatalogSurfaceKey)
|
||||
.ReplaceAsync(AetheriaCatalogSurfaceProjector.Build(catalog, command.IssuedAtUtc))
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildCatalogSurface(catalog, command.IssuedAtUtc))
|
||||
.ConfigureAwait(false);
|
||||
report.AcceptedCatalogRefreshes++;
|
||||
break;
|
||||
|
|
@ -62,7 +62,7 @@ public static class AetheriaEveCommandBridge
|
|||
var verseHostSettings = await node.MutableDocument<AetheriaVerseHostSettings>(AetheriaStateNode.VerseHostSettingsKey).ReadAsync().ConfigureAwait(false);
|
||||
var runtimeSession = await node.MutableDocument<AetheriaRuntimeSession>(AetheriaStateNode.RuntimeSessionKey(eveStatus.RuntimeId)).ReadAsync().ConfigureAwait(false);
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaOperationsSurfaceProjector.Build(
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildOperationsSurface(
|
||||
eveStatus,
|
||||
verseHostSettings,
|
||||
runtimeSession))
|
||||
|
|
@ -123,7 +123,7 @@ public static class AetheriaEveCommandBridge
|
|||
{
|
||||
if (!string.Equals(command.Schema, CommandSchema, StringComparison.Ordinal))
|
||||
return $"Unexpected Eve command schema '{command.Schema}'.";
|
||||
if (!string.Equals(command.ProviderId, AetheriaProviderAdvertisementProjector.ProviderId, StringComparison.Ordinal))
|
||||
if (!string.Equals(command.ProviderId, AetheriaEveSurfaceDocuments.ProviderId, StringComparison.Ordinal))
|
||||
return $"Unexpected Eve provider '{command.ProviderId}'.";
|
||||
if (command.Kind == AetheriaRuntimeEveCommandKind.Unknown)
|
||||
return $"Unknown typed Eve command kind for surface '{command.SurfaceId}' command '{command.Command}'.";
|
||||
|
|
@ -189,7 +189,7 @@ public static class AetheriaEveCommandBridge
|
|||
}
|
||||
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.PlayerSettingsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaPlayerSettingsSurfaceProjector.Build(settings, command.IssuedAtUtc))
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface(settings, command.IssuedAtUtc))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
|
@ -283,13 +283,13 @@ public static class AetheriaEveCommandBridge
|
|||
var runtimeSession = await node.MutableDocument<AetheriaRuntimeSession>(AetheriaStateNode.RuntimeSessionKey(eveStatus.RuntimeId)).ReadAsync().ConfigureAwait(false);
|
||||
|
||||
await node.MutableDocument<EveSurfaceState>(AetheriaStateNode.OperationsSurfaceKey)
|
||||
.ReplaceAsync(AetheriaOperationsSurfaceProjector.Build(
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildOperationsSurface(
|
||||
eveStatus,
|
||||
normalized,
|
||||
runtimeSession))
|
||||
.ConfigureAwait(false);
|
||||
await node.MutableDocument<EveProviderAdvertisementState>(AetheriaStateNode.ProviderAdvertisementSurfaceKey)
|
||||
.ReplaceAsync(AetheriaProviderAdvertisementProjector.Build(normalized, node.StatePath, command.IssuedAtUtc))
|
||||
.ReplaceAsync(AetheriaEveSurfaceDocuments.BuildProviderAdvertisement(normalized, node.StatePath, command.IssuedAtUtc))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
|
|
|||
525
Aetheria.State/AetheriaEveSurfaceDocuments.cs
Normal file
525
Aetheria.State/AetheriaEveSurfaceDocuments.cs
Normal file
|
|
@ -0,0 +1,525 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aetheria.State.Documents;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
using GameCult.Mesh;
|
||||
|
||||
namespace Aetheria.State;
|
||||
|
||||
public static class AetheriaEveSurfaceDocuments
|
||||
{
|
||||
public const string ProviderId = "aetheria";
|
||||
public const string ProviderAdvertisementKey = "eve:provider:aetheria";
|
||||
public const string CatalogSurfaceKey = "eve:surface:aetheria.catalog.operator";
|
||||
public const string OperationsSurfaceKey = "eve:surface:aetheria.operations";
|
||||
public const string PlayerSettingsSurfaceKey = "eve:surface:aetheria.player_settings";
|
||||
public const string DaemonGameSurfaceKey = "eve:surface:aetheria.daemon.game";
|
||||
public const string DaemonGameTuiSurfaceKey = "eve:surface:aetheria.daemon.game.tui";
|
||||
public const string DaemonEditorSurfaceKey = "eve:surface:aetheria.daemon.editor";
|
||||
public const string DaemonEditorTuiSurfaceKey = "eve:surface:aetheria.daemon.editor.tui";
|
||||
|
||||
public const string CatalogSurfaceId = AetheriaRuntimeCatalogCommands.SurfaceId;
|
||||
public const string OperationsSurfaceId = AetheriaRuntimeOperationsCommands.SurfaceId;
|
||||
public const string PlayerSettingsSurfaceId = AetheriaRuntimePlayerSettingsCommands.SurfaceId;
|
||||
|
||||
private const string DaemonCommandBoundaryId = "aetheria.daemon.commands";
|
||||
private const string DaemonRecordTransport = "cultmesh-record";
|
||||
|
||||
public static EveSurfaceState BuildCatalogSurface(
|
||||
AetheriaRuntimeCatalogSnapshot catalog,
|
||||
string updatedAtUtc,
|
||||
long version = 1)
|
||||
{
|
||||
var tradeItems = catalog.TradeItems.Take(12).Select(item =>
|
||||
Row(
|
||||
$"item.{SafeId(item.ItemKey)}",
|
||||
("name", item.Name),
|
||||
("manufacturer", catalog.GetManufacturer(item)?.Name ?? "GameCult"),
|
||||
("price", item.Price.ToString("N0")),
|
||||
("size", item.ShapeWidth > 0 && item.ShapeHeight > 0 ? $"{item.ShapeWidth}x{item.ShapeHeight}" : "")))
|
||||
.ToArray();
|
||||
|
||||
var corporations = catalog.Corporations.Take(12).Select(corporation =>
|
||||
Row(
|
||||
$"corporation.{SafeId(corporation.CorporationKey)}",
|
||||
("name", corporation.Name),
|
||||
("short", corporation.ShortName),
|
||||
("names", catalog.GetNameFile(corporation)?.Name ?? ""),
|
||||
("influence", corporation.InfluenceDistance.ToString())))
|
||||
.ToArray();
|
||||
var refreshCommand = CultMesh.OperationBindingRecord(
|
||||
CultMesh.OperationBinding(
|
||||
AetheriaRuntimeCatalogCommands.Refresh,
|
||||
label: "Refresh",
|
||||
routeHint: new CultMeshRouteHint(
|
||||
CultMeshLocalityKind.Automatic,
|
||||
"cultmesh")));
|
||||
|
||||
return new EveSurfaceState
|
||||
{
|
||||
ProviderId = ProviderId,
|
||||
ProviderKind = "game.runtime",
|
||||
Title = "Aetheria Catalog",
|
||||
Version = version,
|
||||
UpdatedAtUtc = updatedAtUtc,
|
||||
Surface = new EveSurface
|
||||
{
|
||||
Id = CatalogSurfaceId,
|
||||
Root = Node(
|
||||
"aetheria.catalog.root",
|
||||
"surface",
|
||||
[],
|
||||
Node(
|
||||
"aetheria.catalog.summary",
|
||||
"grid",
|
||||
[("columns", "6")],
|
||||
Metric("summary.items", "Items", catalog.Items.Count.ToString()),
|
||||
Metric("summary.trade", "Trade Items", catalog.TradeItems.Count().ToString()),
|
||||
Metric("summary.equipment", "Equipment", catalog.EquipmentItems.Count().ToString()),
|
||||
Metric("summary.behaviors", "Behavior Kinds", catalog.Items.SelectMany(item => item.BehaviorKinds).Distinct().Count().ToString()),
|
||||
Metric("summary.corporations", "Corporations", catalog.Corporations.Count.ToString()),
|
||||
Metric("summary.nameFiles", "Name Files", catalog.NameFiles.Count.ToString())),
|
||||
Node(
|
||||
"aetheria.catalog.trade",
|
||||
"card",
|
||||
[("title", "Trade Catalog")],
|
||||
Node("aetheria.catalog.trade.rows", "inspector.kv", [], tradeItems)),
|
||||
Node(
|
||||
"aetheria.catalog.corporations",
|
||||
"card",
|
||||
[("title", "Corporations")],
|
||||
Node("aetheria.catalog.corporation.rows", "inspector.kv", [], corporations)))
|
||||
},
|
||||
Commands =
|
||||
[
|
||||
new EveCommandTemplate
|
||||
{
|
||||
Command = refreshCommand.OperationId,
|
||||
Label = refreshCommand.Label,
|
||||
Transport = refreshCommand.RouteDescription,
|
||||
SchemaId = refreshCommand.SchemaId,
|
||||
RouteKind = refreshCommand.RouteKind,
|
||||
RouteDescription = refreshCommand.RouteDescription
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
public static EveSurfaceState BuildOperationsSurface(
|
||||
AetheriaEveCommandAcceptanceStatus? eveCommandStatus = null,
|
||||
AetheriaVerseHostSettings? verseHostSettings = null,
|
||||
AetheriaRuntimeSession? runtimeSession = null,
|
||||
long version = 1)
|
||||
{
|
||||
var normalizedVerseHost = AetheriaVerseHostSettingsNormalizer.Normalize(verseHostSettings);
|
||||
var updatedAtUtc = LatestTimestamp(
|
||||
eveCommandStatus?.LastPollAtUtc,
|
||||
normalizedVerseHost.LastUpdatedAtUtc,
|
||||
runtimeSession?.LastSeenAtUtc);
|
||||
var refreshCommand = CultMesh.OperationBindingRecord(
|
||||
CultMesh.OperationBinding(
|
||||
AetheriaRuntimeOperationsCommands.Refresh,
|
||||
label: "Refresh",
|
||||
routeHint: new CultMeshRouteHint(
|
||||
CultMeshLocalityKind.Automatic,
|
||||
"cultmesh")));
|
||||
return new EveSurfaceState
|
||||
{
|
||||
ProviderId = ProviderId,
|
||||
ProviderKind = "game.runtime",
|
||||
Title = "Aetheria Operations",
|
||||
Version = version,
|
||||
UpdatedAtUtc = updatedAtUtc,
|
||||
Surface = new EveSurface
|
||||
{
|
||||
Id = OperationsSurfaceId,
|
||||
Root = Node(
|
||||
"aetheria.operations.root",
|
||||
"surface",
|
||||
[],
|
||||
Node(
|
||||
"aetheria.operations.eveCommandAcceptance",
|
||||
"card",
|
||||
[("title", "Eve Request Acceptance")],
|
||||
Metric("eveCommandAcceptance.status", "Status", eveCommandStatus?.Status ?? "missing"),
|
||||
Metric("eveCommandAcceptance.observed", "Observed Before Accept", (eveCommandStatus?.ObservedBeforeAccept ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.accepted", "Commands Accepted", (eveCommandStatus?.CommandsAccepted ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.rejected", "Commands Rejected", (eveCommandStatus?.CommandsRejected ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.catalogRefreshes", "Catalog Refreshes", (eveCommandStatus?.AppliedCatalogRefreshes ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.operationsRefreshes", "Operations Refreshes", (eveCommandStatus?.AppliedOperationsRefreshes ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.playerSettings", "Player Settings Commands", (eveCommandStatus?.AppliedPlayerSettingsCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.inputSettings", "Input Settings Commands", (eveCommandStatus?.AppliedInputSettingsCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.loadoutTemplates", "Loadout Template Commands", (eveCommandStatus?.AppliedLoadoutTemplateCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.verseHost", "Verse Host Commands", (eveCommandStatus?.AppliedVerseHostCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.failures", "Consecutive Failures", (eveCommandStatus?.ConsecutiveFailures ?? 0).ToString()),
|
||||
Row(
|
||||
"eveCommandAcceptance.last",
|
||||
("runtime", eveCommandStatus?.RuntimeId ?? ""),
|
||||
("lastPoll", eveCommandStatus?.LastPollAtUtc ?? ""),
|
||||
("lastAccepted", eveCommandStatus?.LastAcceptedAtUtc ?? ""),
|
||||
("lastRejected", eveCommandStatus?.LastRejectedCommand ?? ""),
|
||||
("rejectedReason", eveCommandStatus?.LastRejectedReason ?? ""),
|
||||
("error", eveCommandStatus?.LastError ?? ""))),
|
||||
Node(
|
||||
"aetheria.operations.verseHost",
|
||||
"card",
|
||||
[("title", "Verse Host")],
|
||||
Metric("verseHost.visibility", "Visibility", normalizedVerseHost.Visibility),
|
||||
Metric("verseHost.service", "Service", normalizedVerseHost.ServiceId),
|
||||
Metric("verseHost.verse", "Verse", normalizedVerseHost.VerseId),
|
||||
Row(
|
||||
"verseHost.identity",
|
||||
("rootVerse", normalizedVerseHost.RootVerse),
|
||||
("canonicalService", normalizedVerseHost.CanonicalService),
|
||||
("locatedService", normalizedVerseHost.LocatedService),
|
||||
("cultMeshAddress", normalizedVerseHost.CultMeshAddress))),
|
||||
Node(
|
||||
"aetheria.operations.runtimeSession",
|
||||
"card",
|
||||
[("title", "Runtime Session")],
|
||||
Metric("runtimeSession.status", "Status", runtimeSession?.Status ?? "missing"),
|
||||
Metric("runtimeSession.role", "Role", runtimeSession?.Role ?? ""),
|
||||
Row(
|
||||
"runtimeSession.last",
|
||||
("runtime", runtimeSession?.RuntimeId ?? ""),
|
||||
("started", runtimeSession?.StartedAtUtc ?? ""),
|
||||
("lastSeen", runtimeSession?.LastSeenAtUtc ?? ""))))
|
||||
},
|
||||
Commands =
|
||||
[
|
||||
new EveCommandTemplate
|
||||
{
|
||||
Command = refreshCommand.OperationId,
|
||||
Label = refreshCommand.Label,
|
||||
Transport = refreshCommand.RouteDescription,
|
||||
SchemaId = refreshCommand.SchemaId,
|
||||
RouteKind = refreshCommand.RouteKind,
|
||||
RouteDescription = refreshCommand.RouteDescription
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
public static EveSurfaceState BuildPlayerSettingsSurface(
|
||||
AetheriaPlayerSettings? settings,
|
||||
string updatedAtUtc,
|
||||
long version = 1)
|
||||
{
|
||||
settings ??= new AetheriaPlayerSettings();
|
||||
var gameplay = settings.Gameplay ?? new AetheriaPlayerGameplaySettings();
|
||||
var graphics = settings.Graphics ?? new AetheriaPlayerGraphicsSettings();
|
||||
var publishedAtUtc = !string.IsNullOrWhiteSpace(settings.LastUpdatedAtUtc)
|
||||
? settings.LastUpdatedAtUtc
|
||||
: updatedAtUtc;
|
||||
|
||||
var surface = AetheriaRuntimePlayerSettingsSurfaceBuilder.Build(
|
||||
new AetheriaRuntimePlayerSettingsSurfaceState(
|
||||
settings.PlayerName,
|
||||
settings.TutorialPassed,
|
||||
settings.ActiveRunKey,
|
||||
gameplay.TemperatureUnit,
|
||||
gameplay.SignificantDigits,
|
||||
graphics.NebulaQuality,
|
||||
graphics.ShowAsteroidsInMinimap,
|
||||
publishedAtUtc),
|
||||
version);
|
||||
|
||||
return new EveSurfaceState
|
||||
{
|
||||
ProviderId = surface.ProviderId,
|
||||
ProviderKind = surface.ProviderKind,
|
||||
Title = surface.Title,
|
||||
Version = surface.Version,
|
||||
UpdatedAtUtc = surface.UpdatedAtUtc,
|
||||
Surface = new EveSurface
|
||||
{
|
||||
Id = surface.Surface.Id,
|
||||
Root = ConvertComponent(surface.Surface.Root),
|
||||
Styles = surface.Surface.Styles
|
||||
.Select(style => new EveStyleToken
|
||||
{
|
||||
Name = style.Name,
|
||||
Value = style.Value
|
||||
})
|
||||
.ToArray()
|
||||
},
|
||||
Commands = surface.Commands
|
||||
.Select(command =>
|
||||
{
|
||||
var record = CultMesh.OperationBindingRecord(command.Operation);
|
||||
return new EveCommandTemplate
|
||||
{
|
||||
Command = record.OperationId,
|
||||
Label = record.Label,
|
||||
Transport = record.RouteDescription,
|
||||
SchemaId = record.SchemaId,
|
||||
RouteKind = record.RouteKind,
|
||||
RouteDescription = record.RouteDescription
|
||||
};
|
||||
})
|
||||
.ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
public static EveProviderAdvertisementState BuildProviderAdvertisement(
|
||||
AetheriaVerseHostSettings settings,
|
||||
string statePath,
|
||||
string updatedAtUtc)
|
||||
{
|
||||
var normalized = AetheriaVerseHostSettingsNormalizer.Normalize(settings);
|
||||
return new EveProviderAdvertisementState
|
||||
{
|
||||
ProviderId = ProviderId,
|
||||
ServiceId = normalized.ServiceId,
|
||||
VerseId = normalized.VerseId,
|
||||
RootVerse = normalized.RootVerse,
|
||||
CanonicalService = normalized.CanonicalService,
|
||||
LocatedService = normalized.LocatedService,
|
||||
CultMeshAddress = normalized.CultMeshAddress,
|
||||
Title = normalized.Title,
|
||||
Kind = "game.runtime",
|
||||
UpdatedAtUtc = updatedAtUtc,
|
||||
Freshness = new EveProviderFreshness
|
||||
{
|
||||
State = "fresh",
|
||||
LastSeenAtUtc = updatedAtUtc,
|
||||
MaxAgeMs = 15000
|
||||
},
|
||||
Schemas =
|
||||
[
|
||||
"aetheria.world_state.v1",
|
||||
"aetheria.item_definition.v1",
|
||||
"aetheria.corporation.v2",
|
||||
"aetheria.name_file.v2",
|
||||
"aetheria.trade_value_policy.v1",
|
||||
"aetheria.player_settings.v1",
|
||||
"aetheria.loadout_template.v1",
|
||||
"aetheria.run_state.v1",
|
||||
"aetheria.zone_state.v1",
|
||||
"aetheria.entity_snapshot.v1",
|
||||
"aetheria.verse_host_settings.v1",
|
||||
"aetheria.runtime_session.v1",
|
||||
"aetheria.eve_command_acceptance_status.v1",
|
||||
"gamecult.eve.surface.v1",
|
||||
"gamecult.eve.command.v1",
|
||||
AetheriaRuntimeDaemonSchemas.ProviderAdvertisement,
|
||||
AetheriaRuntimeDaemonSchemas.Frame,
|
||||
AetheriaRuntimeDaemonSchemas.SoaView,
|
||||
AetheriaRuntimeDaemonSchemas.Health,
|
||||
AetheriaRuntimeDaemonSchemas.CommandBoundary,
|
||||
AetheriaRuntimeDaemonSchemas.GameSurface,
|
||||
AetheriaRuntimeDaemonSchemas.EditorSurface,
|
||||
AetheriaRuntimeDaemonSchemas.Command
|
||||
],
|
||||
Witnesses =
|
||||
[
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = "cultcache",
|
||||
Ref = statePath,
|
||||
Summary = "Aetheria typed CultCache state file"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement.ToString(),
|
||||
Summary = "Aetheria daemon-owned provider advertisement record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest.ToString(),
|
||||
Summary = "Aetheria daemon latest simulation frame record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonSoaViewLatest.ToString(),
|
||||
Summary = "Aetheria daemon latest SoA view record for thin clients"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonHealth.ToString(),
|
||||
Summary = "Aetheria daemon health record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary.ToString(),
|
||||
Summary = "Aetheria daemon typed command boundary record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonGameSurface.ToString(),
|
||||
Summary = "Aetheria daemon game Eve GUI surface record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface.ToString(),
|
||||
Summary = "Aetheria daemon game Eve TUI surface record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface.ToString(),
|
||||
Summary = "Aetheria daemon editor Eve GUI surface record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface.ToString(),
|
||||
Summary = "Aetheria daemon editor Eve TUI surface record"
|
||||
}
|
||||
],
|
||||
Surfaces =
|
||||
[
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = CatalogSurfaceId,
|
||||
Key = CatalogSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = OperationsSurfaceId,
|
||||
Key = OperationsSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = PlayerSettingsSurfaceId,
|
||||
Key = PlayerSettingsSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId,
|
||||
Key = DaemonGameSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId,
|
||||
Key = DaemonGameTuiSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId,
|
||||
Key = DaemonEditorSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId,
|
||||
Key = DaemonEditorTuiSurfaceKey
|
||||
}
|
||||
],
|
||||
Commands =
|
||||
[
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = DaemonCommandBoundaryId,
|
||||
Transport = "cultmesh",
|
||||
Summary = "Aetheria daemon typed command boundary"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimeCatalogCommands.Refresh,
|
||||
Summary = "Refresh catalog state"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimeOperationsCommands.Refresh,
|
||||
Summary = "Refresh operations state"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.Refresh,
|
||||
Summary = "Refresh player settings state"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.CycleTemperatureUnit,
|
||||
Summary = "Cycle the typed player temperature unit"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.DecrementSignificantDigits,
|
||||
Summary = "Decrease typed player significant digits"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.IncrementSignificantDigits,
|
||||
Summary = "Increase typed player significant digits"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.CycleNebulaQuality,
|
||||
Summary = "Cycle typed player nebula quality"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.ToggleShowAsteroidsInMinimap,
|
||||
Summary = "Toggle typed player minimap asteroid visibility"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
private static string LatestTimestamp(params string?[] timestamps)
|
||||
{
|
||||
var latest = "";
|
||||
foreach (var timestamp in timestamps)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(timestamp) &&
|
||||
(string.IsNullOrWhiteSpace(latest) || string.CompareOrdinal(timestamp, latest) > 0))
|
||||
{
|
||||
latest = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Metric(string id, string label, string value)
|
||||
{
|
||||
return Node(id, "metric", [("label", label), ("value", value)]);
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Row(string id, params (string Key, string Value)[] props)
|
||||
{
|
||||
return Node(id, "row", props);
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Node(
|
||||
string id,
|
||||
string kind,
|
||||
(string Key, string Value)[] props,
|
||||
params EveSurfaceComponent[] children)
|
||||
{
|
||||
return new EveSurfaceComponent
|
||||
{
|
||||
Id = id,
|
||||
Kind = kind,
|
||||
Props = props.ToDictionary(prop => prop.Key, prop => prop.Value),
|
||||
Children = children
|
||||
};
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent ConvertComponent(AetheriaRuntimeSurfaceComponent component)
|
||||
{
|
||||
return new EveSurfaceComponent
|
||||
{
|
||||
Id = component.Id,
|
||||
Kind = component.Kind,
|
||||
Props = new Dictionary<string, string>(component.Props, StringComparer.Ordinal),
|
||||
Children = component.Children.Select(ConvertComponent).ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
private static string SafeId(string value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value)
|
||||
? "empty"
|
||||
: new string(value.Select(character => char.IsLetterOrDigit(character) ? character : '.').ToArray());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
using Aetheria.State.Documents;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
|
||||
namespace Aetheria.State;
|
||||
|
||||
public static class AetheriaOperationsSurfaceProjector
|
||||
{
|
||||
public const string SurfaceKey = "eve:surface:aetheria.operations";
|
||||
public const string SurfaceId = AetheriaRuntimeOperationsCommands.SurfaceId;
|
||||
|
||||
public static EveSurfaceState Build(
|
||||
AetheriaEveCommandAcceptanceStatus? eveCommandStatus = null,
|
||||
AetheriaVerseHostSettings? verseHostSettings = null,
|
||||
AetheriaRuntimeSession? runtimeSession = null,
|
||||
long version = 1)
|
||||
{
|
||||
var normalizedVerseHost = AetheriaVerseHostSettingsNormalizer.Normalize(verseHostSettings);
|
||||
var updatedAtUtc = LatestTimestamp(
|
||||
eveCommandStatus?.LastPollAtUtc,
|
||||
normalizedVerseHost.LastUpdatedAtUtc,
|
||||
runtimeSession?.LastSeenAtUtc);
|
||||
var refreshCommand = GameCult.Mesh.CultMesh.OperationBindingRecord(
|
||||
GameCult.Mesh.CultMesh.OperationBinding(
|
||||
AetheriaRuntimeOperationsCommands.Refresh,
|
||||
label: "Refresh",
|
||||
routeHint: new GameCult.Mesh.CultMeshRouteHint(
|
||||
GameCult.Mesh.CultMeshLocalityKind.Automatic,
|
||||
"cultmesh")));
|
||||
return new EveSurfaceState
|
||||
{
|
||||
ProviderId = "aetheria",
|
||||
ProviderKind = "game.runtime",
|
||||
Title = "Aetheria Operations",
|
||||
Version = version,
|
||||
UpdatedAtUtc = updatedAtUtc,
|
||||
Surface = new EveSurface
|
||||
{
|
||||
Id = SurfaceId,
|
||||
Root = Node(
|
||||
"aetheria.operations.root",
|
||||
"surface",
|
||||
[],
|
||||
Node(
|
||||
"aetheria.operations.eveCommandAcceptance",
|
||||
"card",
|
||||
[("title", "Eve Request Acceptance")],
|
||||
Metric("eveCommandAcceptance.status", "Status", eveCommandStatus?.Status ?? "missing"),
|
||||
Metric("eveCommandAcceptance.observed", "Observed Before Accept", (eveCommandStatus?.ObservedBeforeAccept ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.accepted", "Commands Accepted", (eveCommandStatus?.CommandsAccepted ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.rejected", "Commands Rejected", (eveCommandStatus?.CommandsRejected ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.catalogRefreshes", "Catalog Refreshes", (eveCommandStatus?.AppliedCatalogRefreshes ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.operationsRefreshes", "Operations Refreshes", (eveCommandStatus?.AppliedOperationsRefreshes ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.playerSettings", "Player Settings Commands", (eveCommandStatus?.AppliedPlayerSettingsCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.inputSettings", "Input Settings Commands", (eveCommandStatus?.AppliedInputSettingsCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.loadoutTemplates", "Loadout Template Commands", (eveCommandStatus?.AppliedLoadoutTemplateCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.verseHost", "Verse Host Commands", (eveCommandStatus?.AppliedVerseHostCommands ?? 0).ToString()),
|
||||
Metric("eveCommandAcceptance.failures", "Consecutive Failures", (eveCommandStatus?.ConsecutiveFailures ?? 0).ToString()),
|
||||
Row(
|
||||
"eveCommandAcceptance.last",
|
||||
("runtime", eveCommandStatus?.RuntimeId ?? ""),
|
||||
("lastPoll", eveCommandStatus?.LastPollAtUtc ?? ""),
|
||||
("lastAccepted", eveCommandStatus?.LastAcceptedAtUtc ?? ""),
|
||||
("lastRejected", eveCommandStatus?.LastRejectedCommand ?? ""),
|
||||
("rejectedReason", eveCommandStatus?.LastRejectedReason ?? ""),
|
||||
("error", eveCommandStatus?.LastError ?? ""))),
|
||||
Node(
|
||||
"aetheria.operations.verseHost",
|
||||
"card",
|
||||
[("title", "Verse Host")],
|
||||
Metric("verseHost.visibility", "Visibility", normalizedVerseHost.Visibility),
|
||||
Metric("verseHost.service", "Service", normalizedVerseHost.ServiceId),
|
||||
Metric("verseHost.verse", "Verse", normalizedVerseHost.VerseId),
|
||||
Row(
|
||||
"verseHost.identity",
|
||||
("rootVerse", normalizedVerseHost.RootVerse),
|
||||
("canonicalService", normalizedVerseHost.CanonicalService),
|
||||
("locatedService", normalizedVerseHost.LocatedService),
|
||||
("cultMeshAddress", normalizedVerseHost.CultMeshAddress))),
|
||||
Node(
|
||||
"aetheria.operations.runtimeSession",
|
||||
"card",
|
||||
[("title", "Runtime Session")],
|
||||
Metric("runtimeSession.status", "Status", runtimeSession?.Status ?? "missing"),
|
||||
Metric("runtimeSession.role", "Role", runtimeSession?.Role ?? ""),
|
||||
Row(
|
||||
"runtimeSession.last",
|
||||
("runtime", runtimeSession?.RuntimeId ?? ""),
|
||||
("started", runtimeSession?.StartedAtUtc ?? ""),
|
||||
("lastSeen", runtimeSession?.LastSeenAtUtc ?? ""))))
|
||||
},
|
||||
Commands =
|
||||
[
|
||||
new EveCommandTemplate
|
||||
{
|
||||
Command = refreshCommand.OperationId,
|
||||
Label = refreshCommand.Label,
|
||||
Transport = refreshCommand.RouteDescription,
|
||||
SchemaId = refreshCommand.SchemaId,
|
||||
RouteKind = refreshCommand.RouteKind,
|
||||
RouteDescription = refreshCommand.RouteDescription
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
private static string LatestTimestamp(params string?[] timestamps)
|
||||
{
|
||||
var latest = "";
|
||||
foreach (var timestamp in timestamps)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(timestamp) &&
|
||||
(string.IsNullOrWhiteSpace(latest) || string.CompareOrdinal(timestamp, latest) > 0))
|
||||
{
|
||||
latest = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Metric(string id, string label, string value)
|
||||
{
|
||||
return Node(id, "metric", [("label", label), ("value", value)]);
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Row(string id, params (string Key, string Value)[] props)
|
||||
{
|
||||
return Node(id, "row", props);
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Node(
|
||||
string id,
|
||||
string kind,
|
||||
(string Key, string Value)[] props,
|
||||
params EveSurfaceComponent[] children)
|
||||
{
|
||||
return new EveSurfaceComponent
|
||||
{
|
||||
Id = id,
|
||||
Kind = kind,
|
||||
Props = props.ToDictionary(prop => prop.Key, prop => prop.Value),
|
||||
Children = children
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aetheria.State.Documents;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
|
||||
namespace Aetheria.State;
|
||||
|
||||
public static class AetheriaPlayerSettingsSurfaceProjector
|
||||
{
|
||||
public const string SurfaceKey = "eve:surface:aetheria.player_settings";
|
||||
public const string SurfaceId = AetheriaRuntimePlayerSettingsCommands.SurfaceId;
|
||||
|
||||
public static EveSurfaceState Build(
|
||||
AetheriaPlayerSettings? settings,
|
||||
string updatedAtUtc,
|
||||
long version = 1)
|
||||
{
|
||||
settings ??= new AetheriaPlayerSettings();
|
||||
var gameplay = settings.Gameplay ?? new AetheriaPlayerGameplaySettings();
|
||||
var graphics = settings.Graphics ?? new AetheriaPlayerGraphicsSettings();
|
||||
var publishedAtUtc = !string.IsNullOrWhiteSpace(settings.LastUpdatedAtUtc)
|
||||
? settings.LastUpdatedAtUtc
|
||||
: updatedAtUtc;
|
||||
|
||||
var surface = AetheriaRuntimePlayerSettingsSurfaceBuilder.Build(
|
||||
new AetheriaRuntimePlayerSettingsSurfaceState(
|
||||
settings.PlayerName,
|
||||
settings.TutorialPassed,
|
||||
settings.ActiveRunKey,
|
||||
gameplay.TemperatureUnit,
|
||||
gameplay.SignificantDigits,
|
||||
graphics.NebulaQuality,
|
||||
graphics.ShowAsteroidsInMinimap,
|
||||
publishedAtUtc),
|
||||
version);
|
||||
|
||||
return new EveSurfaceState
|
||||
{
|
||||
ProviderId = surface.ProviderId,
|
||||
ProviderKind = surface.ProviderKind,
|
||||
Title = surface.Title,
|
||||
Version = surface.Version,
|
||||
UpdatedAtUtc = surface.UpdatedAtUtc,
|
||||
Surface = new EveSurface
|
||||
{
|
||||
Id = surface.Surface.Id,
|
||||
Root = ConvertComponent(surface.Surface.Root),
|
||||
Styles = surface.Surface.Styles
|
||||
.Select(style => new EveStyleToken
|
||||
{
|
||||
Name = style.Name,
|
||||
Value = style.Value
|
||||
})
|
||||
.ToArray()
|
||||
},
|
||||
Commands = surface.Commands
|
||||
.Select(command =>
|
||||
{
|
||||
var record = GameCult.Mesh.CultMesh.OperationBindingRecord(command.Operation);
|
||||
return new EveCommandTemplate
|
||||
{
|
||||
Command = record.OperationId,
|
||||
Label = record.Label,
|
||||
Transport = record.RouteDescription,
|
||||
SchemaId = record.SchemaId,
|
||||
RouteKind = record.RouteKind,
|
||||
RouteDescription = record.RouteDescription
|
||||
};
|
||||
})
|
||||
.ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent ConvertComponent(AetheriaRuntimeSurfaceComponent component)
|
||||
{
|
||||
return new EveSurfaceComponent
|
||||
{
|
||||
Id = component.Id,
|
||||
Kind = component.Kind,
|
||||
Props = new Dictionary<string, string>(component.Props, StringComparer.Ordinal),
|
||||
Children = component.Children.Select(ConvertComponent).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,219 +0,0 @@
|
|||
using Aetheria.State.Documents;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
|
||||
namespace Aetheria.State;
|
||||
|
||||
public static class AetheriaProviderAdvertisementProjector
|
||||
{
|
||||
public const string AdvertisementKey = "eve:provider:aetheria";
|
||||
public const string DaemonGameSurfaceKey = "eve:surface:aetheria.daemon.game";
|
||||
public const string DaemonGameTuiSurfaceKey = "eve:surface:aetheria.daemon.game.tui";
|
||||
public const string DaemonEditorSurfaceKey = "eve:surface:aetheria.daemon.editor";
|
||||
public const string DaemonEditorTuiSurfaceKey = "eve:surface:aetheria.daemon.editor.tui";
|
||||
public const string ProviderId = "aetheria";
|
||||
private const string DaemonCommandBoundaryId = "aetheria.daemon.commands";
|
||||
private const string DaemonRecordTransport = "cultmesh-record";
|
||||
|
||||
public static EveProviderAdvertisementState Build(
|
||||
AetheriaVerseHostSettings settings,
|
||||
string statePath,
|
||||
string updatedAtUtc)
|
||||
{
|
||||
var normalized = AetheriaVerseHostSettingsNormalizer.Normalize(settings);
|
||||
return new EveProviderAdvertisementState
|
||||
{
|
||||
ProviderId = ProviderId,
|
||||
ServiceId = normalized.ServiceId,
|
||||
VerseId = normalized.VerseId,
|
||||
RootVerse = normalized.RootVerse,
|
||||
CanonicalService = normalized.CanonicalService,
|
||||
LocatedService = normalized.LocatedService,
|
||||
CultMeshAddress = normalized.CultMeshAddress,
|
||||
Title = normalized.Title,
|
||||
Kind = "game.runtime",
|
||||
UpdatedAtUtc = updatedAtUtc,
|
||||
Freshness = new EveProviderFreshness
|
||||
{
|
||||
State = "fresh",
|
||||
LastSeenAtUtc = updatedAtUtc,
|
||||
MaxAgeMs = 15000
|
||||
},
|
||||
Schemas =
|
||||
[
|
||||
"aetheria.world_state.v1",
|
||||
"aetheria.item_definition.v1",
|
||||
"aetheria.corporation.v2",
|
||||
"aetheria.name_file.v2",
|
||||
"aetheria.trade_value_policy.v1",
|
||||
"aetheria.player_settings.v1",
|
||||
"aetheria.loadout_template.v1",
|
||||
"aetheria.run_state.v1",
|
||||
"aetheria.zone_state.v1",
|
||||
"aetheria.entity_snapshot.v1",
|
||||
"aetheria.verse_host_settings.v1",
|
||||
"aetheria.runtime_session.v1",
|
||||
"aetheria.eve_command_acceptance_status.v1",
|
||||
"gamecult.eve.surface.v1",
|
||||
"gamecult.eve.command.v1",
|
||||
AetheriaRuntimeDaemonSchemas.ProviderAdvertisement,
|
||||
AetheriaRuntimeDaemonSchemas.Frame,
|
||||
AetheriaRuntimeDaemonSchemas.SoaView,
|
||||
AetheriaRuntimeDaemonSchemas.Health,
|
||||
AetheriaRuntimeDaemonSchemas.CommandBoundary,
|
||||
AetheriaRuntimeDaemonSchemas.GameSurface,
|
||||
AetheriaRuntimeDaemonSchemas.EditorSurface,
|
||||
AetheriaRuntimeDaemonSchemas.Command
|
||||
],
|
||||
Witnesses =
|
||||
[
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = "cultcache",
|
||||
Ref = statePath,
|
||||
Summary = "Aetheria typed CultCache state file"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement.ToString(),
|
||||
Summary = "Aetheria daemon-owned provider advertisement record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest.ToString(),
|
||||
Summary = "Aetheria daemon latest simulation frame record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonSoaViewLatest.ToString(),
|
||||
Summary = "Aetheria daemon latest SoA view record for thin clients"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonHealth.ToString(),
|
||||
Summary = "Aetheria daemon health record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary.ToString(),
|
||||
Summary = "Aetheria daemon typed command boundary record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonGameSurface.ToString(),
|
||||
Summary = "Aetheria daemon game Eve GUI surface record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface.ToString(),
|
||||
Summary = "Aetheria daemon game Eve TUI surface record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface.ToString(),
|
||||
Summary = "Aetheria daemon editor Eve GUI surface record"
|
||||
},
|
||||
new EveProviderWitness
|
||||
{
|
||||
Kind = DaemonRecordTransport,
|
||||
Ref = AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface.ToString(),
|
||||
Summary = "Aetheria daemon editor Eve TUI surface record"
|
||||
}
|
||||
],
|
||||
Surfaces =
|
||||
[
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaCatalogSurfaceProjector.SurfaceId,
|
||||
Key = AetheriaCatalogSurfaceProjector.SurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaOperationsSurfaceProjector.SurfaceId,
|
||||
Key = AetheriaOperationsSurfaceProjector.SurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaPlayerSettingsSurfaceProjector.SurfaceId,
|
||||
Key = AetheriaPlayerSettingsSurfaceProjector.SurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId,
|
||||
Key = DaemonGameSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId,
|
||||
Key = DaemonGameTuiSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId,
|
||||
Key = DaemonEditorSurfaceKey
|
||||
},
|
||||
new EveProviderSurfaceRef
|
||||
{
|
||||
SurfaceId = AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId,
|
||||
Key = DaemonEditorTuiSurfaceKey
|
||||
}
|
||||
],
|
||||
Commands =
|
||||
[
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = DaemonCommandBoundaryId,
|
||||
Transport = "cultmesh",
|
||||
Summary = "Aetheria daemon typed command boundary"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimeCatalogCommands.Refresh,
|
||||
Summary = "Refresh catalog projection"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimeOperationsCommands.Refresh,
|
||||
Summary = "Refresh operations projection"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.Refresh,
|
||||
Summary = "Refresh player settings projection"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.CycleTemperatureUnit,
|
||||
Summary = "Cycle the typed player temperature unit"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.DecrementSignificantDigits,
|
||||
Summary = "Decrease typed player significant digits"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.IncrementSignificantDigits,
|
||||
Summary = "Increase typed player significant digits"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.CycleNebulaQuality,
|
||||
Summary = "Cycle typed player nebula quality"
|
||||
},
|
||||
new EveProviderCommandRef
|
||||
{
|
||||
Command = AetheriaRuntimePlayerSettingsCommands.ToggleShowAsteroidsInMinimap,
|
||||
Summary = "Toggle typed player minimap asteroid visibility"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -129,13 +129,13 @@ public sealed class AetheriaStateNode : IAsyncDisposable, IDisposable
|
|||
return _catalogSurface ??= CultMesh.Document(
|
||||
"aetheria.catalog.surface",
|
||||
CultMesh.Verse("aetheria.local", RuntimeId),
|
||||
_ => Task.FromResult(AetheriaCatalogSurfaceProjector.Build(
|
||||
_ => Task.FromResult(AetheriaEveSurfaceDocuments.BuildCatalogSurface(
|
||||
catalog.Latest(),
|
||||
DateTimeOffset.UtcNow.ToString("O"))),
|
||||
_ => Database.WatchRecord<AetheriaRuntimeDaemonFrameDocument>(
|
||||
AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest)
|
||||
.Where(change => change.Document != null)
|
||||
.Select(_ => AetheriaCatalogSurfaceProjector.Build(
|
||||
.Select(_ => AetheriaEveSurfaceDocuments.BuildCatalogSurface(
|
||||
catalog.Latest(),
|
||||
DateTimeOffset.UtcNow.ToString("O"))),
|
||||
sources: new[]
|
||||
|
|
@ -238,16 +238,16 @@ public sealed class AetheriaStateNode : IAsyncDisposable, IDisposable
|
|||
new("global:aetheria.legacy_catalog_quarantine.v1");
|
||||
|
||||
public static CultRecordKey CatalogSurfaceKey { get; } =
|
||||
new(AetheriaCatalogSurfaceProjector.SurfaceKey);
|
||||
new(AetheriaEveSurfaceDocuments.CatalogSurfaceKey);
|
||||
|
||||
public static CultRecordKey OperationsSurfaceKey { get; } =
|
||||
new(AetheriaOperationsSurfaceProjector.SurfaceKey);
|
||||
new(AetheriaEveSurfaceDocuments.OperationsSurfaceKey);
|
||||
|
||||
public static CultRecordKey PlayerSettingsSurfaceKey { get; } =
|
||||
new(AetheriaPlayerSettingsSurfaceProjector.SurfaceKey);
|
||||
new(AetheriaEveSurfaceDocuments.PlayerSettingsSurfaceKey);
|
||||
|
||||
public static CultRecordKey ProviderAdvertisementSurfaceKey { get; } =
|
||||
new(AetheriaProviderAdvertisementProjector.AdvertisementKey);
|
||||
new(AetheriaEveSurfaceDocuments.ProviderAdvertisementKey);
|
||||
|
||||
public static CultRecordKey PlayerSettingsKey { get; } =
|
||||
new("global:aetheria.player_settings.v1");
|
||||
|
|
|
|||
Loading…
Reference in a new issue