mod_minimix/mod_minimix.lua
changeset 3122 24e49391d4e8
parent 2945 a57ed544fece
child 3123 f84a6ad72548
equal deleted inserted replaced
3121:dd6313ddd3e0 3122:24e49391d4e8
     2 --
     2 --
     3 -- Rewrite MUC stanzas suich that the account / bare JID joins rooms instead of clients / full JIDs
     3 -- Rewrite MUC stanzas suich that the account / bare JID joins rooms instead of clients / full JIDs
     4 --
     4 --
     5 local jid_split, jid_join, jid_node, jid_bare = import("util.jid", "split", "join", "node", "bare");
     5 local jid_split, jid_join, jid_node, jid_bare = import("util.jid", "split", "join", "node", "bare");
     6 local st = require "util.stanza";
     6 local st = require "util.stanza";
       
     7 local mt = require "util.multitable";
     7 
     8 
     8 local users = prosody.hosts[module.host].sessions;
     9 local users = prosody.hosts[module.host].sessions;
     9 
    10 
    10 local joined_rooms = module:open_store("joined_rooms", "map"); -- TODO cache?
    11 local data = mt.new();
    11 local room_state = module:open_store("joined_rooms_state", "map");
       
    12 local all_room_state = module:open_store("joined_rooms_state");
       
    13 
    12 
    14 -- FIXME You can join but you can never leave.
    13 -- FIXME You can join but you can never leave.
    15 
    14 
    16 module:hook("pre-presence/full", function (event)
    15 module:hook("pre-presence/full", function (event)
    17 	local origin, stanza = event.origin, event.stanza;
    16 	local origin, stanza = event.origin, event.stanza;
    28 			origin.joined_rooms[room_jid] = nickname;
    27 			origin.joined_rooms[room_jid] = nickname;
    29 		else
    28 		else
    30 			origin.joined_rooms = { [room_jid] = nickname };
    29 			origin.joined_rooms = { [room_jid] = nickname };
    31 		end
    30 		end
    32 
    31 
    33 		if joined_rooms:get(username, room_jid) then
    32 		if data:get(username, room_jid) then
    34 			module:log("debug", "Already joined to %s as %s", room_jid, nickname);
    33 			module:log("debug", "Already joined to %s as %s", room_jid, nickname);
    35 			local state = assert(all_room_state:get(username));
    34 			local presences = data:get(username, room_jid, "presence");
    36 			for jid, stanza in pairs(state) do
    35 			for _, pres in pairs(presences) do
    37 				if jid ~= room_jid and jid ~= stanza.attr.to then
    36 				origin.send(st.clone(pres));
    38 					origin.send(st.clone(st.deserialize(stanza)));
       
    39 				end
       
    40 			end
    37 			end
    41 			origin.send(st.deserialize(state[stanza.attr.to]));
    38 			-- FIXME should send ones own presence last
    42 			origin.send(st.message({type="groupchat",to=origin.full_jid,from=room_jid}):tag("subject"):text(state[room_jid]));
    39 			origin.send(st.clone(data:get(username, room_jid, "subject")));
    43 			-- Send on-join stanzas from local state, somehow
    40 			-- Send on-join stanzas from local state, somehow
    44 			-- Maybe tell them their nickname was changed if it doesn't match the account one
    41 			-- Maybe tell them their nickname was changed if it doesn't match the account one
    45 			return true;
    42 			return true;
    46 		end
    43 		end
    47 
    44 
    48 		joined_rooms:set(username, room_jid, nickname);
       
    49 
       
    50 		local account_join = st.clone(stanza);
    45 		local account_join = st.clone(stanza);
    51 		account_join.attr.from = jid_join(origin.username, origin.host);
    46 		account_join.attr.from = jid_join(origin.username, origin.host);
    52 		module:send(account_join);
    47 		module:send(account_join);
    53 
    48 
       
    49 		data:set(username, room_jid, "joined", nickname);
       
    50 
    54 		return true;
    51 		return true;
    55 	elseif stanza.attr.type == "unavailable" and joined_rooms:get(username, room_jid) then
    52 	elseif stanza.attr.type == "unavailable" then
       
    53 		if origin.joined_rooms and origin.joined_rooms[room_jid] then
       
    54 			origin.joined_rooms[room_jid] = nil;
       
    55 		end
    56 		origin.send(st.reply(stanza));
    56 		origin.send(st.reply(stanza));
    57 		return true;
    57 		return true;
    58 	end
    58 	end
    59 end);
    59 end);
    60 
    60 
    62 	local origin, stanza = event.origin, event.stanza;
    62 	local origin, stanza = event.origin, event.stanza;
    63 	local username = origin.username;
    63 	local username = origin.username;
    64 	local room_jid = jid_bare(stanza.attr.to);
    64 	local room_jid = jid_bare(stanza.attr.to);
    65 
    65 
    66 	module:log("info", "%s", stanza)
    66 	module:log("info", "%s", stanza)
    67 	if joined_rooms:get(username, room_jid) then
    67 	if origin.joined_rooms and origin.joined_rooms[room_jid] then
    68 		local from_account = st.clone(stanza);
    68 		local from_account = st.clone(stanza);
    69 		from_account.attr.from = jid_join(origin.username, origin.host);
    69 		from_account.attr.from = jid_join(username, origin.host);
    70 		module:log("debug", "Sending:\n%s\nInstead of:\n%s", from_account, stanza);
    70 		module:log("debug", "Sending:\n%s\nInstead of:\n%s", from_account, stanza);
    71 		module:send(from_account, origin);
    71 		module:send(from_account, origin);
    72 		return true;
    72 		return true;
    73 	end
    73 	end
    74 end);
    74 end);
    75 
    75 
    76 local function handle_to_bare_jid(event)
    76 local function handle_to_bare_jid(event)
    77 	local origin, stanza = event.origin, event.stanza;
    77 	local stanza = event.stanza;
    78 	local username = jid_node(stanza.attr.to);
    78 	local username = jid_node(stanza.attr.to);
    79 	local room_jid = jid_bare(stanza.attr.from);
    79 	local room_jid = jid_bare(stanza.attr.from);
    80 
    80 
    81 	if joined_rooms:get(username, room_jid) then
    81 	if data:get(username, room_jid) then
    82 		module:log("debug", "handle_to_bare_jid %q, %s", room_jid, stanza);
    82 		module:log("debug", "handle_to_bare_jid %q, %s", room_jid, stanza);
    83 		-- Broadcast to clients
    83 		-- Broadcast to clients
    84 
    84 
    85 		if stanza.name == "message" and stanza.attr.type == "groupchat"
    85 		if stanza.name == "message" and stanza.attr.type == "groupchat"
    86 			and not stanza:get_child("body") and stanza:get_child("subject") then
    86 			and not stanza:get_child("body") and stanza:get_child("subject") then
    87 			room_state:set(username, room_jid, stanza:get_child_text("subject"));
    87 			data:set(username, room_jid, "subject", st.clone(stanza));
    88 		elseif stanza.name == "presence" then
    88 		elseif stanza.name == "presence" then
    89 			if stanza.attr.type == nil then
    89 			if stanza.attr.type == nil then
    90 				room_state:set(username, stanza.attr.from, st.preserialize(stanza));
    90 				data:set(username, room_jid, "presence", stanza.attr.from, st.clone(stanza));
    91 			elseif stanza.attr.type == "unavailable" then
    91 			elseif stanza.attr.type == "unavailable" then
    92 				room_state:set(username, stanza.attr.from, nil);
    92 				data:set(username, room_jid, "presence", stanza.attr.from, nil);
    93 			end
    93 			end
    94 		end
    94 		end
    95 
    95 
    96 		if users[username] then
    96 		if users[username] then
    97 			module:log("debug", "%s has sessions", username);
    97 			module:log("debug", "%s has sessions", username);