|
| 1 | +--- |
| 2 | +title: Your First Plugin |
| 3 | +--- |
| 4 | + |
| 5 | +# Your First Plugin |
| 6 | + |
| 7 | +With the [Maven project set up](./maven-setup), you can now write a real plugin. |
| 8 | +This page builds the smallest plugin that does something, and explains every |
| 9 | +piece so you understand *why* it works. |
| 10 | + |
| 11 | +## The main class |
| 12 | + |
| 13 | +Every plugin has one **main class** that extends |
| 14 | +`dev.waterdog.waterdogpe.plugin.Plugin`. The proxy creates one instance of it |
| 15 | +and calls its lifecycle methods. |
| 16 | + |
| 17 | +Create `src/main/java/com/example/myplugin/MyPlugin.java`: |
| 18 | + |
| 19 | +```java |
| 20 | +package com.example.myplugin; |
| 21 | + |
| 22 | +import dev.waterdog.waterdogpe.plugin.Plugin; |
| 23 | + |
| 24 | +public class MyPlugin extends Plugin { |
| 25 | + |
| 26 | + @Override |
| 27 | + public void onEnable() { |
| 28 | + // Called when the proxy enables your plugin. Put your setup here: |
| 29 | + // register commands, subscribe to events, start tasks, etc. |
| 30 | + this.getLogger().info("MyPlugin has been enabled!"); |
| 31 | + } |
| 32 | + |
| 33 | + @Override |
| 34 | + public void onDisable() { |
| 35 | + // Called on proxy shutdown or when the plugin is disabled. |
| 36 | + // Clean up here: close connections, save data, cancel tasks. |
| 37 | + this.getLogger().info("MyPlugin has been disabled!"); |
| 38 | + } |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +### The plugin lifecycle |
| 43 | + |
| 44 | +The `Plugin` class gives you three methods you can override. Only `onEnable()` |
| 45 | +is required. |
| 46 | + |
| 47 | +| Method | When it runs | Typical use | |
| 48 | +| --- | --- | --- | |
| 49 | +| `onStartup()` | After the plugin is loaded, **before** it is enabled (and before the proxy has finished starting). | Load critical data or open connections that must exist before other plugins enable. Most plugins don't need this. | |
| 50 | +| `onEnable()` *(required)* | Once the proxy startup is complete and plugins are being enabled. | Register commands and events, schedule tasks, read config — your main setup. | |
| 51 | +| `onDisable()` | On proxy shutdown, or when the plugin is disabled. | Clean up: save data, close connections, cancel tasks. | |
| 52 | + |
| 53 | +> **Why `onEnable()` and not the constructor?** When your constructor runs, the |
| 54 | +> plugin is not fully initialised yet — helpers like `getProxy()` and |
| 55 | +> `getLogger()` are not available. Always do your setup in `onEnable()`. |
| 56 | +
|
| 57 | +### Useful methods you inherit |
| 58 | + |
| 59 | +Because you extend `Plugin`, these are available via `this.`: |
| 60 | + |
| 61 | +| Method | Returns | Description | |
| 62 | +| --- | --- | --- | |
| 63 | +| `getProxy()` | `ProxyServer` | The proxy instance — your gateway to almost everything (players, servers, scheduler, events, commands). See the [Plugin API introduction](/plugins/introduction). | |
| 64 | +| `getLogger()` | `Logger` | A logger that prefixes messages with your plugin name. Use `info()`, `warn()`, `error()`. | |
| 65 | +| `getDataFolder()` | `File` | Your plugin's own folder (`plugins/<name>/`), created automatically. Store your files here. | |
| 66 | +| `getConfig()` | `Configuration` | Loads `config.yml` from your data folder (copying it from your jar on first run). | |
| 67 | +| `saveResource(String)` | `boolean` | Copies a file bundled in your jar into the data folder. | |
| 68 | +| `getResourceFile(String)` | `InputStream` | Reads a file bundled inside your jar. | |
| 69 | +| `getName()` | `String` | Your plugin's name from `plugin.yml`. | |
| 70 | + |
| 71 | +## The `plugin.yml` |
| 72 | + |
| 73 | +The proxy needs a descriptor to know how to load your plugin. Create |
| 74 | +`src/main/resources/plugin.yml`: |
| 75 | + |
| 76 | +```yaml |
| 77 | +name: MyPlugin |
| 78 | +version: 1.0.0 |
| 79 | +author: YourName |
| 80 | +main: com.example.myplugin.MyPlugin |
| 81 | +``` |
| 82 | +
|
| 83 | +The fields are: |
| 84 | +
|
| 85 | +| Field | Required | Description | |
| 86 | +| --- | --- | --- | |
| 87 | +| `name` | **yes** | The plugin's name. Also used for the data folder and logger prefix. | |
| 88 | +| `main` | **yes** | The fully-qualified name of your main class (package + class name). This **must** match your class exactly. | |
| 89 | +| `version` | recommended | Your plugin's version string. | |
| 90 | +| `author` | optional | Your name. | |
| 91 | +| `depends` | optional | A list of other plugin names that must load before yours. See below. | |
| 92 | + |
| 93 | +> WaterdogPE also accepts the file named `waterdog.yml`. `plugin.yml` is the |
| 94 | +> conventional choice and is what most examples use. |
| 95 | + |
| 96 | +### Depending on another plugin |
| 97 | + |
| 98 | +If your plugin needs another plugin to be loaded first, list it under `depends`: |
| 99 | + |
| 100 | +```yaml |
| 101 | +name: MyPlugin |
| 102 | +version: 1.0.0 |
| 103 | +main: com.example.myplugin.MyPlugin |
| 104 | +depends: |
| 105 | + - SomeOtherPlugin |
| 106 | +``` |
| 107 | + |
| 108 | +WaterdogPE loads dependencies before your plugin and detects circular |
| 109 | +dependencies. To grab another loaded plugin instance from code: |
| 110 | + |
| 111 | +```java |
| 112 | +Plugin other = this.getProxy().getPluginManager().getPluginByName("SomeOtherPlugin"); |
| 113 | +if (other != null && other.isEnabled()) { |
| 114 | + // safe to use it |
| 115 | +} |
| 116 | +``` |
| 117 | + |
| 118 | +## Build and run |
| 119 | + |
| 120 | +1. Build the jar: `mvn clean package`. |
| 121 | +2. Copy `target/MyPlugin-1.0.0.jar` into your proxy's `plugins/` folder. |
| 122 | +3. Start the proxy. You should see your `onEnable()` log line: |
| 123 | + `[MyPlugin] MyPlugin has been enabled!` |
| 124 | + |
| 125 | +If the plugin doesn't load, double-check that the `main` field in `plugin.yml` |
| 126 | +exactly matches your class's package and name. |
| 127 | + |
| 128 | +## Where to go next |
| 129 | + |
| 130 | +Your plugin works — now make it *do* something: |
| 131 | + |
| 132 | +- [Plugin API Introduction](/plugins/introduction) — the `ProxyServer` object and |
| 133 | + how the pieces fit together. |
| 134 | +- [Working with Players](/plugins/players-guide) — message, transfer and manage |
| 135 | + players. |
| 136 | +- [Commands Guide](/plugins/commands-guide) — add your own `/commands`. |
| 137 | +- [Events Guide](/plugins/events-guide) — react to joins, chat, transfers and more. |
| 138 | +- [Scheduling Tasks](/plugins/scheduling-task) — run delayed and repeating tasks. |
| 139 | + |
| 140 | +You can also browse complete, working examples in the |
| 141 | +[Example-Plugins repository](https://github.com/WaterdogPE/Example-Plugins). |
0 commit comments