about summary refs log tree commit diff
path: root/MiniUtils/Commands
diff options
context:
space:
mode:
Diffstat (limited to 'MiniUtils/Commands')
-rw-r--r--MiniUtils/Commands/DeleteRoomCommand.cs36
-rw-r--r--MiniUtils/Commands/DetectStateSplitCommand.cs72
-rw-r--r--MiniUtils/Commands/DumpTimelineCommand.cs38
-rw-r--r--MiniUtils/Commands/ExperimentalFeaturesCommand.cs5
-rw-r--r--MiniUtils/Commands/IgnoreCommand.cs4
-rw-r--r--MiniUtils/Commands/JoinCommand.cs26
-rw-r--r--MiniUtils/Commands/MakePolicyListCommand.cs1
-rw-r--r--MiniUtils/Commands/MscCommand.cs1
-rw-r--r--MiniUtils/Commands/OpsCommand.cs25
-rw-r--r--MiniUtils/Commands/RedactCommand.cs29
-rw-r--r--MiniUtils/Commands/SpamCommand.cs7
11 files changed, 193 insertions, 51 deletions
diff --git a/MiniUtils/Commands/DeleteRoomCommand.cs b/MiniUtils/Commands/DeleteRoomCommand.cs

index 41dbfb3..8d02dfb 100644 --- a/MiniUtils/Commands/DeleteRoomCommand.cs +++ b/MiniUtils/Commands/DeleteRoomCommand.cs
@@ -1,9 +1,4 @@ -using ArcaneLibs.Extensions; -using LibMatrix.EventTypes.Common; -using LibMatrix.EventTypes.Spec.State.RoomInfo; -using LibMatrix.Helpers; -using LibMatrix.Responses; -using LibMatrix.RoomTypes; +using LibMatrix.Homeservers; using LibMatrix.Utilities.Bot.Interfaces; namespace MiniUtils.Commands; @@ -18,30 +13,9 @@ public class DeleteRoomCommand() : ICommand { public bool Unlisted => false; public async Task Invoke(CommandContext ctx) { - var creationContent = new CreateRoomRequest() { - Name = ctx.Args[0], - RoomAliasName = ctx.Args[0], - Visibility = "private", - CreationContent = new() { - { "type", PolicyRoom.TypeName }, - { "room_version", 11 } - }, - PowerLevelContentOverride = new RoomPowerLevelEventContent() { - EventsDefault = 50, - Invite = 50 - }, - InitialState = [ - new() { - Type = MjolnirShortcodeEventContent.EventId, - StateKey = "", - TypedContent = new MjolnirShortcodeEventContent() { - Shortcode = ctx.Args[0] - } - } - ] - }; - - var result = await ctx.Homeserver.CreateRoom(creationContent); - await ctx.Room.SendMessageEventAsync(new MessageBuilder().WithMention($"#{ctx.Args[0]}:{ctx.Homeserver.ServerName}").Build()); + if (ctx.Homeserver is not AuthenticatedHomeserverSynapse synapse) return; + var res = await synapse.Admin.DeleteRoom(ctx.Args[0], new() { + Purge = true + }, waitForCompletion: false); } } \ No newline at end of file diff --git a/MiniUtils/Commands/DetectStateSplitCommand.cs b/MiniUtils/Commands/DetectStateSplitCommand.cs new file mode 100644
index 0000000..6180f20 --- /dev/null +++ b/MiniUtils/Commands/DetectStateSplitCommand.cs
@@ -0,0 +1,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()); + } +} \ No newline at end of file diff --git a/MiniUtils/Commands/DumpTimelineCommand.cs b/MiniUtils/Commands/DumpTimelineCommand.cs new file mode 100644
index 0000000..4ee53c9 --- /dev/null +++ b/MiniUtils/Commands/DumpTimelineCommand.cs
@@ -0,0 +1,38 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using LibMatrix; +using LibMatrix.Services; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace MiniUtils.Commands; + +public class DumpTimelineCommand(MiniUtilsConfiguration config, HomeserverProviderService hsProvider) : ICommand { + public string Name => "dump timeline"; + + public string[]? Aliases => ["dt"]; + + public string Description => "Dump timeline"; + + public bool Unlisted => false; + + public async Task Invoke(CommandContext ctx) { + MessagesResponse res; + if (ctx.Args.Length < 1) { + res = await ctx.Room.GetMessagesAsync(limit: 250); + } + else { + var profile = config.ExternalProfiles[ctx.Args[0]]; + var rhs = await hsProvider.GetAuthenticatedWithToken(profile.Homeserver, profile.AccessToken, enableServer: false, useGeneric: true); + res = await rhs.GetRoom(ctx.Room.RoomId).GetMessagesAsync(limit: 250); + } + + var ms = new MemoryStream(); + await JsonSerializer.SerializeAsync(ms, res, new JsonSerializerOptions() { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + WriteIndented = true + }); + ms.Seek(0, SeekOrigin.Begin); + + await ctx.Room.SendFileAsync("timeline.json", ms, contentType: "application/json"); + } +} \ No newline at end of file diff --git a/MiniUtils/Commands/ExperimentalFeaturesCommand.cs b/MiniUtils/Commands/ExperimentalFeaturesCommand.cs
index de5d035..8ae40d3 100644 --- a/MiniUtils/Commands/ExperimentalFeaturesCommand.cs +++ b/MiniUtils/Commands/ExperimentalFeaturesCommand.cs
@@ -1,9 +1,4 @@ -using System.Globalization; -using System.Net.Http.Json; -using System.Text; -using System.Text.Json.Nodes; using System.Text.RegularExpressions; -using LibMatrix.EventTypes.Spec.State; using LibMatrix.Extensions; using LibMatrix.Helpers; using LibMatrix.Utilities.Bot.Interfaces; diff --git a/MiniUtils/Commands/IgnoreCommand.cs b/MiniUtils/Commands/IgnoreCommand.cs
index 4b3fe86..4206b72 100644 --- a/MiniUtils/Commands/IgnoreCommand.cs +++ b/MiniUtils/Commands/IgnoreCommand.cs
@@ -51,6 +51,10 @@ public class IgnoreCommand(IgnoreListManager ignoreListManager) : ICommand { var count = await ignoreListManager.MoveList(true, itemsToEnable); await ctx.Room.SendReactionAsync(ctx.MessageEvent.EventId!, $"{Emojis.RightArrowWithTail} {count}"); } + else if (ctx.Args is ["add", .. var itemsToAdd]) { + var count = await ignoreListManager.AddList(itemsToAdd); + await ctx.Room.SendReactionAsync(ctx.MessageEvent.EventId!, $"{Emojis.RightArrowWithTail} {count}"); + } } private async Task Summarize(CommandContext ctx, IgnoredUserListEventContentWithDisabled ignoreList) { diff --git a/MiniUtils/Commands/JoinCommand.cs b/MiniUtils/Commands/JoinCommand.cs new file mode 100644
index 0000000..1ed51b6 --- /dev/null +++ b/MiniUtils/Commands/JoinCommand.cs
@@ -0,0 +1,26 @@ +using LibMatrix.EventTypes.Spec.State.RoomInfo; +using LibMatrix.Services; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace MiniUtils.Commands; + +public class JoinCommand(MiniUtilsConfiguration config, HomeserverProviderService hsProvider) : ICommand { + public string Name => "join"; + + public string[]? Aliases => []; + + public string Description => "Redact all user's events"; + + 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 joinRules = await ctx.Room.GetJoinRuleAsync(); + if (joinRules?.JoinRule is not RoomJoinRulesEventContent.JoinRules.Public) { + await ctx.Room.InviteUserAsync(rhs.UserId); + } + + _ = rhs.GetRoom(ctx.Room.RoomId).JoinAsync([ctx.Homeserver.ServerName]); + } +} \ No newline at end of file diff --git a/MiniUtils/Commands/MakePolicyListCommand.cs b/MiniUtils/Commands/MakePolicyListCommand.cs
index 0498712..40b0695 100644 --- a/MiniUtils/Commands/MakePolicyListCommand.cs +++ b/MiniUtils/Commands/MakePolicyListCommand.cs
@@ -1,4 +1,3 @@ -using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Common; using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Helpers; diff --git a/MiniUtils/Commands/MscCommand.cs b/MiniUtils/Commands/MscCommand.cs
index 62f1bd7..89e9aec 100644 --- a/MiniUtils/Commands/MscCommand.cs +++ b/MiniUtils/Commands/MscCommand.cs
@@ -1,4 +1,3 @@ -using LibMatrix.Extensions; using LibMatrix.Helpers; using LibMatrix.Utilities.Bot.Interfaces; using MiniUtils.Utilities; diff --git a/MiniUtils/Commands/OpsCommand.cs b/MiniUtils/Commands/OpsCommand.cs new file mode 100644
index 0000000..eef6c6f --- /dev/null +++ b/MiniUtils/Commands/OpsCommand.cs
@@ -0,0 +1,25 @@ +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Interfaces; +using MiniUtils.Services; + +namespace MiniUtils.Commands; + +public class OpsCommand(IgnoreListManager ignoreListManager) : ICommand { + public string Name => "ops"; + + public string[]? Aliases => ["admins", "mods"]; + + public string Description => "Ping all the mods"; + + public bool Unlisted => true; + + public async Task Invoke(CommandContext ctx) { + var pls = await ctx.Room.GetPowerLevelsAsync(); + var msb = new MessageBuilder(); + foreach (var pl in pls.Users.Where(x => x.Value >= pls.Kick)) { + msb = msb.WithMention(pl.Key).WithBody(" "); + } + + await ctx.Room.SendMessageEventAsync(msb.Build()); + } +} \ No newline at end of file diff --git a/MiniUtils/Commands/RedactCommand.cs b/MiniUtils/Commands/RedactCommand.cs
index cba06c9..e84191e 100644 --- a/MiniUtils/Commands/RedactCommand.cs +++ b/MiniUtils/Commands/RedactCommand.cs
@@ -1,6 +1,6 @@ using System.Collections.Frozen; using ArcaneLibs.Extensions; -using LibMatrix.EventTypes.Spec; +using LibMatrix; using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Filters; using LibMatrix.Helpers; @@ -19,10 +19,6 @@ public class RedactCommand(IgnoreListManager ignoreListManager) : ICommand { public string Description => "Redact all user's events"; public bool Unlisted => false; - private const string ThumbsUp = "\ud83d\udc4d\ufe0e"; - private const string Recycle = "\u267b\ufe0e"; - private const string Bullseye = "\u25ce\ufe0e"; - private const string RightArrowWithTail = "\u21a3\ufe0e"; public async Task Invoke(CommandContext ctx) { if (ctx.Args is ["banned"]) @@ -42,8 +38,7 @@ public class RedactCommand(IgnoreListManager ignoreListManager) : ICommand { foreach (var chunk in resp.Chunk.Chunk(49)) { foreach (var evt in chunk) { if (!senders.Contains(evt.Sender!)) continue; - if (evt is { StateKey: not null, Type: not RoomMemberEventContent.EventId }) continue; - if (evt is { RawContent: null or { Count: 0 } }) continue; + if(!await IsRedactionNeeded(ctx.Room, evt.EventId!, evt)) continue; tasks.Add(RedactEvent(ctx.Room, evt.EventId!)); count++; } @@ -64,6 +59,26 @@ public class RedactCommand(IgnoreListManager ignoreListManager) : ICommand { // await ctx.Room.SendReactionAsync(ctx.MessageEvent.EventId!, $"{Emojis.Recycle} {count}"); } + private async Task<bool> IsRedactionNeeded(GenericRoom roomId, string eventId, StateEventResponse? evt = null) { + evt ??= await roomId.GetEventAsync(eventId); + + // Ignore room member state events + if (evt is { StateKey: not null, Type: not RoomMemberEventContent.EventId }) return false; + + // Ignore redaction events + if (evt is { Type: RoomRedactionEventContent.EventId }) return false; + + // Ignore empty events + if (evt is { RawContent: null or { Count: 0 } }) return false; + + // Ignore redacted events + if (evt.Unsigned?.ContainsKey("redacted_because") == true) return false; + + + + throw new NotImplementedException("Redaction check not implemented"); + } + private async Task RedactEvent(GenericRoom room, string eventId) { bool success; do { diff --git a/MiniUtils/Commands/SpamCommand.cs b/MiniUtils/Commands/SpamCommand.cs
index 9f475eb..742ae3b 100644 --- a/MiniUtils/Commands/SpamCommand.cs +++ b/MiniUtils/Commands/SpamCommand.cs
@@ -1,8 +1,3 @@ -using System.Collections.Frozen; -using ArcaneLibs.Extensions; -using LibMatrix.EventTypes.Spec; -using LibMatrix.EventTypes.Spec.State.RoomInfo; -using LibMatrix.Filters; using LibMatrix.Helpers; using LibMatrix.RoomTypes; using LibMatrix.Utilities.Bot.Interfaces; @@ -18,7 +13,7 @@ public class SpamCommand(IgnoreListManager ignoreListManager) : ICommand { public string Description => "Redact all user's events"; - public bool Unlisted => false; + public bool Unlisted => true; public async Task Invoke(CommandContext ctx) { var tasks = Enumerable.Range(0, 10000)