Logo hamBot

#!/usr/local/bin/perl

use warnings;

use strict;

use POE;

use POE::Component::IRC;

use IO::Handle;

use LWP::Simple;

use DBI;

use Data::Random qw(:all);

$ENV{PATH} = "/bin:/usr/bin";

delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

open LOG, ">>/home/tomg/hamBot_command.log" or die "Cannot open /home/tomg/hamBot_command.log\n\n";

open CHANNELLOG, ">>/home/tomg/hamBot_channel.log" or die "Cannot open /home/tomg/hamBot_channel.log\n\n";

LOG->autoflush(1);

CHANNELLOG->autoflush(1);

open MYLOG, ">>/home/tomg/hamBot_mysql.log" or die "Cannot open /home/tomg/hamBot_mysql.log\n\n";

MYLOG->autoflush(1);

our ($mysql_command, $db_error, @row, @rows, $db_connected_flag, $dbh, $sth, $loop_count, %commands, @cave);

our $motd = get_item("SELECT message FROM motd WHERE id=(?)", '1');

our $secret_word = get_item("SELECT word FROM secret WHERE id=(?)", '1');

if (! $secret_word) { &pick_secret }

our $shut_up = 0;

our $prod_count = 0;

our $quiet_flag = 0;

our $pm_flag = 0;

our $version = "9.75";

our $start_time = time;

&init;

my ($irc) = POE::Component::IRC->spawn();

POE::Session->create( inline_states => { irc_msg => \&on_msg, irc_part => \&on_part, irc_disconnected => \&reconnect, irc_error => \&reconnect, irc_socketerr => \&reconnect, autoping => \&autoping, _start => \&start, irc_001 => \&on_connect, irc_public => \&on_public, irc_join => \&on_join, _stop => \&shut_down, tick => \&tick, }, );

$poe_kernel->run();

exit 0;

sub CHANNEL () { "#fridaynightroundtable.net" }

#IRC Commands

sub send_msg { # Send message to the proper channel

  my ($msg, $nick) = @_;

  $msg =~ s/(\n+)//g;

  my $ts = scalar localtime;

  if ($pm_flag == 1 and $nick ne "") {

    $irc->yield( privmsg => $nick => $msg );

    print CHANNELLOG "Private | $ts | hamBot : $msg\n";

  } elsif ($shut_up == 0) {

    $irc->yield( privmsg => CHANNEL, $msg );

    print CHANNELLOG "Public  | $ts | hamBot : $msg\n";

  }

}

# IRC Control Housekeeping

sub start { # Start the IRC connection

  $irc->yield( register => "all" );

  $_[KERNEL]->delay( tick => 5 );

  my $nick = 'hamBot';

  $irc->yield( connect => { Nick => $nick, Username => 'hamBot', Ircname => 'Friday Night Roundtable Discussion Net Bot', Server => 'novel.ix.us.dal.net', Port => '6667', } );

}

sub on_connect { # Connected, now join channel

  $irc->yield( join => CHANNEL );

}

sub on_msg { # Private message to hamBot

  $pm_flag = 1;

  my ( $kernel, $heap, $who, $where, $msg ) = @_[ KERNEL, HEAP, ARG0, ARG1, ARG2 ];

  my $nick = ( split /!/, $who )[0];

  if (lc($nick) ne "hambot") { &is_seen($nick) }

  my $channel = $where->[0];

  my ($command, $subject, $text) = parse_command($msg);

  if (defined $commands{$command} ) { $commands{$command}->($subject, $text, $nick) }

}

sub on_public { # A message has been sent to the channel

  $pm_flag = 0;

  $prod_count = $loop_count = 0;

  my ( $kernel, $heap, $who, $where, $msg ) = @_[ KERNEL, HEAP, ARG0, ARG1, ARG2 ];

  my $nick = ( split /!/, $who )[0];

  if (lc($nick) ne "hambot") { &is_seen($nick) }

  my $ts = scalar localtime;

  print CHANNELLOG "Public  | $ts | $nick : $msg\n";

  my $channel = $where->[0];

  if ( lc(substr($msg, 0, 15) ) eq "what time is it") { $commands{'time'}->("", "", $nick); return }

  if ( $msg =~ / $secret_word /i or $msg =~ / $secret_word(.)$/i ) { $commands{'secret'}->($secret_word, "", $nick); return }

  if ( $msg =~ /dumb bot/i) { send_msg("Stupid human!", $nick); return }

  if ( $msg =~ /stupid bot/i) { send_msg("Dumb human!", $nick); return }

  my ($command, $subject, $text) = parse_command($msg);

  if ($command eq "42") { $command = "fortytwo" }

  if (defined $commands{$command} ) { $commands{$command}->($subject, $text, $nick) }

}

sub on_join { # Run whenever someone joins the channel

  my ( $kernel, $who, $where) = @_[ KERNEL, ARG0, ARG1 ];

  my $nick = ( split /!/, $who )[0];

  my $greeting = get_response("greeting", "", $nick);

  if ($nick ne "hamBot") {

    my $ts = scalar localtime;

    send_msg("Everybody welcome $nick to the Friday Night Roundtable Discussion Net IRC Channel!", $nick);

    print LOG "$who joins the channel at $ts\n";

    send_msg("$greeting $nick !! $motd.", $nick);

  }

  &is_seen($nick);

  my $non = get_item( "SELECT COUNT(*) FROM user_notes WHERE sent_to=(?)", ($nick) );

  if ($non == 1) { send_msg("There is a note for you. (read with 'read notes', or /msg hamBot read_notes to read the notes in a private channel.)", $nick) }

  if ($non > 1)  { send_msg("There are $non notes for you. (read the notes with 'read notes')", $nick) }

}

sub on_part { # Run whenever someone leaves the channel

  my ( $kernel, $who, $where) = @_[ KERNEL, ARG0, ARG1 ];

  my $nick = ( split /!/, $who )[0];

  if ($nick ne "hamBot") {

    my $ts = scalar localtime;

    send_msg("Bye $nick !!", $nick);

    print LOG "$who leaves the channel at $ts\n";

  }

  &is_seen($nick);

}

sub autoping { # Keep us connected

  my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];

  $kernel->post( poco_irc => userhost => "hamBot_" )

    unless $heap->{seen_traffic};

  $heap->{seen_traffic} = 0;

  $kernel->delay( autoping => 300 );

}

sub reconnect { # Reconnect if we get disconnected

  my $kernel = $_[KERNEL];

  $kernel->delay( autoping => undef );

  $kernel->delay( connect  => 60 );

}

sub shut_down { # Shut the Bot down

  my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ];

  delete $heap->{wheel};

  $kernel->alias_remove( $heap->{alias} );

  $kernel->alarm_remove_all();

  $kernel->refcount_decrement( $session, 'my ref name' );

  $kernel->post( $heap->{child_session}, 'shutdown' );

  return;

}

# Function Routines

sub user_exists { # Check to see if a user exists. 0 = No such nick 1 = Valid nick

  my ($nick) = @_;

  if ($nick =~ m/^([A-Za-z0-9._-]+)$/) {

    return ( get_item("SELECT count(*) FROM users WHERE nick=(?)", $nick) );

  } else {

    return 0;

  }

}

sub calc_diff { # Calculate time difference

  my ($when) = @_;

  my $diff = (time() - $when);

  my $day = int($diff / 86400);

  $diff -= ($day * 86400);

  my $hrs = int($diff / 3600);

  $diff -= ($hrs * 3600);

  my $min = int($diff / 60);

  $diff -= ($min * 60);

  my $sec = $diff;

  return "${day}d ${hrs}h ${min}m ${sec}s";

}

sub valid_callsign { # Validate callsigns before making a request to the server

  my $call = uc(shift);

  if ( $call =~ m /^[KNW][A-Z][0-9][A-Z]{1,3}$/ or $call =~ m /^A[A-L][0-9][A-Z]{1,3}$/ or $call =~ m /^[KNW][0-9][A-Z]{2,3}$/ ) { return 1 }

  return 0;

}

