html/eliza.pl
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
7 use strict;
8 use 5.6.0;
9 use Irssi;
10 use Chatbot::Eliza;
11
12 use 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";
28 undef $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
34 Irssi::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
46 sub 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
59 Irssi::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
90 sub 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
99 Irssi::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 );