diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs
index bcfb629..04ce050 100644
--- a/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs
@@ -4,12 +4,12 @@ using ArcaneLibs.Extensions;
namespace LibMatrix.HomeserverEmulator.Services;
-public class HSEConfiguration {
- private static ILogger<HSEConfiguration> _logger;
- public static HSEConfiguration Current { get; set; }
+public class HseConfiguration {
+ private static ILogger<HseConfiguration> _logger;
+ public static HseConfiguration Current { get; set; }
[RequiresUnreferencedCode("Uses reflection binding")]
- public HSEConfiguration(ILogger<HSEConfiguration> logger, IConfiguration config, HostBuilderContext host) {
+ public HseConfiguration(ILogger<HseConfiguration> logger, IConfiguration config, HostBuilderContext host) {
Current = this;
_logger = logger;
logger.LogInformation("Loading configuration for environment: {}...", host.HostingEnvironment.EnvironmentName);
@@ -22,15 +22,15 @@ public class HSEConfiguration {
_logger.LogInformation("Configuration loaded: {}", this.ToJson());
}
- public string CacheStoragePath { get; set; }
+ public required string CacheStoragePath { get; set; }
- public string DataStoragePath { get; set; }
+ public required string DataStoragePath { get; set; }
- public bool StoreData { get; set; } = true;
+ public required bool StoreData { get; set; } = true;
- public string ServerName { get; set; } = "localhost";
+ public required string ServerName { get; set; } = "localhost";
- public bool UnknownSyncTokenIsInitialSync { get; set; } = true;
+ public required bool UnknownSyncTokenIsInitialSync { get; set; } = true;
private static string ExpandPath(string path, bool retry = true) {
_logger.LogInformation("Expanding path `{}`", path);
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs
index 00f2a42..7945d3a 100644
--- a/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs
@@ -4,18 +4,18 @@ using LibMatrix.Services;
namespace LibMatrix.HomeserverEmulator.Services;
public class MediaStore {
- private readonly HSEConfiguration _config;
+ private readonly HseConfiguration _config;
private readonly HomeserverResolverService _hsResolver;
- private List<MediaInfo> index = new();
+ private List<MediaInfo> _mediaIndex = new();
- public MediaStore(HSEConfiguration config, HomeserverResolverService hsResolver) {
+ public MediaStore(HseConfiguration config, HomeserverResolverService hsResolver) {
_config = config;
_hsResolver = hsResolver;
if (config.StoreData) {
var path = Path.Combine(config.DataStoragePath, "media");
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
if (File.Exists(Path.Combine(path, "index.json")))
- index = JsonSerializer.Deserialize<List<MediaInfo>>(File.ReadAllText(Path.Combine(path, "index.json")));
+ _mediaIndex = JsonSerializer.Deserialize<List<MediaInfo>>(File.ReadAllText(Path.Combine(path, "index.json")));
}
else
Console.WriteLine("Data storage is disabled, not loading rooms from disk");
@@ -36,7 +36,9 @@ public class MediaStore {
if (_config.StoreData) {
var path = Path.Combine(_config.DataStoragePath, "media", serverName, mediaId);
if (!File.Exists(path)) {
- var mediaUrl = await _hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+ // var mediaUrl = await _hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+ var homeserver = (await _hsResolver.ResolveHomeserverFromWellKnown(serverName)).Client;
+ var mediaUrl = homeserver is null ? null : $"{homeserver}/_matrix/media/v3/download/";
if (mediaUrl is null)
throw new MatrixException() {
ErrorCode = "M_NOT_FOUND",
@@ -50,7 +52,9 @@ public class MediaStore {
return new FileStream(path, FileMode.Open);
}
else {
- var mediaUrl = await _hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+ // var mediaUrl = await _hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+ var homeserver = (await _hsResolver.ResolveHomeserverFromWellKnown(serverName)).Client;
+ var mediaUrl = homeserver is null ? null : $"{homeserver}/_matrix/media/v3/download/";
if (mediaUrl is null)
throw new MatrixException() {
ErrorCode = "M_NOT_FOUND",
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs
index 0128ba6..0603a2d 100644
--- a/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs
@@ -35,15 +35,15 @@ public class PaginationTokenResolverService(ILogger<PaginationTokenResolverServi
}
}
- public async Task<StateEventResponse?> ResolveTokenToEvent(string token, RoomStore.Room room) {
+ public Task<StateEventResponse?> ResolveTokenToEvent(string token, RoomStore.Room room) {
if (token.StartsWith('$')) {
//we have an event ID
logger.LogTrace("ResolveTokenToEvent(EventId({token}), Room({room})): searching for event...", token, room.RoomId);
var evt = room.Timeline.SingleOrDefault(x => x.EventId == token);
- if (evt is not null) return evt;
+ if (evt is not null) return Task.FromResult(evt);
logger.LogTrace("ResolveTokenToEvent({token}, Room({room})): event not in requested room...", token, room.RoomId);
- return null;
+ return Task.FromResult<StateEventResponse?>(null);
}
else {
// we have a sync token
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs
index c798cce..b6fe7c2 100644
--- a/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs
@@ -2,13 +2,12 @@ using System.Collections.Concurrent;
using System.Collections.Frozen;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
-using System.Collections.Specialized;
using System.Text.Json;
using System.Text.Json.Nodes;
using ArcaneLibs;
using ArcaneLibs.Collections;
using ArcaneLibs.Extensions;
-using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.EventTypes.Spec.State.RoomInfo;
using LibMatrix.HomeserverEmulator.Controllers.Rooms;
using LibMatrix.Responses;
@@ -19,14 +18,14 @@ public class RoomStore {
public ConcurrentBag<Room> _rooms = new();
private FrozenDictionary<string, Room> _roomsById = FrozenDictionary<string, Room>.Empty;
- public RoomStore(ILogger<RoomStore> logger, HSEConfiguration config) {
+ public RoomStore(ILogger<RoomStore> logger, HseConfiguration config) {
_logger = logger;
if (config.StoreData) {
var path = Path.Combine(config.DataStoragePath, "rooms");
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
foreach (var file in Directory.GetFiles(path)) {
var room = JsonSerializer.Deserialize<Room>(File.ReadAllText(file));
- if (room is not null) _rooms.Add(room);
+ if (room is not null && room.State.Any(x => x.Type == RoomCreateEventContent.EventId)) _rooms.Add(room);
}
}
else
@@ -35,25 +34,8 @@ public class RoomStore {
RebuildIndexes();
}
- private SemaphoreSlim a = new(1, 1);
private void RebuildIndexes() {
- // a.Wait();
- // lock (_roomsById)
- // _roomsById = new ConcurrentDictionary<string, Room>(_rooms.ToDictionary(u => u.RoomId));
- // foreach (var room in _rooms) {
- // _roomsById.AddOrUpdate(room.RoomId, room, (key, old) => room);
- // }
- //
- // var roomsArr = _rooms.ToArray();
- // foreach (var (id, room) in _roomsById) {
- // if (!roomsArr.Any(x => x.RoomId == id))
- // _roomsById.TryRemove(id, out _);
- // }
-
- // _roomsById = new ConcurrentDictionary<string, Room>(_rooms.ToDictionary(u => u.RoomId));
_roomsById = _rooms.ToFrozenDictionary(u => u.RoomId);
-
- // a.Release();
}
public Room? GetRoomById(string roomId, bool createIfNotExists = false) {
@@ -64,18 +46,19 @@ public class RoomStore {
if (!createIfNotExists)
return null;
- return CreateRoom(new() { });
+ return CreateRoom(new());
}
public Room CreateRoom(CreateRoomRequest request, UserStore.User? user = null) {
var room = new Room(roomId: $"!{Guid.NewGuid().ToString()}");
var newCreateEvent = new StateEvent() {
Type = RoomCreateEventContent.EventId,
- RawContent = new() { }
+ RawContent = new()
};
foreach (var (key, value) in request.CreationContent) {
newCreateEvent.RawContent[key] = value.DeepClone();
+ Console.WriteLine($"RawContent[{key}] = {value.DeepClone().ToJson(ignoreNull: true)}");
}
if (user != null) {
@@ -207,7 +190,7 @@ public class RoomStore {
: JsonSerializer.Deserialize<JsonObject>(JsonSerializer.Serialize(request.TypedContent)))
};
Timeline.Add(state);
- if(state.StateKey != null)
+ if (state.StateKey != null)
RebuildState();
return state;
}
@@ -226,32 +209,36 @@ public class RoomStore {
}
// public async Task SaveDebounced() {
- // if (!HSEConfiguration.Current.StoreData) return;
- // await _debounceCts.CancelAsync();
- // _debounceCts = new CancellationTokenSource();
- // try {
- // await Task.Delay(250, _debounceCts.Token);
- // // Ensure all state events are in the timeline
- // State.Where(s => !Timeline.Contains(s)).ToList().ForEach(s => Timeline.Add(s));
- // var path = Path.Combine(HSEConfiguration.Current.DataStoragePath, "rooms", $"{RoomId}.json");
- // Console.WriteLine($"Saving room {RoomId} to {path}!");
- // await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
- // }
- // catch (TaskCanceledException) { }
+ // if (!HSEConfiguration.Current.StoreData) return;
+ // await _debounceCts.CancelAsync();
+ // _debounceCts = new CancellationTokenSource();
+ // try {
+ // await Task.Delay(250, _debounceCts.Token);
+ // // Ensure all state events are in the timeline
+ // State.Where(s => !Timeline.Contains(s)).ToList().ForEach(s => Timeline.Add(s));
+ // var path = Path.Combine(HSEConfiguration.Current.DataStoragePath, "rooms", $"{RoomId}.json");
+ // Console.WriteLine($"Saving room {RoomId} to {path}!");
+ // await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
+ // }
+ // catch (TaskCanceledException) { }
// }
private SemaphoreSlim saveSemaphore = new(1, 1);
+ private CancellationTokenSource _saveCts = new();
+
public async Task SaveDebounced() {
Task.Run(async () => {
- await saveSemaphore.WaitAsync();
+ // await saveSemaphore.WaitAsync();
+ await _saveCts.CancelAsync();
+ _saveCts = new();
try {
- var path = Path.Combine(HSEConfiguration.Current.DataStoragePath, "rooms", $"{RoomId}.json");
- Console.WriteLine($"Saving room {RoomId} to {path}!");
- await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
+ var path = Path.Combine(HseConfiguration.Current.DataStoragePath, "rooms", $"{RoomId}.json");
+ // Console.WriteLine($"Saving room {RoomId} to {path}!");
+ await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true), _saveCts.Token);
}
finally {
- saveSemaphore.Release();
+ // saveSemaphore.Release();
}
});
}
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs
index 4684b01..7f211e3 100644
--- a/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs
@@ -5,7 +5,6 @@ using System.Text.Json.Nodes;
using ArcaneLibs;
using ArcaneLibs.Collections;
using ArcaneLibs.Extensions;
-using LibMatrix.EventTypes.Spec.State;
using LibMatrix.Filters;
using LibMatrix.Responses;
@@ -13,14 +12,14 @@ namespace LibMatrix.HomeserverEmulator.Services;
public class UserStore {
public ConcurrentBag<User> _users = new();
- private readonly HSEConfiguration _config;
+ private readonly HseConfiguration _config;
private readonly RoomStore _roomStore;
- public UserStore(HSEConfiguration config, RoomStore roomStore) {
+ public UserStore(HseConfiguration config, RoomStore roomStore) {
_config = config;
_roomStore = roomStore;
if (config.StoreData) {
- var dataDir = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users");
+ var dataDir = Path.Combine(HseConfiguration.Current.DataStoragePath, "users");
if (!Directory.Exists(dataDir)) Directory.CreateDirectory(dataDir);
foreach (var userId in Directory.GetDirectories(dataDir)) {
var tokensDir = Path.Combine(dataDir, userId, "tokens.json");
@@ -138,7 +137,7 @@ public class UserStore {
private ObservableDictionary<string, object> _profile;
private ObservableCollection<StateEventResponse> _accountData;
private ObservableDictionary<string, RoomKeysResponse> _roomKeys;
- private ObservableDictionary<string, AuthorizedSession> _authorizedSessions;
+ private ObservableDictionary<string, LoginResponse> _authorizedSessions;
public string UserId {
get => _userId;
@@ -195,7 +194,7 @@ public class UserStore {
}
}
- public ObservableDictionary<string, AuthorizedSession> AuthorizedSessions {
+ public ObservableDictionary<string, LoginResponse> AuthorizedSessions {
get => _authorizedSessions;
set {
if (value == _authorizedSessions) return;
@@ -208,12 +207,12 @@ public class UserStore {
public bool IsGuest { get; set; }
public async Task SaveDebounced() {
- if (!HSEConfiguration.Current.StoreData) return;
+ if (!HseConfiguration.Current.StoreData) return;
await _debounceCts.CancelAsync();
_debounceCts = new CancellationTokenSource();
try {
await Task.Delay(250, _debounceCts.Token);
- var dataDir = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users", _userId);
+ var dataDir = Path.Combine(HseConfiguration.Current.DataStoragePath, "users", _userId);
if (!Directory.Exists(dataDir)) Directory.CreateDirectory(dataDir);
var tokensDir = Path.Combine(dataDir, "tokens.json");
var path = Path.Combine(dataDir, $"user.json");
@@ -264,10 +263,5 @@ public class UserStore {
UserId = UserId
};
}
-
- public class AuthorizedSession {
- public string Homeserver { get; set; }
- public string AccessToken { get; set; }
- }
}
}
\ No newline at end of file
|