diff --git a/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs b/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs
index a31cbbb..a1ebd79 100644
--- a/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs
+++ b/LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs
@@ -3,7 +3,7 @@ using System.Text.Json.Serialization;
namespace LibMatrix.EventTypes.Common;
[MatrixEvent(EventName = EventId)]
-public class MjolnirShortcodeEventContent : TimelineEventContent {
+public class MjolnirShortcodeEventContent : EventContent {
public const string EventId = "org.matrix.mjolnir.shortcode";
[JsonPropertyName("shortcode")]
diff --git a/LibMatrix.EventTypes/EventContent.cs b/LibMatrix.EventTypes/EventContent.cs
index c582cf2..07f56e2 100644
--- a/LibMatrix.EventTypes/EventContent.cs
+++ b/LibMatrix.EventTypes/EventContent.cs
@@ -1,10 +1,23 @@
+using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace LibMatrix.EventTypes;
-public abstract class EventContent;
+public abstract class EventContent {
+ [JsonExtensionData]
+ public Dictionary<string, object>? AdditionalData { get; set; } = [];
+
+ public static List<string> GetMatchingEventTypes<T>() where T : EventContent {
+ var type = typeof(T);
+ var eventTypes = new List<string>();
+ foreach (var attr in type.GetCustomAttributes<MatrixEventAttribute>(true)) {
+ eventTypes.Add(attr.EventName);
+ }
+ return eventTypes;
+ }
+}
public class UnknownEventContent : TimelineEventContent;
@@ -37,6 +50,13 @@ public abstract class TimelineEventContent : EventContent {
[JsonPropertyName("rel_type")]
public string? RelationType { get; set; }
+ // used for reactions
+ [JsonPropertyName("key")]
+ public string? Key { get; set; }
+
+ [JsonExtensionData]
+ public Dictionary<string, object>? AdditionalData { get; set; } = [];
+
public class EventInReplyTo {
[JsonPropertyName("event_id")]
public string? EventId { get; set; }
diff --git a/LibMatrix.EventTypes/Interop/Draupnir/DraupnirProtectedRoomsData.cs b/LibMatrix.EventTypes/Interop/Draupnir/DraupnirProtectedRoomsData.cs
new file mode 100644
index 0000000..1917239
--- /dev/null
+++ b/LibMatrix.EventTypes/Interop/Draupnir/DraupnirProtectedRoomsData.cs
@@ -0,0 +1,11 @@
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.EventTypes.Interop.Draupnir;
+
+[MatrixEvent(EventName = EventId)]
+public class DraupnirProtectedRoomsData : EventContent {
+ public const string EventId = "org.matrix.mjolnir.protected_rooms";
+
+ [JsonPropertyName("rooms")]
+ public List<string> Rooms { get; set; } = new();
+}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj b/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj
index 4276003..0924aba 100644
--- a/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj
+++ b/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj
@@ -1,22 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFramework>net8.0</TargetFramework>
+ <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
- <ProjectReference Condition="Exists('..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj')" Include="..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj"/>
- <!-- This is dangerous, but eases development since locking the version will drift out of sync without noticing,
- which causes build errors due to missing functions.
- Using the NuGet version in development is annoying due to delays between pushing and being able to consume.
- If you want to use a time-appropriate version of the library, recursively clone https://cgit.rory.gay/matrix/MatrixUtils.git
- instead, since this will be locked by the MatrixUtils project, which contains both LibMatrix and ArcaneLibs as a submodule. -->
- <PackageReference Condition="!Exists('..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj')" Include="ArcaneLibs" Version="*-preview*"/>
+ <PackageReference Include="ArcaneLibs" Version="1.0.0-preview.20250419-174711" Condition="'$(Configuration)' == 'Release'" />
+ <ProjectReference Include="..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" Condition="'$(Configuration)' == 'Debug'"/>
</ItemGroup>
- <Target Name="ArcaneLibsNugetWarning" AfterTargets="AfterBuild">
- <Warning Text="ArcaneLibs is being referenced from NuGet, which is dangerous. Please read the warning in LibMatrix.csproj!" Condition="!Exists('..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj')"/>
- </Target>
</Project>
diff --git a/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs b/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs
index 494936d..a7d431c 100644
--- a/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.Ephemeral;
[MatrixEvent(EventName = EventId)]
public class RoomTypingEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/IgnoredUserListEventContent.cs b/LibMatrix.EventTypes/Spec/IgnoredUserListEventContent.cs
new file mode 100644
index 0000000..59e17c9
--- /dev/null
+++ b/LibMatrix.EventTypes/Spec/IgnoredUserListEventContent.cs
@@ -0,0 +1,31 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.EventTypes.Spec;
+
+[MatrixEvent(EventName = EventId)]
+public class IgnoredUserListEventContent : EventContent {
+ public const string EventId = "m.ignored_user_list";
+
+ [JsonPropertyName("ignored_users")]
+ public Dictionary<string, IgnoredUserContent> IgnoredUsers { get; set; } = new();
+
+ // Dummy type to provide easy access to the by-spec empty content
+ public class IgnoredUserContent {
+ [JsonExtensionData]
+ public Dictionary<string, object>? AdditionalData { get; set; } = [];
+
+ public T? GetAdditionalData<T>(string key) where T : class {
+ if (AdditionalData == null || !AdditionalData.TryGetValue(key, out var value))
+ return null;
+
+ if (value is T tValue)
+ return tValue;
+ if (value is JsonElement jsonElement)
+ return jsonElement.Deserialize<T>();
+
+ throw new InvalidCastException($"Value for key '{key}' ({value.GetType()}) cannot be cast to type '{typeof(T)}'. Cannot continue.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs b/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs
index ae893f8..d1cf8be 100644
--- a/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs
@@ -29,13 +29,34 @@ public class RoomMessageEventContent : TimelineEventContent {
[JsonPropertyName("url")]
public string? Url { get; set; }
+ [JsonPropertyName("filename")]
public string? FileName { get; set; }
[JsonPropertyName("info")]
public FileInfoStruct? FileInfo { get; set; }
-
+
[JsonIgnore]
- public string BodyWithoutReplyFallback => Body.Split('\n').SkipWhile(x => x.StartsWith(">")).SkipWhile(x=>x.Trim().Length == 0).Aggregate((x, y) => $"{x}\n{y}");
+ public string BodyWithoutReplyFallback {
+ get {
+ var parts = Body
+ .Split('\n')
+ .SkipWhile(x => x.StartsWith(">"))
+ .SkipWhile(x => x.Trim().Length == 0)
+ .ToList();
+ return parts.Count > 0 ? parts.Aggregate((x, y) => $"{x}\n{y}") : Body;
+ }
+ }
+
+ [JsonPropertyName("m.mentions")]
+ public MentionsStruct? Mentions { get; set; }
+
+ public class MentionsStruct {
+ [JsonPropertyName("user_ids")]
+ public List<string>? Users { get; set; }
+
+ [JsonPropertyName("room")]
+ public bool? Room { get; set; }
+ }
public class FileInfoStruct {
[JsonPropertyName("mimetype")]
@@ -46,10 +67,10 @@ public class RoomMessageEventContent : TimelineEventContent {
[JsonPropertyName("thumbnail_url")]
public string? ThumbnailUrl { get; set; }
-
+
[JsonPropertyName("w")]
public int? Width { get; set; }
-
+
[JsonPropertyName("h")]
public int? Height { get; set; }
}
diff --git a/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
index 6006048..d75b19f 100644
--- a/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
@@ -1,5 +1,9 @@
+using System.Diagnostics;
+using System.Security.Cryptography;
using System.Text.Json.Serialization;
+using System.Text.RegularExpressions;
using ArcaneLibs.Attributes;
+using ArcaneLibs.Extensions;
namespace LibMatrix.EventTypes.Spec.State.Policy;
@@ -28,9 +32,9 @@ public class RoomPolicyRuleEventContent : PolicyRuleEventContent {
public const string EventId = "m.policy.rule.room";
}
+[DebuggerDisplay("""{GetType().Name.Replace("PolicyRuleEventContent", ""),nq} policy matching {Entity}, Reason: {Reason}""")]
public abstract class PolicyRuleEventContent : EventContent {
- public PolicyRuleEventContent() => Console.WriteLine($"init policy {GetType().Name}");
- private string? _reason;
+ // public PolicyRuleEventContent() => Console.WriteLine($"init policy {GetType().Name}");
/// <summary>
/// Entity this ban applies to, can use * and ? as globs.
@@ -40,24 +44,14 @@ public abstract class PolicyRuleEventContent : EventContent {
[FriendlyName(Name = "Entity")]
public string? Entity { get; set; }
- private bool init;
+ // private bool init;
/// <summary>
/// Reason this user is banned
/// </summary>
[JsonPropertyName("reason")]
[FriendlyName(Name = "Reason")]
- public virtual string? Reason {
- get =>
- // Console.WriteLine($"Read policy reason: {_reason}");
- _reason;
- set =>
- // Console.WriteLine($"Set policy reason: {value}");
- // if(init)
- // Console.WriteLine(string.Join('\n', Environment.StackTrace.Split('\n')[..5]));
- // init = true;
- _reason = value;
- }
+ public string? Reason { get; set; }
/// <summary>
/// Suggested action to take
@@ -79,6 +73,7 @@ public abstract class PolicyRuleEventContent : EventContent {
/// </summary>
[JsonPropertyName("gay.rory.matrix_room_utils.readable_expiry_time_utc")]
[FriendlyName(Name = "Expires at")]
+ [TableHide]
public DateTime? ExpiryDateTime {
get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime;
set {
@@ -86,6 +81,49 @@ public abstract class PolicyRuleEventContent : EventContent {
Expiry = ((DateTimeOffset)value).ToUnixTimeMilliseconds();
}
}
+
+ [JsonPropertyName("org.matrix.msc4205.hashes")]
+ [TableHide]
+ public PolicyHash? Hashes { get; set; }
+
+ public string GetDraupnir2StateKey() => Convert.ToBase64String(SHA256.HashData($"{Entity}{Recommendation}".AsBytes().ToArray()));
+
+ public Regex? GetEntityRegex() => Entity is null ? null : new(Entity.Replace(".", "\\.").Replace("*", ".*").Replace("?", "."));
+
+ public bool IsGlobRule() =>
+ !string.IsNullOrWhiteSpace(Entity)
+ && (Entity.Contains('*') || Entity.Contains('?'));
+
+ public bool EntityMatches(string entity) {
+ if (string.IsNullOrWhiteSpace(entity)) return false;
+
+ if (!string.IsNullOrWhiteSpace(Entity)) {
+ // Check if entity is equal regardless of glob check
+ var match = Entity == entity
+ || (IsGlobRule() && GetEntityRegex()!.IsMatch(entity));
+ if (match) return match;
+ }
+
+ if (Hashes is not null) {
+ if (!string.IsNullOrWhiteSpace(Hashes.Sha256)) {
+ var hash = SHA256.HashData(entity.AsBytes().ToArray());
+ var match = Convert.ToBase64String(hash) == Hashes.Sha256;
+ if (match) return match;
+ }
+ }
+
+ return false;
+ }
+
+ public string? GetNormalizedRecommendation() {
+ if (Recommendation is "m.ban" or "org.matrix.mjolnir.ban")
+ return PolicyRecommendationTypes.Ban;
+
+ if (Recommendation is "m.takedown" or "org.matrix.msc4204.takedown")
+ return "m.takedown";
+
+ return Recommendation;
+ }
}
public static class PolicyRecommendationTypes {
@@ -98,6 +136,13 @@ public static class PolicyRecommendationTypes {
/// Mute this user
/// </summary>
public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending
+
+ public static string Takedown = "m.takedown"; //unstable prefix: org.matrix.msc4204.takedown
+}
+
+public class PolicyHash {
+ [JsonPropertyName("sha256")]
+ public string? Sha256 { get; set; }
}
// public class PolicySchemaDefinition {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs
index 93f13ac..ee3234c 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomCanonicalAliasEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs
index c619d0e..37b831a 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs
@@ -1,8 +1,11 @@
+using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
+[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Deserialization, public API")]
+[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Deserialization, public API")]
public class RoomCreateEventContent : EventContent {
public const string EventId = "m.room.create";
@@ -15,17 +18,17 @@ public class RoomCreateEventContent : EventContent {
[JsonPropertyName("m.federate")]
public bool? Federate { get; set; }
- [JsonPropertyName("predecessor")]
- public RoomCreatePredecessor? Predecessor { 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; }
+public class RoomCreatePredecessor {
+ [JsonPropertyName("room_id")]
+ public string? RoomId { get; set; }
- [JsonPropertyName("event_id")]
- public string? EventId { get; set; }
- }
+ [JsonPropertyName("event_id")]
+ public string? EventId { get; set; }
}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs
index b49abfa..16209f0 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomEncryptionEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs
index a7811bf..1ba5a3f 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs
@@ -1,13 +1,13 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomGuestAccessEventContent : EventContent {
public const string EventId = "m.room.guest_access";
[JsonPropertyName("guest_access")]
- public string GuestAccess { get; set; }
+ public required string GuestAccess { get; set; }
[JsonIgnore]
public bool IsGuestAccessEnabled {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs
index 7676dad..8edf4a7 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs
@@ -1,11 +1,17 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomHistoryVisibilityEventContent : EventContent {
public const string EventId = "m.room.history_visibility";
[JsonPropertyName("history_visibility")]
- public string HistoryVisibility { get; set; }
+ public required string HistoryVisibility { get; set; }
+
+ public static class HistoryVisibilityTypes {
+ public const string WorldReadable = "world_readable";
+ public const string Invited = "invited";
+ public const string Shared = "shared";
+ }
}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs
index 349c8a7..03d994d 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomJoinRulesEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs
index b2d5596..b034425 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomMemberEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs
index 3ea5730..415c675 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomNameEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs
index b4474e9..7eee605 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
public class RoomPinnedEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPolicyServerEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPolicyServerEventContent.cs
new file mode 100644
index 0000000..80e254f
--- /dev/null
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPolicyServerEventContent.cs
@@ -0,0 +1,11 @@
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
+
+[MatrixEvent(EventName = EventId)]
+public class RoomPolicyServerEventContent : EventContent {
+ public const string EventId = "org.matrix.msc4284.policy";
+
+ [JsonPropertyName("via")]
+ public string? Via { get; set; }
+}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs
index 49a1b62..22fa3b7 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
@@ -20,7 +20,7 @@ public class RoomPowerLevelEventContent : EventContent {
public long? Kick { get; set; } = 50;
[JsonPropertyName("notifications")]
- public NotificationsPL? NotificationsPl { get; set; } // = null!;
+ public NotificationsPowerLevels? NotificationsPl { get; set; }
[JsonPropertyName("redact")]
public long? Redact { get; set; } = 50;
@@ -29,10 +29,10 @@ public class RoomPowerLevelEventContent : EventContent {
public long? StateDefault { get; set; } = 50;
[JsonPropertyName("events")]
- public Dictionary<string, long>? Events { get; set; } // = null!;
+ public Dictionary<string, long>? Events { get; set; }
[JsonPropertyName("users")]
- public Dictionary<string, long>? Users { get; set; } // = null!;
+ public Dictionary<string, long>? Users { get; set; }
[JsonPropertyName("users_default")]
public long? UsersDefault { get; set; } = 0;
@@ -42,27 +42,28 @@ public class RoomPowerLevelEventContent : EventContent {
[JsonPropertyName("historical")]
public long Historical { get; set; } // = 50;
- public class NotificationsPL {
+ public class NotificationsPowerLevels {
[JsonPropertyName("room")]
public long Room { get; set; } = 50;
}
public bool IsUserAdmin(string userId) {
ArgumentNullException.ThrowIfNull(userId);
- return Users.TryGetValue(userId, out var level) && level >= Events.Max(x => x.Value);
+ return GetUserPowerLevel(userId) >= Events?.Max(x => x.Value);
}
public bool UserHasTimelinePermission(string userId, string eventType) {
ArgumentNullException.ThrowIfNull(userId);
- return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault ?? 0);
+ return GetUserPowerLevel(userId) >= Events?.GetValueOrDefault(eventType, EventsDefault ?? 0);
}
- public bool UserHasStatePermission(string userId, string eventType) {
+ public bool UserHasStatePermission(string userId, string eventType, bool log = false) {
ArgumentNullException.ThrowIfNull(userId);
var userLevel = GetUserPowerLevel(userId);
var eventLevel = GetStateEventPowerLevel(eventType);
-
- Console.WriteLine($"{userId}={userLevel} >= {eventType}={eventLevel} = {userLevel >= eventLevel}");
+
+ if (log)
+ Console.WriteLine($"{userId}={userLevel} >= {eventType}={eventLevel} = {userLevel >= eventLevel}");
return userLevel >= eventLevel;
}
@@ -78,7 +79,7 @@ public class RoomPowerLevelEventContent : EventContent {
if (Events is null) return StateDefault ?? 0;
return Events.TryGetValue(eventType, out var level) ? level : StateDefault ?? 0;
}
-
+
public long GetTimelineEventPowerLevel(string eventType) {
ArgumentNullException.ThrowIfNull(eventType);
if (Events is null) return EventsDefault ?? 0;
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomRedactionEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomRedactionEventContent.cs
new file mode 100644
index 0000000..055f22d
--- /dev/null
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomRedactionEventContent.cs
@@ -0,0 +1,18 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
+
+[MatrixEvent(EventName = EventId)]
+public class RoomRedactionEventContent : EventContent {
+ public const string EventId = "m.room.redaction";
+
+ [JsonPropertyName("reason")]
+ public string? Reason { get; set; }
+
+ /// <summary>
+ /// Required in room version 11
+ /// </summary>
+ [JsonPropertyName("redacts")]
+ public string? Redacts { get; set; }
+}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs
index be83e37..c492250 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs
@@ -1,16 +1,16 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
-public class RoomServerACLEventContent : EventContent {
+public class RoomServerAclEventContent : EventContent {
public const string EventId = "m.room.server_acl";
[JsonPropertyName("allow")]
- public List<string>? Allow { get; set; } // = null!;
+ public List<string>? Allow { get; set; }
[JsonPropertyName("deny")]
- public List<string>? Deny { get; set; } // = null!;
+ public List<string>? Deny { get; set; }
[JsonPropertyName("allow_ip_literals")]
public bool AllowIpLiterals { get; set; } // = false;
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTombstoneEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTombstoneEventContent.cs
new file mode 100644
index 0000000..2c45c41
--- /dev/null
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTombstoneEventContent.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
+
+[MatrixEvent(EventName = EventId)]
+public class RoomTombstoneEventContent : EventContent {
+ public const string EventId = "m.room.tombstone";
+
+ [JsonPropertyName("body")]
+ public string Body { get; set; }
+
+ [JsonPropertyName("replacement_room")]
+ public string ReplacementRoom { get; set; }
+}
\ No newline at end of file
diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs
index 92fa75d..065c976 100644
--- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.RoomInfo;
[MatrixEvent(EventName = EventId)]
[MatrixEvent(EventName = "org.matrix.msc3765.topic", Legacy = true)]
diff --git a/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs b/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs
index d233be4..cd0f1f5 100644
--- a/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.Space;
[MatrixEvent(EventName = EventId)]
public class SpaceChildEventContent : EventContent {
diff --git a/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs b/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs
index 2ab79a4..f50797e 100644
--- a/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs
+++ b/LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace LibMatrix.EventTypes.Spec.State;
+namespace LibMatrix.EventTypes.Spec.State.Space;
[MatrixEvent(EventName = EventId)]
public class SpaceParentEventContent : EventContent {
|