]> git.99rst.org Git - irssi-scripts.irssi.org.git/commitdiff
bitlbee_typing_notice 1.7.2
authorAilin Nemui <redacted>
Fri, 8 Jan 2016 15:59:55 +0000 (16:59 +0100)
committerAilin Nemui <redacted>
Fri, 8 Jan 2016 15:59:55 +0000 (16:59 +0100)
scripts/bitlbee_typing_notice.pl

index 50fe47c30c65502b402949b84d189fd2a3909818..e1d1186083b6fcdc05ae44006ff3b603ce5444ca 100644 (file)
@@ -14,6 +14,9 @@
 # 
 # Changelog:
 #
+# 2016-01-01 (version 1.7.2)
+# * Fix crash in Irssi during disconnect
+#
 # 2010-08-09 (version 1.7.1)
 # * Multiple control channels supported by checking chanmodes
 #
@@ -77,7 +80,7 @@ use Data::Dumper;
 
 use vars qw($VERSION %IRSSI);
 
-$VERSION = '1.7.1';
+$VERSION = '1.7.2';
 %IRSSI = (
        authors         => 'Tijmen "timing" Ruizendaal, Matt "f0rked" Sparks',
        contact         => 'tijmen.ruizendaal@gmail.com, root@f0rked.com',
@@ -85,22 +88,22 @@ $VERSION = '1.7.1';
        description     => '1. Adds an item to the status bar wich shows [typing] when someone is typing a message on the supported IM-networks 2. Sends typing notices to the supported IM networks (the other way arround). (For bitlbee 3.0+)',
        license         => 'GPLv2',
        url             => 'http://the-timing.nl/stuff/irssi-bitlbee, http://f0rked.com',
-       changed         => '2010-08-09',
 );
 
