1#
2# Usage: /MKICK [options] [mode] [mask] [reason]
3# Options:
4#	-n	normal kick
5#	-6	'2+4' kickmethod
6# Mode:
7#	-a	all on channel
8#	-o	chops
9#	-v	chvoices
10#	-d	users without op
11#	-l	users without op and voice
12# Settings.
13#	/SET masskick_default_reason [reason]
14#	/SET masskick_default_use_6method [On/Off]
15#
16
17use strict;
18use Irssi;
19use Irssi::Irc;
20use vars qw($VERSION %IRSSI);
21
22$VERSION = "0.9";
23%IRSSI = (
24	authors		=> 'Marcin Rozycki',
25	contact		=> 'derwan@irssi.pl',
26	name		=> 'mkick',
27	description	=> 'Masskick, usage: /mkick [-aovdln6 (hostmask)] <[:]reason>',
28	license		=> 'GNU GPL v2',
29	url		=> 'http://derwan.irssi.pl',
30	changed		=> 'Wed Oct  6 20:58:38 CEST 2004'
31);
32
33Irssi::theme_register([
34	'mkick_not_connected',	'Mkick: Not connected to server',
35	'mkick_not_chanwin',	'Mkick: Not joined to any channel',
36	'mkick_not_chanop',	'Mkick: You\'re not channel operator on {hilight $0}',
37	'mkick_syntax',		'Mkick: $0, use: /MKICK [-a|-o|-v|-d|-l] [-n|-6] (mask) [reason]',
38	'mkick_no_users',	'%_Mkick:%_ No users matching given criteria',
39	'mkick_kicklist',	'%_Mkick:%_ Send masskick for $1 users on $0: $2-'
40]);
41
42sub cmd_mkick
43{
44	my ($args, $server, $witem) = @_;
45
46	Irssi::printformat(MSGLEVEL_CRAP, "mkick_not_connected"), return if (!$server or !$server->{connected});
47	Irssi::printformat(MSGLEVEL_CRAP, "mkick_not_chanwin"), return if (!$witem or $witem->{type} !~ /^channel$/i);
48	Irssi::printformat(MSGLEVEL_CRAP, "mkick_not_chanop", $witem->{name}), return if (!$witem->{chanop});
49
50	my $reason = Irssi::settings_get_str("masskick_default_reason");
51	my $method = Irssi::settings_get_bool("masskick_default_use_6method");
52	my $servernick = $server->{nick};
53	my $channel = $witem->{name};
54	my $mode = undef;
55	my $mask = "*!*\@*";
56
57	my @kicklist = ();
58	my @nicklist = ();
59	my @args = split(/ +/, $args);
60
61	while ($_ = shift(@args))
62	{
63		/^..*!..*@..*$/ and $mask = "$&", next;
64		/^-(a|o|v|d|l)$/ and s/-//, $mode = $_, next;
65		/^-(n|6)$/ and $method = $_ =~ s/6//, next;
66		/^-/ and Irssi::printformat(MSGLEVEL_CRAP, "mkick_syntax", "Unknown argument: $_"), return;
67		/^:/ and s/^://;
68		$reason = ($#args >= 0) ? $_." ".join(" ", @args) : $_;
69		last;
70	};
71
72	unless ($mode) {
73		Irssi::printformat(MSGLEVEL_CRAP, "mkick_syntax", "Missing argument"), return if ($mask eq '*!*@*');
74		$mode = "a";
75	};
76
77	foreach my $hash ($witem->nicks())
78	{
79		my $nick = $hash->{nick};
80		next if ($nick eq $servernick or !$server->mask_match_address($mask, $nick, $hash->{host}));
81
82		my $isop = $hash->{op};
83		my $isvoice = $hash->{voice};
84
85		if ($mode eq "a" or
86		    $mode eq "o" && $isop or
87		    $mode eq "v" && $isvoice && !$isop or
88		    $mode eq "d" && !$isop or
89		    $mode eq "l" && !$isop && !$isvoice) {
90			push(@kicklist, $nick);
91			my $mod = ($isop == 1) ? "\@" : ($isvoice == 1) ? "+" : undef;
92			push(@nicklist, $mod.$nick);
93		};
94	};
95
96	Irssi::printformat(MSGLEVEL_CRAP, "mkick_no_users", $mask, $mode), return if ($#kicklist < 0);
97	Irssi::printformat(MSGLEVEL_CRAP, "mkick_kicklist", $channel, scalar(@nicklist), @nicklist);
98
99	if ($method > 0) {
100		$reason = substr($reason, 0, 15) if (length($reason) > 15);
101		while (@kicklist) {
102			$server->send_raw("KICK $channel ".join(",", @kicklist[0 .. $method])." :$reason");
103			@kicklist = @kicklist[($method + 1)..$#kicklist];
104			$method = ($method == 3 && $#kicklist > 3) ? 1 : 3;
105		};
106	} else {
107		$server->send_raw_split("KICK $channel ".join(",", @kicklist)." :$reason", 2, $server->{max_kicks_in_cmd});
108	};
109};
110
111Irssi::settings_add_str("misc", "masskick_default_reason", "Irssi BaBy!");
112Irssi::settings_add_bool("misc", "masskick_default_use_6method", 0);
113
114Irssi::command_bind("mkick", "cmd_mkick");
115