namespace NeonSprawl.Server.Game.Factions; /// Id normalization for faction standing stores (NEO-135). public static class FactionStandingIds { /// Trim + lowercase; empty when input is null/whitespace. public static string NormalizePlayerId(string? playerId) { var trimmed = playerId?.Trim(); if (string.IsNullOrEmpty(trimmed)) { return string.Empty; } return trimmed.ToLowerInvariant(); } /// Trim; empty when input is null/whitespace. Faction ids stay case-sensitive (catalog ids are lowercase snake). public static string NormalizeFactionId(string? factionId) { var trimmed = factionId?.Trim(); return string.IsNullOrEmpty(trimmed) ? string.Empty : trimmed; } /// Composite store key for + . public static string MakeStandingKey(string? playerId, string? factionId) { var player = NormalizePlayerId(playerId); var faction = NormalizeFactionId(factionId); if (player.Length == 0 || faction.Length == 0) { return string.Empty; } return $"{player}\0{faction}"; } /// Clamps to the faction definition band. public static int ClampStanding(int standing, FactionDefRow definition) => Math.Clamp(standing, definition.MinStanding, definition.MaxStanding); }