From 8636a8d567dc5775629c5e77b0db74779d28a89d Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 4 Jul 2026 10:12:44 +0000 Subject: [PATCH] fix(mam): Prevent duplicated and out-of-order history messages This resolves an issue where MAM history messages were being appended to the window display buffer in as they arrived, causing them to appear out of order and duplicated when the RSM batch completed and prepended the same sorted messages. Bypass immediate display and file logging for MAM messages and allow them to only be saved to the database. Render them in a single chronological block once the query completes. So in server_events.c we now only decrypt and save MAM messages to db. Once we receive `` we trigger `_mam_rsm_id_handler()` and `_mam_buffer_commit_handler()` which call `mucwin_db_history() and `chatwin_db_history()` which will query the DB and print them to the screen via `win_print_old_history()`. Signed-off-by: Michael Vetter --- src/event/server_events.c | 50 +++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/event/server_events.c b/src/event/server_events.c index 8b05e8613..ff1bfe553 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -358,9 +358,13 @@ sv_ev_room_message(ProfMessage* message) } if (message->is_mam) { - // For MAM, print to window but disable all notifications, unread count increment etc - // And don't filter reflection of our own sent messages (so they get displayed) - mucwin_incoming_msg(mucwin, message, mentions, triggers, FALSE); + // For MAM, do not print to screen immediately. It is loaded and sorted upon query completion. + g_slist_free(mentions); + if (triggers) { + g_list_free_full(triggers, free); + } + message->plain = old_plain; + return; } else { mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE); @@ -515,9 +519,11 @@ _sv_ev_incoming_pgp(ProfChatWin* chatwin, gboolean new_win, ProfMessage* message if (message->plain) { message->enc = PROF_MSG_ENC_PGP; _clean_incoming_message(message); - chatwin_incoming_msg(chatwin, message, new_win); + if (!message->is_mam) { + chatwin_incoming_msg(chatwin, message, new_win); + } log_database_add_incoming(message); - if (logit) { + if (logit && !message->is_mam) { chat_log_pgp_msg_in(message); } chatwin->pgp_recv = TRUE; @@ -531,9 +537,13 @@ _sv_ev_incoming_pgp(ProfChatWin* chatwin, gboolean new_win, ProfMessage* message message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); - chatwin_incoming_msg(chatwin, message, new_win); + if (!message->is_mam) { + chatwin_incoming_msg(chatwin, message, new_win); + } log_database_add_incoming(message); - chat_log_msg_in(message); + if (!message->is_mam) { + chat_log_msg_in(message); + } chatwin->pgp_recv = FALSE; } #endif @@ -552,9 +562,11 @@ _sv_ev_incoming_ox(ProfChatWin* chatwin, gboolean new_win, ProfMessage* message, } //_clean_incoming_message(message); - chatwin_incoming_msg(chatwin, message, new_win); + if (!message->is_mam) { + chatwin_incoming_msg(chatwin, message, new_win); + } log_database_add_incoming(message); - if (logit) { + if (logit && !message->is_mam) { chat_log_pgp_msg_in(message); } chatwin->pgp_recv = TRUE; @@ -578,10 +590,14 @@ _sv_ev_incoming_otr(ProfChatWin* chatwin, gboolean new_win, ProfMessage* message } _clean_incoming_message(message); - chatwin_incoming_msg(chatwin, message, new_win); + if (!message->is_mam) { + chatwin_incoming_msg(chatwin, message, new_win); + } log_database_add_incoming(message); - chat_log_otr_msg_in(message); + if (!message->is_mam) { + chat_log_otr_msg_in(message); + } otr_free_message(message->plain); message->plain = NULL; chatwin->pgp_recv = FALSE; @@ -596,9 +612,11 @@ _sv_ev_incoming_omemo(ProfChatWin* chatwin, gboolean new_win, ProfMessage* messa { #ifdef HAVE_OMEMO _clean_incoming_message(message); - chatwin_incoming_msg(chatwin, message, new_win); + if (!message->is_mam) { + chatwin_incoming_msg(chatwin, message, new_win); + } log_database_add_incoming(message); - if (logit) { + if (logit && !message->is_mam) { chat_log_omemo_msg_in(message); } chatwin->pgp_recv = FALSE; @@ -617,9 +635,11 @@ _sv_ev_incoming_plain(ProfChatWin* chatwin, gboolean new_win, ProfMessage* messa return; } _clean_incoming_message(message); - chatwin_incoming_msg(chatwin, message, new_win); + if (!message->is_mam) { + chatwin_incoming_msg(chatwin, message, new_win); + } log_database_add_incoming(message); - if (logit) { + if (logit && !message->is_mam) { chat_log_msg_in(message); } chatwin->pgp_recv = FALSE;