Diff

plugins/muc/mod_muc.lua @ 6109:566aba0482b6

plugins/muc/mod_muc: Refactor to use new methods available
author daurnimator <quae@daurnimator.com>
date Tue, 18 Mar 2014 18:55:52 -0400
parent 6091:3a1c39b31497
child 6110:d007b3c49078
line wrap: on
line diff
--- a/plugins/muc/mod_muc.lua	Tue Mar 18 18:52:28 2014 -0400
+++ b/plugins/muc/mod_muc.lua	Tue Mar 18 18:55:52 2014 -0400
@@ -106,6 +106,14 @@
 	return room;
 end
 
+function forget_room(jid)
+	rooms[jid] = nil;
+end
+
+function get_room_from_jid(room_jid)
+	return rooms[room_jid]
+end
+
 local persistent_errors = false;
 for jid in pairs(persistent_rooms) do
 	local node = jid_split(jid);
@@ -125,6 +133,7 @@
 local host_room = muc_new_room(muc_host);
 host_room.route_stanza = room_route_stanza;
 host_room.save = room_save;
+rooms[muc_host] = host_room;
 
 module:hook("host-disco-items", function(event)
 	local reply = event.reply;
@@ -136,49 +145,74 @@
 	end
 end);
 
-function stanza_handler(event)
+module:hook("muc-room-destroyed",function(event)
+	local room = event.room
+	forget_room(room.jid)
+end)
+
+module:hook("muc-occupant-left",function(event)
+	local room = event.room
+	if not next(room._occupants) and not persistent_rooms[room.jid] then -- empty, non-persistent room
+		module:fire_event("muc-room-destroyed", { room = room });
+	end
+end);
+
+-- Watch presence to create rooms
+local function attempt_room_creation(event)
 	local origin, stanza = event.origin, event.stanza;
-	local bare = jid_bare(stanza.attr.to);
-	local room = rooms[bare];
-	if not room then
-		if stanza.name ~= "presence" then
-			origin.send(st.error_reply(stanza, "cancel", "item-not-found"));
+	local room_jid = jid_bare(stanza.attr.to);
+	if stanza.attr.type == nil and
+		get_room_from_jid(room_jid) == nil and
+		(
+			not(restrict_room_creation) or
+			is_admin(stanza.attr.from) or
+			(
+				restrict_room_creation == "local" and
+				select(2, jid_split(stanza.attr.from)) == module.host:gsub("^[^%.]+%.", "")
+			)
+		) then
+		create_room(room_jid);
+	end
+end
+module:hook("presence/full", attempt_room_creation, -1)
+module:hook("presence/bare", attempt_room_creation, -1)
+module:hook("presence/host", attempt_room_creation, -1)
+
+for event_name, method in pairs {
+	-- Normal room interactions
+	["iq-get/bare/http://jabber.org/protocol/disco#info:query"] = "handle_disco_info_get_query" ;
+	["iq-get/bare/http://jabber.org/protocol/disco#items:query"] = "handle_disco_items_get_query" ;
+	["iq-set/bare/http://jabber.org/protocol/muc#admin:item"] = "handle_admin_item_set_command" ;
+	["iq-get/bare/http://jabber.org/protocol/muc#admin:item"] = "handle_admin_item_get_command" ;
+	["iq-set/bare/http://jabber.org/protocol/muc#owner:query"] = "handle_owner_query_set_to_room" ;
+	["iq-get/bare/http://jabber.org/protocol/muc#owner:query"] = "handle_owner_query_get_to_room" ;
+	["message/bare"] = "handle_message_to_room" ;
+	["presence/bare"] = "handle_presence_to_room" ;
+	-- Host room
+	["iq-get/host/http://jabber.org/protocol/disco#info:query"] = "handle_disco_info_get_query" ;
+	["iq-get/host/http://jabber.org/protocol/disco#items:query"] = "handle_disco_items_get_query" ;
+	["iq-set/host/http://jabber.org/protocol/muc#admin:item"] = "handle_admin_item_set_command" ;
+	["iq-get/host/http://jabber.org/protocol/muc#admin:item"] = "handle_admin_item_get_command" ;
+	["iq-set/host/http://jabber.org/protocol/muc#owner:query"] = "handle_owner_query_set_to_room" ;
+	["iq-get/host/http://jabber.org/protocol/muc#owner:query"] = "handle_owner_query_get_to_room" ;
+	["message/host"] = "handle_message_to_room" ;
+	["presence/host"] = "handle_presence_to_room" ;
+	-- Direct to occupant (normal rooms and host room)
+	["presence/full"] = "handle_presence_to_occupant" ;
+	["iq/full"] = "handle_iq_to_occupant" ;
+	["message/full"] = "handle_message_to_occupant" ;
+} do
+	module:hook(event_name, function (event)
+		local origin, stanza = event.origin, event.stanza;
+		local room = get_room_from_jid(jid_bare(stanza.attr.to))
+		if room == nil then
+			origin.send(st.error_reply(stanza, "cancel", "not-allowed"));
 			return true;
 		end
-		if not(restrict_room_creation) or
-		  is_admin(stanza.attr.from) or
-		  (restrict_room_creation == "local" and select(2, jid_split(stanza.attr.from)) == module.host:gsub("^[^%.]+%.", "")) then
-			room = create_room(bare);
-		end
-	end
-	if room then
-		room:handle_stanza(origin, stanza);
-		if not next(room._occupants) and not persistent_rooms[room.jid] then -- empty, non-persistent room
-			module:fire_event("muc-room-destroyed", { room = room });
-			rooms[bare] = nil; -- discard room
-		end
-	else
-		origin.send(st.error_reply(stanza, "cancel", "not-allowed"));
-	end
-	return true;
+		return room[method](room, origin, stanza);
+	end, -2)
 end
-module:hook("iq/bare", stanza_handler, -1);
-module:hook("message/bare", stanza_handler, -1);
-module:hook("presence/bare", stanza_handler, -1);
-module:hook("iq/full", stanza_handler, -1);
-module:hook("message/full", stanza_handler, -1);
-module:hook("presence/full", stanza_handler, -1);
 
-local function handle_to_domain(event)
-	local origin, stanza = event.origin, event.stanza;
-	local type = stanza.attr.type;
-	if type == "error" then return; end
-	host_room:handle_stanza(origin, stanza);
-	-- origin.send(st.error_reply(stanza, "cancel", "service-unavailable", "The muc server doesn't deal with messages and presence directed at it"));
-	return true;
-end
-module:hook("message/host", handle_to_domain, -1);
-module:hook("presence/host", handle_to_domain, -1);
 
 hosts[module.host].send = function(stanza) -- FIXME do a generic fix
 	if stanza.attr.type == "result" or stanza.attr.type == "error" then