NAME

OurNet::BBSAgent - Scriptable telnet-based virtual users

SYNOPSIS

    # To run it, make sure you have a 'elixus.bbs' file in the same
    # directory. The actual content is listed just below this section.

    use OurNet::BBSAgent;

    my $remote  = 'elixus.bbs';
    my $timeout = 10;
    my $logfile = 'elixus.org';

    my $bbs = OurNet::BBSAgent->new($remote, $timeout, $logfile);

    $bbs->{debug} = 0; # set to 1 if you want debugging
    $bbs->login($ARGV[0] || 'guest', $ARGV[1]);

    callback($bbs->message) while 1; # procedural interface

    $bbs->Hook('message', \&callback); # callback-based interface
    $bbs->Loop;

    sub callback {
        ($caller, $message) = @_;
        print "Received: $message\n";
        if ($message eq '!quit') {
	    $bbs->logoff;
	    exit;
	}
        $bbs->message_reply("$caller, I've got your message!");
    }

DESCRIPTION

OurNet::BBSAgent provides an object-oriented interface to TCP/IP based interactive services (e.g. BBS, IRC, ICQ and Telnet), by simulating as a "virtual user" with action defined by a script language.

The developer could then use the same methods to access different services, to easily implement interactive robots, spiders, or other cross-service agents.

Site Description File

This module has its own scripting language, which looks like this in a site description file:

    ELIXUS BBS
    elixus.org:23

    =login
    wait ¥N¸¹¡G
    send $[username]\n
    doif $[password]
	wait ±K½X¡G
	send $[password]\nn\n
    endo
    send \n\n\n\n

    =main
    send qqqqqqee
    wait ¥D¥\¯àªí
    till ©I¥s¾¹

    =logoff
    call main
    send \nn\ny\ny\n\n\n

    =message
    wait \e[1;33;46m¡¹
    till \x20\e[37;45m\x20
    till \x20\e[m
    exit

    =message_reply
    send \x12
    wait ¦^À³
    send $[message]\n
    wait [Y]
    send \n
    wait \e[37;45m
    wait \e[m
    exit

The first two lines describes the service's title, its IP address and port number. Any number of 'procedures' then begins with =procname, which could be called like $object->procname([arguments]) in the program.

All procedures are consisted of following directives:

load FILENAME

This directive must be used before any procedures. It loads another BBS definition file under the same directory (or current directory). If the FILENAME contains extentions other than .bbs (e.g. .board, .session), BBSAgent will try to locate additional modules by expanding . into /, and look for the required module with an .inc extention. For example, load maple3.board will look for <maple3/board.inc> in the same directory.

wait STRING
till STRING
or STRING

Tells the agent to wait until STRING is sent by remote host. Might time out after $self->{timeout} seconds. Any trailing or directives specifies an alternative string to match.

If STRING is of format m/.*/[imsx]*, it will be treated as a regular expression. Capturing parentheses are silently ignored.

The till directive is functionally equivalent to wait, except that it will puts anything between the last wait or till and STRING into the return list.

send STRING

Sends STRING to remote host.

doif CONDITION
elif CONDITION
else
endo

The usual flow control directives. Nested doif...endos are supported.

goto PROCEDURE
call PROCEDURE

Executes another procedure in the site description file. A goto never returns, while a call always will. Also, a call will not occur if the destination was the last executed procedure that does not end with exit.

exit

Marks the termination of a procedure; also means this procedure is not a 'state' - that is, multiple calls to it will all be executed.

setv VAR STRING

Sets a global, non-overridable variable (see below).

idle NUMBER

Sleep that much seconds.

Variable Handling

Whenever a variable in the form of $[name] is encountered as part of a directive, it will be looked up in the global 'setv' hash $self->{var} first, then at the procedure-scoped variable hash, then finally shift()ed from the argument list if none are found.

For example:

setv foo World!

=login
send $[bar]      # sends the first argument
send $[foo]      # sends 'World!'
send $[password] # sends the second argument
send $[username] # sends the first argument again

A notable exception are digits-only subscripts (e.g. $[1]), which contains the matched string in the previous 'wait' or 'till' directive. If there are multiple strings via 'or' directives, the subscript correspond to the matched alternative. For example:

=match
wait foo
  or m/baz+/
doif $[1] # 'foo' matched
    send $[1] # sends 'foo'
else
    send $[2] # sends 'bazzzzz...'
endo

Event Hooks

In addition to call the procedures one-by-one, you can 'hook' those that begins with 'wait' (or 'call' and 'wait') so whenever the strings they expected are received, the responsible procedure is immediately called. You can also supply a call-back function to handle its results.

For example, the code in SYNOPSIS above 'hooks' a callback function to procedure 'message', then enters a event loop by calling Loop.

A loop never terminates except when the agent receives '!quit' via the message procedure.

The internal hook table could be accessed by $obj->{hook}.

AUTHORS

Autrijus Tang <autrijus@autrijus.org>

COPYRIGHT

Copyright 2001 by Autrijus Tang <autrijus@autrijus.org>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html

1 POD Error

The following errors were encountered while parsing the POD:

Around line 68:

Non-ASCII character seen before =encoding in '¥N¸¹¡G'. Assuming CP1252