summary refs log tree commit diff
path: root/extra/admin-api/Spacebar.Offload/Controllers
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-06-21 20:41:01 +0200
committerRory& <root@rory.gay>2026-06-21 20:41:01 +0200
commit3d07e05fd0ddd19a22a2883d3dc3446b2cfbe27d (patch)
treec9cb0bfd4643a9dc3a9c30fb66728a2b1c68b308 /extra/admin-api/Spacebar.Offload/Controllers
parentPublish LazyRequest typescript attempt, partial C# impl (diff)
downloadserver-ts-3d07e05fd0ddd19a22a2883d3dc3446b2cfbe27d.tar.xz
Get basic member list working in offload
Diffstat (limited to 'extra/admin-api/Spacebar.Offload/Controllers')
-rw-r--r--extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs67
1 files changed, 50 insertions, 17 deletions
diff --git a/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs b/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs

index 95998151e..f34455542 100644 --- a/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs +++ b/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs
@@ -34,12 +34,56 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen yield break; } + var memberList = await GetGuildMemberListAsync(db, payload.GuildId); + + yield return new ReplicationMessage<GuildMemberListUpdate>() { + UserId = user.Result.Id, + Event = GuildMemberListUpdate.EventId, + Origin = "Offload/LazyRequest", + CreatedAt = DateTime.UtcNow, + Payload = new GuildMemberListUpdate() { + GuildId = payload.GuildId, + ListId = payload.GuildId.ToString(), + OnlineCount = memberList.TakeWhile(x => x is not RoleEntry { Id: "offline" }).Count(), + MemberCount = await db.Members.CountAsync(x => x.GuildId == payload.GuildId), + Operations = [ + new GuildMemberListUpdateOperation.SyncOperation() { + Items = memberList.Select<IMemberListEntry, GuildMemberListSyncItem>(item => item is RoleEntry re + ? new GuildMemberListSyncItem.RoleEntry() { Id = re.Id, Count = re.Count } + : item is MemberEntry me + ? new GuildMemberListSyncItem.MemberEntry() { Member = me.Member } + : throw new InvalidCastException("List item was neither RoleEntry nor MemberEntry???")) + .ToList(), + Range = [0, memberList.Count] + } + ], + Groups = memberList.OfType<RoleEntry>().Select(re => new GuildMemberListSyncItem.RoleEntry() { Id = re.Id, Count = re.Count }).ToList() + } + // TODO: send presence updates + // TODO: handle subscriptions + // TODO: handle channel permissions + // TODO: handle channels at all + }; + } + + private async Task<string?> GetMemberListIdAsync(SpacebarDbContext db, long guildId, long channelId) { + var channel = await db.Channels.AsNoTracking().FirstOrDefaultAsync(c => c.Id == channelId && c.GuildId == guildId); + if (channel == null) return null; + + if (string.IsNullOrWhiteSpace(channel.PermissionOverwrites) || channel.PermissionOverwrites == "[]") { + return "everyone"; + } + + return null; // TODO + } + + private async Task<List<IMemberListEntry>> GetGuildMemberListAsync(SpacebarDbContext db, long guildId) { var memberList = new List<IMemberListEntry>(); // Fetch hoisted roles for the guild to define groups var hoistedRoles = await db.Roles .AsNoTracking() - .Where(r => r.GuildId == payload.GuildId && r.Hoist) + .Where(r => r.GuildId == guildId && r.Hoist) .OrderByDescending(r => r.Position) // .Select(r => r.Id) .ToListAsync(); @@ -51,7 +95,7 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen var members = await db.Members.AsNoTracking() .Include(x => x.IdNavigation) .Where(x => - x.GuildId == payload.GuildId + x.GuildId == guildId && x.Roles.Any(r => r.Id == role) && !x.Roles.Any(r => handledRoles.Contains(r.Id)) // and finally, filter by online @@ -74,7 +118,7 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen .Include(x => x.IdNavigation) // .ThenInclude(x=>x.Sessions) .Where(x => - x.GuildId == payload.GuildId + x.GuildId == guildId && !x.Roles.Any(r => handledRoles.Contains(r.Id)) // and finally, filter by online && x.IdNavigation.Sessions.Any(s => s.Status != "offline" && s.Status != "invisible" && s.Status != "unknown") @@ -90,14 +134,13 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen memberList.AddRange(onlineMembers.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() })); } - if (memberList.Count < 2000) { logger.LogInformation("Less than 2000 members, including offline members..."); var offlineMembers = await db.Members.AsNoTracking() .Include(x => x.IdNavigation) // .ThenInclude(x=>x.Sessions) .Where(x => - x.GuildId == payload.GuildId + x.GuildId == guildId && !x.Roles.Any(r => handledRoles.Contains(r.Id)) // and finally, filter by online && (x.IdNavigation.Sessions.Any(s => s.Status == "offline" || s.Status == "invisible" || s.Status == "unknown") || !x.IdNavigation.Sessions.Any()) @@ -115,24 +158,14 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen } logger.LogInformation("Got member list with {count} total nodes", memberList.Count); - } - - private async Task<string?> GetMemberListIdAsync(SpacebarDbContext db, long guildId, long channelId) { - var channel = await db.Channels.AsNoTracking().FirstOrDefaultAsync(c => c.Id == channelId && c.GuildId == guildId); - if (channel == null) return null; - - if (string.IsNullOrWhiteSpace(channel.PermissionOverwrites) || channel.PermissionOverwrites == "[]") { - return "everyone"; - } - - return null; // TODO + return memberList; } } internal interface IMemberListEntry { } internal struct RoleEntry : IMemberListEntry { - [JsonPropertyName("id"), JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + [JsonPropertyName("id")] public string Id { get; set; } [JsonPropertyName("count")]