From 5affd9f061e75f6575a2fe6715f9e8757cfe87e8 Mon Sep 17 00:00:00 2001 From: "Emma [it/its]@Rory&" Date: Thu, 14 Dec 2023 07:20:46 +0100 Subject: Cleanup --- ArcaneLibs | 2 +- .../Bot/Commands/CmdCommand.cs | 1 - .../Bot/FileStorageProvider.cs | 1 - .../Bot/Interfaces/CommandContext.cs | 1 - ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs | 1 - .../Bot/StartupTasks/ServerRoomSizeCalulator.cs | 2 - ExampleBots/LibMatrix.ExampleBot/Program.cs | 2 - .../ModerationBot/Commands/BanMediaCommand.cs | 2 - .../Commands/DbgAllRoomsArePolicyListsCommand.cs | 5 -- .../Commands/DbgDumpActivePoliciesCommand.cs | 5 -- .../Commands/DbgDumpAllStateTypesCommand.cs | 4 - .../ModerationBot/Commands/JoinRoomCommand.cs | 5 -- .../Commands/JoinSpaceMembersCommand.cs | 4 - ExampleBots/ModerationBot/FirstRunTasks.cs | 1 - ExampleBots/ModerationBot/ModerationBot.cs | 19 ++--- ExampleBots/ModerationBot/PolicyEngine.cs | 15 ++-- ExampleBots/ModerationBot/PolicyList.cs | 1 - .../StateEventTypes/Policies/BasePolicy.cs | 1 + .../Implementations/MediaPolicyHomeserver.cs | 1 - .../Implementations/MessagePolicyContainsText.cs | 1 - .../Policies/Implementations/UnknownPolicy.cs | 3 - .../PluralContactBotPoC/Bot/AccountData/BotData.cs | 1 - .../Bot/AccountData/SystemData.cs | 3 +- ExampleBots/PluralContactBotPoC/Program.cs | 2 - .../Common/MjolnirShortcodeEventContent.cs | 9 ++ .../Common/RoomEmotesEventContent.cs | 22 +++++ LibMatrix.EventTypes/EventContent.cs | 50 +++++++++++ LibMatrix.EventTypes/LibMatrix.EventTypes.csproj | 9 ++ LibMatrix.EventTypes/MatrixEventAttribute.cs | 7 ++ .../Spec/Ephemeral/PresenceStateEventContent.cs | 21 +++++ .../Spec/Ephemeral/RoomTypingEventContent.cs | 11 +++ .../Spec/RoomMessageEventContent.cs | 46 ++++++++++ .../State/Policy/PolicyRuleStateEventContent.cs | 74 ++++++++++++++++ .../Spec/State/RoomInfo/RoomAliasEventContent.cs | 11 +++ .../Spec/State/RoomInfo/RoomAvatarEventContent.cs | 28 ++++++ .../RoomInfo/RoomCanonicalAliasEventContent.cs | 14 +++ .../Spec/State/RoomInfo/RoomCreateEventContent.cs | 31 +++++++ .../State/RoomInfo/RoomEncryptionEventContent.cs | 13 +++ .../State/RoomInfo/RoomGuestAccessEventContent.cs | 15 ++++ .../RoomInfo/RoomHistoryVisibilityEventContent.cs | 9 ++ .../State/RoomInfo/RoomJoinRulesEventContent.cs | 52 ++++++++++++ .../Spec/State/RoomInfo/RoomMemberEventContent.cs | 29 +++++++ .../Spec/State/RoomInfo/RoomNameEventContent.cs | 11 +++ .../Spec/State/RoomInfo/RoomPinnedEventContent.cs | 9 ++ .../State/RoomInfo/RoomPowerLevelEventContent.cs | 78 +++++++++++++++++ .../State/RoomInfo/RoomServerACLEventContent.cs | 15 ++++ .../Spec/State/RoomInfo/RoomTopicEventContent.cs | 10 +++ .../Spec/State/Space/SpaceChildEventContent.cs | 13 +++ .../Spec/State/Space/SpaceParentEventContent.cs | 12 +++ LibMatrix.sln | 6 ++ LibMatrix.sln.DotSettings.user | 1 + LibMatrix/EventIdResponse.cs | 2 +- .../Common/MjolnirShortcodeEventContent.cs | 10 --- .../EventTypes/Common/RoomEmotesEventContent.cs | 25 ------ LibMatrix/EventTypes/MatrixEventAttribute.cs | 7 -- .../Spec/Ephemeral/PresenceStateEventContent.cs | 22 ----- .../Spec/Ephemeral/RoomTypingEventContent.cs | 12 --- .../EventTypes/Spec/RoomMessageEventContent.cs | 47 ---------- .../State/Policy/PolicyRuleStateEventContent.cs | 75 ---------------- .../Spec/State/RoomInfo/RoomAliasEventContent.cs | 12 --- .../Spec/State/RoomInfo/RoomAvatarEventContent.cs | 29 ------- .../RoomInfo/RoomCanonicalAliasEventContent.cs | 15 ---- .../Spec/State/RoomInfo/RoomCreateEventContent.cs | 32 ------- .../State/RoomInfo/RoomEncryptionEventContent.cs | 14 --- .../State/RoomInfo/RoomGuestAccessEventContent.cs | 15 ---- .../RoomInfo/RoomHistoryVisibilityEventContent.cs | 10 --- .../State/RoomInfo/RoomJoinRulesEventContent.cs | 29 ------- .../Spec/State/RoomInfo/RoomMemberEventContent.cs | 30 ------- .../Spec/State/RoomInfo/RoomNameEventContent.cs | 12 --- .../Spec/State/RoomInfo/RoomPinnedEventContent.cs | 10 --- .../State/RoomInfo/RoomPowerLevelEventContent.cs | 79 ----------------- .../State/RoomInfo/RoomServerACLEventContent.cs | 16 ---- .../Spec/State/RoomInfo/RoomTopicEventContent.cs | 11 --- .../Spec/State/Space/SpaceChildEventContent.cs | 14 --- .../Spec/State/Space/SpaceParentEventContent.cs | 13 --- LibMatrix/EventTypes/UnknownStateEventContent.cs | 7 -- LibMatrix/Extensions/HttpClientExtensions.cs | 6 +- LibMatrix/Extensions/JsonElementExtensions.cs | 2 +- LibMatrix/Helpers/MessageFormatter.cs | 9 +- LibMatrix/Helpers/SyncHelper.cs | 12 +-- LibMatrix/Helpers/SyncStateResolver.cs | 6 +- .../Homeservers/AuthenticatedHomeserverGeneric.cs | 13 +-- .../Homeservers/AuthenticatedHomeserverSynapse.cs | 2 +- LibMatrix/Homeservers/RemoteHomeServer.cs | 14 +-- LibMatrix/Interfaces/EventContent.cs | 48 ----------- LibMatrix/LibMatrix.csproj | 9 +- LibMatrix/MatrixException.cs | 4 +- .../Responses/Admin/AdminRoomListingResult.cs | 6 +- LibMatrix/Responses/CreateRoomRequest.cs | 26 +++--- LibMatrix/Responses/CreationContentBaseType.cs | 10 +-- LibMatrix/Responses/LoginResponse.cs | 2 - LibMatrix/Responses/SyncResponse.cs | 10 +-- LibMatrix/Responses/UserProfileResponse.cs | 1 - LibMatrix/RoomTypes/GenericRoom.cs | 74 ++++++++-------- LibMatrix/RoomTypes/SpaceRoom.cs | 4 +- LibMatrix/Services/HomeserverProviderService.cs | 47 ++++++---- LibMatrix/Services/HomeserverResolverService.cs | 25 +++--- LibMatrix/StateEvent.cs | 39 +++------ LibMatrix/UserIdAndReason.cs | 2 +- LibMatrix/WhoAmIResponse.cs | 2 +- .../Abstractions/RoomAbstraction.cs | 3 +- Tests/LibMatrix.Tests/Tests/RoomEventTests.cs | 7 +- Tests/LibMatrix.Tests/Tests/RoomTests.cs | 1 - Tests/LibMatrix.Tests/Tests/TestCleanup.cs | 6 +- Tests/TestDataGenerator/Bot/DataFetcher.cs | 27 ++---- .../Bot/DataFetcherConfiguration.cs | 2 +- Tests/TestDataGenerator/Program.cs | 8 +- .../Controllers/ValidationController.cs | 5 +- .../EventSerializerContexts.g.cs | 99 ---------------------- .../Program.cs | 28 ++++-- .../AppServiceConfiguration.cs | 4 +- .../LibMatrix.Utilities.Bot/BotCommandInstaller.cs | 4 +- .../LibMatrix.Utilities.Bot/FileStorageProvider.cs | 4 - .../Interfaces/CommandContext.cs | 6 +- 114 files changed, 843 insertions(+), 971 deletions(-) create mode 100644 LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs create mode 100644 LibMatrix.EventTypes/Common/RoomEmotesEventContent.cs create mode 100644 LibMatrix.EventTypes/EventContent.cs create mode 100644 LibMatrix.EventTypes/LibMatrix.EventTypes.csproj create mode 100644 LibMatrix.EventTypes/MatrixEventAttribute.cs create mode 100644 LibMatrix.EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs create mode 100644 LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs delete mode 100644 LibMatrix/EventTypes/Common/MjolnirShortcodeEventContent.cs delete mode 100644 LibMatrix/EventTypes/Common/RoomEmotesEventContent.cs delete mode 100644 LibMatrix/EventTypes/MatrixEventAttribute.cs delete mode 100644 LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/Space/SpaceChildEventContent.cs delete mode 100644 LibMatrix/EventTypes/Spec/State/Space/SpaceParentEventContent.cs delete mode 100644 LibMatrix/EventTypes/UnknownStateEventContent.cs delete mode 100644 LibMatrix/Interfaces/EventContent.cs delete mode 100644 Utilities/LibMatrix.JsonSerializerContextGenerator/EventSerializerContexts.g.cs diff --git a/ArcaneLibs b/ArcaneLibs index 788516b..28c0e5a 160000 --- a/ArcaneLibs +++ b/ArcaneLibs @@ -1 +1 @@ -Subproject commit 788516bf3253902b56dfe335c3d2166733969bac +Subproject commit 28c0e5a7c7fdf306901ad20bb324efa697db2225 diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs index ea42597..e690890 100644 --- a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs +++ b/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs @@ -1,4 +1,3 @@ -using ArcaneLibs.Extensions; using ArcaneLibs.StringNormalisation; using LibMatrix.EventTypes.Spec; using LibMatrix.ExampleBot.Bot.Interfaces; diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs index 935d53f..2c014de 100644 --- a/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs +++ b/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs @@ -1,6 +1,5 @@ using System.Text.Json; using ArcaneLibs.Extensions; -using LibMatrix.Extensions; using LibMatrix.Interfaces.Services; using Microsoft.Extensions.Logging; diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs index 9b6ef7a..6dbb7f9 100644 --- a/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs +++ b/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs @@ -1,5 +1,4 @@ using LibMatrix.EventTypes.Spec; -using LibMatrix.Responses; using LibMatrix.RoomTypes; namespace LibMatrix.ExampleBot.Bot.Interfaces; diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs index 8cf4f1f..8e6cd6a 100644 --- a/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs +++ b/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs @@ -3,7 +3,6 @@ using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Spec; using LibMatrix.EventTypes.Spec.State; using LibMatrix.ExampleBot.Bot.Interfaces; -using LibMatrix.Extensions; using LibMatrix.Helpers; using LibMatrix.Homeservers; using LibMatrix.Services; diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs index 890db85..2f6e0b0 100644 --- a/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs +++ b/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs @@ -1,9 +1,7 @@ using System.Diagnostics.CodeAnalysis; -using ArcaneLibs.Extensions; using LibMatrix.ExampleBot.Bot.Interfaces; using LibMatrix.Homeservers; using LibMatrix.Services; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; diff --git a/ExampleBots/LibMatrix.ExampleBot/Program.cs b/ExampleBots/LibMatrix.ExampleBot/Program.cs index 6d8775e..25ce07d 100644 --- a/ExampleBots/LibMatrix.ExampleBot/Program.cs +++ b/ExampleBots/LibMatrix.ExampleBot/Program.cs @@ -3,8 +3,6 @@ using ArcaneLibs; using LibMatrix.ExampleBot.Bot; using LibMatrix.ExampleBot.Bot.Interfaces; -using LibMatrix.ExampleBot.Bot.StartupTasks; -using LibMatrix.Extensions; using LibMatrix.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs b/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs index 9e49b22..535fd4f 100644 --- a/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs +++ b/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs @@ -1,4 +1,3 @@ -using System.Buffers.Text; using System.Security.Cryptography; using ArcaneLibs.Extensions; using LibMatrix; @@ -7,7 +6,6 @@ using LibMatrix.Helpers; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; using ModerationBot.StateEventTypes.Policies.Implementations; namespace ModerationBot.Commands; diff --git a/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs b/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs index 327a9a4..f578f53 100644 --- a/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs +++ b/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs @@ -1,14 +1,9 @@ -using System.Buffers.Text; -using System.Security.Cryptography; -using ArcaneLibs.Extensions; -using LibMatrix; using LibMatrix.EventTypes.Spec; using LibMatrix.Helpers; using LibMatrix.RoomTypes; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; namespace ModerationBot.Commands; diff --git a/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs b/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs index 35c95f8..285d792 100644 --- a/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs +++ b/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs @@ -1,14 +1,9 @@ -using System.Buffers.Text; -using System.Security.Cryptography; using ArcaneLibs.Extensions; -using LibMatrix; using LibMatrix.EventTypes.Spec; -using LibMatrix.Helpers; using LibMatrix.RoomTypes; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; namespace ModerationBot.Commands; diff --git a/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs b/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs index 0013065..3727877 100644 --- a/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs +++ b/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs @@ -1,14 +1,10 @@ -using System.Buffers.Text; -using System.Security.Cryptography; using ArcaneLibs.Extensions; using LibMatrix; using LibMatrix.EventTypes.Spec; -using LibMatrix.Helpers; using LibMatrix.RoomTypes; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; namespace ModerationBot.Commands; diff --git a/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs b/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs index 7496a07..eb22a70 100644 --- a/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs +++ b/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs @@ -1,13 +1,8 @@ -using System.Buffers.Text; -using System.Security.Cryptography; -using ArcaneLibs.Extensions; -using LibMatrix; using LibMatrix.EventTypes.Spec; using LibMatrix.Helpers; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; namespace ModerationBot.Commands; diff --git a/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs b/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs index 6e64f6f..da77b05 100644 --- a/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs +++ b/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs @@ -1,14 +1,10 @@ -using System.Buffers.Text; -using System.Security.Cryptography; using ArcaneLibs.Extensions; -using LibMatrix; using LibMatrix.EventTypes.Spec; using LibMatrix.Helpers; using LibMatrix.RoomTypes; using LibMatrix.Services; using LibMatrix.Utilities.Bot.Interfaces; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; namespace ModerationBot.Commands; diff --git a/ExampleBots/ModerationBot/FirstRunTasks.cs b/ExampleBots/ModerationBot/FirstRunTasks.cs index 83356bf..9dece1d 100644 --- a/ExampleBots/ModerationBot/FirstRunTasks.cs +++ b/ExampleBots/ModerationBot/FirstRunTasks.cs @@ -1,5 +1,4 @@ using LibMatrix; -using LibMatrix.EventTypes.Spec.State; using LibMatrix.Homeservers; using LibMatrix.Responses; using ModerationBot.AccountData; diff --git a/ExampleBots/ModerationBot/ModerationBot.cs b/ExampleBots/ModerationBot/ModerationBot.cs index 8a48b61..1be7bd5 100644 --- a/ExampleBots/ModerationBot/ModerationBot.cs +++ b/ExampleBots/ModerationBot/ModerationBot.cs @@ -1,32 +1,25 @@ -using System.Security.Cryptography; -using System.Text.RegularExpressions; using ArcaneLibs.Extensions; using LibMatrix; using LibMatrix.EventTypes.Spec; using LibMatrix.EventTypes.Spec.State; +using LibMatrix.EventTypes.Spec.State.Policy; using LibMatrix.Helpers; using LibMatrix.Homeservers; -using LibMatrix.Responses; using LibMatrix.RoomTypes; using LibMatrix.Services; -using LibMatrix.Utilities.Bot.Interfaces; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using ModerationBot.AccountData; -using ModerationBot.StateEventTypes; using ModerationBot.StateEventTypes.Policies; namespace ModerationBot; -public class ModerationBot(AuthenticatedHomeserverGeneric hs, ILogger logger, ModerationBotConfiguration configuration, - HomeserverResolverService hsResolver, PolicyEngine engine) : IHostedService { - private readonly IEnumerable _commands; - +public class ModerationBot(AuthenticatedHomeserverGeneric hs, ILogger logger, ModerationBotConfiguration configuration, PolicyEngine engine) : IHostedService { private Task _listenerTask; // private GenericRoom _policyRoom; - private GenericRoom _logRoom; - private GenericRoom _controlRoom; + private GenericRoom? _logRoom; + private GenericRoom? _controlRoom; /// Triggered when the application host is ready to start the service. /// Indicates that the start process has been aborted. @@ -63,6 +56,10 @@ public class ModerationBot(AuthenticatedHomeserverGeneric hs, ILogger logger, ModerationBotConfiguration configuration, HomeserverResolverService hsResolver) { private Dictionary PolicyListAccountData { get; set; } = new(); + // ReSharper disable once MemberCanBePrivate.Global public List ActivePolicyLists { get; set; } = new(); public List ActivePolicies { get; set; } = new(); public Dictionary> ActivePoliciesByType { get; set; } = new(); @@ -47,8 +46,8 @@ public class PolicyEngine(AuthenticatedHomeserverGeneric hs, ILogger(); - if (policy.Entity is null) continue; + var policy = policyEntry.TypedContent is BasePolicy ? policyEntry.TypedContent as BasePolicy : policyEntry.RawContent.Deserialize(); + if (policy?.Entity is null) continue; policy.PolicyList = activePolicyList; policy.OriginalEvent = policyEntry; activePolicies.Add(policy); @@ -152,7 +151,7 @@ public class PolicyEngine(AuthenticatedHomeserverGeneric hs, ILogger diff --git a/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs b/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs index 5d11432..2adcbb3 100644 --- a/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs +++ b/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using LibMatrix.EventTypes; -using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace PluralContactBotPoC.Bot.AccountData; diff --git a/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs b/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs index 42edd23..ad8ab1d 100644 --- a/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs +++ b/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using LibMatrix.EventTypes; -using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace PluralContactBotPoC.Bot.StateEventTypes; @@ -8,7 +7,7 @@ namespace PluralContactBotPoC.Bot.StateEventTypes; [MatrixEvent(EventName = "gay.rory.plural_contact_bot.system_data")] public class SystemData : EventContent { [JsonPropertyName("control_room")] - public string ControlRoom { get; set; } = null!; + public required string ControlRoom { get; set; } [JsonPropertyName("system_members")] public List Members { get; set; } = new(); [JsonPropertyName("dm_space")] diff --git a/ExampleBots/PluralContactBotPoC/Program.cs b/ExampleBots/PluralContactBotPoC/Program.cs index f8d93c6..f65f2e9 100644 --- a/ExampleBots/PluralContactBotPoC/Program.cs +++ b/ExampleBots/PluralContactBotPoC/Program.cs @@ -1,13 +1,11 @@ // See https://aka.ms/new-console-template for more information using System.Text.Json; -using System.Text.Json.Serialization; using ArcaneLibs.Extensions; using LibMatrix.Services; using LibMatrix.Utilities.Bot; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using PluralContactBotPoC; using PluralContactBotPoC.Bot; Console.WriteLine("Hello, World!"); diff --git a/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs b/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs new file mode 100644 index 0000000..7924a33 --- /dev/null +++ b/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Common; + +[MatrixEvent(EventName = "org.matrix.mjolnir.shortcode")] +public class MjolnirShortcodeEventContent : TimelineEventContent { + [JsonPropertyName("shortcode")] + public string? Shortcode { get; set; } +} diff --git a/LibMatrix.EventTypes/Common/RoomEmotesEventContent.cs b/LibMatrix.EventTypes/Common/RoomEmotesEventContent.cs new file mode 100644 index 0000000..bfe480e --- /dev/null +++ b/LibMatrix.EventTypes/Common/RoomEmotesEventContent.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Common; + +[MatrixEvent(EventName = "im.ponies.room_emotes")] +public class RoomEmotesEventContent : TimelineEventContent { + [JsonPropertyName("emoticons")] + public Dictionary? Emoticons { get; set; } + + [JsonPropertyName("images")] + public Dictionary? Images { get; set; } + + [JsonPropertyName("pack")] + public PackInfo? Pack { get; set; } + + public class EmoticonData { + [JsonPropertyName("url")] + public string? Url { get; set; } + } + + public class PackInfo; // TODO: Implement this +} diff --git a/LibMatrix.EventTypes/EventContent.cs b/LibMatrix.EventTypes/EventContent.cs new file mode 100644 index 0000000..608550f --- /dev/null +++ b/LibMatrix.EventTypes/EventContent.cs @@ -0,0 +1,50 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes; + +public abstract class EventContent; + +public class UnknownEventContent : TimelineEventContent; + +public abstract class TimelineEventContent : EventContent { + [JsonPropertyName("m.relates_to")] + public MessageRelatesTo? RelatesTo { get; set; } + + [JsonPropertyName("m.new_content")] + public JsonObject? NewContent { get; set; } + + public TimelineEventContent SetReplaceRelation(string eventId) { + NewContent = JsonSerializer.SerializeToNode(this, GetType())!.AsObject(); + // NewContent = JsonSerializer.Deserialize(jsonText, GetType()); + RelatesTo = new MessageRelatesTo { + RelationType = "m.replace", + EventId = eventId + }; + return this; + } + + public T SetReplaceRelation(string eventId) where T : TimelineEventContent { + return SetReplaceRelation(eventId) as T ?? throw new InvalidOperationException(); + } + + public class MessageRelatesTo { + [JsonPropertyName("m.in_reply_to")] + public EventInReplyTo? InReplyTo { get; set; } + + [JsonPropertyName("event_id")] + public string? EventId { get; set; } + + [JsonPropertyName("rel_type")] + public string? RelationType { get; set; } + + public class EventInReplyTo { + [JsonPropertyName("event_id")] + public string? EventId { get; set; } + + [JsonPropertyName("rel_type")] + public string? RelType { get; set; } + } + } +} \ No newline at end of file diff --git a/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj b/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj new file mode 100644 index 0000000..3a63532 --- /dev/null +++ b/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/LibMatrix.EventTypes/MatrixEventAttribute.cs b/LibMatrix.EventTypes/MatrixEventAttribute.cs new file mode 100644 index 0000000..baa88ff --- /dev/null +++ b/LibMatrix.EventTypes/MatrixEventAttribute.cs @@ -0,0 +1,7 @@ +namespace LibMatrix.EventTypes; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class MatrixEventAttribute : Attribute { + public required string EventName { get; set; } + public bool Legacy { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs b/LibMatrix.EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs new file mode 100644 index 0000000..1e98e12 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.Ephemeral; + +[MatrixEvent(EventName = EventId)] +public class PresenceEventContent : EventContent { + public const string EventId = "m.presence"; + + [JsonPropertyName("presence"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Presence { get; set; } + [JsonPropertyName("last_active_ago")] + public long LastActiveAgo { get; set; } + [JsonPropertyName("currently_active")] + public bool CurrentlyActive { get; set; } + [JsonPropertyName("status_msg"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? StatusMessage { get; set; } + [JsonPropertyName("avatar_url"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AvatarUrl { get; set; } + [JsonPropertyName("displayname"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? DisplayName { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs b/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs new file mode 100644 index 0000000..b62b448 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = EventId)] +public class RoomTypingEventContent : TimelineEventContent { + public const string EventId = "m.typing"; + + [JsonPropertyName("user_ids")] + public string[]? UserIds { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs b/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs new file mode 100644 index 0000000..1e27bce --- /dev/null +++ b/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs @@ -0,0 +1,46 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec; + +[MatrixEvent(EventName = EventId)] +public class RoomMessageEventContent : TimelineEventContent { + public const string EventId = "m.room.message"; + + public RoomMessageEventContent(string messageType = "m.notice", string? body = null) { + MessageType = messageType; + Body = body ?? ""; + } + + [JsonPropertyName("body")] + public string Body { get; set; } + + [JsonPropertyName("msgtype")] + public string MessageType { get; set; } = "m.notice"; + + [JsonPropertyName("formatted_body")] + public string? FormattedBody { get; set; } + + [JsonPropertyName("format")] + public string? Format { get; set; } + + /// + /// Media URI for this message, if any + /// + [JsonPropertyName("url")] + public string? Url { get; set; } + + public string? FileName { get; set; } + + [JsonPropertyName("info")] + public FileInfoStruct? FileInfo { get; set; } + + public class FileInfoStruct { + [JsonPropertyName("mimetype")] + public string? MimeType { get; set; } + [JsonPropertyName("size")] + public long Size { get; set; } + [JsonPropertyName("thumbnail_url")] + public string? ThumbnailUrl { get; set; } + } + +} diff --git a/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs new file mode 100644 index 0000000..d3ab8cb --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs @@ -0,0 +1,74 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State.Policy; + +//spec +[MatrixEvent(EventName = EventId)] //spec +[MatrixEvent(EventName = "m.room.rule.server")] //??? +[MatrixEvent(EventName = "org.matrix.mjolnir.rule.server")] //legacy +public class ServerPolicyRuleEventContent : PolicyRuleEventContent { + public const string EventId = "m.policy.rule.server"; +} + +[MatrixEvent(EventName = EventId)] //spec +[MatrixEvent(EventName = "m.room.rule.user")] //??? +[MatrixEvent(EventName = "org.matrix.mjolnir.rule.user")] //legacy +public class UserPolicyRuleEventContent : PolicyRuleEventContent { + public const string EventId = "m.policy.rule.user"; +} + +[MatrixEvent(EventName = EventId)] //spec +[MatrixEvent(EventName = "m.room.rule.room")] //??? +[MatrixEvent(EventName = "org.matrix.mjolnir.rule.room")] //legacy +public class RoomPolicyRuleEventContent : PolicyRuleEventContent { + public const string EventId = "m.policy.rule.room"; +} + +public abstract class PolicyRuleEventContent : EventContent { + /// + /// Entity this ban applies to, can use * and ? as globs. + /// Policy is invalid if entity is null + /// + [JsonPropertyName("entity")] + public string? Entity { get; set; } + + /// + /// Reason this user is banned + /// + [JsonPropertyName("reason")] + public string? Reason { get; set; } + + /// + /// Suggested action to take + /// + [JsonPropertyName("recommendation")] + public string? Recommendation { get; set; } + + /// + /// Expiry time in milliseconds since the unix epoch, or null if the ban has no expiry. + /// + [JsonPropertyName("support.feline.policy.expiry.rev.2")] //stable prefix: expiry, msc pending + public long? Expiry { get; set; } + + //utils + /// + /// Readable expiry time, provided for easy interaction + /// + [JsonPropertyName("gay.rory.matrix_room_utils.readable_expiry_time_utc")] + public DateTime? ExpiryDateTime { + get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime; + set => Expiry = ((DateTimeOffset)value).ToUnixTimeMilliseconds(); + } +} + +public static class PolicyRecommendationTypes { + /// + /// Ban this user + /// + public static string Ban = "m.ban"; + + /// + /// Mute this user + /// + public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs new file mode 100644 index 0000000..53b85b8 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State.RoomInfo; + +[MatrixEvent(EventName = EventId)] +public class RoomAliasEventContent : TimelineEventContent { + public const string EventId = "m.room.alias"; + + [JsonPropertyName("aliases")] + public List? Aliases { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs new file mode 100644 index 0000000..d15e88e --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State.RoomInfo; + +[MatrixEvent(EventName = EventId)] +public class RoomAvatarEventContent : TimelineEventContent { + public const string EventId = "m.room.avatar"; + + [JsonPropertyName("url")] + public string? Url { get; set; } + + [JsonPropertyName("info")] + public RoomAvatarInfo? Info { get; set; } + + public class RoomAvatarInfo { + [JsonPropertyName("h")] + public int? Height { get; set; } + + [JsonPropertyName("w")] + public int? Width { get; set; } + + [JsonPropertyName("mimetype")] + public string? MimeType { get; set; } + + [JsonPropertyName("size")] + public int? Size { get; set; } + } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs new file mode 100644 index 0000000..265775e --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = EventId)] +public class RoomCanonicalAliasEventContent : TimelineEventContent { + public const string EventId = "m.room.canonical_alias"; + + [JsonPropertyName("alias")] + public string? Alias { get; set; } + + [JsonPropertyName("alt_aliases")] + public string[]? AltAliases { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs new file mode 100644 index 0000000..7d25dc7 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = EventId)] +public class RoomCreateEventContent : TimelineEventContent { + public const string EventId = "m.room.create"; + + [JsonPropertyName("room_version")] + public string? RoomVersion { get; set; } + + [JsonPropertyName("creator")] + public string? Creator { get; set; } + + [JsonPropertyName("m.federate")] + public bool? Federate { get; set; } + + [JsonPropertyName("predecessor")] + public RoomCreatePredecessor? Predecessor { get; set; } + + [JsonPropertyName("type")] + public string? Type { get; set; } + + public class RoomCreatePredecessor { + [JsonPropertyName("room_id")] + public string? RoomId { get; set; } + + [JsonPropertyName("event_id")] + public string? EventId { get; set; } + } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs new file mode 100644 index 0000000..8e9e05f --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.encryption")] +public class RoomEncryptionEventContent : TimelineEventContent { + [JsonPropertyName("algorithm")] + public string? Algorithm { get; set; } + [JsonPropertyName("rotation_period_ms")] + public ulong? RotationPeriodMs { get; set; } + [JsonPropertyName("rotation_period_msgs")] + public ulong? RotationPeriodMsgs { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs new file mode 100644 index 0000000..30f2def --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.guest_access")] +public class RoomGuestAccessEventContent : TimelineEventContent { + [JsonPropertyName("guest_access")] + public required string GuestAccess { get; set; } + + [JsonIgnore] + public bool IsGuestAccessEnabled { + get => GuestAccess == "can_join"; + set => GuestAccess = value ? "can_join" : "forbidden"; + } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs new file mode 100644 index 0000000..26d40e1 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.history_visibility")] +public class RoomHistoryVisibilityEventContent : TimelineEventContent { + [JsonPropertyName("history_visibility")] + public required string HistoryVisibility { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs new file mode 100644 index 0000000..e300b5d --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs @@ -0,0 +1,52 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.join_rules")] +public class RoomJoinRulesEventContent : TimelineEventContent { + /// + /// one of ["public", "invite", "knock", "restricted", "knock_restricted"] + /// "private" is reserved without implementation! + /// + [JsonPropertyName("join_rule")] + public string JoinRuleValue { get; set; } + + [JsonIgnore] + public required JoinRules JoinRule { + get => JoinRuleValue switch { + "public" => JoinRules.Public, + "invite" => JoinRules.Invite, + "knock" => JoinRules.Knock, + "restricted" => JoinRules.Restricted, + "knock_restricted" => JoinRules.KnockRestricted, + _ => throw new ArgumentOutOfRangeException() + }; + set => JoinRuleValue = value switch { + JoinRules.Public => "public", + JoinRules.Invite => "invite", + JoinRules.Knock => "knock", + JoinRules.Restricted => "restricted", + JoinRules.KnockRestricted => "knock_restricted", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) + }; + } + + [JsonPropertyName("allow")] + public List? Allow { get; set; } + + public class AllowEntry { + [JsonPropertyName("type")] + public required string Type { get; set; } + + [JsonPropertyName("room_id")] + public required string RoomId { get; set; } + } + + public enum JoinRules { + Public, + Invite, + Knock, + Restricted, + KnockRestricted + } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs new file mode 100644 index 0000000..7e4f9b6 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = EventId)] +public class RoomMemberEventContent : TimelineEventContent { + public const string EventId = "m.room.member"; + + [JsonPropertyName("reason")] + public string? Reason { get; set; } + + [JsonPropertyName("membership")] + public required string Membership { get; set; } + + [JsonPropertyName("displayname")] + public string? DisplayName { get; set; } + + [JsonPropertyName("is_direct")] + public bool? IsDirect { get; set; } + + [JsonPropertyName("avatar_url")] + public string? AvatarUrl { get; set; } + + [JsonPropertyName("kind")] + public string? Kind { get; set; } + + [JsonPropertyName("join_authorised_via_users_server")] + public string? JoinAuthorisedViaUsersServer { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs new file mode 100644 index 0000000..00a1e8f --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = EventId)] +public class RoomNameEventContent : TimelineEventContent { + public const string EventId = "m.room.name"; + + [JsonPropertyName("name")] + public string? Name { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs new file mode 100644 index 0000000..9bbcd90 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.pinned_events")] +public class RoomPinnedEventContent : TimelineEventContent { + [JsonPropertyName("pinned")] + public string[]? PinnedEvents { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs new file mode 100644 index 0000000..1a09ab8 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs @@ -0,0 +1,78 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = EventId)] +public class RoomPowerLevelEventContent : TimelineEventContent { + public const string EventId = "m.room.power_levels"; + + [JsonPropertyName("ban")] + public long? Ban { get; set; } = 50; + + [JsonPropertyName("events_default")] + public long? EventsDefault { get; set; } = 0; + + [JsonPropertyName("invite")] + public long? Invite { get; set; } = 0; + + [JsonPropertyName("kick")] + public long? Kick { get; set; } = 50; + + [JsonPropertyName("notifications")] + public NotificationsPL? NotificationsPl { get; set; } // = null!; + + [JsonPropertyName("redact")] + public long? Redact { get; set; } = 50; + + [JsonPropertyName("state_default")] + public long? StateDefault { get; set; } = 50; + + [JsonPropertyName("events")] + public Dictionary? Events { get; set; } // = null!; + + [JsonPropertyName("users")] + public Dictionary? Users { get; set; } // = null!; + + [JsonPropertyName("users_default")] + public long? UsersDefault { get; set; } = 0; + + [Obsolete("Historical was a key related to MSC2716, a spec change on backfill that was dropped!", true)] + [JsonIgnore] + [JsonPropertyName("historical")] + public long Historical { get; set; } // = 50; + + public class NotificationsPL { + [JsonPropertyName("room")] + public long Room { get; set; } = 50; + } + + public bool IsUserAdmin(string userId) { + ArgumentNullException.ThrowIfNull(userId); + return Users.TryGetValue(userId, out var level) && level >= Events.Max(x => x.Value); + } + + public bool UserHasTimelinePermission(string userId, string eventType) { + ArgumentNullException.ThrowIfNull(userId); + return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault ?? 0); + } + + public bool UserHasStatePermission(string userId, string eventType) { + ArgumentNullException.ThrowIfNull(userId); + return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, StateDefault ?? 50); + } + + public long GetUserPowerLevel(string userId) { + ArgumentNullException.ThrowIfNull(userId); + return Users.TryGetValue(userId, out var level) ? level : UsersDefault ?? UsersDefault ?? 0; + } + + public long GetEventPowerLevel(string eventType) { + return Events.TryGetValue(eventType, out var level) ? level : EventsDefault ?? EventsDefault ?? 0; + } + + public void SetUserPowerLevel(string userId, long powerLevel) { + ArgumentNullException.ThrowIfNull(userId); + Users ??= new(); + Users[userId] = powerLevel; + } +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs new file mode 100644 index 0000000..75337f5 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.server_acl")] +public class RoomServerACLEventContent : TimelineEventContent { + [JsonPropertyName("allow")] + public List? Allow { get; set; } // = null!; + + [JsonPropertyName("deny")] + public List? Deny { get; set; } // = null!; + + [JsonPropertyName("allow_ip_literals")] + public bool AllowIpLiterals { get; set; } // = false; +} diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs new file mode 100644 index 0000000..3121c39 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.room.topic")] +[MatrixEvent(EventName = "org.matrix.msc3765.topic", Legacy = true)] +public class RoomTopicEventContent : TimelineEventContent { + [JsonPropertyName("topic")] + public string? Topic { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs b/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs new file mode 100644 index 0000000..fb5c938 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.space.child")] +public class SpaceChildEventContent : TimelineEventContent { + [JsonPropertyName("auto_join")] + public bool? AutoJoin { get; set; } + [JsonPropertyName("via")] + public List? Via { get; set; } + [JsonPropertyName("suggested")] + public bool? Suggested { get; set; } +} diff --git a/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs b/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs new file mode 100644 index 0000000..0c23298 --- /dev/null +++ b/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix.EventTypes.Spec.State; + +[MatrixEvent(EventName = "m.space.parent")] +public class SpaceParentEventContent : TimelineEventContent { + [JsonPropertyName("via")] + public string[]? Via { get; set; } + + [JsonPropertyName("canonical")] + public bool? Canonical { get; set; } +} diff --git a/LibMatrix.sln b/LibMatrix.sln index f94131b..f3eae7d 100644 --- a/LibMatrix.sln +++ b/LibMatrix.sln @@ -33,6 +33,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ArcaneLibs", "ArcaneLibs", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs", "ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj", "{13A797D1-7E13-4789-A167-8628B1641AC0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.EventTypes", "LibMatrix.EventTypes\LibMatrix.EventTypes.csproj", "{CD13665B-B964-4AB0-991B-12F067B16DA3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -86,6 +88,10 @@ Global {13A797D1-7E13-4789-A167-8628B1641AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU {13A797D1-7E13-4789-A167-8628B1641AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU {13A797D1-7E13-4789-A167-8628B1641AC0}.Release|Any CPU.Build.0 = Release|Any CPU + {CD13665B-B964-4AB0-991B-12F067B16DA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD13665B-B964-4AB0-991B-12F067B16DA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD13665B-B964-4AB0-991B-12F067B16DA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD13665B-B964-4AB0-991B-12F067B16DA3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {1B1B2197-61FB-416F-B6C8-845F2E5A0442} = {840309F0-435B-43A7-8471-8C2BE643889D} diff --git a/LibMatrix.sln.DotSettings.user b/LibMatrix.sln.DotSettings.user index f720bf5..e26043a 100644 --- a/LibMatrix.sln.DotSettings.user +++ b/LibMatrix.sln.DotSettings.user @@ -1,5 +1,6 @@  True + ShowAndRun <AssemblyExplorer> <Assembly Path="/home/root@Rory/.cache/NuGetPackages/microsoft.extensions.hosting.abstractions/7.0.0/lib/net7.0/Microsoft.Extensions.Hosting.Abstractions.dll" /> </AssemblyExplorer> \ No newline at end of file diff --git a/LibMatrix/EventIdResponse.cs b/LibMatrix/EventIdResponse.cs index 31a95b8..a7feeca 100644 --- a/LibMatrix/EventIdResponse.cs +++ b/LibMatrix/EventIdResponse.cs @@ -4,5 +4,5 @@ namespace LibMatrix; public class EventIdResponse { [JsonPropertyName("event_id")] - public string EventId { get; set; } = null!; + public required string EventId { get; set; } } diff --git a/LibMatrix/EventTypes/Common/MjolnirShortcodeEventContent.cs b/LibMatrix/EventTypes/Common/MjolnirShortcodeEventContent.cs deleted file mode 100644 index a09a393..0000000 --- a/LibMatrix/EventTypes/Common/MjolnirShortcodeEventContent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Common; - -[MatrixEvent(EventName = "org.matrix.mjolnir.shortcode")] -public class MjolnirShortcodeEventContent : TimelineEventContent { - [JsonPropertyName("shortcode")] - public string? Shortcode { get; set; } -} diff --git a/LibMatrix/EventTypes/Common/RoomEmotesEventContent.cs b/LibMatrix/EventTypes/Common/RoomEmotesEventContent.cs deleted file mode 100644 index 8d05a2e..0000000 --- a/LibMatrix/EventTypes/Common/RoomEmotesEventContent.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Common; - -[MatrixEvent(EventName = "im.ponies.room_emotes")] -public class RoomEmotesEventContent : TimelineEventContent { - [JsonPropertyName("emoticons")] - public Dictionary? Emoticons { get; set; } - - [JsonPropertyName("images")] - public Dictionary? Images { get; set; } - - [JsonPropertyName("pack")] - public PackInfo? Pack { get; set; } - - public class EmoticonData { - [JsonPropertyName("url")] - public string? Url { get; set; } - } - - public class PackInfo { - - } -} diff --git a/LibMatrix/EventTypes/MatrixEventAttribute.cs b/LibMatrix/EventTypes/MatrixEventAttribute.cs deleted file mode 100644 index 92334d0..0000000 --- a/LibMatrix/EventTypes/MatrixEventAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace LibMatrix.EventTypes; - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public class MatrixEventAttribute : Attribute { - public string EventName { get; set; } - public bool Legacy { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs b/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs deleted file mode 100644 index 8ffbca5..0000000 --- a/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class PresenceEventContent : EventContent { - public const string EventId = "m.presence"; - - [JsonPropertyName("presence"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Presence { get; set; } - [JsonPropertyName("last_active_ago")] - public long LastActiveAgo { get; set; } - [JsonPropertyName("currently_active")] - public bool CurrentlyActive { get; set; } - [JsonPropertyName("status_msg"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? StatusMessage { get; set; } - [JsonPropertyName("avatar_url"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? AvatarUrl { get; set; } - [JsonPropertyName("displayname"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? DisplayName { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs b/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs deleted file mode 100644 index b947096..0000000 --- a/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomTypingEventContent : TimelineEventContent { - public const string EventId = "m.typing"; - - [JsonPropertyName("user_ids")] - public string[]? UserIds { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs b/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs deleted file mode 100644 index 944ed99..0000000 --- a/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec; - -[MatrixEvent(EventName = EventId)] -public class RoomMessageEventContent : TimelineEventContent { - public const string EventId = "m.room.message"; - - public RoomMessageEventContent(string? messageType = "m.notice", string? body = null) { - MessageType = messageType; - Body = body; - } - - [JsonPropertyName("body")] - public string Body { get; set; } - - [JsonPropertyName("msgtype")] - public string MessageType { get; set; } = "m.notice"; - - [JsonPropertyName("formatted_body")] - public string? FormattedBody { get; set; } - - [JsonPropertyName("format")] - public string? Format { get; set; } - - /// - /// Media URI for this message, if any - /// - [JsonPropertyName("url")] - public string? Url { get; set; } - - public string? FileName { get; set; } - - [JsonPropertyName("info")] - public FileInfoStruct? FileInfo { get; set; } - - public class FileInfoStruct { - [JsonPropertyName("mimetype")] - public string? MimeType { get; set; } - [JsonPropertyName("size")] - public long Size { get; set; } - [JsonPropertyName("thumbnail_url")] - public string? ThumbnailUrl { get; set; } - } - -} diff --git a/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs b/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs deleted file mode 100644 index 80d87d6..0000000 --- a/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -//spec -[MatrixEvent(EventName = EventId)] //spec -[MatrixEvent(EventName = "m.room.rule.server")] //??? -[MatrixEvent(EventName = "org.matrix.mjolnir.rule.server")] //legacy -public class ServerPolicyRuleEventContent : PolicyRuleEventContent { - public const string EventId = "m.policy.rule.server"; -} - -[MatrixEvent(EventName = EventId)] //spec -[MatrixEvent(EventName = "m.room.rule.user")] //??? -[MatrixEvent(EventName = "org.matrix.mjolnir.rule.user")] //legacy -public class UserPolicyRuleEventContent : PolicyRuleEventContent { - public const string EventId = "m.policy.rule.user"; -} - -[MatrixEvent(EventName = EventId)] //spec -[MatrixEvent(EventName = "m.room.rule.room")] //??? -[MatrixEvent(EventName = "org.matrix.mjolnir.rule.room")] //legacy -public class RoomPolicyRuleEventContent : PolicyRuleEventContent { - public const string EventId = "m.policy.rule.room"; -} - -public abstract class PolicyRuleEventContent : EventContent { - /// - /// Entity this ban applies to, can use * and ? as globs. - /// Policy is invalid if entity is null - /// - [JsonPropertyName("entity")] - public string? Entity { get; set; } - - /// - /// Reason this user is banned - /// - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - /// - /// Suggested action to take - /// - [JsonPropertyName("recommendation")] - public string? Recommendation { get; set; } - - /// - /// Expiry time in milliseconds since the unix epoch, or null if the ban has no expiry. - /// - [JsonPropertyName("support.feline.policy.expiry.rev.2")] //stable prefix: expiry, msc pending - public long? Expiry { get; set; } - - //utils - /// - /// Readable expiry time, provided for easy interaction - /// - [JsonPropertyName("gay.rory.matrix_room_utils.readable_expiry_time_utc")] - public DateTime? ExpiryDateTime { - get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime; - set => Expiry = ((DateTimeOffset)value).ToUnixTimeMilliseconds(); - } -} - -public static class PolicyRecommendationTypes { - /// - /// Ban this user - /// - public static string Ban = "m.ban"; - - /// - /// Mute this user - /// - public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs deleted file mode 100644 index 830386d..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomAliasEventContent : TimelineEventContent { - public const string EventId = "m.room.alias"; - - [JsonPropertyName("aliases")] - public List? Aliases { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs deleted file mode 100644 index 9c208ba..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomAvatarEventContent : TimelineEventContent { - public const string EventId = "m.room.avatar"; - - [JsonPropertyName("url")] - public string? Url { get; set; } - - [JsonPropertyName("info")] - public RoomAvatarInfo? Info { get; set; } - - public class RoomAvatarInfo { - [JsonPropertyName("h")] - public int? Height { get; set; } - - [JsonPropertyName("w")] - public int? Width { get; set; } - - [JsonPropertyName("mimetype")] - public string? MimeType { get; set; } - - [JsonPropertyName("size")] - public int? Size { get; set; } - } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs deleted file mode 100644 index 5ba253c..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomCanonicalAliasEventContent : TimelineEventContent { - public const string EventId = "m.room.canonical_alias"; - - [JsonPropertyName("alias")] - public string? Alias { get; set; } - - [JsonPropertyName("alt_aliases")] - public string[]? AltAliases { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs deleted file mode 100644 index 41145de..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomCreateEventContent : TimelineEventContent { - public const string EventId = "m.room.create"; - - [JsonPropertyName("room_version")] - public string? RoomVersion { get; set; } - - [JsonPropertyName("creator")] - public string? Creator { get; set; } - - [JsonPropertyName("m.federate")] - public bool? Federate { get; set; } - - [JsonPropertyName("predecessor")] - public RoomCreatePredecessor? Predecessor { get; set; } - - [JsonPropertyName("type")] - public string? Type { get; set; } - - public class RoomCreatePredecessor { - [JsonPropertyName("room_id")] - public string? RoomId { get; set; } - - [JsonPropertyName("event_id")] - public string? EventId { get; set; } - } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs deleted file mode 100644 index a3627f2..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.encryption")] -public class RoomEncryptionEventContent : TimelineEventContent { - [JsonPropertyName("algorithm")] - public string? Algorithm { get; set; } - [JsonPropertyName("rotation_period_ms")] - public ulong? RotationPeriodMs { get; set; } - [JsonPropertyName("rotation_period_msgs")] - public ulong? RotationPeriodMsgs { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs deleted file mode 100644 index 5bad649..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.guest_access")] -public class RoomGuestAccessEventContent : TimelineEventContent { - [JsonPropertyName("guest_access")] - public string GuestAccess { get; set; } - - public bool IsGuestAccessEnabled { - get => GuestAccess == "can_join"; - set => GuestAccess = value ? "can_join" : "forbidden"; - } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs deleted file mode 100644 index 8f5c7f1..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.history_visibility")] -public class RoomHistoryVisibilityEventContent : TimelineEventContent { - [JsonPropertyName("history_visibility")] - public string HistoryVisibility { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs deleted file mode 100644 index 2db9e60..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.join_rules")] -public class RoomJoinRulesEventContent : TimelineEventContent { - private static string Public = "public"; - private static string Invite = "invite"; - private static string Knock = "knock"; - - /// - /// one of ["public", "invite", "knock", "restricted", "knock_restricted"] - /// "private" is reserved without implementation! - /// - [JsonPropertyName("join_rule")] - public string JoinRule { get; set; } - - [JsonPropertyName("allow")] - public List Allow { get; set; } - - public class AllowEntry { - [JsonPropertyName("type")] - public string Type { get; set; } - - [JsonPropertyName("room_id")] - public string RoomId { get; set; } - } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs deleted file mode 100644 index 698315e..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomMemberEventContent : TimelineEventContent { - public const string EventId = "m.room.member"; - - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - [JsonPropertyName("membership")] - public string Membership { get; set; } = null!; - - [JsonPropertyName("displayname")] - public string? DisplayName { get; set; } - - [JsonPropertyName("is_direct")] - public bool? IsDirect { get; set; } - - [JsonPropertyName("avatar_url")] - public string? AvatarUrl { get; set; } - - [JsonPropertyName("kind")] - public string? Kind { get; set; } - - [JsonPropertyName("join_authorised_via_users_server")] - public string? JoinAuthorisedViaUsersServer { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs deleted file mode 100644 index 9ad67eb..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomNameEventContent : TimelineEventContent { - public const string EventId = "m.room.name"; - - [JsonPropertyName("name")] - public string? Name { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs deleted file mode 100644 index 11fe208..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.pinned_events")] -public class RoomPinnedEventContent : TimelineEventContent { - [JsonPropertyName("pinned")] - public string[]? PinnedEvents { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs deleted file mode 100644 index 08f8ad5..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = EventId)] -public class RoomPowerLevelEventContent : TimelineEventContent { - public const string EventId = "m.room.power_levels"; - - [JsonPropertyName("ban")] - public long? Ban { get; set; } = 50; - - [JsonPropertyName("events_default")] - public long? EventsDefault { get; set; } = 0; - - [JsonPropertyName("invite")] - public long? Invite { get; set; } = 0; - - [JsonPropertyName("kick")] - public long? Kick { get; set; } = 50; - - [JsonPropertyName("notifications")] - public NotificationsPL? NotificationsPl { get; set; } // = null!; - - [JsonPropertyName("redact")] - public long? Redact { get; set; } = 50; - - [JsonPropertyName("state_default")] - public long? StateDefault { get; set; } = 50; - - [JsonPropertyName("events")] - public Dictionary? Events { get; set; } // = null!; - - [JsonPropertyName("users")] - public Dictionary? Users { get; set; } // = null!; - - [JsonPropertyName("users_default")] - public long? UsersDefault { get; set; } = 0; - - [Obsolete("Historical was a key related to MSC2716, a spec change on backfill that was dropped!", true)] - [JsonIgnore] - [JsonPropertyName("historical")] - public long Historical { get; set; } // = 50; - - public class NotificationsPL { - [JsonPropertyName("room")] - public long Room { get; set; } = 50; - } - - public bool IsUserAdmin(string userId) { - if (userId is null) throw new ArgumentNullException(nameof(userId)); - return Users.TryGetValue(userId, out var level) && level >= Events.Max(x => x.Value); - } - - public bool UserHasTimelinePermission(string userId, string eventType) { - if (userId is null) throw new ArgumentNullException(nameof(userId)); - return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault ?? 0); - } - - public bool UserHasStatePermission(string userId, string eventType) { - if (userId is null) throw new ArgumentNullException(nameof(userId)); - return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, StateDefault ?? 50); - } - - public long GetUserPowerLevel(string userId) { - if (userId is null) throw new ArgumentNullException(nameof(userId)); - return Users.TryGetValue(userId, out var level) ? level : UsersDefault ?? UsersDefault ?? 0; - } - - public long GetEventPowerLevel(string eventType) { - return Events.TryGetValue(eventType, out var level) ? level : EventsDefault ?? EventsDefault ?? 0; - } - - public void SetUserPowerLevel(string userId, long powerLevel) { - if (userId is null) throw new ArgumentNullException(nameof(userId)); - Users ??= new(); - Users[userId] = powerLevel; - } -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs deleted file mode 100644 index cbd2241..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.server_acl")] -public class RoomServerACLEventContent : TimelineEventContent { - [JsonPropertyName("allow")] - public List Allow { get; set; } // = null!; - - [JsonPropertyName("deny")] - public List Deny { get; set; } // = null!; - - [JsonPropertyName("allow_ip_literals")] - public bool AllowIpLiterals { get; set; } // = false; -} diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs deleted file mode 100644 index 866eecf..0000000 --- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.room.topic")] -[MatrixEvent(EventName = "org.matrix.msc3765.topic", Legacy = true)] -public class RoomTopicEventContent : TimelineEventContent { - [JsonPropertyName("topic")] - public string? Topic { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/Space/SpaceChildEventContent.cs b/LibMatrix/EventTypes/Spec/State/Space/SpaceChildEventContent.cs deleted file mode 100644 index 82f4b7f..0000000 --- a/LibMatrix/EventTypes/Spec/State/Space/SpaceChildEventContent.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.space.child")] -public class SpaceChildEventContent : TimelineEventContent { - [JsonPropertyName("auto_join")] - public bool? AutoJoin { get; set; } - [JsonPropertyName("via")] - public List? Via { get; set; } - [JsonPropertyName("suggested")] - public bool? Suggested { get; set; } -} diff --git a/LibMatrix/EventTypes/Spec/State/Space/SpaceParentEventContent.cs b/LibMatrix/EventTypes/Spec/State/Space/SpaceParentEventContent.cs deleted file mode 100644 index 887e91c..0000000 --- a/LibMatrix/EventTypes/Spec/State/Space/SpaceParentEventContent.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes.Spec.State; - -[MatrixEvent(EventName = "m.space.parent")] -public class SpaceParentEventContent : TimelineEventContent { - [JsonPropertyName("via")] - public string[]? Via { get; set; } - - [JsonPropertyName("canonical")] - public bool? Canonical { get; set; } -} diff --git a/LibMatrix/EventTypes/UnknownStateEventContent.cs b/LibMatrix/EventTypes/UnknownStateEventContent.cs deleted file mode 100644 index c47dc99..0000000 --- a/LibMatrix/EventTypes/UnknownStateEventContent.cs +++ /dev/null @@ -1,7 +0,0 @@ -using LibMatrix.Interfaces; - -namespace LibMatrix.EventTypes; - -public class UnknownEventContent : TimelineEventContent { - -} diff --git a/LibMatrix/Extensions/HttpClientExtensions.cs b/LibMatrix/Extensions/HttpClientExtensions.cs index 6f27f71..93e1441 100644 --- a/LibMatrix/Extensions/HttpClientExtensions.cs +++ b/LibMatrix/Extensions/HttpClientExtensions.cs @@ -116,8 +116,8 @@ public class MatrixHttpClient : HttpClient { return await response.Content.ReadAsStreamAsync(cancellationToken); } - public new async Task PutAsJsonAsync([StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T value, JsonSerializerOptions? options = null, - CancellationToken cancellationToken = default) { + public async Task PutAsJsonAsync([StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T value, JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default) where T : notnull { options = GetJsonSerializerOptions(options); var request = new HttpRequestMessage(HttpMethod.Put, requestUri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); @@ -130,7 +130,7 @@ public class MatrixHttpClient : HttpClient { } public async Task PostAsJsonAsync([StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T value, JsonSerializerOptions? options = null, - CancellationToken cancellationToken = default) { + CancellationToken cancellationToken = default) where T : notnull { options ??= new(); options.Converters.Add(new JsonFloatStringConverter()); options.Converters.Add(new JsonDoubleStringConverter()); diff --git a/LibMatrix/Extensions/JsonElementExtensions.cs b/LibMatrix/Extensions/JsonElementExtensions.cs index 8c3884e..0bdf01c 100644 --- a/LibMatrix/Extensions/JsonElementExtensions.cs +++ b/LibMatrix/Extensions/JsonElementExtensions.cs @@ -37,7 +37,7 @@ public static class JsonElementExtensions { if (field.Name == "content" && (objectType == typeof(StateEventResponse) || objectType == typeof(StateEvent))) { unknownPropertyFound |= field.FindExtraJsonPropertyFieldsByValueKind( - StateEvent.GetStateEventType(obj.GetProperty("type").GetString()), + StateEvent.GetStateEventType(obj.GetProperty("type").GetString()!), // We expect type to always be present mappedProperty.PropertyType); continue; } diff --git a/LibMatrix/Helpers/MessageFormatter.cs b/LibMatrix/Helpers/MessageFormatter.cs index 03efeec..f275b57 100644 --- a/LibMatrix/Helpers/MessageFormatter.cs +++ b/LibMatrix/Helpers/MessageFormatter.cs @@ -6,7 +6,7 @@ namespace LibMatrix.Helpers; public static class MessageFormatter { public static RoomMessageEventContent FormatError(string error) { return new RoomMessageEventContent(body: error, messageType: "m.text") { - FormattedBody = $"{error}: {error}", + FormattedBody = $"{error}", Format = "org.matrix.custom.html" }; } @@ -46,4 +46,11 @@ public static class MessageFormatter { public static RoomMessageEventContent ToMatrixMessage(this Exception e, string error) => FormatException(error, e); #endregion + + public static RoomMessageEventContent FormatWarning(string warning) { + return new RoomMessageEventContent(body: warning, messageType: "m.text") { + FormattedBody = $"{warning}", + Format = "org.matrix.custom.html" + }; + } } diff --git a/LibMatrix/Helpers/SyncHelper.cs b/LibMatrix/Helpers/SyncHelper.cs index 334c288..ba42735 100644 --- a/LibMatrix/Helpers/SyncHelper.cs +++ b/LibMatrix/Helpers/SyncHelper.cs @@ -38,12 +38,12 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg // Console.WriteLine("Calling: " + url); 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 ?? 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); + logger?.LogInformation("Got sync response: {} bytes, {} elapsed", httpResp.Content.Headers.ContentLength ?? -1, sw.Elapsed); var deserializeSw = Stopwatch.StartNew(); - var resp = await httpResp.Content.ReadFromJsonAsync(cancellationToken: cancellationToken ?? CancellationToken.None)!; - logger?.LogInformation("Deserialized sync response: {} bytes, {} elapsed, {} total", httpResp?.Content.Headers.ContentLength ?? -1, deserializeSw.Elapsed, sw.Elapsed); + var resp = await httpResp.Content.ReadFromJsonAsync(cancellationToken: cancellationToken ?? CancellationToken.None); + logger?.LogInformation("Deserialized sync response: {} bytes, {} elapsed, {} total", httpResp.Content.Headers.ContentLength ?? -1, deserializeSw.Elapsed, sw.Elapsed); var timeToWait = MinimumDelay.Subtract(sw.Elapsed); if (timeToWait.TotalMilliseconds > 0) await Task.Delay(timeToWait); @@ -65,7 +65,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg while (!cancellationToken?.IsCancellationRequested ?? true) { var sync = await SyncAsync(cancellationToken); if (sync is null) continue; - if (!string.IsNullOrWhiteSpace(sync?.NextBatch)) Since = sync.NextBatch; + if (!string.IsNullOrWhiteSpace(sync.NextBatch)) Since = sync.NextBatch; yield return sync; } } @@ -76,7 +76,7 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg var oldTimeout = Timeout; Timeout = 0; await foreach (var sync in EnumerateSyncAsync(cancellationToken)) { - if (sync?.ToJson(ignoreNull: true, indent: false).Length < 250) { + if (sync.ToJson(ignoreNull: true, indent: false).Length < 250) { emptyInitialSyncCount++; if (emptyInitialSyncCount > 5) { IsInitialSync = false; diff --git a/LibMatrix/Helpers/SyncStateResolver.cs b/LibMatrix/Helpers/SyncStateResolver.cs index f40fa22..f380a1f 100644 --- a/LibMatrix/Helpers/SyncStateResolver.cs +++ b/LibMatrix/Helpers/SyncStateResolver.cs @@ -162,7 +162,11 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge oldData.UnreadNotifications.HighlightCount = newData.UnreadNotifications?.HighlightCount ?? oldData.UnreadNotifications.HighlightCount; oldData.UnreadNotifications.NotificationCount = newData.UnreadNotifications?.NotificationCount ?? oldData.UnreadNotifications.NotificationCount; - oldData.Summary ??= new(); + oldData.Summary ??= new() { + Heroes = newData.Summary?.Heroes ?? oldData.Summary.Heroes, + JoinedMemberCount = newData.Summary?.JoinedMemberCount ?? oldData.Summary.JoinedMemberCount, + InvitedMemberCount = newData.Summary?.InvitedMemberCount ?? oldData.Summary.InvitedMemberCount + }; oldData.Summary.Heroes = newData.Summary?.Heroes ?? oldData.Summary.Heroes; oldData.Summary.JoinedMemberCount = newData.Summary?.JoinedMemberCount ?? oldData.Summary.JoinedMemberCount; oldData.Summary.InvitedMemberCount = newData.Summary?.InvitedMemberCount ?? oldData.Summary.InvitedMemberCount; diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs index e85ecd2..cf85287 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; @@ -50,9 +51,9 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke } public WhoAmIResponse WhoAmI { get; set; } - public string? UserId => WhoAmI?.UserId; - public string? UserLocalpart => UserId?.Split(":")[0][1..]; - public string? ServerName => UserId?.Split(":", 2)[1]; + public string UserId => WhoAmI.UserId; + public string UserLocalpart => UserId.Split(":")[0][1..]; + public string ServerName => UserId.Split(":", 2)[1]; // public virtual async Task WhoAmI() { // if (_whoAmI is not null) return _whoAmI; @@ -289,10 +290,10 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke } public async Task JoinRoomAsync(string roomId, List homeservers = null, string? reason = null) { - var join_url = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(roomId)}"; - Console.WriteLine($"Calling {join_url} with {homeservers?.Count ?? 0} via's..."); + var joinUrl = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(roomId)}"; + Console.WriteLine($"Calling {joinUrl} with {homeservers?.Count ?? 0} via's..."); if (homeservers == null || homeservers.Count == 0) homeservers = new() { roomId.Split(':')[1] }; - var fullJoinUrl = $"{join_url}?server_name=" + string.Join("&server_name=", homeservers); + var fullJoinUrl = $"{joinUrl}?server_name=" + string.Join("&server_name=", homeservers); var res = await ClientHttpClient.PostAsJsonAsync(fullJoinUrl, new { reason }); diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs index 28ff775..6562686 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs @@ -20,7 +20,7 @@ public class AuthenticatedHomeserverSynapse : AuthenticatedHomeserverGeneric { Console.WriteLine($"--- ADMIN Querying Room List with URL: {url} - Already have {i} items... ---"); res = await authenticatedHomeserver.ClientHttpClient.GetFromJsonAsync(url); - totalRooms ??= res?.TotalRooms; + totalRooms ??= res.TotalRooms; Console.WriteLine(res.ToJson(false)); foreach (var room in res.Rooms) { if (localFilter is not null) { diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs index f8d61fd..a47b731 100644 --- a/LibMatrix/Homeservers/RemoteHomeServer.cs +++ b/LibMatrix/Homeservers/RemoteHomeServer.cs @@ -2,7 +2,6 @@ using System.Net.Http.Json; using System.Text.Json; using System.Text.Json.Serialization; using ArcaneLibs.Extensions; -using LibMatrix.EventTypes.Spec.State; using LibMatrix.Extensions; using LibMatrix.Responses; using LibMatrix.Services; @@ -10,6 +9,7 @@ using LibMatrix.Services; namespace LibMatrix.Homeservers; public class RemoteHomeserver(string baseUrl) { + public static async Task Create(string baseUrl, string? proxy = null) { var homeserver = new RemoteHomeserver(baseUrl); homeserver.WellKnownUris = await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl); @@ -32,9 +32,10 @@ public class RemoteHomeserver(string baseUrl) { private Dictionary _profileCache { get; set; } = new(); public string BaseUrl { get; } = baseUrl; - public MatrixHttpClient ClientHttpClient { get; set; } - public MatrixHttpClient ServerHttpClient { get; set; } - public HomeserverResolverService.WellKnownUris WellKnownUris { get; set; } + + public MatrixHttpClient ClientHttpClient { get; set; } = null!; + public MatrixHttpClient ServerHttpClient { get; set; } = null!; + public HomeserverResolverService.WellKnownUris WellKnownUris { get; set; } = null!; public async Task GetProfileAsync(string mxid) { if (mxid is null) throw new ArgumentNullException(nameof(mxid)); @@ -63,7 +64,7 @@ public class RemoteHomeserver(string baseUrl) { public async Task ResolveRoomAliasAsync(string alias) { var resp = await ClientHttpClient.GetAsync($"/_matrix/client/v3/directory/room/{alias.Replace("#", "%23")}"); var data = await resp.Content.ReadFromJsonAsync(); - var text = await resp.Content.ReadAsStringAsync(); + //var text = await resp.Content.ReadAsStringAsync(); if (!resp.IsSuccessStatusCode) Console.WriteLine("ResolveAlias: " + data.ToJson()); return data; } @@ -119,8 +120,9 @@ public class RemoteHomeserver(string baseUrl) { public class ServerVersionResponse { [JsonPropertyName("server")] - public ServerInfo Server { get; set; } + public required ServerInfo Server { get; set; } + // ReSharper disable once ClassNeverInstantiated.Global public class ServerInfo { [JsonPropertyName("name")] public string Name { get; set; } diff --git a/LibMatrix/Interfaces/EventContent.cs b/LibMatrix/Interfaces/EventContent.cs deleted file mode 100644 index 76419a6..0000000 --- a/LibMatrix/Interfaces/EventContent.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; - -namespace LibMatrix.Interfaces; - -public abstract class EventContent { } - -public abstract class TimelineEventContent : EventContent { - [JsonPropertyName("m.relates_to")] - public MessageRelatesTo? RelatesTo { get; set; } - - [JsonPropertyName("m.new_content")] - public JsonObject? NewContent { get; set; } - - public TimelineEventContent SetReplaceRelation(string eventId) { - NewContent = JsonSerializer.SerializeToNode(this, GetType()).AsObject(); - // NewContent = JsonSerializer.Deserialize(jsonText, GetType()); - RelatesTo = new() { - RelationType = "m.replace", - EventId = eventId - }; - return this; - } - - public T SetReplaceRelation(string eventId) where T : TimelineEventContent { - return SetReplaceRelation(eventId) as T ?? throw new InvalidOperationException(); - } - - public class MessageRelatesTo { - [JsonPropertyName("m.in_reply_to")] - public EventInReplyTo? InReplyTo { get; set; } - - [JsonPropertyName("event_id")] - public string? EventId { get; set; } - - [JsonPropertyName("rel_type")] - public string? RelationType { get; set; } - - public class EventInReplyTo { - [JsonPropertyName("event_id")] - public string EventId { get; set; } - - [JsonPropertyName("rel_type")] - public string RelType { get; set; } - } - } -} diff --git a/LibMatrix/LibMatrix.csproj b/LibMatrix/LibMatrix.csproj index afe06d7..07bd831 100644 --- a/LibMatrix/LibMatrix.csproj +++ b/LibMatrix/LibMatrix.csproj @@ -20,13 +20,18 @@ + + + + + - + diff --git a/LibMatrix/MatrixException.cs b/LibMatrix/MatrixException.cs index 863c6d4..10f0433 100644 --- a/LibMatrix/MatrixException.cs +++ b/LibMatrix/MatrixException.cs @@ -5,10 +5,10 @@ namespace LibMatrix; public class MatrixException : Exception { [JsonPropertyName("errcode")] - public string ErrorCode { get; set; } + public required string ErrorCode { get; set; } [JsonPropertyName("error")] - public string Error { get; set; } + public required string Error { get; set; } [JsonPropertyName("soft_logout")] public bool? SoftLogout { get; set; } diff --git a/LibMatrix/Responses/Admin/AdminRoomListingResult.cs b/LibMatrix/Responses/Admin/AdminRoomListingResult.cs index f035184..a90bc6f 100644 --- a/LibMatrix/Responses/Admin/AdminRoomListingResult.cs +++ b/LibMatrix/Responses/Admin/AdminRoomListingResult.cs @@ -20,7 +20,7 @@ public class AdminRoomListingResult { public class AdminRoomListingResultRoom { [JsonPropertyName("room_id")] - public string RoomId { get; set; } + public required string RoomId { get; set; } [JsonPropertyName("name")] public string? Name { get; set; } @@ -35,10 +35,10 @@ public class AdminRoomListingResult { public int JoinedLocalMembers { get; set; } [JsonPropertyName("version")] - public string Version { get; set; } + public string? Version { get; set; } [JsonPropertyName("creator")] - public string Creator { get; set; } + public string? Creator { get; set; } [JsonPropertyName("encryption")] public string? Encryption { get; set; } diff --git a/LibMatrix/Responses/CreateRoomRequest.cs b/LibMatrix/Responses/CreateRoomRequest.cs index 85db517..f8d1d05 100644 --- a/LibMatrix/Responses/CreateRoomRequest.cs +++ b/LibMatrix/Responses/CreateRoomRequest.cs @@ -10,28 +10,28 @@ using LibMatrix.Interfaces; namespace LibMatrix.Responses; public class CreateRoomRequest { - [JsonIgnore] public CreationContentBaseType _creationContentBaseType; + [JsonIgnore] public CreationContentBaseType CreationContentBaseType; - public CreateRoomRequest() => _creationContentBaseType = new CreationContentBaseType(this); + public CreateRoomRequest() => CreationContentBaseType = new CreationContentBaseType(this); [JsonPropertyName("name")] - public string Name { get; set; } = null!; + public string? Name { get; set; } [JsonPropertyName("room_alias_name")] - public string RoomAliasName { get; set; } = null!; + public string? RoomAliasName { get; set; } //we dont want to use this, we want more control // [JsonPropertyName("preset")] // public string Preset { get; set; } = null!; [JsonPropertyName("initial_state")] - public List InitialState { get; set; } = null!; + public List? InitialState { get; set; } /// /// One of: ["public", "private"] /// [JsonPropertyName("visibility")] - public string Visibility { get; set; } = null!; + public string? Visibility { get; set; } [JsonPropertyName("power_level_content_override")] public RoomPowerLevelEventContent PowerLevelContentOverride { get; set; } = null!; @@ -46,25 +46,25 @@ public class CreateRoomRequest { /// For use only when you can't use the CreationContent property /// - public StateEvent this[string event_type, string event_key = ""] { + public StateEvent this[string eventType, string eventKey = ""] { get { - var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key); + var stateEvent = InitialState.FirstOrDefault(x => x.Type == eventType && x.StateKey == eventKey); if (stateEvent == null) { InitialState.Add(stateEvent = new StateEvent { - Type = event_type, - StateKey = event_key, + Type = eventType, + StateKey = eventKey, TypedContent = (EventContent)Activator.CreateInstance( StateEvent.KnownStateEventTypes.FirstOrDefault(x => x.GetCustomAttributes()? - .Any(y => y.EventName == event_type) ?? false) ?? typeof(object) - ) + .Any(y => y.EventName == eventType) ?? false) ?? typeof(object) + )! }); } return stateEvent; } set { - var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key); + var stateEvent = InitialState.FirstOrDefault(x => x.Type == eventType && x.StateKey == eventKey); if (stateEvent == null) InitialState.Add(value); else diff --git a/LibMatrix/Responses/CreationContentBaseType.cs b/LibMatrix/Responses/CreationContentBaseType.cs index ba3ce5e..073bb60 100644 --- a/LibMatrix/Responses/CreationContentBaseType.cs +++ b/LibMatrix/Responses/CreationContentBaseType.cs @@ -3,16 +3,16 @@ using System.Text.Json.Serialization; namespace LibMatrix.Responses; public class CreationContentBaseType { - private readonly CreateRoomRequest createRoomRequest; + private readonly CreateRoomRequest _createRoomRequest; - public CreationContentBaseType(CreateRoomRequest createRoomRequest) => this.createRoomRequest = createRoomRequest; + public CreationContentBaseType(CreateRoomRequest createRoomRequest) => this._createRoomRequest = createRoomRequest; [JsonPropertyName("type")] public string Type { - get => (string)createRoomRequest.CreationContent["type"]; + get => (string)_createRoomRequest.CreationContent["type"]; set { - if (value is "null" or "") createRoomRequest.CreationContent.Remove("type"); - else createRoomRequest.CreationContent["type"] = value; + if (value is "null" or "") _createRoomRequest.CreationContent.Remove("type"); + else _createRoomRequest.CreationContent["type"] = value; } } } diff --git a/LibMatrix/Responses/LoginResponse.cs b/LibMatrix/Responses/LoginResponse.cs index 82004fc..c5d4e87 100644 --- a/LibMatrix/Responses/LoginResponse.cs +++ b/LibMatrix/Responses/LoginResponse.cs @@ -1,7 +1,5 @@ -using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; using LibMatrix.Homeservers; -using LibMatrix.Services; namespace LibMatrix.Responses; diff --git a/LibMatrix/Responses/SyncResponse.cs b/LibMatrix/Responses/SyncResponse.cs index d3130bb..42759ff 100644 --- a/LibMatrix/Responses/SyncResponse.cs +++ b/LibMatrix/Responses/SyncResponse.cs @@ -50,13 +50,13 @@ public class SyncResponse { public class LeftRoomDataStructure { [JsonPropertyName("account_data")] - public EventList AccountData { get; set; } + public EventList? AccountData { get; set; } [JsonPropertyName("timeline")] public JoinedRoomDataStructure.TimelineDataStructure? Timeline { get; set; } [JsonPropertyName("state")] - public EventList State { get; set; } + public EventList? State { get; set; } } public class JoinedRoomDataStructure { @@ -99,13 +99,13 @@ public class SyncResponse { public class SummaryDataStructure { [JsonPropertyName("m.heroes")] - public List Heroes { get; set; } + public List? Heroes { get; set; } [JsonPropertyName("m.invited_member_count")] - public int InvitedMemberCount { get; set; } + public int? InvitedMemberCount { get; set; } [JsonPropertyName("m.joined_member_count")] - public int JoinedMemberCount { get; set; } + public int? JoinedMemberCount { get; set; } } } diff --git a/LibMatrix/Responses/UserProfileResponse.cs b/LibMatrix/Responses/UserProfileResponse.cs index e56e87b..9972a26 100644 --- a/LibMatrix/Responses/UserProfileResponse.cs +++ b/LibMatrix/Responses/UserProfileResponse.cs @@ -1,5 +1,4 @@ using System.Text.Json.Serialization; -using LibMatrix.Interfaces; namespace LibMatrix.Responses; diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index 9804e78..d067f9f 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -4,39 +4,39 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Web; using ArcaneLibs.Extensions; +using LibMatrix.EventTypes; using LibMatrix.EventTypes.Spec; using LibMatrix.EventTypes.Spec.State; -using LibMatrix.Extensions; +using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Homeservers; -using LibMatrix.Interfaces; namespace LibMatrix.RoomTypes; public class GenericRoom { internal readonly AuthenticatedHomeserverGeneric Homeserver; - internal readonly MatrixHttpClient _httpClient; public GenericRoom(AuthenticatedHomeserverGeneric homeserver, string roomId) { if (string.IsNullOrWhiteSpace(roomId)) throw new ArgumentException("Room ID cannot be null or whitespace", nameof(roomId)); Homeserver = homeserver; - _httpClient = homeserver.ClientHttpClient; RoomId = roomId; - if (GetType() != typeof(SpaceRoom)) + // if (GetType() != typeof(SpaceRoom)) + if (GetType() == typeof(GenericRoom)) { AsSpace = new SpaceRoom(homeserver, RoomId); + } } public string RoomId { get; set; } public async IAsyncEnumerable GetFullStateAsync() { - var result = _httpClient.GetAsyncEnumerableFromJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state"); + var result = Homeserver.ClientHttpClient.GetAsyncEnumerableFromJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state"); await foreach (var resp in result) { yield return resp; } } public async Task> GetFullStateAsListAsync() { - return await _httpClient.GetFromJsonAsync>($"/_matrix/client/v3/rooms/{RoomId}/state"); + return await Homeserver.ClientHttpClient.GetFromJsonAsync>($"/_matrix/client/v3/rooms/{RoomId}/state"); } public async Task GetStateAsync(string type, string stateKey = "") { @@ -56,7 +56,7 @@ public class GenericRoom { return resp.Deserialize(); #else - var resp = await _httpClient.GetFromJsonAsync(url); + var resp = await Homeserver.ClientHttpClient.GetFromJsonAsync(url); return resp; #endif } @@ -85,8 +85,8 @@ public class GenericRoom { if (!string.IsNullOrWhiteSpace(from)) url += $"&from={from}"; if (limit is not null) url += $"&limit={limit}"; if (!string.IsNullOrWhiteSpace(filter)) url += $"&filter={filter}"; - var res = await _httpClient.GetFromJsonAsync(url); - return res ?? new MessagesResponse(); + var res = await Homeserver.ClientHttpClient.GetFromJsonAsync(url); + return res; } /// @@ -101,8 +101,8 @@ public class GenericRoom { concat.Add(resp); if (!includeState) resp.State.Clear(); - from = resp.End; if (resp.End is null) break; + from = resp.End; } concat.Reverse(); @@ -131,12 +131,12 @@ public class GenericRoom { resp.State.Clear(); limit -= resp.Chunk.Count + resp.State.Count; - from = resp.End; yield return resp; if (resp.End is null) { Console.WriteLine("End is null"); yield break; } + from = resp.End; } } @@ -148,19 +148,19 @@ public class GenericRoom { public async Task JoinAsync(string[]? homeservers = null, string? reason = null, bool checkIfAlreadyMember = true) { if (checkIfAlreadyMember) { try { - var ce = await GetCreateEventAsync(); - return new() { + _ = await GetCreateEventAsync(); + return new RoomIdResponse { RoomId = RoomId }; } catch { } //ignore } - var join_url = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(RoomId)}"; - Console.WriteLine($"Calling {join_url} with {homeservers?.Length ?? 0} via's..."); + var joinUrl = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(RoomId)}"; + Console.WriteLine($"Calling {joinUrl} with {homeservers?.Length ?? 0} via's..."); if (homeservers == null || homeservers.Length == 0) homeservers = new[] { RoomId.Split(':')[1] }; - var fullJoinUrl = $"{join_url}?server_name=" + string.Join("&server_name=", homeservers); - var res = await _httpClient.PostAsJsonAsync(fullJoinUrl, new { + var fullJoinUrl = $"{joinUrl}?server_name=" + string.Join("&server_name=", homeservers); + var res = await Homeserver.ClientHttpClient.PostAsJsonAsync(fullJoinUrl, new { reason }); return await res.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to join room?"); @@ -168,9 +168,9 @@ public class GenericRoom { public async IAsyncEnumerable GetMembersAsync(bool joinedOnly = true) { var sw = Stopwatch.StartNew(); - var res = await _httpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/members"); + var res = await Homeserver.ClientHttpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/members"); Console.WriteLine($"Members call responded in {sw.GetElapsedAndRestart()}"); - var resText = await res.Content.ReadAsStringAsync(); + // var resText = await res.Content.ReadAsStringAsync(); Console.WriteLine($"Members call response read in {sw.GetElapsedAndRestart()}"); var result = await JsonSerializer.DeserializeAsync(await res.Content.ReadAsStreamAsync(), new JsonSerializerOptions() { TypeInfoResolver = ChunkedStateEventResponseSerializerContext.Default, @@ -188,7 +188,7 @@ public class GenericRoom { #region Utility shortcuts - public async Task SendMessageEventAsync(RoomMessageEventContent content) => + public async Task SendMessageEventAsync(RoomMessageEventContent content) => await SendTimelineEventAsync("m.room.message", content); public async Task?> GetAliasesAsync() { @@ -259,29 +259,29 @@ public class GenericRoom { #region Simple calls public async Task ForgetAsync() => - await _httpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null); + await Homeserver.ClientHttpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null); public async Task LeaveAsync(string? reason = null) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/leave", new { + await Homeserver.ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/leave", new { reason }); public async Task KickAsync(string userId, string? reason = null) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/kick", + await Homeserver.ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/kick", new UserIdAndReason { UserId = userId, Reason = reason }); public async Task BanAsync(string userId, string? reason = null) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/ban", + await Homeserver.ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/ban", new UserIdAndReason { UserId = userId, Reason = reason }); public async Task UnbanAsync(string userId) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban", + await Homeserver.ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban", new UserIdAndReason { UserId = userId }); public async Task InviteUserAsync(string userId, string? reason = null, bool skipExisting = true) { if (skipExisting && await GetStateAsync("m.room.member", userId) is not null) return; - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/invite", new UserIdAndReason(userId, reason)); + await Homeserver.ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/invite", new UserIdAndReason(userId, reason)); } #endregion @@ -289,19 +289,19 @@ public class GenericRoom { #region Events public async Task SendStateEventAsync(string eventType, object content) => - await (await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content)) + await (await Homeserver.ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content)) .Content.ReadFromJsonAsync(); public async Task SendStateEventAsync(string eventType, string stateKey, object content) => - await (await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}/{stateKey}", content)) + await (await Homeserver.ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}/{stateKey}", content)) .Content.ReadFromJsonAsync(); - public async Task SendTimelineEventAsync(string eventType, TimelineEventContent content) { - var res = await _httpClient.PutAsJsonAsync( + public async Task SendTimelineEventAsync(string eventType, TimelineEventContent content) { + var res = await Homeserver.ClientHttpClient.PutAsJsonAsync( $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(), content, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); - return await res.Content.ReadFromJsonAsync(); + return await res.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to send event"); } public async Task SendFileAsync(string fileName, Stream fileStream, string messageType = "m.file", string contentType = "application/octet-stream") { @@ -320,7 +320,7 @@ public class GenericRoom { } public async Task GetRoomAccountDataAsync(string key) { - var res = await _httpClient.GetAsync($"/_matrix/client/v3/user/{Homeserver.UserId}/rooms/{RoomId}/account_data/{key}"); + var res = await Homeserver.ClientHttpClient.GetAsync($"/_matrix/client/v3/user/{Homeserver.UserId}/rooms/{RoomId}/account_data/{key}"); if (!res.IsSuccessStatusCode) { Console.WriteLine($"Failed to get room account data: {await res.Content.ReadAsStringAsync()}"); throw new InvalidDataException($"Failed to get room account data: {await res.Content.ReadAsStringAsync()}"); @@ -330,7 +330,7 @@ public class GenericRoom { } public async Task SetRoomAccountDataAsync(string key, object data) { - var res = await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{Homeserver.UserId}/rooms/{RoomId}/account_data/{key}", data); + var res = await Homeserver.ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{Homeserver.UserId}/rooms/{RoomId}/account_data/{key}", data); if (!res.IsSuccessStatusCode) { Console.WriteLine($"Failed to set room account data: {await res.Content.ReadAsStringAsync()}"); throw new InvalidDataException($"Failed to set room account data: {await res.Content.ReadAsStringAsync()}"); @@ -338,12 +338,12 @@ public class GenericRoom { } public async Task GetEventAsync(string eventId) { - return await _httpClient.GetFromJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/event/{eventId}"); + return await Homeserver.ClientHttpClient.GetFromJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/event/{eventId}"); } public async Task RedactEventAsync(string eventToRedact, string reason) { var data = new { reason }; - return (await (await _httpClient.PutAsJsonAsync( + return (await (await Homeserver.ClientHttpClient.PutAsJsonAsync( $"/_matrix/client/v3/rooms/{RoomId}/redact/{eventToRedact}/{Guid.NewGuid()}", data)).Content.ReadFromJsonAsync())!; } @@ -353,7 +353,7 @@ public class GenericRoom { public async Task>> GetMembersByHomeserverAsync(bool joinedOnly = true) { if (Homeserver is AuthenticatedHomeserverMxApiExtended mxaeHomeserver) - return await Homeserver.ClientHttpClient.GetFromJsonAsync>>( + return await mxaeHomeserver.ClientHttpClient.GetFromJsonAsync>>( $"/_matrix/client/v3/rooms/{RoomId}/members_by_homeserver?joined_only={joinedOnly}"); Dictionary> roomHomeservers = new(); var members = GetMembersAsync(); diff --git a/LibMatrix/RoomTypes/SpaceRoom.cs b/LibMatrix/RoomTypes/SpaceRoom.cs index da9fcf8..6ebd62f 100644 --- a/LibMatrix/RoomTypes/SpaceRoom.cs +++ b/LibMatrix/RoomTypes/SpaceRoom.cs @@ -4,10 +4,8 @@ using LibMatrix.Homeservers; namespace LibMatrix.RoomTypes; public class SpaceRoom(AuthenticatedHomeserverGeneric homeserver, string roomId) : GenericRoom(homeserver, roomId) { - private readonly GenericRoom _room; - public async IAsyncEnumerable GetChildrenAsync(bool includeRemoved = false) { - var rooms = new List(); + // var rooms = new List(); var state = GetFullStateAsync(); await foreach (var stateEvent in state) { if (stateEvent!.Type != "m.space.child") continue; diff --git a/LibMatrix/Services/HomeserverProviderService.cs b/LibMatrix/Services/HomeserverProviderService.cs index a42077a..983f469 100644 --- a/LibMatrix/Services/HomeserverProviderService.cs +++ b/LibMatrix/Services/HomeserverProviderService.cs @@ -6,20 +6,20 @@ using Microsoft.Extensions.Logging; namespace LibMatrix.Services; -public class HomeserverProviderService(ILogger logger, HomeserverResolverService homeserverResolverService) { - private static Dictionary _authenticatedHomeserverSemaphore = new(); - private static Dictionary _authenticatedHomeserverCache = new(); +public class HomeserverProviderService(ILogger logger) { + private static readonly Dictionary AuthenticatedHomeserverSemaphore = new(); + private static readonly Dictionary AuthenticatedHomeserverCache = new(); - private static Dictionary _remoteHomeserverSemaphore = new(); - private static Dictionary _remoteHomeserverCache = new(); + private static readonly Dictionary RemoteHomeserverSemaphore = new(); + private static readonly Dictionary RemoteHomeserverCache = new(); public async Task GetAuthenticatedWithToken(string homeserver, string accessToken, string? proxy = null) { var cacheKey = homeserver + accessToken + proxy; - var sem = _authenticatedHomeserverSemaphore.GetOrCreate(cacheKey, _ => new SemaphoreSlim(1, 1)); + var sem = AuthenticatedHomeserverSemaphore.GetOrCreate(cacheKey, _ => new SemaphoreSlim(1, 1)); await sem.WaitAsync(); AuthenticatedHomeserverGeneric? hs; - lock (_authenticatedHomeserverCache) { - if (_authenticatedHomeserverCache.TryGetValue(cacheKey, out hs)) { + lock (AuthenticatedHomeserverCache) { + if (AuthenticatedHomeserverCache.TryGetValue(cacheKey, out hs)) { sem.Release(); return hs; } @@ -30,8 +30,8 @@ public class HomeserverProviderService(ILogger logger var rhs = await RemoteHomeserver.Create(homeserver, proxy); var clientVersions = await rhs.GetClientVersionsAsync(); if (proxy is not null) - Console.WriteLine($"Homeserver {homeserver} proxied via {proxy}..."); - Console.WriteLine($"{homeserver}: " + clientVersions.ToJson()); + logger.LogInformation($"Homeserver {homeserver} proxied via {proxy}..."); + logger.LogInformation($"{homeserver}: " + clientVersions.ToJson()); if (clientVersions.UnstableFeatures.TryGetValue("gay.rory.mxapiextensions.v0", out bool a) && a) hs = await AuthenticatedHomeserverGeneric.Create(homeserver, accessToken, proxy); @@ -43,18 +43,31 @@ public class HomeserverProviderService(ILogger logger hs = await AuthenticatedHomeserverGeneric.Create(homeserver, accessToken, proxy); } - lock (_authenticatedHomeserverCache) - _authenticatedHomeserverCache[cacheKey] = hs; + lock (AuthenticatedHomeserverCache) + AuthenticatedHomeserverCache[cacheKey] = hs; sem.Release(); return hs; } public async Task GetRemoteHomeserver(string homeserver, string? proxy = null) { - var hs = await RemoteHomeserver.Create(homeserver, proxy); - // hs._httpClient.Dispose(); - // hs._httpClient = new MatrixHttpClient { BaseAddress = new Uri(hs.ServerName) }; - // hs._httpClient.Timeout = TimeSpan.FromSeconds(120); + var cacheKey = homeserver + proxy; + var sem = RemoteHomeserverSemaphore.GetOrCreate(cacheKey, _ => new SemaphoreSlim(1, 1)); + await sem.WaitAsync(); + RemoteHomeserver? hs; + lock (RemoteHomeserverCache) { + if (RemoteHomeserverCache.TryGetValue(cacheKey, out hs)) { + sem.Release(); + return hs; + } + } + + hs = await RemoteHomeserver.Create(homeserver, proxy); + + lock (RemoteHomeserverCache) + RemoteHomeserverCache[cacheKey] = hs; + sem.Release(); + return hs; } @@ -68,4 +81,4 @@ public class HomeserverProviderService(ILogger logger var data = await resp.Content.ReadFromJsonAsync(); return data!; } -} +} \ No newline at end of file diff --git a/LibMatrix/Services/HomeserverResolverService.cs b/LibMatrix/Services/HomeserverResolverService.cs index f9f92d6..9f937c5 100644 --- a/LibMatrix/Services/HomeserverResolverService.cs +++ b/LibMatrix/Services/HomeserverResolverService.cs @@ -11,15 +11,15 @@ public class HomeserverResolverService(ILogger? logge Timeout = TimeSpan.FromMilliseconds(10000) }; - private static readonly ConcurrentDictionary _wellKnownCache = new(); - private static readonly ConcurrentDictionary _wellKnownSemaphores = new(); + private static readonly ConcurrentDictionary WellKnownCache = new(); + private static readonly ConcurrentDictionary WellKnownSemaphores = new(); public async Task ResolveHomeserverFromWellKnown(string homeserver) { if (homeserver is null) throw new ArgumentNullException(nameof(homeserver)); - _wellKnownSemaphores.TryAdd(homeserver, new(1, 1)); - await _wellKnownSemaphores[homeserver].WaitAsync(); - if (_wellKnownCache.TryGetValue(homeserver, out var known)) { - _wellKnownSemaphores[homeserver].Release(); + WellKnownSemaphores.TryAdd(homeserver, new(1, 1)); + await WellKnownSemaphores[homeserver].WaitAsync(); + if (WellKnownCache.TryGetValue(homeserver, out var known)) { + WellKnownSemaphores[homeserver].Release(); return known; } @@ -28,8 +28,8 @@ public class HomeserverResolverService(ILogger? logge Client = await _tryResolveFromClientWellknown(homeserver), Server = await _tryResolveFromServerWellknown(homeserver) }; - _wellKnownCache.TryAdd(homeserver, res); - _wellKnownSemaphores[homeserver].Release(); + WellKnownCache.TryAdd(homeserver, res); + WellKnownSemaphores[homeserver].Release(); return res; } @@ -40,7 +40,9 @@ public class HomeserverResolverService(ILogger? logge var hs = resp.GetProperty("m.homeserver").GetProperty("base_url").GetString(); return hs; } - catch { } + catch { + // ignored + } logger?.LogInformation("No client well-known..."); return null; @@ -51,11 +53,14 @@ public class HomeserverResolverService(ILogger? logge try { var resp = await _httpClient.GetFromJsonAsync($"{homeserver}/.well-known/matrix/server"); var hs = resp.GetProperty("m.server").GetString(); + if(hs is null) throw new InvalidDataException("m.server is null"); if (!hs.StartsWithAnyOf("http://", "https://")) hs = $"https://{hs}"; return hs; } - catch { } + catch { + // ignored + } // fallback: most servers host these on the same location var clientUrl = await _tryResolveFromClientWellknown(homeserver); diff --git a/LibMatrix/StateEvent.cs b/LibMatrix/StateEvent.cs index 6ca82f4..cfc7011 100644 --- a/LibMatrix/StateEvent.cs +++ b/LibMatrix/StateEvent.cs @@ -1,3 +1,5 @@ +using System.Collections.Frozen; +using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json; @@ -7,31 +9,23 @@ using ArcaneLibs; using ArcaneLibs.Extensions; using LibMatrix.EventTypes; using LibMatrix.Extensions; -using LibMatrix.Interfaces; namespace LibMatrix; public class StateEvent { - public static List KnownStateEventTypes { get; } = new ClassCollector().ResolveFromAllAccessibleAssemblies(); + public static FrozenSet KnownStateEventTypes { get; } = new ClassCollector().ResolveFromAllAccessibleAssemblies().ToFrozenSet(); - public static readonly Dictionary KnownStateEventTypesByName = KnownStateEventTypes.Aggregate( + public static FrozenDictionary KnownStateEventTypesByName { get; } = KnownStateEventTypes.Aggregate( new Dictionary(), (dict, type) => { var attrs = type.GetCustomAttributes(); foreach (var attr in attrs) { dict[attr.EventName] = type; } - return dict; - }); - - public static Type GetStateEventType(string type) { - if (type == "m.receipt") { - return typeof(Dictionary); - } + }).ToFrozenDictionary(); - return KnownStateEventTypesByName.GetValueOrDefault(type) ?? typeof(UnknownEventContent); - } + public static Type GetStateEventType(string type) => KnownStateEventTypesByName.GetValueOrDefault(type) ?? typeof(UnknownEventContent); private static readonly JsonSerializerOptions TypedContentSerializerOptions = new JsonSerializerOptions() { Converters = { @@ -80,13 +74,7 @@ public class StateEvent { [JsonPropertyName("content")] public JsonObject? RawContent { get => _rawContent; - set { - _rawContent = value; - // if (Type is not null && this is StateEventResponse stateEventResponse) { - // if (File.Exists($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json")) return; - // var x = GetType.Name; - // } - } + set => _rawContent = value; } [JsonIgnore] @@ -139,22 +127,22 @@ public class StateEvent { public class StateEventResponse : StateEvent { [JsonPropertyName("origin_server_ts")] - public ulong OriginServerTs { get; set; } + public ulong? OriginServerTs { get; set; } [JsonPropertyName("room_id")] - public string RoomId { get; set; } + public string? RoomId { get; set; } [JsonPropertyName("sender")] - public string Sender { get; set; } + public string? Sender { get; set; } [JsonPropertyName("unsigned")] public UnsignedData? Unsigned { get; set; } [JsonPropertyName("event_id")] - public string EventId { get; set; } + public string? EventId { get; set; } [JsonPropertyName("replaces_state")] - public new string ReplacesState { get; set; } + public new string? ReplacesState { get; set; } public class UnsignedData { [JsonPropertyName("age")] @@ -179,8 +167,7 @@ public class StateEventResponse : StateEvent { [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(ChunkedStateEventResponse))] -internal partial class ChunkedStateEventResponseSerializerContext : JsonSerializerContext { -} +internal partial class ChunkedStateEventResponseSerializerContext : JsonSerializerContext; public class EventList { [JsonPropertyName("events")] diff --git a/LibMatrix/UserIdAndReason.cs b/LibMatrix/UserIdAndReason.cs index 09dc461..c76ecc7 100644 --- a/LibMatrix/UserIdAndReason.cs +++ b/LibMatrix/UserIdAndReason.cs @@ -2,7 +2,7 @@ using System.Text.Json.Serialization; namespace LibMatrix; -internal class UserIdAndReason(string? userId = null, string? reason = null) { +internal class UserIdAndReason(string userId = null!, string reason = null!) { [JsonPropertyName("user_id")] public string UserId { get; set; } = userId; diff --git a/LibMatrix/WhoAmIResponse.cs b/LibMatrix/WhoAmIResponse.cs index 4eb5f2e..e2ea118 100644 --- a/LibMatrix/WhoAmIResponse.cs +++ b/LibMatrix/WhoAmIResponse.cs @@ -4,7 +4,7 @@ namespace LibMatrix; public class WhoAmIResponse { [JsonPropertyName("user_id")] - public string? UserId { get; set; } = null!; + public required string UserId { get; set; } [JsonPropertyName("device_id")] public string? DeviceId { get; set; } diff --git a/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs b/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs index 76b8c8c..0cbcf75 100644 --- a/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs +++ b/Tests/LibMatrix.Tests/Abstractions/RoomAbstraction.cs @@ -1,5 +1,6 @@ using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Spec.State; +using LibMatrix.EventTypes.Spec.State.RoomInfo; using LibMatrix.Homeservers; using LibMatrix.Responses; using LibMatrix.RoomTypes; @@ -61,7 +62,7 @@ public static class RoomAbstraction { RoomAliasName = Guid.NewGuid().ToString(), InitialState = new() }; - crq._creationContentBaseType.Type = "m.space"; + crq.CreationContentBaseType.Type = "m.space"; var createRoomTasks = Enumerable.Range(0, roomCount) diff --git a/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs b/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs index 6828087..060e6f2 100644 --- a/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs +++ b/Tests/LibMatrix.Tests/Tests/RoomEventTests.cs @@ -1,6 +1,3 @@ -using System.Text; -using ArcaneLibs.Extensions; -using LibMatrix.EventTypes.Spec.State; using LibMatrix.Homeservers; using LibMatrix.Services; using LibMatrix.Tests.Abstractions; @@ -88,8 +85,8 @@ public class RoomEventTests : TestBed { Assert.NotNull(room); var rule = await room.GetJoinRuleAsync(); Assert.NotNull(rule); - Assert.NotNull(rule.JoinRule); - Assert.NotEmpty(rule.JoinRule); + Assert.NotNull(rule.JoinRuleValue); + Assert.NotEmpty(rule.JoinRuleValue); } [Fact] diff --git a/Tests/LibMatrix.Tests/Tests/RoomTests.cs b/Tests/LibMatrix.Tests/Tests/RoomTests.cs index 3a11de9..913e044 100644 --- a/Tests/LibMatrix.Tests/Tests/RoomTests.cs +++ b/Tests/LibMatrix.Tests/Tests/RoomTests.cs @@ -1,5 +1,4 @@ using System.Text; -using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Spec.State; using LibMatrix.Homeservers; using LibMatrix.Responses; diff --git a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs index 8fb7443..d056345 100644 --- a/Tests/LibMatrix.Tests/Tests/TestCleanup.cs +++ b/Tests/LibMatrix.Tests/Tests/TestCleanup.cs @@ -1,9 +1,7 @@ using System.Diagnostics; -using ArcaneLibs.Extensions; using LibMatrix.Helpers; using LibMatrix.Services; using LibMatrix.Tests.Abstractions; -using LibMatrix.Tests.DataTests; using LibMatrix.Tests.Fixtures; using Microsoft.Extensions.Logging; using Xunit.Abstractions; @@ -12,14 +10,14 @@ using Xunit.Microsoft.DependencyInjection.Abstracts; namespace LibMatrix.Tests.Tests; public class TestCleanup : TestBed { - private readonly TestFixture _fixture; + // private readonly TestFixture _fixture; private readonly HomeserverResolverService _resolver; private readonly Config _config; private readonly HomeserverProviderService _provider; private readonly ILogger _logger; public TestCleanup(ITestOutputHelper testOutputHelper, TestFixture fixture) : base(testOutputHelper, fixture) { - _fixture = fixture; + // _fixture = fixture; _resolver = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverResolverService)}"); _config = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(Config)}"); _provider = _fixture.GetService(_testOutputHelper) ?? throw new InvalidOperationException($"Failed to get {nameof(HomeserverProviderService)}"); diff --git a/Tests/TestDataGenerator/Bot/DataFetcher.cs b/Tests/TestDataGenerator/Bot/DataFetcher.cs index b1f8402..5e8c1a1 100644 --- a/Tests/TestDataGenerator/Bot/DataFetcher.cs +++ b/Tests/TestDataGenerator/Bot/DataFetcher.cs @@ -1,25 +1,17 @@ -using System.Text; -using System.Threading.Channels; using ArcaneLibs.Extensions; using LibMatrix.EventTypes.Spec; -using LibMatrix.EventTypes.Spec.State; -using LibMatrix.Helpers; using LibMatrix.Homeservers; -using LibMatrix.Interfaces; using LibMatrix.RoomTypes; -using LibMatrix.Services; -using LibMatrix.Tests; using LibMatrix.Utilities.Bot; -using LibMatrix.Utilities.Bot.Interfaces; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -namespace PluralContactBotPoC.Bot; +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously -public class DataFetcher(AuthenticatedHomeserverGeneric hs, ILogger logger, LibMatrixBotConfiguration botConfiguration, - // DataFetcherConfiguration configuration, - HomeserverResolverService hsResolver) : IHostedService { - private Task _listenerTask; +namespace TestDataGenerator.Bot; + +public class DataFetcher(AuthenticatedHomeserverGeneric hs, ILogger logger, LibMatrixBotConfiguration botConfiguration) : IHostedService { + private Task? _listenerTask; private GenericRoom? _logRoom; @@ -32,7 +24,7 @@ public class DataFetcher(AuthenticatedHomeserverGeneric hs, ILogger private async Task Run(CancellationToken cancellationToken) { Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete); - _logRoom = hs.GetRoom(botConfiguration.LogRoom); + _logRoom = hs.GetRoom(botConfiguration.LogRoom!); await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: "Test data collector started!")); await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: "Fetching rooms...")); @@ -42,16 +34,14 @@ public class DataFetcher(AuthenticatedHomeserverGeneric hs, ILogger await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: "Fetching room data...")); - Config cfg = new Config(); - var roomAliasTasks = rooms.Select(room => room.GetCanonicalAliasAsync()).ToAsyncEnumerable(); List> aliasResolutionTasks = new(); await foreach (var @event in roomAliasTasks) { if (@event?.Alias != null) { await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: $"Fetched room alias {(@event).Alias}!")); - aliasResolutionTasks.Add(Task<(string, string)>.Run(async () => { + aliasResolutionTasks.Add(Task.Run(async () => { var alias = await hs.ResolveRoomAliasAsync(@event.Alias); - return (@event.Alias, @alias.RoomId); + return (@event.Alias, alias.RoomId); }, cancellationToken)); } } @@ -65,5 +55,6 @@ public class DataFetcher(AuthenticatedHomeserverGeneric hs, ILogger /// Indicates that the shutdown process should no longer be graceful. public async Task StopAsync(CancellationToken cancellationToken) { logger.LogInformation("Shutting down bot!"); + _listenerTask?.Dispose(); } } diff --git a/Tests/TestDataGenerator/Bot/DataFetcherConfiguration.cs b/Tests/TestDataGenerator/Bot/DataFetcherConfiguration.cs index 06df0eb..a586d05 100644 --- a/Tests/TestDataGenerator/Bot/DataFetcherConfiguration.cs +++ b/Tests/TestDataGenerator/Bot/DataFetcherConfiguration.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.Configuration; -namespace PluralContactBotPoC.Bot; +namespace TestDataGenerator.Bot; public class DataFetcherConfiguration { public DataFetcherConfiguration(IConfiguration config) => config.GetRequiredSection("DataFetcher").Bind(this); diff --git a/Tests/TestDataGenerator/Program.cs b/Tests/TestDataGenerator/Program.cs index 18ba61e..5d36215 100644 --- a/Tests/TestDataGenerator/Program.cs +++ b/Tests/TestDataGenerator/Program.cs @@ -1,19 +1,15 @@ // See https://aka.ms/new-console-template for more information -using System.Text.Json; -using System.Text.Json.Serialization; -using ArcaneLibs.Extensions; using LibMatrix.Services; using LibMatrix.Utilities.Bot; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using PluralContactBotPoC; -using PluralContactBotPoC.Bot; +using TestDataGenerator.Bot; Console.WriteLine("Hello, World!"); var host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => { - services.AddScoped(x => + services.AddScoped(_ => new TieredStorageService( cacheStorageProvider: new FileStorageProvider("bot_data/cache/"), dataStorageProvider: new FileStorageProvider("bot_data/data/") diff --git a/Utilities/LibMatrix.DebugDataValidationApi/Controllers/ValidationController.cs b/Utilities/LibMatrix.DebugDataValidationApi/Controllers/ValidationController.cs index 81753d1..1b93614 100644 --- a/Utilities/LibMatrix.DebugDataValidationApi/Controllers/ValidationController.cs +++ b/Utilities/LibMatrix.DebugDataValidationApi/Controllers/ValidationController.cs @@ -7,16 +7,15 @@ namespace LibMatrix.DebugDataValidationApi.Controllers; [ApiController] [Route("/")] public class ValidationController(ILogger logger) : ControllerBase { - private readonly ILogger _logger = logger; [HttpPost("/validate/{type}")] public Task Get([FromRoute] string type, [FromBody] JsonElement content) { var t = Type.GetType(type); if (t is null) { - Console.WriteLine($"Type `{type}` does not exist!"); + logger.LogWarning($"Type `{type}` does not exist!"); throw new ArgumentException($"Unknown type {type}!"); } - Console.WriteLine($"Validating {type}..."); + logger.LogInformation($"Validating {type}..."); return Task.FromResult(content.FindExtraJsonElementFields(t, "$")); } } diff --git a/Utilities/LibMatrix.JsonSerializerContextGenerator/EventSerializerContexts.g.cs b/Utilities/LibMatrix.JsonSerializerContextGenerator/EventSerializerContexts.g.cs deleted file mode 100644 index 1ca32dd..0000000 --- a/Utilities/LibMatrix.JsonSerializerContextGenerator/EventSerializerContexts.g.cs +++ /dev/null @@ -1,99 +0,0 @@ -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.UnknownEventContent))] -internal partial class UnknownEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.RoomMessageEventContent))] -internal partial class RoomMessageEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.PresenceEventContent))] -internal partial class PresenceEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomTypingEventContent))] -internal partial class RoomTypingEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.ServerPolicyRuleEventContent))] -internal partial class ServerPolicyRuleEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.UserPolicyRuleEventContent))] -internal partial class UserPolicyRuleEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomPolicyRuleEventContent))] -internal partial class RoomPolicyRuleEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomAliasEventContent))] -internal partial class RoomAliasEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomAvatarEventContent))] -internal partial class RoomAvatarEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomCanonicalAliasEventContent))] -internal partial class RoomCanonicalAliasEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomCreateEventContent))] -internal partial class RoomCreateEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomEncryptionEventContent))] -internal partial class RoomEncryptionEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomGuestAccessEventContent))] -internal partial class RoomGuestAccessEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomHistoryVisibilityEventContent))] -internal partial class RoomHistoryVisibilityEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomJoinRulesEventContent))] -internal partial class RoomJoinRulesEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomMemberEventContent))] -internal partial class RoomMemberEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomNameEventContent))] -internal partial class RoomNameEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomPinnedEventContent))] -internal partial class RoomPinnedEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomPowerLevelEventContent))] -internal partial class RoomPowerLevelEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomServerACLEventContent))] -internal partial class RoomServerACLEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.RoomTopicEventContent))] -internal partial class RoomTopicEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.SpaceChildEventContent))] -internal partial class SpaceChildEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Spec.State.SpaceParentEventContent))] -internal partial class SpaceParentEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Common.MjolnirShortcodeEventContent))] -internal partial class MjolnirShortcodeEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } - -[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] -[System.Text.Json.Serialization.JsonSerializable(typeof(LibMatrix.EventTypes.Common.RoomEmotesEventContent))] -internal partial class RoomEmotesEventContentSerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } diff --git a/Utilities/LibMatrix.JsonSerializerContextGenerator/Program.cs b/Utilities/LibMatrix.JsonSerializerContextGenerator/Program.cs index 76d6357..0c0277b 100644 --- a/Utilities/LibMatrix.JsonSerializerContextGenerator/Program.cs +++ b/Utilities/LibMatrix.JsonSerializerContextGenerator/Program.cs @@ -1,8 +1,6 @@ -using System.Reflection; -using ArcaneLibs; +using ArcaneLibs; using ArcaneLibs.Extensions.Streams; -using LibMatrix; -using LibMatrix.Interfaces; +using LibMatrix.EventTypes; // string binary = args.Length > 1 ? args[0] : Console.ReadLine()!; @@ -10,13 +8,25 @@ using LibMatrix.Interfaces; File.Delete("EventSerializerContexts.g.cs"); var stream = File.OpenWrite("EventSerializerContexts.g.cs"); var eventContentTypes = new ClassCollector().ResolveFromAllAccessibleAssemblies(); + +stream.WriteString("using System.Text.Json.Serialization;\n"); + +stream.WriteString(string.Join('\n', eventContentTypes.DistinctBy(x => x.Namespace) + .Select(x => $"using {x.Namespace};"))); +stream.WriteString("\n\nnamespace LibMatrix.Generated;\n\n[JsonSourceGenerationOptions(WriteIndented = true)]\n"); + +// stream.WriteString(string.Join('\n', eventContentTypes//.DistinctBy(x => x.Namespace) +// .Select(x => $$""" +// [JsonSourceGenerationOptions(WriteIndented = true)] +// [JsonSerializable(typeof({{x.Name}}))] +// internal partial class {{x.Name}}SerializerContext : JsonSerializerContext { } +// +// """))); + stream.WriteString(string.Join('\n', eventContentTypes//.DistinctBy(x => x.Namespace) - .Select(x => $$""" - [System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] - [System.Text.Json.Serialization.JsonSerializable(typeof({{x.FullName}}))] - internal partial class {{x.Name}}SerializerContext : System.Text.Json.Serialization.JsonSerializerContext { } + .Select(x => $"[JsonSerializable(typeof({x.Name}))]"))); - """))); +stream.WriteString("\ninternal partial class EventTypeSerializerContext : JsonSerializerContext { }"); await stream.FlushAsync(); stream.Close(); \ No newline at end of file diff --git a/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs b/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs index 99a789a..d8d1094 100644 --- a/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs +++ b/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs @@ -44,8 +44,8 @@ public class AppServiceConfiguration { else yaml += "protocols: []"; yaml += "\n"; - if (RateLimited is not null) - yaml += $"rate_limited: {RateLimited!.ToString().ToLower()}\n"; + if (RateLimited.HasValue) + yaml += $"rate_limited: {RateLimited.Value.ToString().ToLower()}\n"; else yaml += "rate_limited: false\n"; diff --git a/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs b/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs index 91ec1e8..25a8d92 100644 --- a/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs +++ b/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs @@ -21,8 +21,8 @@ public static class BotCommandInstaller { services.AddSingleton(); services.AddScoped(x => { - var config = x.GetService(); - var hsProvider = x.GetService(); + var config = x.GetService() ?? throw new Exception("No configuration found!"); + var hsProvider = x.GetService() ?? throw new Exception("No homeserver provider found!"); var hs = hsProvider.GetAuthenticatedWithToken(config.Homeserver, config.AccessToken).Result; return hs; diff --git a/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs b/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs index 46032c7..b66fbf5 100644 --- a/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs +++ b/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs @@ -1,13 +1,10 @@ using System.Text.Json; using ArcaneLibs.Extensions; using LibMatrix.Interfaces.Services; -using Microsoft.Extensions.Logging; namespace LibMatrix.Utilities.Bot; public class FileStorageProvider : IStorageProvider { - private readonly ILogger _logger; - public string TargetPath { get; } /// @@ -15,7 +12,6 @@ public class FileStorageProvider : IStorageProvider { /// /// public FileStorageProvider(string targetPath) { - new Logger(new LoggerFactory()).LogInformation("test"); Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); TargetPath = targetPath; if (!Directory.Exists(targetPath)) { diff --git a/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs b/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs index 2d04e37..94ea846 100644 --- a/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs +++ b/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs @@ -5,8 +5,8 @@ using LibMatrix.RoomTypes; namespace LibMatrix.Utilities.Bot.Interfaces; public class CommandContext { - public GenericRoom Room { get; set; } - public StateEventResponse MessageEvent { get; set; } + public required GenericRoom Room { get; set; } + public required StateEventResponse MessageEvent { get; set; } public string MessageContentWithoutReply => (MessageEvent.TypedContent as RoomMessageEventContent)! @@ -16,7 +16,7 @@ public class CommandContext { public string CommandName => MessageContentWithoutReply.Split(' ')[0][1..]; public string[] Args => MessageContentWithoutReply.Split(' ')[1..]; - public AuthenticatedHomeserverGeneric Homeserver { get; set; } + public required AuthenticatedHomeserverGeneric Homeserver { get; set; } public async Task Reply(RoomMessageEventContent content) => await Room.SendMessageEventAsync(content); } -- cgit 1.4.1