about summary refs log tree commit diff
path: root/MiniUtils/Commands/ServersCommand.cs
blob: 7e5c97aa99b7e56c514acde4a18aa808aa200ef9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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<object, List<string>> 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<RoomMessageEventContent>(eventId.EventId)
                );
            }
        }

        await ctx.Room.SendMessageEventAsync(new MessageBuilder()
            .WithBody($"[{Emojis.Bullseye}] {serverVersions.Count} servers found:")
            .Build()
            .SetReplaceRelation<RoomMessageEventContent>(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);
        }
    }
}