Files
Campus-25/server/Server/2025-RecRoom-Server-E12354-main/api/dbs/CuratedListDB.cs
T
2026-10-14 06:59:51 +02:00

79 lines
3.1 KiB
C#

using LiteDB;
namespace Campus_live_rewrite.api.dbs
{
/// <summary>
/// A player's own curated lists (the Lists service's `list` table in the reference): the
/// Play menu's "Saved for Later" row is `__SavedForLater_Rooms` (type 1, room ids), created by
/// the client itself through PUT /lists/curatedlists/{name}/items/{itemId}/createlistifneeded.
/// One list per (owner, type, name).
/// </summary>
public static class CuratedListDB
{
private static readonly Lazy<LiteDatabase> _db = new(() => new LiteDatabase(Path.Combine("Data", "DBs", "CuratedLists.db")));
public class PlayerList
{
[BsonId] public long ListId { get; set; }
public ulong CreatorAccountId { get; set; }
public string Name { get; set; } = "";
public int Type { get; set; } = 1;
public int Accessibility { get; set; } = 0;
public List<string> ItemIds { get; set; } = new();
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
private static ILiteCollection<PlayerList> Col()
{
var c = _db.Value.GetCollection<PlayerList>("lists");
c.EnsureIndex(x => x.CreatorAccountId);
return c;
}
/// <summary>
/// A stable id for (owner, type, name) - the same list has the same id before and after it
/// is created, so a read that answers a not-yet-created reserved list (`__SavedForLater_Rooms`)
/// hands out the id the later write will use. Positive, 63-bit.
/// </summary>
public static long IdFor(ulong owner, int type, string name)
{
unchecked
{
ulong h = 1469598103934665603UL;
foreach (char ch in (name ?? "").ToLowerInvariant()) { h ^= ch; h *= 1099511628211UL; }
h ^= (ulong)type; h *= 1099511628211UL;
h ^= owner; h *= 1099511628211UL;
return (long)(h & 0x7FFF_FFFF_FFFF_FFFFUL) | 1L;
}
}
public static PlayerList? Get(ulong owner, int type, string name) =>
Col().FindById(IdFor(owner, type, name));
public static PlayerList? GetById(long listId) => Col().FindById(listId);
public static PlayerList AddItem(ulong owner, int type, string name, int accessibility, string itemId)
{
var col = Col();
long id = IdFor(owner, type, name);
var list = col.FindById(id) ?? new PlayerList
{
ListId = id, CreatorAccountId = owner, Name = name, Type = type, Accessibility = accessibility, CreatedAt = DateTime.UtcNow
};
if (!list.ItemIds.Contains(itemId)) list.ItemIds.Add(itemId);
col.Upsert(list);
return list;
}
public static PlayerList? RemoveItem(ulong owner, int type, string name, string itemId)
{
var col = Col();
var list = col.FindById(IdFor(owner, type, name));
if (list == null) return null;
list.ItemIds.RemoveAll(x => x == itemId);
col.Update(list);
return list;
}
}
}