diff options
| author | Alexander Færøy | 2014-05-31 13:10:46 +0200 | 
|---|---|---|
| committer | Alexander Færøy | 2014-05-31 13:10:46 +0200 | 
| commit | 2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1 (patch) | |
| tree | 1c5e6d817c88e67b46e216a50e0aef5428bf63df /scripts/modelist-r.pl | |
| parent | 2d080422d79d1fd49d6c5528593ccaaff9bfc583 (diff) | |
| download | scripts.irssi.org-2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1.tar.bz2 | |
Import scripts from scripts.irssi.org
Diffstat (limited to 'scripts/modelist-r.pl')
| -rw-r--r-- | scripts/modelist-r.pl | 467 | 
1 files changed, 467 insertions, 0 deletions
| diff --git a/scripts/modelist-r.pl b/scripts/modelist-r.pl new file mode 100644 index 0000000..5834e5e --- /dev/null +++ b/scripts/modelist-r.pl @@ -0,0 +1,467 @@ +# $Id: modelist-r.pl,v 0.8.0-rc4 2004/11/04 19:56 derwan Exp $ +# +# This script creates cache of channel invites, ban exceptions and reops. +# Reop list is included only in ircd >= 2.11.0 (in IRCnet) - for other servers +# and networks use modelist.pl ( http://derwan.irssi.pl/modelist.pl). +# +# Script commands: +#   /si   - shows channel invites +#   /se   - shows ban exception +#   /sr   - shows reop list +#    +#   /uninvite [<index and masks separated with spaces>] +#         - removes the specified invite(s) from the channel +#   /unexcept [<index and masks separated with spaces>] +#         - removes the specified ban exception(s) from the channel +#   /unreop [<index and masks separated with spaces>] +#         - removes the specified reop(s) from the channel +# +#   Examples: +#      /si +#      /uninvite 1 +#      /unexcept *!*@127.0.0.1 +#      /unreop 1 *!*@127.0.0.1 5 +# +# After loading modelist-r.pl run command +#   /statusbar window add -priority 0 -after usercount modelist  +# +# You can customize the look of this item from theme file: +#   sb_modelist = "{sb $0 modes ($1-)}"; +#   sb_ml_b = "b/%r$*%n"; # bans +#   sb_ml_e = "e/%c$*%n"; # ban exceptions +#   sb_ml_I = "I/%G$*%n"; # invites +#   sb_ml_R = "R/%R$*%n"; # reops +#   sb_ml_space = " ";    # separator +# +# Theme formats: +#   modelist                   $0 - index, $1 - channel, $2 - hostmask, 3 - mode  +#   modelist_long              $4 - nick, $5 - time +#   modelist_empty             $0 - channel, $1 - mode +#   modelist_chan_not_synced   $0 - channel +#   modelist_not_joined +#   modelist_server_version    $0 - version +#    + +use strict; +use vars ('$VERSION', '%IRSSI'); + +use Irssi 20020600 (); +use Irssi::Irc; +use Irssi::TextUI; + +$VERSION = '0.8.0-rc4'; +%IRSSI = +( +   'authors'      => 'Marcin Rozycki', +   'contact'      => 'derwan@irssi.pl', +   'name'         => 'modelist-r', +   'description'  => 'Cache of invites, ban exceptions and reops in channel. Script commands: '. +                     '/si, /se, /sr, /unexcept, /uninvite, /unreop (version only for ircd >= 2.11.0).', +   'license'      => 'GNU GPL v2', +   'modules'      => '', +   'url'          => 'http://derwan.irssi.pl', +   'changed'      => 'Thu Nov  4 17:56:17 2004', +); + +Irssi::theme_register +([ +   # $0 - index, $1 - channel name, $2 - hostmask, $3 - mode (invite, ban exception, reop) +   'modelist', '$0 - {channel $1}: $3 {ban $2}', +   # $0 - index, $1 - channel name, $2 - hostmask, $3 - mode, $4 - nick, $5 - time +   'modelist_long', '$0 - {channel $1}: $3 {ban $2} {comment by {nick $4}, $5 secs ago}', +   # $0 - channel name, $1 - mode +   'modelist_empty', 'No $1s in channel {channel $0}', +   # $0 - channel name +   'modelist_chan_not_synced', 'Channel not fully synchronized yet, try again after a while', +   # $0 - channel name +   'modelist_chan_no_modes', 'Channel {channel $0} doesn\'t support modes', +   'modelist_not_joined', 'Not joined to any channel', +   # $0 - version +   'modelist_server_version', 'This script working only in ircd {hilight >= 2.11.0} with reop list {comment active ircd $0}'  +]); + +# $modelist{str servertag}->{lc str channel}->{str mode} = [ $moderec, ... ] +# $moderec = [ str hostmask, str nick, str time ] +my %modelist = (); + +# $synced{str servertag}->{lc str channel} = int synced +my %synced = (); + +#  $visible{str mode} = str list +my %visible = +( +   'e' => 'ban exception', +   'I' => 'invite', +   'R' => 'reop' +); + +# $sb->{str mode} = int modes +my $sb = {}; + +# server redirections: +#   'modelist I' ( 346, 347, 403, 442, 472, 479, 482) +#   'modelist e' ( 348, 349, 403, 442, 472, 479, 482) +#   'modelist R' ( 344, 345, 403, 442, 472, 479, 482) +Irssi::Irc::Server::redirect_register('modelist I', 0, 0, { 'event 346' => 1 }, { +   'event 347' => 1, # end of channel invite list +   'event 403' => 1, # no such channel +   'event 442' => 1, # you're not on that channel +   'event 472' => 1, # unknown mode +   'event 479' => 1, # illegal channel name +   'event 482' => 1  # you're not channel operator +}, undef ); + +Irssi::Irc::Server::redirect_register('modelist e', 0, 0, { 'event 348' => 1 }, { +   'event 349' => 1, # end of channel exception list +   'event 403' => 1, +   'event 442' => 1, +   'event 472' => 1, +   'event 479' => 1, +   'event 482' => 1 +}, undef ); + +Irssi::Irc::Server::redirect_register('modelist R', 0, 0, { 'event 344' => 1 }, { +   'event 345' => 1, # end of channel reop list +   'event 403' => 1, +   'event 442' => 1, +   'event 472' => 1, +   'event 479' => 1, +   'event 482' => 1 +}, undef ); + +# create_channel (rec channel, int sync) +sub create_channel ($;$) +{ +    destroy_channel($_[0]); +    sb_update(); + +    my ($server, $tag, $channel) = ($_[0]->{server}, $_[0]->{server}->{tag}, lc $_[0]->{name}); +     +     +    if ( !test_version($server) or $_[0]->{no_modes} ) +    { +       $synced{$tag}->{$channel} = 1; +       return; +    } +    $synced{$tag}->{$channel} = ( defined $_[1] ) ? $_[1] : 0; +         +    $modelist{$tag}->{$channel}->{I} = []; +    $server->redirect_event('modelist I', 1, $channel, 0, undef, { +       'event 346' => 'redir modelist invite', +                '' => 'event empty' +    }); +    $server->send_raw(sprintf('mode %s +I', $channel)); + +    $modelist{$tag}->{$channel}->{e} = []; +    $server->redirect_event('modelist e', 1, $channel, 0, undef, { +       'event 348' => 'redir modelist except', +                '' => 'event empty' +    }); +    $server->send_raw(sprintf('mode %s +e', $channel)); + +    $modelist{$tag}->{$channel}->{R} = []; +    $server->redirect_event('modelist R', 1, $channel, 0, undef, { +       'event 344' => 'redir modelist reop', +       'event 345' => 'redir modelist sync', +       'event 403' => 'redir modelist sync', +       'event 442' => 'redir modelist sync', +       'event 472' => 'redir modelist sync', +       'event 479' => 'redir modelist sync', +       'event 482' => 'redir modelist sync', +       '' => 'event empty' +    }); +    $server->send_raw(sprintf('mode %s +R', $channel)); +} + +# destroy_channel (rec channel) +sub destroy_channel ($) +{ +   my ($tag, $channel) = ($_[0]->{server}->{tag}, lc $_[0]->{name}); +   delete $synced{$tag}->{$channel}; +   delete $modelist{$tag}->{$channel}; +   sb_update(); +} + +# sig_redir_modelist (rec server, str data, str mode) +sub sig_redir_modelist ($$$) +{ +   my $chanrec = $_[0]->channel_find(((split(' ', $_[1], 3))[1])); +   if ( ref $chanrec ) +   { +      mode($chanrec, 1, $_[2], ((split(/ +/, $_[1], 4))[2]), undef); +   } +} + +# mode (rec channel, int type, str mode, str hostmask, str setby)  +sub mode ($$$$$) +{ +    my $rec = get_list($_[0], $_[2]); +    if ( ref $rec and $_[1] eq 1 ) +    {     +       push @{$rec}, [ $_[3], $_[4], time ]; +    } +    elsif ( ref $rec and $_[1] eq 0 ) +    { +       for ( my $idx = 0; $idx <= $#{$rec}; $idx++ ) +       { +         if ( lc $rec->[$idx]->[0] eq lc $_[3] ) +         { +            splice @{$rec}, $idx, 1; +            last; +         } +       } +    } +    sb_update(); +} + +# sig_channel_sync (rec channel) +sub sig_channel_sync ($) +{ +   if ( ++$synced{$_[0]->{server}->{tag}}->{lc $_[0]->{name}} < 2 ) +   { +      Irssi::signal_stop(); +   } +} + +# sig_modelist_sync (rec server, str data) +sub sig_modelist_sync ($$) +{ +   my $chanrec = $_[0]->channel_find(((split(/ +/, $_[1], 3))[1])); +   if ( ref $chanrec ) +   { +      Irssi::signal_emit('channel sync', $chanrec); +      sb_update(); +   } +} + +# sig_message_irc_mode (rec server, str channel, str nick, str userhost, str mode) +sub sig_message_irc_mode ($$$$$) +{ +   my $chanrec = $_[0]->channel_find($_[1]); +   unless ( ref $chanrec ) +   { +      return; +   } +    +   my ($q, $mods, @a) = (1, split(/ +/, $_[4])); +   foreach my $mod ( split('', $mods) ) +   { +       ( $mod eq '+' ) and $q = 1, next; +       ( $mod eq '-' ) and $q = 0, next; +       my $a = ( rindex('beIkloRvhx', $mod) >= 0 && $q eq 1 or rindex('beIkoRvhx', $mod) >= 0 && $q eq 0 ) ? shift(@a) : undef; +       if ( rindex('eIR', $mod) >= 0 ) +       { +          mode($chanrec, $q, $mod, $a, $_[2]); +       } +   } +} + +# get_list (rec channel, str mode), rec list +sub get_list ($$) +{ +   if ( ref $_[0] and defined $modelist{$_[0]->{server}->{tag}}->{lc $_[0]->{name}}->{$_[1]} ) +   { +       return $modelist{$_[0]->{server}->{tag}}->{lc $_[0]->{name}}->{$_[1]}; +   } +} + +# test_version (rec server), bool 0/1 +sub test_version ($) +{ +   if ( $_[0] and ref $_[0] and $_[0]->{version} =~ m/^(\d+\.\d+)\./ and $1 >= 2.11 ) +   { +      return 1; +   } +   return 0; +} + + +# test_channel (rec channel, bool quiet), bool 0/1 +sub test_channel ($;$) +{ +   unless ( ref $_[0] and $_[0]->{type} eq 'CHANNEL' ) +   { +       Irssi::printformat(MSGLEVEL_CRAP, 'modelist_not_joined') unless ( $_[1] ); +       return 0; +   } +   if ( $_[0]->{no_modes} ) +   { +       $_[0]->printformat(MSGLEVEL_CRAP, 'modelist_chan_no_modes', $_[0]->{name}) unless ( $_[1] ); +       return 0; +   } +   if ( !test_version($_[0]->{server}) ) +   { +      $_[0]->printformat(MSGLEVEL_CRAP, 'modelist_server_version', $_[0]->{server}->{version}) unless ( $_[1] ); +      return 0; +    +   } +   if ( $synced{$_[0]->{server}->{tag}}->{lc $_[0]->{name}} < 2 ) +   { +      $_[0]->printformat(MSGLEVEL_CRAP, 'modelist_chan_not_synced', $_[0]->{name}) unless ( $_[1] ); +      return 0; +   }    +   return 1; +} + +# cmd_modelist_show (str mode) +sub cmd_modelist_show ($) +{ +   my $chanrec = Irssi::active_win() ? Irssi::active_win()->{active} : undef; +   unless ( test_channel($chanrec) ) +   { +      return; +   } +   my $rec = get_list($chanrec, $_[0]); +   unless ( $#{$rec} >= 0 ) +   { +       $chanrec->printformat +       ( +           MSGLEVEL_CRAP, 'modelist_empty', $chanrec->{name}, $visible{$_[0]} +       ); +       return; +   }         +   for ( my $idx = 0; $idx <= $#{$rec}; $idx++ ) +   { +      $chanrec->printformat +      ( +          MSGLEVEL_CRAP, ( defined $rec->[$idx]->[1] ? 'modelist_long' : 'modelist'),  +          ($idx + 1), $chanrec->{name}, visible($rec->[$idx]->[0]), $visible{$_[0]}, +          $rec->[$idx]->[1], (time() - $rec->[$idx]->[2]) +       ); +   } +} + +# cmd_modelist_del (str mode, str data) +sub cmd_modelist_del ($$) +{ +   my $chanrec = Irssi::active_win() ? Irssi::active_win()->{active} : undef; +   unless ( test_channel($chanrec) ) +   { +      return; +   } +   my ($rec, @m) = (get_list($chanrec, $_[0])); +   foreach my $search ( split /[,;\s]+/, $_[1] ) +   { +      if ( $search =~ m/^\d+$/ )  +      { +          next unless ( $search-- and $search <= $#{$rec} ); +          $search = $rec->[$search]->[0]; +      } +      push @m, $search; +   } +   if ( $#m >= 0 ) +   { +       $chanrec->{server}->command(sprintf("mode %s -%s %s", $chanrec->{name}, $_[0] x scalar(@m), join(' ', @m))); +   } +} + +# visible (str data), str data +sub visible ($) +{ +   my $str = shift(); +   $str =~ tr/\240\002\003\037\026/\206\202\203\237\226/; +   return $str; +} + +# sb_update () +sub sb_update () +{ +   $sb->{b} = $sb->{e} = $sb->{I} = $sb->{R} = $sb->{T} = 0; +    +   my $chanrec = Irssi::active_win() ? Irssi::active_win()->{active} : undef; +   unless ( test_channel($chanrec, 1) ) +   { +      return; +   } + +   $sb->{b} = scalar @{[$chanrec->bans]}; +   $sb->{e} = scalar @{get_list($chanrec, 'e')}; +   $sb->{I} = scalar @{get_list($chanrec, 'I')}; +   $sb->{R} = scalar @{get_list($chanrec, 'R')}; +   $sb->{T} = $sb->{b} + $sb->{e} + $sb->{I} + $sb->{R}; + +   Irssi::statusbar_items_redraw('modelist'); +} + +# sb_modelist(rec item, bool get_size_only) +# tahnks usercount.pl! +sub sb_modelist ($$) +{ +   unless ( $sb->{T} ) +   { +      $_[0]->{min_size} = $_[0]->{max_size} = 0 if ( ref $_[0] ); +      return; +   } + +   my $theme = Irssi::current_theme(); +   my $format = $theme->format_expand('{sb_modelist}'); + +   if ( $format  ) +   { +      my ($str, $space) = ('', $theme->format_expand('{sb_ml_space}')); +      foreach my $mod ( 'b', 'e', 'I', 'R' ) +      { +         next unless ( $sb->{$mod} > 0 ); +         my $tmp = $theme->format_expand +         ( +             sprintf('{sb_ml_%s %d}', $mod, $sb->{$mod}), Irssi::EXPAND_FLAG_IGNORE_EMPTY +         ); +         $str .= $tmp . $space; +      } +      $str =~ s/\Q$space\E$//; +      $format = $theme->format_expand +      ( +         sprintf('{sb_modelist %d %s}', $sb->{T}, $str), Irssi::EXPAND_FLAG_IGNORE_REPLACES +      ); +   } +   else +   { +       my $str = undef; +       foreach my $mod ( 'b', 'e', 'I', 'R' ) +       { +          next unless ( $sb->{$mod} > 0 ); +          $str .= sprintf('%s%d ', $mod, $sb->{$mod}) +       } +       chop($str); +       $format = sprintf('{sb \%%_%d\%%_ modes ', $sb->{T}); +       $format .= sprintf('\%%c(\%%n%s\%%c)', $str) if ( $str ); +   }   + +   $_[0]->default_handler($_[1], $format, undef, 1); +} + +Irssi::signal_add_first('channel sync', 'sig_channel_sync'); +Irssi::signal_add('channel joined' => sub { create_channel($_[0], 0) }); +Irssi::signal_add('channel destroyed' => sub { destroy_channel($_[0]) }); +Irssi::signal_add('redir modelist invite' => sub { sig_redir_modelist($_[0], $_[1], 'I'); }); +Irssi::signal_add('redir modelist except' => sub { sig_redir_modelist($_[0], $_[1], 'e'); }); +Irssi::signal_add('redir modelist reop' => sub { sig_redir_modelist($_[0], $_[1], 'R'); }); +Irssi::signal_add('redir modelist sync', 'sig_modelist_sync'); +Irssi::signal_add('message irc mode', 'sig_message_irc_mode'); +Irssi::signal_add_last('ban new', 'sb_update'); +Irssi::signal_add_last('ban remove', 'sb_update'); +Irssi::signal_add_last('window changed', 'sb_update'); +Irssi::signal_add_last('window item changed', 'sb_update'); +Irssi::command_bind('si' => sub { cmd_modelist_show('I') }); +Irssi::command_bind('se' => sub { cmd_modelist_show('e') }); +Irssi::command_bind('sr' => sub { cmd_modelist_show('R') }); +Irssi::command_bind('uninvite' => sub { cmd_modelist_del('I', $_[0]) }); +Irssi::command_bind('unexcept' => sub { cmd_modelist_del('e', $_[0]) }); +Irssi::command_bind('unreop' => sub { cmd_modelist_del('R', $_[0]) }); + +sb_update(); + +Irssi::statusbar_item_register('modelist', undef, 'sb_modelist'); +Irssi::statusbars_recreate_items(); + +foreach my $server ( Irssi::servers ) +{ +   foreach my $chanrec ( $server->channels ) +   { +      create_channel($chanrec, 1);   +   } +} + + + + | 
