Files
Radicade/Server/Rooms/RoomAssetStore.cs
T
2026-10-16 23:33:13 -07:00

96 lines
3.5 KiB
C#

using Microsoft.EntityFrameworkCore;
using RadicadeServer.DB;
using RadicadeServer.RecNet.Config;
using System.Text.Json;
namespace RadicadeServer.API.Rooms.V1;
internal sealed class RoomAssetRecord
{
public string Id { get; set; } = "";
public long RoomId { get; set; }
public string Kind { get; set; } = "";
public Dictionary<string, object?> Fields { get; set; } = new(StringComparer.OrdinalIgnoreCase);
}
internal static class RoomAssetStore
{
private const string ConfigKey = "RoomAssets";
private static readonly SemaphoreSlim Gate = new(1, 1);
public static async Task<List<RoomAssetRecord>> LoadAsync(RecDBContext db)
{
var config = await db.ServerConfig.AsNoTracking().FirstOrDefaultAsync(row => row.Key == ConfigKey);
if (string.IsNullOrWhiteSpace(config?.Value)) return new List<RoomAssetRecord>();
try
{
return JsonSerializer.Deserialize<List<RoomAssetRecord>>(config.Value,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new List<RoomAssetRecord>();
}
catch (JsonException)
{
return new List<RoomAssetRecord>();
}
}
public static async Task<List<RoomAssetRecord>> ForRoomAsync(RecDBContext db, long roomId, string kind)
{
var records = await LoadAsync(db);
return records.Where(record => record.RoomId == roomId &&
string.Equals(record.Kind, kind, StringComparison.OrdinalIgnoreCase)).ToList();
}
public static async Task SaveAsync(RecDBContext db, RoomAssetRecord record)
{
await Gate.WaitAsync();
try
{
var config = await db.ServerConfig.FirstOrDefaultAsync(row => row.Key == ConfigKey);
List<RoomAssetRecord> records;
try
{
records = string.IsNullOrWhiteSpace(config?.Value)
? new List<RoomAssetRecord>()
: JsonSerializer.Deserialize<List<RoomAssetRecord>>(config.Value,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new List<RoomAssetRecord>();
}
catch (JsonException)
{
records = new List<RoomAssetRecord>();
}
records.RemoveAll(existing => existing.RoomId == record.RoomId &&
string.Equals(existing.Kind, record.Kind, StringComparison.OrdinalIgnoreCase) &&
existing.Id == record.Id);
records.Add(record);
if (config == null)
{
config = new ServerConfigVal(ConfigKey, JsonSerializer.Serialize(records));
await db.ServerConfig.AddAsync(config);
}
else
{
config.Value = JsonSerializer.Serialize(records);
}
await db.SaveChangesAsync();
}
finally
{
Gate.Release();
}
}
public static async Task<List<Dictionary<string, object?>>> GetDtosAsync(RecDBContext db, long roomId, string kind)
{
var records = await ForRoomAsync(db, roomId, kind);
return records.Select(record =>
{
var dto = new Dictionary<string, object?>(record.Fields, StringComparer.OrdinalIgnoreCase);
dto[kind.Equals("currency", StringComparison.OrdinalIgnoreCase) ? "CurrencyId" : "ConsumableId"] = record.Id;
dto["RoomId"] = record.RoomId;
return dto;
}).ToList();
}
}