Aetheria/Aetheria.State.Smoke/Program.cs

172 lines
5.6 KiB
C#
Raw Normal View History

2026-06-13 00:31:22 +01:00
using Aetheria.State;
using Aetheria.State.Documents;
using Aetheria.State.Migration;
using GameCult.Caching;
var root = args.Length > 0 ? args[0] : Directory.GetCurrentDirectory();
var statePath = AetheriaStatePaths.ResolveDefaultStatePath(root);
var now = DateTimeOffset.UtcNow.ToString("O");
2026-06-13 07:46:28 +01:00
var itemLegacyId = "smoke:aether-drive";
var factionLegacyId = "smoke:faction";
var nameFileLegacyId = "smoke:name-file";
2026-06-13 04:00:10 +01:00
var runKey = new CultRecordKey("run:smoke");
2026-06-13 00:31:22 +01:00
await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-state-smoke"))
{
await node.PutWorldAsync(new AetheriaWorldState
{
Name = "Aetheria",
WorldId = "aetheria",
SchemaEpoch = 1,
CreatedAtUtc = now,
UpdatedAtUtc = now
});
2026-06-13 07:46:28 +01:00
await node.PutLegacyItemDefinitionAsync(
2026-06-13 00:31:22 +01:00
new AetheriaItemDefinition
{
Name = "Smoke Aether Drive",
Category = "ship-module",
2026-06-13 07:46:28 +01:00
LegacyId = itemLegacyId,
2026-06-13 00:31:22 +01:00
Description = "Typed CultCache smoke document for the rebuild spine.",
Mass = 12.5,
Volume = 4.0,
Tags = ["smoke", "state-spine"]
});
await node.PutMigrationLedgerAsync(new AetheriaMigrationLedger
{
Source = LegacyMigrationBoundary.LegacyGameDataFile,
SourceFingerprint = "smoke",
LastMigrationAtUtc = now,
Counts =
[
new AetheriaMigrationCount
{
DocumentType = "aetheria.item_definition.v1",
Count = 1
}
],
Notes = ["Smoke proves the new state owner can write, flush, reopen, and read without old JSON/Rethink authority."]
});
2026-06-13 05:53:18 +01:00
await node.PutLegacyCatalogQuarantineAsync(new AetheriaLegacyCatalogQuarantine
{
RootPath = root,
CapturedAtUtc = now,
CatalogFile = LegacyMigrationBoundary.LegacyGameDataFile,
CatalogFingerprint = "smoke",
CatalogBytes = 12,
NameFiles =
[
new AetheriaLegacyCatalogFile
{
RelativePath = "GameData/NameFile/smoke.msgpack",
Fingerprint = "smoke-name-file",
Bytes = 4
}
],
Notes = ["Smoke proves legacy catalog quarantine state is typed and durable."]
});
2026-06-13 07:46:28 +01:00
await node.PutLegacyCorporationAsync(new AetheriaCorporation
2026-06-13 06:15:55 +01:00
{
Name = "Smoke Faction",
2026-06-13 07:46:28 +01:00
LegacyId = factionLegacyId,
2026-06-13 06:15:55 +01:00
Description = "Typed faction/corporation document for legacy catalog migration smoke."
});
2026-06-13 07:46:28 +01:00
await node.PutLegacyNameFileAsync(new AetheriaNameFile
2026-06-13 06:15:55 +01:00
{
Name = "Smoke Names",
2026-06-13 07:46:28 +01:00
LegacyId = nameFileLegacyId,
2026-06-13 06:15:55 +01:00
NameCount = 2,
SampleNames = ["Ada", "Grace"]
});
2026-06-13 08:37:10 +01:00
await node.PutCatalogSurfaceAsync(
AetheriaCatalogSurfaceProjector.Build(node.ReadCatalogSnapshot(), now));
2026-06-13 06:27:59 +01:00
await node.PutRunStateAsync(runKey, new AetheriaRunState
2026-06-13 04:00:10 +01:00
{
RunId = "smoke",
IsTutorial = false,
EntranceZoneIndex = 0,
ExitZoneIndex = 1,
CurrentZoneIndex = 0,
CurrentZoneEntityIndex = 0,
DiscoveredZoneIndices = [0],
ActionBarBindings =
[
new AetheriaActionBarBinding
{
Kind = "weapon-group",
WeaponGroup = 0
}
],
UpdatedAtUtc = now
});
await node.PutPlayerSettingsAsync(new AetheriaPlayerSettings
{
ActiveRunKey = runKey.ToString(),
LastUpdatedAtUtc = now
});
2026-06-13 00:31:22 +01:00
await node.FlushAsync();
}
await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aetheria-state-smoke-reopen"))
{
var world = await reopened.GetWorldAsync();
2026-06-13 07:46:28 +01:00
var item = await reopened.GetItemDefinitionByLegacyIdAsync(itemLegacyId);
var faction = await reopened.GetCorporationByLegacyIdAsync(factionLegacyId);
var nameFile = await reopened.GetNameFileByLegacyIdAsync(nameFileLegacyId);
2026-06-13 05:53:18 +01:00
var quarantine = await reopened.GetLegacyCatalogQuarantineAsync();
2026-06-13 08:37:10 +01:00
var catalogSurface = await reopened.GetCatalogSurfaceAsync();
2026-06-13 04:00:10 +01:00
var playerSettings = await reopened.GetPlayerSettingsAsync();
2026-06-13 06:27:59 +01:00
var runState = await reopened.GetRunStateAsync(runKey);
2026-06-13 00:31:22 +01:00
if (world?.WorldId != "aetheria")
{
throw new InvalidOperationException("World state did not survive flush/reopen.");
}
if (item?.Name != "Smoke Aether Drive")
{
throw new InvalidOperationException("Item definition did not survive flush/reopen.");
}
2026-06-13 04:00:10 +01:00
2026-06-13 07:46:28 +01:00
if (faction?.LegacyId != factionLegacyId)
2026-06-13 06:15:55 +01:00
{
throw new InvalidOperationException("Faction/corporation document did not survive flush/reopen.");
}
if (nameFile?.NameCount != 2)
{
throw new InvalidOperationException("Name file document did not survive flush/reopen.");
}
2026-06-13 05:53:18 +01:00
if (quarantine?.CatalogFingerprint != "smoke" || quarantine.NameFiles.Length != 1)
{
throw new InvalidOperationException("Legacy catalog quarantine did not survive flush/reopen.");
}
2026-06-13 08:37:10 +01:00
if (catalogSurface?.Schema != "gamecult.eve.surface.v1" ||
catalogSurface.Surface.Id != AetheriaCatalogSurfaceProjector.SurfaceId)
{
throw new InvalidOperationException("Eve catalog surface did not survive flush/reopen.");
}
2026-06-13 04:00:10 +01:00
if (playerSettings?.ActiveRunKey != runKey.ToString())
{
throw new InvalidOperationException("Player settings did not survive flush/reopen.");
}
2026-06-13 06:27:59 +01:00
if (runState?.RunId != "smoke" || runState.ActionBarBindings.Length != 1)
2026-06-13 04:00:10 +01:00
{
2026-06-13 06:27:59 +01:00
throw new InvalidOperationException("Run state did not survive flush/reopen.");
2026-06-13 04:00:10 +01:00
}
2026-06-13 00:31:22 +01:00
}
Console.WriteLine($"Aetheria typed state smoke passed: {statePath}");