about summary refs log tree commit diff
path: root/LibMatrix
diff options
context:
space:
mode:
authorEmma [it/its]@Rory& <root@rory.gay>2023-12-01 12:16:00 +0100
committerEmma [it/its]@Rory& <root@rory.gay>2023-12-01 12:16:00 +0100
commit71d115dc8e915a620dd935955ba980fcbe421dad (patch)
treeb836f5b0e1b5955bbc08443f8df6d078bd0fa7ea /LibMatrix
parentModeration bot work (diff)
downloadLibMatrix-71d115dc8e915a620dd935955ba980fcbe421dad.tar.xz
Cleanup, move ArcaneLibs to submodule instead of parent submodule
Diffstat (limited to 'LibMatrix')
-rw-r--r--LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs4
-rw-r--r--LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs4
-rw-r--r--LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs10
-rw-r--r--LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs23
-rw-r--r--LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs4
-rw-r--r--LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs1
-rw-r--r--LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs5
-rw-r--r--LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs2
-rw-r--r--LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs28
-rw-r--r--LibMatrix/Helpers/MessageFormatter.cs6
-rw-r--r--LibMatrix/Helpers/SyncHelper.cs2
-rw-r--r--LibMatrix/Helpers/SyncStateResolver.cs4
-rw-r--r--LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs14
-rw-r--r--LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs12
-rw-r--r--LibMatrix/Homeservers/RemoteHomeServer.cs12
-rw-r--r--LibMatrix/Interfaces/EventContent.cs2
-rw-r--r--LibMatrix/LibMatrix.csproj4
-rw-r--r--LibMatrix/MatrixException.cs2
-rw-r--r--LibMatrix/RoomTypes/GenericRoom.cs22
-rw-r--r--LibMatrix/Services/HomeserverProviderService.cs4
-rw-r--r--LibMatrix/Services/HomeserverResolverService.cs2
-rw-r--r--LibMatrix/StateEvent.cs5
-rw-r--r--LibMatrix/WhoAmIResponse.cs2
23 files changed, 96 insertions, 78 deletions
diff --git a/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs b/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs
index 558e4fc..8ffbca5 100644
--- a/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/Ephemeral/PresenceStateEventContent.cs
@@ -3,8 +3,10 @@ using LibMatrix.Interfaces;
 
 namespace LibMatrix.EventTypes.Spec.State;
 
