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