diff options
60 files changed, 615 insertions, 216 deletions
diff --git a/LibMatrix.DebugDataValidationApi/Properties/launchSettings.json b/LibMatrix.DebugDataValidationApi/Properties/launchSettings.json index c33e091..fe668ce 100644 --- a/LibMatrix.DebugDataValidationApi/Properties/launchSettings.json +++ b/LibMatrix.DebugDataValidationApi/Properties/launchSettings.json @@ -1,40 +1,31 @@ { - "$schema": "http://json.schemastore.org/launchsettings.json", + "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:63687", - "sslPort": 44316 + "applicationUrl": "http://localhost:9169", + "sslPort": 44321 } }, "profiles": { - "http": { + "Development": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "launchUrl": "swagger", - "applicationUrl": "http://localhost:5116", + "applicationUrl": "http://localhost:5258", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, - "https": { + "Local": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7017;http://localhost:5116", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", + "launchBrowser": false, + "applicationUrl": "http://localhost:5258", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "DOTNET_ENVIRONMENT": "Local" } } } diff --git a/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs b/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs index 1e84ab7..2dfcee5 100644 --- a/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs +++ b/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; using LibMatrix.Interfaces.Services; using Microsoft.Extensions.Logging; diff --git a/LibMatrix.ExampleBot/Bot/MRUBot.cs b/LibMatrix.ExampleBot/Bot/MRUBot.cs index cdeefe2..4f9b173 100644 --- a/LibMatrix.ExampleBot/Bot/MRUBot.cs +++ b/LibMatrix.ExampleBot/Bot/MRUBot.cs @@ -1,6 +1,8 @@ using System.Diagnostics.CodeAnalysis; +using ArcaneLibs.Extensions; using LibMatrix.ExampleBot.Bot.Interfaces; using LibMatrix.Extensions; +using LibMatrix.Homeservers; using LibMatrix.Services; using LibMatrix.StateEventTypes.Spec; using Microsoft.Extensions.DependencyInjection; @@ -31,7 +33,7 @@ public class MRUBot : IHostedService { [SuppressMessage("ReSharper", "FunctionNeverReturns")] public async Task StartAsync(CancellationToken cancellationToken) { Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete); - AuthenticatedHomeServer hs; + AuthenticatedHomeserverGeneric hs; try { hs = await _homeserverProviderService.GetAuthenticatedWithToken(_configuration.Homeserver, _configuration.AccessToken); diff --git a/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs b/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs new file mode 100644 index 0000000..4785192 --- /dev/null +++ b/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs @@ -0,0 +1,72 @@ +using System.Diagnostics.CodeAnalysis; +using ArcaneLibs.Extensions; +using LibMatrix.ExampleBot.Bot.Interfaces; +using LibMatrix.Homeservers; +using LibMatrix.Services; +using LibMatrix.StateEventTypes.Spec; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace LibMatrix.ExampleBot.Bot.StartupTasks; + +public class ServerRoomSizeCalulator : IHostedService { + private readonly HomeserverProviderService _homeserverProviderService; + private readonly ILogger<ServerRoomSizeCalulator> _logger; + private readonly MRUBotConfiguration _configuration; + private readonly IEnumerable<ICommand> _commands; + + public ServerRoomSizeCalulator(HomeserverProviderService homeserverProviderService, ILogger<ServerRoomSizeCalulator> logger, + MRUBotConfiguration configuration, IServiceProvider services) { + logger.LogInformation("Server room size calculator hosted service instantiated!"); + _homeserverProviderService = homeserverProviderService; + _logger = logger; + _configuration = configuration; + } + + /// <summary>Triggered when the application host is ready to start the service.</summary> + /// <param name="cancellationToken">Indicates that the start process has been aborted.</param> + [SuppressMessage("ReSharper", "FunctionNeverReturns")] + public async Task StartAsync(CancellationToken cancellationToken) { + Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete); + AuthenticatedHomeserverGeneric hs; + try { + hs = await _homeserverProviderService.GetAuthenticatedWithToken(_configuration.Homeserver, + _configuration.AccessToken); + } + catch (Exception e) { + _logger.LogError("{}", e.Message); + throw; + } + + await (await hs.GetRoom("!DoHEdFablOLjddKWIp:rory.gay")).JoinAsync(); + + Dictionary<string, int> totalRoomSize = new(); + foreach (var room in await hs.GetJoinedRooms()) { + var stateList = room.GetFullStateAsync().ToBlockingEnumerable().ToList(); + var roomSize = stateList.Count; + if (roomSize > 10000) { + await File.AppendAllLinesAsync("large_rooms.txt", new[] { $"{{ \"{room.RoomId}\", {roomSize} }}," }, cancellationToken); + } + + var roomHs = room.RoomId.Split(":")[1]; + if (totalRoomSize.ContainsKey(roomHs)) { + totalRoomSize[roomHs] += roomSize; + } + else { + totalRoomSize.Add(roomHs, roomSize); + } + + _logger.LogInformation($"Got room state for {room.RoomId}!"); + } + + await File.WriteAllTextAsync("server_size.txt", string.Join('\n', totalRoomSize.Select(x => $"{{ \"{x.Key}\", {x.Value} }},")), cancellationToken); + } + + /// <summary>Triggered when the application host is performing a graceful shutdown.</summary> + /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param> + public Task StopAsync(CancellationToken cancellationToken) { + _logger.LogInformation("Shutting down bot!"); + return Task.CompletedTask; + } +} diff --git a/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj b/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj index 03a3f0b..3101842 100644 --- a/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj +++ b/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj @@ -8,15 +8,16 @@ <Nullable>enable</Nullable> <PublishAot>false</PublishAot> <InvariantGlobalization>true</InvariantGlobalization> - <PublishTrimmed>true</PublishTrimmed> - <PublishReadyToRun>true</PublishReadyToRun> - <PublishSingleFile>true</PublishSingleFile> - <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings> - <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison> - <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings> +<!-- <PublishTrimmed>true</PublishTrimmed>--> +<!-- <PublishReadyToRun>true</PublishReadyToRun>--> +<!-- <PublishSingleFile>true</PublishSingleFile>--> +<!-- <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings>--> +<!-- <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison>--> +<!-- <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings>--> </PropertyGroup> <ItemGroup> + <ProjectReference Include="..\..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" /> <ProjectReference Include="..\LibMatrix\LibMatrix.csproj" /> </ItemGroup> diff --git a/LibMatrix.ExampleBot/Program.cs b/LibMatrix.ExampleBot/Program.cs index 63610b4..0378ec9 100644 --- a/LibMatrix.ExampleBot/Program.cs +++ b/LibMatrix.ExampleBot/Program.cs @@ -1,7 +1,9 @@ // See https://aka.ms/new-console-template for more information +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; @@ -22,6 +24,8 @@ var host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => { Console.WriteLine($"Adding command {commandClass.Name}"); services.AddScoped(typeof(ICommand), commandClass); } + + services.AddHostedService<ServerRoomSizeCalulator>(); services.AddHostedService<MRUBot>(); }).UseConsoleLifetime().Build(); diff --git a/LibMatrix.ExampleBot/large_rooms.txt b/LibMatrix.ExampleBot/large_rooms.txt new file mode 100644 index 0000000..1d9341d --- /dev/null +++ b/LibMatrix.ExampleBot/large_rooms.txt @@ -0,0 +1,4 @@ +{ "!ehXvUhWNASUkSLvAGP:matrix.org", 21957 } +{ "!fRRqjOaQcUbKOfCjvc:anontier.nl", 19117 } +{ "!OGEhHVWSdvArJzumhm:matrix.org", 101457 } +{ "!YTvKGNlinIzlkMTVRl:matrix.org", 30164 } diff --git a/LibMatrix.ExampleBot/server_size.txt b/LibMatrix.ExampleBot/server_size.txt new file mode 100644 index 0000000..f275e42 --- /dev/null +++ b/LibMatrix.ExampleBot/server_size.txt @@ -0,0 +1,45 @@ +{ "thearcanebrony.net", 178 } +{ "feline.support", 2654 } +{ "waifuhunter.club", 3997 } +{ "rory.gay", 645 } +{ "the-apothecary.club", 7000 } +{ "fairydust.space", 176 } +{ "envs.net", 165 } +{ "anontier.nl", 44935 } +{ "nightshade.fun", 8 } +{ "matrix.org", 185873 } +{ "nerdsin.space", 2647 } +{ "no.lgbtqia.zone", 2084 } +{ "neko.dev", 2668 } +{ "jameskitt616.one", 390 } +{ "matrix.eclipse.org", 8 } +{ "catgirl.cloud", 16 } +{ "pikaviestin.fi", 368 } +{ "masfloss.net", 8 } +{ "pcg.life", 72 } +{ "grin.hu", 176 } +{ "possum.city", 16 } +{ "nixos.org", 8206 } +{ "tu-dresden.de", 9 } +{ "pixie.town", 817 } +{ "pixelthefox.net", 1478 } +{ "koneko.chat", 132 } +{ "arcticfoxes.net", 982 } +{ "hackint.org", 374 } +{ "tchncs.de", 19 } +{ "seirdy.one", 107 } +{ "fosscord.com", 9 } +{ "fachschaften.org", 1851 } +{ "nheko.im", 1884 } +{ "draupnir.midnightthoughts.space", 22 } +{ "privacyguides.org", 809 } +{ "vscape.tk", 124 } +{ "artemislena.eu", 599 } +{ "midov.pl", 2223 } +{ "e2e.zone", 8 } +{ "tastytea.de", 143 } +{ "matrix.nomagic.uk", 337 } +{ "gitter.im", 2586 } +{ "funklause.de", 113 } +{ "hyteck.de", 8 } +{ "alchemi.dev", 446 } \ No newline at end of file diff --git a/LibMatrix.MxApiExtensions/LibMatrix.MxApiExtensions.csproj b/LibMatrix.MxApiExtensions/LibMatrix.MxApiExtensions.csproj new file mode 100644 index 0000000..009412b --- /dev/null +++ b/LibMatrix.MxApiExtensions/LibMatrix.MxApiExtensions.csproj @@ -0,0 +1,13 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net7.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + + <ItemGroup> + <Folder Include="Classes\" /> + </ItemGroup> + +</Project> diff --git a/LibMatrix/Extensions/HttpClientExtensions.cs b/LibMatrix/Extensions/HttpClientExtensions.cs index d4017ed..4d81b6e 100644 --- a/LibMatrix/Extensions/HttpClientExtensions.cs +++ b/LibMatrix/Extensions/HttpClientExtensions.cs @@ -1,7 +1,12 @@ +using System; using System.Diagnostics; +using System.IO; +using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; namespace LibMatrix.Extensions; diff --git a/LibMatrix/Extensions/JsonElementExtensions.cs b/LibMatrix/Extensions/JsonElementExtensions.cs index f39f300..99fa72d 100644 --- a/LibMatrix/Extensions/JsonElementExtensions.cs +++ b/LibMatrix/Extensions/JsonElementExtensions.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text.Json; using System.Text.Json.Nodes; diff --git a/LibMatrix/Filters/SyncFilter.cs b/LibMatrix/Filters/SyncFilter.cs index c907f6b..e281346 100644 --- a/LibMatrix/Filters/SyncFilter.cs +++ b/LibMatrix/Filters/SyncFilter.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; namespace LibMatrix.Filters; diff --git a/LibMatrix/Helpers/HomeserverWeightEstimation.cs b/LibMatrix/Helpers/HomeserverWeightEstimation.cs new file mode 100644 index 0000000..8f1bf3a --- /dev/null +++ b/LibMatrix/Helpers/HomeserverWeightEstimation.cs @@ -0,0 +1,58 @@ +namespace LibMatrix.Helpers; + +public class HomeserverWeightEstimation { + public static Dictionary<string, int> EstimatedSize = new() { + { "matrix.org", 84387 }, + { "anontier.nl", 44809 }, + { "nixos.org", 8195 }, + { "the-apothecary.club", 6983 }, + { "waifuhunter.club", 3953 }, + { "neko.dev", 2666 }, + { "nerdsin.space", 2647 }, + { "feline.support", 2633 }, + { "gitter.im", 2584 }, + { "midov.pl", 2219 }, + { "no.lgbtqia.zone", 2083 }, + { "nheko.im", 1883 }, + { "fachschaften.org", 1849 }, + { "pixelthefox.net", 1478 }, + { "arcticfoxes.net", 981 }, + { "pixie.town", 817 }, + { "privacyguides.org", 809 }, + { "rory.gay", 653 }, + { "artemislena.eu", 599 }, + { "alchemi.dev", 445 }, + { "jameskitt616.one", 390 }, + { "hackint.org", 382 }, + { "pikaviestin.fi", 368 }, + { "matrix.nomagic.uk", 337 }, + { "thearcanebrony.net", 178 }, + { "fairydust.space", 176 }, + { "grin.hu", 176 }, + { "envs.net", 165 }, + { "tastytea.de", 143 }, + { "koneko.chat", 121 }, + { "vscape.tk", 115 }, + { "funklause.de", 112 }, + { "seirdy.one", 107 }, + { "pcg.life", 72 }, + { "draupnir.midnightthoughts.space", 22 }, + { "tchncs.de", 19 }, + { "catgirl.cloud", 16 }, + { "possum.city", 16 }, + { "tu-dresden.de", 9 }, + { "fosscord.com", 9 }, + { "nightshade.fun", 8 }, + { "matrix.eclipse.org", 8 }, + { "masfloss.net", 8 }, + { "e2e.zone", 8 }, + { "hyteck.de", 8 } + }; + + public static Dictionary<string, int> LargeRooms = new() { + { "!ehXvUhWNASUkSLvAGP:matrix.org", 21957 }, + { "!fRRqjOaQcUbKOfCjvc:anontier.nl", 19117 }, + { "!OGEhHVWSdvArJzumhm:matrix.org", 101457 }, + { "!YTvKGNlinIzlkMTVRl:matrix.org", 30164 } + }; +} diff --git a/LibMatrix/Helpers/MatrixEventAttribute.cs b/LibMatrix/Helpers/MatrixEventAttribute.cs new file mode 100644 index 0000000..7556019 --- /dev/null +++ b/LibMatrix/Helpers/MatrixEventAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace LibMatrix.Helpers; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class MatrixEventAttribute : Attribute { + public string EventName { get; set; } + public bool Legacy { get; set; } +} diff --git a/LibMatrix/Helpers/SyncHelper.cs b/LibMatrix/Helpers/SyncHelper.cs index b957c0c..de4f3d4 100644 --- a/LibMatrix/Helpers/SyncHelper.cs +++ b/LibMatrix/Helpers/SyncHelper.cs @@ -1,19 +1,26 @@ +using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Net.Http.Json; using System.Text.Json.Serialization; +using System.Threading; +using System.Threading.Tasks; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; using LibMatrix.Filters; +using LibMatrix.Homeservers; using LibMatrix.Responses; using LibMatrix.Services; namespace LibMatrix.Helpers; public class SyncHelper { - private readonly AuthenticatedHomeServer _homeServer; + private readonly AuthenticatedHomeserverGeneric _homeserver; private readonly TieredStorageService _storageService; - public SyncHelper(AuthenticatedHomeServer homeServer, TieredStorageService storageService) { - _homeServer = homeServer; + public SyncHelper(AuthenticatedHomeserverGeneric homeserver, TieredStorageService storageService) { + _homeserver = homeserver; _storageService = storageService; } @@ -33,7 +40,7 @@ public class SyncHelper { // else url += "&full_state=true"; Console.WriteLine("Calling: " + url); try { - var req = await _homeServer._httpClient.GetAsync(url, cancellationToken: cancellationToken ?? CancellationToken.None); + var req = await _homeserver._httpClient.GetAsync(url, cancellationToken: cancellationToken ?? CancellationToken.None); // var res = await JsonSerializer.DeserializeAsync<SyncResult>(await req.Content.ReadAsStreamAsync()); diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs new file mode 100644 index 0000000..ecac4e4 --- /dev/null +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Json; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using LibMatrix.Extensions; +using LibMatrix.Helpers; +using LibMatrix.Responses; +using LibMatrix.RoomTypes; +using LibMatrix.Services; + +namespace LibMatrix.Homeservers; + +public class AuthenticatedHomeserverGeneric : RemoteHomeServer { + public AuthenticatedHomeserverGeneric(TieredStorageService storage, string canonicalHomeServerDomain, string accessToken) : base(canonicalHomeServerDomain) { + Storage = storage; + AccessToken = accessToken.Trim(); + HomeServerDomain = canonicalHomeServerDomain.Trim(); + SyncHelper = new SyncHelper(this, storage); + _httpClient = new MatrixHttpClient(); + } + + public TieredStorageService Storage { get; set; } + public SyncHelper SyncHelper { get; init; } + public WhoAmIResponse WhoAmI { get; set; } = null!; + public string UserId => WhoAmI.UserId; + public string AccessToken { get; set; } + + + public Task<GenericRoom> GetRoom(string roomId) => Task.FromResult<GenericRoom>(new(this, roomId)); + + public async Task<List<GenericRoom>> GetJoinedRooms() { + var roomQuery = await _httpClient.GetAsync("/_matrix/client/v3/joined_rooms"); + + var roomsJson = await roomQuery.Content.ReadFromJsonAsync<JsonElement>(); + var rooms = roomsJson.GetProperty("joined_rooms").EnumerateArray().Select(room => new GenericRoom(this, room.GetString()!)).ToList(); + + Console.WriteLine($"Fetched {rooms.Count} rooms"); + + return rooms; + } + + public async Task<string> UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") { + var res = await _httpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream)); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); + throw new InvalidDataException($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); + } + + var resJson = await res.Content.ReadFromJsonAsync<JsonElement>(); + return resJson.GetProperty("content_uri").GetString()!; + } + + public async Task<GenericRoom> CreateRoom(CreateRoomRequest creationEvent) { + var res = await _httpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to create room: {await res.Content.ReadAsStringAsync()}"); + throw new InvalidDataException($"Failed to create room: {await res.Content.ReadAsStringAsync()}"); + } + + return await GetRoom((await res.Content.ReadFromJsonAsync<JsonObject>())!["room_id"]!.ToString()); + } + +#region Account Data + + public async Task<T> GetAccountData<T>(string key) { + var res = await _httpClient.GetAsync($"/_matrix/client/v3/user/{UserId}/account_data/{key}"); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to get account data: {await res.Content.ReadAsStringAsync()}"); + throw new InvalidDataException($"Failed to get account data: {await res.Content.ReadAsStringAsync()}"); + } + + return await res.Content.ReadFromJsonAsync<T>(); + } + + public async Task SetAccountData(string key, object data) { + var res = await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{UserId}/account_data/{key}", data); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to set account data: {await res.Content.ReadAsStringAsync()}"); + throw new InvalidDataException($"Failed to set account data: {await res.Content.ReadAsStringAsync()}"); + } + } + +#endregion +} diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverMxApiExtended.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverMxApiExtended.cs new file mode 100644 index 0000000..8ffcfaf --- /dev/null +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverMxApiExtended.cs @@ -0,0 +1,14 @@ +using LibMatrix.Extensions; +using LibMatrix.Helpers; +using LibMatrix.Services; + +namespace LibMatrix.Homeservers; + +public class AuthenticatedHomeserverMxApiExtended : AuthenticatedHomeserverGeneric { + public AuthenticatedHomeserverMxApiExtended(TieredStorageService storage, string canonicalHomeServerDomain, string accessToken) : base(storage, canonicalHomeServerDomain, accessToken) { + AccessToken = accessToken.Trim(); + HomeServerDomain = canonicalHomeServerDomain.Trim(); + SyncHelper = new SyncHelper(this, storage); + _httpClient = new MatrixHttpClient(); + } +} diff --git a/LibMatrix/AuthenticatedHomeServer.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs index a99dc27..3b0bc10 100644 --- a/LibMatrix/AuthenticatedHomeServer.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs @@ -1,75 +1,18 @@ -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using LibMatrix.Extensions; +using System; +using System.Collections.Generic; +using ArcaneLibs.Extensions; using LibMatrix.Filters; -using LibMatrix.Helpers; -using LibMatrix.Interfaces; -using LibMatrix.Responses; using LibMatrix.Responses.Admin; -using LibMatrix.RoomTypes; using LibMatrix.Services; -namespace LibMatrix; +namespace LibMatrix.Homeservers; -public class AuthenticatedHomeServer : IHomeServer { - private readonly TieredStorageService _storage; - public readonly HomeserverAdminApi Admin; - public readonly SyncHelper SyncHelper; +public class AuthenticatedHomeserverSynapse : AuthenticatedHomeserverGeneric { + public readonly SynapseAdminApi Admin; + public class SynapseAdminApi { + private readonly AuthenticatedHomeserverGeneric _authenticatedHomeserver; - public AuthenticatedHomeServer(TieredStorageService storage, string canonicalHomeServerDomain, string accessToken) { - _storage = storage; - AccessToken = accessToken.Trim(); - HomeServerDomain = canonicalHomeServerDomain.Trim(); - Admin = new HomeserverAdminApi(this); - SyncHelper = new SyncHelper(this, storage); - _httpClient = new MatrixHttpClient(); - } - - public WhoAmIResponse WhoAmI { get; set; } = null!; - public string UserId => WhoAmI.UserId; - public string AccessToken { get; set; } - - - public Task<GenericRoom> GetRoom(string roomId) => Task.FromResult<GenericRoom>(new(this, roomId)); - - public async Task<List<GenericRoom>> GetJoinedRooms() { - var roomQuery = await _httpClient.GetAsync("/_matrix/client/v3/joined_rooms"); - - var roomsJson = await roomQuery.Content.ReadFromJsonAsync<JsonElement>(); - var rooms = roomsJson.GetProperty("joined_rooms").EnumerateArray().Select(room => new GenericRoom(this, room.GetString()!)).ToList(); - - Console.WriteLine($"Fetched {rooms.Count} rooms"); - - return rooms; - } - - public async Task<string> UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") { - var res = await _httpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream)); - if (!res.IsSuccessStatusCode) { - Console.WriteLine($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); - throw new InvalidDataException($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); - } - - var resJson = await res.Content.ReadFromJsonAsync<JsonElement>(); - return resJson.GetProperty("content_uri").GetString()!; - } - - public async Task<GenericRoom> CreateRoom(CreateRoomRequest creationEvent) { - var res = await _httpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent); - if (!res.IsSuccessStatusCode) { - Console.WriteLine($"Failed to create room: {await res.Content.ReadAsStringAsync()}"); - throw new InvalidDataException($"Failed to create room: {await res.Content.ReadAsStringAsync()}"); - } - - return await GetRoom((await res.Content.ReadFromJsonAsync<JsonObject>())!["room_id"]!.ToString()); - } - - public class HomeserverAdminApi { - private readonly AuthenticatedHomeServer _authenticatedHomeServer; - - public HomeserverAdminApi(AuthenticatedHomeServer authenticatedHomeServer) => _authenticatedHomeServer = authenticatedHomeServer; + public SynapseAdminApi(AuthenticatedHomeserverGeneric authenticatedHomeserver) => _authenticatedHomeserver = authenticatedHomeserver; public async IAsyncEnumerable<AdminRoomListingResult.AdminRoomListingResultRoom> SearchRoomsAsync(int limit = int.MaxValue, string orderBy = "name", string dir = "f", string? searchTerm = null, LocalRoomQueryFilter? localFilter = null) { AdminRoomListingResult? res = null; @@ -83,7 +26,7 @@ public class AuthenticatedHomeServer : IHomeServer { Console.WriteLine($"--- ADMIN Querying Room List with URL: {url} - Already have {i} items... ---"); - res = await _authenticatedHomeServer._httpClient.GetFromJsonAsync<AdminRoomListingResult>(url); + res = await _authenticatedHomeserver._httpClient.GetFromJsonAsync<AdminRoomListingResult>(url); totalRooms ??= res?.TotalRooms; Console.WriteLine(res.ToJson(false)); foreach (var room in res.Rooms) { @@ -160,14 +103,8 @@ public class AuthenticatedHomeServer : IHomeServer { } while (i < Math.Min(limit, totalRooms ?? limit)); } } -} -public class WhoAmIResponse { - [JsonPropertyName("user_id")] - public string UserId { get; set; } = null!; - - [JsonPropertyName("device_id")] - public string? DeviceId { get; set; } - [JsonPropertyName("is_guest")] - public bool? IsGuest { get; set; } + public AuthenticatedHomeserverSynapse(TieredStorageService storage, string canonicalHomeServerDomain, string accessToken) : base(storage, canonicalHomeServerDomain, accessToken) { + Admin = new(this); + } } diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs new file mode 100644 index 0000000..fc31f4f --- /dev/null +++ b/LibMatrix/Homeservers/RemoteHomeServer.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Net.Http.Json; +using System.Threading; +using System.Threading.Tasks; +using LibMatrix.Extensions; +using LibMatrix.Responses; +using LibMatrix.StateEventTypes.Spec; + +namespace LibMatrix.Homeservers; + +public class RemoteHomeServer { + public RemoteHomeServer(string canonicalHomeServerDomain) { + HomeServerDomain = canonicalHomeServerDomain; + _httpClient = new MatrixHttpClient(); + _httpClient.Timeout = TimeSpan.FromSeconds(5); + } + + private Dictionary<string, object> _profileCache { get; set; } = new(); + public string HomeServerDomain { get; set; } + public string FullHomeServerDomain { get; set; } + public MatrixHttpClient _httpClient { get; set; } + + public async Task<ProfileResponseEventData> GetProfile(string mxid) { + if(mxid is null) throw new ArgumentNullException(nameof(mxid)); + if (_profileCache.TryGetValue(mxid, out var value)) { + if (value is SemaphoreSlim s) await s.WaitAsync(); + if (value is ProfileResponseEventData p) return p; + } + _profileCache[mxid] = new SemaphoreSlim(1); + + var resp = await _httpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}"); + var data = await resp.Content.ReadFromJsonAsync<ProfileResponseEventData>(); + if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); + _profileCache[mxid] = data; + + return data; + } + + public async Task<ClientVersionsResponse> GetClientVersions() { + var resp = await _httpClient.GetAsync($"/_matrix/client/versions"); + var data = await resp.Content.ReadFromJsonAsync<ClientVersionsResponse>(); + if (!resp.IsSuccessStatusCode) Console.WriteLine("ClientVersions: " + data); + return data; + } +} diff --git a/LibMatrix/Interfaces/IHomeServer.cs b/LibMatrix/Interfaces/IHomeServer.cs deleted file mode 100644 index 5e7e374..0000000 --- a/LibMatrix/Interfaces/IHomeServer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Net.Http.Json; -using LibMatrix.Extensions; -using LibMatrix.StateEventTypes.Spec; - -namespace LibMatrix.Interfaces; - -public class IHomeServer { - private readonly Dictionary<string, object> _profileCache = new(); - public string HomeServerDomain { get; set; } - public string FullHomeServerDomain { get; set; } - - public MatrixHttpClient _httpClient { get; set; } = new(); - - public async Task<ProfileResponseEventData> GetProfile(string mxid) { - if(mxid is null) throw new ArgumentNullException(nameof(mxid)); - if (_profileCache.ContainsKey(mxid)) { - if (_profileCache[mxid] is SemaphoreSlim s) await s.WaitAsync(); - if (_profileCache[mxid] is ProfileResponseEventData p) return p; - } - _profileCache[mxid] = new SemaphoreSlim(1); - - var resp = await _httpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}"); - var data = await resp.Content.ReadFromJsonAsync<ProfileResponseEventData>(); - if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); - _profileCache[mxid] = data; - - return data; - } -} diff --git a/LibMatrix/Interfaces/IStateEventType.cs b/LibMatrix/Interfaces/IStateEventType.cs index d80f22d..13a0d05 100644 --- a/LibMatrix/Interfaces/IStateEventType.cs +++ b/LibMatrix/Interfaces/IStateEventType.cs @@ -1,5 +1,3 @@ namespace LibMatrix.Interfaces; -public interface IStateEventType { - -} +public interface IStateEventType { } diff --git a/LibMatrix/Interfaces/Services/IStorageProvider.cs b/LibMatrix/Interfaces/Services/IStorageProvider.cs index 519d8ed..e07e136 100644 --- a/LibMatrix/Interfaces/Services/IStorageProvider.cs +++ b/LibMatrix/Interfaces/Services/IStorageProvider.cs @@ -1,3 +1,8 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + namespace LibMatrix.Interfaces.Services; public interface IStorageProvider { diff --git a/LibMatrix/LibMatrix.csproj b/LibMatrix/LibMatrix.csproj index 3571eab..8ae57cc 100644 --- a/LibMatrix/LibMatrix.csproj +++ b/LibMatrix/LibMatrix.csproj @@ -11,4 +11,8 @@ <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" /> + </ItemGroup> + </Project> diff --git a/LibMatrix/MatrixException.cs b/LibMatrix/MatrixException.cs index 99bacb5..1b38a6e 100644 --- a/LibMatrix/MatrixException.cs +++ b/LibMatrix/MatrixException.cs @@ -1,4 +1,6 @@ +using System; using System.Text.Json.Serialization; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; namespace LibMatrix; diff --git a/LibMatrix/MessagesResponse.cs b/LibMatrix/MessagesResponse.cs index f09d136..d7bb54a 100644 --- a/LibMatrix/MessagesResponse.cs +++ b/LibMatrix/MessagesResponse.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; using LibMatrix.Responses; diff --git a/LibMatrix/RemoteHomeServer.cs b/LibMatrix/RemoteHomeServer.cs deleted file mode 100644 index 81ef9a7..0000000 --- a/LibMatrix/RemoteHomeServer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using LibMatrix.Extensions; -using LibMatrix.Interfaces; - -namespace LibMatrix; - -public class RemoteHomeServer : IHomeServer { - public RemoteHomeServer(string canonicalHomeServerDomain) { - HomeServerDomain = canonicalHomeServerDomain; - _httpClient = new MatrixHttpClient(); - _httpClient.Timeout = TimeSpan.FromSeconds(5); - } - -} diff --git a/LibMatrix/Responses/Admin/AdminRoomListingResult.cs b/LibMatrix/Responses/Admin/AdminRoomListingResult.cs index f035184..bbc23e6 100644 --- a/LibMatrix/Responses/Admin/AdminRoomListingResult.cs +++ b/LibMatrix/Responses/Admin/AdminRoomListingResult.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; namespace LibMatrix.Responses.Admin; diff --git a/LibMatrix/Responses/ClientVersionsResponse.cs b/LibMatrix/Responses/ClientVersionsResponse.cs new file mode 100644 index 0000000..7fac565 --- /dev/null +++ b/LibMatrix/Responses/ClientVersionsResponse.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace LibMatrix.Responses; + +public class ClientVersionsResponse { + [JsonPropertyName("versions")] + public List<string> Versions { get; set; } = new(); + + [JsonPropertyName("unstable_features")] + public Dictionary<string, bool> UnstableFeatures { get; set; } = new(); +} diff --git a/LibMatrix/Responses/CreateRoomRequest.cs b/LibMatrix/Responses/CreateRoomRequest.cs index d59e6fd..c1c1697 100644 --- a/LibMatrix/Responses/CreateRoomRequest.cs +++ b/LibMatrix/Responses/CreateRoomRequest.cs @@ -1,8 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.StateEventTypes.Spec; namespace LibMatrix.Responses; diff --git a/LibMatrix/Responses/LoginResponse.cs b/LibMatrix/Responses/LoginResponse.cs index 2800a9c..175f337 100644 --- a/LibMatrix/Responses/LoginResponse.cs +++ b/LibMatrix/Responses/LoginResponse.cs @@ -15,3 +15,24 @@ public class LoginResponse { [JsonPropertyName("user_id")] public string UserId { get; set; } } +public class LoginRequest { + [JsonPropertyName("type")] + public string Type { get; set; } = "m.login.password"; + + [JsonPropertyName("identifier")] + public LoginIdentifier Identifier { get; set; } = new(); + + [JsonPropertyName("password")] + public string Password { get; set; } = ""; + + [JsonPropertyName("initial_device_display_name")] + public string InitialDeviceDisplayName { get; set; } = "Rory&::LibMatrix"; + + public class LoginIdentifier { + [JsonPropertyName("type")] + public string Type { get; set; } = "m.id.user"; + + [JsonPropertyName("user")] + public string User { get; set; } = ""; + } +} diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index df1eb52..3ba965b 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -1,22 +1,28 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; using System.Net.Http.Json; using System.Text.Json; +using System.Threading.Tasks; using System.Web; using LibMatrix.Extensions; +using LibMatrix.Homeservers; using LibMatrix.Responses; using LibMatrix.StateEventTypes.Spec; namespace LibMatrix.RoomTypes; public class GenericRoom { - internal readonly AuthenticatedHomeServer _homeServer; + internal readonly AuthenticatedHomeserverGeneric Homeserver; internal readonly MatrixHttpClient _httpClient; - public GenericRoom(AuthenticatedHomeServer homeServer, string roomId) { - _homeServer = homeServer; - _httpClient = homeServer._httpClient; + public GenericRoom(AuthenticatedHomeserverGeneric homeserver, string roomId) { + Homeserver = homeserver; + _httpClient = homeserver._httpClient; RoomId = roomId; if (GetType() != typeof(SpaceRoom)) - AsSpace = new SpaceRoom(homeServer, RoomId); + AsSpace = new SpaceRoom(homeserver, RoomId); } public string RoomId { get; set; } @@ -182,5 +188,23 @@ public class GenericRoom { return res; } + public async Task<T> GetRoomAccountData<T>(string key) { + var res = await _httpClient.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()}"); + } + + return await res.Content.ReadFromJsonAsync<T>(); + } + + public async Task SetRoomAccountData(string key, object data) { + var res = await _httpClient.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()}"); + } + } + public readonly SpaceRoom AsSpace; } diff --git a/LibMatrix/RoomTypes/SpaceRoom.cs b/LibMatrix/RoomTypes/SpaceRoom.cs index 5393ee7..017a123 100644 --- a/LibMatrix/RoomTypes/SpaceRoom.cs +++ b/LibMatrix/RoomTypes/SpaceRoom.cs @@ -1,13 +1,17 @@ +using System.Collections.Generic; +using System.Threading; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; +using LibMatrix.Homeservers; namespace LibMatrix.RoomTypes; public class SpaceRoom : GenericRoom { - private new readonly AuthenticatedHomeServer _homeServer; + private new readonly AuthenticatedHomeserverGeneric _homeserver; private readonly GenericRoom _room; - public SpaceRoom(AuthenticatedHomeServer homeServer, string roomId) : base(homeServer, roomId) { - _homeServer = homeServer; + public SpaceRoom(AuthenticatedHomeserverGeneric homeserver, string roomId) : base(homeserver, roomId) { + _homeserver = homeserver; } private static SemaphoreSlim _semaphore = new(1, 1); @@ -18,7 +22,7 @@ public class SpaceRoom : GenericRoom { await foreach (var stateEvent in state) { if (stateEvent.Type != "m.space.child") continue; if (stateEvent.RawContent.ToJson() != "{}" || includeRemoved) - yield return await _homeServer.GetRoom(stateEvent.StateKey); + yield return await _homeserver.GetRoom(stateEvent.StateKey); } _semaphore.Release(); } diff --git a/LibMatrix/Services/HomeserverProviderService.cs b/LibMatrix/Services/HomeserverProviderService.cs index 366f0ca..776c7eb 100644 --- a/LibMatrix/Services/HomeserverProviderService.cs +++ b/LibMatrix/Services/HomeserverProviderService.cs @@ -1,7 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json.Serialization; +using System.Threading; +using System.Threading.Tasks; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; +using LibMatrix.Homeservers; using LibMatrix.Responses; using Microsoft.Extensions.Logging; @@ -22,46 +29,53 @@ public class HomeserverProviderService { } private static Dictionary<string, SemaphoreSlim> _authenticatedHomeserverSemaphore = new(); - private static Dictionary<string, AuthenticatedHomeServer> _authenticatedHomeServerCache = new(); + private static Dictionary<string, AuthenticatedHomeserverGeneric> _authenticatedHomeServerCache = new(); - public async Task<AuthenticatedHomeServer> GetAuthenticatedWithToken(string homeserver, string accessToken, - string? overrideFullDomain = null) { - var sem = _authenticatedHomeserverSemaphore.GetOrCreate(homeserver+accessToken, _ => new SemaphoreSlim(1, 1)); + public async Task<AuthenticatedHomeserverGeneric> GetAuthenticatedWithToken(string homeserver, string accessToken, + string? proxy = null) { + var sem = _authenticatedHomeserverSemaphore.GetOrCreate(homeserver + accessToken, _ => new SemaphoreSlim(1, 1)); await sem.WaitAsync(); - if (_authenticatedHomeServerCache.ContainsKey(homeserver+accessToken)) { + if (_authenticatedHomeServerCache.ContainsKey(homeserver + accessToken)) { sem.Release(); - return _authenticatedHomeServerCache[homeserver+accessToken]; + return _authenticatedHomeServerCache[homeserver + accessToken]; } - var hs = new AuthenticatedHomeServer(_tieredStorageService, homeserver, accessToken); - hs.FullHomeServerDomain = overrideFullDomain ?? - await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); - hs._httpClient.Dispose(); - hs._httpClient = new MatrixHttpClient { BaseAddress = new Uri(hs.FullHomeServerDomain) }; - hs._httpClient.Timeout = TimeSpan.FromSeconds(120); + var domain = proxy ?? await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); + var hc = new MatrixHttpClient { BaseAddress = new Uri(domain) }; + + AuthenticatedHomeserverGeneric hs; + if (true) { + hs = new AuthenticatedHomeserverMxApiExtended(_tieredStorageService, homeserver, accessToken); + } + else { + hs = new AuthenticatedHomeserverGeneric(_tieredStorageService, homeserver, accessToken); + } + + hs.FullHomeServerDomain = domain; + hs._httpClient = hc; + hs._httpClient.Timeout = TimeSpan.FromMinutes(15); hs._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); hs.WhoAmI = (await hs._httpClient.GetFromJsonAsync<WhoAmIResponse>("/_matrix/client/v3/account/whoami"))!; - _authenticatedHomeServerCache[homeserver+accessToken] = hs; + lock(_authenticatedHomeServerCache) + _authenticatedHomeServerCache[homeserver + accessToken] = hs; sem.Release(); return hs; } - public async Task<RemoteHomeServer> GetRemoteHomeserver(string homeserver, string? overrideFullDomain = null) { + public async Task<RemoteHomeServer> GetRemoteHomeserver(string homeserver, string? proxy = null) { var hs = new RemoteHomeServer(homeserver); - hs.FullHomeServerDomain = overrideFullDomain ?? - await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); + hs.FullHomeServerDomain = proxy ?? await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); hs._httpClient.Dispose(); hs._httpClient = new MatrixHttpClient { BaseAddress = new Uri(hs.FullHomeServerDomain) }; hs._httpClient.Timeout = TimeSpan.FromSeconds(120); return hs; } - public async Task<LoginResponse> Login(string homeserver, string user, string password, - string? overrideFullDomain = null) { - var hs = await GetRemoteHomeserver(homeserver, overrideFullDomain); + public async Task<LoginResponse> Login(string homeserver, string user, string password, string? proxy = null) { + var hs = await GetRemoteHomeserver(homeserver, proxy); var payload = new LoginRequest { Identifier = new LoginRequest.LoginIdentifier { User = user }, Password = password @@ -70,26 +84,4 @@ public class HomeserverProviderService { var data = await resp.Content.ReadFromJsonAsync<LoginResponse>(); return data!; } - - private class LoginRequest { - [JsonPropertyName("type")] - public string Type { get; set; } = "m.login.password"; - - [JsonPropertyName("identifier")] - public LoginIdentifier Identifier { get; set; } = new(); - - [JsonPropertyName("password")] - public string Password { get; set; } = ""; - - [JsonPropertyName("initial_device_display_name")] - public string InitialDeviceDisplayName { get; set; } = "Rory&::LibMatrix"; - - public class LoginIdentifier { - [JsonPropertyName("type")] - public string Type { get; set; } = "m.id.user"; - - [JsonPropertyName("user")] - public string User { get; set; } = ""; - } - } } diff --git a/LibMatrix/Services/HomeserverResolverService.cs b/LibMatrix/Services/HomeserverResolverService.cs index 78c5c37..dcd0fe9 100644 --- a/LibMatrix/Services/HomeserverResolverService.cs +++ b/LibMatrix/Services/HomeserverResolverService.cs @@ -1,4 +1,10 @@ +using System; +using System.Collections.Generic; +using System.IO; using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; using Microsoft.Extensions.Logging; @@ -26,9 +32,9 @@ public class HomeserverResolverService { if (homeserver is null) throw new ArgumentNullException(nameof(homeserver)); var sem = _wellKnownSemaphores.GetOrCreate(homeserver, _ => new SemaphoreSlim(1, 1)); await sem.WaitAsync(); - if (_wellKnownCache.ContainsKey(homeserver)) { + if (_wellKnownCache.TryGetValue(homeserver, out var known)) { sem.Release(); - return _wellKnownCache[homeserver]; + return known; } string? result = null; diff --git a/LibMatrix/Services/ServiceInstaller.cs b/LibMatrix/Services/ServiceInstaller.cs index b1c98e1..9c4cdb9 100644 --- a/LibMatrix/Services/ServiceInstaller.cs +++ b/LibMatrix/Services/ServiceInstaller.cs @@ -1,3 +1,5 @@ +using System; +using System.Linq; using Microsoft.Extensions.DependencyInjection; namespace LibMatrix.Services; diff --git a/LibMatrix/StateEvent.cs b/LibMatrix/StateEvent.cs index a2f951b..26dc39a 100644 --- a/LibMatrix/StateEvent.cs +++ b/LibMatrix/StateEvent.cs @@ -1,8 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; +using ArcaneLibs; +using ArcaneLibs.Extensions; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix; @@ -103,6 +109,7 @@ public class StateEvent { } //debug + [JsonIgnore] public string dtype { get { var res = GetType().Name switch { @@ -113,5 +120,6 @@ public class StateEvent { } } + [JsonIgnore] public string cdtype => TypedContent.GetType().Name; } diff --git a/LibMatrix/StateEventTypes/Common/MjolnirShortcodeEventData.cs b/LibMatrix/StateEventTypes/Common/MjolnirShortcodeEventData.cs index 808a0db..c3fee34 100644 --- a/LibMatrix/StateEventTypes/Common/MjolnirShortcodeEventData.cs +++ b/LibMatrix/StateEventTypes/Common/MjolnirShortcodeEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Common; diff --git a/LibMatrix/StateEventTypes/Common/RoomEmotesEventData.cs b/LibMatrix/StateEventTypes/Common/RoomEmotesEventData.cs index af1c09e..754a9dc 100644 --- a/LibMatrix/StateEventTypes/Common/RoomEmotesEventData.cs +++ b/LibMatrix/StateEventTypes/Common/RoomEmotesEventData.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Common; diff --git a/LibMatrix/StateEventTypes/Spec/CanonicalAliasEventData.cs b/LibMatrix/StateEventTypes/Spec/CanonicalAliasEventData.cs index 36cc90e..384ca43 100644 --- a/LibMatrix/StateEventTypes/Spec/CanonicalAliasEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/CanonicalAliasEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/GuestAccessEventData.cs b/LibMatrix/StateEventTypes/Spec/GuestAccessEventData.cs index b6ddd93..eadba67 100644 --- a/LibMatrix/StateEventTypes/Spec/GuestAccessEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/GuestAccessEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/HistoryVisibilityEventData.cs b/LibMatrix/StateEventTypes/Spec/HistoryVisibilityEventData.cs index 8836fc0..1c73346 100644 --- a/LibMatrix/StateEventTypes/Spec/HistoryVisibilityEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/HistoryVisibilityEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/JoinRulesEventData.cs b/LibMatrix/StateEventTypes/Spec/JoinRulesEventData.cs index 0393395..d3da559 100644 --- a/LibMatrix/StateEventTypes/Spec/JoinRulesEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/JoinRulesEventData.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; @@ -14,5 +16,13 @@ public class JoinRulesEventData : IStateEventType { public string JoinRule { get; set; } [JsonPropertyName("allow")] - public List<string> Allow { get; set; } + public List<AllowEntry> 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/StateEventTypes/Spec/PolicyRuleStateEventData.cs b/LibMatrix/StateEventTypes/Spec/PolicyRuleStateEventData.cs index 963864f..c0aed9e 100644 --- a/LibMatrix/StateEventTypes/Spec/PolicyRuleStateEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/PolicyRuleStateEventData.cs @@ -1,5 +1,7 @@ +using System; using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/PresenceStateEventData.cs b/LibMatrix/StateEventTypes/Spec/PresenceStateEventData.cs index fa75a88..c5a95ae 100644 --- a/LibMatrix/StateEventTypes/Spec/PresenceStateEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/PresenceStateEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; @@ -14,4 +15,8 @@ public class PresenceStateEventData : IStateEventType { public bool CurrentlyActive { get; set; } [JsonPropertyName("status_msg")] public string StatusMessage { get; set; } + [JsonPropertyName("avatar_url")] + public string AvatarUrl { get; set; } + [JsonPropertyName("displayname")] + public string DisplayName { get; set; } } diff --git a/LibMatrix/StateEventTypes/Spec/ProfileResponseEventData.cs b/LibMatrix/StateEventTypes/Spec/ProfileResponseEventData.cs index d2340f5..14449e0 100644 --- a/LibMatrix/StateEventTypes/Spec/ProfileResponseEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/ProfileResponseEventData.cs @@ -5,8 +5,8 @@ namespace LibMatrix.StateEventTypes.Spec; public class ProfileResponseEventData : IStateEventType { [JsonPropertyName("avatar_url")] - public string? AvatarUrl { get; set; } = ""; + public string? AvatarUrl { get; set; } [JsonPropertyName("displayname")] - public string? DisplayName { get; set; } = ""; + public string? DisplayName { get; set; } } diff --git a/LibMatrix/StateEventTypes/Spec/RoomAliasEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomAliasEventData.cs index 8d921b2..df80a08 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomAliasEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomAliasEventData.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomAvatarEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomAvatarEventData.cs index cbe41dd..4d3fabf 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomAvatarEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomAvatarEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomCreateEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomCreateEventData.cs index b96c31e..0b1bd5c 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomCreateEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomCreateEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomEncryptionEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomEncryptionEventData.cs index e16716e..126117d 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomEncryptionEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomEncryptionEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomMemberEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomMemberEventData.cs index 623c43c..7c181ae 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomMemberEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomMemberEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomMessageEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomMessageEventData.cs index 14dd67a..5d65237 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomMessageEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomMessageEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomNameEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomNameEventData.cs index 9d13513..2245793 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomNameEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomNameEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomPinnedEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomPinnedEventData.cs index c7d29fa..10ef3f5 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomPinnedEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomPinnedEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomPowerLevelEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomPowerLevelEventData.cs index c5dda78..3c985f6 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomPowerLevelEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomPowerLevelEventData.cs @@ -1,5 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; @@ -7,43 +11,43 @@ namespace LibMatrix.StateEventTypes.Spec; [MatrixEvent(EventName = "m.room.power_levels")] public class RoomPowerLevelEventData : IStateEventType { [JsonPropertyName("ban")] - public int Ban { get; set; } // = 50; + public long Ban { get; set; } // = 50; [JsonPropertyName("events_default")] - public int EventsDefault { get; set; } // = 0; + public long EventsDefault { get; set; } // = 0; [JsonPropertyName("events")] - public Dictionary<string, int> Events { get; set; } // = null!; + public Dictionary<string, long> Events { get; set; } // = null!; [JsonPropertyName("invite")] - public int Invite { get; set; } // = 50; + public long Invite { get; set; } // = 50; [JsonPropertyName("kick")] - public int Kick { get; set; } // = 50; + public long Kick { get; set; } // = 50; [JsonPropertyName("notifications")] public NotificationsPL NotificationsPl { get; set; } // = null!; [JsonPropertyName("redact")] - public int Redact { get; set; } // = 50; + public long Redact { get; set; } // = 50; [JsonPropertyName("state_default")] - public int StateDefault { get; set; } // = 50; + public long StateDefault { get; set; } // = 50; [JsonPropertyName("users")] - public Dictionary<string, int> Users { get; set; } // = null!; + public Dictionary<string, long> Users { get; set; } // = null!; [JsonPropertyName("users_default")] - public int UsersDefault { get; set; } // = 0; + 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 int Historical { get; set; } // = 50; + public long Historical { get; set; } // = 50; public class NotificationsPL { [JsonPropertyName("room")] - public int Room { get; set; } = 50; + public long Room { get; set; } = 50; } public bool IsUserAdmin(string userId) { diff --git a/LibMatrix/StateEventTypes/Spec/RoomTopicEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomTopicEventData.cs index 0fd0df6..eaf9e8c 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomTopicEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomTopicEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/RoomTypingEventData.cs b/LibMatrix/StateEventTypes/Spec/RoomTypingEventData.cs index 857338c..cebb238 100644 --- a/LibMatrix/StateEventTypes/Spec/RoomTypingEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/RoomTypingEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/ServerACLEventData.cs b/LibMatrix/StateEventTypes/Spec/ServerACLEventData.cs index 68bbe6b..a258707 100644 --- a/LibMatrix/StateEventTypes/Spec/ServerACLEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/ServerACLEventData.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/SpaceChildEventData.cs b/LibMatrix/StateEventTypes/Spec/SpaceChildEventData.cs index a55e941..5ccab88 100644 --- a/LibMatrix/StateEventTypes/Spec/SpaceChildEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/SpaceChildEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/StateEventTypes/Spec/SpaceParentEventData.cs b/LibMatrix/StateEventTypes/Spec/SpaceParentEventData.cs index 7dc7f4c..6477290 100644 --- a/LibMatrix/StateEventTypes/Spec/SpaceParentEventData.cs +++ b/LibMatrix/StateEventTypes/Spec/SpaceParentEventData.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Helpers; using LibMatrix.Interfaces; namespace LibMatrix.StateEventTypes.Spec; diff --git a/LibMatrix/WhoAmIResponse.cs b/LibMatrix/WhoAmIResponse.cs new file mode 100644 index 0000000..f461c9b --- /dev/null +++ b/LibMatrix/WhoAmIResponse.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace LibMatrix; + +public class WhoAmIResponse { + [JsonPropertyName("user_id")] + public string UserId { get; set; } = null!; + + [JsonPropertyName("device_id")] + public string? DeviceId { get; set; } + [JsonPropertyName("is_guest")] + public bool? IsGuest { get; set; } +} \ No newline at end of file |