-[MatrixEvent(EventName = "m.presence")]
+[MatrixEvent(EventName = EventId)]
 public class PresenceEventContent : EventContent {
+    public const string EventId = "m.presence";
+
     [JsonPropertyName("presence"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
     public string? Presence { get; set; }
     [JsonPropertyName("last_active_ago")]
diff --git a/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs b/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs
index 661cf63..b947096 100644
--- a/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/Ephemeral/RoomTypingEventContent.cs
@@ -3,8 +3,10 @@ using LibMatrix.Interfaces;
 
 namespace LibMatrix.EventTypes.Spec.State;
 
-[MatrixEvent(EventName = "m.typing")]
+[MatrixEvent(EventName = EventId)]
 public class RoomTypingEventContent : TimelineEventContent {
+    public const string EventId = "m.typing";
+
     [JsonPropertyName("user_ids")]
     public string[]? UserIds { get; set; }
 }
diff --git a/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs b/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs
index 8a22489..944ed99 100644
--- a/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/RoomMessageEventContent.cs
@@ -3,8 +3,10 @@ using LibMatrix.Interfaces;
 
 namespace LibMatrix.EventTypes.Spec;
 
-[MatrixEvent(EventName = "m.room.message")]
+[MatrixEvent(EventName = EventId)]
 public class RoomMessageEventContent : TimelineEventContent {
+    public const string EventId = "m.room.message";
+
     public RoomMessageEventContent(string? messageType = "m.notice", string? body = null) {
         MessageType = messageType;
         Body = body;
@@ -27,9 +29,9 @@ public class RoomMessageEventContent : TimelineEventContent {
     /// </summary>
     [JsonPropertyName("url")]
     public string? Url { get; set; }
-    
+
     public string? FileName { get; set; }
-    
+
     [JsonPropertyName("info")]
     public FileInfoStruct? FileInfo { get; set; }
 
@@ -41,5 +43,5 @@ public class RoomMessageEventContent : TimelineEventContent {
         [JsonPropertyName("thumbnail_url")]
         public string? ThumbnailUrl { get; set; }
     }
-    
+
 }
diff --git a/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs b/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
index 757a9e9..80d87d6 100644
--- a/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/State/Policy/PolicyRuleStateEventContent.cs
@@ -4,27 +4,34 @@ using LibMatrix.Interfaces;
 namespace LibMatrix.EventTypes.Spec.State;
 
 //spec
-[MatrixEvent(EventName = "m.policy.rule.server")] //spec
+[MatrixEvent(EventName = EventId)] //spec
 [MatrixEvent(EventName = "m.room.rule.server")] //???
 [MatrixEvent(EventName = "org.matrix.mjolnir.rule.server")] //legacy
-public class ServerPolicyRuleEventContent : PolicyRuleEventContent { }
+public class ServerPolicyRuleEventContent : PolicyRuleEventContent {
+    public const string EventId = "m.policy.rule.server";
+}
 
-[MatrixEvent(EventName = "m.policy.rule.user")] //spec
+[MatrixEvent(EventName = EventId)] //spec
 [MatrixEvent(EventName = "m.room.rule.user")] //???
 [MatrixEvent(EventName = "org.matrix.mjolnir.rule.user")] //legacy
-public class UserPolicyRuleEventContent : PolicyRuleEventContent { }
+public class UserPolicyRuleEventContent : PolicyRuleEventContent {
+    public const string EventId = "m.policy.rule.user";
+}
 
-[MatrixEvent(EventName = "m.policy.rule.room")] //spec
+[MatrixEvent(EventName = EventId)] //spec
 [MatrixEvent(EventName = "m.room.rule.room")] //???
 [MatrixEvent(EventName = "org.matrix.mjolnir.rule.room")] //legacy
-public class RoomPolicyRuleEventContent : PolicyRuleEventContent { }
+public class RoomPolicyRuleEventContent : PolicyRuleEventContent {
+    public const string EventId = "m.policy.rule.room";
+}
 
 public abstract class PolicyRuleEventContent : EventContent {
     /// <summary>
     ///     Entity this ban applies to, can use * and ? as globs.
+    ///     Policy is invalid if entity is null
     /// </summary>
     [JsonPropertyName("entity")]
-    public string Entity { get; set; }
+    public string? Entity { get; set; }
 
     /// <summary>
     ///     Reason this user is banned
@@ -65,4 +72,4 @@ public static class PolicyRecommendationTypes {
     ///     Mute this user
     /// </summary>
     public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending
-}
\ No newline at end of file
+}
diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs
index 28d525c..830386d 100644
--- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAliasEventContent.cs
@@ -3,8 +3,10 @@ using LibMatrix.Interfaces;
 
 namespace LibMatrix.EventTypes.Spec.State;
 
-[MatrixEvent(EventName = "m.room.alias")]
+[MatrixEvent(EventName = EventId)]
 public class RoomAliasEventContent : TimelineEventContent {
+    public const string EventId = "m.room.alias";
+
     [JsonPropertyName("aliases")]
     public List<string>? Aliases { get; set; }
 }
diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs
index fb05b2a..9c208ba 100644
--- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomAvatarEventContent.cs
@@ -6,6 +6,7 @@ namespace LibMatrix.EventTypes.Spec.State;
 [MatrixEvent(EventName = EventId)]
 public class RoomAvatarEventContent : TimelineEventContent {
     public const string EventId = "m.room.avatar";
+
     [JsonPropertyName("url")]
     public string? Url { get; set; }
 
diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs
index a5dec35..5ba253c 100644
--- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomCanonicalAliasEventContent.cs
@@ -3,10 +3,13 @@ using LibMatrix.Interfaces;
 
 namespace LibMatrix.EventTypes.Spec.State;
 
-[MatrixEvent(EventName = "m.room.canonical_alias")]
+[MatrixEvent(EventName = EventId)]
 public class RoomCanonicalAliasEventContent : TimelineEventContent {
+    public const string EventId = "m.room.canonical_alias";
+
     [JsonPropertyName("alias")]
     public string? Alias { get; set; }
+
     [JsonPropertyName("alt_aliases")]
     public string[]? AltAliases { get; set; }
 }
diff --git a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs
index 3eacd44..9ad67eb 100644
--- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomNameEventContent.cs
@@ -9,4 +9,4 @@ public class RoomNameEventContent : TimelineEventContent {
 
     [JsonPropertyName("name")]
     public string? Name { 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 6d01b8c..08f8ad5 100644
--- a/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs
+++ b/LibMatrix/EventTypes/Spec/State/RoomInfo/RoomPowerLevelEventContent.cs
@@ -13,9 +13,6 @@ public class RoomPowerLevelEventContent : TimelineEventContent {
     [JsonPropertyName("events_default")]
     public long? EventsDefault { get; set; } = 0;
 
-    [JsonPropertyName("events")]
-    public Dictionary<string, long>? Events { get; set; } // = null!;
-
     [JsonPropertyName("invite")]
     public long? Invite { get; set; } = 0;
 
@@ -31,6 +28,9 @@ public class RoomPowerLevelEventContent : TimelineEventContent {
     [JsonPropertyName("state_default")]
     public long? StateDefault { get; set; } = 50;
 
+    [JsonPropertyName("events")]
+    public Dictionary<string, long>? Events { get; set; } // = null!;
+
     [JsonPropertyName("users")]
     public Dictionary<string, long>? Users { get; set; } // = null!;
 
@@ -48,17 +48,22 @@ public class RoomPowerLevelEventContent : TimelineEventContent {
     }
 
     public bool IsUserAdmin(string userId) {
-        if(userId is null) throw new ArgumentNullException(nameof(userId));
+        if (userId is null) throw new ArgumentNullException(nameof(userId));
         return Users.TryGetValue(userId, out var level) && level >= Events.Max(x => x.Value);
     }
 
-    public bool UserHasPermission(string userId, string eventType) {
-        if(userId is null) throw new ArgumentNullException(nameof(userId));
+    public bool UserHasTimelinePermission(string userId, string eventType) {
+        if (userId is null) throw new ArgumentNullException(nameof(userId));
         return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault ?? 0);
     }
 
+    public bool UserHasStatePermission(string userId, string eventType) {
+        if (userId is null) throw new ArgumentNullException(nameof(userId));
+        return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, StateDefault ?? 50);
+    }
+
     public long GetUserPowerLevel(string userId) {
-        if(userId is null) throw new ArgumentNullException(nameof(userId));
+        if (userId is null) throw new ArgumentNullException(nameof(userId));
         return Users.TryGetValue(userId, out var level) ? level : UsersDefault ?? UsersDefault ?? 0;
     }
 
@@ -67,13 +72,8 @@ public class RoomPowerLevelEventContent : TimelineEventContent {
     }
 
     public void SetUserPowerLevel(string userId, long powerLevel) {
-        if(userId is null) throw new ArgumentNullException(nameof(userId));
+        if (userId is null) throw new ArgumentNullException(nameof(userId));
         Users ??= new();
-        if (Users.TryGetValue(userId, out var level)) {
-            Users[userId] = powerLevel;
-        }
-        else {
-            Users.Add(userId, powerLevel);
-        }
+        Users[userId] = powerLevel;
     }
 }
diff --git a/LibMatrix/Helpers/MessageFormatter.cs b/LibMatrix/Helpers/MessageFormatter.cs
index 3ebc9a2..03efeec 100644
--- a/LibMatrix/Helpers/MessageFormatter.cs
+++ b/LibMatrix/Helpers/MessageFormatter.cs
@@ -35,15 +35,15 @@ public static class MessageFormatter {
     public static string HtmlFormatMention(string id, string? displayName = null) {
         return $"<a href=\"https://matrix.to/#/{id}\">{displayName ?? id}</a>";
     }
-    
+
     public static string HtmlFormatMessageLink(string roomId, string eventId, string[]? servers = null, string? displayName = null) {
         if (servers is not { Length: > 0 }) servers = new[] { roomId.Split(':', 2)[1] };
         return $"<a href=\"https://matrix.to/#/{roomId}/{eventId}?via={string.Join("&via=", servers)}\">{displayName ?? eventId}</a>";
     }
 
-#region Extension functions
+    #region Extension functions
 
     public static RoomMessageEventContent ToMatrixMessage(this Exception e, string error) => FormatException(error, e);
 
-#endregion
+    #endregion
 }
diff --git a/LibMatrix/Helpers/SyncHelper.cs b/LibMatrix/Helpers/SyncHelper.cs
index a63b8bb..a05b915 100644
--- a/LibMatrix/Helpers/SyncHelper.cs
+++ b/LibMatrix/Helpers/SyncHelper.cs
@@ -125,4 +125,4 @@ public class SyncHelper(AuthenticatedHomeserverGeneric homeserver, ILogger? logg
     /// Event fired when an account data event is received
     /// </summary>
     public List<Func<StateEventResponse, Task>> AccountDataReceivedHandlers { get; } = new();
-}
\ No newline at end of file
+}
diff --git a/LibMatrix/Helpers/SyncStateResolver.cs b/LibMatrix/Helpers/SyncStateResolver.cs
index 0070d60..3482be3 100644
--- a/LibMatrix/Helpers/SyncStateResolver.cs
+++ b/LibMatrix/Helpers/SyncStateResolver.cs
@@ -74,7 +74,7 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge
         return oldState;
     }
 
-#region Merge rooms
+    #region Merge rooms
 
     private SyncResponse.RoomsDataStructure MergeRoomsDataStructure(SyncResponse.RoomsDataStructure oldState, SyncResponse.RoomsDataStructure newState) {
         oldState.Join ??= new();
@@ -170,5 +170,5 @@ public class SyncStateResolver(AuthenticatedHomeserverGeneric homeserver, ILogge
         return oldData;
     }
 
-#endregion
+    #endregion
 }
diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
index 288608d..e85ecd2 100644
--- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
+++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
@@ -136,7 +136,7 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke
         }
     }
 
-#region Utility Functions
+    #region Utility Functions
 
     public virtual async IAsyncEnumerable<GenericRoom> GetJoinedRoomsByType(string type) {
         var rooms = await GetJoinedRooms();
@@ -154,9 +154,9 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke
         }
     }
 
-#endregion
+    #endregion
 
-#region Account Data
+    #region Account Data
 
     public virtual async Task<T> GetAccountDataAsync<T>(string key) {
         // var res = await _httpClient.GetAsync($"/_matrix/client/v3/user/{UserId}/account_data/{key}");
@@ -177,7 +177,7 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke
         }
     }
 
-#endregion
+    #endregion
 
     public async Task UpdateProfileAsync(UserProfileResponse? newProfile, bool preserveCustomRoomProfile = true) {
         if (newProfile is null) return;
@@ -299,11 +299,11 @@ public class AuthenticatedHomeserverGeneric(string serverName, string accessToke
         return await res.Content.ReadFromJsonAsync<RoomIdResponse>() ?? throw new Exception("Failed to join room?");
     }
 
-#region Room Profile Utility
+    #region Room Profile Utility
 
     private async Task<KeyValuePair<string, RoomMemberEventContent>> GetOwnRoomProfileWithIdAsync(GenericRoom room) {
         return new KeyValuePair<string, RoomMemberEventContent>(room.RoomId, await room.GetStateAsync<RoomMemberEventContent>("m.room.member", WhoAmI.UserId!));
     }
 
-#endregion
-}
\ No newline at end of file
+    #endregion
+}
diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs
index 15e5b65..28ff775 100644
--- a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs
+++ b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs
@@ -52,29 +52,29 @@ public class AuthenticatedHomeserverSynapse : AuthenticatedHomeserverGeneric {
                             totalRooms--;
                             continue;
                         }
-                        if(!room.GuestAccess?.Contains(localFilter.GuestAccessContains) == true) {
+                        if (!room.GuestAccess?.Contains(localFilter.GuestAccessContains) == true) {
                             totalRooms--;
                             continue;
                         }
-                        if(!room.HistoryVisibility?.Contains(localFilter.HistoryVisibilityContains) == true) {
+                        if (!room.HistoryVisibility?.Contains(localFilter.HistoryVisibilityContains) == true) {
                             totalRooms--;
                             continue;
                         }
 
-                        if(localFilter.CheckFederation && room.Federatable != localFilter.Federatable) {
+                        if (localFilter.CheckFederation && room.Federatable != localFilter.Federatable) {
                             totalRooms--;
                             continue;
                         }
-                        if(localFilter.CheckPublic && room.Public != localFilter.Public) {
+                        if (localFilter.CheckPublic && room.Public != localFilter.Public) {
                             totalRooms--;
                             continue;
                         }
 
-                        if(room.JoinedMembers < localFilter.JoinedMembersGreaterThan || room.JoinedMembers > localFilter.JoinedMembersLessThan) {
+                        if (room.JoinedMembers < localFilter.JoinedMembersGreaterThan || room.JoinedMembers > localFilter.JoinedMembersLessThan) {
                             totalRooms--;
                             continue;
                         }
-                        if(room.JoinedLocalMembers < localFilter.JoinedLocalMembersGreaterThan || room.JoinedLocalMembers > localFilter.JoinedLocalMembersLessThan) {
+                        if (room.JoinedLocalMembers < localFilter.JoinedLocalMembersGreaterThan || room.JoinedLocalMembers > localFilter.JoinedLocalMembersLessThan) {
                             totalRooms--;
                             continue;
                         }
diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs
index 55a3a02..f8d61fd 100644
--- a/LibMatrix/Homeservers/RemoteHomeServer.cs
+++ b/LibMatrix/Homeservers/RemoteHomeServer.cs
@@ -68,7 +68,7 @@ public class RemoteHomeserver(string baseUrl) {
         return data;
     }
 
-#region Authentication
+    #region Authentication
 
     public async Task<LoginResponse> LoginAsync(string username, string password, string? deviceName = null) {
         var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/r0/login", new {
@@ -102,13 +102,13 @@ public class RemoteHomeserver(string baseUrl) {
         return data;
     }
 
-#endregion
+    #endregion
 
     public async Task<ServerVersionResponse> GetServerVersionAsync() {
         return await ServerHttpClient.GetFromJsonAsync<ServerVersionResponse>("/_matrix/federation/v1/version");
     }
-    
-    
+
+
     public string? ResolveMediaUri(string? mxcUri) {
         if (mxcUri is null) return null;
         if (mxcUri.StartsWith("https://")) return mxcUri;
@@ -120,11 +120,11 @@ public class ServerVersionResponse {
 
     [JsonPropertyName("server")]
     public ServerInfo Server { get; set; }
-    
+
     public class ServerInfo {
         [JsonPropertyName("name")]
         public string Name { get; set; }
-        
+
         [JsonPropertyName("version")]
         public string Version { get; set; }
     }
diff --git a/LibMatrix/Interfaces/EventContent.cs b/LibMatrix/Interfaces/EventContent.cs
index 1fb6974..76419a6 100644
--- a/LibMatrix/Interfaces/EventContent.cs
+++ b/LibMatrix/Interfaces/EventContent.cs
@@ -45,4 +45,4 @@ public abstract class TimelineEventContent : EventContent {
             public string RelType { get; set; }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/LibMatrix/LibMatrix.csproj b/LibMatrix/LibMatrix.csproj
index 690556f..afe06d7 100644
--- a/LibMatrix/LibMatrix.csproj
+++ b/LibMatrix/LibMatrix.csproj
@@ -16,13 +16,13 @@
     </ItemGroup>
 
     <ItemGroup>
-        <ProjectReference Condition="Exists('..\..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj')" Include="..\..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj"/>
+        <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://git.rory.gay/matrix/MatrixRoomUtils.git
                 instead, since this will be locked by the MatrixRoomUtils project, which contains both LibMatrix and ArcaneLibs as a submodule. -->
-        <PackageReference Condition="!Exists('..\..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj')" Include="ArcaneLibs" Version="*-preview*"/>
+        <PackageReference Condition="!Exists('..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj')" Include="ArcaneLibs" Version="*-preview*"/>
     </ItemGroup>
     
     <Target Name="ArcaneLibsNugetWarning" AfterTargets="AfterBuild">
diff --git a/LibMatrix/MatrixException.cs b/LibMatrix/MatrixException.cs
index f127abf..863c6d4 100644
--- a/LibMatrix/MatrixException.cs
+++ b/LibMatrix/MatrixException.cs
@@ -17,7 +17,7 @@ public class MatrixException : Exception {
     public int? RetryAfterMs { get; set; }
 
     public string RawContent { get; set; }
-    
+
     public string? GetAsJson() => new { ErrorCode, Error, SoftLogout, RetryAfterMs }.ToJson(ignoreNull: true);
 
 
diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs
index d26b1f8..a64e167 100644
--- a/LibMatrix/RoomTypes/GenericRoom.cs
+++ b/LibMatrix/RoomTypes/GenericRoom.cs
@@ -185,7 +185,7 @@ public class GenericRoom {
         Console.WriteLine($"Members call iterated in {sw.GetElapsedAndRestart()}");
     }
 
-#region Utility shortcuts
+    #region Utility shortcuts
 
     public async Task<EventIdResponse?> SendMessageEventAsync(RoomMessageEventContent content) =>
         await SendTimelineEventAsync("m.room.message", content);
@@ -253,9 +253,9 @@ public class GenericRoom {
         await Task.WhenAll(tasks);
     }
 
-#endregion
+    #endregion
 
-#region Simple calls
+    #region Simple calls
 
     public async Task ForgetAsync() =>
         await _httpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null);
@@ -283,9 +283,9 @@ public class GenericRoom {
         await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/invite", new UserIdAndReason(userId, reason));
     }
 
-#endregion
+    #endregion
 
-#region Events
+    #region Events
 
     public async Task<EventIdResponse?> SendStateEventAsync(string eventType, object content) =>
         await (await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content))
@@ -346,9 +346,9 @@ public class GenericRoom {
             $"/_matrix/client/v3/rooms/{RoomId}/redact/{eventToRedact}/{Guid.NewGuid()}", data)).Content.ReadFromJsonAsync<EventIdResponse>())!;
     }
 
-#endregion
+    #endregion
 
-#region Utilities
+    #region Utilities
 
     public async Task<Dictionary<string, List<string>>> GetMembersByHomeserverAsync(bool joinedOnly = true) {
         if (Homeserver is AuthenticatedHomeserverMxApiExtended mxaeHomeserver)
@@ -366,11 +366,11 @@ public class GenericRoom {
         return roomHomeservers;
     }
 
-#endregion
+    #endregion
 
     public readonly SpaceRoom AsSpace;
 
-#region Disband room
+    #region Disband room
 
     public async Task DisbandRoomAsync() {
         var states = GetFullStateAsync();
@@ -397,10 +397,10 @@ public class GenericRoom {
         }
     }
 
-#endregion
+    #endregion
 }
 
 public class RoomIdResponse {
     [JsonPropertyName("room_id")]
     public string RoomId { get; set; } = null!;
-}
\ No newline at end of file
+}
diff --git a/LibMatrix/Services/HomeserverProviderService.cs b/LibMatrix/Services/HomeserverProviderService.cs
index 5c8827c..a42077a 100644
--- a/LibMatrix/Services/HomeserverProviderService.cs
+++ b/LibMatrix/Services/HomeserverProviderService.cs
@@ -29,7 +29,7 @@ public class HomeserverProviderService(ILogger<HomeserverProviderService> logger
 
         var rhs = await RemoteHomeserver.Create(homeserver, proxy);
         var clientVersions = await rhs.GetClientVersionsAsync();
-        if(proxy is not null)
+        if (proxy is not null)
             Console.WriteLine($"Homeserver {homeserver} proxied via {proxy}...");
         Console.WriteLine($"{homeserver}: " + clientVersions.ToJson());
 
@@ -68,4 +68,4 @@ public class HomeserverProviderService(ILogger<HomeserverProviderService> logger
         var data = await resp.Content.ReadFromJsonAsync<LoginResponse>();
         return data!;
     }
-}
\ No newline at end of file
+}
diff --git a/LibMatrix/Services/HomeserverResolverService.cs b/LibMatrix/Services/HomeserverResolverService.cs
index 556bf86..f9f92d6 100644
--- a/LibMatrix/Services/HomeserverResolverService.cs
+++ b/LibMatrix/Services/HomeserverResolverService.cs
@@ -78,4 +78,4 @@ public class HomeserverResolverService(ILogger<HomeserverResolverService>? logge
         public string? Client { get; set; }
         public string? Server { get; set; }
     }
-}
\ No newline at end of file
+}
diff --git a/LibMatrix/StateEvent.cs b/LibMatrix/StateEvent.cs
index 3e8c4b5..6d69820 100644
--- a/LibMatrix/StateEvent.cs
+++ b/LibMatrix/StateEvent.cs
@@ -39,7 +39,7 @@ public class StateEvent {
     [JsonIgnore]
     public EventContent TypedContent {
         get {
-            if(Type == "m.receipt") {
+            if (Type == "m.receipt") {
                 return null!;
             }
             try {
@@ -181,8 +181,7 @@ public class StateEventResponse : StateEvent {
 
 [JsonSourceGenerationOptions(WriteIndented = true)]
 [JsonSerializable(typeof(ChunkedStateEventResponse))]
-internal partial class ChunkedStateEventResponseSerializerContext : JsonSerializerContext
-{
+internal partial class ChunkedStateEventResponseSerializerContext : JsonSerializerContext {
 }
 
 public class EventList {
diff --git a/LibMatrix/WhoAmIResponse.cs b/LibMatrix/WhoAmIResponse.cs
index 3884b1d..4eb5f2e 100644
--- a/LibMatrix/WhoAmIResponse.cs
+++ b/LibMatrix/WhoAmIResponse.cs
@@ -10,4 +10,4 @@ public class WhoAmIResponse {
     public string? DeviceId { get; set; }
     [JsonPropertyName("is_guest")]
     public bool? IsGuest { get; set; }
-}
\ No newline at end of file
+}