diff --git a/MatrixRoomUtils.Core/Extensions/ClassCollector.cs b/MatrixRoomUtils.Core/Extensions/ClassCollector.cs
index 9d3d3c0..d4ba838 100644
--- a/MatrixRoomUtils.Core/Extensions/ClassCollector.cs
+++ b/MatrixRoomUtils.Core/Extensions/ClassCollector.cs
@@ -19,12 +19,4 @@ public class ClassCollector<T> where T : class {
public List<Type> ResolveFromAssembly(Assembly assembly) => assembly.GetTypes()
.Where(x => x is { IsClass: true, IsAbstract: false } && x.GetInterfaces().Contains(typeof(T))).ToList();
- // {
- // List<Type> ret = new();
- // foreach (var x in assembly.GetTypes().Where(x => x is { IsClass: true, IsAbstract: false } && x.GetInterfaces().Contains(typeof(T))).ToList()) {
- // // Console.WriteLine($"[!!] Found class {x.FullName}");
- // ret.Add(x);
- // }
- // return ret;
- // }
-}
\ No newline at end of file
+}
diff --git a/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs b/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs
index 695e8e3..9ac9c6b 100644
--- a/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs
+++ b/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs
@@ -19,40 +19,42 @@ public static class HttpClientExtensions {
}
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");
+ 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);
- // var asm = Assembly.Load("Microsoft.AspNetCore.Components.WebAssembly");
- // var browserHttpHandlerType = asm.GetType("Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions", true);
- // var browserHttpHandlerMethod = browserHttpHandlerType.GetMethod("SetBrowserResponseStreamingEnabled", BindingFlags.Public | BindingFlags.Static);
- // browserHttpHandlerMethod?.Invoke(null, new object[] {request, true});
}
- catch (Exception e)
- {
+ 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}");
+ 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);
+ 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);
diff --git a/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs b/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs
index 36da644..7701c9e 100644
--- a/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs
+++ b/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs
@@ -3,37 +3,149 @@ 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([DisallowNull] this JsonElement? res, Type t) {
- var props = t.GetProperties();
- var unknownPropertyFound = false;
- foreach (var field in res.Value.EnumerateObject()) {
- if (props.Any(x => x.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name == field.Name)) continue;
- Console.WriteLine($"[!!] Unknown property {field.Name} in {t.Name}!");
+ 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;
}
- if (unknownPropertyFound) Console.WriteLine(res.Value.ToJson());
-
return unknownPropertyFound;
}
- public static bool FindExtraJsonObjectFields([DisallowNull] this JsonObject? res, Type t) {
- var props = t.GetProperties();
- var unknownPropertyFound = false;
- foreach (var field in res) {
- if (props.Any(x => x.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name == field.Key)) continue;
- Console.WriteLine($"[!!] Unknown property {field.Key} in {t.Name}!");
- unknownPropertyFound = true;
- // foreach (var propertyInfo in props) {
- // Console.WriteLine($"[!!] Known property {propertyInfo.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name} in {t.Name}!");
- // }
+
+ private static bool FindExtraJsonPropertyFieldsByValueKind(this JsonProperty field, Type containerType,
+ Type propertyType) {
+ if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
+ propertyType = propertyType.GetGenericArguments()[0];
}
- if (unknownPropertyFound) Console.WriteLine(res.ToJson());
+ 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 unknownPropertyFound;
+ 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)
+ );
}
-}
\ No newline at end of file
+}
diff --git a/MatrixRoomUtils.Core/Filters/SyncFilter.cs b/MatrixRoomUtils.Core/Filters/SyncFilter.cs
index 7957898..bc81101 100644
--- a/MatrixRoomUtils.Core/Filters/SyncFilter.cs
+++ b/MatrixRoomUtils.Core/Filters/SyncFilter.cs
@@ -4,47 +4,50 @@ namespace MatrixRoomUtils.Core.Filters;
public class SyncFilter {
[JsonPropertyName("account_data")]
- public AccountDataFilter? AccountData { get; set; }
+ public EventFilter? AccountData { get; set; }
[JsonPropertyName("presence")]
- public PresenceFilter? Presence { get; set; }
+ public EventFilter? Presence { get; set; }
[JsonPropertyName("room")]
public RoomFilter? Room { get; set; }
-}
-public class PresenceFilter {
- [JsonPropertyName("not_types")]
- public List<string>? NotTypes { get; set; }
-}
+ public class RoomFilter {
+ [JsonPropertyName("account_data")]
+ public StateFilter? AccountData { get; set; }
-public class RoomFilter {
- [JsonPropertyName("account_data")]
- public AccountDataFilter? AccountData { get; set; }
+ [JsonPropertyName("ephemeral")]
+ public StateFilter? Ephemeral { get; set; }
- [JsonPropertyName("ephemeral")]
- public EphemeralFilter? Ephemeral { get; set; }
+ [JsonPropertyName("state")]
+ public StateFilter? State { get; set; }
- public class EphemeralFilter {
- [JsonPropertyName("not_types")]
- public List<string>? NotTypes { get; set; }
- }
+ [JsonPropertyName("timeline")]
+ public StateFilter? Timeline { get; set; }
- [JsonPropertyName("state")]
- public StateFilter? State { get; set; }
- public class StateFilter {
- [JsonPropertyName("lazy_load_members")]
- public bool? LazyLoadMembers { get; set; }
+ public class StateFilter : EventFilter {
+ [JsonPropertyName("contains_url")]
+ public bool? ContainsUrl { get; set; }
- [JsonPropertyName("types")]
- public List<string>? Types { 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("timeline")]
- public TimelineFilter? Timeline { get; set; }
+ [JsonPropertyName("unread_thread_notifications")]
+ public bool? UnreadThreadNotifications { get; set; }
+ }
+ }
- public class TimelineFilter {
+ public class EventFilter {
[JsonPropertyName("limit")]
public int? Limit { get; set; }
@@ -53,10 +56,11 @@ public class RoomFilter {
[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; }
}
}
-
-public class AccountDataFilter {
- [JsonPropertyName("not_types")]
- public List<string>? NotTypes { get; set; }
-}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs b/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs
index be78a97..540a323 100644
--- a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs
+++ b/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs
@@ -31,7 +31,7 @@ public class CreateRoomRequest {
public string Visibility { get; set; } = null!;
[JsonPropertyName("power_level_content_override")]
- public PowerLevelEventData PowerLevelContentOverride { get; set; } = null!;
+ public RoomPowerLevelEventData PowerLevelContentOverride { get; set; } = null!;
[JsonPropertyName("creation_content")]
public JsonObject CreationContent { get; set; } = new();
diff --git a/MatrixRoomUtils.Core/Responses/StateEventResponse.cs b/MatrixRoomUtils.Core/Responses/StateEventResponse.cs
index 422a557..a7f9187 100644
--- a/MatrixRoomUtils.Core/Responses/StateEventResponse.cs
+++ b/MatrixRoomUtils.Core/Responses/StateEventResponse.cs
@@ -1,3 +1,4 @@
+using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using MatrixRoomUtils.Core.Interfaces;
@@ -25,20 +26,23 @@ public class StateEventResponse : StateEvent {
[JsonPropertyName("replaces_state")]
public string ReplacesState { get; set; }
- [JsonPropertyName("prev_content")]
- public dynamic PrevContent { get; set; }
-
public class UnsignedData {
[JsonPropertyName("age")]
public ulong? Age { get; set; }
- [JsonPropertyName("prev_content")]
- public dynamic? PrevContent { get; set; }
-
[JsonPropertyName("redacted_because")]
- public dynamic? RedactedBecause { get; set; }
+ 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; }
}
-}
\ No newline at end of file
+}
diff --git a/MatrixRoomUtils.Core/StateEvent.cs b/MatrixRoomUtils.Core/StateEvent.cs
index 1c0a1cf..785c637 100644
--- a/MatrixRoomUtils.Core/StateEvent.cs
+++ b/MatrixRoomUtils.Core/StateEvent.cs
@@ -14,6 +14,17 @@ 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 {
@@ -21,8 +32,9 @@ public class StateEvent {
}
catch (JsonException e) {
Console.WriteLine(e);
- Console.WriteLine("Content:\n"+ObjectExtensions.ToJson(RawContent));
+ Console.WriteLine("Content:\n" + ObjectExtensions.ToJson(RawContent));
}
+
return null;
}
set => RawContent = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.Serialize(value));
@@ -65,12 +77,7 @@ public class StateEvent {
[JsonIgnore]
public Type GetType {
get {
- if (Type == "m.receipt") {
- return typeof(Dictionary<string, JsonObject>);
- }
-
- var type = KnownStateEventTypes.FirstOrDefault(x =>
- x.GetCustomAttributes<MatrixEventAttribute>()?.Any(y => y.EventName == Type) ?? false);
+ var type = GetStateEventType(Type);
//special handling for some types
// if (type == typeof(RoomEmotesEventData)) {
@@ -94,7 +101,7 @@ public class StateEvent {
// }
// }
- return type ?? typeof(object);
+ return type;
}
}
diff --git a/MatrixRoomUtils.Core/StateEventStruct.cs b/MatrixRoomUtils.Core/StateEventStruct.cs
deleted file mode 100644
index cd301ac..0000000
--- a/MatrixRoomUtils.Core/StateEventStruct.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace MatrixRoomUtils.Core;
-
-public struct StateEventStruct {
- public object content { get; set; }
- public long origin_server_ts { get; set; }
- public string sender { get; set; }
- public string state_key { get; set; }
- public string type { get; set; }
- public string event_id { get; set; }
- public string user_id { get; set; }
- public string replaces_state { get; set; }
-}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs
index 633998c..c263a3a 100644
--- a/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs
+++ b/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs
@@ -2,25 +2,25 @@ using System.Text.Json.Serialization;
using MatrixRoomUtils.Core.Extensions;
using MatrixRoomUtils.Core.Interfaces;
-namespace MatrixRoomUtils.Core.StateEventTypes.Common;
+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 {
-
-}
\ No newline at end of file
+ public class PackInfo {
+
+ }
+}
diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs
index bab297b..a14e4c5 100644
--- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs
+++ b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs
@@ -2,17 +2,27 @@ using System.Text.Json.Serialization;
using MatrixRoomUtils.Core.Extensions;
using MatrixRoomUtils.Core.Interfaces;
-namespace MatrixRoomUtils.Core.StateEventTypes.Spec;
+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; }
}
-}
\ No newline at end of file
+}
diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs
index 8b85d69..6127028 100644
--- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs
+++ b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs
@@ -2,7 +2,7 @@ using System.Text.Json.Serialization;
using MatrixRoomUtils.Core.Extensions;
using MatrixRoomUtils.Core.Interfaces;
-namespace MatrixRoomUtils.Core.StateEventTypes.Spec;
+namespace MatrixRoomUtils.Core.StateEventTypes.Spec;
[MatrixEvent(EventName = "m.room.create")]
public class RoomCreateEventData : IStateEventType {
@@ -16,6 +16,12 @@ public class RoomCreateEventData : IStateEventType {
public RoomCreatePredecessor? Predecessor { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
-
- public class RoomCreatePredecessor { }
-}
\ No newline at end of file
+
+ 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/PowerLevelEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs
index 6846db4..1cde660 100644
--- a/MatrixRoomUtils.Core/StateEventTypes/Spec/PowerLevelEventData.cs
+++ b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs
@@ -5,7 +5,7 @@ using MatrixRoomUtils.Core.Interfaces;
namespace MatrixRoomUtils.Core.StateEventTypes.Spec;
[MatrixEvent(EventName = "m.room.power_levels")]
-public class PowerLevelEventData : IStateEventType {
+public class RoomPowerLevelEventData : IStateEventType {
[JsonPropertyName("ban")]
public int Ban { get; set; } // = 50;
@@ -35,14 +35,22 @@ public class PowerLevelEventData : IStateEventType {
[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;
}
-}
\ No newline at end of file
+
+ 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);
+ }
+}
|