1### operit.pl (c) 2002, 2003 Petr Baudis <pasky@ucw.cz> 2# 3## Perform certain action (invite/op/...) on request authenticated by the 4## IRC operator status. 5# 6## See http://pasky.ji.cz/~pasky/dev/irssi/ for the latest version. 7# 8## Thanks to: 9## mofo <mick@mofo.nl> (patches) 10## Garion <garion@dnsspam.nl> (ideas) 11## Borys <borys@irc.pl> (ideas) 12## devastor <devastor@idiosynkrasia.net>(bug reports) 13## babar <babar@magicnet.org> (delay patch) 14# 15## $Id: operit.pl,v 1.14 2003/09/06 12:27:11 pasky Exp pasky $ 16# 17# $Log: operit.pl,v $ 18# Revision 1.14 2003/09/06 12:27:11 pasky 19# Okay, so while I'm at it updated other instance of my email addy, copyright, bunch of grammar fixes and documented the operit_public_delay variable. 20# 21# Revision 1.13 2003/09/06 12:25:09 pasky 22# Updated my email addy. 23# 24# Revision 1.12 2003/09/06 12:23:50 pasky 25# Added support for randomly delayed operit - if operit is public, the delay is zero to five seconds by default - this helps greatly if there is a lot of operit-enabled clients on a channel. Patch by Babar <babar@magicnet.org> and me. 26# 27# Revision 1.11 2003/03/20 08:58:18 pasky 28# Match whole channel, not random part, when checking for deny_channels and deny_hosts. So you can deny operits at #iraq but still allow them at #iraqlive ;-). Thanks to viha for cooperation during testing. 29# 30# Revision 1.10 2002/11/29 16:51:46 pasky 31# Don't play with channels we aren't on. Fixes occassional 'can't call method command on undefined value'; thanks to devastor for a report. 32# 33# Revision 1.9 2002/10/19 13:12:34 pasky 34# Introduced operit_allow_public (by default on), which toggles accepting of public (on-channel) operit requests. Idea by Borys. 35# 36# Revision 1.8 2002/10/13 12:33:13 pasky 37# We don't care about /^operit [^!#&]/ anymore. Thanks fly to Garion for suggestion. 38# 39# Revision 1.7 2002/10/07 14:16:58 pasky 40# Added operit_show_requests bool setting (by default 1, that is same behaviour as now). 41# 42# Revision 1.6 2002/09/01 12:27:08 pasky 43# Erm, compilation fixes. 44# 45# Revision 1.5 2002/09/01 12:24:24 pasky 46# Allow specification of more channels separated by a comma in requests. Changed default value of operit_hosts_deny to something harmless. Patch by mofo <mick@mofo.nl>. 47# 48# Revision 1.4 2002/03/13 13:17:36 pasky 49# remove one debug message accidentally left there 50# 51# Revision 1.3 2002/03/12 18:02:37 pasky 52# invait actually works now 53# 54# Revision 1.2 2002/02/05 17:47:13 pasky 55# fixed many things :^). now it basically works how it should... 56# 57# Revision 1.1 2002/02/05 16:47:09 pasky 58# Initial revision 59# 60# 61### 62 63### Inspired by Operit-2.01b+enge script for ircII+ clients by 64## - Viha (Viha@Theblah.Org) 65# - Karzan (Kari@Theblah.Org) 66# 67## Credits also go to: 68# - LuckyS (lucky@binet.lv) [bug reports] 69# - Fusion (fusion@nuts.edu) [bug reports] 70# - RA^v^EN (raven@sky.siol.org) [bug reports] 71# - tumble (tumble@openface.ca) [beta testing] 72# - koopal (andre@nl.uu.net) [script ideas] 73# - pt (primetime@wnol.net) [script ideas] 74# - delta (delta@rus.uni-stuttgart.de) [script ideas] 75# - pht (svobodam@irc.vsp.cz) [bug reports] 76# - enge (engerim@magicnet.org) [modifications] 77# 78### The most recent version can always be found at 79# http://www.vip.fi/~viha/irc/ 80### 81 82use strict; 83 84use vars qw ($VERSION %IRSSI $rcsid); 85 86$rcsid = '$Id: operit.pl,v 1.14 2003/09/06 12:27:11 pasky Exp pasky $'; 87($VERSION) = '$Revision: 1.14 $' =~ / (\d+\.\d+) /; 88%IRSSI = ( 89 name => 'operit', 90 authors => 'Petr Baudis', 91 contact => 'pasky@ucw.cz', 92 url => 'http://pasky.ji.cz/~pasky/dev/irssi/', 93 license => 'BSD', 94 description => 'Perform certain action (invite/op/...) on request authenticated by the IRC operator status.' 95 ); 96 97 98use Irssi 20021117; # timeout_add_once 99use Irssi::Irc; 100 101 102my $queue = 0; # already queued an operit? (when?) 103my $disp = 0; # already displayed kind notice about already queued operit? 104my $cmd = ""; # command issued 105my $target = ""; # who issued the command 106my $chan = ""; # object of the command 107 108my $coperit = 0; 109my $cinvait = 0; 110my $cdamode = 0; 111my $mpublic = 0; 112 113 114sub event_privmsg { 115 my ($server, $data, $nick, $address) = @_; 116 my ($msgtarget, $text) = split(/ :/, $data, 2); 117 118 return if (Irssi::settings_get_bool("operit_deny")); 119 120 if ($text =~ s/^(invait|operit|damode)( .*)?$/$2/i) { 121 if (uc($msgtarget) eq uc($server->{nick})) { 122 $mpublic = 0; 123 } else { 124 return unless (Irssi::settings_get_bool("operit_allow_public")); 125 $mpublic = 1; 126 } 127 128 if (time - $queue < 10) { 129 Irssi::print "Operit currently deactivated or queued. Request ignored." 130 if (time - $disp > 20); 131 $disp = time; 132 return; 133 } 134 135 $cmd = $1; $target = $nick; $queue = 0; $disp = 0; 136 137# if ($msgtarget eq $N or $cmd eq 'invait') { 138 if (1) { 139 ($_, $chan) = split /\s+/, $text; # oh.. oh well :) 140 my $a = 0; 141 142 $chan = $msgtarget if (not $chan and $msgtarget ne $server->{nick}); 143 return unless ($chan =~ /^[#!&]/); 144 145 foreach (split /\s+/, Irssi::settings_get_str("operit_chans")) { 146 s/\./\\./; 147 s/\*/.*/g; 148 if ($chan =~ /^$_$/i) { 149 $a++; 150 } 151 } 152 153 unless ($a) { 154 Irssi::print "Unauthorized $cmd $chan by $target (not in operit_chans)" if (Irssi::settings_get_bool("operit_show_requests")); 155 return; 156 } 157 158 foreach (split /\s+/, Irssi::settings_get_str("operit_chans_deny")) { 159 s/\./\\./; 160 s/\*/.*/g; 161 if ($chan =~ /^$_$/i) { 162 Irssi::print "Unauthorized $cmd $chan by $target (in operit_chans_deny)" if (Irssi::settings_get_bool("operit_show_requests")); 163 return; 164 } 165 } 166 167 foreach (split /^\s+$/, Irssi::settings_get_str("operit_hosts_deny")) { 168 s/\./\\./; 169 s/\*/.*/g; 170 if ($address =~ /$_/i) { 171 Irssi::print "Unauthorized $cmd $chan by $target <$address> (in operit_hosts_deny)" if (Irssi::settings_get_bool("operit_show_requests")); 172 return; 173 } 174 } 175 176 $queue = time; 177 178 $server->redirect_event("userhost", 1, $target, 0, 'redir userhost_operit_error', 179 {"event 302" => "redir userhost_operit"}); 180 181 $server->command("USERHOST $target"); 182 } 183 } 184} 185 186sub event_userhost_error { 187 Irssi::print "Operit userhost on $target failed, aborting the action..."; 188 189 $queue = $disp = 0; 190} 191 192 193sub event_userhost_operit { 194 my ($server, $data) = @_; 195 my ($mynick, $reply) = split(/ +/, $data); 196 my ($nick, $user, $host) = $reply =~ /^:(.*)=.(.*)@(.*)/; 197 198 unless ($nick =~ s/\*$//) { 199 Irssi::print "$target requested UNAUTHORIZED $cmd on channel $chan" if (Irssi::settings_get_bool("operit_show_requests")); 200 return; 201 } 202 203 Irssi::print "$target requested $cmd on channel $chan" if (Irssi::settings_get_bool("operit_show_requests")); 204 205 foreach my $chansplit (split(/\,/, $chan)) { 206 my $channel = $server->channel_find($chansplit); 207 208 next unless ($channel); 209 210 if (lc($cmd) eq "operit") { 211 if ($mpublic) { 212 my $precision = 10; # Delay precision (10 = 1/10s) 213 my $rdelay = int(rand(Irssi::settings_get_str("operit_public_delay") * $precision)) * 1000 / $precision; 214 215 Irssi::print "Waiting " . ($rdelay / 1000) . " seconds before executing PUBLIC $cmd for $target on $chan"; 216 Irssi::timeout_add_once($rdelay + 11, sub { # XXX why + 10 ? --pasky 217 my ($target, $channel) = @{$_[0]}; 218 my ($tgrec) = $channel->nick_find($target); 219 $channel->command("op $target") unless ($tgrec and $tgrec->{'op'}); 220 }, [ $target, $channel ]); 221 } else { 222 $channel->command("op $target"); 223 } 224 $coperit++; 225 226 } elsif (lc($cmd) eq "invait") { 227 $server->command("invite $target $chansplit"); 228 $cinvait++; 229 230 } elsif (lc($cmd) eq "damode") { 231 $server->command("notice $target mode for $chansplit is +$channel->{mode}"); 232 $cdamode++; 233 } 234 } 235 236 $queue = $disp = 0; 237} 238 239 240sub event_ctcp { 241 my ($server, $data, $nick, $address, $target) = @_; 242 243 return if (Irssi::settings_get_bool("operit_deny")); 244 245 if ($data =~ /^operit/i) { 246 Irssi::print "$nick requested operit thru CTCP... no way!" if (Irssi::settings_get_bool("operit_show_requests")); 247 $server->command("NOTICE $nick ssshht!"); 248 Irssi::signal_stop(); 249 } 250} 251 252 253sub cmd_operit { 254 my ($data, $server, $channel) = @_; 255 256 if ($data =~ /^(usage|help)/i) { 257 258 foreach (split /\n/, <<USAGEE 259Operit: 260 261Local commands 262 263operit usage - This help. 264operit help - This help. 265operit status - Display statistical information. 266 267Remote commands 268 269operit #chan - Op the person in question on #chan. (req. *) 270invait #chan - Invait the person in question to #chan. (req. *) 271damode #chan - Give the person in question the modes of #chan. (req. *) 272 273Variables 274 275operit_chans - The channelmask operit/invait is permitted on. (* is *) 276operit_chans_deny - The channel(s) operit/invait is not permitted on. (* is *) 277operit_hosts_deny - The user\@host(s) operit/invait is not permitted from. (* is *) 278operit_deny - Toogle this ON if you don't actually want invait/operit to function. 279operit_show_requests 280 - Toogle this OFF if you don't want to see messages about operit requests. 281operit_allow_public 282 - Toogle this OFF if you don't want requests written on channels to be proceeded. 283operit_public_delay 284 - Set this to 0 if you don't want random delay between request and action. 285USAGEE 286 ) { 287 Irssi::print $_; 288 } 289 290 } elsif ($data =~ /^status/i) { 291 my $ctotal = $coperit + $cinvait + $cdamode; 292 293 Irssi::print "Operit $VERSION Status:"; 294 Irssi::print "The last person to request $cmd was $target [$chan]."; 295 Irssi::print "This session has served $coperit op-requests, $cinvait invite-requests and $cdamode mode-requests."; 296 Irssi::print "Making a total of $ctotal succesful requests."; 297 298 } else { 299 Irssi::print "Excuse moi, sir? I guess that you want /operit usage ..?"; 300 } 301} 302 303 304Irssi::command_bind("operit", "cmd_operit"); 305Irssi::signal_add("redir userhost_operit", "event_userhost_operit"); 306Irssi::signal_add("redir userhost_operit_error", "event_userhost_error"); 307Irssi::signal_add("default ctcp msg", "event_ctcp"); 308Irssi::signal_add("event privmsg", "event_privmsg"); 309 310 311Irssi::settings_add_str("operit", "operit_chans", "#* !*"); 312Irssi::settings_add_str("operit", "operit_chans_deny", "#ircophackers"); 313Irssi::settings_add_str("operit", "operit_hosts_deny", "*!*@*.lamehost1 *lamehost2"); 314Irssi::settings_add_bool("operit", "operit_deny", 0); 315Irssi::settings_add_bool("operit", "operit_show_requests", 1); 316Irssi::settings_add_bool("operit", "operit_allow_public", 1); 317Irssi::settings_add_str("operit", "operit_public_delay", 5); 318 319 320Irssi::print("Operit $VERSION loaded... see command 'operit usage'"); 321