keepban.pl


use strict;
use Irssi;
use Irssi::Irc;
use Data::Dumper;
use IO::File;

use vars qw($VERSION %IRSSI %keepbans);
$VERSION = '0.3';
%IRSSI = (
    authors     => 'Valentin Batz',
    contact     => 'senneth@irssi.org',
    name        => 'keepban',
    description => 'keeps bans in the channel',
    url		=> 'http://www.oberkommando.org/~senneth/irssi/scripts/',
    licence	=> 'GPLv2',
    revision    => '$LastChangedRevision: 439 $',
    changed     => '$LastChangedDate: 2006-09-18 15:28:26 +0200 (Mo, 18 Sep 2006) $',
    version     => $VERSION,
);

my %keepbans;
Irssi::theme_register(['keepban', '$0 - {channel $1}: keepban {ban $2}']);

sub ban_remove() {
	my ($channel, $ban) = @_;
	return unless $channel;
	my $server = $channel->{server};
	$keepbans{$server->{tag}}{$channel->{name}} =~ s/^\s+|\s+$//;
	my @bans = split(/ +/, $keepbans{$server->{tag}}{$channel->{name}});
	return unless (@bans);
	foreach my $mask (@bans) {
		if ($mask eq $ban->{ban}) {
	   		$channel->command('ban '.$ban->{ban});
	   	}
	}
}

sub check_bans() {
	my $exists;
	foreach my $server (Irssi::servers()) {
		next if ($server->{chat_type} ne 'IRC');
		foreach my $channel ($server->channels()) {
			$keepbans{$server->{tag}}{$channel->{name}} =~ s/^\s+|\s+$//;
			my @bans = split(/ +/, $keepbans{$server->{tag}}{$channel->{name}});
			next unless (@bans);
			foreach my $ban (@bans) {
				$exists = 0;
				foreach my $chanban ($channel->bans()) {
					if ($chanban->{ban} eq $ban) {
						$exists = 1;
					}
				}
				if ($exists == 0) {
					$channel->command('ban '.$ban);
				}
			}
		}
	}
}       

sub keepban() {
	my ($args, $server, $witem) = @_;
	return unless $witem;
	return unless $server;
	return unless ($witem->{active}->{type} ne 'CHANNEL');
	$keepbans{$server->{tag}}{$witem->{name}} =~ s/^\s+|\s+$//;
	my @bans = sort split(/ +/, $keepbans{$server->{tag}}{$witem->{name}});
	my $exist = 0;
	my $cnt = 1;
	if (lc $args eq 'check') { 
			check_bans();
			return;
	}
	if ($args eq '') {
		foreach my $ban (@bans) {
			$witem->printformat(MSGLEVEL_CRAP, 'keepban', $cnt, $witem->{name}, $ban);
			$cnt++;
		}
		return;
	} else {
		foreach my $ban (@bans) {
			if ($ban eq $args) {
				$exist = 1;
			}
		}
		if ($exist != 1) {
			push (@bans, $args);
			$witem->command('ban '.$args);
		}
		$keepbans{$server->{tag}}{$witem->{name}}=join(" ", @bans);
	}
}

sub unkeepban() {
	my ($args, $server, $witem) = @_;
	return unless $witem;
	return unless $server;
	return unless ($witem->{active}->{type} ne 'CHANNEL');
	$keepbans{$server->{tag}}{$witem->{name}} =~ s/^\s+|\s+$//;
	my @bans = sort split(/ +/, $keepbans{$server->{tag}}{$witem->{name}});
	return unless (@bans);
	return unless ($args ne '');
	my $cnt=0;
	if ($args =~ /^\d+$/) {
		if (exists $bans[$args-1]) {
			$witem->command('unban '.$bans[$args-1]);
			delete(@bans[$args-1]);
		}
	} else {
		foreach my $ban (@bans) {
			if ($ban eq $args) {
				delete(@bans[$cnt]);
				$witem->command('unban '.$args);
				$cnt++;
			}
		}
	}
	$keepbans{$server->{tag}}{$witem->{name}}=join(" ", @bans);
}

sub save_bans() {
        my $filename = Irssi::get_irssi_dir()."/keepbans";
        my $io = new IO::File $filename, "w";
        if (defined $io) {
        	my $dumper = Data::Dumper->new([\%keepbans]);
        	$dumper->Purity(1)->Deepcopy(1);
        	$io->print($dumper->Dump);
        	$io->close;
        }
        Irssi::print("Keepbans saved to ".$filename);
}

sub load_bans() {
    my $filename = Irssi::get_irssi_dir()."/keepbans";;
    my $io = new IO::File $filename, "r";
    if (defined $io) {
        no strict 'vars';
        my $text;
        $text .= $_ foreach ($io->getlines);
        my $keepbans = eval "$text";
        %keepbans = %$keepbans if ref $keepbans;
    }
    Irssi::print("Keepbans loaded from ".$filename);
}

sub UNLOAD {
	save_bans();
}


Irssi::signal_add('ban remove', \&ban_remove);
Irssi::command_bind('keepban', \&keepban);
Irssi::command_bind('unkeepban', \&unkeepban);
Irssi::command_bind('checkbans', \&check_bans);
Irssi::signal_add('setup saved', \&save_bans);

load_bans();
check_bans();