1# Answers to /msg's using Chatbot::Eliza when you're away.
2
3# Put definition files to ~/.irssi/eliza/*.txt
4# Uses the default definitions if there aren't any definition files.
5# http://misterhouse.net:81/mh/data/eliza/
6
7use strict;
8use 5.6.0;
9use Irssi;
10use Chatbot::Eliza;
11
12use vars qw($VERSION %IRSSI $eliza_dir @cmd_queue
13  $min_reply_time $max_reply_time
14  %conversations $conversation_expire);
15
16$VERSION = '1.0';
17%IRSSI = (
18    authors     => 'Johan "Ion" Kiviniemi',
19    contact     => 'ion at hassers.org',
20    name        => 'Eliza',
21    description => 'Answers to /msg\'s using Chatbot::Eliza when you\'re away.',
22    license     => 'Public Domain',
23    url         => 'http://ion.amigafin.org/scripts/',
24    changed     => 'Thu Mar 14 05:29 EET 2002',
25);
26
27$eliza_dir = Irssi::get_irssi_dir . "/eliza";
28undef $eliza_dir unless -d $eliza_dir;
29
30$min_reply_time      = 5;      # seconds
31$max_reply_time      = 15;     # seconds as well
32$conversation_expire = 600;    # seconds again
33
34Irssi::timeout_add(
35    1000 * $conversation_expire, sub {
36        foreach (keys %conversations) {
37            if ($conversations{$_}{lastmsg} < time - $conversation_expire) {
38                # The Chatbot::Eliza object will be destroyed automagically.
39                delete $conversations{$_};
40            }
41        }
42    },
43    undef
44);
45
46sub new_eliza {
47    my ($name, $eliza_o, @files) = shift;
48    if ($eliza_dir) { @files = <$eliza_dir/*.txt> }
49    if (@files) {
50        $eliza_o = Chatbot::Eliza->new(scriptfile => $files[ rand @files ])
51          || return;
52    } else {
53        $eliza_o = Chatbot::Eliza->new() || return;
54    }
55    $eliza_o->name($name);
56    return $eliza_o;
57}
58
59Irssi::signal_add(
60    'message private' => sub {
61        # Someone just msg'ed me.
62        my ($server, $message, $nick, $address) = @_;
63        return if $nick eq $server->{nick};
64
65        # Ignore it if I'm not away.
66        return unless $server->{usermode_away};
67
68        if (not $conversations{$address}
69            and $conversations{$address}{lastmsg} < time - $conversation_expire)
70        {
71            # A new conversation.
72            $conversations{$address} = { lastmsg => time };
73            unless ($conversations{$address}{eliza} =
74                new_eliza($server->{nick}))
75            {
76                Irssi::print("Chatbot::Eliza->new() failed!",
77                    MSGLEVEL_CLIENTERROR);
78                delete $conversations{$address};
79                return;
80            }
81        } else {
82            # Continuing an old conversation.
83            $conversations{$address}{lastmsg} = time;
84        }
85        push_queue($server, "msg $nick "
86            . $conversations{$address}{eliza}->transform($message));
87    }
88);
89
90sub push_queue {
91    my ($server, $command) = @_;
92    return if @cmd_queue > 3;
93    my $reply_time =
94      int(time + $min_reply_time + rand($max_reply_time - $min_reply_time));
95    push @cmd_queue, [ $reply_time, $server, $command ];
96    @cmd_queue = sort { $a->[0] <=> $b->[0] } @cmd_queue;
97}
98
99Irssi::timeout_add(
100    1000, sub {
101        while (@cmd_queue and $cmd_queue[0][0] <= time) {
102            my $cmd = shift @cmd_queue;
103            $cmd->[1]->command($cmd->[2]);
104        }
105    },
106    undef
107);
108