diff --git a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs
index 502fe5b..be085c1 100644
--- a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs
+++ b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs
@@ -1,7 +1,9 @@
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
+using System.Text.Json.Nodes;
using MatrixRoomUtils.Core.Interfaces;
+using MatrixRoomUtils.Core.Responses;
namespace MatrixRoomUtils.Core;
@@ -72,6 +74,17 @@ public class AuthenticatedHomeServer : IHomeServer
}
+ public async Task<Room> CreateRoom(CreateRoomRequest creationEvent)
+ {
+ var res = await _httpClient.PostAsJsonAsync("/_matrix/client/r0/createRoom", creationEvent);
+ if (!res.IsSuccessStatusCode)
+ {
+ Console.WriteLine($"Failed to create room: {await res.Content.ReadAsStringAsync()}");
+ throw new InvalidDataException($"Failed to create room: {await res.Content.ReadAsStringAsync()}");
+ }
+
+ return await GetRoom((await res.Content.ReadFromJsonAsync<JsonObject>())!["room_id"]!.ToString()!);
+ }
@@ -83,12 +96,6 @@ public class AuthenticatedHomeServer : IHomeServer
{
_authenticatedHomeServer = authenticatedHomeServer;
}
-
-
-
-
-
-
-
}
+
}
diff --git a/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs b/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs
new file mode 100644
index 0000000..cce71dd
--- /dev/null
+++ b/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs
@@ -0,0 +1,15 @@
+namespace MatrixRoomUtils.Core.Extensions;
+
+public static class DictionaryExtensions
+{
+ public static bool ChangeKey<TKey, TValue>(this IDictionary<TKey, TValue> dict,
+ TKey oldKey, TKey newKey)
+ {
+ TValue value;
+ if (!dict.Remove(oldKey, out value))
+ return false;
+
+ dict[newKey] = value; // or dict.Add(newKey, value) depending on ur comfort
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs
index 9f7bfee..bae55e7 100644
--- a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs
+++ b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs
@@ -93,7 +93,7 @@ public class IHomeServer
{
while (_profileCache[mxid] == null)
{
- Console.WriteLine($"Waiting for profile cache for {mxid}, currently {_profileCache[mxid]?.ToJson()} within {_profileCache.Count} profiles...");
+ Console.WriteLine($"Waiting for profile cache for {mxid}, currently {_profileCache[mxid]?.ToJson() ?? "null"} within {_profileCache.Count} profiles...");
await Task.Delay(Random.Shared.Next(50, 500));
}
return _profileCache[mxid];
diff --git a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs b/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs
index 6949b1a..5df99f7 100644
--- a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs
+++ b/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs
@@ -2,6 +2,7 @@ using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
+using MatrixRoomUtils.Core.Extensions;
namespace MatrixRoomUtils.Core.Responses;
@@ -26,6 +27,22 @@ public class CreateRoomRequest
/// For use only when you can't use the CreationContent property
/// </summary>
+ public StateEvent this[string event_type, string event_key = ""]
+ {
+ get => InitialState.First(x => x.Type == event_type && x.StateKey == event_key);
+ set
+ {
+ var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key);
+ if (stateEvent == null)
+ {
+ InitialState.Add(value);
+ }
+ else
+ {
+ InitialState[InitialState.IndexOf(stateEvent)] = value;
+ }
+ }
+ }
//extra properties
[JsonIgnore]
@@ -116,52 +133,118 @@ public class CreateRoomRequest
}
}
- [JsonIgnore]
- public string GuestAccess
+ // [JsonIgnore]
+ // public string GuestAccess
+ // {
+ // get
+ // {
+ // var stateEvent = InitialState.FirstOrDefault(x => x.Type == "m.room.guest_access");
+ // if (stateEvent == null)
+ // {
+ // InitialState.Add(new StateEvent()
+ // {
+ // Type = "m.room.guest_access",
+ // Content = new JsonObject()
+ // {
+ // ["guest_access"] = "can_join"
+ // }
+ // });
+ // return "can_join";
+ // }
+ //
+ // return stateEvent.ContentAsJsonNode["guest_access"].GetValue<string>();
+ // }
+ // set
+ // {
+ // var stateEvent = InitialState.FirstOrDefault(x => x.Type == "m.room.guest_access");
+ // if (stateEvent == null)
+ // {
+ // InitialState.Add(new StateEvent()
+ // {
+ // Type = "m.room.guest_access",
+ // Content = new JsonObject()
+ // {
+ // ["guest_access"] = value
+ // }
+ // });
+ // }
+ // else
+ // {
+ // var v = stateEvent.ContentAsJsonNode;
+ // v["guest_access"] = value;
+ // stateEvent.ContentAsJsonNode = v;
+ // }
+ // }
+ // }
+
+ public ServerACL ServerACLs
{
get
{
- var stateEvent = InitialState.FirstOrDefault(x => x.Type == "m.room.guest_access");
+ var stateEvent = InitialState.FirstOrDefault(x => x.Type == "m.room.server_acl");
if (stateEvent == null)
{
InitialState.Add(new StateEvent()
{
- Type = "m.room.guest_access",
+ Type = "m.room.server_acl",
Content = new JsonObject()
{
- ["guest_access"] = "can_join"
+ ["allow"] = new JsonArray()
+ {
+ "*"
+ },
+ ["deny"] = new JsonArray()
}
});
- return "can_join";
+ return new ServerACL()
+ {
+ Allow = new List<string>()
+ {
+ "*"
+ },
+ Deny = new List<string>(),
+ AllowIpLiterals = true
+ };
}
-
- return stateEvent.ContentAsJsonNode["guest_access"].GetValue<string>();
+ return new ServerACL()
+ {
+ Allow = JsonSerializer.Deserialize<List<string>>(stateEvent.ContentAsJsonNode["allow"]),
+ Deny = JsonSerializer.Deserialize<List<string>>(stateEvent.ContentAsJsonNode["deny"]),
+ AllowIpLiterals = true
+ };
}
set
{
- var stateEvent = InitialState.FirstOrDefault(x => x.Type == "m.room.guest_access");
+ Console.WriteLine($"Setting server acl to {value.ToJson()}");
+ var stateEvent = InitialState.FirstOrDefault(x => x.Type == "m.room.server_acl");
if (stateEvent == null)
{
InitialState.Add(new StateEvent()
{
- Type = "m.room.guest_access",
+ Type = "m.room.server_acl",
Content = new JsonObject()
{
- ["guest_access"] = value
+ ["allow"] = JsonArray.Parse(JsonSerializer.Serialize(value.Allow)),
+ ["deny"] = JsonArray.Parse(JsonSerializer.Serialize(value.Deny))
+ ["allow_ip_literals"] = value.AllowIpLiterals
}
});
}
else
{
var v = stateEvent.ContentAsJsonNode;
- v["guest_access"] = value;
+ v["allow"] = JsonArray.Parse(JsonSerializer.Serialize(value.Allow));
+ v["deny"] = JsonArray.Parse(JsonSerializer.Serialize(value.Deny));
+ v["allow_ip_literals"] = value.AllowIpLiterals;
stateEvent.ContentAsJsonNode = v;
+ Console.WriteLine($"v={v.ToJson()}");
+ Console.WriteLine($"stateEvent.ContentAsJsonNode={stateEvent.ContentAsJsonNode.ToJson()}");
}
}
}
- [JsonIgnore] public CreationContentBaseType _creationContentBaseType;
+ [JsonIgnore] public CreationContentBaseType _creationContentBaseType;
public CreateRoomRequest() => _creationContentBaseType = new(this);
@@ -214,4 +297,11 @@ public class PowerLevelEvent
public class NotificationsPL
{
[JsonPropertyName("room")] public int Room { get; set; } = 50;
+}
+
+public class ServerACL
+{
+ [JsonPropertyName("allow")] public List<string> Allow { get; set; } // = null!;
+ [JsonPropertyName("deny")] public List<string> Deny { get; set; } // = null!;
+ [JsonPropertyName("allow_ip_literals")] public bool AllowIpLiterals { get; set; } // = false;
}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Core/StateEvent.cs b/MatrixRoomUtils.Core/StateEvent.cs
index 2201587..f98d963 100644
--- a/MatrixRoomUtils.Core/StateEvent.cs
+++ b/MatrixRoomUtils.Core/StateEvent.cs
@@ -6,15 +6,12 @@ namespace MatrixRoomUtils.Core;
public class StateEvent
{
- [JsonPropertyName("content")]
- public dynamic Content { get; set; } = new{};
- [JsonPropertyName("state_key")]
- public string? StateKey { get; set; }
- [JsonPropertyName("type")]
- public string Type { get; set; }
- [JsonPropertyName("replaces_state")]
- public string? ReplacesState { get; set; }
-
+ [JsonPropertyName("content")] public dynamic Content { get; set; } = new { };
+
+ [JsonPropertyName("state_key")] public string StateKey { get; set; } = "";
+ [JsonPropertyName("type")] public string Type { get; set; }
+ [JsonPropertyName("replaces_state")] public string? ReplacesState { get; set; }
+
//extra properties
[JsonIgnore]
public JsonNode ContentAsJsonNode
@@ -22,17 +19,24 @@ public class StateEvent
get => JsonSerializer.SerializeToNode(Content);
set => Content = value;
}
+
+ public StateEvent<T> As<T>() where T : class
+ {
+ return (StateEvent<T>)this;
+ }
}
public class StateEvent<T> : StateEvent where T : class
{
- public new T content { get; set; }
-
-
- [JsonIgnore]
- public new JsonNode ContentAsJsonNode
+ public StateEvent()
{
- get => JsonSerializer.SerializeToNode(Content);
- set => Content = value.Deserialize<T>();
+ //import base content if not an empty object
+ if (base.Content.GetType() == typeof(T))
+ {
+ Console.WriteLine($"StateEvent<{typeof(T)}> created with base content of type {base.Content.GetType()}. Importing base content.");
+ Content = base.Content;
+ }
}
+ [JsonPropertyName("content")]
+ public T Content { get; set; }
}
\ No newline at end of file
|