From 42b8580f3bb62069ffddcd7e7e3ac84da989be3c Mon Sep 17 00:00:00 2001 From: olcxja Date: Thu, 23 Jul 2026 19:02:21 +0200 Subject: [PATCH] fix reactions --- LarpixServer/Account/Requests.cs | 10 +++- LarpixServer/Room/Requests.cs | 94 ++++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/LarpixServer/Account/Requests.cs b/LarpixServer/Account/Requests.cs index 6c4ac7b..17e0327 100644 --- a/LarpixServer/Account/Requests.cs +++ b/LarpixServer/Account/Requests.cs @@ -753,10 +753,16 @@ public static async Task Auth(HttpContext context, Func next, IQueryCollec await Room.Requests.DmMessageDelete(id, serializedBody.string2) , password)); break; - case "dm/message/react": + case "dm/message/react/add": await context.Response.WriteAsync( Encryption.Encryption.EncryptString( - await Room.Requests.DmMessageReact(id, serializedBody.string2) + await Room.Requests.DmMessageReactAdd(id, serializedBody.string2) + , password)); + break; + case "dm/message/react/remove": + await context.Response.WriteAsync( + Encryption.Encryption.EncryptString( + await Room.Requests.DmMessageReactRemove(id, serializedBody.string2) , password)); break; case "dm/messages/get": diff --git a/LarpixServer/Room/Requests.cs b/LarpixServer/Room/Requests.cs index 7c77e49..d1af6ce 100644 --- a/LarpixServer/Room/Requests.cs +++ b/LarpixServer/Room/Requests.cs @@ -74,7 +74,40 @@ public class Requests { if (fetched > 0) sb.Append(','); sb.Append($"\"{i}\":"); - sb.Append(Encoding.UTF8.GetString(await Fs.ReadFile(p))); + + string msgJson = Encoding.UTF8.GetString(await Fs.ReadFile(p)); + Message msgObj = JsonSerializer.Deserialize(msgJson, AppJsonSerializerContext.Default.Message); + + string reactDir = $"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/reactions/{i}"; + if (Fs.Exists(reactDir)) + { + StringBuilder rxSb = new StringBuilder("["); + string[] reactFiles = Fs.ReadDirectory(reactDir); + int rxCount = 0; + foreach(string rf in reactFiles) + { + string rId = System.IO.Path.GetFileName(rf); + if (rId == "last") continue; + string content = Encoding.UTF8.GetString(await Fs.ReadFile($"{reactDir}/{rId}")); + int nLineIdx = content.IndexOf('\n'); + if (nLineIdx != -1) + { + string u = content.Substring(0, nLineIdx).Trim(); + string r = content.Substring(nLineIdx + 1).Trim(); + if (rxCount > 0) rxSb.Append(','); + rxSb.Append($"{{\"id\":\"{rId}\",\"u\":\"{u}\",\"r\":\"{r}\"}}"); + rxCount++; + } + } + rxSb.Append("]"); + msgObj.reactions = rxCount > 0 ? rxSb.ToString() : ""; + } + else + { + msgObj.reactions = ""; + } + + sb.Append(JsonSerializer.Serialize(msgObj, AppJsonSerializerContext.Default.Message)); fetched++; } } @@ -523,7 +556,7 @@ public class Requests return "success:message.deleted"; } - public static async Task DmMessageReact(string id, string body) + public static async Task DmMessageReactAdd(string id, string body) { Universal3String serializedBody = JsonSerializer.Deserialize( body, @@ -531,12 +564,12 @@ public class Requests ); string dmId = serializedBody.string1; string msgId = serializedBody.string2; - string reactions = serializedBody.string3; + string reaction = serializedBody.string3; if (!IsSafeMsgId(msgId)) return "error:invalid.msg.id"; if (!await IsMemberOfDm(id, dmId)) return "error:forbidden"; - if (reactions != null && reactions.Length > LarpixServer.Utils.Utils.MAX_REACTION_SIZE) + if (reaction != null && reaction.Length > LarpixServer.Utils.Utils.MAX_REACTION_SIZE) { string sizeStr = LarpixServer.Utils.Utils.MAX_REACTION_SIZE >= 1024 ? $"{LarpixServer.Utils.Utils.MAX_REACTION_SIZE / 1024.0:0.##} KB" : $"{LarpixServer.Utils.Utils.MAX_REACTION_SIZE} B"; return $"error:reaction.too.long:{sizeStr}"; @@ -552,9 +585,18 @@ public class Requests if (msg.type == "larp.redacted") return "error:message.already.deleted"; - msg.reactions = reactions ?? ""; + string reactDir = $"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/reactions/{msgId}"; + if (!Fs.Exists(reactDir)) Fs.CreateDirectory(reactDir); - await Fs.WriteFile(msgPath, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(msg, AppJsonSerializerContext.Default.Message))); + long last = 0; + if (Fs.Exists($"{reactDir}/last")) + { + last = long.Parse(Encoding.UTF8.GetString(await Fs.ReadFile($"{reactDir}/last"))); + } + long nextId = last + 1; + + await Fs.WriteFile($"{reactDir}/{nextId}", Encoding.UTF8.GetBytes($"{id}\n{reaction}")); + await Fs.WriteFile($"{reactDir}/last", Encoding.UTF8.GetBytes(nextId.ToString())); string[] members = Fs.ReadDirectory($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members"); foreach(string memberWD in members) @@ -568,4 +610,44 @@ public class Requests } return "success:message.reacted"; } + + public static async Task DmMessageReactRemove(string id, string body) + { + Universal3String serializedBody = JsonSerializer.Deserialize( + body, + AppJsonSerializerContext.Default.Universal3String + ); + string dmId = serializedBody.string1; + string msgId = serializedBody.string2; + string reactionId = serializedBody.string3; + + if (!IsSafeMsgId(msgId)) return "error:invalid.msg.id"; + if (!IsSafeMsgId(reactionId)) return "error:invalid.reaction.id"; + if (!await IsMemberOfDm(id, dmId)) return "error:forbidden"; + + string reactPath = $"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/reactions/{msgId}/{reactionId}"; + if (!Fs.Exists(reactPath)) return "error:reaction.not.found"; + + string content = Encoding.UTF8.GetString(await Fs.ReadFile(reactPath)); + int nLineIdx = content.IndexOf('\n'); + if (nLineIdx != -1) + { + string u = content.Substring(0, nLineIdx).Trim(); + if (u != id) return "error:forbidden"; + } + + Fs.DeleteFile(reactPath); + + string[] members = Fs.ReadDirectory($"{ROOMS_DIR}/dms/{DOMAIN}/{dmId}/members"); + foreach(string memberWD in members) + { + bool isLocal = Account.Utils.IsUserLocal(memberWD, out string domain); + string memberId = Account.Utils.GetValidIdOrZero(memberWD); + if (isLocal) + { + await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}:update"); + } + } + return "success:message.reaction.removed"; + } } \ No newline at end of file