diff options
Diffstat (limited to '')
-rw-r--r-- | LibMatrix/Helpers/HomeserverWeightEstimation.cs | 2 | ||||
-rw-r--r-- | LibMatrix/Helpers/MessageBuilder.cs | 31 | ||||
-rw-r--r-- | LibMatrix/Helpers/MessageFormatter.cs | 55 | ||||
-rw-r--r-- | LibMatrix/Helpers/SyncHelper.cs | 20 | ||||
-rw-r--r-- | LibMatrix/Helpers/SyncStateResolver.cs | 106 |
5 files changed, 95 insertions, 119 deletions
diff --git a/LibMatrix/Helpers/HomeserverWeightEstimation.cs b/LibMatrix/Helpers/HomeserverWeightEstimation.cs index 02f9185..5735af3 100644 --- a/LibMatrix/Helpers/HomeserverWeightEstimation.cs +++ b/LibMatrix/Helpers/HomeserverWeightEstimation.cs @@ -55,4 +55,4 @@ public class HomeserverWeightEstimation { { "!OGEhHVWSdvArJzumhm:matrix.org", 101457 }, { "!YTvKGNlinIzlkMTVRl:matrix.org", 30164 } }; -} +} \ No newline at end of file diff --git a/LibMatrix/Helpers/MessageBuilder.cs b/LibMatrix/Helpers/MessageBuilder.cs index 250187a..68f6300 100644 --- a/LibMatrix/Helpers/MessageBuilder.cs +++ b/LibMatrix/Helpers/MessageBuilder.cs @@ -8,46 +8,42 @@ public class MessageBuilder(string msgType = "m.text", string format = "org.matr MessageType = msgType, Format = format }; - + public RoomMessageEventContent Build() => Content; - + public MessageBuilder WithBody(string body) { Content.Body += body; Content.FormattedBody += body; return this; } - + public MessageBuilder WithHtmlTag(string tag, string body, Dictionary<string, string>? attributes = null) { Content.Body += body; Content.FormattedBody += $"<{tag}"; - if (attributes != null) { - foreach (var (key, value) in attributes) { + if (attributes != null) + foreach (var (key, value) in attributes) Content.FormattedBody += $" {key}=\"{value}\""; - } - } Content.FormattedBody += $">{body}</{tag}>"; return this; } - + public MessageBuilder WithHtmlTag(string tag, Action<MessageBuilder> bodyBuilder, Dictionary<string, string>? attributes = null) { Content.FormattedBody += $"<{tag}"; - if (attributes != null) { - foreach (var (key, value) in attributes) { + if (attributes != null) + foreach (var (key, value) in attributes) Content.FormattedBody += $" {key}=\"{value}\""; - } - } Content.FormattedBody += ">"; bodyBuilder(this); Content.FormattedBody += $"</{tag}>"; return this; } - + public MessageBuilder WithColoredBody(string color, string body) { Content.Body += body; Content.FormattedBody += $"<font color=\"{color}\">{body}</font>"; return this; } - + public MessageBuilder WithColoredBody(string color, Action<MessageBuilder> bodyBuilder) { Content.FormattedBody += $"<font color=\"{color}\">"; bodyBuilder(this); @@ -55,7 +51,7 @@ public class MessageBuilder(string msgType = "m.text", string format = "org.matr return this; } - public MessageBuilder WithRainbowString(string text, byte skip = 1, int offset = 0, double lengthFactor = 255.0, bool useLength = true) { + public MessageBuilder WithRainbowString(string text, byte skip = 1, int offset = 0, double lengthFactor = 255.0, bool useLength = true) => // if (useLength) { // lengthFactor = text.Length; // } @@ -67,8 +63,5 @@ public class MessageBuilder(string msgType = "m.text", string format = "org.matr // // Console.WriteLine($"RBA: {r} {g} {b} {a}"); // // Content.FormattedBody += $"<font color=\"#{r:X2}{g:X2}{b:X2}\">{text[i]}</font>"; // } - - return this; - } - + this; } \ No newline at end of file diff --git a/LibMatrix/Helpers/MessageFormatter.cs b/LibMatrix/Helpers/MessageFormatter.cs index b7c6975..1b9b4f3 100644 --- a/LibMatrix/Helpers/MessageFormatter.cs +++ b/LibMatrix/Helpers/MessageFormatter.cs @@ -4,73 +4,64 @@ using LibMatrix.EventTypes.Spec; namespace LibMatrix.Helpers; public static class MessageFormatter { - public static RoomMessageEventContent FormatError(string error) { - return new RoomMessageEventContent(body: error, messageType: "m.text") { + public static RoomMessageEventContent FormatError(string error) => + new(body: error, messageType: "m.text") { FormattedBody = $"<font color=\"#EE4444\">{error}</font>", Format = "org.matrix.custom.html" }; - } - public static RoomMessageEventContent FormatException(string error, Exception e) { - return new RoomMessageEventContent(body: $"{error}: {e.Message}", messageType: "m.text") { + public static RoomMessageEventContent FormatException(string error, Exception e) => + new(body: $"{error}: {e.Message}", messageType: "m.text") { FormattedBody = $"<font color=\"#EE4444\">{error}: <pre><code>{e.Message}</code></pre></font>", Format = "org.matrix.custom.html" }; - } - public static RoomMessageEventContent FormatSuccess(string text) { - return new RoomMessageEventContent(body: text, messageType: "m.text") { + public static RoomMessageEventContent FormatSuccess(string text) => + new(body: text, messageType: "m.text") { FormattedBody = $"<font color=\"#00FF00\">{text}</font>", Format = "org.matrix.custom.html" }; - } - public static RoomMessageEventContent FormatSuccessJson(string text, object data) { - return new RoomMessageEventContent(body: text, messageType: "m.text") { + public static RoomMessageEventContent FormatSuccessJson(string text, object data) => + new(body: text, messageType: "m.text") { FormattedBody = $"<font color=\"#00FF00\">{text}: <pre><code>{data.ToJson(ignoreNull: true)}</code></pre></font>", Format = "org.matrix.custom.html" }; - } - public static string HtmlFormatMention(string id, string? displayName = null) { - return $"<a href=\"https://matrix.to/#/{id}\">{displayName ?? id}</a>"; - } + public static string HtmlFormatMention(string id, string? displayName = null) => $"<a href=\"https://matrix.to/#/{id}\">{displayName ?? id}</a>"; public static string HtmlFormatMessageLink(string roomId, string eventId, string[]? servers = null, string? displayName = null) { if (servers is not { Length: > 0 }) servers = new[] { roomId.Split(':', 2)[1] }; return $"<a href=\"https://matrix.to/#/{roomId}/{eventId}?via={string.Join("&via=", servers)}\">{displayName ?? eventId}</a>"; } - #region Extension functions +#region Extension functions public static RoomMessageEventContent ToMatrixMessage(this Exception e, string error) => FormatException(error, e); - #endregion +#endregion - public static RoomMessageEventContent FormatWarning(string warning) { - return new RoomMessageEventContent(body: warning, messageType: "m.text") { + public static RoomMessageEventContent FormatWarning(string warning) => + new(body: warning, messageType: "m.text") { FormattedBody = $"<font color=\"#FFFF00\">{warning}</font>", Format = "org.matrix.custom.html" }; - } - - public static RoomMessageEventContent FormatWarningJson(string warning, object data) { - return new RoomMessageEventContent(body: warning, messageType: "m.text") { + + public static RoomMessageEventContent FormatWarningJson(string warning, object data) => + new(body: warning, messageType: "m.text") { FormattedBody = $"<font color=\"#FFFF00\">{warning}: <pre><code>{data.ToJson(ignoreNull: true)}</code></pre></font>", Format = "org.matrix.custom.html" }; - } - - public static RoomMessageEventContent Concat(this RoomMessageEventContent a, RoomMessageEventContent b) { - return new RoomMessageEventContent(body: $"{a.Body}{b.Body}", messageType: a.MessageType) { + + public static RoomMessageEventContent Concat(this RoomMessageEventContent a, RoomMessageEventContent b) => + new(body: $"{a.Body}{b.Body}", messageType: a.MessageType) { FormattedBody = $"{a.FormattedBody}{b.FormattedBody}", Format = a.Format }; - } - public static RoomMessageEventContent ConcatLine(this RoomMessageEventContent a, RoomMessageEventContent b) { - return new RoomMessageEventContent(body: $"{a.Body}\n{b.Body}", messageType: "m.text") { + + public static RoomMessageEventContent ConcatLine(this RoomMessageEventContent a, RoomMessageEventContent b) => + new(body: $"{a.Body}\n{b.Body}", messageType: "m.text") { FormattedBody = $"{a.FormattedBody}<br/>{b.FormattedBody}", Format = "org.matrix.custom.html" }; - } -} +} \ No newline at end of file diff --git a/LibMatrix/Helpers/SyncHelper.cs b/LibMatrix/Helpers/SyncHelper.cs index 636cfdd..47e5b1e 100644 --- a/LibMatrix/Helpers/SyncHelper.cs +++ b/LibMatrix/Helpers/SyncHelper.cs @@ -28,6 +28,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg _filter = null; } } + public string? NamedFilterName { get => _namedFilterName; set { @@ -81,11 +82,11 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg var url = $"/_matrix/client/v3/sync?timeout={Timeout}&set_presence={SetPresence}&full_state={(FullState ? "true" : "false")}"; if (!string.IsNullOrWhiteSpace(Since)) url += $"&since={Since}"; if (_filterId is not null) url += $"&filter={_filterId}"; - + logger?.LogInformation("SyncHelper: Calling: {}", url); - + try { - var httpResp = await homeserver.ClientHttpClient.GetAsync(url, cancellationToken: cancellationToken ?? CancellationToken.None); + var httpResp = await homeserver.ClientHttpClient.GetAsync(url, cancellationToken ?? CancellationToken.None); if (httpResp is null) throw new NullReferenceException("Failed to send HTTP request"); logger?.LogInformation("Got sync response: {} bytes, {} elapsed", httpResp.Content.Headers.ContentLength ?? -1, sw.Elapsed); var deserializeSw = Stopwatch.StartNew(); @@ -120,8 +121,8 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg public async Task RunSyncLoopAsync(bool skipInitialSyncEvents = true, CancellationToken? cancellationToken = null) { var sw = Stopwatch.StartNew(); - int emptyInitialSyncCount = 0; - int syncCount = 0; + var emptyInitialSyncCount = 0; + var syncCount = 0; var oldTimeout = Timeout; Timeout = 0; await foreach (var sync in EnumerateSyncAsync(cancellationToken)) { @@ -163,27 +164,25 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg var tasks = SyncReceivedHandlers.Select(x => x(syncResponse)).ToList(); await Task.WhenAll(tasks); - if (syncResponse.AccountData is { Events.Count: > 0 }) { + if (syncResponse.AccountData is { Events.Count: > 0 }) foreach (var accountDataEvent in syncResponse.AccountData.Events) { tasks = AccountDataReceivedHandlers.Select(x => x(accountDataEvent)).ToList(); await Task.WhenAll(tasks); } - } await RunSyncLoopRoomCallbacksAsync(syncResponse, isInitialSync); } private async Task RunSyncLoopRoomCallbacksAsync(SyncResponse syncResponse, bool isInitialSync) { - if (syncResponse.Rooms is { Invite.Count: > 0 }) { + if (syncResponse.Rooms is { Invite.Count: > 0 }) foreach (var roomInvite in syncResponse.Rooms.Invite) { var tasks = InviteReceivedHandlers.Select(x => x(roomInvite)).ToList(); await Task.WhenAll(tasks); } - } if (isInitialSync) return; - if (syncResponse.Rooms is { Join.Count: > 0 }) { + if (syncResponse.Rooms is { Join.Count: > 0 }) foreach (var updatedRoom in syncResponse.Rooms.Join) { if (updatedRoom.Value.Timeline is null) continue; foreach (var stateEventResponse in updatedRoom.Value.Timeline.Events) { @@ -192,7 +191,6 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg await Task.WhenAll(tasks); } } - } } /// <summary> diff --git a/LibMatrix/Helpers/SyncStateResolver.cs b/LibMatrix/Helpers/SyncStateResolver.cs index f380a1f..72d600d 100644 --- a/LibMatrix/Helpers/SyncStateResolver.cs +++ b/LibMatrix/Helpers/SyncStateResolver.cs @@ -15,7 +15,7 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge public SyncResponse? MergedState { get; set; } - private SyncHelper _syncHelper = new SyncHelper(homeserver, logger); + private SyncHelper _syncHelper = new(homeserver, logger); public async Task<(SyncResponse next, SyncResponse merged)> ContinueAsync(CancellationToken? cancellationToken = null) { // copy properties @@ -36,61 +36,55 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge private SyncResponse MergeSyncs(SyncResponse oldState, SyncResponse newState) { oldState.NextBatch = newState.NextBatch ?? oldState.NextBatch; - oldState.AccountData ??= new(); - oldState.AccountData.Events ??= new(); + oldState.AccountData ??= new EventList(); + oldState.AccountData.Events ??= new List<StateEventResponse>(); if (newState.AccountData?.Events is not null) - oldState.AccountData.Events.MergeStateEventLists(newState.AccountData?.Events ?? new()); + oldState.AccountData.Events.MergeStateEventLists(newState.AccountData?.Events ?? new List<StateEventResponse>()); - oldState.Presence ??= new(); + oldState.Presence ??= new SyncResponse.PresenceDataStructure(); if (newState.Presence?.Events is not null) - oldState.Presence.Events.MergeStateEventLists(newState.Presence?.Events ?? new()); + oldState.Presence.Events.MergeStateEventLists(newState.Presence?.Events ?? new List<StateEventResponse>()); - oldState.DeviceOneTimeKeysCount ??= new(); + oldState.DeviceOneTimeKeysCount ??= new Dictionary<string, int>(); if (newState.DeviceOneTimeKeysCount is not null) - foreach (var (key, value) in newState.DeviceOneTimeKeysCount) { + foreach (var (key, value) in newState.DeviceOneTimeKeysCount) oldState.DeviceOneTimeKeysCount[key] = value; - } - oldState.Rooms ??= new(); + oldState.Rooms ??= new SyncResponse.RoomsDataStructure(); if (newState.Rooms is not null) oldState.Rooms = MergeRoomsDataStructure(oldState.Rooms, newState.Rooms); - oldState.ToDevice ??= new(); - oldState.ToDevice.Events ??= new(); + oldState.ToDevice ??= new EventList(); + oldState.ToDevice.Events ??= new List<StateEventResponse>(); if (newState.ToDevice?.Events is not null) - oldState.ToDevice.Events.MergeStateEventLists(newState.ToDevice?.Events ?? new()); + oldState.ToDevice.Events.MergeStateEventLists(newState.ToDevice?.Events ?? new List<StateEventResponse>()); - oldState.DeviceLists ??= new(); + oldState.DeviceLists ??= new SyncResponse.DeviceListsDataStructure(); if (newState.DeviceLists?.Changed is not null) - foreach (var s in oldState.DeviceLists.Changed!) { + foreach (var s in oldState.DeviceLists.Changed!) oldState.DeviceLists.Changed.Add(s); - } if (newState.DeviceLists?.Left is not null) - foreach (var s in oldState.DeviceLists.Left!) { + foreach (var s in oldState.DeviceLists.Left!) oldState.DeviceLists.Left.Add(s); - } - return oldState; } - #region Merge rooms +#region Merge rooms private SyncResponse.RoomsDataStructure MergeRoomsDataStructure(SyncResponse.RoomsDataStructure oldState, SyncResponse.RoomsDataStructure newState) { - oldState.Join ??= new(); - foreach (var (key, value) in newState.Join ?? new()) { + oldState.Join ??= new Dictionary<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure>(); + foreach (var (key, value) in newState.Join ?? new Dictionary<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure>()) if (!oldState.Join.ContainsKey(key)) oldState.Join[key] = value; else oldState.Join[key] = MergeJoinedRoomDataStructure(oldState.Join[key], value); - } - oldState.Invite ??= new(); - foreach (var (key, value) in newState.Invite ?? new()) { + oldState.Invite ??= new Dictionary<string, SyncResponse.RoomsDataStructure.InvitedRoomDataStructure>(); + foreach (var (key, value) in newState.Invite ?? new Dictionary<string, SyncResponse.RoomsDataStructure.InvitedRoomDataStructure>()) if (!oldState.Invite.ContainsKey(key)) oldState.Invite[key] = value; else oldState.Invite[key] = MergeInvitedRoomDataStructure(oldState.Invite[key], value); - } - oldState.Leave ??= new(); - foreach (var (key, value) in newState.Leave ?? new()) { + oldState.Leave ??= new Dictionary<string, SyncResponse.RoomsDataStructure.LeftRoomDataStructure>(); + foreach (var (key, value) in newState.Leave ?? new Dictionary<string, SyncResponse.RoomsDataStructure.LeftRoomDataStructure>()) { if (!oldState.Leave.ContainsKey(key)) oldState.Leave[key] = value; else oldState.Leave[key] = MergeLeftRoomDataStructure(oldState.Leave[key], value); if (oldState.Invite.ContainsKey(key)) oldState.Invite.Remove(key); @@ -102,67 +96,67 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge private SyncResponse.RoomsDataStructure.LeftRoomDataStructure MergeLeftRoomDataStructure(SyncResponse.RoomsDataStructure.LeftRoomDataStructure oldData, SyncResponse.RoomsDataStructure.LeftRoomDataStructure newData) { - oldData.AccountData ??= new(); - oldData.AccountData.Events ??= new(); - oldData.Timeline ??= new(); - oldData.Timeline.Events ??= new(); - oldData.State ??= new(); - oldData.State.Events ??= new(); + oldData.AccountData ??= new EventList(); + oldData.AccountData.Events ??= new List<StateEventResponse>(); + oldData.Timeline ??= new SyncResponse.RoomsDataStructure.JoinedRoomDataStructure.TimelineDataStructure(); + oldData.Timeline.Events ??= new List<StateEventResponse>(); + oldData.State ??= new EventList(); + oldData.State.Events ??= new List<StateEventResponse>(); if (newData.AccountData?.Events is not null) - oldData.AccountData.Events.MergeStateEventLists(newData.AccountData?.Events ?? new()); + oldData.AccountData.Events.MergeStateEventLists(newData.AccountData?.Events ?? new List<StateEventResponse>()); if (newData.Timeline?.Events is not null) - oldData.Timeline.Events.MergeStateEventLists(newData.Timeline?.Events ?? new()); + oldData.Timeline.Events.MergeStateEventLists(newData.Timeline?.Events ?? new List<StateEventResponse>()); oldData.Timeline.Limited = newData.Timeline?.Limited ?? oldData.Timeline.Limited; oldData.Timeline.PrevBatch = newData.Timeline?.PrevBatch ?? oldData.Timeline.PrevBatch; if (newData.State?.Events is not null) - oldData.State.Events.MergeStateEventLists(newData.State?.Events ?? new()); + oldData.State.Events.MergeStateEventLists(newData.State?.Events ?? new List<StateEventResponse>()); return oldData; } private SyncResponse.RoomsDataStructure.InvitedRoomDataStructure MergeInvitedRoomDataStructure(SyncResponse.RoomsDataStructure.InvitedRoomDataStructure oldData, SyncResponse.RoomsDataStructure.InvitedRoomDataStructure newData) { - oldData.InviteState ??= new(); - oldData.InviteState.Events ??= new(); + oldData.InviteState ??= new EventList(); + oldData.InviteState.Events ??= new List<StateEventResponse>(); if (newData.InviteState?.Events is not null) - oldData.InviteState.Events.MergeStateEventLists(newData.InviteState?.Events ?? new()); + oldData.InviteState.Events.MergeStateEventLists(newData.InviteState?.Events ?? new List<StateEventResponse>()); return oldData; } private SyncResponse.RoomsDataStructure.JoinedRoomDataStructure MergeJoinedRoomDataStructure(SyncResponse.RoomsDataStructure.JoinedRoomDataStructure oldData, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure newData) { - oldData.AccountData ??= new(); - oldData.AccountData.Events ??= new(); - oldData.Timeline ??= new(); - oldData.Timeline.Events ??= new(); - oldData.State ??= new(); - oldData.State.Events ??= new(); - oldData.Ephemeral ??= new(); - oldData.Ephemeral.Events ??= new(); + oldData.AccountData ??= new EventList(); + oldData.AccountData.Events ??= new List<StateEventResponse>(); + oldData.Timeline ??= new SyncResponse.RoomsDataStructure.JoinedRoomDataStructure.TimelineDataStructure(); + oldData.Timeline.Events ??= new List<StateEventResponse>(); + oldData.State ??= new EventList(); + oldData.State.Events ??= new List<StateEventResponse>(); + oldData.Ephemeral ??= new EventList(); + oldData.Ephemeral.Events ??= new List<StateEventResponse>(); if (newData.AccountData?.Events is not null) - oldData.AccountData.Events.MergeStateEventLists(newData.AccountData?.Events ?? new()); + oldData.AccountData.Events.MergeStateEventLists(newData.AccountData?.Events ?? new List<StateEventResponse>()); if (newData.Timeline?.Events is not null) - oldData.Timeline.Events.MergeStateEventLists(newData.Timeline?.Events ?? new()); + oldData.Timeline.Events.MergeStateEventLists(newData.Timeline?.Events ?? new List<StateEventResponse>()); oldData.Timeline.Limited = newData.Timeline?.Limited ?? oldData.Timeline.Limited; oldData.Timeline.PrevBatch = newData.Timeline?.PrevBatch ?? oldData.Timeline.PrevBatch; if (newData.State?.Events is not null) - oldData.State.Events.MergeStateEventLists(newData.State?.Events ?? new()); + oldData.State.Events.MergeStateEventLists(newData.State?.Events ?? new List<StateEventResponse>()); if (newData.Ephemeral?.Events is not null) - oldData.Ephemeral.Events.MergeStateEventLists(newData.Ephemeral?.Events ?? new()); + oldData.Ephemeral.Events.MergeStateEventLists(newData.Ephemeral?.Events ?? new List<StateEventResponse>()); - oldData.UnreadNotifications ??= new(); + oldData.UnreadNotifications ??= new SyncResponse.RoomsDataStructure.JoinedRoomDataStructure.UnreadNotificationsDataStructure(); oldData.UnreadNotifications.HighlightCount = newData.UnreadNotifications?.HighlightCount ?? oldData.UnreadNotifications.HighlightCount; oldData.UnreadNotifications.NotificationCount = newData.UnreadNotifications?.NotificationCount ?? oldData.UnreadNotifications.NotificationCount; - oldData.Summary ??= new() { + oldData.Summary ??= new SyncResponse.RoomsDataStructure.JoinedRoomDataStructure.SummaryDataStructure { Heroes = newData.Summary?.Heroes ?? oldData.Summary.Heroes, JoinedMemberCount = newData.Summary?.JoinedMemberCount ?? oldData.Summary.JoinedMemberCount, InvitedMemberCount = newData.Summary?.InvitedMemberCount ?? oldData.Summary.InvitedMemberCount @@ -174,5 +168,5 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge return oldData; } - #endregion -} +#endregion +} \ No newline at end of file |