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);
}
|