about summary refs log tree commit diff
diff options
context:
space:
mode:
m---------ArcaneLibs0
-rw-r--r--LibMatrix/Helpers/MessageBuilder.cs18
-rw-r--r--LibMatrix/Helpers/RoomBuilder.cs17
-rw-r--r--LibMatrix/Helpers/RoomUpgradeBuilder.cs81
-rw-r--r--LibMatrix/Responses/CreateRoomRequest.cs1
-rw-r--r--LibMatrix/RoomTypes/GenericRoom.cs2
6 files changed, 116 insertions, 3 deletions
diff --git a/ArcaneLibs b/ArcaneLibs
-Subproject fef0025c87017e1fd25b59f464a354fea746bc6
+Subproject d3f0ba9cb7ec36ab2f9574fd563c467b61512b9
diff --git a/LibMatrix/Helpers/MessageBuilder.cs b/LibMatrix/Helpers/MessageBuilder.cs

index 6f55739..f753bf7 100644 --- a/LibMatrix/Helpers/MessageBuilder.cs +++ b/LibMatrix/Helpers/MessageBuilder.cs
@@ -95,8 +95,13 @@ public class MessageBuilder(string msgType = "m.text", string format = "org.matr return this; } - public MessageBuilder WithMention(string id, string? displayName = null) { - Content.Body += $"@{displayName ?? id}"; + public MessageBuilder WithMention(string id, string? displayName = null, string[]? vias = null, bool useIdInPlainText = false, bool useLinkInPlainText = false) { + if (!useLinkInPlainText) Content.Body += $"@{(useIdInPlainText ? id : displayName ?? id)}"; + else { + Content.Body += $"https://matrix.to/#/{id}"; + if (vias is { Length: > 0 }) Content.Body += $"?via={string.Join("&via=", vias)}"; + } + Content.FormattedBody += $"<a href=\"https://matrix.to/#/{id}\">{displayName ?? id}</a>"; if (id == "@room") { Content.Mentions ??= new(); @@ -111,6 +116,15 @@ public class MessageBuilder(string msgType = "m.text", string format = "org.matr return this; } + public MessageBuilder WithRoomMention() { + // Legacy push rules support + Content.Body += "@room"; + Content.FormattedBody += "@room"; + Content.Mentions ??= new(); + Content.Mentions.Room = true; + return this; + } + public MessageBuilder WithNewline() { Content.Body += "\n"; Content.FormattedBody += "<br>"; diff --git a/LibMatrix/Helpers/RoomBuilder.cs b/LibMatrix/Helpers/RoomBuilder.cs
index ae01d11..8843a21 100644 --- a/LibMatrix/Helpers/RoomBuilder.cs +++ b/LibMatrix/Helpers/RoomBuilder.cs
@@ -1,4 +1,5 @@ using System.Runtime.Intrinsics.X86; +using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Homeservers; using LibMatrix.Responses; @@ -34,6 +35,8 @@ public class RoomBuilder { AllowIpLiterals = false }; + public RoomEncryptionEventContent? Encryption { get; set; } + /// <summary> /// State events to be sent *before* room access is configured. Keep this small! /// </summary> @@ -47,7 +50,12 @@ public class RoomBuilder { /// <summary> /// Users to invite, with optional reason /// </summary> - public Dictionary<string, string?> Invites { get; set; } = new(); + public Dictionary<string, string?> Invites { get; set; } = []; + + /// <summary> + /// Users to ban, with optional reason + /// </summary> + public Dictionary<string, string?> Bans { get; set; } = []; public RoomPowerLevelEventContent PowerLevels { get; set; } = new() { EventsDefault = 0, @@ -184,6 +192,13 @@ public class RoomBuilder { private async Task SetAccessAsync(GenericRoom room) { if(!V12PlusRoomVersions.Contains(Version)) PowerLevels.Users![room.Homeserver.WhoAmI.UserId] = OwnPowerLevel; + else { + PowerLevels.Users!.Remove(room.Homeserver.WhoAmI.UserId); + foreach (var additionalCreator in AdditionalCreators) + { + PowerLevels.Users!.Remove(additionalCreator); + } + } await room.SendStateEventAsync(RoomPowerLevelEventContent.EventId, PowerLevels); if (!string.IsNullOrWhiteSpace(HistoryVisibility.HistoryVisibility)) diff --git a/LibMatrix/Helpers/RoomUpgradeBuilder.cs b/LibMatrix/Helpers/RoomUpgradeBuilder.cs new file mode 100644
index 0000000..cbc7876 --- /dev/null +++ b/LibMatrix/Helpers/RoomUpgradeBuilder.cs
@@ -0,0 +1,81 @@ +using System.Text.Json.Serialization; +using LibMatrix.EventTypes.Spec; +using LibMatrix.EventTypes.Spec.State.RoomInfo; +using LibMatrix.RoomTypes; + +namespace LibMatrix.Helpers; + +public class RoomUpgradeBuilder(GenericRoom oldRoom) : RoomBuilder { + public GenericRoom OldRoom { get; } = oldRoom; + public RoomUpgradeOptions UpgradeOptions { get; set; } = new(); + + public async Task ImportAsync() { + await foreach (var evt in OldRoom.GetFullStateAsync()) { + if (evt is null) continue; + if (evt.StateKey == "") { + if (evt.TypedContent is RoomCreateEventContent createEvt) + foreach (var (key, value) in evt.RawContent) { + if (key == "version") continue; + if (key == "type") + Type = value!.GetValue<string>(); + else AdditionalCreationContent[key] = value; + } + else if (evt.TypedContent is RoomNameEventContent name) + Name = name; + else if (evt.TypedContent is RoomTopicEventContent topic) + Topic = topic; + else if (evt.TypedContent is RoomAvatarEventContent avatar) + Avatar = avatar; + else if (evt.TypedContent is RoomCanonicalAliasEventContent alias) { + CanonicalAlias = alias; + AliasLocalPart = alias.Alias?.Split(':',2).FirstOrDefault()?[1..] ?? string.Empty; + } + else if (evt.TypedContent is RoomJoinRulesEventContent joinRules) + JoinRules = joinRules; + else if (evt.TypedContent is RoomHistoryVisibilityEventContent historyVisibility) + HistoryVisibility = historyVisibility; + else if (evt.TypedContent is RoomGuestAccessEventContent guestAccess) + GuestAccess = guestAccess; + else if (evt.TypedContent is RoomServerAclEventContent serverAcls) + ServerAcls = serverAcls; + else if (evt.TypedContent is RoomPowerLevelEventContent powerLevels) { + if (UpgradeOptions.InvitePowerlevelUsers && powerLevels.Users != null) + foreach (var (userId, level) in powerLevels.Users) + if (level > powerLevels.UsersDefault) + Invites.Add(userId, "Room upgrade (had a power level)"); + + PowerLevels = powerLevels; + } + else if (evt.TypedContent is RoomEncryptionEventContent encryption) + Encryption = encryption; + else if (evt.TypedContent is RoomPinnedEventContent) ; // Discard as you can't cross reference pinned events + else InitialState.Add(evt); + } + else if (evt.Type == RoomMemberEventContent.EventId) { + if (UpgradeOptions.InviteMembers && evt.TypedContent is RoomMemberEventContent { Membership: "join" or "invite" }) + if (!Invites.ContainsKey(evt.StateKey)) + Invites.Add(evt.StateKey, "Room upgrade"); + else if (UpgradeOptions.MigrateBans && evt.TypedContent is RoomMemberEventContent { Membership: "ban" } bannedMember) + Bans.Add(evt.StateKey, bannedMember.Reason); + } + else InitialState.Add(evt); + } + } + + public class RoomUpgradeOptions { + public bool InviteMembers { get; set; } + public bool InvitePowerlevelUsers { get; set; } + public bool MigrateBans { get; set; } + + [JsonIgnore] + public Func<GenericRoom, Task<RoomMessageEventContent>> RoomUpgradeNotice { get; set; } = async newRoom => new MessageBuilder() + .WithRoomMention() + .WithBody("This room has been upgraded to a new version. This version of the room will be kept as an archive.") + .WithNewline() + .WithBody("You can join the new room by clicking the link below:") + .WithNewline() + .WithRoomMention() + .WithMention(newRoom.RoomId, await newRoom.GetNameOrFallbackAsync(), vias: (await newRoom.GetHomeserversInRoom()).ToArray(), useLinkInPlainText: true) + .Build(); + } +} \ No newline at end of file diff --git a/LibMatrix/Responses/CreateRoomRequest.cs b/LibMatrix/Responses/CreateRoomRequest.cs
index 8f8af31..db7d004 100644 --- a/LibMatrix/Responses/CreateRoomRequest.cs +++ b/LibMatrix/Responses/CreateRoomRequest.cs
@@ -47,6 +47,7 @@ public class CreateRoomRequest { [JsonPropertyName("invite")] public List<string>? Invite { get; set; } + [JsonPropertyName("room_version")] public string? RoomVersion { get; set; } /// <summary> diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs
index 565776c..7fc942e 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs
@@ -695,6 +695,8 @@ public class GenericRoom { return creators[0].Split(':', 2)[1]; } + + public async Task<List<string>> GetHomeserversInRoom() => (await GetMemberIdsListAsync("join")).Select(x => x.Split(':', 2)[1]).Distinct().ToList(); } public class RoomIdResponse {