1# Fixes for multiple servers and window items by dg
2#
3# 2003-08-27 coekie:
4# - use item names and server tags, fixes irssi crash if window item or server is destroyed
5#
6# 2003-08-19
7#  - changed timer stop code a bit.
8#    should fix the random timer o.O never happened to me before.
9#
10# 2002-12-21 darix:
11#  - nearly complete rewrite ;) the old version wasnt "use strict;" capable =)
12#  - still some warnings with "use warnings;"
13#  - use of command_runsub now :)
14#
15
16use strict;
17use Data::Dumper;
18use warnings;
19use vars  qw ($VERSION %IRSSI);
20use Irssi 20020325 qw (command_bind command_runsub command timeout_add timeout_remove signal_add_first);
21
22$VERSION = '0.8';
23%IRSSI = (
24    authors     => 'Kimmo Lehto, Marcus Rueckert',
25    contact     => 'kimmo@a-men.org, darix@irssi.org' ,
26    name        => 'Timer',
27    description => 'Provides /timer command for mIRC/BitchX type timer functionality.',
28    license     => 'Public Domain',
29    changed     => '2015-02-07'
30);
31
32Irssi::settings_add_bool('timer', 'timer_stop_msgs', 1);
33
34our %timers;
35# my %timer = { repeat => \d+, command => '' , windowitem => NULL , server=> NULL, timer = NULL};
36
37sub timer_command {
38    my ( $name ) = @_;
39    if ( exists ( $timers{$name} ) ) {
40        my ($server, $item);
41        if ($timers{$name}->{'server'}) {
42            $server = Irssi::server_find_tag( $timers{$name}->{'server'} );
43        }
44        if ( $server ) {
45	    if ( $timers{$name}->{'windowitem'}) {
46                $item = $server->window_find_item( $timers{$name}->{'windowitem'} );
47            }
48            ($item ? $item : $server)->command( $timers{$name}->{'command'} );
49        } else {
50            command( $timers{$name}->{'command'} );
51        }
52
53        if ( $timers{$name}->{'repeat'} != -1 ) {
54            if ( --$timers{$name}->{'repeat'} == 0) {
55                cmd_timerstop( $name );
56            }
57        }
58    }
59}
60
61sub cmd_timerstop {
62    my ( $name ) = @_;
63
64    my $verbose = Irssi::settings_get_bool('timer_stop_msgs');
65    if ( exists ( $timers{$name} ) ) {
66        timeout_remove($timers{$name}->{'timer'});
67        $timers{$name} = ();
68        delete ( $timers{$name} );
69        print( CRAP "Timer \"$name\" stopped." ) if $verbose;
70    }
71    else {
72        print( CRAP "\cBTimer:\cB No such timer \"$name\"." ) if $verbose;
73    }
74}
75
76sub cmd_timer_help {
77    print ( <<EOF
78
79TIMER LIST
80TIMER ADD  <name> <interval in seconds> [<repeat>] <command>
81TIMER STOP <name>
82
83repeat value of 0 means unlimited too
84
85EOF
86    );
87}
88
89command_bind 'timer add' => sub {
90    my ( $data, $server, $item ) = @_;
91    my ( $name, $interval, $times, $command );
92
93    if ( $data =~ /^\s*(\S+)\s+(\d+(?:\.\d+)?)\s+(-?\d+)\s+(.*)$/ ) {
94        ( $name, $interval, $times, $command ) = ( $1, $2, $3, $4 );
95        $times = -1 if ( $times == 0 );
96    }
97    elsif ( $data =~ /^\s*(\S+)\s+(\d+(?:\.\d+)?)\s+(.*)$/ )
98    {
99        ( $name, $interval, $times, $command ) = ( $1, $2, -1, $3 );
100    }
101    else {
102        print( CRAP "\cBTimer:\cB parameters not understood. commandline was: timer add $data");
103        return;
104    };
105
106    if ( $times < -1 ) {
107        print( CRAP "\cBTimer:\cB repeat should be greater or equal to -1" );
108        return;
109    };
110
111    if ( $command eq "" ) {
112        print( CRAP "\cBTimer:\cB command is empty commandline was: timer add $data" );
113        return;
114    };
115
116    if ( exists ( $timers{$name} ) ) {
117        print( CRAP "\cBTimer:\cB Timer \"$name\" already active." );
118    }
119    else {
120        #$timers{$name} = {};
121        $timers{$name}->{'repeat'}     = $times;
122        $timers{$name}->{'interval'}   = $interval;
123        $timers{$name}->{'command'}    = $command;
124	if ($item) {
125            $timers{$name}->{'windowitem'} = $item->{'name'};
126	}
127	if ($server) {
128            $timers{$name}->{'server'}     = $server->{'tag'};
129	}
130
131        if ( $times == -1 ) {
132            $times = 'until stopped.';
133        }
134        else {
135            $times .= " times.";
136        }
137
138        print( CRAP "Starting timer \"$name\" repeating \"$command\" every $interval seconds $times" );
139
140        $timers{$name}->{'timer'} = timeout_add( $interval * 1000, \&timer_command, $name );
141    }
142};
143
144command_bind 'timer list' => sub {
145    print( CRAP "Active timers:" );
146    foreach my $name ( keys %timers ) {
147        if ( $timers{$name}->{repeat} == -1 ) {
148            print( CRAP "$name = $timers{$name}->{'command'} (until stopped)");
149        }
150        else {
151            print( CRAP "$name = $timers{$name}->{'command'} ($timers{$name}->{'repeat'} repeats left)" );
152        }
153    }
154    print( CRAP "End of /timer list" );
155};
156
157command_bind 'timer stop' => sub {
158    my ( $data, $server, $item ) = @_;
159    cmd_timerstop ($data);
160};
161
162command_bind 'timer help' => sub { cmd_timer_help() };
163
164command_bind 'timer' => sub {
165    my ( $data, $server, $item ) = @_;
166    $data =~ s/\s+$//g;
167    command_runsub ( 'timer', $data, $server, $item ) ;
168};
169
170
171signal_add_first 'default command timer' => sub {
172#
173# gets triggered if called with unknown subcommand
174#
175    cmd_timer_help()
176}
177
178