diff options
Diffstat (limited to '')
m--------- | ArcaneLibs | 0 | ||||
m--------- | ExampleBots/LibMatrix.ExampleBot | 0 | ||||
m--------- | ExampleBots/ModerationBot | 0 | ||||
m--------- | ExampleBots/PluralContactBotPoC | 0 | ||||
-rw-r--r-- | LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs | 4 | ||||
-rw-r--r-- | LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs | 22 | ||||
-rw-r--r-- | LibMatrix/Extensions/HttpClientExtensions.cs | 2 | ||||
-rw-r--r-- | LibMatrix/Helpers/SyncHelper.cs | 9 | ||||
-rw-r--r-- | LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs | 24 | ||||
-rw-r--r-- | LibMatrix/RoomTypes/GenericRoom.cs | 2 | ||||
-rw-r--r-- | LibMatrix/RoomTypes/SpaceRoom.cs | 5 | ||||
-rw-r--r-- | LibMatrix/Utilities/CommonSyncFilters.cs | 47 | ||||
-rw-r--r-- | Tests/LibMatrix.Tests/Tests/RoomTests.cs | 2 | ||||
-rw-r--r-- | Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs | 15 |
14 files changed, 108 insertions, 24 deletions
diff --git a/ArcaneLibs b/ArcaneLibs -Subproject f69bb51f21002870b0f2dd1c135209cabc83549 +Subproject f7bcde91ffd1ec285a3f6d3febbb2433daf9634 diff --git a/ExampleBots/LibMatrix.ExampleBot b/ExampleBots/LibMatrix.ExampleBot -Subproject ecda7b17dfd83d787bc12d7194103d20cd4a835 +Subproject 4f9311ed047c6e6a62e3d49be330a83a829b72f diff --git a/ExampleBots/ModerationBot b/ExampleBots/ModerationBot -Subproject ee6e58970f62fa19d04f07d06d6c1476bf7e278 +Subproject 8579db2c9099630b6a268015d586db73435032f diff --git a/ExampleBots/PluralContactBotPoC b/ExampleBots/PluralContactBotPoC -Subproject 14c20d6905640c8f691fec76752318a474fa0bc +Subproject 7ef0970090c1525a60063c0ba7c0a4bd9fd8cc2 diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs index b557e47..349c8a7 100644 --- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs @@ -43,6 +43,10 @@ public class RoomJoinRulesEventContent : EventContent { [JsonPropertyName("room_id")] public required string RoomId { get; set; } + + public static class Types { + public const string RoomMembership = "m.room_membership"; + } } public enum JoinRules { diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs index cb9ebb7..49a1b62 100644 --- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs @@ -59,15 +59,31 @@ public class RoomPowerLevelEventContent : EventContent { public bool UserHasStatePermission(string userId, string eventType) { ArgumentNullException.ThrowIfNull(userId); - return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, StateDefault ?? 50); + var userLevel = GetUserPowerLevel(userId); + var eventLevel = GetStateEventPowerLevel(eventType); + + Console.WriteLine($"{userId}={userLevel} >= {eventType}={eventLevel} = {userLevel >= eventLevel}"); + + return userLevel >= eventLevel; } public long GetUserPowerLevel(string userId) { ArgumentNullException.ThrowIfNull(userId); - return Users.TryGetValue(userId, out var level) ? level : UsersDefault ?? UsersDefault ?? 0; + if (Users is null) return UsersDefault ?? 0; + return Users.TryGetValue(userId, out var level) ? level : UsersDefault ?? 0; } - public long GetEventPowerLevel(string eventType) => Events.TryGetValue(eventType, out var level) ? level : EventsDefault ?? EventsDefault ?? 0; + public long GetStateEventPowerLevel(string eventType) { + ArgumentNullException.ThrowIfNull(eventType); + if (Events is null) return StateDefault ?? 0; + return Events.TryGetValue(eventType, out var level) ? level : StateDefault ?? 0; + } + + public long GetTimelineEventPowerLevel(string eventType) { + ArgumentNullException.ThrowIfNull(eventType); + if (Events is null) return EventsDefault ?? 0; + return Events.TryGetValue(eventType, out var level) ? level : EventsDefault ?? 0; + } public void SetUserPowerLevel(string userId, long powerLevel) { ArgumentNullException.ThrowIfNull(userId); diff --git a/LibMatrix/Extensions/HttpClientExtensions.cs b/LibMatrix/Extensions/HttpClientExtensions.cs index b2f45bd..60b1fc1 100644 --- a/LibMatrix/Extensions/HttpClientExtensions.cs +++ b/LibMatrix/Extensions/HttpClientExtensions.cs @@ -57,7 +57,7 @@ public class MatrixHttpClient : HttpClient { HttpResponseMessage responseMessage; // try { - responseMessage = await base.SendAsync(request, cancellationToken); + responseMessage = await base.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); // } // catch (Exception e) { // if (requestSettings is { Retries: 0 }) throw; diff --git a/LibMatrix/Helpers/SyncHelper.cs b/LibMatrix/Helpers/SyncHelper.cs index 47e5b1e..f9a7cb7 100644 --- a/LibMatrix/Helpers/SyncHelper.cs +++ b/LibMatrix/Helpers/SyncHelper.cs @@ -120,7 +120,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg } public async Task RunSyncLoopAsync(bool skipInitialSyncEvents = true, CancellationToken? cancellationToken = null) { - var sw = Stopwatch.StartNew(); + // var sw = Stopwatch.StartNew(); var emptyInitialSyncCount = 0; var syncCount = 0; var oldTimeout = Timeout; @@ -153,7 +153,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg Timeout = oldTimeout; } } - else if (syncCount > 15) + else if (syncCount > 15 && IsInitialSync) Console.WriteLine(sync.ToJson(ignoreNull: true, indent: true)); await RunSyncLoopCallbacksAsync(sync, IsInitialSync && skipInitialSyncEvents); @@ -212,4 +212,9 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg /// Event fired when an account data event is received /// </summary> public List<Func<StateEventResponse, Task>> AccountDataReceivedHandlers { get; } = new(); + + private void Log(string message) { + if (logger is null) Console.WriteLine(message); + else logger.LogInformation(message); + } } \ No newline at end of file diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs index 02f3e3a..1c93235 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -295,6 +295,27 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke } public async Task<FilterIdResponse> UploadFilterAsync(SyncFilter filter) { + List<List<string>?> senderLists = [ + filter.AccountData?.Senders, + filter.AccountData?.NotSenders, + filter.Presence?.Senders, + filter.Presence?.NotSenders, + filter.Room?.AccountData?.Senders, + filter.Room?.AccountData?.NotSenders, + filter.Room?.Ephemeral?.Senders, + filter.Room?.Ephemeral?.NotSenders, + filter.Room?.State?.Senders, + filter.Room?.State?.NotSenders, + filter.Room?.Timeline?.Senders, + filter.Room?.Timeline?.NotSenders + ]; + + foreach (var list in senderLists) + if (list is { Count: > 0 } && list.Contains("@me")) { + list.Remove("@me"); + list.Add(UserId); + } + var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/v3/user/" + UserId + "/filter", filter); return await resp.Content.ReadFromJsonAsync<FilterIdResponse>() ?? throw new Exception("Failed to upload filter?"); } @@ -327,8 +348,7 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke /// <returns>Filter ID response</returns> /// <exception cref="Exception"></exception> public async Task<FilterIdResponse> UploadNamedFilterAsync(string filterName, SyncFilter filter) { - var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/v3/user/" + UserId + "/filter", filter); - var idResp = await resp.Content.ReadFromJsonAsync<FilterIdResponse>() ?? throw new Exception("Failed to upload filter?"); + var idResp = await UploadFilterAsync(filter); var filterList = await GetNamedFilterListOrNullAsync() ?? new Dictionary<string, string>(); filterList[filterName] = idResp.FilterId; diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index eee6041..cf32df8 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -435,7 +435,7 @@ public class GenericRoom { #region Disband room - public async Task DisbandRoomAsync() { + public async Task PermanentlyBrickRoomAsync() { var states = GetFullStateAsync(); List<string> stateTypeIgnore = new() { "m.room.create", diff --git a/LibMatrix/RoomTypes/SpaceRoom.cs b/LibMatrix/RoomTypes/SpaceRoom.cs index 9bd1173..49e751d 100644 --- a/LibMatrix/RoomTypes/SpaceRoom.cs +++ b/LibMatrix/RoomTypes/SpaceRoom.cs @@ -1,5 +1,6 @@ using ArcaneLibs.Extensions; using LibMatrix.Homeservers; +using Microsoft.Extensions.Logging; namespace LibMatrix.RoomTypes; @@ -31,4 +32,8 @@ public class SpaceRoom(AuthenticatedHomeserverGeneric homeserver, string roomId) }); return resp; } + + public async Task<EventIdResponse> AddChildByIdAsync(string id) { + return await AddChildAsync(Homeserver.GetRoom(id)); + } } \ No newline at end of file diff --git a/LibMatrix/Utilities/CommonSyncFilters.cs b/LibMatrix/Utilities/CommonSyncFilters.cs index 8e727be..bf8b987 100644 --- a/LibMatrix/Utilities/CommonSyncFilters.cs +++ b/LibMatrix/Utilities/CommonSyncFilters.cs @@ -1,5 +1,7 @@ using System.Collections.Frozen; +using LibMatrix.EventTypes.Common; using LibMatrix.EventTypes.Spec.State; +using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Filters; namespace LibMatrix.Utilities; @@ -9,15 +11,16 @@ public static class CommonSyncFilters { public const string GetAccountDataWithRooms = "gay.rory.libmatrix.get_account_data_with_rooms.v0"; public const string GetBasicRoomInfo = "gay.rory.matrixutils.get_basic_room_info.v0"; public const string GetSpaceRelations = "gay.rory.matrixutils.get_space_relations.v0"; + public const string GetOwnMemberEvents = "gay.rory.matrixutils.get_own_member_events.v0"; - public static readonly SyncFilter GetAccountDataFilter = new() { + public static SyncFilter GetAccountDataFilter => new() { Presence = new SyncFilter.EventFilter(notTypes: ["*"]), Room = new SyncFilter.RoomFilter() { Rooms = [] } }; - public static readonly SyncFilter GetAccountDataWithRoomsFilter = new() { + public static SyncFilter GetAccountDataWithRoomsFilter => new() { Presence = new SyncFilter.EventFilter(notTypes: ["*"]), Room = new SyncFilter.RoomFilter() { State = new SyncFilter.RoomFilter.StateFilter(notTypes: ["*"]), @@ -26,7 +29,7 @@ public static class CommonSyncFilters { } }; - public static readonly SyncFilter GetBasicRoomDataFilter = new() { + public static SyncFilter GetBasicRoomDataFilter => new() { AccountData = new SyncFilter.EventFilter(notTypes: ["*"], limit: 1), Presence = new SyncFilter.EventFilter(notTypes: ["*"], limit: 1), Room = new SyncFilter.RoomFilter { @@ -34,11 +37,11 @@ public static class CommonSyncFilters { Ephemeral = new SyncFilter.RoomFilter.StateFilter(rooms: []), State = new SyncFilter.RoomFilter.StateFilter { Types = new List<string> { - "m.room.create", - "m.room.name", - "m.room.avatar", - "org.matrix.mjolnir.shortcode", - "m.room.power_levels" + RoomCreateEventContent.EventId, + RoomNameEventContent.EventId, + RoomAvatarEventContent.EventId, + MjolnirShortcodeEventContent.EventId, + RoomPowerLevelEventContent.EventId }, LazyLoadMembers = true, IncludeRedundantMembers = false }, @@ -46,7 +49,7 @@ public static class CommonSyncFilters { } }; - public static readonly SyncFilter GetSpaceRelationsFilter = new() { + public static SyncFilter GetSpaceRelationsFilter => new() { AccountData = new SyncFilter.EventFilter(notTypes: ["*"], limit: 1), Presence = new SyncFilter.EventFilter(notTypes: ["*"], limit: 1), Room = new SyncFilter.RoomFilter { @@ -54,8 +57,8 @@ public static class CommonSyncFilters { Ephemeral = new SyncFilter.RoomFilter.StateFilter(rooms: []), State = new SyncFilter.RoomFilter.StateFilter { Types = new List<string> { - "m.space.child", - "m.space.parent" + SpaceChildEventContent.EventId, + SpaceParentEventContent.EventId }, LazyLoadMembers = true, IncludeRedundantMembers = false }, @@ -63,11 +66,29 @@ public static class CommonSyncFilters { } }; + public static SyncFilter GetOwnMemberEventsFilter => new() { + AccountData = new SyncFilter.EventFilter(types: ["m.room.member"], limit: 1), + Presence = new SyncFilter.EventFilter(notTypes: ["*"], limit: 1), + Room = new SyncFilter.RoomFilter { + AccountData = new SyncFilter.RoomFilter.StateFilter(rooms: []), + Ephemeral = new SyncFilter.RoomFilter.StateFilter(rooms: []), + State = new SyncFilter.RoomFilter.StateFilter { + Types = new List<string> { + RoomMemberEventContent.EventId + }, + LazyLoadMembers = true, IncludeRedundantMembers = false, + Senders = ["@me"] + }, + Timeline = new SyncFilter.RoomFilter.StateFilter(rooms: []) + } + }; + // This must be down here, due to statics load order - public static readonly FrozenDictionary<string, SyncFilter> FilterMap = new Dictionary<string, SyncFilter>() { + public static FrozenDictionary<string, SyncFilter> FilterMap => new Dictionary<string, SyncFilter>() { [GetAccountData] = GetAccountDataFilter, [GetAccountDataWithRooms] = GetAccountDataWithRoomsFilter, [GetBasicRoomInfo] = GetBasicRoomDataFilter, - [GetSpaceRelations] = GetSpaceRelationsFilter + [GetSpaceRelations] = GetSpaceRelationsFilter, + [GetOwnMemberEvents] = GetOwnMemberEventsFilter }.ToFrozenDictionary(); } \ No newline at end of file diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests.cs index 4f7ac17..4c8dcb4 100644 --- a/Tests/LibMatrix.Tests/Tests/RoomTests.cs +++ b/Tests/LibMatrix.Tests/Tests/RoomTests.cs @@ -198,7 +198,7 @@ public class RoomTests : TestBed<TestFixture> { var room = await RoomAbstraction.GetTestRoom(hs); Assert.NotNull(room); - await room.DisbandRoomAsync(); + await room.PermanentlyBrickRoomAsync(); } [Fact] diff --git a/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs b/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs index 11ee740..d9e4dc8 100644 --- a/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs +++ b/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs @@ -1,4 +1,6 @@ +using System.Reflection.Metadata; using LibMatrix.EventTypes.Spec; +using LibMatrix.Filters; using LibMatrix.Helpers; using LibMatrix.Homeservers; using LibMatrix.Utilities.Bot.Interfaces; @@ -37,8 +39,19 @@ public class CommandListenerHostedService : IHostedService { private async Task? Run(CancellationToken cancellationToken) { _logger.LogInformation("Starting command listener!"); + var filter = await _hs.GetOrUploadNamedFilterIdAsync("gay.rory.libmatrix.utilities.bot.command_listener_syncfilter.dev2", new SyncFilter() { + AccountData = new SyncFilter.EventFilter(notTypes: ["*"], limit: 1), + Presence = new SyncFilter.EventFilter(notTypes: ["*"]), + Room = new SyncFilter.RoomFilter() { + AccountData = new SyncFilter.RoomFilter.StateFilter(notTypes: ["*"]), + Ephemeral = new SyncFilter.RoomFilter.StateFilter(notTypes: ["*"]), + State = new SyncFilter.RoomFilter.StateFilter(notTypes: ["*"]), + Timeline = new SyncFilter.RoomFilter.StateFilter(types: ["m.room.message"], notSenders: [_hs.WhoAmI.UserId]), + } + }); var syncHelper = new SyncHelper(_hs, _logger) { - Timeout = 300_000 + Timeout = 300_000, + FilterId = filter }; syncHelper.TimelineEventHandlers.Add(async @event => { try { |