Using other script files as libraries

I have found two ways to include another script's contents in the current script: direct inclusion of other files using the source() method or importing methods and classes from files in some directory using the importCommands() method.

Direct inclusion

The BeanShell builtin method source(String) executes the given file in the current interpreter. Which means any methods or classes defined there end being present in the calling script's namespace. Note that all script-level statements also get executed.

An executable script file, goes under batclient/scripts

SCRIPT_NAME = "example_source";

String s = java.io.File.separator; // Platform independence
source(System.getProperty("user.home")
     + s + "batclient" + s + "scriptlibs"
     + s + "loaded.bsh");

void run() {
    helloWorld();
}

And the library file. The file extension does not matter with the source() approach, but it does with importCommands(). I'm using .bsh for consistency. Place under batclient/scriptlibs.

void helloWorld() {
    clientGUI.printText("general", "Hello World! From example_source_lib!\n");
}

/* This gets executed when you load the sourcing script. The output goes to
 * stdout, which is the Java console most of the time.
 */
print("Example lib file sourced\n");

Files:

Importing commands

The BeanShell builtin method importCommands(String) imports all BeanShell "commands" found at the location given in the argument. The argument is either a Java package name (format foo.bar.baz) or a "resource path" (format /foo/bar/baz). The location is sought for relative to the classpath, which by default does not contain the BatClient directory. Therefore one needs add it to the classpath first before importing using the addClassPath(String) method.

The import behaves in a rather interesting way. First, there are certain limitations:

In order for a file's contents to be imported, the "name method" has to be called. This means that if the file has other things intended to be used besides that method, it has to be called at least once before any of those other things are used. Upon loading, any statements at the top level of the loaded script are executed. Entities in the importing script's namespace override anything imported with the same signature, so unlike with source(), there is no danger of clobbering data in the importing script.

I think a good policy for library files would be to have the "name method" be either empty or do whatever initialisation is necessary. Then a library can be loaded by calling it's "name method".

An executable script file, goes under batclient/scripts

SCRIPT_NAME = "example_import";

addClassPath(System.getProperty("user.home") + java.io.File.separator + "batclient");
importCommands("scriptlibs");
example_import_lib(); // Load the library

void run() {
    helloWorld();
}

The library file:

void example_import_lib() { /* The "name method" */ }

void helloWorld() {
    clientGUI.printText("general", "Hello World! From example_import_lib!\n");
}

/* This gets executed when you load the importing script. The output goes to
 * stdout, which is the Java console most of the time.
 */
print("Example lib file imported");

Files:

Notes

Colour and other codes sent by the server

Being curious about how the server marks what text is to be coloured, I apt-getted myself Wireshark and took a peek at the traffic. It turns out the colour codes are pretty simple and that the client applies them to text printed via clientGUI.printText(). While looking, I also found out about some other codes.

So far, I have seen the server send two kinds of codes to mark up it's output: ANSI and something else (which might be custom). As far as I can tell, these codes can't be sent to the server.

ANSI codes

These are used to do some colourings and probably all the bold/italic text. The format is <ESC>[Nm, where <ESC> is the character 27 and N is one of the control codes, or a list of control codes separated with ; characters. A partial reference

Example:

clientGUI.printText("general", "\033[31mThis is red and \033[1mbold\033[22m.\033[0m\n");

Bat codes

These are of the general format <ESC><NNcode_parameter<ESC>|code_target<ESC>>NN, where NN is a two-digit parameter (base number unknown) that determines what type code is in question.

Codes I've found so far:

Valid XHTML 1.1