-
Notifications
You must be signed in to change notification settings - Fork 1
Scripting
/scripts run <script name> [<function name>]
-
<script name>- The script's file path within thescriptsdirectory, you can use tab completions to find the one you're lookingfor. -
[function name]- An optional argument for the name of the function within the script to call.
You can also execute raw JavaScript code by using the eval command
like so:
/scripts eval <java script code>
/scripts run path/to/script.js
Simply runs the script file, not calling any methods
/scripts run path/to/script.js methodName
Evaluates the script file like above, and after executes The method
named 'methodName'
/scripts eval let x = 0; let y = 1; print(x + y);
Executes the raw JavaScript code that's passed to it
First, we'll need to create an instance of the Script class, we can do
so using one of the following methods:
Via a file path:
import net.fothecrown.core.script2.*;
Path path = /* Acquire it somehow */
Script script = Script.of(path);
// This string path is relative to the `plugins/ForTheCrown/scripts`
// directory
String stringPath = /* Create a path */
Script anotherScript = Script.of(stringPath);Or via raw JavaScript:
String jsCode = "print('Hello, world!')";
Script script = Script.ofCode(jsCode);Next, we'll need to compile and then evaluate the script
Script script = // ...;
// This will load and compile the script
script.compile();
// After compilation, you can place any optional binding
// values into the script, these will be accesible from
// inside the script
script.put("a_binding_value", "Foor");
// Evaluate the script's main function, aka run it
// Returns a result detailing how the execution went.
ScriptResult result = script.eval();
// Test if the execution failed due to an error
// Note: If any error was thrown, it will be logged automatically
if (result.error().isPresent()) {
return;
}
// result() returns an Optional<Object>, empty if there was an
// error, or if the function returned nothing
Object resultingObject = result.result().orElse(null);
// This will return the resultingObject, shown above, as an
// Optional<Boolean>. If the resultingObject doesn't exist, or
// can't be converted to a boolean, this method returns empty
result.asBoolean();scripts/loader.toml is used by FTC's script loader to
load scripts on plugin startup. See the file itself for it's format.
The JavaScript engine used by FTC (Nashorn) is completely compatible with Java.
To this end, you can import java classes like almost just like you would in regular Java, for example, to import the Time utility class, you can use the following:
import "@ftc.utils.Time";The @ftc is an 'import placeholder', basically used to make import
statements shorter and less of a hassel to write. All import
placeholders are defined in import_placeholders.toml
If you're encountering issues with the above shown method, you can fallback to Nashorn's actual method of importing classes:
const Time = Java.type("net.forthecrown.utils.Time");FYI, the method of using the 'import' keyword, is just remapped to the second method by a preprocessor, thus, in effect, the 2 above methods are essentially the same
Please also be aware that the Nashorn engine, is not 100% up to ECMAscript 6 standards, there are many missing features. Be careful when using newer JavaScript features such as classes, as they do not exist within the engine.
The script engine comes with several custom built in parts, the
first of these are the classes that are automatically imported in to every script.
Be aware, this list may not be complete, see the BuiltIn class for the definitive list of all imported classes.
org.bukkit.Bukkitorg.bukkit.Locationorg.bukkit.enity.EntityTypeorg.bukkit.Materialnet.kyori.adventure.text.Componentnet.kyori.adventure.text.format.NamedTextColornet.kyori.adventure.text.event.ClickEventnet.kyori.adventure.text.event.HoverEventnet.kyori.adventure.text.format.Stylenet.kyori.adventure.text.format.TextDecorationnet.forthecrown.utils.text.Textnet.forthecrown.utils.Utilnet.forthecrown.utils.Cooldownsnet.forthecrown.utils.inventory.ItemStacksnet.forthecrown.utils.math.Bounds3inet.forthecrown.utils.math.WorldVec3inet.forthecrown.utils.math.WorldBounds3inet.forthecrown.utils.math.Vectorsnet.forthecrown.user.Users
Ontop of these imports, you are given a Log4J logger to use for
logging, accessible like so:
logger.info("I am logged message! :)");Note: Any logger calls on level ERROR will be automatically forwarded to the error-log channel in Discord.
And a function to compile other scripts:
// This will only perform the Script#compile() call
// Note: the path given to this function is relative to
// file of the current script
const otherScript = compile("path/to/script.js");
// Here, just like above, you can place objects into the script's
// bindings, but in a simpler way, like so:
otherScript.foo = "bar";
// calls Script#eval()
// Will throw an exception if the script's evaluation fails and
// returns the result of the script's evaluation
let result = otherScript();Links for some extra reading: