html/operit.pl


   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 
  82 use strict;
  83 
  84 use 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 
  98 use Irssi 20021117; # timeout_add_once
  99 use Irssi::Irc;
 100 
 101 
 102 my $queue = 0;   # already queued an operit? (when?)
 103 my $disp = 0;    # already displayed kind notice about already queued operit?
 104 my $cmd = "";    # command issued
 105 my $target = ""; # who issued the command
 106 my $chan = "";   # object of the command
 107 
 108 my $coperit = 0;
 109 my $cinvait = 0;
 110 my $cdamode = 0;
 111 my $mpublic = 0;
 112 
 113 
 114 sub 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 
 186 sub event_userhost_error {
 187   Irssi::print "Operit userhost on $target failed, aborting the action...";
 188 
 189   $queue = $disp = 0;
 190 }
 191 
 192 
 193 sub 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 
 240 sub 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 
 253 sub cmd_operit {
 254   my ($data, $server, $channel) = @_;
 255   
 256   if ($data =~ /^(usage|help)/i) {
 257 
 258     foreach (split /\n/, <<USAGEE
 259 Operit:
 260 
 261 Local commands
 262 
 263 operit usage      - This help.
 264 operit help       - This help.
 265 operit status     - Display statistical information.
 266 
 267 Remote commands
 268 
 269 operit #chan      - Op the person in question on #chan.     (req. *)
 270 invait #chan      - Invait the person in question to #chan. (req. *)
 271 damode #chan      - Give the person in question the modes of #chan. (req. *)
 272 
 273 Variables
 274 
 275 operit_chans      - The channelmask operit/invait is permitted on. (* is *)
 276 operit_chans_deny - The channel(s) operit/invait is not permitted on. (* is *)
 277 operit_hosts_deny - The user\@host(s) operit/invait is not permitted from. (* is *)
 278 operit_deny       - Toogle this ON if you don't actually want invait/operit to function.
 279 operit_show_requests
 280                   - Toogle this OFF if you don't want to see messages about operit requests.
 281 operit_allow_public
 282                   - Toogle this OFF if you don't want requests written on channels to be proceeded.
 283 operit_public_delay
 284 		  - Set this to 0 if you don't want random delay between request and action.
 285 USAGEE
 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 
 304 Irssi::command_bind("operit", "cmd_operit");
 305 Irssi::signal_add("redir userhost_operit", "event_userhost_operit");
 306 Irssi::signal_add("redir userhost_operit_error", "event_userhost_error");
 307 Irssi::signal_add("default ctcp msg", "event_ctcp");
 308 Irssi::signal_add("event privmsg", "event_privmsg");
 309 
 310 
 311 Irssi::settings_add_str("operit", "operit_chans", "#* !*");
 312 Irssi::settings_add_str("operit", "operit_chans_deny", "#ircophackers");
 313 Irssi::settings_add_str("operit", "operit_hosts_deny", "*!*@*.lamehost1 *lamehost2");
 314 Irssi::settings_add_bool("operit", "operit_deny", 0);
 315 Irssi::settings_add_bool("operit", "operit_show_requests", 1);
 316 Irssi::settings_add_bool("operit", "operit_allow_public", 1);
 317 Irssi::settings_add_str("operit", "operit_public_delay", 5);
 318 
 319 
 320 Irssi::print("Operit $VERSION loaded... see command 'operit usage'");