Resolve item stat refs in runtime reader

This commit is contained in:
Meta Vens 2026-06-21 22:40:43 +01:00
commit fd3f945341
4 changed files with 294 additions and 68 deletions

View file

@ -4287,10 +4287,23 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root)
throw new InvalidOperationException("InventoryMenu cargo click path no longer routes item inspection through the Eve surface.");
}
if (!source.Contains("ResolveInventorySurfaceStateRef", StringComparison.Ordinal) ||
!source.Contains("AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef(", StringComparison.Ordinal) ||
!source.Contains("AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(", StringComparison.Ordinal) ||
var runtimeStateReaderPath = Path.Combine(
root,
"Packages",
"org.gamecult.aetheria.state",
"Runtime",
"AetheriaRuntimeStateReader.cs");
var runtimeStateReader = File.Exists(runtimeStateReaderPath)
? File.ReadAllText(runtimeStateReaderPath)
: throw new InvalidOperationException("Cannot verify item stat state-ref authority; AetheriaRuntimeStateReader.cs is missing.");
if (!runtimeStateReader.Contains("TryResolveDaemonItemStatRef(", StringComparison.Ordinal) ||
!runtimeStateReader.Contains("AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef(", StringComparison.Ordinal) ||
!runtimeStateReader.Contains("AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(", StringComparison.Ordinal) ||
!runtimeStateReader.Contains("FindDaemonItem(", StringComparison.Ordinal) ||
!cargoItemSurfaceBuilder.Contains("AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(", StringComparison.Ordinal) ||
source.Contains("ResolveInventorySurfaceStateRef", StringComparison.Ordinal) ||
source.Contains("TryResolveInventorySurfaceStateRef", StringComparison.Ordinal) ||
source.Contains("private static bool TryReadItemStatRef(", StringComparison.Ordinal) ||
source.Contains("DecodeRefToken", StringComparison.Ordinal) ||
source.Contains("GameManager.ItemManager.GetTier", StringComparison.Ordinal) ||
@ -9708,7 +9721,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"ResolveEveSurfaceStateRef",
"TryResolveEveSurfaceStateRef",
"TryResolveDaemonStateRef",
"TryResolveDaemonItemStatRef",
"AetheriaRuntimeDaemonStateRefs.Prefix",
"AetheriaRuntimeDaemonItemStatQueries.StateRefPrefix",
"AetheriaRuntimeDaemonStateRefs.CurrentEntityName",
"AetheriaRuntimeDaemonPublicationStore.TryReadGameSurface",
"AetheriaRuntimeDaemonPublicationStore.TryReadGameTuiSurface",
@ -9722,6 +9737,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"ResolveSurfaceStateRefs(stateFilePath, surface)",
"public static Func<string, string> CreateEveSurfaceStateRefResolver(string stateFilePath)",
"CreateStateRefResolver(string stateFilePath)",
"FindDaemonItem(",
"AetheriaRuntimeEveSurfaceAdapter.ResolveStateRefs(",
"AetheriaRuntimeEveSurfaceAdapter.EmptySurface(surfaceId)"
};

View file

@ -406,6 +406,82 @@ public class DaemonRuntimeDocumentTests
AetheriaRuntimeDaemonStateRefs.CurrentTargetName));
}
[Test]
public void RuntimeStateReaderResolvesItemStatRefsFromDaemonFrame()
{
var frame = new AetheriaRuntimeDaemonFrameDocument
{
Run = new AetheriaRuntimeRunCheckpointCommit
{
Zones = new[]
{
new AetheriaRuntimeZoneSnapshotCommit
{
Entities = new[]
{
new AetheriaRuntimeEntitySnapshotCommit
{
Equipment = new[]
{
new AetheriaRuntimeLoadoutItemSlotCommit
{
Item = new AetheriaRuntimeLoadoutItemCommit
{
ItemKey = "test-laser",
Quality = 0.5,
Durability = 1.0,
Enabled = true
}
}
}
}
}
}
}
}
};
var statValue = new AetheriaRuntimeBehaviorValue(
"performance-stat",
"",
0,
false,
"",
"",
new[]
{
NumberValue(10),
NumberValue(20),
NumberValue(0),
NumberValue(0),
NumberValue(1),
EmptyBehaviorValue("stat-recipe")
},
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
var catalog = new AetheriaRuntimeCatalogSnapshot(
new[]
{
CatalogItem(
"test-laser",
new[]
{
new AetheriaRuntimeBehaviorPayload(
0,
"Weapon",
2,
new[] { new AetheriaRuntimeBehaviorField(7, statValue) })
})
},
Array.Empty<AetheriaRuntimeCorporation>(),
Array.Empty<AetheriaRuntimeNameFile>());
Assert.IsTrue(AetheriaRuntimeStateReader.TryResolveDaemonItemStatRef(
frame,
catalog,
AetheriaRuntimeDaemonItemStatQueries.ItemStatRef("test-laser", "Weapon", 2, 7),
out var value));
Assert.AreEqual("15", value);
}
[Test]
public void TickRunnerSkipsPreviouslyAccountedObservedCommands()
{
@ -3501,6 +3577,87 @@ public class DaemonRuntimeDocumentTests
"state.cc.daemon.soa.cc");
}
private static AetheriaRuntimeCatalogItem CatalogItem(
string itemKey,
IReadOnlyList<AetheriaRuntimeBehaviorPayload> behaviorPayloads)
{
return new AetheriaRuntimeCatalogItem(
itemKey,
itemKey,
"",
"",
"",
0,
0,
0,
0,
0,
0,
0,
0,
Array.Empty<AetheriaRuntimeShapeCell>(),
0,
0,
0,
Array.Empty<AetheriaRuntimeShapeCell>(),
Array.Empty<AetheriaRuntimeHardpoint>(),
behaviorPayloads,
"",
"",
behaviorPayloads.Select(payload => payload.Kind).ToArray(),
1,
false,
0,
1,
"",
"",
"",
"",
"",
0,
0,
Array.Empty<AetheriaRuntimeCurveKey>(),
"",
1,
0,
0,
0,
false,
0,
0,
"",
Array.Empty<AetheriaRuntimeAudioStat>(),
Array.Empty<AetheriaRuntimeCurveKey>(),
"",
"");
}
private static AetheriaRuntimeBehaviorValue NumberValue(double value)
{
return new AetheriaRuntimeBehaviorValue(
"",
"",
value,
false,
"",
"",
Array.Empty<AetheriaRuntimeBehaviorValue>(),
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
}
private static AetheriaRuntimeBehaviorValue EmptyBehaviorValue(string kind)
{
return new AetheriaRuntimeBehaviorValue(
kind,
"",
0,
false,
"",
"",
Array.Empty<AetheriaRuntimeBehaviorValue>(),
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
}
private static bool ContainsSurfaceMetric(
AetheriaRuntimeSurfaceComponent component,
string label,

View file

@ -261,7 +261,6 @@ public class InventoryMenu : MonoBehaviour
AetheriaRuntimeCargoItemDetailsSurfaceBuilder.Build(ProjectCargoItemDetailsSurface(item, typedItem)),
HandleCargoItemDetailsSurfaceCommand,
_cargoItemDetailsSurfaceChrome,
ResolveInventorySurfaceStateRef,
sortingOrder: 1001);
}
@ -304,7 +303,6 @@ public class InventoryMenu : MonoBehaviour
AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Build(ProjectEquippedItemDetailsSurface(item, typedItem)),
HandleEquippedItemDetailsSurfaceCommand,
_equippedItemDetailsSurfaceChrome,
ResolveInventorySurfaceStateRef,
sortingOrder: 1002);
}
@ -539,15 +537,6 @@ public class InventoryMenu : MonoBehaviour
: "";
}
private static string FormatCurrentItemStat(AetheriaRuntimeBehaviorValue stat, EquippableItem item)
{
return ActionGameManager.RuntimePlayerSettings.Format(
AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(
stat,
ToRuntimeLoadoutItem(item),
item?.Temperature ?? 0));
}
private static AetheriaRuntimeLoadoutItemCommit ToRuntimeLoadoutItem(EquippableItem item)
{
return AetheriaRuntimeDaemonItemStatQueries.ItemCommit(
@ -558,51 +547,6 @@ public class InventoryMenu : MonoBehaviour
overrideShutdown: item != null && item.OverrideShutdown);
}
private string ResolveInventorySurfaceStateRef(string stateRef)
{
return TryResolveInventorySurfaceStateRef(stateRef, out var value) ? value : "";
}
private bool TryResolveInventorySurfaceStateRef(string stateRef, out string value)
{
value = "";
if (!AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef(
stateRef,
out var itemKey,
out var behaviorKind,
out var behaviorGroup,
out var fieldKey))
return false;
var item = ResolveSelectedEquippableItem(itemKey);
var typedItem = FindTypedInventoryItem(item);
var behavior = typedItem?.BehaviorPayloads?.FirstOrDefault(candidate =>
string.Equals(candidate.Kind, behaviorKind, StringComparison.Ordinal) &&
candidate.Group == behaviorGroup);
var field = behavior?.Fields?.FirstOrDefault(candidate => candidate.Key == fieldKey);
if (item == null || field == null)
return false;
value = FormatCurrentItemStat(field.Value, item);
return true;
}
private EquippableItem ResolveSelectedEquippableItem(string itemKey)
{
var equipped = _selectedEquippedItem?.EquippableItem;
if (ItemKeyMatches(equipped, itemKey))
return equipped;
var cargo = _selectedItem as EquippableItem;
return ItemKeyMatches(cargo, itemKey) ? cargo : null;
}
private static bool ItemKeyMatches(EquippableItem item, string itemKey)
{
return item != null &&
string.Equals(item.ItemKey ?? "", itemKey ?? "", StringComparison.Ordinal);
}
private static bool IsWeaponGroupAssigned(EquippedItem item, int groupIndex)
{
return item?.Entity?.WeaponGroups != null &&

View file

@ -121,13 +121,24 @@ namespace GameCult.Aetheria.State.Verse
if (string.IsNullOrWhiteSpace(stateRef))
return false;
if (!stateRef.StartsWith(AetheriaRuntimeDaemonStateRefs.Prefix + "/", StringComparison.Ordinal))
return false;
TryReadDaemonFrame(stateFilePath, out var frame);
AetheriaRuntimeDaemonPublicationStore.TryReadHealth(stateFilePath, out var health);
AetheriaRuntimeDaemonPublicationStore.TryReadCommandBoundary(stateFilePath, out var commandBoundary);
return TryResolveDaemonStateRef(frame, health, commandBoundary, stateRef, out value);
if (stateRef.StartsWith(AetheriaRuntimeDaemonStateRefs.Prefix + "/", StringComparison.Ordinal))
{
AetheriaRuntimeDaemonPublicationStore.TryReadHealth(stateFilePath, out var health);
AetheriaRuntimeDaemonPublicationStore.TryReadCommandBoundary(stateFilePath, out var commandBoundary);
return TryResolveDaemonStateRef(frame, health, commandBoundary, stateRef, out value);
}
if (stateRef.StartsWith(AetheriaRuntimeDaemonItemStatQueries.StateRefPrefix + "/", StringComparison.Ordinal))
{
return TryResolveDaemonItemStatRef(
frame,
OpenRuntimeCatalog(stateFilePath),
stateRef,
out value);
}
return false;
}
public static bool TryResolveDaemonStateRef(
@ -211,6 +222,42 @@ namespace GameCult.Aetheria.State.Verse
}
}
public static bool TryResolveDaemonItemStatRef(
AetheriaRuntimeDaemonFrameDocument? frame,
AetheriaRuntimeCatalogSnapshot? catalog,
string stateRef,
out string value)
{
value = "";
if (!AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef(
stateRef,
out var itemKey,
out var behaviorKind,
out var behaviorGroup,
out var fieldKey))
{
return false;
}
var item = FindDaemonItem(frame?.Run, itemKey);
var typedItem = catalog?.FindItem(itemKey);
var field = typedItem?.BehaviorPayloads?
.FirstOrDefault(candidate =>
string.Equals(candidate.Kind, behaviorKind, StringComparison.Ordinal) &&
candidate.Group == behaviorGroup)
?.Fields?
.FirstOrDefault(candidate => candidate.Key == fieldKey);
if (item == null || field == null)
return false;
value = AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(
field.Value,
item,
heat: 0)
.ToString("0.###", CultureInfo.InvariantCulture);
return true;
}
public static bool TryReadDaemonGameSurface(
string stateFilePath,
out EveSurfaceDocument document)
@ -303,9 +350,71 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeDaemonPublicationStore.TryReadHealth(stateFilePath, out var health);
AetheriaRuntimeDaemonPublicationStore.TryReadCommandBoundary(stateFilePath, out var commandBoundary);
return stateRef => TryResolveDaemonStateRef(frame, health, commandBoundary, stateRef, out var value)
? value
: "";
return stateRef =>
{
if (TryResolveDaemonStateRef(frame, health, commandBoundary, stateRef, out var value))
return value;
return stateRef.StartsWith(AetheriaRuntimeDaemonItemStatQueries.StateRefPrefix + "/", StringComparison.Ordinal) &&
TryResolveDaemonItemStatRef(frame, OpenRuntimeCatalog(stateFilePath), stateRef, out value)
? value
: "";
};
}
private static AetheriaRuntimeLoadoutItemCommit? FindDaemonItem(
AetheriaRuntimeRunCheckpointCommit? run,
string itemKey)
{
if (run == null || string.IsNullOrWhiteSpace(itemKey))
return null;
foreach (var zone in run.Zones ?? Array.Empty<AetheriaRuntimeZoneSnapshotCommit>())
foreach (var entity in zone.Entities ?? Array.Empty<AetheriaRuntimeEntitySnapshotCommit>())
{
var item = FindDaemonItem(entity.Equipment, itemKey)
?? FindDaemonItem(entity.CargoBays, itemKey)
?? FindDaemonItem(entity.DockingBays, itemKey)
?? FindDaemonItem(entity.CargoContents, itemKey)
?? FindDaemonItem(entity.DockingBayContents, itemKey);
if (item != null)
return item;
}
return null;
}
private static AetheriaRuntimeLoadoutItemCommit? FindDaemonItem(
IReadOnlyList<AetheriaRuntimeLoadoutItemSlotCommit>? slots,
string itemKey)
{
foreach (var slot in slots ?? Array.Empty<AetheriaRuntimeLoadoutItemSlotCommit>())
{
if (IsItemMatch(slot?.Item, itemKey))
return slot?.Item;
}
return null;
}
private static AetheriaRuntimeLoadoutItemCommit? FindDaemonItem(
IReadOnlyList<AetheriaRuntimeCargoBayLoadoutCommit>? cargoBays,
string itemKey)
{
foreach (var cargoBay in cargoBays ?? Array.Empty<AetheriaRuntimeCargoBayLoadoutCommit>())
{
var item = FindDaemonItem(cargoBay?.Items, itemKey);
if (item != null)
return item;
}
return null;
}
private static bool IsItemMatch(AetheriaRuntimeLoadoutItemCommit? item, string itemKey)
{
return item != null &&
string.Equals(item.ItemKey ?? "", itemKey ?? "", StringComparison.Ordinal);
}
private static AetheriaRuntimeZoneSnapshotCommit FindCurrentZone(AetheriaRuntimeRunCheckpointCommit run)