Use faction keys for shell identity
This commit is contained in:
parent
392c24a7da
commit
8ea97a08f8
11 changed files with 77 additions and 10 deletions
Binary file not shown.
|
|
@ -15,6 +15,7 @@ RequireTypedGalaxyFactionRelationships(root);
|
|||
RequireRuntimeCatalogKeyOnlyLookups(root);
|
||||
RequireTypedBehaviorBodyKeys(root);
|
||||
RequireTypedFactionShellLinks(root);
|
||||
RequireFactionKeyIdentity(root);
|
||||
RequireEveRuntimeBootstrap(root);
|
||||
RequireNoRendererLocalConsole(root);
|
||||
RequireNoRendererLocalDebugPanels(root);
|
||||
|
|
@ -809,6 +810,49 @@ static void RequireTypedFactionShellLinks(string root)
|
|||
}
|
||||
}
|
||||
|
||||
static void RequireFactionKeyIdentity(string root)
|
||||
{
|
||||
var checkedFiles = new[]
|
||||
{
|
||||
Path.Combine(root, "Assets", "Scripts", "ServerShared", "Corporations.cs"),
|
||||
Path.Combine(root, "Assets", "Scripts", "ServerShared", "Entity.cs"),
|
||||
Path.Combine(root, "Assets", "Scripts", "ServerShared", "Galaxy.cs"),
|
||||
Path.Combine(root, "Assets", "Scripts", "ServerShared", "Zone.cs"),
|
||||
Path.Combine(root, "Assets", "Scripts", "ServerShared", "Narrative", "ZoneConstraints.cs"),
|
||||
Path.Combine(root, "Assets", "Scripts", "Gameplay", "ActionGameManager.cs"),
|
||||
Path.Combine(root, "Assets", "Scripts", "UI", "Menu", "SectorRenderer.cs")
|
||||
};
|
||||
|
||||
var forbiddenSymbols = new[]
|
||||
{
|
||||
"ID.GetHashCode",
|
||||
"faction.ID == ID",
|
||||
"Faction.ID ==",
|
||||
"faction.ID ==",
|
||||
".ID == TargetFaction",
|
||||
".ID == GalaxyZone.Owner",
|
||||
".ID != zone.Owner",
|
||||
"pair.Key.ID",
|
||||
"f.ID != zone.Owner",
|
||||
"Owner.ID =="
|
||||
};
|
||||
|
||||
var hits = checkedFiles
|
||||
.Where(File.Exists)
|
||||
.SelectMany(path => File.ReadLines(path)
|
||||
.Select((line, index) => new { Path = path, LineNumber = index + 1, Line = line }))
|
||||
.Where(line => forbiddenSymbols.Any(symbol => line.Line.Contains(symbol, StringComparison.Ordinal)))
|
||||
.Select(line => $"{Path.GetRelativePath(root, line.Path)}:{line.LineNumber}: {line.Line.Trim()}")
|
||||
.ToArray();
|
||||
|
||||
if (hits.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Faction identity must compare and order by FactionKey; Faction.ID is temporary projection residue only: " +
|
||||
string.Join("; ", hits));
|
||||
}
|
||||
}
|
||||
|
||||
static void RequireEveRuntimeBootstrap(string root)
|
||||
{
|
||||
var bootstrapPath = Path.Combine(
|
||||
|
|
|
|||
|
|
@ -114,6 +114,10 @@ resolver are deleted from the simulation shell.
|
|||
The remaining temporary `Faction` shell also uses `GeonameFileKey` and
|
||||
`BossHullItemKey`; it no longer parses name-file or boss-hull legacy IDs into
|
||||
GUID link fields.
|
||||
`Faction` equality, hashing, narrative constraints, sector display filtering,
|
||||
zone security ownership checks, and runtime faction-relationship ordering now
|
||||
use `FactionKey`. The legacy `Faction.ID` remains projection residue only until
|
||||
the temporary simulation shell is removed.
|
||||
Run checkpoint commit DTOs carry typed `OrbitKey`, `ParentOrbitKey`, and
|
||||
`BodyKey` only for zone orbit/body snapshots. The old pending-command
|
||||
`OrbitLegacyId`, `ParentLegacyId`, and `BodyLegacyId` fallback fields are
|
||||
|
|
|
|||
|
|
@ -677,7 +677,7 @@ public class ActionGameManager : MonoBehaviour
|
|||
{
|
||||
return CurrentGalaxy?.FactionRelationships?
|
||||
.Where(pair => pair.Key != null)
|
||||
.OrderBy(pair => pair.Key.ID)
|
||||
.OrderBy(pair => pair.Key.FactionKey ?? "", StringComparer.OrdinalIgnoreCase)
|
||||
.Select(pair => new AetheriaRuntimeFactionRelationshipCommit
|
||||
{
|
||||
FactionKey = pair.Key.FactionKey ?? "",
|
||||
|
|
|
|||
|
|
@ -56,13 +56,20 @@ public class Faction : INamedEntry
|
|||
set => Name = value;
|
||||
}
|
||||
|
||||
public bool HasSameKey(Faction other)
|
||||
{
|
||||
return other != null &&
|
||||
!string.IsNullOrWhiteSpace(FactionKey) &&
|
||||
string.Equals(FactionKey, other.FactionKey, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ID.GetHashCode();
|
||||
return StringComparer.OrdinalIgnoreCase.GetHashCode(FactionKey ?? "");
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Faction faction && faction.ID == ID;
|
||||
return obj is Faction faction && HasSameKey(faction);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ public abstract class Entity
|
|||
|
||||
// TODO: Inter-faction hostility
|
||||
// When the entity faction owns the zone, they are hostile to trespassers or those hostile to them
|
||||
if (Faction.ID == Zone.GalaxyZone.Owner?.ID)
|
||||
if (Faction.HasSameKey(Zone.GalaxyZone.Owner))
|
||||
return recursive ? !(other.PresencePermitted?.Value ?? true) : !(other.PresencePermitted?.Value ?? true)|| other.IsHostileTo(this, true);
|
||||
|
||||
return !recursive && other.IsHostileTo(this, true);
|
||||
|
|
@ -302,7 +302,7 @@ public abstract class Entity
|
|||
return FactionRelationship.Neutral;
|
||||
if (this is Ship {IsPlayerShip: true})
|
||||
return Zone.Galaxy.FactionRelationships[faction];
|
||||
return faction.ID == Faction.ID ? FactionRelationship.Beloved : FactionRelationship.Neutral;
|
||||
return faction.HasSameKey(Faction) ? FactionRelationship.Beloved : FactionRelationship.Neutral;
|
||||
}
|
||||
|
||||
public static bool IsPresencePermitted(FactionRelationship relationship, SecurityLevel securityLevel) =>
|
||||
|
|
|
|||
|
|
@ -254,6 +254,11 @@ public class Galaxy
|
|||
|
||||
private static Faction ProjectFaction(AetheriaRuntimeCorporation corporation)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(corporation.CorporationKey))
|
||||
{
|
||||
throw new InvalidOperationException($"Typed catalog corporation {corporation.Name} has no corporation key.");
|
||||
}
|
||||
|
||||
return new Faction
|
||||
{
|
||||
ID = ParseLegacyId(corporation.LegacyId, nameof(corporation.LegacyId), corporation.Name),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public class FactionPresenceConstraint : ZoneConstraint
|
|||
|
||||
protected override bool TestZone(GalaxyZone zone)
|
||||
{
|
||||
return zone.Factions.Any(f=>f.ID == TargetFaction?.ID);
|
||||
return zone.Factions.Any(f => f.HasSameKey(TargetFaction));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ public class FactionOwnerConstraint : ZoneConstraint
|
|||
|
||||
protected override bool TestZone(GalaxyZone zone)
|
||||
{
|
||||
return zone.Owner.ID == TargetFaction?.ID;
|
||||
return zone.Owner?.HasSameKey(TargetFaction) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,4 +86,4 @@ public class DistanceConstraint : ZoneConstraint
|
|||
{
|
||||
return _targetZone != null && _test(zone.Distance[_targetZone]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ public class Zone
|
|||
var security = SecurityLevel.Open;
|
||||
foreach (var entity in Entities)
|
||||
{
|
||||
if (entity is OrbitalEntity orbitalEntity && orbitalEntity.SecurityRadius > 1 && entity.Faction.ID == GalaxyZone.Owner.ID)
|
||||
if (entity is OrbitalEntity orbitalEntity && orbitalEntity.SecurityRadius > 1 && entity.Faction.HasSameKey(GalaxyZone.Owner))
|
||||
{
|
||||
if (orbitalEntity.SecurityLevel > security && length(orbitalEntity.Position.xz - pos) < orbitalEntity.SecurityRadius * Settings.SecureAreaRadiusMultiplier)
|
||||
security = orbitalEntity.SecurityLevel;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS
|
|||
Properties.Title.text = zone.Name;
|
||||
Properties.AddProperty("Owner", () => zone.Owner?.Name ?? "None");
|
||||
var otherFactions = zone.Factions
|
||||
.Where(f => f.ID != zone.Owner?.ID)
|
||||
.Where(f => !f.HasSameKey(zone.Owner))
|
||||
.Select(f=>f.Name).ToArray();
|
||||
if (otherFactions.Length > 0)
|
||||
Properties.AddProperty("Factions Present", () => string.Join(", ", otherFactions));
|
||||
|
|
|
|||
|
|
@ -1022,6 +1022,10 @@ First Aetheria surfaces to publish:
|
|||
- Done: delete the temporary `Faction` shell's `GeonameFile` and `BossHull`
|
||||
GUID link fields; galaxy name generation and boss-zone eligibility use
|
||||
`GeonameFileKey` and `BossHullItemKey`.
|
||||
- Done: move temporary `Faction` equality, hashing, narrative constraints,
|
||||
sector display filtering, zone security ownership checks, and runtime
|
||||
faction-relationship ordering to `FactionKey`. `Faction.ID` is now
|
||||
projection residue rather than comparison/order authority.
|
||||
- Done: move package and canonical manufacturer/corporation/name-file lookup
|
||||
to typed keys (`ManufacturerKey`, `CorporationKey`, `GeonameFileKey`,
|
||||
and `NameFileKey`), and move loadout manufacturer-distance weighting to
|
||||
|
|
@ -1764,6 +1768,9 @@ First Aetheria surfaces to publish:
|
|||
return.
|
||||
- `Aetheria.State.Verify` guards temporary `Faction` shell links: geoname and
|
||||
boss-hull relationships use typed keys, not legacy GUID projection fields.
|
||||
- `Aetheria.State.Verify` guards temporary `Faction` identity: equality,
|
||||
hashing, ordering, narrative checks, sector filtering, and zone security
|
||||
checks must use `FactionKey`, leaving `Faction.ID` as projection residue only.
|
||||
- Unity batchmode compile returned cleanly after the runtime blueprint rename;
|
||||
live Unity source has no `EntityPack`, `ShipPack`, `OrbitalEntityPack`,
|
||||
`ZonePack`, `PackedContents`, `PackZone`, `EntitySerializer.Pack`, or
|
||||
|
|
|
|||
Loading…
Reference in a new issue