1 # ho_mkick.pl
  2 #
  3 # $Id: ho_mkick.pl,v 1.6 2004/08/22 20:19:26 jvunder REL_0_3 $
  4 #
  5 # Part of the Hybrid Oper Script Collection.
  6 #
  7 # This provides a /MKICK command to masskick clients from a channel.
  8 #
  9 # TODO:
 10 # * support multiple kicks in 1 line if the ircd supports it.
 11 
 12 # ---------------------------------------------------------------------
 13 
 14 use strict;
 15 use vars qw($VERSION %IRSSI $SCRIPT_NAME);
 16 
 17 use Irssi;
 18 use Irssi::Irc;
 19 use HOSC::again;
 20 use HOSC::again 'HOSC::Base';
 21 use HOSC::again 'HOSC::Tools';
 22 use Getopt::Long;
 23 
 24 # ---------------------------------------------------------------------
 25 
 26 ($VERSION) = '$Revision: 1.6 $' =~ / (\d+\.\d+) /;
 27 %IRSSI = (
 28     authors    => 'Garion',
 29     contact    => 'garion@efnet.nl',
 30     name    => 'ho_mkick.pl',
 31     description    => 'Masskick command for a channel.',
 32     license    => 'Public Domain',
 33     url        => 'http://www.garion.org/irssi/',
 34     changed    => '25 May 2004 22:53:46',
 35 );
 36 $SCRIPT_NAME = 'Masskick';
 37 
 38 
 39 # ---------------------------------------------------------------------
 40 
 41 sub cmd_mkick {
 42     my ($cmdline, $server, $chan) = @_;
 43 
 44     if ($cmdline =~ /^help/) {
 45         return print_help();
 46     }
 47 
 48     my $args = process_arguments($cmdline);
 49 
 50     if ($args->{help}) {
 51         return print_help();
 52     }
 53     
 54     if (!$server) {
 55         ho_print_error("Please use /MKICK in a window of the server ".
 56             "you want to masskick on.");
 57         return;
 58     }
 59     
 60     if (!defined $args->{channel}) {
 61         ho_print_error("<channel> argument missing. See /MKICK HELP for help.");
 62         return;
 63     }
 64 
 65     my $channel = $server->channel_find($args->{channel});
 66 
 67     if (!defined $channel) {
 68         ho_print_error("You are not on channel " . $args->{channel} .
 69             " on this server.");
 70         return;
 71     }
 72     if (!$channel->{ownnick}->{op}) {
 73         ho_print_error("You are not opped on channel " . $args->{channel} .
 74             " on this server.");
 75         return;
 76     }
 77 
 78     $args->{channel_obj} = $channel;
 79     $args->{server_obj}  = $server;
 80 
 81     if (!defined $args->{reason}) {
 82         $args->{reason} = Irssi::settings_get_str('ho_mkick_reason');
 83     }
 84 
 85     if (defined $args->{hostmask} && 
 86         $args->{hostmask} =~ /^(?:(.+)!)?(.+)@(.+)$/
 87     ) {
 88         $args->{nick} = $1 ? $1 : "*";
 89         $args->{user} = $2;
 90         $args->{host} = $3;
 91     } else {
 92         ho_print_error("Missing or invalid hostmask. See /MKICK HELP for help.");
 93         return;
 94     }
 95     
 96     ho_print('Simulation enabled.') if $args->{simulation};
 97     ho_print('Masskicking clients matching ' . 
 98         $args->{nick} . "!" .
 99         $args->{user} . "@" .
100         $args->{host} . " in " .
101         $args->{channel} . " for reason '" . $args->{reason} . "'.");
102 
103     perform_masskick($args);
104 }
105 
106 
107 sub perform_masskick {
108     my ($args) = @_;
109     ho_print("Performing masskick.");
110 
111     my $num_kicks = 0;
112     
113     for my $client ($args->{channel_obj}->nicks()) {
114         my $nick = $client->{nick};
115         # Don't kick myself!
116         next if $nick eq $args->{server_obj}->{nick};
117 
118         my $hostmask = $client->{host};
119         if (Irssi::mask_match_address($args->{nick} . '!' .
120             $args->{user} . '@' . $args->{host}, 
121             $nick, $hostmask)
122         ) {
123             if ($client->{op} && !$args->{ops}) {
124                 ho_print($nick . " is opped. Not kicking.")
125                     if $args->{verbose};
126                 next;
127             }
128             if ($client->{voice} && !($args->{voices} || $args->{ops})) {
129                 ho_print($nick . " is voiced. Not kicking.")
130                     if $args->{verbose};
131                 next;
132             }
133             my $rawcmd = "KICK " . $args->{channel} . " $nick :" . $args->{reason};
134             my $cmd = "KICK " . $args->{channel} . " $nick " . $args->{reason};
135             my $can_flood = Irssi::settings_get_bool('ho_mkick_can_flood');
136             if ($args->{simulation}) {
137                 ho_print($cmd);
138             } else {
139                 if ($can_flood) {
140                     $args->{server_obj}->send_raw_now($rawcmd);
141                 } else {
142                     $args->{server_obj}->command($cmd);
143                 }
144             }
145             $num_kicks++;
146         }    
147     }
148 
149     ho_print("Done. Kicked $num_kicks client" . 
150         ($num_kicks == 1 ? '' : 's') . ".");
151 }
152 
153 
154 sub process_arguments {
155     my ($arguments) = @_;
156     my $opt;
157 
158     # Removes double spaces in kick reason *shrug*
159     local @ARGV = split / +/, $arguments;
160 
161     my $res = GetOptions(
162         'ops'        => \$opt->{ops},
163         'voices'     => \$opt->{voices},
164         'sim'        => \$opt->{simulation},
165         'simulate'   => \$opt->{simulation},
166         'simulation' => \$opt->{simulation},
167         'verbose'    => \$opt->{verbose},
168     );
169 
170     # Get the channel.
171     if (@ARGV) {
172         $opt->{channel} = shift @ARGV;
173     }
174 
175     # Get the hostmask.
176     if (@ARGV) {
177         $opt->{hostmask} = shift @ARGV;
178     }
179 
180     # Reassemble the reason.
181     for my $arg (@ARGV) {
182         $opt->{reason} .= $arg . " ";
183     }
184     $opt->{reason} =~ s/ $// if defined $opt->{reason};
185     
186     return $opt;                             
187 }    
188 
189 # ---------------------------------------------------------------------
190 
191 ho_print_init_begin($SCRIPT_NAME);
192 
193 Irssi::command_bind('mkick', 'cmd_mkick');
194 
195 Irssi::settings_add_str('ho',  'ho_mkick_reason',    'Plonk!');
196 Irssi::settings_add_bool('ho', 'ho_mkick_can_flood', 0);
197 
198 ho_print_init_end($SCRIPT_NAME);
199 ho_print("Use /MKICK HELP for help.");
200 
201 # ---------------------------------------------------------------------
202 
203 sub print_help {
204     ho_print_help('head', $SCRIPT_NAME);
205 
206     ho_print_help('section', 'Syntax');
207     ho_print_help('syntax', 'MKICK [-simulation] [-ops] [-voices] <channel> <[nick!]user@host> [<reason>]');
208 
209     ho_print_help('section', 'Description');
210     ho_print_help(
211     "Masskicks all users in this channel matching the given hostmask. ".
212     "By default only non-opped users are kicked, but if ".
213     "you specify the -ops flag, ops are killed as well.".
214     "Same for voiced users and the -voices flag. The -ops flag overrules ".
215     "the -voices flag, so if you want to kick both ops and voices you only ".
216     "need to specify -ops."
217     );
218 }


syntax highlighted by Code2HTML, v. 0.9.1