html/modelist.pl


   1 # modelist.pl v 0.7.2 by Marcin Rozycki (derwan@irssi.pl) changed at Sat Jun  5 22:38:59 CEST 2004
   2 #
   3 # Usage:
   4 #   /se
   5 #   /si
   6 #   /unexcept [index]	( ex. /unexcept 1 5 17)
   7 #   /uninvite [index]	( ex. /uninvite 3 8)
   8 #
   9 
  10 use strict;
  11 use Irssi 20020600 ();
  12 use Irssi::Irc;
  13 
  14 use vars qw($VERSION %IRSSI);
  15 
  16 $VERSION = "0.7.2";
  17 %IRSSI = (
  18 	authors		=> 'Marcin Rozycki',
  19 	contact		=> 'derwan@irssi.pl',
  20 	name		=> 'modelist',
  21 	description	=> 'Cache of invites and ban exceptions in channel. Usage: /si, /se, '.
  22 			   '/unexcept [indexes], /uninvite [indexes]',
  23 	license		=> 'GNU GPL v2',
  24 	url		=> 'http://derwan.irssi.pl',
  25 	changed		=> 'Sat Jun  5 22:38:59 CEST 2004'
  26 );
  27 
  28 Irssi::theme_register([
  29 	'modelist',		'$0 - {hilight $1}: $2 %c$3%n $4'
  30 ]);
  31 
  32 my %modelist = ();
  33 
  34 sub channel_create
  35 {
  36 	my ($server, $channel) = (@_[0], lc($_[1]));
  37 	delete $modelist{lc($server->{tag})}{$channel};
  38 
  39 	$server->redirect_event("mode I", 1, "$channel", 0, undef, {
  40 		'event 346'	=> 'redir modelist invite',
  41 		''		=> 'event empty' });
  42 	$server->send_raw("MODE $channel I");
  43 
  44 	$server->redirect_event("mode e", 1, "$channel", 0, undef, {
  45 		'event 348'	=> 'redir modelist except',
  46 		''		=> 'event empty' });
  47 	$server->send_raw("MODE $channel e");
  48 }
  49 
  50 sub sig_channel_created
  51 {
  52 	channel_create($_[0]->{server}, $_[0]->{name}) unless ($_[0]->{no_modes});
  53 }
  54 
  55 
  56 sub sig_redir_modelist_invite
  57 {
  58 	my ($nick, $chan, $mode) = split(/ +/, $_[1], 3);
  59 	message_irc_mode($_[0], $chan, undef, undef, "+I $mode");
  60 }
  61 
  62 sub sig_redir_modelist_except
  63 {
  64 	my ($nick, $chan, $mode) = split(/ +/, $_[1], 3);
  65 	message_irc_mode($_[0], $chan, undef, undef, "+e $mode");
  66 }
  67 
  68 sub message_irc_mode
  69 {
  70 	my ($mode, @args) = split(/ +/, $_[4]);
  71 	return unless $_[0]->ischannel($_[1]);
  72 	my ($tag, $chan, $mod) = (lc($_[0]->{tag}), lc($_[0]->channel_find($_[1])->{name}), "+");
  73 	foreach ( split //, $mode )
  74 	{
  75 		/([+-])/ and $mod = $_, next;
  76 		my $arg = ( $mod eq '+' && $_ =~ m/[beIkloRvh]/ or $mod eq '-' && $_ =~ m/[beIkoRvh]/ ) ? shift(@args) : undef;
  77 		next unless ( $_ =~ m/[eI]/ );
  78 		( $mod eq '+' ) and push(@{$modelist{$tag}{$chan}{$_}}, [$arg, $_[2], time]), next;
  79 		for (my $idx = 0; $idx <= $#{$modelist{$tag}{$chan}{$_}}; $idx++) {
  80 			splice(@{$modelist{$tag}{$chan}{$_}}, $idx, 1) if ($modelist{$tag}{$chan}{$_}[$idx][0] eq $arg);
  81 		}
  82 	}
  83 }
  84 
  85 sub proc_modelist_show
  86 {
  87 	my ($arg, $server, $channel, $list, $mode) = @_;
  88 
  89 	Irssi::print("You\'re not connected to server"), return unless ($server and $server->{connected});
  90 	
  91 	$arg =~ s/\s.*//;
  92 	if ($arg) {
  93 		Irssi::print("Bad channel name: $arg"), return unless ($server->ischannel($arg));
  94 		unless ($channel = $server->channel_find($arg)) {
  95 			Irssi::print("You\'re not in channel $arg --> sending request to server");
  96 			$server->send_raw("MODE $arg $list");
  97 			return;
  98 		}
  99 	}
 100 
 101 	Irssi::print("Not joined to any channel"), return unless ($channel and $channel->{type} eq "CHANNEL");
 102 	Irssi::print("Channel not fully synchronized yet, try again after a while"), return unless ($channel->{synced});
 103 	Irssi::print("Channel doesn\'t support modes"), return if ($channel->{no_modes});
 104 
 105 	my ($tag, $name) = (lc($server->{tag}), $channel->{name});
 106 	my $chan = lc($name);
 107 	my $items = $#{$modelist{$tag}{$chan}{$list}};
 108 
 109 	Irssi::print("No $mode\s in channel %_$name%_"), return if ($items < 0);
 110 
 111 	for (my $idx = 0; $idx <= $items; $idx++)
 112 	{
 113 		my ($mask, $who) = ($modelist{$tag}{$chan}{$list}[$idx]->[0], $modelist{$tag}{$chan}{$list}[$idx]->[1]);
 114 		$mask =~ tr/\240\002\003\037\026/\206\202\203\237\226/;
 115 		my $setby = ($who) ? "\00314[\003by \002$who\002, ".(time - $modelist{$tag}{$chan}{$list}[$idx]->[2])." secs ago\00314]\003" : undef;
 116 		$channel->printformat(MSGLEVEL_CRAP, 'modelist', ($idx+1), $name, $mode, $mask, $setby);
 117 	}
 118 }
 119 
 120 sub cmd_si { proc_modelist_show @_, "I", "invite"; }
 121 sub cmd_se { proc_modelist_show @_, "e", "ban exception"; }
 122 
 123 sub cmd_modelist {
 124 	my ( $type, $data, $server, $witem) = @_;
 125 	Irssi::print("You\'re not connected to server"), return unless ($server and $server->{connected});
 126 	Irssi::print("Not joined to any channel"), return unless ( $witem and $witem->{type} eq "CHANNEL" );
 127 	my ($tag, $chan, @masks) = (lc($server->{tag}), lc($server->channel_find($witem->{name})->{name})); 
 128 	while ( $data =~ m/(\d+)/g ) {
 129 		my $idx = $1 - 1;
 130 		next unless ( exists $modelist{$tag}{$chan}{$type}[$idx] );
 131 		push(@masks, $modelist{$tag}{$chan}{$type}[$idx]->[0]);
 132 	}
 133 	return unless ( $#masks >= 0 );
 134 	$witem->command(sprintf("MODE %s -%s %s", $chan, $type x scalar(@masks), join(" ", @masks)));
 135 }
 136 
 137 Irssi::signal_add("channel created", "sig_channel_created");
 138 Irssi::signal_add("redir modelist invite", "sig_redir_modelist_invite");
 139 Irssi::signal_add("redir modelist except", "sig_redir_modelist_except");
 140 Irssi::signal_add("message irc mode", "message_irc_mode");
 141 
 142 Irssi::command_bind("si", "cmd_si");
 143 Irssi::command_bind("se", "cmd_se");
 144 Irssi::command_bind("uninvite" => sub { cmd_modelist("I", @_); });
 145 Irssi::command_bind("unexcept" => sub { cmd_modelist("e", @_); });
 146 
 147 foreach my $server (Irssi::servers)
 148 {
 149 	foreach my $channel ($server->channels())
 150 	{
 151 		channel_create($server, $channel->{name}) unless ($channel->{no_modes});
 152 	}
 153 }