|
1 | | -# ZenithProxy Example Plugin |
| 1 | +# ZenithProxy Example Plugin - GraalVM Native Image |
2 | 2 |
|
3 | | -[ZenithProxy](https://github.com/rfresh2/ZenithProxy) is a Minecraft proxy and bot. |
| 3 | +This branch contains an example of how to build a native image of ZenithProxy with your plugin included |
4 | 4 |
|
5 | | -This repository is an example core plugin for ZenithProxy, allowing you to add custom modules and commands. |
| 5 | +See GraalVM documentation for more information: https://www.graalvm.org/latest/reference-manual/native-image/basics/ |
6 | 6 |
|
7 | | -## Installing Plugins |
| 7 | +This is _not_ compiling a GraalVM native image of your plugin alone - it is the full ZenithProxy application with your plugin included. |
8 | 8 |
|
9 | | -Plugins are only supported on the `java` ZenithProxy release channel (i.e. not `linux`). |
| 9 | +GraalVM native image is not able to dynamically load more plugins at runtime. |
10 | 10 |
|
11 | | -Place plugin jars in the `plugins` folder inside the same folder as the ZenithProxy launcher. |
| 11 | +# Usage |
12 | 12 |
|
13 | | -Restart ZenithProxy to load plugins. Loading plugins after launch or hot reloading is not supported. |
| 13 | +`./gradlew nativeCompile` |
14 | 14 |
|
15 | | -## Creating Plugins |
| 15 | +The executable will be at: `build/native/nativeCompile/` |
16 | 16 |
|
17 | | -Use this repository as a template to create your own plugin repository. |
| 17 | +# Licensing Implications |
18 | 18 |
|
19 | | -### Plugin Structure |
| 19 | +ZenithProxy is licensed under the [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html) |
20 | 20 |
|
21 | | -Each plugin needs a main class that implements `ZenithProxyPlugin` and is annotated with `@Plugin`. |
| 21 | +If you distribute a native image of ZenithProxy with your plugin, this - including your plugin - must also be licensed under the AGPL |
22 | 22 |
|
23 | | -Plugin metadata like its unique id, version, and supported MC versions is defined in the `@Plugin` annotation. |
| 23 | +This is different than if you were to only distribute your plugin jar, as it now is a full ZenithProxy application. |
24 | 24 |
|
25 | | -[See example](https://github.com/rfresh2/ZenithProxyExamplePlugin/blob/1.21.4/src/main/java/org/example/ExamplePlugin.java) |
| 25 | +# Limitations |
26 | 26 |
|
27 | | -### Plugin API |
| 27 | +### Reachability Metadata |
28 | 28 |
|
29 | | -The `ZenithProxyPlugin` interface requires you to implement an `onLoad` method. |
| 29 | +A GraalVM `Feature` class is provided to quickly register additional reflection |
30 | 30 |
|
31 | | -This method provides a `PluginAPI` object that you can use to register modules, commands, and config files. |
| 31 | +You may need to register other types of reachability metadata yourself: https://www.graalvm.org/latest/reference-manual/native-image/metadata/ |
32 | 32 |
|
33 | | -`Module` and `Command` classes are implemented the same as in the ZenithProxy source code. |
| 33 | +### Launcher |
34 | 34 |
|
35 | | -I recommend looking at existing modules, commands, and plugins for examples. |
| 35 | +The compiled build output is a full ZenithProxy application with the plugin included. |
36 | 36 |
|
37 | | -* [Module](https://github.com/rfresh2/ZenithProxy/tree/1.21.4/src/main/java/com/zenith/module) |
38 | | -* [Command](https://github.com/rfresh2/ZenithProxy/tree/1.21.4/src/main/java/com/zenith/command) |
39 | | -* Plugins |
40 | | - * [ZenithProxyVillagerTrader](https://github.com/rfresh2/ZenithProxyVillagerTrader) |
41 | | - * [ZenithProxyWebAPI](https://github.com/rfresh2/ZenithProxyWebAPI) |
42 | | - * [ZenithProxyChatControl](https://github.com/rfresh2/ZenithProxyChatControl) |
43 | | - * More in [my discord server](https://discord.com/channels/1127460556710883391/1369081651564515358) |
| 37 | +So the launcher will not be downloading and running this application during normal operation. |
44 | 38 |
|
45 | | -### JavaDocs |
| 39 | +You can execute the application directly from the command line |
46 | 40 |
|
47 | | -https://maven.2b2t.vc/javadoc/releases/com/zenith/ZenithProxy/1.21.4-SNAPSHOT |
| 41 | +or the launcher will execute the application if you replace the normal `linux` release channel exe at: `launcher/ZenithProxy` but this is not officially supported. |
48 | 42 |
|
49 | | -### Building Plugins |
| 43 | +### Multiple Plugins |
50 | 44 |
|
51 | | -Execute the Gradle `build` task: `./gradlew build` - or double-click the task in Intellij |
| 45 | +This example only builds ZenithProxy with this single plugin |
52 | 46 |
|
53 | | -The built plugin jar will be in the `build/libs` directory. |
| 47 | +Any plugin included on the compile classpath will be included in the native image, so in theory it may be possible |
54 | 48 |
|
55 | | -### Testing Plugins |
| 49 | +but no example or additional documentation is provided here |
56 | 50 |
|
57 | | -Execute the `run` task: `./gradlew run` - or double-click the task in Intellij |
| 51 | +# New GraalVM Plugin Checklist |
58 | 52 |
|
59 | | -This will run ZenithProxy with your plugin loaded in the `run` directory. |
60 | | - |
61 | | -### New Plugin Checklist |
62 | | - |
63 | | -1. Edit `gradle.properties`: |
64 | | - - `plugin_name` - Name of your plugin, shown to users and in the plugin jar file name (e.g. `ExamplePlugin`) |
65 | | - - `plugin_id` - Unique identifier for your plugin (e.g. `example-plugin`) |
66 | | - - Must start with a lowercase letter and contain only lowercase letters, numbers, or dashes (`-`) |
67 | | - - `mc` - MC version of ZenithProxy your plugin is compiled for (e.g. `1.21.4`) |
68 | | - - `maven_group` - Java package for your project (e.g. `com.github.rfresh2`) |
69 | | -1. Move files to your new corresponding package / maven group: |
70 | | - - Example: `src/main/java/org/example` -> `src/main/java/com/github/rfresh2` |
71 | | - - First create the new package in `src/main/java`. Then click and drag original subpackages/classes to your new one |
72 | | - - Do this with Intellij to avoid manually editing all the source files |
73 | | - - You must also create and move package folders for the `src/main/templates` folder |
74 | | -1. Edit `ExamplePlugin.java`, or remove it and create a new main class |
75 | | - - Make sure to update the `@Plugin` annotation |
| 53 | +1. Edit `ExamplePluginReflectionFeature.java`: |
| 54 | + - Move the feature class to your new corresponding package / maven group |
| 55 | + - Enter any additional packages to register reflection for (if needed) |
| 56 | +2. Edit `src/resources/META-INF/native-image/org.example/exampleplugin/native-image.properties` |
| 57 | + - Edit the `Feature` class path to match your new feature class |
| 58 | + - Create directories and move this file to your corresponding package/maven group |
| 59 | +3. Build and verify |
| 60 | + - Any additional build arguments needed should be set in `build.gradle.kts`'s `graalvmNative` section |
| 61 | + - e.g. config for plugin dependencies, different build options, etc. |
0 commit comments