html/kicks.pl
1 #!/usr/bin/perl -w
2 # various kick and ban commands
3 # by c0ffee
4 # - http://www.penguin-breeder.org/irssi/
5
6 #<scriptinfo>
7 use vars qw($VERSION %IRSSI);
8
9 use Irssi 20020120;
10 $VERSION = "0.26";
11 %IRSSI = (
12 authors => "c0ffee",
13 contact => "c0ffee\@penguin-breeder.org",
14 name => "Various kick and ban commands",
15 description => "Enhances /k /kb and /kn with some nice options.",
16 license => "Public Domain",
17 url => "http://www.penguin-breeder.org/irssi/",
18 changed => "Tue Nov 14 23:19:19 CET 2006",
19 );
20 #</scriptinfo>
21
22 my %kickreasons = (
23 default => ["random kick victim",
24 "no",
25 "are you stupid?",
26 "i don't like you, go away!",
27 "oh, fsck off",
28 "waste other ppls time, elsewhere",
29 "get out and STAY OUT",
30 "don't come back",
31 "no thanks",
32 "on popular demand, you are now leaving the channel",
33 "\$N",
34 "*void*",
35 "/part is the command you're looking for",
36 "this is the irssi of borg. your mIRC will be assimilated. resistance is futile.",
37 "Autokick! mwahahahah!"
38 ],
39 none => [""],
40 topic => ["\$topic"],
41 );
42
43
44 # fine tune the script for different chatnets
45 # cmdline_k regular expr that matches a correct cmdline for /k
46 # req_chan 0/1 whether the channel is always part of the cmdline
47 # num_nicks number of nicks ... (-1 = inf)
48 # start_with_dash 0/1 whether the normal cmdline may start with a dash
49 # match_chn matches channels
50 # match_n match nicks
51 # match_reason matches reasons
52 # default_reason reason to give as "no reason"
53 my %cfg = (
54 IRC => {
55 cmdline_k => '\s*([!#+&][^\x0\a\n\r ]*)\s+[-\[\]\\\\\`{}\w_|^\'~]+(,[-\[\]\\\\\`{}\w_|^\'~]+)*\s+\S.*',
56 req_chan => 0,
57 num_nicks => 3, # actually, /k takes more, but
58 # normal irc servers only take
59 # three in a row
60 start_with_dash => 1,
61 match_chn => '([!#+&][^\x0\a\n\r ]*)\s',
62 match_n => '(?:^|\s+)([-\[\]\\\\\`{}\w_|^\'~]+(?:,[-\[\]\\\\\`{}\w_|^\']+)*)',
63 match_reason => '^\s*[!#+&][^\x0\a\n\r ]*\s+[-\[\]\\\\\`{}\w_|^\'~]+(?:,[-\[\]\\\\\`{}\w_|^\'~]+)*\s+(\S.*)$',
64 default_reason => '$N'
65 },
66
67 SILC => {
68 cmdline_k => '\s*[^\x0-\x20\*\?,@!]+\s+[^\x0-\x20\*\?,@!]+\s+\S.*',
69 req_chan => 1,
70 num_nicks => 1,
71 start_with_dash => 0,
72 match_chn => '\s*([^\x0-\x20\*\?,@!]+)\s+[^\x0-\x20\*\?,@!]+(?:,[^\x0-\x20\*\?,@!]+)*',
73 match_n => '\s*(?:[^\x0-\x20\*\?,@!]+\s+)?([^\x0-\x20\*\?,@!]+(?:,[^\x0-\x20\*\?,@!]+)*)',
74 match_reason => '\s*[^\x0-\x20\*\?,@!]+\s+[^\x0-\x20\*\?,@!]+(?:,[^\x0-\x20\*\?,@!]+)*\s+(\S.*)',
75 default_reason => '$N'
76 }
77 );
78
79 sub initialize {
80
81 my $conf_file = Irssi::settings_get_str("kicks_configuration");
82 $conf_file =~ s/~/$ENV{HOME}/;
83 my ($basedir) = $conf_file =~ /^(.*\/).*?/;
84
85 if (-f $conf_file) {
86 open CONF, $conf_file;
87
88 while (<CONF>) {
89 $line++;
90
91 next if /^\s*#/;
92
93 chomp;
94 ($key, $reasons) = /^(\S+)\s+(.+)\s*$/ or next;
95
96 if ($reasons =~ /\`([^\s]+).*?\`/) {
97 $kickreasons{$key} = "$reasons";
98 Irssi::print("Added executable $1 as $key...");
99 next;
100 }
101
102 $reasons =~ s/^"(.*)"$/$1/;
103 $reasons =~ s/~/$ENV{HOME}/;
104 $reasons =~ s/^([^\/])/$basedir$1/;
105
106 if (-f $reasons) {
107
108 $kickreasons{$key} = [];
109
110 open REASON, $reasons;
111
112 while (<REASON>) {
113 chomp;
114 push @{$kickreasons{$key}}, $_;
115 }
116
117 close REASON;
118 Irssi::print("Loaded $reasons as $key...");
119 } else {
120 Irssi::print("can't parse config line $line...");
121 }
122 }
123 close CONF;
124 } else {
125 Irssi::print("Could not find configuration file for kicks...");
126 Irssi::print("... use /set kicks_configuration <file>");
127 }
128 }
129
130
131 sub get_a_reason {
132 my ($topic) = @_;
133
134
135 return "" if not defined $kickreasons{$topic};
136
137 $_ = eval $kickreasons{$topic}, chomp, s/[\n\t]+/ /mg, return $_
138 if ref($kickreasons{$topic}) ne "ARRAY";
139
140 return $kickreasons{$topic}[rand @{$kickreasons{$topic}}];
141
142 }
143
144 sub cmd_realkick {
145 my ($data, $server, $channel, $cmd) = @_;
146 my $reasons = "default";
147
148 return if not $server
149 or not defined $cfg{$server->{chat_type}}
150 or not $channel
151 or $data =~ /^$cfg{$server->{chat_type}}{cmdline_k}$/;
152
153 Irssi::signal_stop();
154
155 # let's see whether some options where supplied
156 $default = Irssi::settings_get_str("default_kick_options");
157 $data = "$default $data" if not $default =~ /^\s*$/;
158 @opts = split /\s+/, $data;
159
160 while (($opt) = (shift @opts) =~ /^\s*-(\S+)/) {
161
162 $data =~ s/^\s*--\s+//, last if $opt eq "-";
163
164 $data =~ s/^\s*-$opt\s+//,
165 $reasons = lc $opt,
166 next if defined $kickreasons{lc $opt};
167
168 last if $cfg{$server->{chat_type}}{start_with_dash};
169
170 Irssi::print("Unknown option -$opt");
171 $fail = true;
172
173 }
174
175 return if $fail;
176
177 $chn = "";
178 ($chn) = $data =~ /^$cfg{$server->{chat_type}}{match_chn}/;
179
180 if ($cfg{$server->{chat_type}}{req_chan} && ($chn eq "")) {
181 Irssi::print "Not joined to any channel";
182 return;
183 }
184
185 # do we need to add a channel?
186 if ($chn eq "") {
187 Irssi::print("Not joined to any channel"), return
188 if $channel->{type} ne "CHANNEL";
189 $chn = $channel->{name};
190
191 $data = "$chn $data";
192 }
193
194 # is a reason already supplied?
195 $reason = get_a_reason($reasons)
196 if not (($reason) = $data =~ /$cfg{$server->{chat_type}}{match_reason}/);
197
198 $reason = $cfg{$server->{chat_type}}{default_reason}
199 if $reason =~ /^\s*$/;
200
201 @nicks = split /,/, ($data =~ /$cfg{$server->{chat_type}}{match_n}/)[0];
202 $num_nicks = $cfg{$server->{chat_type}}{num_nicks};
203 $num_nicks = @nicks if $num_nicks <= 0;
204
205 undef @commands;
206
207 while (@nicks) {
208 $tmp = ($chn ne "" ? "$chn " : "") .
209 join ",", (splice @nicks,0,$num_nicks);
210 $tmp =~ s/([;\\\$])/\\$1/g;
211 push @commands, "$tmp $reason";
212 }
213
214 foreach (@commands) {
215 if ($_ =~ /^$cfg{$server->{chat_type}}{cmdline_k}$/) {
216 s/\s+$//;
217 $channel->command("EVAL $cmd $_")
218 } else {
219 Irssi::print("BUG: generated invalid $cmd command: $_");
220 }
221 }
222 }
223
224 sub cmd_kick {
225 my ($data, $server, $channel) = @_;
226
227 cmd_realkick $data, $server, $channel, "KICK";
228
229 }
230
231 sub cmd_kickban {
232 my ($data, $server, $channel) = @_;
233
234 cmd_realkick $data, $server, $channel, "KICKBAN";
235
236 }
237
238 Irssi::settings_add_str("misc", "default_kick_options", "");
239 Irssi::settings_add_str("misc", "kicks_configuration",
240 Irssi::get_irssi_dir() . "/kicks.conf");
241
242 Irssi::command_bind("kick", "cmd_kick");
243 Irssi::command_bind("kickban", "cmd_kickban");
244
245 initialize();
246