fix(feature-flags): define stock flag defaults in code so JSONs exist on first boot (#2653)
### Summary `default-flags.json` was never shipped — `Configuration/` is gitignored — so the predefined-flag loader has been dead since #2328. A fresh shard boots with 0 flags and writes no JSON until an admin changes something, so `[FeatureList` is empty on first run. Stock flags are now defined in code. `Initialize()` runs `Load()` first, then `LoadDefaultFlags()` seeds any of the 14 stock keys the save is missing, reading each default from the static it syncs (`ServerFeatureFlags` / `ContentFeatureFlags`) rather than a duplicated boolean — so `speedhack_detection` stays off and `insurance` honors `Insurance.Configure` (`insurance.enable`). Existing entries are never overwritten, so admin state survives upgrades and saves predating a flag pick it up. `Save()` runs only when something was seeded, so all five JSON files exist from first boot. Verified: `dotnet build Projects/UOContent/UOContent.csproj -c Release`, 0 warnings 0 errors.
This commit is contained in:
parent
34ab194c00
commit
35e3a31b4c
1 changed files with 47 additions and 7 deletions
|
|
@ -40,9 +40,8 @@ public static class FeatureFlagManager
|
||||||
Directory.CreateDirectory(savePath);
|
Directory.CreateDirectory(savePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load predefined flags from JSON, then overlay runtime state
|
|
||||||
LoadDefaultFlags();
|
|
||||||
Load();
|
Load();
|
||||||
|
LoadDefaultFlags();
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
logger.Information(
|
logger.Information(
|
||||||
|
|
@ -751,14 +750,55 @@ public static class FeatureFlagManager
|
||||||
|
|
||||||
private static void LoadDefaultFlags()
|
private static void LoadDefaultFlags()
|
||||||
{
|
{
|
||||||
var defaultFlagsPath = Path.Combine(Core.BaseDirectory, "Configuration", "FeatureFlags", "default-flags.json");
|
(string Key, string Category, string Description, bool Enabled)[] defaults =
|
||||||
var defaultFlags = JsonConfig.Deserialize<List<FeatureFlag>>(defaultFlagsPath);
|
[
|
||||||
if (defaultFlags != null)
|
("player_trading", "Economy", "Allow secure trades between players", ServerFeatureFlags.PlayerTrading),
|
||||||
|
("pvp_combat", "Combat", "Allow player vs player combat", ServerFeatureFlags.PvPCombat),
|
||||||
|
("bank_access", "Economy", "Allow players to access their bank boxes", ServerFeatureFlags.BankAccess),
|
||||||
|
("speedhack_detection", "System", "Enable speedhack detection", ServerFeatureFlags.SpeedhackDetection),
|
||||||
|
("insurance", "Economy", "Enable item insurance", ServerFeatureFlags.InsuranceEnabled),
|
||||||
|
("vendor_purchase", "Economy", "Allow purchasing from NPC vendors", ContentFeatureFlags.VendorPurchase),
|
||||||
|
("vendor_sell", "Economy", "Allow selling to NPC vendors", ContentFeatureFlags.VendorSell),
|
||||||
|
("player_vendors", "Economy", "Allow player vendor interactions", ContentFeatureFlags.PlayerVendors),
|
||||||
|
("house_placement", "Housing", "Allow new house placements", ContentFeatureFlags.HousePlacement),
|
||||||
|
("boat_placement", "Housing", "Allow new boat placements", ContentFeatureFlags.BoatPlacement),
|
||||||
|
("bulk_orders", "Crafting", "Allow bulk order deeds", ContentFeatureFlags.BulkOrders),
|
||||||
|
("passive_detect_hidden", "System", "Enable passive detect hidden", ContentFeatureFlags.PassiveDetectHidden),
|
||||||
|
("young_player_system", "System", "Enable the young player system", ContentFeatureFlags.YoungPlayerSystem),
|
||||||
|
("bitmap_pathfinding_cache", "Performance", "Enable the bitmap pathfinding cache", ContentFeatureFlags.BitmapPathfindingCache),
|
||||||
|
];
|
||||||
|
|
||||||
|
var now = Core.Now;
|
||||||
|
var added = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < defaults.Length; i++)
|
||||||
{
|
{
|
||||||
foreach (var flag in defaultFlags)
|
var (key, category, description, enabled) = defaults[i];
|
||||||
|
if (_flags.ContainsKey(key))
|
||||||
{
|
{
|
||||||
_flags.TryAdd(flag.Key, flag);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_flags.Add(
|
||||||
|
key,
|
||||||
|
new FeatureFlag
|
||||||
|
{
|
||||||
|
Key = key,
|
||||||
|
Description = description,
|
||||||
|
Category = category,
|
||||||
|
DefaultEnabled = enabled,
|
||||||
|
Enabled = enabled,
|
||||||
|
LastModified = now,
|
||||||
|
LastModifiedBy = "System"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
added++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added > 0)
|
||||||
|
{
|
||||||
|
Save();
|
||||||
|
logger.Information("Seeded {Count} default feature flag(s)", added);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue