A plugin generator and safe abstraction for making Minecraft Bukkit Server Plugins in Rust using JNI.
(early prototype)
- Create a new Cargo library project (
cargo new --lib) - Add waterjet as dependency and build dependency
- Edit the project's Cargo.toml to include to following lines:
[package]
# ...
build = "build.rs"
[lib]
crate_type = ["cdylib"]
[package.metadata.waterjet]
name = "NameOfYourPluginsMainClass"- Create a build script (
build.rsin this example) which includes the following lines:
fn main() {
waterjet::build::build();
}- Add these lines to your
src/lib.rs
use waterjet::{
jni::{objects::GlobalRef, JNIEnv},
McPlugin,
};
waterjet::hook!(NameOfYourPluginsMainClass, Model);
struct Model {}
impl Default for Model {
fn default() -> Self {
Model {}
}
}
impl McPlugin for Model {
fn on_enable(&self, _plugin: &GlobalRef, jni: &JNIEnv) {
println!("Hello, World!");
}
fn on_disable(&self, _plugin: &GlobalRef, _jni: &JNIEnv) {
println!("Bye, World!");
}
}- Build the project using
cargo build - Copy the generated
.jarfile from thetarget/$PROFILEfolder into your server'spluginsdirectory and the.so/.dllfile intoplugins/lib - Start the server and you should see
Hello, World!appear after the message indicating that[NameOfYourPluginsMainClass] version x.y.zwas enabled
-
The function
waterjet::build::buildparses your packages Cargo.toml for values underpackage.metadata.waterjetand converts them to aplugin.ymlwhich is included in the generated JAR file. Supported keys include:Key Default value Hint namecamel-cased CARGO_PKG_NAMEsingle-line string authors( CARGO_PKG_AUTHORS)list or string website( CARGO_PKG_HOMEPAGE)single-line string description( CARGO_PKG_DESCRIPTION)optionally multi-line string version( CARGO_PKG_VERSION)single-line string api-version1.13 single-line string prefixsingle-line string loadbeforelist or string dependlist or string softdependlist or string extramulti-line string containing YAML Note: The
extrakey may be used for anything which should be appended to the generated plugin.yml (eg. permissions, commands)Note: For info on the keys supported by Spigot: https://www.spigotmc.org/wiki/plugin-yml/
-
waterjet automatically generates a
NameOfYourPluginsMainClass.jarfile with all the necessary FFI code (currentlyonEnableandonDisable) which is linked to by the JVM against functions generated in thewaterjet::hookproc-macro -
NameOfYourPluginsMainClassmust be consistent across the Cargo.toml's valuepackage.metadata.waterjet.nameand the first argument supplied to thewaterjet::hookproc-macro
- Generation of JAR containing plugin code which calls Rust code
- Automatic loading of Rust code from the plugin
- Compatibility with
/reloadcommand: Rust code is loaded by a custom classloader which is destructed inonDisable(see todo) - Trait providing basic plugin methods (
onEnable,onDisable) providing a reference to theJavaPlugininstance and to theJNIEnv
- Event handling
- Currently, the API is not on solid ground and must be redesigned for event handling, which would include rethinking the current threaded approach of the onEnable FFI function
onDisableuses aSystem.gc()call to free theClassLoaderwhich loaded the plugin's Rust code, which may cause performance problems (quick and dirty solution to make/reloadwork)