sub get_response { # Pick a random response, depending on $type

  my ($type, $option, $nick) = @_;

  my (@responses);

  if ($type eq "greeting") {

    @responses = ("Welcome", "Hi", "Hello", "Good to see you", "What a pleasure it is to see you", "Thanks for visiting", "Greetings", "Come on in", "You made it",
                   "We are graced by your presence", "Come in, come in", "We open our doors to you", );

  } elsif ($type eq "win") {

    @responses = ("Very good $nick! You won!", "Excellent job $nick! You won the game!", "Excellent! You won!", "Fabulous work! You win!", "A ding ding ding! We have a W*I*N*N*E*R!",
                  "Most excellent win $nick!",  );

  } elsif ($type eq "lose") {

    @responses = ("Sorry $nick, you lost the game :(", "Whoops, that was the last try. You lost the game", "Dang! You lost.", "Better luck next time $nick, you lost the game",
                  "Better luck next time, you lost the game", "Geeeez, no more turns. You lost the game", "Well that blows rather large chunks. You lost the game.",
                  "That was the suck. You lost the game.", "Well, that's the end of that, the game is over. You lost :(", );

  } elsif ($type eq "wrong") {

    @responses = ("WRONG WRONG WRONG", "Sorry $nick, that answer is not correct.", "So sorry, that is not correct.", "So sorry, that is wrong", "So sorry, that is incorrect",
                  "$option is incorrect. Sorry.",  );

  } elsif ($type eq "correct") {

    @responses = ("", "", "");

  } elsif ($type eq "prod") {

    @responses = ("No one is saying anything...", "Let's chat it up out there...", "I hear crickets...", "Sure is quiet in here :)", "Sssshhhh, I'm trying to sleep ;)",
                     "tick...tick...tick...", "Sure is quiet in here...", );

  }

    return $responses[int(rand($#responses + 1))];

}

sub parse_command { # Parse input from the IRC channel to get commands and other parameters

  my ($msg) = @_;

  $msg =~ s/^[\s]+//;

  my @msgs    = split /[\s]+/, $msg;

  my $command = shift(@msgs);

  my $subject = shift(@msgs);

  my $message = join(" ", @msgs);

  if (! defined $command) { $command = "" }

  if (! defined $subject) { $subject = "" }

  if (! defined $message) { $message = "" }

  return $command, $subject, $message;

}

sub ordinalize {

  my ($input) = @_;

  if ( (substr($input, -2) > 3) and (substr($input, -2) < 21) ) { $input .= "th"; }

  elsif ( substr($input, -1) == 3 ) { $input .= "rd"; }

  elsif ( substr($input, -1) == 2 ) { $input .= "nd"; }

  elsif ( substr($input, -1) == 1 ) { $input .= "st"; }

  else  { $input .= "th"; }

  return $input;

}

sub ran_function {

  return int(rand() * shift) + 1;

}

sub pick_secret {

  my $now = get_item("SELECT COUNT(*) FROM hangman WHERE word like (?)", "%");

  $secret_word = get_item("SELECT word FROM hangman WHERE id=(?)", int(rand($now) + 1));

  do_query("UPDATE secret SET word=(?), time=(?) WHERE id=(?)", ($secret_word, time, '1'));

}

# Bot Commands

sub check_net_message { # See if there are any message from net_controller.pl

  my ($mysql_command, @mysql_data, $nick);

  $mysql_command = "SELECT msg_from, message FROM msg_data WHERE msg_from=(?)";

  @mysql_data    = ('NETMSG');

  my ($msg_from, $message) = get_record($mysql_command, @mysql_data);

  if ($message) {

    send_msg("$msg_from: $message", $nick);

    $mysql_command = "UPDATE msg_data SET message=(?) where msg_from=(?)";

    @mysql_data    = ('', 'NETMSG');

    do_query($mysql_command, @mysql_data);

  }

}

sub tick { # This routine is run every 5 seconds

  &check_net_message;

  ∏

  $_[KERNEL]->delay( tick => 5);

}

sub prod { # If no one is saying anything prod them to say something (6 times and then be quiet)

  ++$loop_count;

  if ($loop_count >= 300 and $prod_count <= 6) {

    send_msg(get_response("prod", "", ""), "");

    $loop_count = 0;

    ++$prod_count;

    $quiet_flag = 0;

  } elsif ($loop_count >= 300 and $prod_count > 6 and $quiet_flag == 0) {

    send_msg("I'm going to be quiet now. It's up to you people to say something now...", "");

    ++$quiet_flag;

  }


}

sub is_seen { # Update last_seen in the database

  my ($nick) = @_;

  if (user_exists($nick)) {

    do_query("UPDATE users SET last_seen=(?) where nick=(?)", (time, $nick));

  } else {

    do_query("INSERT INTO users (nick, last_seen, status, kizmit, trivia, mastermind, bamboozled, rev, twenty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", ($nick, time, "normal", "0", "0~0~0~0", "0~0~0~0", "0~0~0~0", "0~0~0", "0~0~0"));

  }

}

# MySQL Routines

sub do_query { # Perform non-read queries on the database

  my ($mysql_command, @mysql_data) = @_;

  print MYLOG "Executing $mysql_command using @mysql_data\n";

  if (! $db_connected_flag ) { &connect_to_database }

  $sth = $dbh->prepare($mysql_command);

  $sth->execute(@mysql_data);

  $db_error = $sth->errstr();

  if ($db_error) {

    print MYLOG "DB ERROR in do_query - mysql_command = $mysql_command - mysql_data = @mysql_data - $db_error\n";

  }

}

sub get_item { # Retrieve one item from database

  my ($mysql_command, $mysql_data) = @_;

  my @result = get_record($mysql_command, ($mysql_data));

  return $result[0];

}

sub get_record { # Retrieve one record from database

  my ($mysql_command, @mysql_data) = @_;

  if (! $db_connected_flag ) { &connect_to_database }

  $sth = $dbh->prepare($mysql_command);

  $sth->execute(@mysql_data);

  $db_error = $sth->errstr;

  if ($db_error) {

    print MYLOG "DB ERROR in pull_record : mysql_command = $mysql_command / mysql_data = @mysql_data : $db_error \n";

    return ();

  } else {

    return $sth->fetchrow_array();

  }

}

sub get_records { # Retrieve multiple records from database

  my ($mysql_command, @mysql_data) = @_;

  if (! $db_connected_flag ) { &connect_to_database }

  $sth = $dbh->prepare($mysql_command);

  $sth->execute(@mysql_data);

  $db_error = $sth->errstr;

  if ($db_error) {

    print MYLOG "DB ERROR in get_records : mysql_command = $mysql_command / mysql_data = @mysql_data : $db_error \n";

  } else {

    @rows = ();

    while ( @row = $sth->fetchrow_array() ) {

      push @rows, [@row];

    }

    return @rows;

  }

}

sub connect_to_database { # Create the connection to the MySQL database

  $dbh = DBI->connect("this is all secret stuff");

  $db_connected_flag = 1;

}

# Wumpus routines

sub hazard_warnings {

  my ($nick, @objects) = @_;

  if ( grep /^$objects[1]$/,               @{$cave[$objects[0]]}[1..3]  ) { send_msg("I SMELL A WUMPUS!", $nick) }

  if ( grep /^($objects[2]|$objects[3])$/, @{$cave[$objects[0]]}[1..3]  ) { send_msg("I FEEL A DRAFT!", $nick)   }

  if ( grep /^($objects[4]|$objects[5])$/, @{$cave[$objects[0]]}[1..3]  ) { send_msg("BATS NEARBY!", $nick)      }

  send_msg("YOU ARE IN ROOM $objects[0]", $nick);

  send_msg("TUNNELS LEAD TO " . join(" ", @{$cave[$objects[0]]}[1..3]), $nick);

}

sub move_wumpus {

  my ($nick, @objects) = @_;

  my $move_to = &ran_function(4);

  if ( ($move_to == 4 and $objects[1] == $objects[0]) or $cave[$objects[1]][$move_to] == $objects[0] ) { send_msg("WUMPUS: Tsk Tsk Tsk - The Wumpus got you!", $nick); return ('2', @objects) }

  $objects[1] = $cave[$objects[1]][$move_to];

  return ('0', @objects);

}

sub init { # Initialization - Contains all the command subroutines

  our %commands = (

    wumpus     => sub {

      my ($subject, $text, $nick) = @_;

      $pm_flag = 0;

      my $game_state = get_item("SELECT game_state FROM wumpus WHERE id like (?)", "%");

      if (lc($subject) eq "start") {

        do_query("UPDATE wumpus SET game_starter=(?), game_state=(?), program_state=(?), objects=(?), start_objects=(?), cave_type=(?) WHERE id like (?)", ($nick, '0', '0', "AAAAAAAA", "AAAAAAAA", '0', "%") );

        $commands{'wr'}->("0", "", $nick);

        return;

      }

      if (lc($subject) eq "help" or $subject eq "") {

        send_msg("This is the game of Hunt the Wumpus 2. It would be much easier for you to understand how this game is played by", $nick);

        send_msg("visiting http://www.fridaynightroundtable.net/hambot.hmtl or http://jerz.setonhill.edu/if/canon/Hunt_the_Wumpus.htm", $nick);

        send_msg("Hunt the Wumpus was written in 1972 by Gregory Yob. ", $nick);

        return;

      }

      if ($game_state != 3) {

        send_msg("WUMPUS: There is no game in progress. Enter 'wumpus start' to begin a new game", $nick);

        return;

      }

      send_msg("Wumpus what? What's a wumpus? Need help? Enter 'wumpus help'.", $nick);

      send_msg("Attempting to send a response to the Hunt the Wumpus game? Precede your response with the letters 'wr'.", $nick);

    },

    wr         => sub {

      my ($subject, $text, $nick) = @_;

      $pm_flag = 0;

      my ($id, $game_starter, $game_state, $program_state, $objects, $start_objects, $cave_type) = get_record('SELECT * FROM wumpus WHERE id like (?)', '%');

      if ($game_state == 3) { send_msg('Sorry, there is no Wumpus 2 game in progress. Enter \'wumpus start\' to begin a new game.', $nick); return }

      my ($random_number, $flag);

      my $cave = get_item("SELECT $cave_type FROM wumpus_caves WHERE id=(?)", ('caves') );

      @cave = (undef, map([undef, map($_-64, unpack('C3', $_))], unpack('(A3)*', $cave))) ;

      my @objects =  map {ord($_)-65} (unpack('(A)*', $objects));

      my @start_objects =  map {ord($_)-65} (unpack('(A)*', $start_objects));

      if ($game_state == 0 and $subject eq "status") {

        &hazard_warnings($nick, @objects);

        send_msg("You have $objects[6] arrow(s) left.", $nick);

        return;

      }

      if ($program_state == 0) {

        send_msg('WUMPUS: 1)Dodecahedron 2)Mobius Strip 3)String of Beads 4)Hex Network 5)Dendrites 6)One-way Streets', $nick);

        send_msg('WUMPUS: Which cave would you like?', $nick);

        $program_state = 1;

      }

      elsif ($program_state == 1) {

        if    ($subject == 1 or lc($subject) eq "dodecahedron")    { $cave_type = "dodecahedron" }

        elsif ($subject == 2 or lc($subject) eq "mobius strip")    { $cave_type = "mobius_strip" }

        elsif ($subject == 3 or lc($subject) eq "string of beads") { $cave_type = "stringofbeads" }

        elsif ($subject == 4 or lc($subject) eq "hex network")     { $cave_type = "hexnetwork" }

        elsif ($subject == 5 or lc($subject) eq "dendrite")        { $cave_type = "dendrite" }

        elsif ($subject == 6 or lc($subject) eq "one-way streets") { $cave_type = "onewaystreets" }

        else { $program_state = 0; send_msg('WUMPUS: You need to pick one the of listed caves! Enter the cave number or name!', $nick); return }

        for my $j (0..5) { $flag = 0; while ($flag == 0) { $random_number = &ran_function(20); $flag = 1; if ($j > 1 and grep /$random_number/, @objects) { $flag = 0 } } $objects[$j] = $random_number }

        @start_objects = @objects;

        $objects[6] = 5;

        $game_state = 0;

        $program_state = 2;

        $cave = get_item("SELECT $cave_type FROM wumpus_caves WHERE id=(?)", ('caves') );

        @cave = (undef, map([undef, map($_-64, unpack('C3', $_))], unpack('(A3)*', $cave))) ;

        send_msg("HUNT THE WUMPUS!", $nick);

        &hazard_warnings($nick, @objects);

        send_msg("WUMPUS: (S)hoot or (M)ove ?", $nick);

      }

      elsif ($program_state == 2 and $text eq "") {

        if (lc($subject) eq "s" or lc($subject) eq "shoot") {

          send_msg("WUMPUS: Number of rooms (1-5) ?", $nick);

          $program_state = 4;

        }

        elsif (lc($subject) eq "m" or lc($subject) eq "move") {

          send_msg("WUMPUS: Where to?", $nick);

          $program_state = 3;

        }

        else {

          send_msg("WUMPUS: You must either (S)hoot an arrow or (M)ove to a different room!", $nick);

          &hazard_warnings($nick, @objects);

          send_msg("WUMPUS: (S)hoot or (M)ove ?", $nick);

          return;

        }

      }

      elsif ($program_state == 3 or ($program_state == 2 and $text ne "")) {

        if ($text) { $subject = $text }

        if ($subject < 1 or $subject > 20 or int($subject) != abs($subject) ) {

          send_msg("WUMPUS: There is no room number $subject!", $nick);

          send_msg("WUMPUS: Where to ? (Enter a valid room number!)", $nick);

          return;

        }

        elsif ($subject == $objects[0]) {

          send_msg("WUMPUS: You'll never get anywhere in this game if you just walk in circles!", $nick);

          &hazard_warnings($nick, @objects);

          send_msg("WUMPUS: Where to?", $nick);

          return

        }

        elsif (! grep /^$subject$/, @{$cave[$objects[0]]}[1..3] ) {

          send_msg("WUMPUS: There is no tunnel leading to room #$subject!", $nick);

          &hazard_warnings($nick, @objects);

          send_msg("WUMPUS: Where to?", $nick);

          return

        }
        my $flag = 0;

        while ($flag == 0) {

          $flag = 1;

          if ($subject == $objects[1]) { send_msg("WUMPUS: Oops! Bumped the Wumpus", $nick); ($game_state, @objects) = &move_wumpus($nick, @objects) }

          if ($subject == $objects[2] or $subject == $objects[3]) { send_msg("WUMPUS: YYYYIIIIEEEE . . . You fell in a pit", $nick); $game_state = 2 }

          if ($subject == $objects[4] or $subject == $objects[5]) { send_msg("WUMPUS: Zap--Super Bat Snatch! Elsewhereville for you!", $nick); $subject = &ran_function(20); $flag = 0; }

        }

        $objects[0] = $subject;

        if ($game_state == 0) {

          $program_state = 2;

          &hazard_warnings($nick, @objects);

          send_msg("WUMPUS: (S)hoot or (M)ove ?", $nick);

        }

      }

      elsif ($program_state == 4) {
if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: program_state($program_state) / @objects", $nick) }
        if ($subject < 1 or $subject > 5 or int($subject) != abs($subject)) {

          send_msg("WUMPUS: Your arrow can travel through up to 5 connected rooms. How many rooms would you like your arrow to pass through?", $nick);

          return;

        }

        $objects[7] = $subject;

        send_msg("WUMPUS: Enter Room #1", $nick);

        $program_state = 5;

      }

      elsif ($program_state == 5) {

        my @arrow_path = (@objects)[8..$objects[7] + 7];
if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: program_state($program_state) / nor set to $objects[7] / nor entered is $#arrow_path arrow_path @arrow_path / objects @objects", $nick) }
        if ($subject < 1 or $subject > 20 or int($subject) != abs($subject) ) {

          send_msg("WUMPUS: You must enter a valid room # (1-20)", $nick);

          return;

        }

        if (grep /^$subject$/, @arrow_path) {

          send_msg("WUMPUS: Arrows aren't that crooked, try a different room!", $nick);

          return;

        }

        push @arrow_path, $subject;

        push @objects, $subject;

if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: program_state($program_state) / nor set to $objects[7] / nor entered is $#arrow_path arrow_path @arrow_path / objects @objects", $nick) }
        if ($#arrow_path + 1 < $objects[7]) {

          send_msg("WUMPUS: Enter Room #" . ($#arrow_path + 1), $nick);

          $program_state = 5;

        } else {

          my $arrow_room = $objects[0];
if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: arrow starts in $arrow_room", $nick) }
          for my $k (0..$#arrow_path) {

            if ( grep /^$arrow_path[$k]$/, @{$cave[$arrow_room]}[1..3] ) { $arrow_room = $arrow_path[$k]; if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: arrow goes to $arrow_room", $nick) } next }

            $arrow_room = $cave[$objects[0]][&ran_function(3)];
if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: arrow ends in random room $arrow_room off of room $objects[0]", $nick) }
            last;

          }

          if ($arrow_room == $objects[1]) { send_msg("WUMPUS: AHA! You got the Wumpus!!", $nick); $game_state = 1 }

          if ($arrow_room == $objects[0]) { send_msg("WUMPUS: OUCH! You shot yourself!!", $nick); $game_state = 2 }

          if ($game_state == 0) {

            send_msg("WUMPUS: The arrow missed! :(", $nick);
if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: pre move_wumpus game_state = $game_state / @objects", $nick) }
            ($game_state, @objects) = &move_wumpus($nick, @objects);
if ($text eq "debug" and ($nick eq "W1SDM" or $nick eq "fullautoglock")) { send_msg("WUMPUS DEBUG: post move_wumpus game_state = $game_state / @objects", $nick) }
            --$objects[6];

            if ($objects[6] == 0) { send_msg("WUMPUS: You are out of arrows.", $nick); $game_state = 2 }

            @objects = @objects[0..7];

          }

          if ($game_state == 0) {

            &hazard_warnings($nick, @objects);

            $program_state = 2;

          }

        }

      }

      elsif ($program_state == 6) {

        if (lc($subject) ne "y" and lc($subject) ne "yes" and lc($subject) ne "n" and lc($subject) ne "no") {

          send_msg("WUMPUS: Would you like to play another game?", $nick);

        }

        if (lc($subject) eq "y" or lc($subject) eq "yes") {

          $program_state = 7;

        } else {

          $program_state = 8;

          $game_state = 3;

          $game_starter = "";

          $cave_type = "";

          @objects = (undef);

          @start_objects = (undef);

        }

      }

      elsif ($program_state == 7) {

        if (lc($subject) ne "y" and lc($subject) ne "yes" and lc($subject) ne "n" and lc($subject) ne "no") {

          send_msg("WUMPUS: Would you like to the same setup as last game?", $nick);

          $program_state = 7;

        }

        $game_starter = $nick;

        $game_state = 0;

        if (lc($subject) eq "n" or lc($subject) eq "no") {

          $program_state = 0;

          @objects = (undef);

          for my $j (0..5) { $flag = 0; while ($flag == 0) { $random_number = &ran_function(20); $flag = 1; if ($j > 1 and grep /$random_number/, @objects) { $flag = 0 } } $objects[$j] = $random_number }

          @start_objects = @objects;

          $objects[6] = 5;

          $program_state = 2;

          send_msg("HUNT THE WUMPUS!", $nick);

          &hazard_warnings($nick, @objects);

          send_msg("WUMPUS: (S)hoot or (M)ove ?", $nick);

        }

        if (lc($subject) eq "n" or lc($subject) eq "no") {

          @objects = @start_objects;

          $program_state = 2;

          $objects[6] = 5;

        }

      }

      elsif ($program_state == 8) {

        send_msg("WUMPUS: There is no game in progress. Enter 'wumpus start' to begin a new game", $nick);

        return;

      }

      if ($game_state == 2) {

        send_msg("WUMPUS: You lose the game. :(", $nick);

        $game_state = 3;

        $program_state = 6;

        send_msg("WUMPUS: Thanks for playing though!", $nick);

      }

      if ($game_state == 1) {

        send_msg("WUMPUS: :) !!YOU WIN THE GAME!! :)", $nick);

        send_msg("WUMPUS: The Wumpus'll get you next time!", $nick);

        $game_state = 3;

        $program_state = 6;

      }

      $objects =  join("", map {chr($_ + 65)} @objects);

      $start_objects =  join("", map {chr($_ + 65)} @start_objects);

      do_query("UPDATE wumpus SET game_starter=(?), game_state=(?), program_state=(?), objects=(?), start_objects=(?), cave_type=(?) WHERE id like (?)", ($game_starter, $game_state, $program_state, $objects, $start_objects, $cave_type, "%") );

    },

    twenty     => sub {

      my ($subject, $text, $nick) = @_;

      $pm_flag = 0;

      $subject =~ s/( +)//g;

      my ($game_state, $response, $choices);

      $game_state = get('http://www.mindformation.com/cgi-bin/20q_server.pl?command=STATUS');

      if ($game_state == 1) { send_msg("hamBot: There is a 20 Questions game already in progress.", $nick); return }

      if ($game_state == 0 and lc($subject) eq "start") {

        $response = get("http://www.mindformation.com/cgi-bin/20q_server.pl?command=START&nick=$nick");

        $response = substr($response, 3);

        ($response, $choices) = split /\|\|\|/, $response;

        send_msg("20Q: $response", $nick);

        send_msg("20Q: $choices", $nick);

      } else {

        send_msg("20 Questions is a game whose questions are supplied byby http://www.20q.net/", $nick);

        send_msg("Twenty uses a HIGHLY modified version of the WWW::TwentyQuestions Perl module and other Perl software.", $nick);

        send_msg("A 20 questions server was set up on www.mindformation.com to interface this IRC version with the 20q.net web site.", $nick);

        return;

      }

    },

    tqr        => sub {

      my ($subject, $text, $nick) = @_;

      $pm_flag = 0;

      my ($response, $word, $choices);

      my $game_state = get("http://www.mindformation.com/cgi-bin/20q_server.pl?command=STATUS&nick=$nick");

      if ($game_state == 0) { send_msg("There is no 20 Questions game in progress. To start a 20 Questions game enter 'twenty start'.", $nick); return }

      $subject =~ s/( +)//g;

      if ($subject) { $response = get("http://www.mindformation.com/cgi-bin/20q_server.pl?command=RESPONSE&response=$subject&nick=$nick") }

      if ($response =~ /^ERROR/) { send_msg("There has been an error of some sort :( Game being reset", $nick); $game_state = 0 }

      if ($response =~ /^MSG:LOSE/) {

        $word = substr($response, 9);

        send_msg("20 Questions guessed that you were $word", $nick);

        send_msg("20 Questions WON, better luck next time!", $nick);

        $game_state = 0

      }

      if ($game_state == 0) { $response = get("http://www.mindformation.com/cgi-bin/20q_server.pl?command=RESET&response=GAMEOVER&nick=$nick"); return }

      if (length($response) > 4) { $response = substr($response, 4) }

      ($response, $choices) = split /\|\|\|/, $response;

      send_msg("20Q: $response", $nick);

      send_msg("20Q: $choices", $nick);

    },

    rev        => sub {

      my ($subject, $text, $nick) = @_;

      my ($rev_stats, $games_started, $games_finished, $total_moves, $flag, $random_number, @objects, $rev_object);

      $pm_flag = 0;

      my ($game_state, $rev_game_count, $rev_number, $rev_move_count) = get_record("SELECT * FROM rev_game WHERE state LIKE (?)", "%");

      if ($subject eq "help") {

        send_msg("This is the game of 'reverse'(original game by Peter Sessions), we call it rev. Enter the numbers of numbers from the left that you want to reverse.", $nick);

        send_msg("You win the game when you have the numbers in order from 1 to 9. Good luck. Precede the number you are entering with 'rr'", $nick);

        return;

      }

      if ($game_state == 1) { send_msg("There is a rev game already in progress.", $nick) }

      if ($game_state == 0 and $subject ne "start") { send_msg("There is no rev game running. Enter \"rev start\" to begin a new game.", $nick); return }

      if ($game_state == 0 and lc($subject) eq "start") {

        @objects = ('');

        for my $j (1..9) { $flag = 0; while ($flag == 0) { $random_number = int(rand() * 9) + 1; $flag = 1; if ($j > 1 and grep /$random_number/, @objects) { $flag = 0 } } $objects[$j] = $random_number }

        shift @objects;

        $rev_object = join("  ", @objects);

        $rev_number = join('', @objects);

        $rev_stats = get_item("SELECT rev FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_finished, $total_moves) = split /~/, $rev_stats;

        ++$games_started;

        do_query("UPDATE users SET rev=(?) WHERE nick=(?)", ("$games_started~$games_finished~$total_moves", $nick));

        $rev_game_count = get_item("SELECT game_number FROM rev_game WHERE state LIKE (?)", "%");

        ++$rev_game_count;

        do_query("UPDATE rev_game SET state=(?), game_number=(?), rev_number=(?), move_count=(?) WHERE state LIKE (?)",("1", $rev_game_count, $rev_number, '0', "%"));

        send_msg("Starting rev game #$rev_game_count.", $nick);

        send_msg("REV: -->  $rev_object  <--", $nick);

        return;

      } else {

        $rev_number = get_item("SELECT rev_number FROM rev_game WHERE state LIKE (?)", "%");

        @objects = split //, $rev_number;

        $rev_object = join("  ", @objects);

        send_msg("REV: Current state is -->  $rev_object  <--", $nick);

      }

    },

    rr         => sub {

      my ($subject, $text, $nick) = @_;

      my ($rev_stats, $games_started, $games_finished, $total_moves, @objects, $rev_object);

      my ($game_state, $rev_game_count, $rev_number, $rev_move_count) = get_record("SELECT * FROM rev_game WHERE state LIKE (?)", "%");

      $pm_flag = 0;

      if ($game_state == 0) {

        send_msg("Sorry, there is no rev game in progress. To start a rev game, enter \"rev start\"", $nick);

        return;

      }

      if ($subject eq "") { send_msg("Let's see, reverse null numbers? You don't want to do that! :)", $nick); return }

      $subject += 0;

      if ($subject < 2 or $subject > 9 or int($subject) != abs($subject) ) { send_msg("That's a crazy number! :)", $nick); return }

      $rev_number = reverse(substr($rev_number, 0, $subject)) . substr($rev_number, $subject);

      @objects = split //, $rev_number;

      $rev_object = join("  ", @objects);

      send_msg("REV: -->  $rev_object  <--", $nick);

      ++$rev_move_count;

      if ( $rev_number eq "123456789" ) {

        send_msg(get_response('win', $rev_move_count, $nick), $nick);

        $rev_stats = get_item("SELECT rev FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_finished, $total_moves) = split /~/, $rev_stats;

        ++$total_moves;

        ++$games_finished;

        do_query("UPDATE users SET rev=(?) WHERE nick=(?)", ("$games_started~$games_finished~$total_moves", $nick));

        if ($rev_move_count == 1) { send_msg("It only took 1 move! Very good then.", $nick) } else { send_msg("It took " . ($rev_move_count) . " moves.", $nick) }

        do_query("UPDATE rev_game SET state=(?) WHERE state LIKE (?)", ("0", "%"));

        send_msg("To start another game, enter \"rev start\"", $nick);

      } else {

        $rev_stats = get_item("SELECT rev FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_finished, $total_moves) = split /~/, $rev_stats;

        ++$total_moves;

        do_query("UPDATE users SET rev=(?) WHERE nick=(?)", ("$games_started~$games_finished~$total_moves", $nick));

        do_query("UPDATE rev_game SET state=(?), game_number=(?), rev_number=(?), move_count=(?) WHERE state LIKE (?)",("1", $rev_game_count, $rev_number, $rev_move_count, "%"));

      }

    },

    trivia     => sub {

      my ($subject, $text, $nick) = @_;

      my ($trivia_stats, $games_started, $games_won, $games_lost, $answers_given);

      $pm_flag = 0;

      my ($game_state, $trivia_game_count, $trivia_category, $trivia_question, $trivia_answer, $trivia_guess_count, $last_guess, $last_nick, $trivia_guesses_allowed) = get_record("SELECT * FROM trivia_game WHERE state LIKE (?)", "%");

      if ($nick eq "W1SDM" and $subject eq "ga" and $text > 0 and $text <= 12 and $game_state == 0) {

        do_query("UPDATE trivia_game SET guesses_allowed=$text WHERE state LIKE (?)", "%");

        send_msg("Trivia guesses allowed is now $text", $nick);

        return;

      }

      if ($subject eq "help") {

        send_msg("Just answer the flippin' question correctly. Oh, and enter tq before your answer!", $nick);

        return;

      }

      if ($game_state == 1) { send_msg("There is a trivia game already in progress.", $nick) }

      if ($game_state == 0 and $subject ne "start") { send_msg("There is no trivia game running. Enter \"trivia start\" to begin a new game.", $nick); return }

      if ($game_state == 0 and lc($subject) eq "start") {

        $trivia_stats = get_item("SELECT trivia FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $trivia_stats;

        ++$games_started;

        do_query("UPDATE users SET trivia=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

        my $noq = get_item("SELECT count(*) FROM trivia WHERE id LIKE (?)", '%');

        ($trivia_category, $trivia_question, $trivia_answer) = get_record("SELECT category, question, answer FROM trivia WHERE id=(?)", int(rand($noq)) + 1);

        $trivia_game_count = get_item("SELECT game_number FROM trivia_game WHERE state LIKE (?)", "%");

        ++$trivia_game_count;

        do_query("UPDATE trivia_game SET state=(?), game_number=(?), category=(?), question=(?), answer=(?), guess_count=(?) WHERE state LIKE (?)",("1", $trivia_game_count, $trivia_category, $trivia_question, $trivia_answer, "0", "%"));

        $trivia_guess_count = 0;

        send_msg("Starting trivia game #$trivia_game_count.", $nick);

        send_msg("The trivia category is : $trivia_category", $nick);

        send_msg("The trivia question is : $trivia_question", $nick);

        return;

      } else {

        send_msg("The current trivia cateogry is $trivia_category, the question is : $trivia_question", $nick);

        if ($trivia_guess_count != 1) {

          if ($trivia_guesses_allowed - $trivia_guess_count == 1) {

            send_msg("There have been $trivia_guess_count guesses. One more guess before the answer is revealed.", $nick);

          } else {

            send_msg("There have been $trivia_guess_count guesses. " . ($trivia_guesses_allowed - $trivia_guess_count) . " more guesses before the answer is revealed.", $nick);

          }

        } else {

          send_msg("There has been 1 guess. " . ($trivia_guesses_allowed - 1) . " more guesses before the answer is revealed.", $nick);

        }

      }

    },

    tr         => sub {

      my ($subject, $text, $nick) = @_;

      my ($trivia_stats, $games_started, $games_won, $games_lost, $answers_given);

      if ($text) { $subject .= " $text" }

      $subject = lc($subject);

      $pm_flag = 0;

      my ($game_state, $trivia_game_count, $trivia_category, $trivia_question, $trivia_answer, $trivia_guess_count, $last_guess, $last_nick, $trivia_guesses_allowed) = get_record("SELECT * FROM trivia_game WHERE state LIKE (?)", "%");

      if ($game_state == 0) {

        send_msg("Sorry, there is no trivia game in progress. To start a trivia game, enter \"trivia start\"", $nick);

        return;

      }

      if ($subject eq $last_guess) {

        if ($last_nick eq $nick) {

          send_msg("Hey, you just said that. It was wrong then, it is wrong now. Try again.", $nick);

        } else {

          send_msg("I hear an echo, $last_nick just said that. $subject is still wrong Try again.", $nick);

        }

        do_query("UPDATE trivia_game SET last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ($subject, $nick, "%") );

        return;

      }

      if ($subject eq "") {

        send_msg("What is that? Some sort of Zen thing? Try actually entering an answer.", $nick);

        do_query("UPDATE trivia_game SET last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ($subject, $nick, "%") );

        return;

      }

      if ( grep /\b$subject\b/, lc($trivia_answer) ) {

        send_msg(get_response("win", $trivia_answer, $nick), $nick);

        $trivia_stats = get_item("SELECT trivia FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $trivia_stats;

        ++$answers_given;

        ++$games_won;

        do_query("UPDATE users SET trivia=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

        if ($trivia_guess_count == 0) { send_msg("It only took 1 guess! Very good then.", $nick) } else { send_msg("It took " . ($trivia_guess_count + 1) . " guesses.", $nick) }

        do_query("UPDATE trivia_game SET state=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ("0", $subject, $nick, "%"));

        send_msg("To start another game, enter \"trivia start\"", $nick);

        return;

      } else {

        send_msg(get_response("wrong", $subject, $nick), $nick);

        ++$trivia_guess_count;

        do_query("UPDATE trivia_game SET guess_count=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ($trivia_guess_count, $subject, $nick, "%") );

        if ($trivia_guesses_allowed - $trivia_guess_count <= 0) {

          $trivia_stats = get_item("SELECT trivia FROM users WHERE nick=(?)", $nick);

          ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $trivia_stats;

          ++$answers_given;

          ++$games_lost;

          do_query("UPDATE users SET trivia=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

          send_msg(get_response("lose", "", $nick));

          do_query("UPDATE trivia_game SET state=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ("0", $subject, $nick, "%"));

          send_msg("To start another game, enter \"trivia start\"", $nick);

          return;

        }

        $trivia_stats = get_item("SELECT trivia FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $trivia_stats;

        ++$answers_given;

        do_query("UPDATE users SET trivia=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

        if ($trivia_guess_count !=1 and $trivia_guesses_allowed - $trivia_guess_count != 1) {

          send_msg("That's $trivia_guess_count guesses. There are " . ($trivia_guesses_allowed - $trivia_guess_count) . " guesses left.", $nick);

        } elsif ($trivia_guess_count == 1) {

          send_msg("That's 1 guess. There are " . ($trivia_guesses_allowed - $trivia_guess_count) . " guesses left.", $nick);

        } elsif ($trivia_guesses_allowed - $trivia_guess_count == 1) {

          send_msg("That's $trivia_guess_count guesses. There is 1 guess left.", $nick);

        }

      }

    },

    bamboozled => sub {

      my ($subject, $text, $nick) = @_;

      $pm_flag = 0;

      my ($game_state, $bamboozled_game_count, $word, $turn_count, $letters_chosen, $letters_left, $guesses_allowed) = get_record("SELECT * FROM bamboozled_game WHERE state LIKE (?)", "%");

      if ($nick eq "W1SDM" and $subject eq "ga" and $text > 0 and $text <= 12 and $game_state == 0) {

        do_query("UPDATE bamboozled_game SET guesses_allowed=(?) WHERE state LIKE (?)", ($text, "%"));

        send_msg("Bamboozled guesses allowed is now $text", $nick);

        return;

      }

      if ($subject eq "help") {

        return;

      }

      if ($game_state == 1) { send_msg("There is a Bamboozled game already in progress.", $nick) }

      if ($game_state == 0 and $subject ne "start") { send_msg("There is no Bamboozled game running. Enter \"bamboozled start\" to begin a new game.", $nick); return }

      if ($game_state == 0 and lc($subject) eq "start") {

        my ($games_started, $games_won, $games_lost, $letters_guessed) = split /~/, get_item("SELECT bamboozled FROM users WHERE nick=(?)", $nick);

        ++$games_started;

        do_query("UPDATE users SET bamboozled=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$letters_guessed", $nick));

        ++$bamboozled_game_count;

        my $now = get_item("SELECT COUNT(*) FROM hangman WHERE word like (?)", "%");

        $word = uc(get_item("SELECT word FROM hangman WHERE id=(?)", int(rand($now) + 1)));

        $game_state = 1;

        $turn_count = 0;

        $letters_left = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        $letters_chosen = "";

        do_query("UPDATE bamboozled_game SET state=(?), game_number=(?), word=(?), turn_count=(?), letters_chosen=(?), letters_left=(?) WHERE state LIKE (?)", ($game_state, $bamboozled_game_count, $word, $turn_count, $letters_chosen, $letters_left, "%"));

        send_msg("Starting Game #$bamboozled_game_count.", $nick);

        send_msg("I have a word in mind, let's see if you can find that word!", $nick);

        my $msg = "(  ) " . " " x (12 - $turn_count) . "Secret Word-> " . " - " x length($word) . " <-Secret Word    ( $letters_left )";

        send_msg($msg, $nick);

        return;

      } else {

        if ($turn_count != 1) {

          if ($guesses_allowed - $turn_count == 1) {

            send_msg("There have been $turn_count incorrect guesses. One more turn before the game is over.", $nick);

          } else {

            send_msg("There have been $turn_count incorrect guesses. " . ($guesses_allowed - $turn_count) . " more incorrect letters before the game is over.", $nick);

          }

        } else {

          send_msg("There has been 1 incorrect letter chosen. " . ($guesses_allowed - 1) . " more incorrect letters before the word is revealed and the game is over.", $nick);

        }

      }

    },

    br         => sub {

      my ($subject, $text, $nick) = @_;

      $subject = uc($subject);

      my ($games_started, $games_won, $games_lost, $letters_guessed) = split /~/, get_item("SELECT bamboozled FROM users WHERE nick LIKE (?)", ($nick));

      my ($state, $bamboozled_game_count, $word, $turn_count, $letters_chosen, $letters_left, $guesses_allowed) = get_record("SELECT * FROM bamboozled_game WHERE state like (?)", ("%"));

      $pm_flag = 0;

      if ($state == 0) {

        send_msg("There is no Bamboozled game in progress. To start a game of Bamboozled, enter \"bamboozled start\"", $nick);

        return;

      }

      if ($subject eq "") {

        send_msg("I'm not sure I understand what it is you want me to do. You must enter a letter. \"bamboozled help\" might help too.", $nick);

        return;

      }

      if (length($subject) != 1 and $subject ne "SHOW") {

        send_msg("Whoa, one letter at a time there buckaroo!", $nick);

        return;

      }

      if (! ($subject =~ /^[A-Z]/ )) {

        send_msg("Nothing fancy going on here, just enter a letter of the english alphabet that hasn't been chosen already!", $nick);

        return;

      }

      if (index($letters_left, $subject) == -1) {

        send_msg("The letter $subject has already been chosen. Please choose a letter that hasn't been (chosen) :)", $nick);

        return;

      }

      $letters_chosen .= $subject;

      substr($letters_left, ord($subject) - 65, 1) = "_";

      ++$letters_guessed;

      my $show_word = "";

      if (index($word, substr($letters_chosen, length($letters_chosen) - 1 , 1)) == -1) { ++$turn_count }

      for my $x (0..length($word)) {

        if ( index($letters_chosen, substr($word, $x, 1) ) != -1) {

          $show_word .= " " . substr($word, $x, 1) . " ";

        } else {

          $show_word .= " - ";

        }

      }

      my $msg = "( " . substr("bamboozled", 0, $turn_count) . " ) " . " " x (12 - $turn_count) . " Secret Word-> $show_word <-Secret Word   ( $letters_left )";

      send_msg($msg, $nick);

      $show_word =~ s/ //g;

      if ($word eq $show_word) {

        send_msg(get_response("win", "", $nick));

        send_msg("The word was $word. You weren't bamboozled!", $nick);

        ++$games_won;

        $state = 0;

      } elsif ($turn_count >= $guesses_allowed ) {

        send_msg(get_response("lose", "", $nick));

        send_msg("You've been bamboozled! The word was $word", $nick);

        ++$games_lost;

        $state = 0;

      }

      do_query("UPDATE users SET bamboozled=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$letters_guessed", $nick));

      do_query("UPDATE bamboozled_game SET state=(?), turn_count=(?), letters_chosen=(?), letters_left=(?) WHERE state LIKE(?)", ($state, $turn_count, $letters_chosen, $letters_left, "%"));

    },

    hambot     => sub {

      my ($subject, $text, $nick) = @_;

      if ($subject eq "") {

        print LOG "$nick asks for hamBot information\n";

        send_msg( "I am a Bot. I am hamBot version $version and W1SDM wrote me using POE::IRC. Visit http://www.fridaynightroundtable.net/hambot.html to see what I can do\n", $nick );

      }

      if ($nick ne "W1SDM" and $subject eq "shutup") { send_msg("You're not the boss of me. :P", $nick); return }

      if ($nick ne "W1SDM" and $subject eq "talk")   { send_msg("What would you like me to say. :|", $nick); return }

      if ($nick eq "W1SDM" and $subject eq "shutup") { send_msg("Sorry... :(", $nick); $shut_up = 1; return }

      if ($nick eq "W1SDM" and $subject eq "talk")   { $shut_up = 0; send_msg("Thank you. :D", $nick); return }

    },

    stats      => sub {

      my ($subject, $text, $nick) = @_;

      my  ($kizmit, $trivia_stats, $mastermind_stats, $bamboozled_stats) = get_record("SELECT kizmit, trivia, mastermind, bamboozled FROM users WHERE nick=(?)", ($nick));

      my  ($trivia_games_started, $trivia_games_won, $trivia_games_lost, $trivia_answers_given) = split /~/, $trivia_stats;

      my  ($mastermind_games_started, $mastermind_games_won, $mastermind_games_lost, $mastermind_answers_given) = split /~/, $mastermind_stats;

      my  ($bamboozled_games_started, $bamboozled_games_won, $bamboozled_games_lost, $bamboozled_letters_entered) = split /~/, $bamboozled_stats;

      send_msg("You are $nick and your kizmit is $kizmit", $nick);

      send_msg ("Trivia - Games Started: $trivia_games_started  Games Won: $trivia_games_won  Games Lost: $trivia_games_lost  Answers Submitted: $trivia_answers_given");

      send_msg ("MasterMind - Games Started: $mastermind_games_started  Games Won: $mastermind_games_won  Games Lost: $mastermind_games_lost  Guesses Submitted: $mastermind_answers_given");

      send_msg ("Bamboozled - Games Started: $bamboozled_games_started  Games Won: $bamboozled_games_won  Games Lost: $bamboozled_games_lost  Letters Submitted: $bamboozled_letters_entered");

    },

    dow        => sub {

      my ($subject, $text, $nick) = @_;

      if ($text ne "") { $subject .= " $text" }

      send_msg(get("http://www.mindformation.com/cgi-bin/net_dow.pl?$subject"), $nick);

    },

    mastermind => sub {

      my ($subject, $text, $nick) = @_;

      my ($mastermind_stats, $games_started, $games_won, $games_lost, $answers_given);

      $pm_flag = 0;

      my ($game_state, $mastermind_game_count, $mastermind_answer, $mastermind_guess_count, $last_guess, $last_nick, $mastermind_guesses_allowed) = get_record("SELECT * FROM mastermind_game WHERE state LIKE (?)", "%");

      if ($nick eq "W1SDM" and $subject eq "ga" and $text > 0 and $text <= 12 and $game_state == 0) {

        do_query("UPDATE mastermind_game SET guesses_allowed=$text WHERE state LIKE (?)", "%");

        send_msg("MasterMind guesses allowed is now $text", $nick);

        return;

      }

      if ($subject eq "help") {

        send_msg("A + indicates a correct digit, in the correct position.", $nick);

        send_msg("A ? indicates a correct digit, in the wrong position.", $nick);

        send_msg("A - indicates an incorrect digit.", $nick);

        send_msg("Precede your guess with mm", $nick);

        return;

      }

      if ($game_state == 1) { send_msg("There is a MasterMind game already in progress.", $nick) }

      if ($game_state == 0 and $subject ne "start") { send_msg("There is no MasterMind game running. Enter \"mastermind start\" to begin a new game.", $nick); return }

      if ($game_state == 0 and lc($subject) eq "start") {

        $mastermind_stats = get_item("SELECT mastermind FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $mastermind_stats;

        ++$games_started;

        do_query("UPDATE users SET mastermind=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

        ++$mastermind_game_count;

        do_query("UPDATE mastermind_game SET state=(?), game_number=(?), game_answer=(?), guess_count=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ("1", $mastermind_game_count, join("", (rand_chars( set=> 'numeric', size => '4'))), "0", "", "", "%"));

        send_msg("Starting MasterMind game #$mastermind_game_count.", $nick);

        send_msg("I am electronic processing of a 4 digit number, see if you can guess what it is!", $nick);

        return;

      } else {

        if ($mastermind_guess_count != 1) {

          if ($mastermind_guesses_allowed - $mastermind_guess_count == 1) {

            send_msg("There have been $mastermind_guess_count guesses. One more guess before the 4 digit number is revealed.", $nick);

          } else {

            send_msg("There have been $mastermind_guess_count guesses. " . ($mastermind_guesses_allowed - $mastermind_guess_count) . " more guesses before the 4 digit number is revealed.", $nick);

          }

        } else {

          send_msg("There has been 1 guess. " . ($mastermind_guesses_allowed - 1) . " more guesses before the answer is revealed.", $nick);

        }

      }


    },

    mr         => sub {

      my ($subject, $text, $nick) = @_;

      my ($mastermind_stats, $games_started, $games_won, $games_lost, $answers_given);

      $pm_flag = 0;

      my ($game_state, $mastermind_game_count, $mastermind_answer, $mastermind_guess_count, $last_guess, $last_nick, $mastermind_guesses_allowed) = get_record("SELECT * FROM mastermind_game WHERE state LIKE (?)", "%");

      if ($game_state == 0) {

        send_msg("There is no MasterMind game in progress. To start a game of MasterMind, enter \"mastermind start\"", $nick);

        return;

      }

      if ($subject eq "") {

        send_msg("What the? Your four digits disappeared? Oh, I see what you did there, you forgot to enter them.", $nick);

        return;

      }

      if (length($subject) != 4) {

        send_msg("The answer will be 4 (four) [count them, FOUR] characters long. Not " . length($subject) . ". Gosh!", $nick);

        return;

      }

      if (! ($subject =~ /^\d\d\d\d$/ )) {

        send_msg("Please, this isn't rocket science. The answer will be 4 characters long and the characters will be the numbers 0 - 9.", $nick);

        return;

      }

      if ($mastermind_answer eq $subject) {

        send_msg("$mastermind_answer  Ding ding ding. We have a W*I*N*N*E*R. Way to go $nick!", $nick);

        $mastermind_stats = get_item("SELECT mastermind FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $mastermind_stats;

        ++$answers_given;

        ++$games_won;

        do_query("UPDATE users SET mastermind=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

        if ($mastermind_guess_count == 0) {

          send_msg("You got it on the 1st guess! What a lucky person!", $nick);

        } else {

          send_msg("It took " . ($mastermind_guess_count + 1) . " guesses.", $nick);

        }

        do_query("UPDATE mastermind_game SET state=(?), game_answer=(?), guess_count=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ("0", $mastermind_answer, $mastermind_guess_count, $subject, $nick, "%"));

        send_msg("To start another game, enter \"mastermind start\"", $nick);

        return;

      } else {

        my @x = split //, $subject;

        my @n = split //, $mastermind_answer;

        my $mastermind_result = "";

        my (@x1, @n1);

        for my $i (0 .. 3) { $n1[$i] = "0" }

        for my $i (0 .. 3) { $x1[$i] = "0" }

        for my $i (0 .. 3) {

          if ($x[$i] == $n[$i]) {

            $x1[$i] = 1;

            $n1[$i] = 1;

            $mastermind_result .= "+";

          }

        }

        for my $i (0 .. 3) {

          for my $j (0 .. 3) {

            if ($x1[$i] != 1 and $n1[$j] != 1 and $x[$i] == $n[$j]) {

              $x1[$i] = 1;

              $n1[$j] = 1;

              $mastermind_result .= "?";

              last;

            }

          }

        }

        $mastermind_result .= "-" x (4 - length($mastermind_result));

        @n = split //, $mastermind_result;

        $mastermind_result = join(" ", @n);

        send_msg("$subject : $mastermind_result", $nick);

        ++$mastermind_guess_count;

        do_query("UPDATE mastermind_game SET guess_count=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ($mastermind_guess_count, $subject, $nick, "%"));

        if ($mastermind_guesses_allowed - $mastermind_guess_count == 0) {

          $mastermind_stats = get_item("SELECT mastermind FROM users WHERE nick=(?)", $nick);

          ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $mastermind_stats;

          ++$answers_given;

          ++$games_lost;

          do_query("UPDATE users SET mastermind=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

          send_msg("No more guesses. The 4 digits were $mastermind_answer. Better luck next time.", $nick);

          do_query("UPDATE mastermind_game SET state=(?), game_answer=(?), guess_count=(?), last_guess=(?), last_nick=(?) WHERE state LIKE (?)", ("0", $mastermind_answer, $mastermind_guess_count, $subject, $nick, "%"));

          send_msg("To start another game, enter \"mastermind start\"", $nick);

          return;

        }

        $mastermind_stats = get_item("SELECT mastermind FROM users WHERE nick=(?)", $nick);

        ($games_started, $games_won, $games_lost, $answers_given) = split /~/, $mastermind_stats;

        ++$answers_given;

        do_query("UPDATE users SET mastermind=(?) WHERE nick=(?)", ("$games_started~$games_won~$games_lost~$answers_given", $nick));

        if ($mastermind_guess_count !=1 and $mastermind_guesses_allowed - $mastermind_guess_count != 1) {

          send_msg("That's $mastermind_guess_count guesses. There are " . ($mastermind_guesses_allowed - $mastermind_guess_count) . " guesses left.", $nick);

        } elsif ($mastermind_guess_count == 1) {

          send_msg("That's 1 guess. There are " . ($mastermind_guesses_allowed - $mastermind_guess_count) . " guesses left.", $nick);

        } elsif ($mastermind_guesses_allowed - $mastermind_guess_count == 1) {

          send_msg("That's $mastermind_guess_count guesses. There is 1 guess left.", $nick);

        }

      }

    },

    version    => sub {

      my ($subject, $text, $nick) = @_;

      send_msg("hamBot is Version $version", $nick);

    },

    kizmit     => sub {

      my ($subject, $text, $nick) = @_;

      my ($mysql_command, $mysql_data, @mysql_data, $kizmit);

      if (lc($subject) eq "hambot") {

        if ( $text eq "++") {

         send_msg("hamBot's kizmit is already infinite, trying to increase it would just be a waste of electrons.", $nick);

         return;

        } elsif ( $text eq "--") {

          send_msg("Hahaha, Sisyphus had a better chance. You cannot decrease hamBot's kizmit. Forgeddabout it...", $nick);

          return;

        } elsif ($text) {

          send_msg("You are messing with hamBot's kizmit, that can't be a good thing. Please, leave it alone, there is nothing you can do about it.", $nick);

          return;

        }

        send_msg("Normally you can't view other people's kizmit, but I can tell you that hamBot's kizmit, like Chuck Norris', is infinite! :)", $nick);

        return;

      }

      if (lc($subject) eq lc($nick) or !$subject) {

        if ($text eq "--" or $text eq "++") {

          send_msg("You can't directly change your own kizmit, it has to happen of it's own accord. Be good in life and your kizmit will increase!", $nick);

          return;

        } elsif ($text) {

          send_msg("Careful, don't mess with your own kizmit.", $nick);

          return;

        }

        $mysql_command = "SELECT kizmit FROM users WHERE nick=(?)";

        $mysql_data    = $nick;

        $kizmit        = get_item($mysql_command, $mysql_data);

        send_msg("Your kizmit is $kizmit", $nick);

        return;

      }

      if ($subject and !$text) { send_msg("You can't peer into other peoples kizmit, you can only affect it.", $nick); return }

      if (user_exists($subject)) {

        $mysql_command = "SELECT kizmit FROM users WHERE nick=(?)";

        $mysql_data    = $subject;

        $kizmit        = get_item($mysql_command, $mysql_data);

        if ($text eq "++") { ++$kizmit; send_msg("$subject\'s kizmit has increased...", $nick) }

        if ($text eq "--") { --$kizmit; send_msg("$subject\'s kizmit has decreased...", $nick) }

        $mysql_command    = "UPDATE users SET kizmit=(?) WHERE nick=(?)";

        @mysql_data       = ($kizmit, $subject);

        do_query($mysql_command, @mysql_data);

      } else {

        send_msg("Altering the kizmit of non-existent nicks may cause irrevocable damage to the universe! In other words, I don't know $subject", $nick);

      }

    },

    visitors   => sub {

      my ($subject, $text, $nick) = @_;

      my $msg = `/web/fnrt/bin/lineup.pl`;

      print LOG "$nick runs lineup\n";

      send_msg( $msg, $nick );

    },

    fortytwo   => sub {

      my ($subject, $text, $nick) = @_;

      send_msg("the answer to life, the universe and everything", $nick);

    },

    seen       => sub {

      my ($subject, $text, $nick) = @_;

      if (defined $subject) {

        print LOG "$nick is looking for $subject\n";

        if ($subject eq "") { send_msg("You looking for no one, or everyone?", $nick); return }

        if ($subject eq "*") { send_msg("You're looking for everyone??", $nick); return }

        if ($subject eq "?") { send_msg("? was here a couple days ago, anonymously... :)", $nick); return }

        if ($subject eq "42") { send_msg("the answer to life, the universe and everything", $nick); return }

        if ("$subject $text" eq "the answer to life, the universe and everything") { send_msg("42", $nick); return }

        if (lc($subject) eq "hambot")   { send_msg("I'm right here! Right now!", $nick); return }

        if (lc($subject) eq lc($nick))  { send_msg("Look in the mirror! You are here right now!", $nick); return }

        if (user_exists($subject) == 0) { send_msg("I've never seen $subject.", $nick); return }

        my $last_time = get_item( "SELECT last_seen FROM users WHERE nick=(?)", $subject );

        if (defined $last_time) {

          my $ts = scalar localtime($last_time);

          $ts = substr($ts, 0, 11) . substr($ts, 20, 4) . " at " . substr($ts, 11, 8);

          send_msg("$subject was last seen on $ts", $nick);

        } else {

          send_msg("I haven't seen $subject", $nick);

        }

      } else {

        send_msg('Who or what is it you are looking for?', $nick);

      }

    },

    brb        => sub {

      my ($subject, $text, $nick) = @_;

      send_msg("Hurry back now!", $nick);

    },

    afkb       => sub {

      my ($subject, $text, $nick) = @_;

      send_msg("Don't be away too long $nick.", $nick);

    },

    help       => sub {

      my (@subject, $text, $nick) = @_;

      send_msg("Hello, I am an IRC Bot. I can report various information to you. I can play games with you. I can do many different things.", $nick);

      send_msg("To see the entire list of commands that I know, visit http://www.fridaynightroundtable.net/hambot.html    Have fun!", $nick);

    },

    up         => sub {

      my ($subject, $text, $nick) = @_;

      print LOG "$nick runs server_up\n";

      $text = `uptime`;

      send_msg("Server up: $text" , $nick );

      send_msg("hamBot up: " . calc_diff($start_time) . " . . . man am I tired . . . ", $nick);

    },

    weather    => sub {

      my ($subject, $text, $nick) = @_;

      if (! defined $subject) { $subject = "KMIC" }

      if ($subject eq "") { $subject = "KMIC" }

      if (length($subject) != 4) { send_msg("Weather option can ONLY be an ICAO identifier."); return }

      my $weather = get("http://www.mindformation.com/cgi-bin/net_weather.pl?$subject");

      print LOG "$nick asks for weather report from $subject and gets $weather\n";

      send_msg( $weather, $nick );

    },

    norris     => sub {

      my ($subject, $text, $nick) = @_;

      my $msg = get('http://www.mindformation.com/cgi-bin/norris_server.pl');

      print LOG "$nick asks for norris factoid\n";

      send_msg($msg, $nick);

    },

    secret     => sub {

      my ($subject, $text, $nick) = @_;

      if ($subject eq $secret_word) {

        send_msg("DING DING DING (duck drops down) You said the secret word - '$secret_word' Your Kizmit goes up 2 points!", $nick);

        if (user_exists($nick)) {

          my $kizmit = get_item("SELECT kizmit FROM users WHERE nick=(?)", ($nick));

          $kizmit = $kizmit + 2;

          do_query("UPDATE users SET kizmit=(?) WHERE nick=(?)", ($kizmit, $nick));

          &pick_secret;

        }

      } else {

        my $word_time = get_item("SELECT time FROM secret WHERE id=(?)", '1');

        send_msg("The current secret word is " . calc_diff($word_time) . " old.", $nick);


      }


    },

    name       => sub {

      my ($subject, $text, $nick) = @_;

      my $result = get("http://www.mindformation.com/cgi-bin/name_server.pl");

      print LOG "$nick asks for a name and gets $result\n";

      send_msg($result, $nick);

    },

    fortune    => sub {

      my ($subject, $text, $nick) = @_;

      my $result = get("http://www.mindformation.com/cgi-bin/net_fortune.pl");

      print LOG "$nick asks for a fortune and gets $result\n";

      send_msg($result, $nick);

    },

    quote      => sub {

      my ($subject, $text, $nick) = @_;

      my $msg = get('http://www.mindformation.com/cgi-bin/net_quoter.pl');

      print LOG "$nick asks for quote and gets $msg\n";

      send_msg($msg, $nick);

    },

    wright     => sub {

      my ($subject, $text, $nick) = @_;

      my $msg = get('http://www.mindformation.com/cgi-bin/wright_server.pl');

      print LOG "$nick asks for Steven Wright quote and gets $msg\n";

      send_msg($msg, $nick);

    },

    tvland     => sub {

      my ($subject, $text, $nick) = @_;

      my $msg = get('http://www.mindformation.com/cgi-bin/net_tvland.pl');

      print LOG "$nick asks for tvland show and gets $msg\n";

      send_msg($msg, $nick);

    },

    limerick   => sub {

      my ($subject, $text, $nick) = @_;

      my $limerick = get("http://www.mindformation.com/cgi-bin/limerick_server.pl");

      my @limerick_lines = split /~/, $limerick;

      print LOG "$nick asks for a limerick\n";

      foreach $limerick (@limerick_lines) { send_msg($limerick, $nick) }

    },

    byeham     => sub {

      my ($subject, $text, $nick) = @_;

      if ($nick eq "W1SDM") { send_msg("hamBot will be back shortly...", $nick); exit } else { send_msg("Uh, I don't think so...", $nick) }

    },

    jpole      => sub {

      my ($subject, $text, $nick) = @_;

      print LOG "$nick asks for a J-Pole for $subject\n";

      if ( $subject > 14.230 and $subject < 1230) {

        my $measurement = get("http://www.mindformation.com/cgi-bin/jpole_server.pl?f=$subject");

        my @measurements = split /~/, $measurement;

        foreach $measurement (@measurements) { send_msg($measurement, $nick) }

      } else {

        send_msg("Please try a more reasonable frequency, say from 50 - 800 MHz\n", $nick);

      }

    },

    film       => sub {

      my ($subject, $text, $nick) = @_;

      $subject .= " " . $text;

      my $msg = get("http://www.mindformation.com/cgi-bin/net_imdb.pl?$subject");

      print LOG "$nick asks for information on the film $subject\n";

      send_msg( $msg, $nick );

    },

    nslookup   => sub {

      my ($subject, $text, $nick) = @_;

      my $result = get("http://www.mindformation.com/cgi-bin/net_nslookup.pl?$subject");

      print LOG "$nick asks for nslookup for $subject and gets $result\n";

      send_msg($result, $nick);

    },

    read_notes => sub {

      my ($subject, $text, $nick) = @_;

      my ($ts);

      if (get_item("SELECT COUNT(*) FROM user_notes WHERE sent_to=(?)", $nick)) {

        send_msg("Notes will be erased after being displayed.", $nick);

        my @notes = get_records("SELECT sent_by, send_time, text FROM user_notes WHERE sent_to=(?)", ($nick));

        foreach my $x (0..$#notes) {

          $ts = scalar localtime($notes[$x][1]);

          $ts = substr($ts, 0, 11) . substr($ts, 20, 4) . " at " . substr($ts, 11, 8);

          send_msg("From $notes[$x][0] on $ts - $notes[$x][2]", $nick);

          if ($notes[$x][0] ne "hamBot") {

            do_query("INSERT INTO user_notes (sent_by, sent_to, send_time, text) VALUES (?, ?, ?, ?)", ('hamBot', $notes[$x][0], time, "$nick read the note that you sent on $ts") );

          }

        }

        do_query( "DELETE FROM user_notes WHERE sent_to=(?)", ($nick) );

      } else {

        send_msg("Sorry, I have no notes for you.", $nick);

      }

    },

    send_note  => sub {

      my ($subject, $text, $nick) = @_;

      if (user_exists($subject) != 1) { send_msg("I don't know $subject. Are you sure you spelled that correctly?", $nick); return }

      $text =~ s/\'/\\\'/g;

      if ($text =~ m/^([A-Za-z0-9., \'\"\?\\]+)$/) {

        do_query("INSERT INTO user_notes (sent_by, sent_to, send_time, text) VALUES (?, ?, ?, ?)", ($nick, $subject, time, $text));

        send_msg("Your note to $subject has been saved!", $nick);

      } else {

        send_msg("hamBot is VERY picky. The RegEx Filter is : m/^([A-Za-z0-9., \'\"\?\\]+)$/ So please confine yourself to it's truth.", $nick);

      }

    },

    forecast   => sub {

      my ($subject, $text, $nick) = @_;

      if (! defined $subject) { $subject = "55430" }

      if ($subject eq "") { $subject = "55430" }

      if (length($subject) != 5) { send_msg("Weather option can ONLY be a valid Zip Code."); return }

      my $weather = get("http://www.mindformation.com/cgi-bin/net_forecast.pl?$subject");

      print LOG "$nick asks for forecast from $subject and gets $weather\n";

      send_msg( $weather, $nick );

    },

    flux       => sub {

      my ($subject, $text, $nick) = @_;

      my $msg = get('http://www.mindformation.com/cgi-bin/flux_server.pl');

      print LOG "$nick asks for flux information\n";

      send_msg($msg, $nick);

    },

    lookup     => sub {

      my ($subject, $text, $nick) = @_;

      print LOG "$nick looks up $subject ";

      my $luc = valid_callsign($subject);

      if ($luc == 1) {

        my $result = get("http://www.w1sdm.com/cgi-bin/callsign.pl?$subject");

        $result =~ s/\n/  /g;

        print LOG "and gets $result\n";

        send_msg( $result, $nick );

      } else {

        print LOG "and RegEx doesn't like it\n";

        send_msg( "According to my regex, $subject isn't a valid U.S. callsign\n", $nick );

      }

    },

    time       => sub {

      my ($subject, $text, $nick) = @_;

      my $time_now = time;

      my @days   = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');

      my @months = ('January','February','March','April','May','June','July','August','September','October','November','December');

      my ($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime($time_now))[0,1,2,3,4,5,6];

      my $time = sprintf("%02d:%02d:%02d",$hour,$min,$sec);

      $year += 1900;

      my $cst_date = "$days[$wday], $months[$mon] " . ordinalize($mday) . ", $year - $time";

      ($sec,$min,$hour,$mday,$mon,$year,$wday) = (gmtime($time_now))[0,1,2,3,4,5,6];

      $time = sprintf("%02d:%02d:%02d",$hour,$min,$sec);

      $year += 1900;

      my $gmt_date = "$days[$wday], $months[$mon] " . ordinalize($mday) . ", $year - $time";

      send_msg("It is $cst_date Central Time", $nick);

      send_msg("It is $gmt_date Greenwich Mean Time", $nick);

    },

    metar      => sub {

      my ($subject, $text, $nick) = @_;

      my $metar;

      if (length($subject) != 4) { send_msg("Bad or no ICAO identifier. Using KMIC...", $nick); $subject = 'KMIC' }

      if ( $subject =~ m/^[a-zA-Z0-9]{4}/ ) {

        $metar = get("http://www.w1sdm.com/cgi-bin/metar.pl?$subject");

      } else {

        $metar = 'Aaaack. No such ICAO identifier!';

      }

      print LOG "$nick asks for metar for $subject and gets $metar\n";

      send_msg($metar, $nick);

    },

    onthisday  => sub {

      $commands{'otd'}->(@_);

    },

    otd        => sub {

      my ($subject, $text, $nick) = @_;

      my ($result, $year);

      if ($subject eq "") {

        my ($mday,$mon) = (localtime(time))[3,4];

        $subject = $mon + 1 . "/$mday";

      }

      $subject =~ s/\s+//g;

      if (length($subject) > 4 or length($subject) < 3 ) { send_msg("That doesn't appear to be a valid date, use the format mon/day Thanks.", $nick); return }

      $result = get("http://www.w1sdm.com/cgi-bin/history.cgi?command=Date&request=$subject");

      if ($result =~ /Bad Day/ or $result =~ /Bad Month/) { send_msg("Bad date format...", $nick); return }

      ($result, $year) = split /~~/, $result;

      print LOG "$nick asks for History Fact for $subject and gets $result\n";

      if ($year and $result) {

        send_msg("On $subject in $year : $result", $nick);

      } else {

        send_msg("The server didn't answer properly...", $nick);

      }

    },

    tftd       => sub {

      my ($subject, $text, $nick) = @_;

      my ($result, $year);

      if ($subject eq "") {

        my ($mday,$mon) = (localtime(time))[3,4];

        $subject = $mon + 1 . "/$mday";

      }

      $subject =~ s/\s+//g;

      if (length($subject) > 4 or length($subject) < 3 ) { send_msg("That doesn't appear to be a valid date, use the format mon/day Thanks.", $nick); return }

      $result = get("http://www.w1sdm.com/cgi-bin/history.cgi?command=Thought&request=$subject");

      if ($result =~ /Bad Day/ or $result =~ /Bad Month/) { send_msg("Bad date format...", $nick); return }

      print LOG "$nick asks for TFTD for $subject and gets $result\n";

      send_msg("Thought for the day ($subject): $result", $nick);

    },

    holiday    => sub {

      my ($subject, $text, $nick) = @_;

      if ($text) { $subject .= $text }

      my ($result, $year);

      if ($subject eq "") {

        my ($mday,$mon) = (localtime(time))[3,4];

        $subject = $mon + 1 . "/$mday";

      }

      $subject =~ s/\s+//g;

      if (length($subject) > 4 or length($subject) < 3 ) { send_msg("That doesn't appear to be a valid date, use the format mon/day Thanks.", $nick); return }

      $result = get("http://www.w1sdm.com/cgi-bin/history.cgi?command=Holiday&request=$subject");

      if ($result =~ /Bad Day/ or $result =~ /Bad Month/) { send_msg("Bad date format...", $nick); return }

      print LOG "$nick asks for History Fact for $subject and gets $result\n";

      send_msg("$subject : $result", $nick);

    },

    whatabout  => sub {

      my ($subject, $text, $nick) = @_;

      if ($text) { $subject .= " $text" }

      my ($result, $year);

      if ($subject eq "") { send_msg("What about who? What?", $nick) }

      $subject =~ s/\s/%20/g;

      $result = get("http://www.w1sdm.com/cgi-bin/history.cgi?command=What&request=$subject");

      $subject =~ s/\%20+/ /g;

      if ($result) {

        print LOG "$nick asks for 'What about' for $subject and gets $result\n";

        my @items = split / :: /, $result;

        foreach my $item (@items) { send_msg("$subject: $item", $nick) }

      } else {

        send_msg("$subject: No data", $nick);

        print LOG "$nick asks for 'What about' for $subject and gets nothing\n";

      }

    },

    game       => sub {

      my ($subject, $text, $nick) = @_;

      send_msg("To start a game, enter the name of the game followed by the word 'start'", $nick);

      send_msg("To pass a response to a game precede all responses with the first letter of the name of the game,", $nick);

      send_msg("followed by the letter 'r'. So if you were playing trivia, you would precede your answer with 'tr',", $nick);

    },

    play       => sub {

      my ($subject, $text, $nick) = @_;

      if (lc($subject) eq "trivia") {

        $commands{'trivia'}->("start", "", $nick);

        return;

      }

      if (lc($subject) eq "mastermind") {

        $commands{'mastermind'}->("start", "", $nick);

        return;

      }

      if (lc($subject) eq "bamboozled") {

        $commands{'bamboozled'}->("start", "", $nick);

        return;

      }

      if (lc($subject) eq "wumpus") {

        $commands{'wumpus'}->("start", "", $nick);

        return;

      }

      send_msg("Play what? I can play Trivia, MasterMind, Bamboozled and Wumpus.", $nick);

    },

    spawn      => sub {

      my ($subject, $text, $nick) = @_;

      if ($nick eq "W1SDM" and $subject eq "NoW") { send_msg("reloading...", $nick); exec '/home/tomg/perlfiles/perlbot_v9.pl' }

    },

    motd       => sub {

      my ($subject, $text, $nick) = @_;

      send_msg("Current motd is $motd", $nick);

      if ($nick eq "W1SDM" and $subject and $text)  { $motd = "$subject $text"; send_msg("motd changed to $motd", $nick); }

      do_query("UPDATE motd SET message=(?) WHERE id=(?)", ($motd, '1'));

    },

    nickometer => sub {

      my ($subject, $text, $nick) = @_;

      if (! defined $subject) { $subject = $nick }

      if ($subject eq "") { $subject = $nick }

      print LOG "$nick gets the nickometer for $subject\n";

      if (lc($subject) eq "hambot") { send_msg("hambot reads infinite COOLAGE on the nickometer, if I do say so myself!", $nick); return }

      my $nickometer = get("http://www.w1sdm.com/cgi-bin/nickometer_frontend.pl?$subject");

      send_msg($nickometer, $nick);

    },

    rot13      => sub {

      my ($subject, $text, $nick) = @_;

      print LOG "$nick asks to rot13 $subject\n";

      if (lc($subject) eq "help") {

        send_msg("rot13 is a method of \"hiding\" spoilers, punchlines, puzzle solutions, and offensive materials from the casual glance. rot13 simply changes each character to the 13th character down the list of letters in the English alphabet. An A becomes N, B becomes O, and so on up to M, which becomes Z.", $nick);

      }

      $subject =~ tr/[a-zA-Z]/[n-za-mN-ZA-M]/;

      send_msg( $subject, $nick );

    },

  );

}