1##
2# autorejoinpunish - 	your solution for banning people who don't
3#			know what kicks are for.
4# This script is for irssi 0.8.4, and was written by Paul Raade,
5# laaama in IRCNet.
6##
7# Explanations for the settings, with defaults shown:
8#
9# /set autorejoinpunish_time_limit 3
10# 	- The time limit in seconds for measuring what is an
11#	  autorejoin, and what is not.
12# /set autorejoinpunish_kickban_message Kickban for autorejoining.
13# 	- Kick reason, if kickban was selected.
14# /set autorejoinpunish_knockout ON
15# 	- Whether kick or knockout. As default, knockout is
16#	  selected, so that the bans will be removed automatically.
17# /set autorejoinpunish_knockout_time 60
18# 	- Time in seconds how long a ban will be kept if
19#	  knockout is selected.
20# /set autorejoinpunish_knockout_message Temporary ban for autorejoining.
21# 	- Kick reason, if knockout was selected.
22# /set autorejoinpunish_channels
23# 	- Space separated list of channels on which autorejoin punishment
24#	  be used will
25# /set autorejoinpunish_only_own_kicks ON
26#	- If set ON, only people kicked by you will be banned.
27##
28# Changelog:
29# - 0.2: Better way of checking channels, /set autorejoinpunish_only_own_kicks added.
30# - 0.1: Initial release.
31##
32# Happy banning! ;)
33##
34
35use strict;
36use Irssi qw(settings_get_str settings_get_int settings_get_bool
37timeout_add settings_add_int settings_add_str settings_add_bool
38signal_add_first command server_find_tag);
39
40use vars qw(%IRSSI $VERSION);
41$VERSION = '0.3';
42%IRSSI = (
43	authors		=> 'Paul \'laaama\' Raade',
44	contact 	=> 'paul\@raade.org',
45	name		=> 'Autorejoin punisher',
46	description	=> 'Kickbans or knockouts people who use autorejoin on kick.',
47	license		=> 'BSD',
48	url		=> 'http://www.raade.org/~paul/irssi/scripts/',
49	changes		=> 'Changed signals to be added to the top of the list to make the script work with scripts that stop the signals (autorealname, for example).',
50	changed		=> 'Thu 02 May 2002, 22:04:48 EEST'
51);
52
53my %victims;
54my %bans;
55
56sub message_kick { # Set a time stamp for people who are kicked.
57	#  "message kick", SERVER_REC, char *channel, char *nick, char *kicker, char *address, char *reason
58	my ($server, $channel, $nick, $kicker, $address, undef) = @_;
59	if ((settings_get_bool('autorejoinpunish_only_own_kicks') == 0) || (settings_get_bool('autorejoinpunish_only_own_kicks') == 1 && ($kicker eq $server->{nick}) )) {
60		foreach my $item (split(' ', lc(settings_get_str('autorejoinpunish_channels')))) {
61			if ((lc $channel) eq $item) { $victims{$channel}{$nick} = time(); }
62		}
63	}
64}
65
66sub message_join { # Check for recent kicks,
67	# "message join", SERVER_REC, char *channel, char *nick, char *address
68	my ($server, $channel, $nick, $address) = @_;
69	if ($victims{$channel}{$nick} && ((time()-$victims{$channel}{$nick}) <= settings_get_int('autorejoinpunish_time_limit'))) {
70		if (settings_get_bool('autorejoinpunish_knockout') == 1) {
71			$server->command('mode' . ' ' . $channel . ' +b *!' . $address);
72			$server->command('kick' . ' ' . $channel . ' ' . $nick . ' ' . settings_get_str('autorejoinpunish_knockout_message'));
73			$bans{$server->{tag}}{time()} = $channel . '/' . $address;
74		} else {
75			$server->command('mode' . ' ' . $channel . ' +b *!' . $address);
76			$server->command('kick' . ' ' . $channel . ' ' . $nick . ' ' . settings_get_str('autorejoinpunish_kickban_message'));
77		}
78	}
79	delete $victims{$channel}{$nick};
80}
81
82sub clean_list {
83	my ($channelkey, $nickkey);
84	if (%victims) {
85		foreach $channelkey (keys %victims) {
86			foreach $nickkey (keys %{$victims{$channelkey}}) {
87				if ((time()-$victims{$channelkey}{$nickkey}) > settings_get_int('autorejoinpunish_time_limit')) {
88					delete $victims{$channelkey}{$nickkey};
89				}
90			}
91		}
92	}
93}
94
95sub check_bans {
96	my ($server, $timestamp);
97	if (%bans) {
98		foreach $server (keys %bans) {
99			foreach $timestamp (keys %{$bans{$server}}) {
100				if ((time()-$timestamp) > settings_get_int('autorejoinpunish_knockout_time')) {
101					my ($channel, $address) = split(/\//, $bans{$server}{$timestamp});
102					server_find_tag($server)->command('mode' . ' ' . $channel . ' -b *!' . $address);
103					delete $bans{$server}{$timestamp};
104				}
105			}
106		}
107	}
108}
109
110
111settings_add_int  ('misc', 'autorejoinpunish_time_limit', '3');
112settings_add_str  ('misc', 'autorejoinpunish_kickban_message', 'Kickban for autorejoining.');
113settings_add_bool ('misc', 'autorejoinpunish_knockout', '1');
114settings_add_int  ('misc', 'autorejoinpunish_knockout_time', '60');
115settings_add_str  ('misc', 'autorejoinpunish_knockout_message', 'Temporary ban for autorejoining.');
116settings_add_str  ('misc', 'autorejoinpunish_channels', '');
117settings_add_bool ('misc', 'autorejoinpunish_only_own_kicks', '1');
118
119signal_add_first 'message join' => 'message_join';
120signal_add_first 'message kick' => 'message_kick';
121
122timeout_add ('5000', 'check_bans', '');
123timeout_add ('3600000', 'clean_list', '');
124# 1h = 60min * 60s * 1000ms = 3600000ms
125