using System.Collections.Frozen; using ArcaneLibs.Extensions; using LibMatrix; using LibMatrix.EventTypes.Spec; using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Filters; using LibMatrix.Helpers; using LibMatrix.Homeservers; using LibMatrix.Responses.Federation; using LibMatrix.RoomTypes; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using MiniUtils.Classes; using MiniUtils.Services; namespace MiniUtils.Commands; public class ServersCommand(HomeserverProviderService hsProvider) : ICommand { public string Name => "servers"; public string[]? Aliases => []; public string Description => "Get a list of servers in the room"; public bool Unlisted => false; public async Task Invoke(CommandContext ctx) { var lastUpdated = DateTime.Now; var servers = (await ctx.Room.GetMembersByHomeserverAsync()).Keys.Select(GetServerVersionAsync).ToList().ToAsyncResultEnumerable(); Dictionary> serverVersions = new(); var message = new MessageBuilder() .WithBody($"[{Emojis.Hourglass}] {Emojis.Recycle} Gathering server versions, please wait...") .Build(); var eventId = await ctx.Room.SendMessageEventAsync(message); await foreach (var result in servers) { if (!serverVersions.TryGetValue(result, out var serverNames)) { serverNames = []; serverVersions[result] = serverNames; } serverNames.Add(result.Server); if (DateTime.Now - lastUpdated > TimeSpan.FromMilliseconds(500)) { lastUpdated = DateTime.Now; var msb = new MessageBuilder() .WithBody($"[{Emojis.Hourglass}] {serverVersions.Count} servers found so far:").WithNewline(); foreach (var (res, serversByVersion) in serverVersions.Where(x => x.Key is ServerVersionResponse)) { var svr = (ServerVersionResponse)res; msb.WithBody($"- {svr.Server.Name} {svr.Server.Version}: {string.Join(", ", serversByVersion)}").WithNewline(); } await ctx.Room.SendMessageEventAsync( msb.Build() .SetReplaceRelation(eventId.EventId) ); } } await ctx.Room.SendMessageEventAsync(new MessageBuilder() .WithBody($"[{Emojis.Bullseye}] {serverVersions.Count} servers found:") .Build() .SetReplaceRelation(eventId.EventId) ); } private async Task<(string Server, object Result)> GetServerVersionAsync(string server) { try { var hs = await hsProvider.GetRemoteHomeserver(server); var version = await hs.FederationClient.GetServerVersionAsync(); return (server, version); } catch (Exception e) { return (server, e); } } }