-my $bitlbee_server; # server object
-my @control_channels; # mostly: &bitlbee, &facebook etc.
+my %bitlbee_tag; # server object
+my %control_channels; # mostly: &bitlbee, &facebook etc.
 init();
 
 sub init { # if script is loaded after connect
        my @servers = Irssi::servers();
        foreach my $server(@servers) {
                if( $server->isupport('NETWORK') eq 'BitlBee' ){
-                       $bitlbee_server = $server;
+                       my $T = $server->{tag};
+                       $bitlbee_tag{$T} = 1;
                        my @channels = $server->channels();
                        foreach my $channel(@channels) {
                                if( $channel->{mode} =~ /C/ ){
-                                       push @control_channels, $channel->{name} unless (grep $_ eq $channel->{name}, @control_channels);
+                                       push @{ $control_channels{$T} }, $channel->{name} unless (grep $_ eq $channel->{name}, @{ $control_channels{$T} // [] });
                                }
                        }
                }
@@ -110,14 +113,15 @@ sub init { # if script is loaded after connect
 Irssi::signal_add_last('event 005' => sub {
        my( $server ) = @_;
        if( $server->isupport('NETWORK') eq 'BitlBee' ){
-               $bitlbee_server = $server;
+               $bitlbee_tag{ $server->{tag} } = 1;
        }
 });
 # if new control channel is synced after script is loaded
 Irssi::signal_add_last('channel sync' => sub {
        my( $channel ) = @_;
-       if( $channel->{mode} =~ /C/ && $channel->{server}->{tag} eq $bitlbee_server->{tag} ){
-               push @control_channels, $channel->{name} unless (grep $_ eq $channel->{name}, @control_channels);
+       my $T = $channel->{server}->{tag};
+       if( $channel->{mode} =~ /C/ && $bitlbee_tag{$T} ){
+               push @{ $control_channels{$T} }, $channel->{name} unless (grep $_ eq $channel->{name}, @{ $control_channels{$T} // [] });
        }
 });
 
@@ -140,81 +144,89 @@ my $to_char = Irssi::settings_get_str("completion_char"); # mostly: :
 
 sub event_ctcp_msg {
        my ($server, $msg, $from, $address) = @_;
-       return if $server->{tag} ne $bitlbee_server->{tag};
+       my $tag = $server->{tag};
+       return unless $bitlbee_tag{ $tag };
        if ( my($type) = $msg =~ "TYPING ([0-9])" ){
                Irssi::signal_stop();
                if( $type == 0 ){
-                       unset_typing($from);
+                       unset_typing($tag, $from);
                } elsif( $type == 1 ){
-                       $typing{$from}=1;
+                       my $k = "$tag/$from";
+                       $typing{$k}=1;
                        if( $address !~ /\@login\.oscar\.aol\.com/ and $address !~ /\@YAHOO/ and $address !~ /\@login\.icq\.com/ ){
-                               Irssi::timeout_remove($tag{$from});
-                               delete($tag{$from});
-                               $tag{$from}=Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000,"unset_typing",$from);
+                               Irssi::timeout_remove($tag{$k});
+                               delete($tag{$k});
+                               $tag{$k}=Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000,"unset_typing",[$tag,$from]);
                        }
-                       redraw($from);
+                       redraw($tag, $from);
                } elsif( $type == 2 ){
-                       stale_typing($from);
+                       stale_typing($tag, $from);
                }
        }
 }
 
 sub unset_typing {
-       my($from,$no_redraw)=@_;
-       delete $typing{$from} if $typing{$from};
-       Irssi::timeout_remove($tag{$from});
-       delete($tag{$from});
-       redraw($from) if !$no_redraw;
+       my($tag,$from,$no_redraw)=@_;
+       my $k = "$tag/$from";
+       delete $typing{$k} if $typing{$k};
+       Irssi::timeout_remove($tag{$k});
+       delete($tag{$k});
+       redraw($tag, $from) if !$no_redraw;
 }
 
 sub stale_typing {
-       my($from)=@_;
-       $typing{$from}=2;
-       redraw($from);
+       my($tag,$from)=@_;
+       my $k = "$tag/$from";
+       $typing{$k}=2;
+       redraw($tag, $from);
 }
 
 sub redraw {
-       my($from)=@_;
+       my($tag,$from)=@_;
        my $window = Irssi::active_win();
        my $name = $window->get_active_name();
        
        # only redraw if current window equals to the typing person, is a control channel or if allwin is set
-       if( $from eq $name || (grep $_ eq $name, @control_channels) || Irssi::settings_get_bool("bitlbee_typing_allwin") ){
+       if( $from eq $name || (grep $_ eq $name, @{ $control_channels{$tag} // [] }) || Irssi::settings_get_bool("bitlbee_typing_allwin") ){
                Irssi::statusbar_items_redraw('typing_notice');
        }
 }      
 
 sub event_msg {
        my ($server,$data,$from,$address,$target) = @_;
-       return if $server->{tag} ne $bitlbee_server->{tag};
+       my $tag = $server->{tag};
+       return unless $bitlbee_tag{ $tag };
        my $channel=Irssi::active_win()->get_active_name();
-       unset_typing $from, "no redraw";
-       unset_typing $channel;
+       unset_typing $tag, $from, "no redraw";
+       unset_typing $tag, $channel;
 }
 
 sub event_quit {
        my $server = shift;
-       return if $server->{tag} ne $bitlbee_server->{tag};
+       my $tag = $server->{tag};
+       return unless $bitlbee_tag{ $tag };
        my $nick = shift;
-       unset_typing $nick;
+       unset_typing $tag, $nick;
 }
 
 sub typing_notice {
        my ($item, $get_size_only) = @_;
        my $window = Irssi::active_win();
+       my $tag = Irssi::active_server->{tag};
        my $channel = $window->get_active_name();
+       my $k = "$tag/$channel";
        
-       if (exists($typing{$channel})) {
-               my $append=$typing{$channel}==2 ? " (stale)" : "";
+       if (exists($typing{$k})) {
+               my $append=$typing{$k}==2 ? " (stale)" : "";
                $item->default_handler($get_size_only, "{sb typing$append}", 0, 1);
        } else {
                $item->default_handler($get_size_only, "", 0, 1);
-               Irssi::timeout_remove($tag{$channel});
-               delete($tag{$channel});
+               Irssi::timeout_remove($tag{$k});
+               delete($tag{$k});
        }
        # we check for correct windows again, because the statusbar item is redrawn after window change too.
-       if( (grep $_ eq $channel, @control_channels) || Irssi::settings_get_bool("bitlbee_typing_allwin")) {
-               foreach my $key (keys(%typing)) {
+       if( (grep $_ eq $channel, @{ $control_channels{$tag} // [] }) || Irssi::settings_get_bool("bitlbee_typing_allwin")) {
+               foreach my $key (sort keys(%typing)) {
                        $line .= " ".$key;
                        if ($typing{$key}==2) { $line .= " (stale)"; }
                }
@@ -228,7 +240,7 @@ sub typing_notice {
 sub window_change {
        Irssi::statusbar_items_redraw('typing_notice');
        my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
-       if (ref $win && ($win->{server}->{tag} eq $bitlbee_server->{tag})) {
+       if (ref $win && defined $win->{server}->{tag} && $bitlbee_tag{ $win->{server}->{tag} }) {
                if (!$keylog_active) {
                        $keylog_active = 1;
                        Irssi::signal_add_last('gui key pressed', 'key_pressed');
@@ -244,24 +256,24 @@ sub window_change {
 sub key_pressed {
        return if !Irssi::settings_get_bool("bitlbee_send_typing");
        my $key = shift;
-       if ($key != 9 && $key != 10 && $lastkey != 27 && $key != 27 
+       if ($key != 9 && $key != 10 && $key != 13 && $lastkey != 27 && $key != 27 
           && $lastkey != 91 && $key != 126 && $key != 127) 
        {
                my $server = Irssi::active_server();
                my $window = Irssi::active_win();
                my $nick = $window->get_active_name();
-
-               if ($server->{tag} eq $bitlbee_server->{tag} && $nick ne "(status)" && $nick ne "root") {
-                       if( grep $_ eq $nick, @control_channels ){ # send typing if in control channel
+               my $tag = $server->{tag};
+               if (defined $tag && $bitlbee_tag{ $tag } && $nick ne "(status)" && $nick ne "root") {
+                       if( grep $_ eq $nick, @{ $control_channels{$tag} // [] } ){ # send typing if in control channel
                                my $input = Irssi::parse_special("\$L");
                                my ($first_word) = split(/ /,$input);
                                if ($input !~ /^$command_char.*/ && $first_word =~ s/$to_char$//){
-                                       send_typing($first_word);
+                                       send_typing($tag, $first_word);
                                }
                        } else { # or any other channels / query
                                my $input = Irssi::parse_special("\$L");
                                if ($input !~ /^$command_char.*/ && length($input) > 0){
-                                       send_typing($nick);
+                                       send_typing($tag, $nick);
                                }
                        }
                }
@@ -269,35 +281,53 @@ sub key_pressed {
        $lastkey = $key;
 }
 
+sub delete_server {
+       my $tag = shift;
+       delete $bitlbee_tag{$tag};
+       delete $control_channels{$tag};
+       undef;
+}
+
 sub out_empty {
        my ($a) = @_;
        my($nick,$tag)=@{$a};
-       delete($out_typing{$nick});
-       Irssi::timeout_remove($timer_tag{$nick});
-       delete($timer_tag{$nick});
-       $bitlbee_server->command("^CTCP $nick TYPING 0");
+       my $k = "$tag/$nick";
+       delete($out_typing{$k});
+       Irssi::timeout_remove($timer_tag{$k});
+       delete($timer_tag{$k});
+       if (my $bitlbee_server = Irssi::server_find_tag($tag)) {
+               $bitlbee_server->command("^CTCP $nick TYPING 0");
+       } else {
+               delete_server($tag);
+       }
 }
 
 sub send_typing {
-       my $nick = shift;
-       if (!exists($out_typing{$nick}) || time - $out_typing{$nick} > $KEEP_TYPING_TIMEOUT) {
-               $bitlbee_server->command("^CTCP $nick TYPING 1");
-               $out_typing{$nick} = time;
+       my ($tag, $nick) = @_;
+       my $k = "$tag/$nick";
+       if (!exists($out_typing{$k}) || time - $out_typing{$k} > $KEEP_TYPING_TIMEOUT) {
+               if (my $bitlbee_server = Irssi::server_find_tag($tag)) {
+                       $bitlbee_server->command("^CTCP $nick TYPING 1");
+               } else {
+                       delete_server($tag);
+               }
+               $out_typing{$k} = time;
                ### Reset 'stop-typing' timer
-               Irssi::timeout_remove($timer_tag{$nick});
-               delete($timer_tag{$nick});
+               Irssi::timeout_remove($timer_tag{$k});
+               delete($timer_tag{$k});
 
                ### create new timer
-               $timer_tag{$nick} = Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000, 'out_empty', ["$nick", $bitlbee_server->{tag}]);
+               $timer_tag{$k} = Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000, 'out_empty', ["$nick", $tag]);
        }
 }
 
 #README: Delete the old bitlbee_send_typing string from ~/.irssi/config. A boolean is better.
 
-sub db_typing { 
+sub db_typing {
+       local $Data::Dumper::Sortkeys = 1;
        print "Detected channels: ";
-       print Dumper(@control_channels);
-       print "Detected server tag: ".$bitlbee_server->{tag};
+       print Dumper(%control_channels);
+       print "Detected server tag: ".join ", ", sort keys %bitlbee_tag;
        print "Tag: ".Dumper(%tag);     
        print "Timer Tag: ".Dumper(%timer_tag); 
        print "Typing: ".Dumper(%typing);       
git clone https://git.99rst.org/PROJECT