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