1use strict;
2use Irssi;
3use Irssi::Irc;
4
5use vars qw($VERSION %IRSSI);
6
7$VERSION="0.3";
8%IRSSI = (
9	authors=> 'BC-bd',
10	contact=> 'bd@bc-bd.org',
11	name=> 'ai',
12	description=> 'Puts people on ignore if they do a public away. See source for options.',
13	license=> 'GPL v2',
14	url=> 'https://bc-bd.org/svn/repos/irssi/trunk/',
15);
16
17# $Id: ai.pl,v 1.4 2002/06/02 15:20:03 bd Exp $
18# for irssi 0.8.4 by bd@bc-bd.org
19#
20#########
21# USAGE
22###
23#
24# Examples:
25#
26#	Ignore people saying "away"
27#		/set ai_words away
28#
29#	Ignore people saying "gone for good" or "back"
30#		/set ai_words gone for good,back
31#
32#	Ignore people for 500 seconds
33#		/set ai_time 500
34#
35#	Ignore people forever
36#		/set ai_time 0
37#
38#	Ignore people only on channels #foo,#bar
39#		/set ai_ignore_only_in ON
40#		/set ai_channels #foo,#bar
41#
42#	Ignore people on all channels BUT #foo,#bar
43#		/set ai_ignore_only_in OFF
44#		/set ai_channels #foo,#bar
45#
46#	Ignore people on all channels
47#		/set ai_ignore_only_in OFF
48#		/set -clear ai_channels
49#
50#	Perform a command on ignore (e.g send them a message)
51#		/set ai_command ^msg -$C $N no "$W" in $T please
52#
53#	would become on #foo on chatnet bar from nick dude with "dude is away"
54#		/msg -cbar dude no "away" in #foo please
55#
56#	look further down for details
57#
58#	Per channel command on #irssi:
59#		/ai #irssi ^say foobar
60#
61#	delete channel command in #irssi:
62#		/ai #irssi
63#
64#########
65# OPTIONS
66#########
67#
68# /set ai_words [expr[,]+]+
69#		* expr  : comma seperated list of expressions that should trigger an ignore
70#		  e.g.  : away,foo,bar baz bat,bam
71#
72# /set ai_command [command]
73#		* command  : to be executed on a triggered ignore.
74#		  /set -clear ai_command to disable. The following $'s are expanded
75#		  ( see the default command for an example ):
76#		    $C : Chatnet (e.g. IRCnet, DALNet, ...)
77#		    $N : Nick (some dude)
78#		    $W : Word (the word(s) that triggered the ignore
79#		    $T : Target (e.g. the channel)
80#
81# /set ai_channels [#channel[ ]]+
82#		* #channel  : space seperated list of channels, see ai_ignore_only_in
83#
84# /set ai_time <seconds>
85#		* seconds  : number of seconds to wait before removing the ignore
86#
87# /set ai_ignore_only_in <ON|OFF>
88#		* ON  : only trigger ignores in ai_channels
89#		* OFF : trigger ignores in all channels EXCEPT ai_channels
90#
91# /set ai_display <ON|OFF>
92#		* ON  : log whole sentence
93#		* OFF : only log word that matched regex
94#
95###
96################
97###
98#
99# Changelog
100#
101# Version 0.4
102# 	- added optional sentence output
103#
104# Version 0.3
105#	- added per channel command support
106#	- the command is now executed in the channel the event occured
107#	- changed the expand char from % to $
108#
109# Version 0.2
110#  - changed MSGLVL_ALL to MSGLVL_ACTIONS to avoid problems
111#	  with channels with ignored Levels
112#
113# Version 0.1
114#  - initial release
115#
116###
117################
118
119sub expand {
120  my ($string, %format) = @_;
121  my ($exp, $repl);
122  $string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format));
123  return $string;
124}
125
126sub combineSettings {
127	my ($setting,$string,$match) = @_;
128
129	$match =  quotemeta($match);
130
131	if ($setting) {
132		if ($string !~ /$match\b/i) {
133			return 1;
134		}
135	} else {
136		if ($string =~ /$match\b/i) {
137			return 1;
138		}
139	}
140
141	return 0;
142}
143
144sub sig_action {
145	my ($server,$msg,$nick,$address,$target) = @_;
146
147	my $command;
148
149	if ($server->ignore_check($nick, $address, $target, $msg, MSGLEVEL_ACTIONS)) {
150		return;
151	}
152
153	if (combineSettings(Irssi::settings_get_bool('ai_ignore_only_in'),
154		Irssi::settings_get_str('ai_channels'),$target)) {
155		return ;
156	}
157
158	my @words = split(',',Irssi::settings_get_str('ai_words'));
159
160	foreach (@words) {
161		if ($msg =~ /$_/i) {
162			my $word = $_;
163
164			my $sentence = $word;
165
166			my $channel = $server->channel_find($target);
167			my $n = $channel->nick_find($nick);
168
169			my $type = Irssi::Irc::MASK_USER | Irssi::Irc::MASK_DOMAIN;
170			my $mask = Irssi::Irc::get_mask($n->{nick}, $n->{host}, $type);
171
172			my $time = Irssi::settings_get_int('ai_time');
173			if ($time == 0) {
174				$time = "";
175			} else {
176				$time = "-time ".$time;
177			}
178			Irssi::command("^ignore ".$time." $mask");
179
180			if (Irssi::settings_get_bool('ai_display')) {
181				$sentence = $msg
182			}
183			Irssi::print("Ignoring $nick$target\@$server->{chatnet} because of '$sentence'");
184
185			my %commands = stringToHash('`',Irssi::settings_get_str('ai_commands'));
186			if (defined $commands{$target}) {
187				$command = $commands{$target};
188			} else {
189				$command = Irssi::settings_get_str('ai_command');
190			}
191
192			if ($command ne "") {
193				$command = expand($command,"C",$server->{tag},"N",$nick,"T",$target,"W",$word);
194				$server->window_item_find($target)->command($command);
195				$server->window_item_find($target)->print($command);
196			}
197
198			return;
199		}
200	}
201}
202
203sub stringToHash {
204	my ($delim,$str) = @_;
205
206	return split($delim,$str);
207}
208
209sub hashToString {
210	my ($delim,%hash) = @_;
211
212	return join($delim,%hash);
213}
214
215sub colorCommand {
216	my ($com) = @_;
217
218	$com =~ s/\$(.)/%_\$$1%_/g;
219
220	return $com;
221}
222
223sub cmd_ai {
224	my ($data, $server, $channel) = @_;
225
226	my $chan = $data;
227	$chan =~ s/ .*//;
228	$data =~ s/^\Q$chan\E *//;
229
230	my %command = stringToHash('`',Irssi::settings_get_str('ai_commands'));
231
232	if ($chan eq "") {
233		foreach my $key (keys(%command)) {
234			Irssi::print("AI: %_$key%_ = ".colorCommand($command{$key}));
235		}
236
237		Irssi::print("AI: placeholders: %_\$C%_)hatnet %_\$N%_)ick %_\$W%_)ord %_\$T%_)arget");
238		Irssi::print("AI: not enough parameters: ai <channel> [command]");
239
240		return;
241	}
242
243	if ($data eq "") {
244		delete($command{$chan});
245	} else {
246		$command{$chan} = $data;
247	}
248
249	Irssi::settings_set_str('ai_commands',hashToString('`',%command));
250
251	Irssi::print("AI: command on %_$chan%_ now: '".colorCommand($data)."'");
252}
253
254Irssi::command_bind('ai', 'cmd_ai');
255
256# "message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target
257Irssi::signal_add_first('message irc action', 'sig_action');
258
259Irssi::settings_add_str('misc', 'ai_commands', '');
260Irssi::settings_add_str('misc', 'ai_words', 'away,gone,ist auf');
261Irssi::settings_add_str('misc', 'ai_command', '^msg -$C $N no "$W" in $T please');
262Irssi::settings_add_str('misc', 'ai_channels', '');
263Irssi::settings_add_int('misc', 'ai_time', 500);
264Irssi::settings_add_bool('misc', 'ai_ignore_only_in', 0);
265Irssi::settings_add_bool('misc', 'ai_display', 0);
266