aboutsummaryrefslogtreecommitdiffstats
path: root/throttled-autojoin/throttled_autojoin.pl
blob: 6c90d14844185826dd0fc22462a6bab59eb5c38a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use strict;
use vars qw($VERSION %IRSSI);

use Irssi;

$VERSION = '0.1';
%IRSSI = (
          authors     => 'Shabble',
          contact     => 'shabble+irssi /at/ metavore /dot/ org',
          name        => 'Autojoin channels with a configurable delay',
          description => 'Mass autojoining can confuse some servers and slow/crash irssi.'
          . ' This is an alternative.',
          license     => 'WTFPL',
         );

# settings

Irssi::settings_add_int('throttled_autojoin', 'autojoin_initial_delay', 1000);
Irssi::settings_add_int('throttled_autojoin', 'autojoin_repeat_delay', 1000);
Irssi::settings_add_bool('throttled_autojoin', 'autojoin_auto_start', 0);

# format is space-separated list of '$tag/$channel'
Irssi::settings_add_str('throttled_autojoin', 'autojoin_channels', '');

my @join_queue = ();
my $autojoin_initialised = 0;
my $autojoin_running = 0;
my $autojoin_timer;
my $chan_list = {};

sub parse_channel_settings {
    my $chan_str = Irssi::settings_get_str('autojoin_channels');

    return unless length $chan_str;

    my @chans = split /\s+/, $chan_str;
    foreach my $chan (@chans) {
        if ($chan =~ m|(.*?)/(#.+)|) {
            push @{$chan_list->{$1}}, $2;
        } else {
            Irssi::print("Failed to parse channel setting: $chan");
        }
    }
}

sub handle_server_connected {
    my ($server) = @_;
    # add all the channels for the server in our setting into the queue.
    my $tag = $server->{tag};
    my $chatnet = $server->{chatnet};
    if (exists $chan_list->{$chatnet}) {
        my @chans = @{ $chan_list->{$chatnet} };
        foreach my $chan (@chans) {
            push @join_queue, [$server, $chan];
        }
        print "Server $tag ($chatnet) connected, adding "
          . join(", ", @chans) . " to join queue";

        # restart queue processing if it had stopped already.
        if ($autojoin_initialised && !$autojoin_running) {
            begin_queue_processing();
        }

    } else {
        print "Server joined, but no channels to autojoin";
    }
}

sub startup {
    my $initial_interval = Irssi::settings_get_int('autojoin_initial_delay') // 1000;

    parse_channel_settings();
    $autojoin_initialised = 0;

    Irssi::timeout_add_once($initial_interval, \&intialise_autojoin, 0);
}

sub intialise_autojoin {
    $autojoin_initialised = 1;
    begin_queue_processing();
}

sub begin_queue_processing {
    my $repeat_interval = Irssi::settings_get_int('autojoin_repeat_delay') // 1000;
    $autojoin_timer = Irssi::timeout_add($repeat_interval, \&process_queue, 0);
    $autojoin_running = 1;

}

sub process_queue {

    unless (@join_queue) {
        print "Join Queue empty, shutting down queue processor";
        $autojoin_running = 0;
        Irssi::timeout_remove($autojoin_timer);
        $autojoin_timer = undef;
        return;
    }
    # dequeue an item, and try to join it.
    my $next = shift @join_queue;
    my ($server, $channel) = @$next;
    if ($server->{connected} && !($server->channel_find($channel))) {
        $server->command("JOIN $channel");
    }
}

# listen for server connected.
Irssi::signal_add('server connected', \&handle_server_connected);

my $auto_start = Irssi::settings_get_bool('autojoin_auto_start') // 0;
if ($auto_start) {
    startup();
} else {
    Irssi::command_bind('autojoin', \&startup, 0);
}