examples/evil.lua
changeset 68 742878c74b8e
parent 66 542f61e113cb
child 99 ed4676536ed9
--- a/examples/evil.lua	Sat Mar 28 19:43:12 2009 +0200
+++ b/examples/evil.lua	Tue Mar 31 18:35:34 2009 +0300
@@ -1,58 +1,110 @@
 
--- MALICIOUS STANZAS (XEP-0076)
-
--- library
-
-local lm = require 'lm'
-local iq = require 'iq'
+local lm   = require 'lm'
+local evil = require 'lm.evil'
 
--- public
+evil.handler (
+	function ( mess )
+		local evillevel = tonumber(main.option ( 'lua_evil_sensibility' ))
+		local mtype, smtype = mess:type ()
+		if evillevel > 1 then
+			main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type ' .. mtype .. '.' .. smtype .. ' detected!' )
+		elseif evillevel > 0 then
+			print ( 'Tainted by evil stanza of type ' .. mtype .. '.' .. smtype .. ' from ' .. ( mess:attribute ( 'from' ) or '... unknown in black' ) )
+		end
+		return main.yesno ( main.option ( 'lua_filter_evil' ) )
+	end )
 
-local O = {
-	handler =
-		function ( mess )
-			return false
-		end,
+local stat2xmpp = {
+	free     = 'chat',
+	online   = '',
+	away     = 'away',
+	dnd      = 'dnd',
+	notavail = 'xa',
+	offline  = 'unavailable',
 }
 
-local F = { }
-
-function F.handler ( handler )
-	O.handler = handler
-end
+-- TODO improve interface, check if we sending right thing for offline
+main.command ( 'evil',
+	function ( args )
+		local conn = lm.connection.bless ( main.connection () )
+		if args[1] == 'status' then
+			local text = ''
+			for i, mesg in ipairs ( args ) do
+				if i > 2 then
+					text = text .. ' ' .. mesg
+				end
+			end
+			local st = stat2xmpp[args[2]]
+			if not st then
+				st = ''
+			end
+			evil.presence ( conn, args.t, st, text:sub ( 2 ) )
+		else
+			local text = ''
+			if args[1] == 'message' then
+				for i, mesg in ipairs ( args ) do
+					if i > 1 then
+						text = text .. ' ' .. mesg
+					end
+				end
+			else
+				for i, mesg in ipairs ( args ) do
+					text = text .. ' ' .. mesg
+				end
+			end
+			local mtype = 'chat'
+			if args.k then
+				mtype = args.k
+			end
+			local who
+			if args.t then
+				who = args.t
+			else
+				who = main.current_buddy ()
+			end
+			evil.message ( conn, who, mtype, text:sub ( 2 ) )
+		end
+	end, true )
 
-function F.message ( conn, to, mtype, message )
-	conn:send ( lm.message.create { mtype = 'message-' .. mtype, to = to,
-			body = { message },
-			evil = { xmlns = 'http://jabber.org/protocol/evil' },
-		} )
-end
+commands_help['evil'] = "[-t jid] [status stat [message] | [-k message_type] [message] message]\n\nSends evil message or presence.\nmessage_type may be chat, normal, headline.\nNote, that for now it will not change mcabber's status."
+
+local evil_handler = lm.message_handler.new ( evil.stanza_handler )
+local evil_handler_registered = false
 
-function F.presence ( conn, to, status, message )
-	local mtype = 'presence-available'
-	if status == 'unavailable' then
-		mtype = 'presence-unavailable'
-		status = ''
+hooks_d['hook-post-connect'].evil =
+	function ( args )
+		lm.connection.bless( main.connection () ):handler ( evil_handler, 'iq',       'first' )
+		lm.connection.bless( main.connection () ):handler ( evil_handler, 'message',  'first' )
+		lm.connection.bless( main.connection () ):handler ( evil_handler, 'presence', 'first' )
+		evil_handler_registered = true
+		hooks_d['hook-post-connect'].evil = nil
+		hooks_d['hook-quit'].evil =
+			function ( args )
+				if evil_handler_registered then
+					lm.connection.bless( main.connection () ):handler ( evil_handler, 'iq'       )
+					lm.connection.bless( main.connection () ):handler ( evil_handler, 'message'  )
+					lm.connection.bless( main.connection () ):handler ( evil_handler, 'presence' )
+				end
+			end
 	end
-	conn:send ( lm.message.create { mtype = mtype, from = conn:jid (), to = to,
-			show   = { status },
-			status = { message },
-			evil   = { xmlns = 'http://jabber.org/protocol/evil' },
-		} )
-end
+
+local char2xmpp = {
+	f = 'chat',
+	o = '',
+	a = 'away',
+	d = 'dnd',
+	n = 'xa',
+	_ = 'unavailable',
+}
 
-function F.iq ( conn, to, action, contents, success, fail )
-	contents.evil = { xmlns = 'http://jabber.org/protocol/evil' }
-	iq.send ( conn, to, action, contents, success, fail )
-end
+-- hack, but working ;)
+hooks_d['hook-my-status-change'].evil =
+	function ( args )
+		if main.yesno ( main.option ( 'lua_evil_mode' ) ) then
+			evil.presence ( lm.connection.bless ( main.connection () ), nil, char2xmpp[args.new_status], args.message )
+		end
+	end
 
-function F.stanza_handler ( conn, mess )
-	local e = mess:child ( 'evil' )
-	if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/evil' then
-		return O.handler ( mess )
-	end
-end
-
-return F
+main.add_feature ( 'http://jabber.org/protocol/evil' )
 
 -- vim: se ts=4: --