diff --git a/LibMatrix/Helpers/SyncProcessors/Msc4222EmulationSyncProcessor.cs b/LibMatrix/Helpers/SyncProcessors/Msc4222EmulationSyncProcessor.cs
index b18a8e0..f9f6ba3 100644
--- a/LibMatrix/Helpers/SyncProcessors/Msc4222EmulationSyncProcessor.cs
+++ b/LibMatrix/Helpers/SyncProcessors/Msc4222EmulationSyncProcessor.cs
@@ -7,7 +7,11 @@ namespace LibMatrix.Helpers.SyncProcessors;
public class Msc4222EmulationSyncProcessor(AuthenticatedHomeserverGeneric homeserver) {
private static bool StateEventsMatch(StateEventResponse a, StateEventResponse b) {
- return a.Type == b.Type && a.StateKey == b.StateKey && a.OriginServerTs < b.OriginServerTs;
+ return a.Type == b.Type && a.StateKey == b.StateKey;
+ }
+
+ private static bool StateEventIsNewer(StateEventResponse a, StateEventResponse b) {
+ return StateEventsMatch(a, b) && a.OriginServerTs < b.OriginServerTs;
}
public async Task<SyncResponse?> EmulateMsc4222(SyncResponse? resp) {
@@ -40,7 +44,7 @@ public class Msc4222EmulationSyncProcessor(AuthenticatedHomeserverGeneric homese
}
Console.WriteLine($"Msc4222EmulationSyncProcessor.EmulateMsc4222 processed {resp.Rooms?.Join?.Count}/{resp.Rooms?.Leave?.Count} rooms in {sw.Elapsed}");
- if (modified)
+ if (modified)
resp.Msc4222Method = SyncResponse.Msc4222SyncType.Emulated;
return resp;
@@ -48,14 +52,78 @@ public class Msc4222EmulationSyncProcessor(AuthenticatedHomeserverGeneric homese
private async Task<bool> ProcessJoinedRooms(KeyValuePair<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure> roomData) {
var (roomId, data) = roomData;
+ var room = homeserver.GetRoom(roomId);
if (data.StateAfter is { Events.Count: > 0 }) {
return false;
}
- data.StateAfter = new() { };
+ data.StateAfter = new() { Events = [] };
+
+ data.StateAfter = new() {
+ Events = []
+ };
+
+ var oldState = new List<StateEventResponse>();
+ if (data.State is { Events.Count: > 0 }) {
+ oldState.ReplaceBy(data.State.Events, StateEventIsNewer);
+ }
+
+ if (data.Timeline is { Limited: true }) {
+ if (data.Timeline.Events != null)
+ oldState.ReplaceBy(data.Timeline.Events, StateEventIsNewer);
+
+ try {
+ var timeline = await homeserver.GetRoom(roomId).GetMessagesAsync(limit: 250);
+ if (timeline is { State.Count: > 0 }) {
+ oldState.ReplaceBy(timeline.State, StateEventIsNewer);
+ }
+
+ if (timeline is { Chunk.Count: > 0 }) {
+ oldState.ReplaceBy(timeline.Chunk.Where(x => x.StateKey != null), StateEventIsNewer);
+ }
+ }
+ catch (Exception e) {
+ Console.WriteLine($"Msc4222Emulation: Failed to get timeline for room {roomId}, state may be incomplete!\n{e}");
+ }
+ }
- return false;
+ oldState = oldState.DistinctBy(x => (x.Type, x.StateKey)).ToList();
+
+ // Different order: we need oldState here to reduce the set
+ try {
+ data.StateAfter.Events = (await room.GetFullStateAsListAsync())
+ // .Where(x=> oldState.Any(y => StateEventsMatch(x, y)))
+ // .Join(oldState, x => (x.Type, x.StateKey), y => (y.Type, y.StateKey), (x, y) => x)
+ .IntersectBy(oldState.Select(s => (s.Type, s.StateKey)), s => (s.Type, s.StateKey))
+ .ToList();
+
+ data.State = null;
+ return true;
+ }
+ catch (Exception e) {
+ Console.WriteLine($"Msc4222Emulation: Failed to get full state for room {roomId}, state may be incomplete!\n{e}");
+ }
+
+ var tasks = oldState
+ .Select(async oldEvt => {
+ try {
+ return await room.GetStateEventAsync(oldEvt.Type, oldEvt.StateKey!);
+ }
+ catch (Exception e) {
+ Console.WriteLine($"Msc4222Emulation: Failed to get state event {oldEvt.Type}/{oldEvt.StateKey} for room {roomId}, state may be incomplete!\n{e}");
+ return oldEvt;
+ }
+ });
+
+ var tasksEnum = tasks.ToAsyncEnumerable();
+ await foreach (var evt in tasksEnum) {
+ data.StateAfter.Events.Add(evt);
+ }
+
+ data.State = null;
+
+ return true;
}
private async Task<bool> ProcessLeftRooms(KeyValuePair<string, SyncResponse.RoomsDataStructure.LeftRoomDataStructure> roomData) {
@@ -72,6 +140,7 @@ public class Msc4222EmulationSyncProcessor(AuthenticatedHomeserverGeneric homese
try {
data.StateAfter.Events = await room.GetFullStateAsListAsync();
+ data.State = null;
return true;
}
catch (Exception e) {
@@ -80,21 +149,21 @@ public class Msc4222EmulationSyncProcessor(AuthenticatedHomeserverGeneric homese
var oldState = new List<StateEventResponse>();
if (data.State is { Events.Count: > 0 }) {
- oldState.ReplaceBy(data.State.Events, StateEventsMatch);
+ oldState.ReplaceBy(data.State.Events, StateEventIsNewer);
}
if (data.Timeline is { Limited: true }) {
if (data.Timeline.Events != null)
- oldState.ReplaceBy(data.Timeline.Events, StateEventsMatch);
+ oldState.ReplaceBy(data.Timeline.Events, StateEventIsNewer);
try {
var timeline = await homeserver.GetRoom(roomId).GetMessagesAsync(limit: 250);
if (timeline is { State.Count: > 0 }) {
- oldState.ReplaceBy(timeline.State, StateEventsMatch);
+ oldState.ReplaceBy(timeline.State, StateEventIsNewer);
}
if (timeline is { Chunk.Count: > 0 }) {
- oldState.ReplaceBy(timeline.Chunk.Where(x => x.StateKey != null), StateEventsMatch);
+ oldState.ReplaceBy(timeline.Chunk.Where(x => x.StateKey != null), StateEventIsNewer);
}
}
catch (Exception e) {
@@ -120,6 +189,8 @@ public class Msc4222EmulationSyncProcessor(AuthenticatedHomeserverGeneric homese
data.StateAfter.Events.Add(evt);
}
+ data.State = null;
+
return true;
}
}
\ No newline at end of file
|