mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
Add Rec Center doors management: implement endpoints for retrieving and updating door configurations; enhance database schema and UI integration
This commit is contained in:
@@ -60,6 +60,18 @@ public class ServerSettingsService(DorkNetDbContext db)
|
||||
return ToPlayMenuTags(row);
|
||||
}
|
||||
|
||||
public async Task<RecCenterDoorSettings> GetRecCenterDoorsAsync()
|
||||
{
|
||||
var row = await GetAsync();
|
||||
return ToRecCenterDoors(row);
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<GameConfigurationSetting>> GetGameConfigurationsAsync()
|
||||
{
|
||||
var doors = await GetRecCenterDoorsAsync();
|
||||
return ToGameConfigurations(doors);
|
||||
}
|
||||
|
||||
public async Task<PlayMenuTagSettings> SetPlayMenuTagsAsync(
|
||||
IReadOnlyList<string> pinned,
|
||||
IReadOnlyList<string> popular)
|
||||
@@ -72,6 +84,17 @@ public class ServerSettingsService(DorkNetDbContext db)
|
||||
return normalized with { UpdatedAt = existing.UpdatedAt };
|
||||
}
|
||||
|
||||
public async Task<RecCenterDoorSettings> SetRecCenterDoorsAsync(
|
||||
IReadOnlyList<RecCenterDoorConfig> doors)
|
||||
{
|
||||
var normalized = NormalizeRecCenterDoors(doors);
|
||||
var existing = await GetTrackedRowAsync();
|
||||
existing.RecCenterDoorsJson = JsonSerializer.Serialize(normalized, JsonOptions);
|
||||
existing.UpdatedAt = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync();
|
||||
return normalized with { UpdatedAt = existing.UpdatedAt };
|
||||
}
|
||||
|
||||
public async Task<WeeklyChallengeSettings> SetWeeklyChallengesAsync(
|
||||
bool completedRequired,
|
||||
IReadOnlyList<WeeklyChallengeTemplate> challenges,
|
||||
@@ -163,6 +186,29 @@ public class ServerSettingsService(DorkNetDbContext db)
|
||||
return DefaultPlayMenuTags() with { UpdatedAt = row.UpdatedAt };
|
||||
}
|
||||
|
||||
private static RecCenterDoorSettings ToRecCenterDoors(ServerSettingsEntity row)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(row.RecCenterDoorsJson))
|
||||
{
|
||||
try
|
||||
{
|
||||
var parsed = JsonSerializer.Deserialize<RecCenterDoorSettings>(
|
||||
row.RecCenterDoorsJson,
|
||||
JsonOptions);
|
||||
if (parsed is not null)
|
||||
return NormalizeRecCenterDoors(parsed.Doors)
|
||||
with { UpdatedAt = row.UpdatedAt };
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Bad settings should not break Rec Center startup; admins
|
||||
// can overwrite them from the SPA.
|
||||
}
|
||||
}
|
||||
|
||||
return DefaultRecCenterDoors() with { UpdatedAt = row.UpdatedAt };
|
||||
}
|
||||
|
||||
private static List<WeeklyChallengeTemplate> NormalizeWeeklyChallenges(
|
||||
IReadOnlyList<WeeklyChallengeTemplate> challenges)
|
||||
{
|
||||
@@ -265,6 +311,42 @@ public class ServerSettingsService(DorkNetDbContext db)
|
||||
],
|
||||
UpdatedAt: DateTime.UtcNow);
|
||||
|
||||
public static RecCenterDoorSettings DefaultRecCenterDoors() =>
|
||||
new(
|
||||
Doors:
|
||||
[
|
||||
new("Shooters", "Shooters", "#paintball|#lasertag|#recroyale"),
|
||||
new("Creative", "Creative", "#creative|#makerpen|#template"),
|
||||
new("Quests", "Quests", "#quest"),
|
||||
new("Sports", "Sports", "#sport"),
|
||||
new("Featured", "Featured", "#featured|#recroomoriginal"),
|
||||
],
|
||||
UpdatedAt: DateTime.UtcNow);
|
||||
|
||||
public static IReadOnlyList<GameConfigurationSetting> ToGameConfigurations(
|
||||
RecCenterDoorSettings doors)
|
||||
{
|
||||
var rows = new List<GameConfigurationSetting>();
|
||||
foreach (var door in NormalizeRecCenterDoors(doors.Doors).Doors)
|
||||
{
|
||||
rows.Add(new($"Door.{door.Key}.Title", door.Title));
|
||||
rows.Add(new($"Door.{door.Key}.Query", door.Query));
|
||||
}
|
||||
|
||||
rows.AddRange([
|
||||
new("Rewards.UseRewardSelection", "false"),
|
||||
new("RoomDetails.PhotoRollEnabled", "false"),
|
||||
new("SynchronizedField.RemoveDefaultEntries", "false"),
|
||||
new("Rendering.DisableSrpBatcher", "false"),
|
||||
new("splitTestSoftOverrides", "{}"),
|
||||
new("splitTestHardOverrides", "{}"),
|
||||
new("splitTestSegmentProbabilities", "{}"),
|
||||
new("loadingNetworkTimeout", "30"),
|
||||
new("runningNetworkTimeout", "30"),
|
||||
]);
|
||||
return rows;
|
||||
}
|
||||
|
||||
private static PlayMenuTagSettings NormalizePlayMenuTags(
|
||||
IReadOnlyList<string> pinned,
|
||||
IReadOnlyList<string> popular)
|
||||
@@ -289,6 +371,50 @@ public class ServerSettingsService(DorkNetDbContext db)
|
||||
popularTags.Count > 0 ? popularTags : defaults.PopularTags,
|
||||
DateTime.UtcNow);
|
||||
}
|
||||
|
||||
private static RecCenterDoorSettings NormalizeRecCenterDoors(
|
||||
IReadOnlyList<RecCenterDoorConfig> doors)
|
||||
{
|
||||
static string NormalizeKey(string value)
|
||||
{
|
||||
var clean = new string((value ?? string.Empty)
|
||||
.Where(char.IsLetterOrDigit)
|
||||
.ToArray());
|
||||
return string.IsNullOrWhiteSpace(clean) ? string.Empty : clean;
|
||||
}
|
||||
|
||||
static string NormalizeQuery(string value)
|
||||
{
|
||||
var tags = (value ?? string.Empty)
|
||||
.Split(['|', ',', '\n', '\r', ' ', '\t'], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.Select(t => t.Trim().TrimStart('#').ToLowerInvariant())
|
||||
.Where(t => t.Length > 0)
|
||||
.Where(t => t.All(c => char.IsLetterOrDigit(c) || c is '-' or '_'))
|
||||
.Select(t => $"#{t}")
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Take(12)
|
||||
.ToList();
|
||||
return string.Join("|", tags);
|
||||
}
|
||||
|
||||
var normalized = doors
|
||||
.Select(d =>
|
||||
{
|
||||
var key = NormalizeKey(d.Key);
|
||||
var title = string.IsNullOrWhiteSpace(d.Title) ? key : d.Title.Trim();
|
||||
var query = NormalizeQuery(d.Query);
|
||||
return new RecCenterDoorConfig(key, title, query);
|
||||
})
|
||||
.Where(d => d.Key.Length > 0 && d.Query.Length > 0)
|
||||
.GroupBy(d => d.Key, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(g => g.First())
|
||||
.Take(8)
|
||||
.ToList();
|
||||
|
||||
return new RecCenterDoorSettings(
|
||||
normalized.Count > 0 ? normalized : DefaultRecCenterDoors().Doors,
|
||||
DateTime.UtcNow);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record WeeklyChallengeSettings(
|
||||
@@ -320,3 +446,18 @@ public sealed record PlayMenuTagSettings(
|
||||
List<string> PinnedTags,
|
||||
List<string> PopularTags,
|
||||
DateTime UpdatedAt);
|
||||
|
||||
public sealed record RecCenterDoorSettings(
|
||||
List<RecCenterDoorConfig> Doors,
|
||||
DateTime UpdatedAt);
|
||||
|
||||
public sealed record RecCenterDoorConfig(
|
||||
string Key,
|
||||
string Title,
|
||||
string Query);
|
||||
|
||||
public sealed record GameConfigurationSetting(
|
||||
string Key,
|
||||
string Value,
|
||||
DateTime? StartTime = null,
|
||||
DateTime? EndTime = null);
|
||||
|
||||
Reference in New Issue
Block a user