diff options
Diffstat (limited to 'MatrixRoomUtils.Core')
57 files changed, 0 insertions, 2313 deletions
diff --git a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs deleted file mode 100644 index fbbb99f..0000000 --- a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Filters; -using MatrixRoomUtils.Core.Helpers; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.Responses.Admin; -using MatrixRoomUtils.Core.RoomTypes; -using MatrixRoomUtils.Core.Services; - -namespace MatrixRoomUtils.Core; - -public class AuthenticatedHomeServer : IHomeServer { - private readonly TieredStorageService _storage; - public readonly HomeserverAdminApi Admin; - public readonly SyncHelper SyncHelper; - - 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 async Task<GenericRoom> GetRoom(string roomId) => new(this, roomId); - - public async Task<List<GenericRoom>> GetJoinedRooms() { - var rooms = new List<GenericRoom>(); - var roomQuery = await _httpClient.GetAsync("/_matrix/client/v3/joined_rooms"); - - var roomsJson = await roomQuery.Content.ReadFromJsonAsync<JsonElement>(); - foreach (var room in roomsJson.GetProperty("joined_rooms").EnumerateArray()) rooms.Add(new GenericRoom(this, room.GetString())); - - 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 async IAsyncEnumerable<AdminRoomListingResult.AdminRoomListingResultRoom> SearchRoomsAsync(int limit = int.MaxValue, string orderBy = "name", string dir = "f", string? searchTerm = null, LocalRoomQueryFilter? localFilter = null) { - AdminRoomListingResult? res = null; - var i = 0; - int? totalRooms = null; - do { - var url = $"/_synapse/admin/v1/rooms?limit={Math.Min(limit, 100)}&dir={dir}&order_by={orderBy}"; - if (!string.IsNullOrEmpty(searchTerm)) url += $"&search_term={searchTerm}"; - - if (res?.NextBatch is not null) url += $"&from={res.NextBatch}"; - - Console.WriteLine($"--- ADMIN Querying Room List with URL: {url} - Already have {i} items... ---"); - - res = await _authenticatedHomeServer._httpClient.GetFromJsonAsync<AdminRoomListingResult>(url); - totalRooms ??= res?.TotalRooms; - Console.WriteLine(res.ToJson(false)); - foreach (var room in res.Rooms) { - if (localFilter is not null) { - if (!room.RoomId.Contains(localFilter.RoomIdContains)) { - totalRooms--; - continue; - } - if (!room.Name?.Contains(localFilter.NameContains) == true) { - totalRooms--; - continue; - } - if (!room.CanonicalAlias?.Contains(localFilter.CanonicalAliasContains) == true) { - totalRooms--; - continue; - } - if (!room.Version.Contains(localFilter.VersionContains)) { - totalRooms--; - continue; - } - if (!room.Creator.Contains(localFilter.CreatorContains)) { - totalRooms--; - continue; - } - if (!room.Encryption?.Contains(localFilter.EncryptionContains) == true) { - totalRooms--; - continue; - } - if (!room.JoinRules?.Contains(localFilter.JoinRulesContains) == true) { - totalRooms--; - continue; - } - if(!room.GuestAccess?.Contains(localFilter.GuestAccessContains) == true) { - totalRooms--; - continue; - } - if(!room.HistoryVisibility?.Contains(localFilter.HistoryVisibilityContains) == true) { - totalRooms--; - continue; - } - - if(localFilter.CheckFederation && room.Federatable != localFilter.Federatable) { - totalRooms--; - continue; - } - if(localFilter.CheckPublic && room.Public != localFilter.Public) { - totalRooms--; - continue; - } - - if(room.JoinedMembers < localFilter.JoinedMembersGreaterThan || room.JoinedMembers > localFilter.JoinedMembersLessThan) { - totalRooms--; - continue; - } - if(room.JoinedLocalMembers < localFilter.JoinedLocalMembersGreaterThan || room.JoinedLocalMembers > localFilter.JoinedLocalMembersLessThan) { - totalRooms--; - continue; - } - } - // if (contentSearch is not null && !string.IsNullOrEmpty(contentSearch) && - // !( - // room.Name?.Contains(contentSearch, StringComparison.InvariantCultureIgnoreCase) == true || - // room.CanonicalAlias?.Contains(contentSearch, StringComparison.InvariantCultureIgnoreCase) == true || - // room.Creator?.Contains(contentSearch, StringComparison.InvariantCultureIgnoreCase) == true - // ) - // ) { - // totalRooms--; - // continue; - // } - - i++; - yield return room; - } - } 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; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/EventIdResponse.cs b/MatrixRoomUtils.Core/EventIdResponse.cs deleted file mode 100644 index 77dc7f8..0000000 --- a/MatrixRoomUtils.Core/EventIdResponse.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core; - -public class EventIdResponse { - [JsonPropertyName("event_id")] - public string EventId { get; set; } = null!; -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Extensions/ClassCollector.cs b/MatrixRoomUtils.Core/Extensions/ClassCollector.cs deleted file mode 100644 index d4ba838..0000000 --- a/MatrixRoomUtils.Core/Extensions/ClassCollector.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; - -namespace MatrixRoomUtils.Core.Extensions; - -public class ClassCollector<T> where T : class { - static ClassCollector() { - if (!typeof(T).IsInterface) - throw new ArgumentException( - $"ClassCollector<T> must be used with an interface type. Passed type: {typeof(T).Name}"); - } - - public List<Type> ResolveFromAllAccessibleAssemblies() => AppDomain.CurrentDomain.GetAssemblies().SelectMany(ResolveFromAssembly).ToList(); - - public List<Type> ResolveFromObjectReference(object obj) => ResolveFromTypeReference(obj.GetType()); - - public List<Type> ResolveFromTypeReference(Type t) => Assembly.GetAssembly(t)?.GetReferencedAssemblies().SelectMany(ResolveFromAssemblyName).ToList() ?? new List<Type>(); - - public List<Type> ResolveFromAssemblyName(AssemblyName assemblyName) => ResolveFromAssembly(Assembly.Load(assemblyName)); - - public List<Type> ResolveFromAssembly(Assembly assembly) => assembly.GetTypes() - .Where(x => x is { IsClass: true, IsAbstract: false } && x.GetInterfaces().Contains(typeof(T))).ToList(); -} diff --git a/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs b/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs deleted file mode 100644 index 78bbdfa..0000000 --- a/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace MatrixRoomUtils.Core.Extensions; - -public static class DictionaryExtensions { - public static bool ChangeKey<TKey, TValue>(this IDictionary<TKey, TValue> dict, - TKey oldKey, TKey newKey) { - TValue value; - if (!dict.Remove(oldKey, out value)) - return false; - - dict[newKey] = value; // or dict.Add(newKey, value) depending on ur comfort - return true; - } - - public static Y GetOrCreate<X, Y>(this IDictionary<X, Y> dict, X key) where Y : new() { - if (dict.TryGetValue(key, out var value)) { - return value; - } - - value = new Y(); - dict.Add(key, value); - return value; - } - - public static Y GetOrCreate<X, Y>(this IDictionary<X, Y> dict, X key, Func<X, Y> valueFactory) { - if (dict.TryGetValue(key, out var value)) { - return value; - } - - value = valueFactory(key); - dict.Add(key, value); - return value; - } -} diff --git a/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs b/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs deleted file mode 100644 index 009338a..0000000 --- a/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Net.Http.Headers; -using System.Reflection; -using System.Text.Json; - -namespace MatrixRoomUtils.Core.Extensions; - -public static class HttpClientExtensions { - public static async Task<bool> CheckSuccessStatus(this HttpClient hc, string url) { - //cors causes failure, try to catch - try { - var resp = await hc.GetAsync(url); - return resp.IsSuccessStatusCode; - } - catch (Exception e) { - Console.WriteLine($"Failed to check success status: {e.Message}"); - return false; - } - } -} - -public class MatrixHttpClient : HttpClient { - public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, - CancellationToken cancellationToken) { - Console.WriteLine($"Sending request to {request.RequestUri}"); - try { - HttpRequestOptionsKey<bool> WebAssemblyEnableStreamingResponseKey = - new HttpRequestOptionsKey<bool>("WebAssemblyEnableStreamingResponse"); - request.Options.Set(WebAssemblyEnableStreamingResponseKey, true); - } - catch (Exception e) { - Console.WriteLine("Failed to set browser response streaming:"); - Console.WriteLine(e); - } - - var a = await base.SendAsync(request, cancellationToken); - if (!a.IsSuccessStatusCode) { - var content = await a.Content.ReadAsStringAsync(cancellationToken); - if (content.StartsWith('{')) { - var ex = JsonSerializer.Deserialize<MatrixException>(content); - ex.RawContent = content; - // Console.WriteLine($"Failed to send request: {ex}"); - if (ex?.RetryAfterMs is not null) { - await Task.Delay(ex.RetryAfterMs.Value, cancellationToken); - typeof(HttpRequestMessage).GetField("_sendStatus", BindingFlags.NonPublic | BindingFlags.Instance) - ?.SetValue(request, 0); - return await SendAsync(request, cancellationToken); - } - - throw ex!; - } - - throw new InvalidDataException("Encountered invalid data:\n" + content); - } - - return a; - } - - // GetFromJsonAsync - public async Task<T> GetFromJsonAsync<T>(string requestUri, CancellationToken cancellationToken = default) { - var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - var response = await SendAsync(request, cancellationToken); - response.EnsureSuccessStatusCode(); - await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken); - return await JsonSerializer.DeserializeAsync<T>(responseStream, cancellationToken: cancellationToken); - } - - // GetStreamAsync - public async Task<Stream> GetStreamAsync(string requestUri, CancellationToken cancellationToken = default) { - var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - var response = await SendAsync(request, cancellationToken); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStreamAsync(cancellationToken); - } -} diff --git a/MatrixRoomUtils.Core/Extensions/IEnumerableExtensions.cs b/MatrixRoomUtils.Core/Extensions/IEnumerableExtensions.cs deleted file mode 100644 index 8994529..0000000 --- a/MatrixRoomUtils.Core/Extensions/IEnumerableExtensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.Extensions; - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public class MatrixEventAttribute : Attribute { - public string EventName { get; set; } - public bool Legacy { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs b/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs deleted file mode 100644 index 7701c9e..0000000 --- a/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core.Extensions; - -public static class JsonElementExtensions { - public static bool FindExtraJsonElementFields(this JsonElement obj, Type objectType, string objectPropertyName) { - if (objectPropertyName == "content" && objectType == typeof(JsonObject)) - objectType = typeof(StateEventResponse); - // if (t == typeof(JsonNode)) - // return false; - - Console.WriteLine($"{objectType.Name} {objectPropertyName}"); - bool unknownPropertyFound = false; - var mappedPropsDict = objectType.GetProperties() - .Where(x => x.GetCustomAttribute<JsonPropertyNameAttribute>() is not null) - .ToDictionary(x => x.GetCustomAttribute<JsonPropertyNameAttribute>()!.Name, x => x); - objectType.GetProperties().Where(x => !mappedPropsDict.ContainsKey(x.Name)) - .ToList().ForEach(x => mappedPropsDict.TryAdd(x.Name, x)); - - foreach (var field in obj.EnumerateObject()) { - if (mappedPropsDict.TryGetValue(field.Name, out var mappedProperty)) { - //dictionary - if (mappedProperty.PropertyType.IsGenericType && - mappedProperty.PropertyType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) { - unknownPropertyFound |= _checkDictionary(field, objectType, mappedProperty.PropertyType); - continue; - } - - if (mappedProperty.PropertyType.IsGenericType && - mappedProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) { - unknownPropertyFound |= _checkList(field, objectType, mappedProperty.PropertyType); - continue; - } - - if (field.Name == "content" && (objectType == typeof(StateEventResponse) || objectType == typeof(StateEvent))) { - unknownPropertyFound |= field.FindExtraJsonPropertyFieldsByValueKind( - StateEvent.GetStateEventType(obj.GetProperty("type").GetString()), - mappedProperty.PropertyType); - continue; - } - - unknownPropertyFound |= - field.FindExtraJsonPropertyFieldsByValueKind(objectType, mappedProperty.PropertyType); - continue; - } - - Console.WriteLine($"[!!] Unknown property {field.Name} in {objectType.Name}!"); - unknownPropertyFound = true; - } - - return unknownPropertyFound; - } - - private static bool FindExtraJsonPropertyFieldsByValueKind(this JsonProperty field, Type containerType, - Type propertyType) { - if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { - propertyType = propertyType.GetGenericArguments()[0]; - } - - bool switchResult = false; - switch (field.Value.ValueKind) { - case JsonValueKind.Array: - switchResult = field.Value.EnumerateArray().Aggregate(switchResult, - (current, element) => current | element.FindExtraJsonElementFields(propertyType, field.Name)); - break; - case JsonValueKind.Object: - switchResult |= field.Value.FindExtraJsonElementFields(propertyType, field.Name); - break; - case JsonValueKind.True: - case JsonValueKind.False: - return _checkBool(field, containerType, propertyType); - case JsonValueKind.String: - return _checkString(field, containerType, propertyType); - case JsonValueKind.Number: - return _checkNumber(field, containerType, propertyType); - case JsonValueKind.Undefined: - case JsonValueKind.Null: - break; - default: - throw new ArgumentOutOfRangeException(); - } - - return switchResult; - } - - private static bool _checkBool(this JsonProperty field, Type containerType, Type propertyType) { - if (propertyType == typeof(bool)) return true; - Console.WriteLine( - $"[!!] Encountered bool for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); - return false; - } - - private static bool _checkString(this JsonProperty field, Type containerType, Type propertyType) { - if (propertyType == typeof(string)) return true; - // ReSharper disable once BuiltInTypeReferenceStyle - if (propertyType == typeof(String)) return true; - Console.WriteLine( - $"[!!] Encountered string for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); - return false; - } - - private static bool _checkNumber(this JsonProperty field, Type containerType, Type propertyType) { - if (propertyType == typeof(int) || - propertyType == typeof(double) || - propertyType == typeof(float) || - propertyType == typeof(decimal) || - propertyType == typeof(long) || - propertyType == typeof(short) || - propertyType == typeof(uint) || - propertyType == typeof(ulong) || - propertyType == typeof(ushort) || - propertyType == typeof(byte) || - propertyType == typeof(sbyte)) - return true; - Console.WriteLine( - $"[!!] Encountered number for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); - return false; - } - - private static bool _checkDictionary(this JsonProperty field, Type containerType, Type propertyType) { - var keyType = propertyType.GetGenericArguments()[0]; - var valueType = propertyType.GetGenericArguments()[1]; - valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; - Console.WriteLine( - $"Encountered dictionary {field.Name} with key type {keyType.Name} and value type {valueType.Name}!"); - - return field.Value.EnumerateObject() - .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) - .Aggregate(false, (current, key) => - current | key.FindExtraJsonPropertyFieldsByValueKind(containerType, valueType) - ); - } - - private static bool _checkList(this JsonProperty field, Type containerType, Type propertyType) { - var valueType = propertyType.GetGenericArguments()[0]; - valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; - Console.WriteLine( - $"Encountered list {field.Name} with value type {valueType.Name}!"); - - return field.Value.EnumerateArray() - .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) - .Aggregate(false, (current, key) => - current | key.FindExtraJsonElementFields(valueType, field.Name) - ); - } -} diff --git a/MatrixRoomUtils.Core/Extensions/ObjectExtensions.cs b/MatrixRoomUtils.Core/Extensions/ObjectExtensions.cs deleted file mode 100644 index a4b0791..0000000 --- a/MatrixRoomUtils.Core/Extensions/ObjectExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Encodings.Web; -using System.Text.Json; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core.Extensions; - -public static class ObjectExtensions { - public static string ToJson(this object obj, bool indent = true, bool ignoreNull = false, bool unsafeContent = false) { - var jso = new JsonSerializerOptions(); - if (indent) jso.WriteIndented = true; - if (ignoreNull) jso.IgnoreNullValues = true; - if (unsafeContent) jso.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping; - return JsonSerializer.Serialize(obj, jso); - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Extensions/StringExtensions.cs b/MatrixRoomUtils.Core/Extensions/StringExtensions.cs deleted file mode 100644 index b81d59f..0000000 --- a/MatrixRoomUtils.Core/Extensions/StringExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MatrixRoomUtils.Core.Extensions; - -public static class StringExtensions { - // public static async Task<string> GetMediaUrl(this string MxcUrl) - // { - // //MxcUrl: mxc://rory.gay/ocRVanZoUTCcifcVNwXgbtTg - // //target: https://matrix.rory.gay/_matrix/media/v3/download/rory.gay/ocRVanZoUTCcifcVNwXgbtTg - // - // var server = MxcUrl.Split('/')[2]; - // var mediaId = MxcUrl.Split('/')[3]; - // return $"{(await new RemoteHomeServer(server).Configure()).FullHomeServerDomain}/_matrix/media/v3/download/{server}/{mediaId}"; - // } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Filters/LocalRoomQueryFilter.cs b/MatrixRoomUtils.Core/Filters/LocalRoomQueryFilter.cs deleted file mode 100644 index 65c7baa..0000000 --- a/MatrixRoomUtils.Core/Filters/LocalRoomQueryFilter.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace MatrixRoomUtils.Core.Filters; - -public class LocalRoomQueryFilter { - public string RoomIdContains { get; set; } = ""; - public string NameContains { get; set; } = ""; - public string CanonicalAliasContains { get; set; } = ""; - public string VersionContains { get; set; } = ""; - public string CreatorContains { get; set; } = ""; - public string EncryptionContains { get; set; } = ""; - public string JoinRulesContains { get; set; } = ""; - public string GuestAccessContains { get; set; } = ""; - public string HistoryVisibilityContains { get; set; } = ""; - - public bool Federatable { get; set; } = true; - public bool Public { get; set; } = true; - - public int JoinedMembersGreaterThan { get; set; } = 0; - public int JoinedMembersLessThan { get; set; } = int.MaxValue; - - public int JoinedLocalMembersGreaterThan { get; set; } = 0; - public int JoinedLocalMembersLessThan { get; set; } = int.MaxValue; - public int StateEventsGreaterThan { get; set; } = 0; - public int StateEventsLessThan { get; set; } = int.MaxValue; - - - public bool CheckFederation { get; set; } - public bool CheckPublic { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Filters/SyncFilter.cs b/MatrixRoomUtils.Core/Filters/SyncFilter.cs deleted file mode 100644 index bc81101..0000000 --- a/MatrixRoomUtils.Core/Filters/SyncFilter.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Filters; - -public class SyncFilter { - [JsonPropertyName("account_data")] - public EventFilter? AccountData { get; set; } - - [JsonPropertyName("presence")] - public EventFilter? Presence { get; set; } - - [JsonPropertyName("room")] - public RoomFilter? Room { get; set; } - - public class RoomFilter { - [JsonPropertyName("account_data")] - public StateFilter? AccountData { get; set; } - - [JsonPropertyName("ephemeral")] - public StateFilter? Ephemeral { get; set; } - - [JsonPropertyName("state")] - public StateFilter? State { get; set; } - - [JsonPropertyName("timeline")] - public StateFilter? Timeline { get; set; } - - - public class StateFilter : EventFilter { - [JsonPropertyName("contains_url")] - public bool? ContainsUrl { get; set; } - - [JsonPropertyName("include_redundant_members")] - public bool? IncludeRedundantMembers { get; set; } - - [JsonPropertyName("lazy_load_members")] - public bool? LazyLoadMembers { get; set; } - - [JsonPropertyName("rooms")] - public List<string>? Rooms { get; set; } - - [JsonPropertyName("not_rooms")] - public List<string>? NotRooms { get; set; } - - [JsonPropertyName("unread_thread_notifications")] - public bool? UnreadThreadNotifications { get; set; } - } - } - - public class EventFilter { - [JsonPropertyName("limit")] - public int? Limit { get; set; } - - [JsonPropertyName("types")] - public List<string>? Types { get; set; } - - [JsonPropertyName("not_types")] - public List<string>? NotTypes { get; set; } - - [JsonPropertyName("senders")] - public List<string>? Senders { get; set; } - - [JsonPropertyName("not_senders")] - public List<string>? NotSenders { get; set; } - } -} diff --git a/MatrixRoomUtils.Core/Helpers/MediaResolver.cs b/MatrixRoomUtils.Core/Helpers/MediaResolver.cs deleted file mode 100644 index 0869135..0000000 --- a/MatrixRoomUtils.Core/Helpers/MediaResolver.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MatrixRoomUtils.Core.Helpers; - -public class MediaResolver { - public static string ResolveMediaUri(string homeserver, string mxc) => - mxc.Replace("mxc://", $"{homeserver}/_matrix/media/v3/download/"); -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs b/MatrixRoomUtils.Core/Helpers/SyncHelper.cs deleted file mode 100644 index e12164c..0000000 --- a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Filters; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.Responses.Admin; -using MatrixRoomUtils.Core.Services; -using MatrixRoomUtils.Core.StateEventTypes; - -namespace MatrixRoomUtils.Core.Helpers; - -public class SyncHelper { - private readonly AuthenticatedHomeServer _homeServer; - private readonly TieredStorageService _storageService; - - public SyncHelper(AuthenticatedHomeServer homeServer, TieredStorageService storageService) { - _homeServer = homeServer; - _storageService = storageService; - } - - public async Task<SyncResult?> Sync( - string? since = null, - int? timeout = 30000, - string? setPresence = "online", - SyncFilter? filter = null, - CancellationToken? cancellationToken = null) { - var outFileName = "sync-" + - (await _storageService.CacheStorageProvider.GetAllKeysAsync()).Count( - x => x.StartsWith("sync")) + - ".json"; - var url = $"/_matrix/client/v3/sync?timeout={timeout}&set_presence={setPresence}"; - if (!string.IsNullOrWhiteSpace(since)) url += $"&since={since}"; - if (filter is not null) url += $"&filter={filter.ToJson(ignoreNull: true, indent: false)}"; - // else url += "&full_state=true"; - Console.WriteLine("Calling: " + url); - try { - var req = await _homeServer._httpClient.GetAsync(url, cancellationToken: cancellationToken ?? CancellationToken.None); - - // var res = await JsonSerializer.DeserializeAsync<SyncResult>(await req.Content.ReadAsStreamAsync()); - -#if DEBUG && false - var jsonObj = await req.Content.ReadFromJsonAsync<JsonElement>(); - try { - await _homeServer._httpClient.PostAsJsonAsync( - "http://localhost:5116/validate/" + typeof(SyncResult).AssemblyQualifiedName, jsonObj); - } - catch (Exception e) { - Console.WriteLine("[!!] Checking sync response failed: " + e); - } - - var res = jsonObj.Deserialize<SyncResult>(); - return res; -#else - return await req.Content.ReadFromJsonAsync<SyncResult>(); -#endif - } - catch (TaskCanceledException) { - Console.WriteLine("Sync cancelled!"); - } - catch (Exception e) { - Console.WriteLine(e); - } - - return null; - } - - [SuppressMessage("ReSharper", "FunctionNeverReturns")] - public async Task RunSyncLoop( - bool skipInitialSyncEvents = true, - string? since = null, - int? timeout = 30000, - string? setPresence = "online", - SyncFilter? filter = null, - CancellationToken? cancellationToken = null - ) { - await Task.WhenAll((await _storageService.CacheStorageProvider.GetAllKeysAsync()) - .Where(x => x.StartsWith("sync")) - .ToList() - .Select(x => _storageService.CacheStorageProvider.DeleteObjectAsync(x))); - SyncResult? sync = null; - string? nextBatch = since; - while (cancellationToken is null || !cancellationToken.Value.IsCancellationRequested) { - sync = await Sync(since: nextBatch, timeout: timeout, setPresence: setPresence, filter: filter, - cancellationToken: cancellationToken); - nextBatch = sync?.NextBatch ?? nextBatch; - if (sync is null) continue; - Console.WriteLine($"Got sync, next batch: {nextBatch}!"); - - if (sync.Rooms is { Invite.Count: > 0 }) { - foreach (var roomInvite in sync.Rooms.Invite) { - var tasks = InviteReceivedHandlers.Select(x => x(roomInvite)).ToList(); - await Task.WhenAll(tasks); - } - } - - if (sync.AccountData is { Events: { Count: > 0 } }) { - foreach (var accountDataEvent in sync.AccountData.Events) { - var tasks = AccountDataReceivedHandlers.Select(x => x(accountDataEvent)).ToList(); - await Task.WhenAll(tasks); - } - } - - // Things that are skipped on the first sync - if (skipInitialSyncEvents) { - skipInitialSyncEvents = false; - continue; - } - - if (sync.Rooms is { Join.Count: > 0 }) { - foreach (var updatedRoom in sync.Rooms.Join) { - foreach (var stateEventResponse in updatedRoom.Value.Timeline.Events) { - stateEventResponse.RoomId = updatedRoom.Key; - var tasks = TimelineEventHandlers.Select(x => x(stateEventResponse)).ToList(); - await Task.WhenAll(tasks); - } - } - } - } - } - - /// <summary> - /// Event fired when a room invite is received - /// </summary> - public List<Func<KeyValuePair<string, SyncResult.RoomsDataStructure.InvitedRoomDataStructure>, Task>> - InviteReceivedHandlers { get; } = new(); - - public List<Func<StateEventResponse, Task>> TimelineEventHandlers { get; } = new(); - public List<Func<StateEventResponse, Task>> AccountDataReceivedHandlers { get; } = new(); -} - -public class SyncResult { - [JsonPropertyName("next_batch")] - public string NextBatch { get; set; } - - [JsonPropertyName("account_data")] - public EventList? AccountData { get; set; } - - [JsonPropertyName("presence")] - public PresenceDataStructure? Presence { get; set; } - - [JsonPropertyName("device_one_time_keys_count")] - public Dictionary<string, int> DeviceOneTimeKeysCount { get; set; } - - [JsonPropertyName("rooms")] - public RoomsDataStructure? Rooms { get; set; } - - [JsonPropertyName("to_device")] - public EventList? ToDevice { get; set; } - - [JsonPropertyName("device_lists")] - public DeviceListsDataStructure? DeviceLists { get; set; } - - public class DeviceListsDataStructure { - [JsonPropertyName("changed")] - public List<string>? Changed { get; set; } - - [JsonPropertyName("left")] - public List<string>? Left { get; set; } - } - - // supporting classes - public class PresenceDataStructure { - [JsonPropertyName("events")] - public List<StateEventResponse> Events { get; set; } - } - - public class RoomsDataStructure { - [JsonPropertyName("join")] - public Dictionary<string, JoinedRoomDataStructure>? Join { get; set; } - - [JsonPropertyName("invite")] - public Dictionary<string, InvitedRoomDataStructure>? Invite { get; set; } - - public class JoinedRoomDataStructure { - [JsonPropertyName("timeline")] - public TimelineDataStructure Timeline { get; set; } - - [JsonPropertyName("state")] - public EventList State { get; set; } - - [JsonPropertyName("account_data")] - public EventList AccountData { get; set; } - - [JsonPropertyName("ephemeral")] - public EventList Ephemeral { get; set; } - - [JsonPropertyName("unread_notifications")] - public UnreadNotificationsDataStructure UnreadNotifications { get; set; } - - [JsonPropertyName("summary")] - public SummaryDataStructure Summary { get; set; } - - public class TimelineDataStructure { - [JsonPropertyName("events")] - public List<StateEventResponse> Events { get; set; } - - [JsonPropertyName("prev_batch")] - public string PrevBatch { get; set; } - - [JsonPropertyName("limited")] - public bool Limited { get; set; } - } - - public class UnreadNotificationsDataStructure { - [JsonPropertyName("notification_count")] - public int NotificationCount { get; set; } - - [JsonPropertyName("highlight_count")] - public int HighlightCount { get; set; } - } - - public class SummaryDataStructure { - [JsonPropertyName("m.heroes")] - public List<string> Heroes { get; set; } - - [JsonPropertyName("m.invited_member_count")] - public int InvitedMemberCount { get; set; } - - [JsonPropertyName("m.joined_member_count")] - public int JoinedMemberCount { get; set; } - } - } - - public class InvitedRoomDataStructure { - [JsonPropertyName("invite_state")] - public EventList InviteState { get; set; } - } - } -} - -public class EventList { - [JsonPropertyName("events")] - public List<StateEventResponse> Events { get; set; } -} diff --git a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs deleted file mode 100644 index 3521a51..0000000 --- a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.StateEventTypes; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Core.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/MatrixRoomUtils.Core/Interfaces/IStateEventType.cs b/MatrixRoomUtils.Core/Interfaces/IStateEventType.cs deleted file mode 100644 index 053f50c..0000000 --- a/MatrixRoomUtils.Core/Interfaces/IStateEventType.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MatrixRoomUtils.Core.Interfaces; - -public interface IStateEventType { - -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs b/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs deleted file mode 100644 index 1de9885..0000000 --- a/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace MatrixRoomUtils.Core.Interfaces.Services; - -public interface IStorageProvider { - // save all children of a type with reflection - public Task SaveAllChildrenAsync<T>(string key, T value) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveAllChildren<T>(key, value)!"); - throw new NotImplementedException(); - } - - // load all children of a type with reflection - public Task<T?> LoadAllChildrenAsync<T>(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadAllChildren<T>(key)!"); - throw new NotImplementedException(); - } - - - public Task SaveObjectAsync<T>(string key, T value) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveObject<T>(key, value)!"); - throw new NotImplementedException(); - } - - // load - public Task<T?> LoadObjectAsync<T>(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadObject<T>(key)!"); - throw new NotImplementedException(); - } - - // check if exists - public Task<bool> ObjectExistsAsync(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement ObjectExists(key)!"); - throw new NotImplementedException(); - } - - // get all keys - public Task<List<string>> GetAllKeysAsync() { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement GetAllKeys()!"); - throw new NotImplementedException(); - } - - - // delete - public Task DeleteObjectAsync(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement DeleteObject(key)!"); - throw new NotImplementedException(); - } - - // save stream - public Task SaveStreamAsync(string key, Stream stream) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveStream(key, stream)!"); - throw new NotImplementedException(); - } - - // load stream - public Task<Stream?> LoadStreamAsync(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadStream(key)!"); - throw new NotImplementedException(); - } -} diff --git a/MatrixRoomUtils.Core/MatrixException.cs b/MatrixRoomUtils.Core/MatrixException.cs deleted file mode 100644 index a469a62..0000000 --- a/MatrixRoomUtils.Core/MatrixException.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; - -namespace MatrixRoomUtils.Core; - -public class MatrixException : Exception { - [JsonPropertyName("errcode")] - public string ErrorCode { get; set; } - - [JsonPropertyName("error")] - public string Error { get; set; } - - [JsonPropertyName("soft_logout")] - public bool? SoftLogout { get; set; } - - [JsonPropertyName("retry_after_ms")] - public int? RetryAfterMs { get; set; } - - public string RawContent { get; set; } - - public override string Message => - $"{ErrorCode}: {ErrorCode switch { - // common - "M_FORBIDDEN" => $"You do not have permission to perform this action: {Error}", - "M_UNKNOWN_TOKEN" => $"The access token specified was not recognised: {Error}{(SoftLogout == true ? " (soft logout)" : "")}", - "M_MISSING_TOKEN" => $"No access token was specified: {Error}", - "M_BAD_JSON" => $"Request contained valid JSON, but it was malformed in some way: {Error}", - "M_NOT_JSON" => $"Request did not contain valid JSON: {Error}", - "M_NOT_FOUND" => $"The requested resource was not found: {Error}", - "M_LIMIT_EXCEEDED" => $"Too many requests have been sent in a short period of time. Wait a while then try again: {Error}", - "M_UNRECOGNISED" => $"The server did not recognise the request: {Error}", - "M_UNKOWN" => $"The server encountered an unexpected error: {Error}", - // endpoint specific - "M_UNAUTHORIZED" => $"The request did not contain valid authentication information for the target of the request: {Error}", - "M_USER_DEACTIVATED" => $"The user ID associated with the request has been deactivated: {Error}", - "M_USER_IN_USE" => $"The user ID associated with the request is already in use: {Error}", - "M_INVALID_USERNAME" => $"The requested user ID is not valid: {Error}", - "M_ROOM_IN_USE" => $"The room alias requested is already taken: {Error}", - "M_INVALID_ROOM_STATE" => $"The room associated with the request is not in a valid state to perform the request: {Error}", - "M_THREEPID_IN_USE" => $"The threepid requested is already associated with a user ID on this server: {Error}", - "M_THREEPID_NOT_FOUND" => $"The threepid requested is not associated with any user ID: {Error}", - "M_THREEPID_AUTH_FAILED" => $"The provided threepid and/or token was invalid: {Error}", - "M_THREEPID_DENIED" => $"The homeserver does not permit the third party identifier in question: {Error}", - "M_SERVER_NOT_TRUSTED" => $"The homeserver does not trust the identity server: {Error}", - "M_UNSUPPORTED_ROOM_VERSION" => $"The room version is not supported: {Error}", - "M_INCOMPATIBLE_ROOM_VERSION" => $"The room version is incompatible: {Error}", - "M_BAD_STATE" => $"The request was invalid because the state was invalid: {Error}", - "M_GUEST_ACCESS_FORBIDDEN" => $"Guest access is forbidden: {Error}", - "M_CAPTCHA_NEEDED" => $"Captcha needed: {Error}", - "M_CAPTCHA_INVALID" => $"Captcha invalid: {Error}", - "M_MISSING_PARAM" => $"Missing parameter: {Error}", - "M_INVALID_PARAM" => $"Invalid parameter: {Error}", - "M_TOO_LARGE" => $"The request or entity was too large: {Error}", - "M_EXCLUSIVE" => $"The resource being requested is reserved by an application service, or the application service making the request has not created the resource: {Error}", - "M_RESOURCE_LIMIT_EXCEEDED" => $"Exceeded resource limit: {Error}", - "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM" => $"Cannot leave server notice room: {Error}", - _ => $"Unknown error: {new { ErrorCode, Error, SoftLogout, RetryAfterMs }.ToJson(ignoreNull: true)}" - }}"; -} diff --git a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj b/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj deleted file mode 100644 index 3571eab..0000000 --- a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj +++ /dev/null @@ -1,14 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <ImplicitUsings>enable</ImplicitUsings> - <Nullable>enable</Nullable> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> - <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> - </ItemGroup> - -</Project> diff --git a/MatrixRoomUtils.Core/MessagesResponse.cs b/MatrixRoomUtils.Core/MessagesResponse.cs deleted file mode 100644 index 7a303bc..0000000 --- a/MatrixRoomUtils.Core/MessagesResponse.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core; - -public class MessagesResponse { - [JsonPropertyName("start")] - public string Start { get; set; } - - [JsonPropertyName("end")] - public string? End { get; set; } - - [JsonPropertyName("chunk")] - public List<StateEventResponse> Chunk { get; set; } = new(); - - [JsonPropertyName("state")] - public List<StateEventResponse> State { get; set; } = new(); -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/RemoteHomeServer.cs b/MatrixRoomUtils.Core/RemoteHomeServer.cs deleted file mode 100644 index e6c28c3..0000000 --- a/MatrixRoomUtils.Core/RemoteHomeServer.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Services; - -namespace MatrixRoomUtils.Core; - -public class RemoteHomeServer : IHomeServer { - public RemoteHomeServer(string canonicalHomeServerDomain) { - HomeServerDomain = canonicalHomeServerDomain; - _httpClient = new MatrixHttpClient(); - _httpClient.Timeout = TimeSpan.FromSeconds(5); - } - -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomDeleteRequest.cs b/MatrixRoomUtils.Core/Responses/Admin/AdminRoomDeleteRequest.cs deleted file mode 100644 index 5605329..0000000 --- a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomDeleteRequest.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses.Admin; - -public class AdminRoomDeleteRequest { - [JsonPropertyName("new_room_user_id")] - public string? NewRoomUserId { get; set; } - [JsonPropertyName("room_name")] - public string? RoomName { get; set; } - [JsonPropertyName("block")] - public bool Block { get; set; } - [JsonPropertyName("purge")] - public bool Purge { get; set; } - [JsonPropertyName("message")] - public string? Message { get; set; } - [JsonPropertyName("force_purge")] - public bool ForcePurge { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomListingResult.cs b/MatrixRoomUtils.Core/Responses/Admin/AdminRoomListingResult.cs deleted file mode 100644 index d6da859..0000000 --- a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomListingResult.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses.Admin; - -public class AdminRoomListingResult { - [JsonPropertyName("offset")] - public int Offset { get; set; } - - [JsonPropertyName("total_rooms")] - public int TotalRooms { get; set; } - - [JsonPropertyName("next_batch")] - public int? NextBatch { get; set; } - - [JsonPropertyName("prev_batch")] - public int? PrevBatch { get; set; } - - [JsonPropertyName("rooms")] - public List<AdminRoomListingResultRoom> Rooms { get; set; } = new(); - - public class AdminRoomListingResultRoom { - [JsonPropertyName("room_id")] - public string RoomId { get; set; } - - [JsonPropertyName("name")] - public string? Name { get; set; } - - [JsonPropertyName("canonical_alias")] - public string? CanonicalAlias { get; set; } - - [JsonPropertyName("joined_members")] - public int JoinedMembers { get; set; } - - [JsonPropertyName("joined_local_members")] - public int JoinedLocalMembers { get; set; } - - [JsonPropertyName("version")] - public string Version { get; set; } - - [JsonPropertyName("creator")] - public string Creator { get; set; } - - [JsonPropertyName("encryption")] - public string? Encryption { get; set; } - - [JsonPropertyName("federatable")] - public bool Federatable { get; set; } - - [JsonPropertyName("public")] - public bool Public { get; set; } - - [JsonPropertyName("join_rules")] - public string? JoinRules { get; set; } - - [JsonPropertyName("guest_access")] - public string? GuestAccess { get; set; } - - [JsonPropertyName("history_visibility")] - public string? HistoryVisibility { get; set; } - - [JsonPropertyName("state_events")] - public int StateEvents { get; set; } - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs b/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs deleted file mode 100644 index 540a323..0000000 --- a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Reflection; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.StateEventTypes; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Core.Responses; - -public class CreateRoomRequest { - [JsonIgnore] public CreationContentBaseType _creationContentBaseType; - - public CreateRoomRequest() => _creationContentBaseType = new CreationContentBaseType(this); - - [JsonPropertyName("name")] - public string Name { get; set; } = null!; - - [JsonPropertyName("room_alias_name")] - public string RoomAliasName { get; set; } = null!; - - //we dont want to use this, we want more control - // [JsonPropertyName("preset")] - // public string Preset { get; set; } = null!; - - [JsonPropertyName("initial_state")] - public List<StateEvent> InitialState { get; set; } = null!; - - [JsonPropertyName("visibility")] - public string Visibility { get; set; } = null!; - - [JsonPropertyName("power_level_content_override")] - public RoomPowerLevelEventData PowerLevelContentOverride { get; set; } = null!; - - [JsonPropertyName("creation_content")] - public JsonObject CreationContent { get; set; } = new(); - - /// <summary> - /// For use only when you can't use the CreationContent property - /// </summary> - - public StateEvent this[string event_type, string event_key = ""] { - get { - var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key); - if (stateEvent == null) { - InitialState.Add(stateEvent = new StateEvent { - Type = event_type, - StateKey = event_key, - TypedContent = Activator.CreateInstance( - StateEvent.KnownStateEventTypes.FirstOrDefault(x => - x.GetCustomAttributes<MatrixEventAttribute>()? - .Any(y => y.EventName == event_type) ?? false) ?? typeof(object) - ) - }); - } - return stateEvent; - } - set { - var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key); - if (stateEvent == null) - InitialState.Add(value); - else - InitialState[InitialState.IndexOf(stateEvent)] = value; - } - } - - public Dictionary<string, string> Validate() { - Dictionary<string, string> errors = new(); - if (!Regex.IsMatch(RoomAliasName, @"[a-zA-Z0-9_\-]+$")) - errors.Add("room_alias_name", - "Room alias name must only contain letters, numbers, underscores, and hyphens."); - - return errors; - } -} diff --git a/MatrixRoomUtils.Core/Responses/CreationContentBaseType.cs b/MatrixRoomUtils.Core/Responses/CreationContentBaseType.cs deleted file mode 100644 index 743c552..0000000 --- a/MatrixRoomUtils.Core/Responses/CreationContentBaseType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses; - -public class CreationContentBaseType { - private readonly CreateRoomRequest createRoomRequest; - - public CreationContentBaseType(CreateRoomRequest createRoomRequest) => this.createRoomRequest = createRoomRequest; - - [JsonPropertyName("type")] - public string Type { - get => (string)createRoomRequest.CreationContent["type"]; - set { - if (value is "null" or "") createRoomRequest.CreationContent.Remove("type"); - else createRoomRequest.CreationContent["type"] = value; - } - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/LoginResponse.cs b/MatrixRoomUtils.Core/Responses/LoginResponse.cs deleted file mode 100644 index 239ea03..0000000 --- a/MatrixRoomUtils.Core/Responses/LoginResponse.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses; - -public class LoginResponse { - [JsonPropertyName("access_token")] - public string AccessToken { get; set; } - - [JsonPropertyName("device_id")] - public string DeviceId { get; set; } - - [JsonPropertyName("home_server")] - public string Homeserver { get; set; } - - [JsonPropertyName("user_id")] - public string UserId { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/StateEventResponse.cs b/MatrixRoomUtils.Core/Responses/StateEventResponse.cs deleted file mode 100644 index a7f9187..0000000 --- a/MatrixRoomUtils.Core/Responses/StateEventResponse.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.Responses; - -public class StateEventResponse : StateEvent { - [JsonPropertyName("origin_server_ts")] - public ulong OriginServerTs { get; set; } - - [JsonPropertyName("room_id")] - public string RoomId { get; set; } - - [JsonPropertyName("sender")] - public string Sender { get; set; } - - [JsonPropertyName("unsigned")] - public UnsignedData? Unsigned { get; set; } - - [JsonPropertyName("event_id")] - public string EventId { get; set; } - - [JsonPropertyName("user_id")] - public string UserId { get; set; } - - [JsonPropertyName("replaces_state")] - public string ReplacesState { get; set; } - - public class UnsignedData { - [JsonPropertyName("age")] - public ulong? Age { get; set; } - - [JsonPropertyName("redacted_because")] - public object? RedactedBecause { get; set; } - - [JsonPropertyName("transaction_id")] - public string? TransactionId { get; set; } - - [JsonPropertyName("replaces_state")] - public string? ReplacesState { get; set; } - - [JsonPropertyName("prev_sender")] - public string? PrevSender { get; set; } - - [JsonPropertyName("prev_content")] - public JsonObject? PrevContent { get; set; } - } -} diff --git a/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs b/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs deleted file mode 100644 index eced379..0000000 --- a/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Web; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Core.RoomTypes; - -public class GenericRoom { - internal readonly AuthenticatedHomeServer _homeServer; - internal readonly MatrixHttpClient _httpClient; - - public GenericRoom(AuthenticatedHomeServer homeServer, string roomId) { - _homeServer = homeServer; - _httpClient = homeServer._httpClient; - RoomId = roomId; - if (GetType() != typeof(SpaceRoom)) - AsSpace = new SpaceRoom(homeServer, RoomId); - } - - public string RoomId { get; set; } - - [Obsolete("", true)] - public async Task<JsonElement?> GetStateAsync(string type, string stateKey = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/state"; - if (!string.IsNullOrEmpty(type)) url += $"/{type}"; - if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}"; - return await _httpClient.GetFromJsonAsync<JsonElement>(url); - } - - public async IAsyncEnumerable<StateEventResponse?> GetFullStateAsync() { - var res = await _httpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/state"); - var result = - JsonSerializer.DeserializeAsyncEnumerable<StateEventResponse>(await res.Content.ReadAsStreamAsync()); - await foreach (var resp in result) { - yield return resp; - } - } - - public async Task<T?> GetStateAsync<T>(string type, string stateKey = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/state"; - if (!string.IsNullOrEmpty(type)) url += $"/{type}"; - if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}"; - try { -#if DEBUG && false - var resp = await _httpClient.GetFromJsonAsync<JsonObject>(url); - try { - _homeServer._httpClient.PostAsJsonAsync( - "http://localhost:5116/validate/" + typeof(T).AssemblyQualifiedName, resp); - } - catch (Exception e) { - Console.WriteLine("[!!] Checking state response failed: " + e); - } - - return resp.Deserialize<T>(); -#else - var resp = await _httpClient.GetFromJsonAsync<T>(url); - return resp; -#endif - } - catch (MatrixException e) { - if (e is not { ErrorCode: "M_NOT_FOUND" }) { - throw; - } - - Console.WriteLine(e); - return default; - } - } - - public async Task<MessagesResponse> GetMessagesAsync(string from = "", int limit = 10, string dir = "b", - string filter = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/messages?from={from}&limit={limit}&dir={dir}"; - if (!string.IsNullOrEmpty(filter)) url += $"&filter={filter}"; - var res = await _httpClient.GetFromJsonAsync<MessagesResponse>(url); - return res ?? new MessagesResponse(); - } - - public async Task<string> GetNameAsync() { - try { - var res = await GetStateAsync<RoomNameEventData>("m.room.name"); - return res?.Name ?? RoomId; - } - catch (MatrixException e) { - return $"{RoomId} ({e.ErrorCode})"; - } - } - - public async Task JoinAsync(string[]? homeservers = null, string? reason = null) { - var join_url = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(RoomId)}"; - Console.WriteLine($"Calling {join_url} 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 { - reason - }); - } - - public async IAsyncEnumerable<StateEventResponse> GetMembersAsync(bool joinedOnly = true) { - var res = GetFullStateAsync(); - await foreach (var member in res) { - if (member.Type != "m.room.member") continue; - if (joinedOnly && (member.TypedContent as RoomMemberEventData).Membership is not "join") continue; - yield return member; - } - } - - public async Task<List<string>> GetAliasesAsync() { - var res = await GetStateAsync<RoomAliasEventData>("m.room.aliases"); - return res.Aliases; - } - - public async Task<CanonicalAliasEventData?> GetCanonicalAliasAsync() => - await GetStateAsync<CanonicalAliasEventData>("m.room.canonical_alias"); - - public async Task<RoomTopicEventData?> GetTopicAsync() => - await GetStateAsync<RoomTopicEventData>("m.room.topic"); - - public async Task<RoomAvatarEventData?> GetAvatarUrlAsync() => - await GetStateAsync<RoomAvatarEventData>("m.room.avatar"); - - public async Task<JoinRulesEventData> GetJoinRuleAsync() => - await GetStateAsync<JoinRulesEventData>("m.room.join_rules"); - - public async Task<HistoryVisibilityEventData?> GetHistoryVisibilityAsync() => - await GetStateAsync<HistoryVisibilityEventData>("m.room.history_visibility"); - - public async Task<GuestAccessEventData?> GetGuestAccessAsync() => - await GetStateAsync<GuestAccessEventData>("m.room.guest_access"); - - public async Task<RoomCreateEventData> GetCreateEventAsync() => - await GetStateAsync<RoomCreateEventData>("m.room.create"); - - public async Task<string?> GetRoomType() { - var res = await GetStateAsync<RoomCreateEventData>("m.room.create"); - return res.Type; - } - - public async Task ForgetAsync() => - await _httpClient.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 { - reason - }); - - public async Task KickAsync(string userId, string? reason = null) => - await _httpClient.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", - new UserIdAndReason() { UserId = userId, Reason = reason }); - - public async Task UnbanAsync(string userId) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban", - new UserIdAndReason() { UserId = userId }); - - public async Task<EventIdResponse> SendStateEventAsync(string eventType, object content) => - await (await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content)) - .Content.ReadFromJsonAsync<EventIdResponse>(); - - public async Task<EventIdResponse> SendMessageEventAsync(string eventType, RoomMessageEventData content) { - var res = await _httpClient.PutAsJsonAsync( - $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(), content); - var resu = await res.Content.ReadFromJsonAsync<EventIdResponse>(); - return resu; - } - - public async Task<EventIdResponse> SendFileAsync(string eventType, string fileName, Stream fileStream) { - var content = new MultipartFormDataContent(); - content.Add(new StreamContent(fileStream), "file", fileName); - var res = await - ( - await _httpClient.PutAsync( - $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(), - content - ) - ) - .Content.ReadFromJsonAsync<EventIdResponse>(); - return res; - } - - public readonly SpaceRoom AsSpace; -} diff --git a/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs b/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs deleted file mode 100644 index 1b93064..0000000 --- a/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core.RoomTypes; - -public class SpaceRoom : GenericRoom { - private readonly AuthenticatedHomeServer _homeServer; - private readonly GenericRoom _room; - - public SpaceRoom(AuthenticatedHomeServer homeServer, string roomId) : base(homeServer, roomId) { - _homeServer = homeServer; - } - - private static SemaphoreSlim _semaphore = new(1, 1); - public async IAsyncEnumerable<GenericRoom> GetRoomsAsync(bool includeRemoved = false) { - await _semaphore.WaitAsync(); - var rooms = new List<GenericRoom>(); - var state = GetFullStateAsync(); - 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); - } - _semaphore.Release(); - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs b/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs deleted file mode 100644 index 4bc785a..0000000 --- a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Responses; -using Microsoft.Extensions.Logging; - -namespace MatrixRoomUtils.Core.Services; - -public class HomeserverProviderService { - private readonly TieredStorageService _tieredStorageService; - private readonly ILogger<HomeserverProviderService> _logger; - private readonly HomeserverResolverService _homeserverResolverService; - - public HomeserverProviderService(TieredStorageService tieredStorageService, - ILogger<HomeserverProviderService> logger, HomeserverResolverService homeserverResolverService) { - Console.WriteLine("Homeserver provider service instantiated!"); - _tieredStorageService = tieredStorageService; - _logger = logger; - _homeserverResolverService = homeserverResolverService; - logger.LogDebug( - $"New HomeserverProviderService created with TieredStorageService<{string.Join(", ", tieredStorageService.GetType().GetProperties().Select(x => x.Name))}>!"); - } - - private static Dictionary<string, SemaphoreSlim> _authenticatedHomeserverSemaphore = new(); - private static Dictionary<string, AuthenticatedHomeServer> _authenticatedHomeServerCache = new(); - - public async Task<AuthenticatedHomeServer> GetAuthenticatedWithToken(string homeserver, string accessToken, - string? overrideFullDomain = null) { - SemaphoreSlim sem = _authenticatedHomeserverSemaphore.GetOrCreate(homeserver+accessToken, _ => new SemaphoreSlim(1, 1)); - await sem.WaitAsync(); - if (_authenticatedHomeServerCache.ContainsKey(homeserver+accessToken)) { - sem.Release(); - 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); - hs._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - - hs.WhoAmI = (await hs._httpClient.GetFromJsonAsync<WhoAmIResponse>("/_matrix/client/v3/account/whoami"))!; - - _authenticatedHomeServerCache[homeserver+accessToken] = hs; - sem.Release(); - - return hs; - } - - public async Task<RemoteHomeServer> GetRemoteHomeserver(string homeserver, string? overrideFullDomain = null) { - var hs = new RemoteHomeServer(homeserver); - 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); - return hs; - } - - public async Task<LoginResponse> Login(string homeserver, string user, string password, - string? overrideFullDomain = null) { - var hs = await GetRemoteHomeserver(homeserver, overrideFullDomain); - var payload = new LoginRequest { - Identifier = new() { User = user }, - Password = password - }; - var resp = await hs._httpClient.PostAsJsonAsync("/_matrix/client/v3/login", payload); - 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/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs b/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs deleted file mode 100644 index 5856000..0000000 --- a/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using Microsoft.Extensions.Logging; - -namespace MatrixRoomUtils.Core.Services; - -public class HomeserverResolverService { - private readonly MatrixHttpClient _httpClient = new(); - private readonly ILogger<HomeserverResolverService> _logger; - - private static readonly Dictionary<string, string> _wellKnownCache = new(); - private static readonly Dictionary<string, SemaphoreSlim> _wellKnownSemaphores = new(); - - public HomeserverResolverService(ILogger<HomeserverResolverService> logger) { - _logger = logger; - } - - public async Task<string> ResolveHomeserverFromWellKnown(string homeserver) { - var res = await _resolveHomeserverFromWellKnown(homeserver); - if (!res.StartsWith("http")) res = "https://" + res; - if (res.EndsWith(":443")) res = res.Substring(0, res.Length - 4); - return res; - } - - private async Task<string> _resolveHomeserverFromWellKnown(string homeserver) { - if (homeserver is null) throw new ArgumentNullException(nameof(homeserver)); - SemaphoreSlim sem = _wellKnownSemaphores.GetOrCreate(homeserver, _ => new SemaphoreSlim(1, 1)); - await sem.WaitAsync(); - if (_wellKnownCache.ContainsKey(homeserver)) { - sem.Release(); - return _wellKnownCache[homeserver]; - } - - string? result = null; - _logger.LogInformation($"Attempting to resolve homeserver: {homeserver}"); - result ??= await _tryResolveFromClientWellknown(homeserver); - result ??= await _tryResolveFromServerWellknown(homeserver); - result ??= await _tryCheckIfDomainHasHomeserver(homeserver); - - if (result is not null) { - _logger.LogInformation($"Resolved homeserver: {homeserver} -> {result}"); - _wellKnownCache[homeserver] = result; - sem.Release(); - return result; - } - - throw new InvalidDataException($"Failed to resolve homeserver for {homeserver}! Is it online and configured correctly?"); - } - - private async Task<string?> _tryResolveFromClientWellknown(string homeserver) { - if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; - if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/client")) { - var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{homeserver}/.well-known/matrix/client"); - var hs = resp.GetProperty("m.homeserver").GetProperty("base_url").GetString(); - return hs; - } - - _logger.LogInformation("No client well-known..."); - return null; - } - - private async Task<string?> _tryResolveFromServerWellknown(string homeserver) { - if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; - if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/server")) { - var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{homeserver}/.well-known/matrix/server"); - var hs = resp.GetProperty("m.server").GetString(); - return hs; - } - - _logger.LogInformation("No server well-known..."); - return null; - } - - private async Task<string?> _tryCheckIfDomainHasHomeserver(string homeserver) { - _logger.LogInformation($"Checking if {homeserver} hosts a homeserver..."); - if (await _httpClient.CheckSuccessStatus($"{homeserver}/_matrix/client/versions")) - return homeserver; - _logger.LogInformation("No homeserver on shortname..."); - return null; - } - - private async Task<string?> _tryCheckIfSubDomainHasHomeserver(string homeserver, string subdomain) { - homeserver = homeserver.Replace("https://", $"https://{subdomain}."); - return await _tryCheckIfDomainHasHomeserver(homeserver); - } -} diff --git a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs b/MatrixRoomUtils.Core/Services/ServiceInstaller.cs deleted file mode 100644 index bd5b1bd..0000000 --- a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MatrixRoomUtils.Core.Extensions; -using Microsoft.Extensions.DependencyInjection; - -namespace MatrixRoomUtils.Core.Services; - -public static class ServiceInstaller { - - public static IServiceCollection AddRoryLibMatrixServices(this IServiceCollection services, RoryLibMatrixConfiguration? config = null) { - //Check required services - if (!services.Any(x => x.ServiceType == typeof(TieredStorageService))) - throw new Exception("[MRUCore/DI] No TieredStorageService has been registered!"); - //Add config - if(config is not null) - services.AddSingleton(config); - else { - services.AddSingleton(new RoryLibMatrixConfiguration()); - } - //Add services - services.AddSingleton<HomeserverProviderService>(); - services.AddSingleton<HomeserverResolverService>(); - // services.AddScoped<MatrixHttpClient>(); - return services; - } - - -} - -public class RoryLibMatrixConfiguration { - public string AppName { get; set; } = "Rory&::LibMatrix"; -} diff --git a/MatrixRoomUtils.Core/Services/TieredStorageService.cs b/MatrixRoomUtils.Core/Services/TieredStorageService.cs deleted file mode 100644 index 2f27443..0000000 --- a/MatrixRoomUtils.Core/Services/TieredStorageService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using MatrixRoomUtils.Core.Interfaces.Services; - -namespace MatrixRoomUtils.Core.Services; - -public class TieredStorageService { - public IStorageProvider CacheStorageProvider { get; } - public IStorageProvider DataStorageProvider { get; } - - public TieredStorageService(IStorageProvider cacheStorageProvider, IStorageProvider dataStorageProvider) { - CacheStorageProvider = cacheStorageProvider; - DataStorageProvider = dataStorageProvider; - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEvent.cs b/MatrixRoomUtils.Core/StateEvent.cs deleted file mode 100644 index 785c637..0000000 --- a/MatrixRoomUtils.Core/StateEvent.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Diagnostics; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.StateEventTypes; - -namespace MatrixRoomUtils.Core; - -public class StateEvent { - public static List<Type> KnownStateEventTypes = - new ClassCollector<IStateEventType>().ResolveFromAllAccessibleAssemblies(); - - public static Type GetStateEventType(string type) { - if (type == "m.receipt") { - return typeof(Dictionary<string, JsonObject>); - } - - var eventType = KnownStateEventTypes.FirstOrDefault(x => - x.GetCustomAttributes<MatrixEventAttribute>()?.Any(y => y.EventName == type) ?? false); - - return eventType ?? typeof(object); - } - - public object TypedContent { - get { - try { - return RawContent.Deserialize(GetType)!; - } - catch (JsonException e) { - Console.WriteLine(e); - Console.WriteLine("Content:\n" + ObjectExtensions.ToJson(RawContent)); - } - - return null; - } - set => RawContent = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.Serialize(value)); - } - - [JsonPropertyName("state_key")] - public string StateKey { get; set; } = ""; - - private string _type; - - [JsonPropertyName("type")] - public string Type { - get => _type; - set { - _type = value; - // if (RawContent is not null && this is StateEventResponse stateEventResponse) { - // if (File.Exists($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json")) return; - // var x = GetType.Name; - // } - } - } - - [JsonPropertyName("replaces_state")] - public string? ReplacesState { get; set; } - - private JsonObject? _rawContent; - - [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; - // } - } - } - - [JsonIgnore] - public Type GetType { - get { - var type = GetStateEventType(Type); - - //special handling for some types - // if (type == typeof(RoomEmotesEventData)) { - // RawContent["emote"] = RawContent["emote"]?.AsObject() ?? new JsonObject(); - // } - // - // if (this is StateEventResponse stateEventResponse) { - // if (type == null || type == typeof(object)) { - // Console.WriteLine($"Warning: unknown event type '{Type}'!"); - // Console.WriteLine(RawContent.ToJson()); - // Directory.CreateDirectory($"unknown_state_events/{Type}"); - // File.WriteAllText($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json", - // RawContent.ToJson()); - // Console.WriteLine($"Saved to unknown_state_events/{Type}/{stateEventResponse.EventId}.json"); - // } - // else if (RawContent is not null && RawContent.FindExtraJsonObjectFields(type)) { - // Directory.CreateDirectory($"unknown_state_events/{Type}"); - // File.WriteAllText($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json", - // RawContent.ToJson()); - // Console.WriteLine($"Saved to unknown_state_events/{Type}/{stateEventResponse.EventId}.json"); - // } - // } - - return type; - } - } - - //debug - public string dtype { - get { - var res = GetType().Name switch { - "StateEvent`1" => $"StateEvent", - _ => GetType().Name - }; - return res; - } - } - - public string cdtype => TypedContent.GetType().Name; -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Common/MjolnirShortcodeEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Common/MjolnirShortcodeEventData.cs deleted file mode 100644 index 66dcdb9..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Common/MjolnirShortcodeEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Common; - -[MatrixEvent(EventName = "org.matrix.mjolnir.shortcode")] -public class MjolnirShortcodeEventData : IStateEventType { - [JsonPropertyName("shortcode")] - public string? Shortcode { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs deleted file mode 100644 index c263a3a..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Common; - -[MatrixEvent(EventName = "im.ponies.room_emotes")] -public class RoomEmotesEventData : IStateEventType { - [JsonPropertyName("emoticons")] - public Dictionary<string, EmoticonData>? Emoticons { get; set; } - - [JsonPropertyName("images")] - public Dictionary<string, EmoticonData>? 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/MatrixRoomUtils.Core/StateEventTypes/Spec/CanonicalAliasEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/CanonicalAliasEventData.cs deleted file mode 100644 index 354f99d..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/CanonicalAliasEventData.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.canonical_alias")] -public class CanonicalAliasEventData : IStateEventType { - [JsonPropertyName("alias")] - public string? Alias { get; set; } - [JsonPropertyName("alt_aliases")] - public string[]? AltAliases { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/GuestAccessEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/GuestAccessEventData.cs deleted file mode 100644 index c5b92ad..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/GuestAccessEventData.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.guest_access")] -public class GuestAccessEventData : IStateEventType { - [JsonPropertyName("guest_access")] - public string GuestAccess { get; set; } - - public bool IsGuestAccessEnabled { - get => GuestAccess == "can_join"; - set => GuestAccess = value ? "can_join" : "forbidden"; - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/HistoryVisibilityEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/HistoryVisibilityEventData.cs deleted file mode 100644 index e0785b9..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/HistoryVisibilityEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.history_visibility")] -public class HistoryVisibilityEventData : IStateEventType { - [JsonPropertyName("history_visibility")] - public string HistoryVisibility { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/JoinRulesEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/JoinRulesEventData.cs deleted file mode 100644 index f5410dc..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/JoinRulesEventData.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.join_rules")] -public class JoinRulesEventData : IStateEventType { - private static string Public = "public"; - private static string Invite = "invite"; - private static string Knock = "knock"; - - [JsonPropertyName("join_rule")] - public string JoinRule { get; set; } - - [JsonPropertyName("allow")] - public List<string> Allow { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/PolicyRuleStateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/PolicyRuleStateEventData.cs deleted file mode 100644 index ef94cff..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/PolicyRuleStateEventData.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.policy.rule.user")] -[MatrixEvent(EventName = "m.policy.rule.server")] -[MatrixEvent(EventName = "org.matrix.mjolnir.rule.server")] -public class PolicyRuleStateEventData : IStateEventType { - /// <summary> - /// Entity this ban applies to, can use * and ? as globs. - /// </summary> - [JsonPropertyName("entity")] - public string Entity { get; set; } - - /// <summary> - /// Reason this user is banned - /// </summary> - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - /// <summary> - /// Suggested action to take - /// </summary> - [JsonPropertyName("recommendation")] - public string? Recommendation { get; set; } - - /// <summary> - /// Expiry time in milliseconds since the unix epoch, or null if the ban has no expiry. - /// </summary> - [JsonPropertyName("support.feline.policy.expiry.rev.2")] //stable prefix: expiry, msc pending - public long? Expiry { get; set; } - - //utils - /// <summary> - /// Readable expiry time, provided for easy interaction - /// </summary> - [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 { - /// <summary> - /// Ban this user - /// </summary> - public static string Ban = "m.ban"; - - /// <summary> - /// Mute this user - /// </summary> - public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/PresenceStateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/PresenceStateEventData.cs deleted file mode 100644 index c5eb2ea..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/PresenceStateEventData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.presence")] -public class PresenceStateEventData : IStateEventType { - [JsonPropertyName("presence")] - 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")] - public string StatusMessage { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/ProfileResponseEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/ProfileResponseEventData.cs deleted file mode 100644 index f3a0ce9..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/ProfileResponseEventData.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -public class ProfileResponseEventData : IStateEventType { - [JsonPropertyName("avatar_url")] - public string? AvatarUrl { get; set; } = ""; - - [JsonPropertyName("displayname")] - public string? DisplayName { get; set; } = ""; -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAliasEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAliasEventData.cs deleted file mode 100644 index 611e8a2..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAliasEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.alias")] -public class RoomAliasEventData : IStateEventType { - [JsonPropertyName("aliases")] - public List<string>? Aliases { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs deleted file mode 100644 index a14e4c5..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.avatar")] -public class RoomAvatarEventData : IStateEventType { - [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/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs deleted file mode 100644 index 6127028..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.create")] -public class RoomCreateEventData : IStateEventType { - [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/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomEncryptionEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomEncryptionEventData.cs deleted file mode 100644 index c473082..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomEncryptionEventData.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.encryption")] -public class RoomEncryptionEventData : IStateEventType { - [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; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMemberEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMemberEventData.cs deleted file mode 100644 index a543a2f..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMemberEventData.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.member")] -public class RoomMemberEventData : IStateEventType { - [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; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMessageEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMessageEventData.cs deleted file mode 100644 index 2c56b88..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMessageEventData.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.message")] -public class RoomMessageEventData : IStateEventType { - [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; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomNameEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomNameEventData.cs deleted file mode 100644 index e5b7d59..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomNameEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.name")] -public class RoomNameEventData : IStateEventType { - [JsonPropertyName("name")] - public string? Name { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPinnedEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPinnedEventData.cs deleted file mode 100644 index d84e962..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPinnedEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.pinned_events")] -public class RoomPinnedEventData : IStateEventType { - [JsonPropertyName("pinned")] - public string[]? PinnedEvents { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs deleted file mode 100644 index 1cde660..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.power_levels")] -public class RoomPowerLevelEventData : IStateEventType { - [JsonPropertyName("ban")] - public int Ban { get; set; } // = 50; - - [JsonPropertyName("events_default")] - public int EventsDefault { get; set; } // = 0; - - [JsonPropertyName("events")] - public Dictionary<string, int> Events { get; set; } // = null!; - - [JsonPropertyName("invite")] - public int Invite { get; set; } // = 50; - - [JsonPropertyName("kick")] - public int Kick { get; set; } // = 50; - - [JsonPropertyName("notifications")] - public NotificationsPL NotificationsPl { get; set; } // = null!; - - [JsonPropertyName("redact")] - public int Redact { get; set; } // = 50; - - [JsonPropertyName("state_default")] - public int StateDefault { get; set; } // = 50; - - [JsonPropertyName("users")] - public Dictionary<string, int> Users { get; set; } // = null!; - - [JsonPropertyName("users_default")] - public int 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 class NotificationsPL { - [JsonPropertyName("room")] - public int Room { get; set; } = 50; - } - - public bool IsUserAdmin(string userId) { - return Users.TryGetValue(userId, out var level) && level >= Events.Max(x=>x.Value); - } - - public bool UserHasPermission(string userId, string eventType) { - return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault); - } -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTopicEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTopicEventData.cs deleted file mode 100644 index cdd62a1..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTopicEventData.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.topic")] -[MatrixEvent(EventName = "org.matrix.msc3765.topic", Legacy = true)] -public class RoomTopicEventData : IStateEventType { - [JsonPropertyName("topic")] - public string? Topic { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTypingEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTypingEventData.cs deleted file mode 100644 index 017a117..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTypingEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.typing")] -public class RoomTypingEventData : IStateEventType { - [JsonPropertyName("user_ids")] - public string[]? UserIds { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/ServerACLEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/ServerACLEventData.cs deleted file mode 100644 index 4b559c6..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/ServerACLEventData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.server_acl")] -public class ServerACLEventData : IStateEventType { - [JsonPropertyName("allow")] - public List<string> Allow { get; set; } // = null!; - - [JsonPropertyName("deny")] - public List<string> Deny { get; set; } // = null!; - - [JsonPropertyName("allow_ip_literals")] - public bool AllowIpLiterals { get; set; } // = false; -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceChildEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceChildEventData.cs deleted file mode 100644 index bb62d92..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceChildEventData.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.space.child")] -public class SpaceChildEventData : IStateEventType { - [JsonPropertyName("auto_join")] - public bool? AutoJoin { get; set; } - [JsonPropertyName("via")] - public string[]? Via { get; set; } - [JsonPropertyName("suggested")] - public bool? Suggested { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceParentEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceParentEventData.cs deleted file mode 100644 index a40f7ae..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceParentEventData.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.space.parent")] -public class SpaceParentEventData : IStateEventType { - [JsonPropertyName("via")] - public string[]? Via { get; set; } - - [JsonPropertyName("canonical")] - public bool? Canonical { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/UserIdAndReason.cs b/MatrixRoomUtils.Core/UserIdAndReason.cs deleted file mode 100644 index 3801077..0000000 --- a/MatrixRoomUtils.Core/UserIdAndReason.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core; - -internal class UserIdAndReason { - [JsonPropertyName("user_id")] - public string UserId { get; set; } - [JsonPropertyName("reason")] - public string? Reason { get; set; } -} \ No newline at end of file |