fix(feature-flags): custom flags no longer throw; removing a flag restores its real default (#2654)

Two bugs found while reworking #2653.

**Custom flags throw.** `SyncStaticFlag` is a switch expression with no discard arm, so any key that has no static behind it throws `SwitchExpressionException`. `[FeatureFlag mykey create <category> <desc>` crashes in `CreateOrUpdateFlag`, and once such a key is in `flags.json`, every boot's `SyncAllStaticFlags()` throws mid-iteration — caught and logged as "Failed to load feature flags", but stock flags later in dictionary order never sync. Added `_ => enabled`.

**Removing a flag turns some features on.** `RemoveFlag` hardcoded `SyncStaticFlag(flagKey, true)`. For `speedhack_detection` and `insurance` the real default is `false` / `insurance.enable`, so deleting the flag enabled the feature. It now syncs the removed flag's `DefaultEnabled`, which #2653 seeds from the static.

Verified: `dotnet build Projects/UOContent/UOContent.csproj -c Release`, 0 `CS` diagnostics (post-build copy to `Distribution/` was blocked by a running server instance).
This commit is contained in:
Kamron Batman 2026-09-18 19:25:39 -07:00 committed by GitHub
parent f211607d63
commit 12b0886cef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -138,9 +138,9 @@ public static class FeatureFlagManager
public static bool RemoveFlag(string flagKey, string removedBy = "System")
{
if (_flags.Remove(flagKey))
if (_flags.Remove(flagKey, out var flag))
{
SyncStaticFlag(flagKey, true); // Reset to default enabled
SyncStaticFlag(flagKey, flag.DefaultEnabled);
if (FeatureFlagSettings.LogChanges)
{
@ -1018,6 +1018,9 @@ public static class FeatureFlagManager
"passive_detect_hidden" => ContentFeatureFlags.PassiveDetectHidden = enabled,
"young_player_system" => ContentFeatureFlags.YoungPlayerSystem = enabled,
"bitmap_pathfinding_cache" => ContentFeatureFlags.BitmapPathfindingCache = enabled,
// Custom flags have no static to mirror
_ => enabled,
};
}