Resolve zone body and orbit keys natively
This commit is contained in:
parent
d7ad15c35c
commit
452184ea3a
5 changed files with 96 additions and 38 deletions
Binary file not shown.
|
|
@ -18,6 +18,7 @@ RequireTypedOrbitTaskKeys(root);
|
|||
RequireTypedOrbitalEntityOrbitKeys(root);
|
||||
RequireTypedOrbitConsumerKeys(root);
|
||||
RequireKeyedOrbitRuntimeWrappers(root);
|
||||
RequireNativeZoneKeyResolution(root);
|
||||
RequireTypedFactionShellLinks(root);
|
||||
RequireFactionKeyIdentity(root);
|
||||
RequireEveRuntimeBootstrap(root);
|
||||
|
|
@ -807,7 +808,6 @@ static void RequireTypedBehaviorBodyKeys(string root)
|
|||
"public string OrbitKey { get; }",
|
||||
"public string ParentOrbitKey { get; }",
|
||||
"public string GetBodyKey(Guid bodyId)",
|
||||
"public static Guid ParseBodyGuid(string bodyKey)",
|
||||
"public bool TryGetPlanet(string bodyKey, out Planet planet)",
|
||||
"public bool TryGetAsteroidBelt(string bodyKey, out AsteroidBelt belt)"
|
||||
};
|
||||
|
|
@ -899,7 +899,6 @@ static void RequireTypedOrbitTaskKeys(string root)
|
|||
: throw new InvalidOperationException("Cannot verify orbit-key task ownership; Zone source is missing.");
|
||||
var requiredZoneSymbols = new[]
|
||||
{
|
||||
"public static Guid ParseOrbitGuid(string orbitKey)",
|
||||
"public bool TryGetOrbit(string orbitKey, out Orbit orbit)",
|
||||
"public float2 GetOrbitPosition(string orbitKey)"
|
||||
};
|
||||
|
|
@ -1151,7 +1150,8 @@ static void RequireKeyedOrbitRuntimeWrappers(string root)
|
|||
{
|
||||
"public Orbit Orbit;",
|
||||
"public Orbit Orbit { get; }",
|
||||
"AsteroidBelts[belt.ID] = new AsteroidBelt(belt, Orbits[belt.Orbit]);",
|
||||
"var runtimeBelt = new AsteroidBelt(belt, Orbits[belt.Orbit]);",
|
||||
"AsteroidBelts[belt.ID] = runtimeBelt;",
|
||||
"belt.NewOrbitPosition = GetOrbitPosition(belt.Orbit.ParentOrbitKey);",
|
||||
"public AsteroidBelt(AsteroidBeltConstructionData data, Orbit orbit)",
|
||||
"Orbit = orbit;"
|
||||
|
|
@ -1206,6 +1206,62 @@ static void RequireTypedFactionShellLinks(string root)
|
|||
}
|
||||
}
|
||||
|
||||
static void RequireNativeZoneKeyResolution(string root)
|
||||
{
|
||||
var zoneSourcePath = Path.Combine(root, "Assets", "Scripts", "ServerShared", "Zone.cs");
|
||||
var zoneSource = File.Exists(zoneSourcePath)
|
||||
? File.ReadAllText(zoneSourcePath)
|
||||
: throw new InvalidOperationException("Cannot verify native Zone key resolution; Zone source is missing.");
|
||||
|
||||
var forbiddenSymbols = new[]
|
||||
{
|
||||
"public static Guid ParseOrbitGuid(string orbitKey)",
|
||||
"public static Guid ParseBodyGuid(string bodyKey)",
|
||||
"PlanetInstances.TryGetValue(ParseBodyGuid(bodyKey), out planet)",
|
||||
"AsteroidBelts.TryGetValue(ParseBodyGuid(bodyKey), out belt)",
|
||||
"Orbits.TryGetValue(ParseOrbitGuid(orbitKey), out orbit)",
|
||||
"return GetOrbitPosition(ParseOrbitGuid(orbitKey));",
|
||||
"return GetOrbitVelocity(ParseOrbitGuid(orbitKey));"
|
||||
};
|
||||
var hits = forbiddenSymbols
|
||||
.Where(symbol => zoneSource.Contains(symbol, StringComparison.Ordinal))
|
||||
.Select(symbol => $"Assets/Scripts/ServerShared/Zone.cs: contains {symbol}")
|
||||
.ToArray();
|
||||
if (hits.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Zone key-facing APIs must resolve typed body/orbit keys natively instead of reparsing GUIDs from those keys: " +
|
||||
string.Join("; ", hits));
|
||||
}
|
||||
|
||||
var requiredSymbols = new[]
|
||||
{
|
||||
"private readonly Dictionary<string, Planet> _planetsByBodyKey = new Dictionary<string, Planet>(StringComparer.Ordinal);",
|
||||
"private readonly Dictionary<string, AsteroidBelt> _asteroidBeltsByBodyKey = new Dictionary<string, AsteroidBelt>(StringComparer.Ordinal);",
|
||||
"private readonly Dictionary<string, Orbit> _orbitsByKey = new Dictionary<string, Orbit>(StringComparer.Ordinal);",
|
||||
"_orbitsByKey[runtimeOrbit.OrbitKey] = runtimeOrbit;",
|
||||
"_asteroidBeltsByBodyKey[runtimeBelt.BodyKey] = runtimeBelt;",
|
||||
"_planetsByBodyKey[runtimeSun.BodyKey] = runtimeSun;",
|
||||
"_planetsByBodyKey[runtimeGas.BodyKey] = runtimeGas;",
|
||||
"_planetsByBodyKey[runtimePlanet.BodyKey] = runtimePlanet;",
|
||||
"return _planetsByBodyKey.TryGetValue(bodyKey ?? \"\", out planet);",
|
||||
"return _asteroidBeltsByBodyKey.TryGetValue(bodyKey ?? \"\", out belt);",
|
||||
"return _orbitsByKey.TryGetValue(orbitKey ?? \"\", out orbit);",
|
||||
"return TryGetOrbit(orbitKey, out var orbit)",
|
||||
"? GetOrbitPosition(orbit.ID)",
|
||||
"? GetOrbitVelocity(orbit.ID)"
|
||||
};
|
||||
var missingSymbols = requiredSymbols
|
||||
.Where(symbol => !zoneSource.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Zone must keep native key-indexed runtime lookup tables for body and orbit resolution: " +
|
||||
string.Join(", ", missingSymbols));
|
||||
}
|
||||
}
|
||||
|
||||
static void RequireFactionKeyIdentity(string root)
|
||||
{
|
||||
var checkedFiles = new[]
|
||||
|
|
|
|||
|
|
@ -146,6 +146,10 @@ reading wrapper GUID orbit fields directly.
|
|||
orbit GUID fields either: they keep `OrbitKey` plus their `Orbit` runtime
|
||||
object, and `Zone` lowers asteroid transforms through `belt.Orbit.ParentOrbitKey`
|
||||
instead of reading a raw wrapper orbit GUID.
|
||||
`Zone`'s own public key-facing lookup surface is also now natively keyed:
|
||||
body and orbit lookups resolve through key-indexed runtime dictionaries rather
|
||||
than reparsing GUIDs from `BodyKey` or `OrbitKey` strings before touching the
|
||||
Guid-indexed substrate.
|
||||
The package runtime catalog snapshot indexes items by canonical item key; Unity
|
||||
gameplay, HUD, inventory, trade, ship, and zone helper lookups use `ItemKey`
|
||||
directly instead of deriving `ItemId` and searching by legacy GUID.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ public class Zone
|
|||
public Dictionary<Guid, Orbit> Orbits = new Dictionary<Guid, Orbit>();
|
||||
public Dictionary<Guid, AsteroidBelt> AsteroidBelts = new Dictionary<Guid, AsteroidBelt>();
|
||||
public PlanetSettings Settings;
|
||||
|
||||
private readonly Dictionary<string, Planet> _planetsByBodyKey = new Dictionary<string, Planet>(StringComparer.Ordinal);
|
||||
private readonly Dictionary<string, AsteroidBelt> _asteroidBeltsByBodyKey = new Dictionary<string, AsteroidBelt>(StringComparer.Ordinal);
|
||||
private readonly Dictionary<string, Orbit> _orbitsByKey = new Dictionary<string, Orbit>(StringComparer.Ordinal);
|
||||
|
||||
private HashSet<Guid> _updatedOrbits = new HashSet<Guid>();
|
||||
|
||||
|
|
@ -58,7 +62,9 @@ public class Zone
|
|||
|
||||
foreach (var orbit in blueprint.Orbits)
|
||||
{
|
||||
Orbits.Add(orbit.ID, new Orbit(Settings, orbit));
|
||||
var runtimeOrbit = new Orbit(Settings, orbit);
|
||||
Orbits.Add(orbit.ID, runtimeOrbit);
|
||||
_orbitsByKey[runtimeOrbit.OrbitKey] = runtimeOrbit;
|
||||
}
|
||||
|
||||
foreach (var planet in blueprint.Bodies)
|
||||
|
|
@ -66,16 +72,24 @@ public class Zone
|
|||
switch (planet)
|
||||
{
|
||||
case AsteroidBeltConstructionData belt:
|
||||
AsteroidBelts[belt.ID] = new AsteroidBelt(belt, Orbits[belt.Orbit]);
|
||||
var runtimeBelt = new AsteroidBelt(belt, Orbits[belt.Orbit]);
|
||||
AsteroidBelts[belt.ID] = runtimeBelt;
|
||||
_asteroidBeltsByBodyKey[runtimeBelt.BodyKey] = runtimeBelt;
|
||||
break;
|
||||
case SunConstructionData sun:
|
||||
PlanetInstances.Add(sun.ID, new Sun(settings, sun, Orbits[planet.Orbit]));
|
||||
var runtimeSun = new Sun(settings, sun, Orbits[planet.Orbit]);
|
||||
PlanetInstances.Add(sun.ID, runtimeSun);
|
||||
_planetsByBodyKey[runtimeSun.BodyKey] = runtimeSun;
|
||||
break;
|
||||
case GasGiantConstructionData gas:
|
||||
PlanetInstances.Add(gas.ID, new GasGiant(settings, gas, Orbits[planet.Orbit]));
|
||||
var runtimeGas = new GasGiant(settings, gas, Orbits[planet.Orbit]);
|
||||
PlanetInstances.Add(gas.ID, runtimeGas);
|
||||
_planetsByBodyKey[runtimeGas.BodyKey] = runtimeGas;
|
||||
break;
|
||||
default:
|
||||
PlanetInstances.Add(planet.ID, new Planet(settings, planet, Orbits[planet.Orbit]));
|
||||
var runtimePlanet = new Planet(settings, planet, Orbits[planet.Orbit]);
|
||||
PlanetInstances.Add(planet.ID, runtimePlanet);
|
||||
_planetsByBodyKey[runtimePlanet.BodyKey] = runtimePlanet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -119,17 +133,6 @@ public class Zone
|
|||
return id == Guid.Empty ? "" : $"{BodyKeyPrefix}{id:D}";
|
||||
}
|
||||
|
||||
public static Guid ParseOrbitGuid(string orbitKey)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(orbitKey))
|
||||
return Guid.Empty;
|
||||
|
||||
var runtimeOrbitId = orbitKey.StartsWith(OrbitKeyPrefix, StringComparison.OrdinalIgnoreCase)
|
||||
? orbitKey.Substring(OrbitKeyPrefix.Length)
|
||||
: orbitKey;
|
||||
return Guid.TryParse(runtimeOrbitId, out var id) ? id : Guid.Empty;
|
||||
}
|
||||
|
||||
public string GetBodyKey(Guid bodyId)
|
||||
{
|
||||
if (bodyId == Guid.Empty)
|
||||
|
|
@ -141,30 +144,19 @@ public class Zone
|
|||
return BodyKey(bodyId);
|
||||
}
|
||||
|
||||
public static Guid ParseBodyGuid(string bodyKey)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(bodyKey))
|
||||
return Guid.Empty;
|
||||
|
||||
var runtimeBodyId = bodyKey.StartsWith(BodyKeyPrefix, StringComparison.OrdinalIgnoreCase)
|
||||
? bodyKey.Substring(BodyKeyPrefix.Length)
|
||||
: bodyKey;
|
||||
return Guid.TryParse(runtimeBodyId, out var id) ? id : Guid.Empty;
|
||||
}
|
||||
|
||||
public bool TryGetPlanet(string bodyKey, out Planet planet)
|
||||
{
|
||||
return PlanetInstances.TryGetValue(ParseBodyGuid(bodyKey), out planet);
|
||||
return _planetsByBodyKey.TryGetValue(bodyKey ?? "", out planet);
|
||||
}
|
||||
|
||||
public bool TryGetAsteroidBelt(string bodyKey, out AsteroidBelt belt)
|
||||
{
|
||||
return AsteroidBelts.TryGetValue(ParseBodyGuid(bodyKey), out belt);
|
||||
return _asteroidBeltsByBodyKey.TryGetValue(bodyKey ?? "", out belt);
|
||||
}
|
||||
|
||||
public bool TryGetOrbit(string orbitKey, out Orbit orbit)
|
||||
{
|
||||
return Orbits.TryGetValue(ParseOrbitGuid(orbitKey), out orbit);
|
||||
return _orbitsByKey.TryGetValue(orbitKey ?? "", out orbit);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
|
|
@ -234,7 +226,9 @@ public class Zone
|
|||
|
||||
public float2 GetOrbitPosition(string orbitKey)
|
||||
{
|
||||
return GetOrbitPosition(ParseOrbitGuid(orbitKey));
|
||||
return TryGetOrbit(orbitKey, out var orbit)
|
||||
? GetOrbitPosition(orbit.ID)
|
||||
: float2.zero;
|
||||
}
|
||||
|
||||
public float2 GetOrbitVelocity(Guid orbit)
|
||||
|
|
@ -246,7 +240,9 @@ public class Zone
|
|||
|
||||
public float2 GetOrbitVelocity(string orbitKey)
|
||||
{
|
||||
return GetOrbitVelocity(ParseOrbitGuid(orbitKey));
|
||||
return TryGetOrbit(orbitKey, out var orbit)
|
||||
? GetOrbitVelocity(orbit.ID)
|
||||
: float2.zero;
|
||||
}
|
||||
|
||||
public int NearestAsteroid(Guid planetDataID, float2 position)
|
||||
|
|
|
|||
|
|
@ -1375,9 +1375,11 @@ First Aetheria surfaces to publish:
|
|||
`ResourceScanner` orbit readers now also consume the wrapper `OrbitKey`
|
||||
edge instead of wrapper GUID orbit fields. `Planet` and `AsteroidBelt`
|
||||
runtime wrappers no longer publish separate wrapper orbit GUID fields
|
||||
either; they retain `OrbitKey` plus their runtime `Orbit` object. Remaining
|
||||
broader simulation paths still derive legacy GUIDs until those structures
|
||||
move to typed keys.
|
||||
either; they retain `OrbitKey` plus their runtime `Orbit` object. `Zone`'s
|
||||
key-facing lookup surface also resolves through native key-indexed runtime
|
||||
dictionaries instead of reparsing GUIDs from key strings. Remaining broader
|
||||
simulation paths still derive legacy GUIDs until those structures move to
|
||||
typed keys.
|
||||
- Done: delete the `ItemInstance.ItemId` legacy-GUID projection; diagnostics
|
||||
now report `ItemKey` so item instances expose only typed item-key identity.
|
||||
- Done: delete `Entity`/`EquippedCargoBay` cargo and consumable GUID lookup
|
||||
|
|
|
|||
Loading…
Reference in a new issue