diff options
Diffstat (limited to '')
| -rw-r--r-- | auto-server/auto_server-ng.pl | 224 | ||||
| -rw-r--r-- | auto-server/auto_server.pl | 9 | ||||
| -rw-r--r-- | goodnicks/goodnicks.pl | 321 | 
3 files changed, 553 insertions, 1 deletions
| diff --git a/auto-server/auto_server-ng.pl b/auto-server/auto_server-ng.pl new file mode 100644 index 0000000..b54ca26 --- /dev/null +++ b/auto-server/auto_server-ng.pl @@ -0,0 +1,224 @@ +# This script was initially written by shabble, this fork (and molestation) is +# built upon his original work. +# +# USAGE: +# +# the primary command used is /join+ #channelname +# +# Mappings for channels to servers is accomplished with the +# joinplus_server_maps setting. +# +# Within this setting, space separated pairs denote channel, server pairs. +# Spaces also separate individual pairs, for example: +# +# /set joinplus_server_maps #foo Freenode #bar irc.somewhere.tld #meep DALNet +# +# Then use /join+ #foo, and if you are not already connected to freenode, it +# will connect you, and then join that channel. + +# TODO: +# Autocompletion for channel names +# address conflict resolution +# fix that disgusting race condition + +use strict; +use warnings; + + +use Irssi; +use Irssi::Irc; +use Irssi::TextUI; + +use Data::Dumper; + + +my $DEBUG_ENABLED = 0; +sub DEBUG () { $DEBUG_ENABLED } + +sub _debug_print { +    return unless DEBUG; +    return unless scalar (grep { defined && length } @_) == @_; +    my $win = Irssi::active_win; +    my $str = join('', @_); +    $win->print($str, Irssi::MSGLEVEL_CLIENTCRAP); +} + +our $VERSION = '0.0.' . (split(/ /, '$Rev: 362 $'))[1]; + +our %IRSSI = ( +              authors     => 'shabble, richo', +              contact     => 'richo@psych0tik.net', +              name        => 'auto-join-ng', +              description => 'connects to a specified server in order to connect' . +                             ' to a channel there, without having first to' . +                             ' connect to the server', +              license     => 'Public Domain', +             ); + +my $channel_map = {}; +my @hack_channels; +my $pending_joins; + +sub auto_server_init { +    Irssi::command_bind('join+', \&join_plus); +    Irssi::settings_add_str('join_plus', 'joinplus_server_maps', ''); +    Irssi::signal_add_last('setup changed', \&setup_changed); +    Irssi::settings_add_bool('join_plus', 'join_plus_debug', 0); + +    setup_changed(); +    $pending_joins = {}; + +} + +sub setup_changed { +    $DEBUG_ENABLED  = Irssi::settings_get_bool('join_plus_debug'); +    parse_channel_map(); +} + +# This is a tremendous kludge. +# If anyone knows a better way to get this listing, I'd like to hear it. +# This has so many race condition bugs I just don't even know where to start. +sub retrieve_channels { +    @hack_channels = (); +    Irssi::signal_add_first('print text', 'haxy_print_hook'); +    Irssi::command("CHANNEL LIST"); +    Irssi::signal_remove('print text', 'haxy_print_hook'); +    return join(" ", @hack_channels); +} + + +# The idea for how to do this courtesy of http://wouter.coekaerts.be/site/irssi/aliases +sub haxy_print_hook { +    Irssi::signal_remove('print text', 'haxy_print_hook'); +    Irssi::signal_stop(); +    my $data = $_[1]; +    # Hose control characters +    $data =~ s/\x04.//g; +    if ($data =~ m/^#/) { +        my @items = split /\s+/, $data; +        push(@hack_channels, $items[0]); +        push(@hack_channels, $items[1]); +    } +    Irssi::signal_add_first('print text', 'haxy_print_hook'); +} + +sub parse_channel_map { +    #my $data = Irssi::settings_get_str('joinplus_server_maps'); +    my $data = retrieve_channels(); +    unbind_completion(); +    my @items = split /\s+/, $data; +    if (@items % 2 == 0) { +        $channel_map = { @items }; # risky? +    } else { +        Irssi::active_win->print("Could not process channel => server mappings"); +        $channel_map = {}; +    } +    _debug_print Dumper($channel_map); +    bind_completion(); +} + +# Bind a stack of commands so that irssi knows to complete them. +sub bind_completion { +    foreach(%$channel_map) { +        Irssi::command_bind("join+ $_", \&join_plus); +    } +} + +sub unbind_completion { +    foreach(%$channel_map) { +        Irssi::command_unbind("join+ $_", \&join_plus); +    } +} +    + +sub join_plus { +    my ($args, $cmd_server, $witem) = @_; +    #print Dumper($cmd, "moo", $win); + +    # parse out channel name from args: +    my $channel; +    if ($args =~ m/^(#?[#a-zA-Z0-9]+)/) { +        $channel = $1; +        _debug_print ("Channel is: $channel"); +    } + +    unless ($channel) { +        Irssi::active_win()->print("Channel $args not recognised"); +        return; +    } + +    # lookup server +    my $server_id = $channel_map->{$channel}; +    _debug_print($server_id); + +    unless ($server_id) { +        Irssi::active_win()->print("Channel $channel does not have an" +                                   . " appropriate server mapping"); +            return; +    } +    # TODO: search values() and give a 'did you mean' for closest channel + +    # check if we're connected to that server +    my $server = Irssi::server_find_tag($server_id); + +    if (not defined $server) { +        $server = Irssi::server_find_chatnet($server_id); +    } + +    if (not defined $server) { +        # still no server, walk the server list looking for address matches. +        my @servers = Irssi::servers(); +        foreach my $srv (@servers) { +            if (($srv->{address} eq $server_id) or +                ($srv->{real_address} eq $server_id)) { +                $server = $srv; +                last; +            } +        } +    } + +    if (defined $server) { + +        _debug_print ("Already connected to server: " . $server->{tag} ); + +        # check if we're already on the required channel +        my $on_channel = $server->channel_find($channel); + +        if (defined $channel && ref($channel) eq 'Irssi::Irc::Channel') { +            Irssi::active_win()->print("You are already connected to " +                                       . " $channel on " . $server->{tag}); +            return; +        } else { +            _debug_print ("joining channel: $channel"); +            $server->command("JOIN $channel"); +        } +    } else { +        # not connected to server. +        _debug_print ("connecting to server: $server_id"); + +        Irssi::command("CONNECT $server_id"); +        _debug_print ("awaiting connection for join"); + +        $pending_joins->{$server_id} = $channel; +        Irssi::signal_add_last("event 376", 'do_channel_join'); +    } +} + +sub do_channel_join { +    my ($serv) = @_; +    #_debug_print("server is " . Dumper($serv)); +    _debug_print(sprintf("server is %s (%s)", $serv->{address}, $serv->{tag})); + +    my $channel = $pending_joins->{$serv->{address}}; +    $channel = $pending_joins->{$serv->{tag}} unless $channel; + +    _debug_print ("attempting to join $channel"); + +    Irssi::server_find_tag($serv->{tag})->command("JOIN $channel"); + +    delete $pending_joins->{$serv->{address}}; +    delete $pending_joins->{$serv->{tag}}; + +} + +auto_server_init(); diff --git a/auto-server/auto_server.pl b/auto-server/auto_server.pl index 8676726..77ba527 100644 --- a/auto-server/auto_server.pl +++ b/auto-server/auto_server.pl @@ -108,7 +108,7 @@ sub parse_channel_map {          Irssi::active_win->print("Could not process channel => server mappings");          $channel_map = {};      } -    _debug_print Dumper($channel_map); +    #_debug_print Dumper($channel_map);      bind_completion();  } @@ -150,6 +150,8 @@ sub join_plus {              return;      }      # TODO: search values() and give a 'did you mean' for closest channel +    # TODO: Fuzzy match for ## channels (Would be nice to hax at teh tab +    # completion too)      # check if we're connected to that server      my $server = Irssi::server_find_tag($server_id); @@ -177,6 +179,8 @@ sub join_plus {          # check if we're already on the required channel          my $on_channel = $server->channel_find($channel); +        # FIXME +        # Should this be $on_channel? Need docs..          if (defined $channel && ref($channel) eq 'Irssi::Irc::Channel') {              Irssi::active_win()->print("You are already connected to "                                         . " $channel on " . $server->{tag}); @@ -193,11 +197,14 @@ sub join_plus {          _debug_print ("awaiting connection for join");          $pending_joins->{$server_id} = $channel; +        # This comes tumbling down if the server doesn't have a MOTD. +        # is that RFC required?          Irssi::signal_add_last("event 376", 'do_channel_join');      }  }  sub do_channel_join { +    Irssi::signal_remove("event 376", 'do_channel_join');      my ($serv) = @_;      #_debug_print("server is " . Dumper($serv));      _debug_print(sprintf("server is %s (%s)", $serv->{address}, $serv->{tag})); diff --git a/goodnicks/goodnicks.pl b/goodnicks/goodnicks.pl new file mode 100644 index 0000000..9512759 --- /dev/null +++ b/goodnicks/goodnicks.pl @@ -0,0 +1,321 @@ +# Original Author, more credit be to him +#%IRSSI = ( +#	authors     => 'Wouter Coekaerts', +#	contact     => 'coekie@irssi.org', +#	license     => 'GPLv2', +#	url         => 'http://wouter.coekaerts.be/irssi', +#	changed     => '29/06/2004' +#); + + +# TODO +# Right so I knocked off the old todo list. +# Now, some umode checking would be nice :) +# Fix all the commands that only kinda work +# Sort out the messagelevel stuff +# Add badnicks, which are nicks we never wnt to talk to, +#  - Should invalidate a chan even if no goodnicks + +# Add fingerprint support +# Hook to catch a fingerprint response on supported servers + +# finish cleanup + +use Irssi; +use strict; +use IO::Handle; # for (auto)flush +use Fcntl; # for sysopen +use vars qw($VERSION %IRSSI); +$VERSION = '0.0.' . (split(/ /, '$Rev: 1117 $'))[1]; +my $LastModifiedDate = (split(/ /, '$LastChangedDate: 2010-12-15 11:26:10 +1100 (Wed, 15 Dec 2010) $'))[1]; +$LastModifiedDate =~ s/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/; + +%IRSSI = ( +	authors     => 'richo, Wouter Coekaerts', +	contact     => 'richo@psych0tik.net', +	name        => 'goodnicks', +	description => 'alert you when nicks you don\'t trust are present in a channel', +	license     => 'GPLv2', +	url         => 'http://natalya.psych0tik.net/~richo/irssi/', +	changed     => $LastModifiedDate +); + +sub cmd_help { +	print ( <<EOF +goodnicks is a system for keeping track of whether there's anyone who can hear you, who shouldn't. + +GOODNICKS ADD nick          - Add nick to the goodnicks list for current channel +GOODNICKS DEL nick          - Delete nick from the goodnicks list for current channel +GOODNICKS CLEAR             - Clear the goodnicks list for current channel +GOODNICKS THEME COOL theme  - set the theme for when things are cool to theme +GOODNICKS THEME BAD theme   - set the theme to use when someone can hear you +GOODNICKS LIST              - Show the goodnicks list for the current channel +GOODNICKS WHO               - Show the list of people not valid to be on the current channel + +EOF +    ); +} + +my $need_redraw = 0;                 # goodnicks needs redrawing +my $active_channel;                  # (REC) + +my @goodnicks=();                     # array of hashes, containing the internal goodnicks of the active channel +my @badnicks=(); +my @enabled_channels = (); +my @valid_peeps=();                     # all peeps who are allowed to be in the chan +my @seen_chans = (); # All the channels we've looked at to date. +	# nick => realnick +	# mode => +	my ($MODE_OP, $MODE_HALFOP, $MODE_VOICE, $MODE_NORMAL) = (0,1,2,3); +	# status => +	my ($STATUS_NORMAL, $STATUS_JOINING, $STATUS_PARTING, $STATUS_QUITING, $STATUS_KICKED, $STATUS_SPLIT) = (0,1,2,3,4,5); +	# text => text to be printed +	# cmp => text used to compare (sort) nicks + + +# 'cached' settings +my ($screen_prefix, $irssi_width, @prefix_mode, @prefix_status, $height, $goodnicks_width); + + +sub update { +	read_settings(); +} + +sub cmd_theme { +    my @args = split(/ /, shift); +    if (@args < 2 and (@args[0] == 'cool' or @args[0] == 'bad')) { +        Irssi::print("Usage: goodnicks theme [cool | bad] [themename]"); +    } else { +        Irssi::settings_set_str('goodnicks_theme_'.@args[0], @args[1]); +    } +} + +sub cmd_debug { +    Irssi::print("Current Server: ".Irssi::active_server()->{tag}); +    Irssi::print("Alt form ". Irssi::active_server()->{tag}); +    #Irssi::print(@valid_peeps); +    #my $tmpnix = Irssi::settings_get_str('goodnicks_chan_'.$channel.'valid_peeps'); +    #Irssi::settings_add_str('goodnicks', 'goodnicks_chan_kthxbai_valid_peeps', ''); +    #Irssi::print(Irssi::settings_get_str('goodnicks_'.Irssi::active_server()->{tag}.'_kthxbai_valid_peeps')); +} + +### both ### + +# TODO Rename +sub need_redraw { +    # Code to validate @goodnicks against @valid_peeps needs to go in here. +    my $func = \&chan_is_cool; +    my $tmp_server = Irssi::active_server(); +    my $own_nick = lc($tmp_server->{nick}); +    # If valid peeps is empty we assume that we don't care who's in there. +    if (@valid_peeps > 0) { +        foreach my $nick (@goodnicks){ +            if (not(grep m/^\Q$nick\E$/i, @valid_peeps) && ($own_nick ne lc($nick)))  { +                push @badnicks, $nick; +                $func = \&chan_is_bad; +            } +        } +    } +    &$func() + +} + +sub haxy_print_hook { +    Irssi::signal_stop(); +} +sub set_theme { +    my $theme = shift; +    Irssi::signal_add_first('print text', 'haxy_print_hook'); +    Irssi::command("set theme ".$theme); +    Irssi::signal_remove('print text', 'haxy_print_hook'); +} + + +sub chan_is_cool { +    # Do stuff to alert user chan is well groovy +    my $theme = Irssi::settings_get_str('goodnicks_theme_cool'); +    set_theme($theme) +} + +sub chan_is_bad { +    # Do stuff to alert user to chan not being all good +    my $theme = Irssi::settings_get_str('goodnicks_theme_bad'); +    set_theme($theme) +} + +sub get_valid_peeps { +    my $channel = shift; +    $channel = $channel->{name}; +    $channel =~ s/^#//; +    if (not ( grep m/^\Q$channel\E$/i, @seen_chans)) { +        Irssi::settings_add_str('goodnicks', 'goodnicks_'.Irssi::active_server()->{tag}.'_'.$channel.'_valid_peeps', ''); +    } +    my $thisnick; +    my $tmpnix = Irssi::settings_get_str('goodnicks_'.Irssi::active_server()->{tag}.'_'.$channel.'_valid_peeps'); +    $tmpnix =~ s/\\e/\033/g; +    @valid_peeps = split( /,/, $tmpnix); +} + + +# make the (internal) goodnicks (@goodnicks) +sub make_goodnicks { +    my $thisnick; + +    @valid_peeps = (); +	@goodnicks = (); +    @badnicks = (); + +	### get & check channel ### +	my $channel = Irssi::active_win->{active}; + +	if (!$channel || (ref($channel) ne 'Irssi::Irc::Channel' && ref($channel) ne 'Irssi::Silc::Channel') || $channel->{'type'} ne 'CHANNEL' || ($channel->{chat_type} ne 'SILC' && !$channel->{'names_got'}) ) { +		$active_channel = undef; +		# no goodnicks +	} else { +		$active_channel = $channel; +		### make goodnicks ### +        get_valid_peeps($active_channel); +		foreach my $nick ($channel->nicks()) { +			$thisnick = {'nick' => $nick->{'nick'}}; +            if (grep m/^.+$/, $thisnick) { +                push @goodnicks, $thisnick->{nick}; +            } +		} + +	} +	need_redraw(); +} + +sub cmd_add { +    my $nick = shift; +    if (not ( grep m/^\Q$nick\E$/i, @valid_peeps)) { +        my $channel = $active_channel->{name}; +        $channel =~ s/^#//; +        push @valid_peeps, $nick; +        my $tmpnicks = join(',', @valid_peeps); +        Irssi::settings_set_str('goodnicks_'.Irssi::active_server()->{tag}.'_'.$channel.'_valid_peeps', $tmpnicks); +        write_to_current_channel("Added ".$nick." to goodnicks"); +    } else { +        write_to_current_channel($nick." already present in goodnicks"); +    } +    make_goodnicks(); +} + +sub cmd_del { +    my $nick = shift; +    my @delorted = (); +    my $index = 0; +    my $channel = $active_channel->{name}; +    $channel =~ s/^#//; +    my @newnicks = (); +    while ($index <= $#valid_peeps) { +        if (lc($valid_peeps[$index]) ne lc($nick)) { +            push @newnicks, $valid_peeps[$index]; +            push @delorted, $nick; +        } +        $index++; +    } +    @valid_peeps = @newnicks; +    my $tmpnicks = join(',', @valid_peeps); +    Irssi::settings_set_str('goodnicks_'.Irssi::active_server()->{tag}.'_'.$channel.'_valid_peeps', $tmpnicks); +    if (@delorted > 0) { +        my $data = join(', ', @delorted); +        write_to_current_channel("Deleted from goodnicks: ".$data); +    } else { +        write_to_current_channel($nick." not found in goodnicks."); +    } +    make_goodnicks(); +} + +sub cmd_clear { +    my $channel = $active_channel->{name}; +    $channel =~ s/^#//; +    @valid_peeps = (); +    my $tmpnicks = ''; +    Irssi::settings_set_str('goodnicks_'.Irssi::active_server()->{tag}.'_'.$channel.'_valid_peeps', $tmpnicks); +    write_to_current_channel("Cleared goodnicks for ".$active_channel->{name}); +    make_goodnicks(); +} + +sub write_to_current_channel { +    my $data = shift; +    $active_channel->print($data, MSGLEVEL_CRAP); +} + +sub cmd_list { +    if (@valid_peeps > 0) { +        my $nicks; +        write_to_current_channel("Valid peeps for ".$active_channel->{name}); +        $nicks = join(', ', @valid_peeps); +        write_to_current_channel($nicks); +    } else { +        write_to_current_channel("goodnicks disabled for ".$active_channel->{name}); +    } +} +sub cmd_who { +    if (@badnicks > 0) { +        my $nicks; +        write_to_current_channel("Invalid peeps on ".$active_channel->{name}); +        $nicks = join(', ', @badnicks); +        write_to_current_channel($nicks); +    } else { +        if (@valid_peeps > 0) { +            write_to_current_channel("No invalid peeps on ".$active_channel->{name}); +        } else { +            write_to_current_channel("goodnicks disabled for ".$active_channel->{name}); +        } +    } +} + +##### command binds ##### +Irssi::command_bind 'goodnicks' => sub { +    my ( $data, $server, $item ) = @_; +    $data =~ s/\s+$//g; +    Irssi::command_runsub ('goodnicks', $data, $server, $item ) ; +}; +Irssi::signal_add_first 'default command goodnicks' => sub { +	# gets triggered if called with unknown subcommand +	cmd_help(); +}; +Irssi::command_bind('goodnicks help',\&cmd_help); +Irssi::command_bind('goodnicks add', \&cmd_add); +Irssi::command_bind('goodnicks del', \&cmd_del); +Irssi::command_bind('goodnicks clear', \&cmd_clear); +Irssi::command_bind('goodnicks theme', \&cmd_theme); +# XXX Need to add this. +Irssi::command_bind('goodnicks list', \&cmd_list); +Irssi::command_bind('goodnicks who', \&cmd_who); +Irssi::command_bind('goodnicks debug',\&cmd_debug); + +# +###### signals ##### +Irssi::signal_add_last('window item changed', \&make_goodnicks); +Irssi::signal_add_last('window changed', \&make_goodnicks); +#Irssi::signal_add_last('channel wholist', \&sig_channel_wholist); +Irssi::signal_add_first('message join', \&make_goodnicks); # first, to be before ignores +Irssi::signal_add_first('message part', \&make_goodnicks); +Irssi::signal_add_first('message kick', \&make_goodnicks); +Irssi::signal_add_first('message quit', \&make_goodnicks); +Irssi::signal_add_first('message nick', \&make_goodnicks); +#Irssi::signal_add_first('message own_nick', \&sig_nick); +#Irssi::signal_add_first('nick mode changed', \&sig_mode); +# +#Irssi::signal_add('setup changed', \&read_settings); +# +###### settings ##### +#Irssi::settings_add_str('goodnicks', 'goodnicks_screen_prefix', '\e[m '); +Irssi::settings_add_str('goodnicks', 'goodnicks_prefix_mode_op', '\e[32m@\e[39m'); +Irssi::settings_add_str('goodnicks', 'goodnicks_prefix_mode_halfop', '\e[34m%\e[39m'); +Irssi::settings_add_str('goodnicks', 'goodnicks_prefix_mode_voice', '\e[33m+\e[39m'); +Irssi::settings_add_str('goodnicks', 'goodnicks_prefix_mode_normal', ' '); +Irssi::settings_add_str('goodnicks', 'goodnicks_theme_bad', 'intruder'); +Irssi::settings_add_str('goodnicks', 'goodnicks_theme_cool', 'default'); +# +#Irssi::settings_add_int('goodnicks', 'goodnicks_width',11); +#Irssi::settings_add_int('goodnicks', 'goodnicks_height',24); +Irssi::settings_add_str('goodnicks', 'goodnicks_channels', ''); +#Irssi::settings_add_str('goodnicks', 'goodnicks_screen_split_windows', ''); +#Irssi::settings_add_str('goodnicks', 'goodnicks_automode', ''); +Irssi::settings_add_str('goodnicks', 'goodnicks_', ''); +# +#} | 
