about summary refs log tree commit diff
path: root/LibMatrix.EventTypes
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix.EventTypes')
-rw-r--r--LibMatrix.EventTypes/Common/MjolnirShortcodeEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/EventContent.cs22
-rw-r--r--LibMatrix.EventTypes/Interop/Draupnir/DraupnirProtectedRoomsData.cs11
-rw-r--r--LibMatrix.EventTypes/LibMatrix.EventTypes.csproj14
-rw-r--r--LibMatrix.EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/IgnoredUserListEventContent.cs31
-rw-r--r--LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs29
-rw-r--r--LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs73
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs21
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomEncryptionEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomGuestAccessEventContent.cs4
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs10
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomJoinRulesEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomMemberEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPinnedEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPolicyServerEventContent.cs11
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs23
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomRedactionEventContent.cs18
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs8
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTombstoneEventContent.cs14
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomTopicEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/Space/SpaceChildEventContent.cs2
-rw-r--r--LibMatrix.EventTypes/Spec/State/Space/SpaceParentEventContent.cs2
25 files changed, 242 insertions, 69 deletions
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 {