From 99bba146286eb24acb173c86f2739cef6154fc56 Mon Sep 17 00:00:00 2001 From: Shawn Date: Sun, 12 Nov 2023 15:13:40 +0000 Subject: [PATCH] fix(breakout-rooms, persistent-lobby): support for using both these modules together --- .../mod_muc_breakout_rooms.lua | 34 +++++++++++++++++-- .../prosody-plugins/mod_persistent_lobby.lua | 31 +++++++++++++++-- .../prosody-plugins/mod_room_destroy.lua | 15 ++++++++ 3 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 resources/prosody-plugins/mod_room_destroy.lua diff --git a/resources/prosody-plugins/mod_muc_breakout_rooms.lua b/resources/prosody-plugins/mod_muc_breakout_rooms.lua index b3557c66d6..3f79ed5766 100644 --- a/resources/prosody-plugins/mod_muc_breakout_rooms.lua +++ b/resources/prosody-plugins/mod_muc_breakout_rooms.lua @@ -15,6 +15,9 @@ -- muc_room_locking = false -- muc_room_default_public_jids = true -- + +module:depends('room_destroy'); + -- we use async to detect Prosody 0.10 and earlier local have_async = pcall(require, 'util.async'); @@ -427,14 +430,39 @@ function on_occupant_left(event) -- and we will have the old instance local main_room, main_room_jid = get_main_room(room_jid); if main_room and main_room.close_timer then - module:log('info', 'Closing conference %s as all left for good.', main_room_jid); - main_room:set_persistent(false); - main_room:destroy(nil, 'All occupants left.'); + prosody.events.fire_event("maybe-destroy-room", { + room = main_room; + reason = 'All occupants left.'; + caller = module:get_name(); + }); end end); end end +-- Stop other modules from destroying room if breakout rooms not empty +function handle_maybe_destroy_main_room(event) + local main_room = event.room; + local caller = event.caller; + + if caller == module:get_name() then + -- we were the one that requested the deletion. Do not override. + return nil; -- stop room destruction + end + + -- deletion was requested by another module. Check for break room occupants. + for breakout_room_jid, _ in pairs(main_room._data.breakout_rooms or {}) do + local breakout_room = breakout_rooms_muc_service.get_room_from_jid(breakout_room_jid); + if breakout_room and breakout_room:has_occupant() then + module:log('info', 'Suppressing room destroy. Breakout room still occupied %s', breakout_room_jid); + return true; -- stop room destruction + end + end +end + +module:hook_global("maybe-destroy-room", handle_maybe_destroy_main_room) + + function on_main_room_destroyed(event) local main_room = event.room; diff --git a/resources/prosody-plugins/mod_persistent_lobby.lua b/resources/prosody-plugins/mod_persistent_lobby.lua index 2ebfaa48b2..2f4e30c399 100644 --- a/resources/prosody-plugins/mod_persistent_lobby.lua +++ b/resources/prosody-plugins/mod_persistent_lobby.lua @@ -8,6 +8,7 @@ -- To trigger creation of lobby room: -- prosody.events.fire_event("create-persistent-lobby-room", { room = room; }); -- +module:depends('room_destroy'); local util = module:require "util"; local is_healthcheck_room = util.is_healthcheck_room; @@ -86,8 +87,11 @@ end -- Helper method to trigger main room destroy local function trigger_room_destroy(room) - room:set_persistent(false); - room:destroy(nil, 'main room and lobby now empty'); + prosody.events.fire_event("maybe-destroy-room", { + room = room; + reason = 'main room and lobby now empty'; + caller = module:get_name(); + }); end @@ -170,3 +174,26 @@ end module:hook_global('create-persistent-lobby-room', handle_create_persistent_lobby); + +-- Stop other modules from destroying room if persistent lobby not empty +function handle_maybe_destroy_main_room(event) + local main_room = event.room; + local caller = event.caller; + + if caller == module:get_name() then + -- we were the one that requested the deletion. Do not override. + return nil; + end + + -- deletion was requested by another module. Check for lobby occupants. + if has_persistent_lobby(main_room) and main_room._data.lobbyroom then + local lobby_room_jid = main_room._data.lobbyroom; + local lobby_room = lobby_muc_service.get_room_from_jid(lobby_room_jid); + if lobby_room and lobby_room:has_occupant() then + module:log('info', 'Suppressing room destroy. Persistent lobby still occupied %s', lobby_room_jid); + return true; -- stop room destruction + end + end +end + +module:hook_global("maybe-destroy-room", handle_maybe_destroy_main_room); diff --git a/resources/prosody-plugins/mod_room_destroy.lua b/resources/prosody-plugins/mod_room_destroy.lua new file mode 100644 index 0000000000..d3dfb3b961 --- /dev/null +++ b/resources/prosody-plugins/mod_room_destroy.lua @@ -0,0 +1,15 @@ +-- Handle room destroy requests it such a way that it can be suppressed by other +-- modules that handle room lifecycle and wish to keep the room alive. + +function handle_room_destroy(event) + local room = event.room; + local reason = event.reason; + local caller = event.caller; + + module:log('info', 'Destroying room %s (requested by %s)', room.jid, caller); + room:set_persistent(false); + room:destroy(nil, reason); +end + +module:hook_global("maybe-destroy-room", handle_room_destroy, -1); +module:log('info', 'loaded');