Skip to content
This repository has been archived by the owner on May 3, 2018. It is now read-only.

The ScriptAPI

Ash edited this page Jun 15, 2015 · 10 revisions

The Dragonet ScriptAPI

What is it?

The ScriptAPI is a JavaScript class (like the ServerAPI or the ConfigAPI) that allows you to send messages and information to other scripts by creating custom functions, methods and commands.

Okay, so how do I use it?

It's easy! First, you have to make your ScriptAPI instance. Simply put the following at the top of your script:

var Scripts = new ScriptAPI();

Of course, you don't have to name it Scripts, but all our examples assume that you have. From here, there are 3 methods of communication - through functions, methods and commands. Here's how they work:

Contacting other scripts (creating functions)

So, you know what a function is, right? One of these:

function Tick() {
    //Do stuff here
}

Using the ScriptAPI, you can actually make your own functions and run them on demand from within your script. No setup is required; simply run the trigger and all other scripts implementing that function will be called. So, say we have a chat filter script and we want other scripts to know that we blocked a message. Here's how we'd do it:

Note: In these examples, we assume your ScriptAPI object is named "Scripts"

Your script (Script A)

//This can be at any point in your script. For our example, it's in the section where the message is blocked.
Scripts.callCustomFunction("myScript_chatBlocked");
//You don't have to put your plugin name in the function, but it's recommended to avoid conflicts.

Other scripts (Script B)

function myScript_chatBlocked() {
    //Do stuff here. How about...
    Server.clientMessage("Chat was blocked!");
}

That's it! Now, whenever script A blocks a piece of chat, it'll run the function "chatBlocked" in all other scripts that implement it.

Allowing other scripts to contact you (creating methods)

That's all good, but what if you want the communication to go the other way? Sure, the other script could just use callCustomFunction, but imagine there was a script C that also implements this function. Such a script would be called as well. While this is perfectly fine in some situations, in others you need a little extra security. This is where custom methods come in.

Back to our hypothetical chat filter, say you want other plugins to be able to temporarily disable the filter. Of course, you don't want other plugins to know when this happens, as they could immediately change it back. So, you need a custom method.

Note: In these examples, we assume your ScriptAPI object is named "Scripts", and your UID variable is called "UID"

Your script (Script A)

//This section must be present in your script, and it must be in the postInit section
function postInit() {
    Scripts.addMethod("myScript_disableFilter", "disableFilter_handle", UID);
    //Syntax: ("method other scripts will call", "method that will be called when this happens", UID)
    //You don't have to put your plugin name in the method, but it's recommended to avoid conflicts.
}
function disableFilter_handle() {
    //Disable the filter here, however your script does that.
    filterEnabled = false;
}

Other scripts (Script B)

//This can be anywhere in the script
Scripts.callCustomMethod("myScript_disableFilter");

And there you have it! Script B can now send a message to script A that only script A will receive. But, what if you want a simple command to tie it all together?

Allowing player contact (creating commands)

Note: I haven't yet been able to personally test this system - I'm just going to infer what I can from DefinitelyEvil's example script and the code itself. I will update this if I find any issues.

Creating a command with the ScriptAPI is pretty simple. Since your script is now treated as a Bukkit plugin, you can use nearly the exact same syntax to get a simple command working. For example, let's say we wanted to have a command that enables and disables our chat filter. Here's how we'd do it:

Your script

var Scripts = new ScriptAPI();
var me;
function onLoad(script){
    me = script;
}
function onEnable(){
    Scripts.registerCommand(me, "filter", "onCommand");
    //Syntax: (me, "command name", "handler");
}
function onCommand(sender, cmd, alias, args){
    if(cmd.equals("filter")){ //cmd is a Java string, so you have to use .equals()
        //Everything from here on out is optional, just showing how to look at command arguments.
        if(args[0].equals("disable")) { //"filter' is our command name and comes int the "cmd" variable, but all arguments come in this array instead
            //Disable our chat filter.
        }
    }
}

Note: As I mentioned above, I'm not personally familiar with this system and therefore I don't know the exact syntax. As such, I can't rule out the alternative syntax also posted by DefinitelyEvil which lists the arguments to onCommand as CommandSender, Command, String, String[]. The only difference to the above code would be the first if statement, requiring cmd.getLabel().equals instead of just cmd.equals. Try it and see what works.

Arguments and Variables

In some cases you'll want to do more than sending signals. Sometimes you'll want to pass a variable along too. Luckily, the ScriptAPI is more than capable of doing something like this. All you have to do is put a variable as your second argument. So, if we decide to update our chat filter to add the blocked message as an argument:

Your script (Script A)

Scripts.callCustomFunction("myScript_chatBlocked", message);
//"message" can be any object, but it's recommended that you stick to java natives (String, int, byte etc)

Other scripts (Script B)

function myScript_chatBlocked(message) {
    //Do stuff here. How about...
    Server.clientMessage("Chat was blocked! Message was: " + message);
}

As you can see, you can now pass arguments! You can do something similar with methods too:

Your script (Script A)

//This section must be present in your script, and it must be in the postInit section
function postInit() {
    Scripts.addMethod("myScript_disableFilter", "disableFilter_handle", UID);
    //This is the same as before
}
function disableFilter_handle(reason) {
    //Disable the filter here, however your script does that.
    if (isValid(reason)) {
        filterEnabled = false;
    }
}

Other scripts (Script B)

Scripts.callCustomMethod("myScript_disableFilter", reason);
//As with before, you can use any object, but I reccomend you stick to standard Java types (String, int, byte etc)

Multiple Arguments

After playing around a bit, you may notice that you can only pass one argument. If you want to pass multiple arguments, you'll need to use an array. Check out the Rhino Documentation on how to create an array, then just pass it as any other object.

Conclusion

The ScriptAPI can really help you to add interactivity and expandability to your script, by allowing other scripts to work with yours.

Other Stuff

Original PR with differently worded explanation

PR for arguments - not much written here ;3

Complete Methods List

  • callCustomFunction(functionName, arguments_array) - Calls a custom function implemented by other scripts. See the tutorial.
  • addMethod(methodName, handlerFunctionName, String ownerUID) - Adds a custom method for other scripts to call. See the tutorial.
  • callCustomMethod(methodName, arguments_array) - Call a custom method registered with addMethod. See the tutorial.
  • registerCommand(script_instance, commandName, handlerFunction) - Register a command to the server. See the tutorial.
  • registerCommandWithPerms(script_instance, commandName, handlerFunction, requiredPermissions) - Register a command to the server with required permissions(split by ,). You're on your own with this one ;3

Coming soon!~

  • Auto-expanding of argument arrays (you pass array[b,c,d] they get b,c,d as separate arguments)

Written by Ash. Damn, this took ages.