Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

mod_muc_max_occupants.lua 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. -- MUC Max Occupants
  2. -- Configuring muc_max_occupants will set a limit of the maximum number
  3. -- of participants that will be able to join in a room.
  4. -- Participants in muc_access_whitelist will not be counted for the
  5. -- max occupants value (values are jids like recorder@jitsi.meeet.example.com).
  6. -- This module is configured under the muc component that is used for jitsi-meet
  7. local split_jid = require "util.jid".split;
  8. local st = require "util.stanza";
  9. local it = require "util.iterators";
  10. local is_healthcheck_room = module:require "util".is_healthcheck_room;
  11. local whitelist = module:get_option_set("muc_access_whitelist");
  12. local MAX_OCCUPANTS = module:get_option_number("muc_max_occupants", -1);
  13. local function count_keys(t)
  14. return it.count(it.keys(t));
  15. end
  16. local function check_for_max_occupants(event)
  17. local room, origin, stanza = event.room, event.origin, event.stanza;
  18. local user, domain, res = split_jid(stanza.attr.from);
  19. if is_healthcheck_room(room.jid) then
  20. return;
  21. end
  22. --no user object means no way to check for max occupants
  23. if user == nil then
  24. return
  25. end
  26. -- If we're a whitelisted user joining the room, don't bother checking the max
  27. -- occupants.
  28. if whitelist and whitelist:contains(domain) or whitelist:contains(user..'@'..domain) then
  29. return;
  30. end
  31. if room and not room._jid_nick[stanza.attr.from] then
  32. local max_occupants_by_room = event.room._data.max_occupants;
  33. local count = count_keys(room._occupants);
  34. -- if no of occupants limit is set per room basis use
  35. -- that settings otherwise use the global one
  36. local slots = max_occupants_by_room or MAX_OCCUPANTS;
  37. -- If there is no whitelist, just check the count.
  38. if not whitelist and count >= slots then
  39. module:log("info", "Attempt to enter a maxed out MUC");
  40. origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
  41. return true;
  42. end
  43. -- TODO: Are Prosody hooks atomic, or is this a race condition?
  44. -- For each person in the room that's not on the whitelist, subtract one
  45. -- from the count.
  46. for _, occupant in room:each_occupant() do
  47. user, domain, res = split_jid(occupant.bare_jid);
  48. if not whitelist:contains(domain) and not whitelist:contains(user..'@'..domain) then
  49. slots = slots - 1
  50. end
  51. end
  52. -- If the room is full (<0 slots left), error out.
  53. if slots <= 0 then
  54. module:log("info", "Attempt to enter a maxed out MUC");
  55. origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
  56. return true;
  57. end
  58. end
  59. end
  60. if MAX_OCCUPANTS > 0 then
  61. module:hook("muc-occupant-pre-join", check_for_max_occupants, 10);
  62. end