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/Common/Msc2545EmoteRoomsAccountDataEventContent.cs31
-rw-r--r--LibMatrix.EventTypes/EventContent.cs2
-rw-r--r--LibMatrix.EventTypes/LibMatrix.EventTypes.csproj8
-rw-r--r--LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs28
-rw-r--r--LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs81
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs5
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs7
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomPolicyServerEventContent.cs11
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomRedactionEventContent.cs18
-rw-r--r--LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs7
-rw-r--r--LibMatrix.EventTypes/deps.json0
12 files changed, 166 insertions, 34 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/Common/Msc2545EmoteRoomsAccountDataEventContent.cs b/LibMatrix.EventTypes/Common/Msc2545EmoteRoomsAccountDataEventContent.cs new file mode 100644
index 0000000..4fd5c29 --- /dev/null +++ b/LibMatrix.EventTypes/Common/Msc2545EmoteRoomsAccountDataEventContent.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 Msc2545EmoteRoomsAccountDataEventContent : EventContent { + public const string EventId = "im.ponies.emote_rooms"; + + [JsonPropertyName("rooms")] + public Dictionary<string, Dictionary<string, EnabledEmotePackEntry>> Rooms { get; set; } = new(); + + // Dummy type to provide easy access to the by-spec empty content + public class EnabledEmotePackEntry { + [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/EventContent.cs b/LibMatrix.EventTypes/EventContent.cs
index 07f56e2..d612e44 100644 --- a/LibMatrix.EventTypes/EventContent.cs +++ b/LibMatrix.EventTypes/EventContent.cs
@@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json; using System.Text.Json.Nodes; @@ -5,6 +6,7 @@ using System.Text.Json.Serialization; namespace LibMatrix.EventTypes; +[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "These get instantiated via reflection")] public abstract class EventContent { [JsonExtensionData] public Dictionary<string, object>? AdditionalData { get; set; } = []; diff --git a/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj b/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj
index 0924aba..31dfe16 100644 --- a/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj +++ b/LibMatrix.EventTypes/LibMatrix.EventTypes.csproj
@@ -1,14 +1,16 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net9.0</TargetFramework> + <TargetFramework>net10.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> - <PackageReference Include="ArcaneLibs" Version="1.0.0-preview.20250419-174711" Condition="'$(Configuration)' == 'Release'" /> - <ProjectReference Include="..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" Condition="'$(Configuration)' == 'Debug'"/> + <!-- <PackageReference Include="ArcaneLibs" Version="1.0.0-preview.20250806-011111" Condition="'$(Configuration)' == 'Release'" />--> + <!-- <ProjectReference Include="..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" Condition="'$(Configuration)' == 'Debug'"/>--> + <ProjectReference Include="..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" Condition="'$(ContinuousIntegrationBuild)'!='true'"/> + <PackageReference Include="ArcaneLibs" Version="*-*" Condition="'$(ContinuousIntegrationBuild)'=='true'"/> </ItemGroup> </Project> diff --git a/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs b/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs
index 9602bf3..d1cf8be 100644 --- a/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs +++ b/LibMatrix.EventTypes/Spec/RoomMessageEventContent.cs
@@ -34,9 +34,29 @@ public class RoomMessageEventContent : TimelineEventContent { [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")] @@ -47,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 6f8c194..36c94ae 100644 --- a/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
@@ -1,5 +1,6 @@ using System.Diagnostics; using System.Security.Cryptography; +using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using ArcaneLibs.Attributes; @@ -35,7 +36,6 @@ public class RoomPolicyRuleEventContent : PolicyRuleEventContent { [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; /// <summary> /// Entity this ban applies to, can use * and ? as globs. @@ -52,17 +52,7 @@ public abstract class PolicyRuleEventContent : EventContent { /// </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 @@ -93,29 +83,55 @@ public abstract class PolicyRuleEventContent : EventContent { } } + [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("?", "."), RegexOptions.Compiled); + public bool IsGlobRule() => !string.IsNullOrWhiteSpace(Entity) && (Entity.Contains('*') || Entity.Contains('?')); + public bool IsHashedRule() => string.IsNullOrWhiteSpace(Entity) && Hashes is not null; - public Regex? GetEntityRegex() => Entity is null ? null : new(Entity.Replace(".", "\\.").Replace("*", ".*").Replace("?", ".")); + public bool EntityMatches(string entity) { + if (string.IsNullOrWhiteSpace(entity)) return false; - public bool IsGlobRule() => - Entity != null - && (Entity.Contains('*') || Entity.Contains('?')); + 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; + } - public bool EntityMatches(string entity) => - Entity != null - && ( - Entity == entity - || ( - IsGlobRule() - ? GetEntityRegex()!.IsMatch(entity) - : entity == Entity - ) - ); + 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 string? GetSpecRecommendation() { + if (Recommendation is "m.ban" or "org.matrix.mjolnir.ban") + return PolicyRecommendationTypes.Ban; + + if (Recommendation is "m.mute" or "support.feline.policy.recommendation_mute") + return PolicyRecommendationTypes.Mute; + + if (Recommendation is "m.takedown" or "org.matrix.msc4204.takedown") + return PolicyRecommendationTypes.Takedown; + return Recommendation; } } @@ -130,6 +146,19 @@ public static class PolicyRecommendationTypes { /// Mute this user /// </summary> public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending + + /// <summary> + /// Take down the user with all means available + /// </summary> + public static string Takedown = "org.matrix.msc4204.takedown"; //stable prefix: m.takedown, msc pending +} + +public class PolicyHash { + [JsonPropertyName("sha256")] + public string? Sha256 { get; set; } + + [JsonExtensionData] + public Dictionary<string, object>? AdditionalProperties { get; set; } } // public class PolicySchemaDefinition { diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs
index 37b831a..8519889 100644 --- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomCreateEventContent.cs
@@ -12,9 +12,14 @@ public class RoomCreateEventContent : EventContent { [JsonPropertyName("room_version")] public string? RoomVersion { get; set; } + // missing in room version 11+ [JsonPropertyName("creator")] public string? Creator { get; set; } + // v12+ + [JsonPropertyName("additional_creators")] + public List<string>? AdditionalCreators { get; set; } + [JsonPropertyName("m.federate")] public bool? Federate { get; set; } diff --git a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs
index 16cfcb0..3b3ba34 100644 --- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomHistoryVisibilityEventContent.cs
@@ -8,4 +8,11 @@ public class RoomHistoryVisibilityEventContent : EventContent { [JsonPropertyName("history_visibility")] 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"; + public const string Joined = "joined"; + } } \ No newline at end of file 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/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 c492250..c7ad491 100644 --- a/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs +++ b/LibMatrix.EventTypes/Spec/State/RoomInfo/RoomServerACLEventContent.cs
@@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using System.Text.RegularExpressions; namespace LibMatrix.EventTypes.Spec.State.RoomInfo; @@ -14,4 +15,10 @@ public class RoomServerAclEventContent : EventContent { [JsonPropertyName("allow_ip_literals")] public bool AllowIpLiterals { get; set; } // = false; + + [JsonIgnore] + public List<Regex>? AllowRegexes => Allow?.ConvertAll(pattern => new Regex(pattern.Replace(".", "\\.").Replace("*", ".*").Replace("?", "."), RegexOptions.Compiled)) ?? []; + + [JsonIgnore] + public List<Regex>? DenyRegexes => Deny?.ConvertAll(pattern => new Regex(pattern.Replace(".", "\\.").Replace("*", ".*").Replace("?", "."), RegexOptions.Compiled)) ?? []; } \ No newline at end of file diff --git a/LibMatrix.EventTypes/deps.json b/LibMatrix.EventTypes/deps.json new file mode 100644
index 0000000..e69de29 --- /dev/null +++ b/LibMatrix.EventTypes/deps.json