The Bot Who Came In Out of the Cold
I’ve now sunk a number of hours into it and added some functionality, none of which really works yet. But in the interest of keeping things going, here’s where things stand now. Explore doesn’t quite work, and there are still weird undef matches in the dialogue. But I pulled out all of Expect.pm and went to Smart::Comments.
#!/usr/bin/perl
# mudbot by Shannon Prickett <stp@manjusri.org>
# connect a pandorabots.com chatbot with a particular TinyMUCK, Pegasus.
package mudbot;
use Smart::Comments;
use Modern::Perl;
use Net::Telnet;
use Net::AIML;
use DB_File;
use vars qw{$being_quiet %global_exit $mud_connection $mud_conversation $mud_host $mud_name
$mud_pass $mud_port $mud_sent $pid $robot %room_name };
use subs qw{setup};
$mud_host = 'ginka.armageddon.org';
$mud_port = '4242';
$mud_name = 'Somebot';
$mud_pass = 'YRMEME';
$being_quiet = 0;
$pid = $$;
tie %room_name, 'DB_File', 'mapfile' or
die "can't tie to mapfile: $!\n";
$robot = Net::AIML->new( botid => 'GETFROMPANDORABOTS' );
$mud_connection = new Net::Telnet( Host => $mud_host, Port => $mud_port )
or die "Can't connect to $mud_host $mud_port: $!";
setup( $mud_connection );
TALKLOOP: while (1) {
### TALKLOOP start
my $atme = 0;
my $prematch = '';
my $postmatch = '';
my $who_said;
my ($stub_said, $what_said) =
$mud_connection->waitfor( Match => '/ says, ".*"/',
Errmode => 'return', );
next TALKLOOP unless defined $what_said;
$stub_said =~ qr{ START \d+ .+ \b(\w+)\b }msx;
$who_said = $1;
$what_said =~ s{says, \"(.*)\"}{$1}g;
### Got: $who_said
### Got: $what_said
if ($what_said =~ qr{$mud_name}msxi){
### saw my name
$atme = 1;
}
$what_said =~ s{$mud_name}{}g;
if ( ($atme) && ($what_said =~ qr{QUIT}) ) {
$mud_connection->print("QUIT");
exit;
}
if ( ($atme) && ($what_said =~ qr{be quiet}) ) {
if ($being_quiet) {
$mud_connection->print("say Maximum verbosity achieved.");
$being_quiet = 0;
} else
{
$mud_connection->print("say Shutting up now.");
$being_quiet = 1;
}
}
if ( ($atme) && ($what_said =~ qr{search for '(.*)'}msxi) ) {
my $terms = $1;
my @terms = split $terms;
my $querystring = join '+', @terms;
$mud_connection->print("say Found http://lmgtfy.com/q=$querystring");
}
if ( ($atme) && ($what_said =~ qr{explore}) ) {
$mud_connection->print("say OK, going to poke around now.");
sleep 3;
$mud_connection->print('home');
goto EXPLORELOOP;
}
if ($being_quiet) {
next TALKLOOP;
}
my $response = $robot->tell($what_said);
if ($atme) {
print "response: $response\n";
speak( $response );
}
else {
if ( !$being_quiet && (rand() > .75) ) {
print "jumping in with $response\n";
speak( $response );
}
}
}
EXPLORELOOP: while (1) {
### exploring
my ($name, $desc);
$mud_connection->print('look');
my $startmark = $mud_connection->getline( );
$name = $mud_connection->getline( );
while (my $line = $mud_connection->getline( Errmode => 'return', )) {
$desc .= $line;
}
$mud_connection->waitfor( Match => '/END$pid/', Errmode => 'return');
chomp $name;
chomp $desc;
### got: $name
### got: $desc
$room_name{$name} = $desc;
sleep 10;
$mud_connection->print('out');
}
sub setup {
my $mc = shift;
$mc->dump_log('/home/binder/src/mb/logfile');
$mc->waitfor('/connect\s+guest\s+guest/');
$mc->print("connect $mud_name $mud_pass");
$mc->waitfor('/Vote to ban the MisInformation SuperHighway/');
$mc->print('@desc me=Just a Perl toy of Binder\'s.');
$mc->print("OUTPUTPREFIX START$pid");
$mc->print("OUTPUTSUFFIX END$pid");
$mc->waitfor('/Description set/');
$mc->print("home\nout\nvillage");
}
sub speak {
my $response = shift;
my @lines = split /\n/, $response;
for my $line (@lines) {
$mud_connection->print("say $line");
}
}
