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
|
using System.Collections.Frozen;
using ArcaneLibs.Extensions;
using LibMatrix;
using LibMatrix.Helpers;
using LibMatrix.Services;
using LibMatrix.Utilities.Bot.Interfaces;
namespace MiniUtils.Commands;
public class DetectStateSplitCommand(MiniUtilsConfiguration config, HomeserverProviderService hsProvider) : ICommand {
public string Name => "detect state split";
public string[]? Aliases => ["dss"];
public string Description => "Detect room splits";
public bool Unlisted => false;
public async Task Invoke(CommandContext ctx) {
var profile = config.ExternalProfiles[ctx.Args[0]];
var rhs = await hsProvider.GetAuthenticatedWithToken(profile.Homeserver, profile.AccessToken, enableServer: false, useGeneric: true);
var localStateTask = ctx.Room.GetFullStateAsListAsync();
var remoteStateTask = rhs.GetRoom(ctx.Room.RoomId).GetFullStateAsListAsync();
var localState = await localStateTask;
var remoteState = await remoteStateTask;
var keySet = localState.Concat(remoteState)
.Select(x => (x.Type, x.StateKey))
.ToFrozenSet();
var differences = 0;
foreach (var keyPair in keySet) {
var local = localState.FirstOrDefault(x => x.Type == keyPair.Type && x.StateKey == keyPair.StateKey);
var remote = remoteState.FirstOrDefault(x => x.Type == keyPair.Type && x.StateKey == keyPair.StateKey);
if (local == null) {
await ctx.Room.SendMessageEventAsync(new MessageBuilder()
.WithCollapsibleSection($"Missing {keyPair.Type} {keyPair.StateKey} locally", b =>
b.WithCodeBlock(remote.ToJson(ignoreNull: true), "json")
).Build());
differences++;
continue;
}
if (remote == null) {
await ctx.Room.SendMessageEventAsync(new MessageBuilder()
.WithCollapsibleSection($"Missing {keyPair.Type} {keyPair.StateKey} remotely", b =>
b.WithCodeBlock(local.ToJson(ignoreNull: true), "json")
).Build());
differences++;
continue;
}
if (!StateEvent.Equals(local, remote)) {
await ctx.Room.SendMessageEventAsync(new MessageBuilder()
.WithCollapsibleSection($"Different {keyPair.Type} {keyPair.StateKey}", b =>
b.WithCodeBlock(local.ToJson(ignoreNull: true), "json")
.WithCodeBlock(remote.ToJson(ignoreNull: true), "json")
).Build());
differences++;
}
}
if (differences > 0)
await ctx.Room.SendMessageEventAsync(new MessageBuilder().WithBody($"No differences found").Build());
else
await ctx.Room.SendMessageEventAsync(new MessageBuilder().WithBody($"Found {differences} differences!").Build());
// await ctx.Room.SendMessageEventAsync(new MessageBuilder().WithCodeBlock(rhs.WhoAmI.ToJson()).Build());
}
}
|