From ee10602000cf35e9d240f04a61f907842e7a8928 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sat, 5 Dec 2020 18:13:06 +0100 Subject: [PATCH 01/14] Start documenting event system --- .../creating-your-first-event-listener.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/development/creating-your-first-event-listener.md diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md new file mode 100644 index 0000000..6cff271 --- /dev/null +++ b/docs/development/creating-your-first-event-listener.md @@ -0,0 +1,49 @@ +--- +id: creating-your-first-event-listener +title: Creating Your First Event Listener +sidebar_label: Creating Your First Event Listener +--- + +## Prerequisites + +This guide assumes that you have a [plugin environment](/docs/development/creating-first-plugin) setup. +If you have not already, follow that guide first. + +## Event Concept + +Many actions done by players, blocks or mobs trigger an event. Technically: a class extending `Event`. Events allow you to know, edit or cancel default behaviour. +For your plugin to get informed when an event happens, you need to create a class implementing `EventListener` (a marker interface): + +```java +public class MyFirstEventHandler implements EventListener {} +``` + +Now we marked the class for us and the api as event listener. Next up we need to define which event(s) we want to listen to in this event listener. +This is done simply by creating a method annotated with @EventHandler inside: + +```java +public class MyFirstEventHandler implements EventListener { + + @EventHandler + public void onExplode(EntityExplodeEvent event) { + // this method gets called every time an entity explodes + } +} +``` + +Now we just need to implement some logic. We can praise explosions for example with a chat message sent to every player: + + +```java +public class MyFirstEventHandler implements EventListener { + + @EventHandler + public void onExplode(EntityExplodeEvent event) { + GoMint.instance().getPlayers().forEach(p -> { + p.sendMessage("Hooray, " + event.getAffectedBlocks().size() + " are gone!"); + }); + } +} +``` + +## Cancellable events From 9ba61a10526576dc9906fb2f3f60ffea95ff5681 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sat, 5 Dec 2020 19:46:54 +0100 Subject: [PATCH 02/14] Small fixes based on omniboy's feedback --- docs/development/creating-your-first-event-listener.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index 6cff271..bf9040a 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -19,11 +19,10 @@ public class MyFirstEventHandler implements EventListener {} ``` Now we marked the class for us and the api as event listener. Next up we need to define which event(s) we want to listen to in this event listener. -This is done simply by creating a method annotated with @EventHandler inside: +This is done simply by creating a method annotated with `@EventHandler` inside: ```java public class MyFirstEventHandler implements EventListener { - @EventHandler public void onExplode(EntityExplodeEvent event) { // this method gets called every time an entity explodes @@ -36,7 +35,6 @@ Now we just need to implement some logic. We can praise explosions for example w ```java public class MyFirstEventHandler implements EventListener { - @EventHandler public void onExplode(EntityExplodeEvent event) { GoMint.instance().getPlayers().forEach(p -> { From 77f6b6c82b0096b7df764bfc088057e2c11c2e83 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sat, 13 Feb 2021 20:14:27 +0100 Subject: [PATCH 03/14] wip --- .../creating-your-first-event-listener.md | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index bf9040a..9902bd5 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -15,11 +15,19 @@ Many actions done by players, blocks or mobs trigger an event. Technically: a cl For your plugin to get informed when an event happens, you need to create a class implementing `EventListener` (a marker interface): ```java -public class MyFirstEventHandler implements EventListener {} +public class MyFirstEventListener implements EventListener {} ``` -Now we marked the class for us and the api as event listener. Next up we need to define which event(s) we want to listen to in this event listener. -This is done simply by creating a method annotated with `@EventHandler` inside: +Now we marked the class for us and the api as event listener. Then we have to register our class to the API. We do that for example in the `onInstall` method in our `TestPlugin` class: + +```java + @Override + public void onInstall() { + registerListener(new MyFirstEventListener()); + } +``` +Next up we need to define which event(s) we want to listen to in this event listener. +This is done simply by creating a method annotated with `@EventHandler` which takes one argument (the event we want to listen to) and returns `void`: ```java public class MyFirstEventHandler implements EventListener { @@ -37,11 +45,11 @@ Now we just need to implement some logic. We can praise explosions for example w public class MyFirstEventHandler implements EventListener { @EventHandler public void onExplode(EntityExplodeEvent event) { - GoMint.instance().getPlayers().forEach(p -> { - p.sendMessage("Hooray, " + event.getAffectedBlocks().size() + " are gone!"); - }); + GoMint.instance().onlinePlayers().forEach(p -> p.sendMessage("Hooray, " + event.getAffectedBlocks().size() + " are gone!")); } } ``` ## Cancellable events + +We changed our minds now and want to prevent explosions from happening. Great that [EntityExplodeEvent](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/entity/EntityExplodeEvent.html) extends [CancellableEvent](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/CancellableEvent.html). From 1b244d67cc23cb8d565e63b609086a5785df35cb Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 01:22:33 +0100 Subject: [PATCH 04/14] Create plugin-world-restriction.md --- docs/get-started/plugin-world-restriction.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/get-started/plugin-world-restriction.md diff --git a/docs/get-started/plugin-world-restriction.md b/docs/get-started/plugin-world-restriction.md new file mode 100644 index 0000000..74d3ac2 --- /dev/null +++ b/docs/get-started/plugin-world-restriction.md @@ -0,0 +1,13 @@ +--- +id: plugin-world-restriction +title: Plugin World Restriction +sidebar_label: Plugin World Restriction +--- + +GoMint worlds are running mostly independent of each other. Every GoMint world has its own thread. +This allows Gomint to scale better than many other minecraft server softwares and you can build a little "server network" just with one GoMint running many worlds. + +To not make plugin development unneccessary complex, we created an API that allows plugins to only run in certain worlds. +You can set up the worlds of a plugin within the `worlds.yml` file you can find in the folder `plugins/ThePluginName`. + +While plugins are not forced by the server to follow this setting, it is strongly adviced that every plugin uses the easy provided API to follow the `worlds.yml` setting. From 5b82c1560aeb864ed41506fc6ccd3f5a49d8ca01 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 01:25:32 +0100 Subject: [PATCH 05/14] Update getting-started.md --- docs/get-started/getting-started.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/get-started/getting-started.md b/docs/get-started/getting-started.md index 2eddd17..7cc3b63 100644 --- a/docs/get-started/getting-started.md +++ b/docs/get-started/getting-started.md @@ -15,5 +15,8 @@ sidebar_label: Getting Started ## Concluding Thoughts -You may want to visit the next tutorial about [configuring](/docs/get-started/general-configuration) your new server. +You may want to visit the next tutorial about [configuring](general-configuration.md) your new server. + +If you want to know more about gomint's unique world system, visit the [Plugin World Restrictions](plugin-world-restriction.md) information page. + Or, if you want to dive into writing custom plugins, visit the [first plugin](/docs/development/creating-first-plugin) tutorial. From 276a7a7d327a8f0465856f58cf8c0d5ba1134fda Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 01:26:04 +0100 Subject: [PATCH 06/14] Update getting-started.md --- docs/development/getting-started.md | 134 +++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 12 deletions(-) diff --git a/docs/development/getting-started.md b/docs/development/getting-started.md index 4a47d3d..7ea11dc 100644 --- a/docs/development/getting-started.md +++ b/docs/development/getting-started.md @@ -1,26 +1,133 @@ --- id: getting-started -title: Introduction to the GoMint API -sidebar_label: Introduction to GoMint API +title: IDE setup for GoMint plugin development +sidebar_label: IDE setup for GoMint plugin development --- -## Downloading the API JARs +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -## Adding JARs to Eclipse +This is a brief explanation to show you how to add gomint-api to your classpath to start writing gomint plugins. -### Mac OS Instructions +There are multiple options available for this: -Before adding the JAR files to your build path in Eclipse, it's best to place them -in the workspace folder that you are working with, in a designated folder for -dependencies, or somewhere it will not be moved or accidentally deleted. +## Using a dependency management system -1. To begin, create a new Java Project in Eclipse, or click the name of the project +### Maven + +This is the recommended way. Maven is not hard to learn and it makes dependency management really easy. + +Before you begin writing a plugin, you will need a ```pom.xml``` for the plugin. It is pertinent that this file be included. + +Example pom.xml file for maven: + +```xml + + + 4.0.0 + + + io.gomint.demo.testplugin + myfirstplugin + 1.0-SNAPSHOT + + + My first Plugin + A demonstration and tutorial plugin for gomint's api + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + + + io.gomint + gomint-api + 1.0.0-SNAPSHOT + provided + + + +``` + +### Gradle + +Here is the repository snippet: + + + + +```groovy + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } +``` + + + + +```kotlin + maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } +``` + + + + +and here is the dependencies snippet: + + + + +```groovy + compile "io.gomint:gomint-api:1.0.0-SNAPSHOT" +``` + + + + +```kotlin + compile("io.gomint:gomint-api:1.0.0-SNAPSHOT") +``` + + + + +## Downloading the API JARs manually + +You can download the latest API jar here: https://ci.janmm14.de/job/public%7Emcbe%7Egomint/lastSuccessfulBuild/artifact/gomint-api/target/ +Place this jar somewhere where you will not accidentally move or delete it, at best create a dedicated java dependencies folder. +You can additionally download sources or javadoc jar IF you are a little more experienced to also add them to to your IDE. + +### Adding JARs to IntelliJ IDEA + +Create a new java project in [IntelliJ IDEA](https://www.jetbrains.com/idea/download/#section=windows). See [here](https://www.jetbrains.com/help/idea/working-with-module-dependencies.html) for how to add a jar dependency to your project. + +### Adding JARs to Eclipse + +1. To begin, create a new Java Project in [Eclipse](https://www.eclipse.org/downloads/packages/), or click the name of the project in the project explorer if you have already created it. 2. Click ```File->Properties``` 3. Select "Java Build Path" from the list on the left. 4. Select "Classpath" from the list in the panel. 5. Select the button titled "Add External Jars" -6. Navigate to the JAR using Finder and select it. +6. Navigate to the JAR and select it. Once you have completed these steps, the API should be installed into your classpath in Eclipse and ready to use for creating plugins. @@ -28,5 +135,8 @@ classpath in Eclipse and ready to use for creating plugins. ## Accessing the Javadoc The GoMint API Javadoc can be found [here](https://s.janmm14.de/gomint-javadoc). -While not every method and class has been documented, the majority have been with -brief explanations as to their functionality. +While not every method and class has been documented, the majority is. + +## Next up + +[Create your first plugin](creating-a-first-plugin.md) From 6a3b164a03e2c8def2610f871e57de3ec3c7bd24 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 01:39:41 +0100 Subject: [PATCH 07/14] Update creating-a-first-plugin.md --- docs/development/creating-a-first-plugin.md | 80 ++++++--------------- 1 file changed, 23 insertions(+), 57 deletions(-) diff --git a/docs/development/creating-a-first-plugin.md b/docs/development/creating-a-first-plugin.md index 51cfa34..78ac606 100644 --- a/docs/development/creating-a-first-plugin.md +++ b/docs/development/creating-a-first-plugin.md @@ -6,59 +6,13 @@ sidebar_label: Creating Your First Plugin ## Prerequisites -1. Follow the ["API Getting Started" guide](/docs/api/api-getting-started) and -install the API into your classpath. -2. An understanding of the Java programming language is necessary. +1. An understanding of the Java programming language is necessary. +2. Follow the [Getting Started guide](getting-started.md) to set up the project in your Java IDE (like IntelliJ IDEA or Eclipse). 3. A test plugin has been created in the GoMint repository and can be browsed [here](https://github.com/gomint/GoMint/tree/master/gomint-test-plugin/src/main/java/io/gomint/testplugin) for another example of what we will be creating. -### pom.xml Setup - -Before you begin writing a plugin, you will need a ```pom.xml``` for the plugin. It is pertinent that this file be included. - -```xml - - - 4.0.0 - - - io.gomint.testplugin - gomint-testplugin - 1.0-SNAPSHOT - - - GoMint Test Plugin - A plugin to test and see GoMint's API design - - - - - io.gomint - gomint-api - 1.0.0-SNAPSHOT - provided - - - - - - - ${pom.basedir}/src/main/resources - true - - *.* - - - - - - -``` - ## Step One - The ```Plugin``` Type -All plugins for the GoMint server contain a class extending ```io.gomint.plugin.Plugin``` +All plugins for the GoMint server contain a class extending [```io.gomint.plugin.Plugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/Plugin.html) where the initialization and cleanup of the plugin will take place, as well as the registration of event handlers, new logic, etc. In lieu of a ```main()``` method, the plugin management system handles the initialization of plugins, so it is important that the annotations and types are setup correctly. @@ -68,7 +22,7 @@ package me.plugincrafter.demo; import io.gomint.plugin.Plugin; // The class MUST extend Plugin. It is common for new users to write -// 'JavaPlugin', as they are coming from Bukkit/Spigot. +// 'JavaPlugin', as they are coming from Bukkit/Spigot, but here it is just 'Plugin'. public class TestPlugin extends Plugin {} ``` @@ -78,11 +32,11 @@ Rather than use a configuration file that is packed into the JAR file to describ Annotations: -| Annotation | Type | Value | See Also | -|------------|-----------------|---------------------------|---------------------------------------------------------------------------------------| -| PluginName | String | Your plugin's name | | -| Version | int, int | ```major```, ```minor``` | | -| Startup | StartupPriority | See Enums | [JavaDoc](https://janmm14.de/static/gomint/index.html?gomint.api/module-summary.html) | +| Annotation | Type | Value | +|------------|-----------------|---------------------------------------------------------------------------------------------------------------------| +| PluginName | String | Your plugin's name | +| Version | int, int | ```major```, ```minor``` | +| Startup | StartupPriority | See Enum in [JavaDoc](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/StartupPriority.html) | ```java package me.plugincrafter.demo; @@ -99,17 +53,29 @@ import io.gomint.plugin.Version; public class TestPlugin extends Plugin {} ``` +## Step Three - GoMint API philosophies and differences to other server software + +GoMint is one of the first Minecraft server softwares which have built in world multithreading - each world has its own main thread. +This means that many actions to worlds and entites need to run in the world's thread. + +Additionally GoMint provides an easy-to-use API for plugins to [restrict plugins to certain worlds](../get-started/plugin-world-restriction.md), which **every** plugin should obey to. + ## ```Plugin``` Available Methods -The following methods are inherited from ```Plugin``` and can be used to install event handlers, listeners, and setup your plugin: +The following methods are inherited from [```Plugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/Plugin.html) and can be used to install event handlers, listeners, and setup your plugin: * ```onInstall()``` - Invoked when the plugin enters the runtime stage. * ```onStartup()``` - Invoked when the plugin has been installed. * ```onUninstall()``` - Invoked when the plugin has been uninstalled. * ```isInstalled()``` - Can be invoked to determine if the plugin has been installed yet. * ```registerCommand(io.gomint.command.Command)``` - Invoke to register your own commands. -* ```registerListener(io.gomint.event.EventListener)``` - Invoke to register your own event listeners. +* ```registerActiveWorldsListener(io.gomint.event.EventListener)``` - Invoke to register your own event listeners, limited to the [worlds your plugin should be active in](../get-started/plugin-world-restriction.md). +* ```registerListener(io.gomint.event.EventListener)``` - Invoke to register your own global event listeners. +* ```registerListener(io.gomint.event.EventListener, Predicate)``` - Invoke to register your own custom-limited event listeners. * ```unregisterListener(io.gomint.event.EventListener)``` - Invoke to remove an event listener. +* ```activeInWorld(io.gomint.world.World)``` - Returns whether the plugin should be active in the given world. +* ```eventInActiveWorlds(io.gomint.event.Event)``` - Returns whether the plugin should be active in the given world. +* ```activeWorldsSnapshot()``` - Returns a set of currently loaded worlds where the plugin should be active in. Do **not** save it for later use. * ```getDataFolder()``` - Returns the data folder for this plugin as a File object. * ```getPluginManager()``` - Returns the plugin manager of the GoMint server. * ```getName() ``` - Returns the name of this plugin. From 44e3ca3c977f93f3b658d5836fa568b17507aade Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 01:42:21 +0100 Subject: [PATCH 08/14] Update creating-your-first-event-listener.md --- .../creating-your-first-event-listener.md | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index 9902bd5..ed94b00 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -18,19 +18,19 @@ For your plugin to get informed when an event happens, you need to create a clas public class MyFirstEventListener implements EventListener {} ``` -Now we marked the class for us and the api as event listener. Then we have to register our class to the API. We do that for example in the `onInstall` method in our `TestPlugin` class: +Now we marked the class for us and the api as event listener. Then we have to register our class to the API. We do that for example in the `onInstall` method in our `TestPlugin` class. Note that we use the method [`registerActiveWorldsListener`](https://janmm14.de/static/gomint/gomint.api/io/gomint/plugin/Plugin.html#registerActiveWorldsListener(io.gomint.event.EventListener)) which automatically filters events so we only get events taking place in any of the [plugin's active worlds](../get-started/plugin-world-restriction.md). ```java @Override public void onInstall() { - registerListener(new MyFirstEventListener()); + registerActiveWorldsListener(new MyFirstEventListener()); } ``` Next up we need to define which event(s) we want to listen to in this event listener. This is done simply by creating a method annotated with `@EventHandler` which takes one argument (the event we want to listen to) and returns `void`: ```java -public class MyFirstEventHandler implements EventListener { +public class MyFirstEventListener implements EventListener { @EventHandler public void onExplode(EntityExplodeEvent event) { // this method gets called every time an entity explodes @@ -42,14 +42,40 @@ Now we just need to implement some logic. We can praise explosions for example w ```java -public class MyFirstEventHandler implements EventListener { +public class MyFirstEventListener implements EventListener { @EventHandler public void onExplode(EntityExplodeEvent event) { - GoMint.instance().onlinePlayers().forEach(p -> p.sendMessage("Hooray, " + event.getAffectedBlocks().size() + " are gone!")); + GoMint.instance().onlinePlayers().forEach(p -> p.sendMessage("Hooray, " + event.affectedBlocks().size() + " are gone!")); } } ``` ## Cancellable events -We changed our minds now and want to prevent explosions from happening. Great that [EntityExplodeEvent](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/entity/EntityExplodeEvent.html) extends [CancellableEvent](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/CancellableEvent.html). +We changed our minds now and want to prevent explosions from happening. Great that [EntityExplodeEvent](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/entity/EntityExplodeEvent.html) extends [CancellableEvent](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/CancellableEvent.html). To cancel events we write this method in our event listener: + +```java + @EventHandler + public void preventExplosions(EntityExplodeEvent event) { + event.cancelled(true); + } +``` + +## EventHandler options + +| option | possible values | +|-----------------|-----------------| +| priority | [EventPriority](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/EventPriority.html) enum: `LOWEST`, `LOW`, `NORMAL` (default), `HIGH`, `HIGHEST` | +| ignoreCancelled |
  • `true` method will not be called for cancelled events
  • `false` (default) method will be called regardless of event cancelled state
| + +### Details on priority option + +We have two event listeners for the same event. So how do we define the order in which they will execute? + +This is possible with the priority option of the `@EventHandler` annotation. + +```java + @EventHandler(priority = EventPriority.HIGHEST) +``` + +Priority `LOWEST` is called first, `HIGHEST` will be called last. So you should choose `HIGHEST` if you want to monitor the result of an event, use `HIGH` to override other plugins and use `LOWEST` or `LOW` for changes other plugins who listen on a higher priority should be able to react to. From 747cff82a2a402738893a15eb02d5631098152e5 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 01:44:03 +0100 Subject: [PATCH 09/14] Update creating-your-first-event-listener.md --- docs/development/creating-your-first-event-listener.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index ed94b00..abdd960 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -61,7 +61,7 @@ We changed our minds now and want to prevent explosions from happening. Great th } ``` -## EventHandler options +## ```@EventHandler``` options | option | possible values | |-----------------|-----------------| From 0485895a67de64d2226ff7a4c9c1e9f3a67ab760 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 02:00:34 +0100 Subject: [PATCH 10/14] Update creating-your-first-event-listener.md --- docs/development/creating-your-first-event-listener.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index abdd960..dc1018d 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -6,7 +6,7 @@ sidebar_label: Creating Your First Event Listener ## Prerequisites -This guide assumes that you have a [plugin environment](/docs/development/creating-first-plugin) setup. +This guide assumes that you have a [plugin environment](creating-a-first-plugin.md) setup. If you have not already, follow that guide first. ## Event Concept From 2962656e293081ead38ceb9b3d13dee6ada5ec96 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Sun, 14 Feb 2021 02:36:22 +0100 Subject: [PATCH 11/14] Update creating-your-first-command.md --- .../creating-your-first-command.md | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/docs/development/creating-your-first-command.md b/docs/development/creating-your-first-command.md index fe4e484..9f3635a 100644 --- a/docs/development/creating-your-first-command.md +++ b/docs/development/creating-your-first-command.md @@ -5,7 +5,7 @@ sidebar_label: Creating Your First Command --- ## Prerequisites -This guide assumes that you have a [plugin environment](/docs/development/creating-first-plugin) setup. +This guide assumes that you have a [plugin environment](creating-a-first-plugin.md) setup. If you have not already, follow that guide first. ## Writing a ```Command``` type @@ -82,6 +82,39 @@ public class CommandVelocity extends Command { } ``` +## World check and grab Plugin main class +Due to GoMints plugin world restriction ideas, we should not allow the plugin to run in worlds it should not be active in. We use the [```@InjectPlugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/injection/InjectPlugin.html) annotation here to get our plugin instance into our command; this only works in annotation-defined commands. Commands by players are executed in the world thread of the player, so we do not need to care about this for now. + +```java +@Name("velocity") +@Description("Give custom velocity to the player who runs it") +public class CommandVelocity extends Command { + + @InjectPlugin + private TestPlugin plugin; + + @Override + public void execute(CommandSender commandSender, String alias, Map arguments, CommandOutput output) { + + if (commandSender instanceof PlayerCommandSender) { + EntityPlayer player = (EntityPlayer) commandSender; + if (!plugin.activeInworld(player.world()) { + output.fail("Plugin not active in your world"); + return; + } + + // Now that we have casted the CommandSender to an EntityPlayer, we can use those methods on the object. + player.setVelocity(new Vector(0, 2, 0)); + } else if (commandSender instanceof ConsoleCommandSender) { + // TODO: Let's add arguments in a moment! + } + + return output; + } +} +``` + + ## Adding Permissions Adding permissions to a command is as simple as adding the permission annotation. Supposing that we want to only allow players to use the velocity command if they have the ```velocityplugin.command.velocity```, we can append the annotation to the class declaration: @@ -120,7 +153,7 @@ The parameter annotation accepts the following fields: ``` ### Arguments Passed -The arguments passed when a command is executed by the player/console are passed to ```execute``` in the Map object ```arguments```. For our velocity command example, we will allow a ```ConsoleCommandSender``` to specify a player's name to apply the velocity to. +The arguments passed when a command is executed by the player/console are passed to ```execute``` in the Map object ```arguments```. For our velocity command example, we will allow a ```ConsoleCommandSender``` to specify a player's name to apply the velocity to. We also have to schedule our work to the target player's world here, as console commands are running in a different thread. ```java // Continued from above @@ -130,12 +163,19 @@ The arguments passed when a command is executed by the player/console are passed Float velocity_y = (Float) arguments.getOrDefault("velocity_y", 2f); Float velocity_z = (Float) arguments.getOrDefault("velocity_z", 0f); - // If all the parameters were passed, the player will receive the specified velocity. - // Otherwise, they will receive a velocity of (x: 0, y: 2, z: 0). - player.setVelocity(new Vector(velocity_x, velocity_y, velocity_z)); + // As we are scheduling the command's world to another thread, command execution ends asynchroniously + // We have to mark this and later call markFinished when our command execution is over. + output.markAsync(); + + // Do not edit player's velocity asynchroniously - we schedule to its thread + player.world().scheduler().execute(() -> { + // If all the parameters were passed, the player will receive the specified velocity. + // Otherwise, they will receive a velocity of (x: 0, y: 2, z: 0). + player.setVelocity(new Vector(velocity_x, velocity_y, velocity_z)); - // When the velocity was successfully applied to the given player, a messagae will be sent to the ConsoleCommandSender. - output.success("Applied velocity to " + player.getNameTag()); + // When the velocity was successfully applied to the given player, a message will be sent to the ConsoleCommandSender. + output.success("Applied velocity to " + player.getNameTag()).markFinished(); + }); } ``` From c591e03c2d3f6733b4dec0abdb0cd2b54eb4af61 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Mon, 15 Feb 2021 11:01:45 +0100 Subject: [PATCH 12/14] stuff --- docs/development/creating-a-first-plugin.md | 21 +++-- .../creating-your-first-command.md | 91 +++++++------------ .../creating-your-first-event-listener.md | 13 ++- docs/development/getting-started.md | 2 + docs/get-started/getting-started.md | 4 +- docs/get-started/plugin-world-restriction.md | 2 + docs/guides.md | 10 +- 7 files changed, 71 insertions(+), 72 deletions(-) diff --git a/docs/development/creating-a-first-plugin.md b/docs/development/creating-a-first-plugin.md index 808befa..c422d6b 100644 --- a/docs/development/creating-a-first-plugin.md +++ b/docs/development/creating-a-first-plugin.md @@ -8,7 +8,8 @@ sidebar_label: Creating Your First Plugin 1. An understanding of the Java programming language is necessary. 2. Follow the [Getting Started guide](getting-started.md) to set up the project in your Java IDE (like IntelliJ IDEA or Eclipse). -3. A test plugin has been created in the GoMint repository and can be browsed [here](https://github.com/gomint/GoMint/tree/master/gomint-test-plugin/src/main/java/io/gomint/testplugin) for another example of what we will be creating. + +A test plugin has been created in the GoMint repository and can be browsed [here](https://github.com/gomint/GoMint/tree/master/gomint-test-plugin/src/main/java/io/gomint/testplugin) for another example of what we will be creating. ## Step One - The ```Plugin``` Type @@ -16,6 +17,10 @@ All plugins for the GoMint server contain a class extending [```io.gomint.plugin where the initialization and cleanup of the plugin will take place, as well as the registration of event handlers, new logic, etc. In lieu of a ```main()``` method, the plugin management system handles the initialization of plugins, so it is important that the annotations and types are setup correctly. +:::info +The class in your plugin extending `Plugin` is often also referred to as *main class* of your plugin. +::: + ```java package me.plugincrafter.demo; @@ -58,24 +63,26 @@ public class TestPlugin extends Plugin {} GoMint is one of the first Minecraft server softwares which have built in world multithreading - each world has its own main thread. This means that many actions to worlds and entites need to run in the world's thread. -Additionally GoMint provides an easy-to-use API for plugins to [restrict plugins to certain worlds](../get-started/plugin-world-restriction.md), which **every** plugin should obey to. +Additionally GoMint provides easy-to-use API for plugins to handle the world multithreading and [restrict plugins to certain worlds](../get-started/plugin-world-restriction.md), which **every** plugin should obey to. ## ```Plugin``` Available Methods The following methods are inherited from [```Plugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/Plugin.html) and can be used to install event handlers, listeners, and setup your plugin: -* ```onInstall()``` - Invoked when the plugin enters the runtime stage. -* ```onStartup()``` - Invoked when the plugin has been installed. -* ```onUninstall()``` - Invoked when the plugin has been uninstalled. +* ```onInstall()``` - Invoked when the plugin enters the runtime stage. Meant to be overriden. +* ```onUninstall()``` - Invoked when the plugin has been uninstalled. Meant to be overriden. +* ```onStartup()``` - Invoked when the plugin has been installed. Can be overridden if needed. * ```isInstalled()``` - Can be invoked to determine if the plugin has been installed yet. * ```registerCommand(io.gomint.command.Command)``` - Invoke to register your own commands. * ```registerActiveWorldsListener(io.gomint.event.EventListener)``` - Invoke to register your own event listeners, limited to the [worlds your plugin should be active in](../get-started/plugin-world-restriction.md). * ```registerListener(io.gomint.event.EventListener)``` - Invoke to register your own global event listeners. -* ```registerListener(io.gomint.event.EventListener, Predicate)``` - Invoke to register your own custom-limited event listeners. +* ```registerListener(io.gomint.event.EventListener, Predicate)``` - Invoke to register your own custom-limited event listeners. * ```unregisterListener(io.gomint.event.EventListener)``` - Invoke to remove an event listener. * ```activeInWorld(io.gomint.world.World)``` - Returns whether the plugin should be active in the given world. * ```eventInActiveWorlds(io.gomint.event.Event)``` - Returns whether the plugin should be active in the given world. -* ```activeWorldsSnapshot()``` - Returns a set of currently loaded worlds where the plugin should be active in. Do **not** save it for later use. +* ```activeWorldsSnapshot()``` - Returns a set of _currently_ loaded worlds where the plugin should be active in. Do **not** save it for later use. +* ```activeWorldsPlayers()``` - Returns a set of players in your plugin's active worlds +* ```activeWorldsPlayers(Consumer)``` - Calls the given consumer for every player in your plugin's active worlds on the world's thread * ```dataFolder()``` - Returns the data folder for this plugin as a File object. * ```pluginManager()``` - Returns the plugin manager of the GoMint server. * ```name() ``` - Returns the name of this plugin. diff --git a/docs/development/creating-your-first-command.md b/docs/development/creating-your-first-command.md index 9f3635a..dd70504 100644 --- a/docs/development/creating-your-first-command.md +++ b/docs/development/creating-your-first-command.md @@ -20,13 +20,16 @@ public class CommandVelocity extends Command {} Commands in GoMint are based on annotations and injection. There are two required annotations that each command must have, but the full list of annotations for commands are below. GoMint will detect all classes in your plugin which extend `Command` and have at least the required annotations and will automatically create an instance and register it. For custom conditions on command registration you need to use [methods for describing your command](#commandmethod) instead. -| Annotation | Type | Value | Required? | Repeatable? | -|-------------|-----------------|----------------------------------------------------|-----------|-------------| -| Name | String | The command's name | Yes | No | -| Description | String | A description of the command | Yes | No | -| Alias | String | An alias for the command that will also execute it | No | Yes | -| Permission | String | The permission required for the command to execute | No | No | -| Overload | ... | See [overload annotation](#overload) information | No | Yes | +| Annotation | Type | Value | Required? | Repeatable? | +|-----------------------|-----------------|----------------------------------------------------------------------------------------|-----------|-------------| +| Name | String | The command's name | Yes | No | +| Description | String | A description of the command | Yes | No | +| Scope | | Where the command will be available | No | No | +| - `activeWorldsOnly` | boolean | If the command is only available to players in plugin's active worlds. Default: `true` | No | No | +| - `console` | boolean | If the command is available to the console. Default: `true` | No | No | +| Alias | String | An alias for the command that will also execute it | No | Yes | +| Permission | String | The permission required for the command to execute | No | No | +| Overload | ... | See [overload annotation](#overload) information | No | Yes | The next step to writing your command is to add the necessary annotations to the class: @@ -47,10 +50,7 @@ which must be overridden from ```io.gomint.command.Command``` type. Our ```Comma public class CommandVelocity extends Command { @Override - public CommandOutput execute(CommandSender commandSender, String alias, Map arguments) { - CommandOutput output = new CommandOutput(); - - return output; + public void execute(CommandSender commandSender, String alias, Map arguments, CommandOutput output) { } } ``` @@ -65,25 +65,22 @@ It is important to verify that the sender was the correct type before performing public class CommandVelocity extends Command { @Override - public CommandOutput execute(CommandSender commandSender, String alias, Map arguments) { - CommandOutput output = new CommandOutput(); - + public void execute(CommandSender commandSender, String alias, Map arguments, CommandOutput output) { if (commandSender instanceof PlayerCommandSender) { EntityPlayer player = (EntityPlayer) commandSender; // Now that we have casted the CommandSender to an EntityPlayer, we can use those methods on the object. + // Commands from players are executed on player'S current world thread, so we do not need to care about that for now. player.setVelocity(new Vector(0, 2, 0)); } else if (commandSender instanceof ConsoleCommandSender) { // TODO: Let's add arguments in a moment! } - - return output; } } ``` -## World check and grab Plugin main class -Due to GoMints plugin world restriction ideas, we should not allow the plugin to run in worlds it should not be active in. We use the [```@InjectPlugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/injection/InjectPlugin.html) annotation here to get our plugin instance into our command; this only works in annotation-defined commands. Commands by players are executed in the world thread of the player, so we do not need to care about this for now. +## Get Plugin class +If we need the Plugin class, we can use the [```@InjectPlugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/injection/InjectPlugin.html) annotation on a field with the type of our Plugin class; this only works in annotation-defined commands. ```java @Name("velocity") @@ -92,25 +89,6 @@ public class CommandVelocity extends Command { @InjectPlugin private TestPlugin plugin; - - @Override - public void execute(CommandSender commandSender, String alias, Map arguments, CommandOutput output) { - - if (commandSender instanceof PlayerCommandSender) { - EntityPlayer player = (EntityPlayer) commandSender; - if (!plugin.activeInworld(player.world()) { - output.fail("Plugin not active in your world"); - return; - } - - // Now that we have casted the CommandSender to an EntityPlayer, we can use those methods on the object. - player.setVelocity(new Vector(0, 2, 0)); - } else if (commandSender instanceof ConsoleCommandSender) { - // TODO: Let's add arguments in a moment! - } - - return output; - } } ``` @@ -145,9 +123,9 @@ The parameter annotation accepts the following fields: ```java // Our velocity command should be able to accept a parameter for a player name and the specified velocity they should receive. @Overload({ - @Parameter(name = "player", validator = TargetValidator.class, optional = true) - @Parameter(name = "velocity_x", validator = FloatValidator.class, optional = true) - @Parameter(name = "velocity_y", validator = FloatValidator.class, optional = true) + @Parameter(name = "player", validator = TargetValidator.class, optional = true), + @Parameter(name = "velocity_x", validator = FloatValidator.class, optional = true), + @Parameter(name = "velocity_y", validator = FloatValidator.class, optional = true), @Parameter(name = "velocity_z", validator = FloatValidator.class, optional = true) }) ``` @@ -164,21 +142,25 @@ The arguments passed when a command is executed by the player/console are passed Float velocity_z = (Float) arguments.getOrDefault("velocity_z", 0f); // As we are scheduling the command's world to another thread, command execution ends asynchroniously - // We have to mark this and later call markFinished when our command execution is over. + // We have to mark this and later call markFinished() when our command execution is over. output.markAsync(); - // Do not edit player's velocity asynchroniously - we schedule to its thread + // Cannot not edit player's velocity asynchroniously - we schedule to player's world thread player.world().scheduler().execute(() -> { // If all the parameters were passed, the player will receive the specified velocity. // Otherwise, they will receive a velocity of (x: 0, y: 2, z: 0). player.setVelocity(new Vector(velocity_x, velocity_y, velocity_z)); // When the velocity was successfully applied to the given player, a message will be sent to the ConsoleCommandSender. - output.success("Applied velocity to " + player.getNameTag()).markFinished(); + output.success("Applied velocity to " + player.getNameTag()).markFinished(); // markFinished() is required after calling markAsync() }); } ``` +:::danger +Most player and world access and editing methods require that you call them from the (player's) world's thread. Not doing so will throw an exception in runtime. +::: + ## Additional Information ### Adding Commands Using Methods @@ -197,10 +179,7 @@ public class CommandVelocity extends Command { } @Override - public CommandOutput execute(CommandSender commandSender, String alias, Map arguments) { - CommandOutput output = new CommandOutput(); - - return output; + public CommandOutput execute(CommandSender commandSender, String alias, Map arguments, CommandOutput output) { } } ``` @@ -222,16 +201,16 @@ Calling not repeatable methods again will overwrite the existing value. Each call to `overload()` will add a new overload to your method. By default the overload is empty. To add a parameter you have to call the `param(...)` functions on the return `ComandOverload` object. The param function takes the name of parameter first, next up is the ParamValidator. The third argument is the optional boolean, which is itself optional and defaults to false as well. -The ParamValidator needs to be instantiated here instead of it's class. +The ParamValidator needs to be instantiated here instead of it's class given. ```java -public CommandVelocity() { - super("velocity"); - description("Give custom velocity to the player who runs it"); - permission("velocityplugin.command.velocity"); - overload().param("player", new TargetValidator(), true) - .param("velocity_x", new FloatValidator(), true) - .param("velocity_y", new FloatValidator(), true) - .param("velocity_z", new FloatValidator(), true); + public CommandVelocity() { + super("velocity"); + description("Give custom velocity to the player who runs it"); + permission("velocityplugin.command.velocity"); + overload().param("player", new TargetValidator(), true) + .param("velocity_x", new FloatValidator(), true) + .param("velocity_y", new FloatValidator(), true) + .param("velocity_z", new FloatValidator(), true); } ``` diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index dc1018d..563213d 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -12,6 +12,11 @@ If you have not already, follow that guide first. ## Event Concept Many actions done by players, blocks or mobs trigger an event. Technically: a class extending `Event`. Events allow you to know, edit or cancel default behaviour. + +:::note +If not otherwise noted in the specifics event javadoc, events are called on the source world thread if they implement [`WorldEvent`](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/interfaces/WorldEvent.html). +::: + For your plugin to get informed when an event happens, you need to create a class implementing `EventListener` (a marker interface): ```java @@ -26,8 +31,13 @@ Now we marked the class for us and the api as event listener. Then we have to re registerActiveWorldsListener(new MyFirstEventListener()); } ``` + Next up we need to define which event(s) we want to listen to in this event listener. -This is done simply by creating a method annotated with `@EventHandler` which takes one argument (the event we want to listen to) and returns `void`: +This is done simply by creating a method annotated with `@EventHandler` which takes one argument (the event we want to listen to): + +:::note +Event handling methods need to return `void`. Their visibility must be `public` or package-private. +::: ```java public class MyFirstEventListener implements EventListener { @@ -40,7 +50,6 @@ public class MyFirstEventListener implements EventListener { Now we just need to implement some logic. We can praise explosions for example with a chat message sent to every player: - ```java public class MyFirstEventListener implements EventListener { @EventHandler diff --git a/docs/development/getting-started.md b/docs/development/getting-started.md index 7ea11dc..ad89701 100644 --- a/docs/development/getting-started.md +++ b/docs/development/getting-started.md @@ -62,6 +62,7 @@ Example pom.xml file for maven: Here is the repository snippet: -## Concluding Thoughts - You may want to visit the next tutorial about [configuring](general-configuration.md) your new server. +## Concluding Thoughts + If you want to know more about gomint's unique world system, visit the [Plugin World Restrictions](plugin-world-restriction.md) information page. Or, if you want to dive into writing custom plugins, visit the [first plugin](/docs/development/creating-first-plugin) tutorial. diff --git a/docs/get-started/plugin-world-restriction.md b/docs/get-started/plugin-world-restriction.md index 74d3ac2..7279a8e 100644 --- a/docs/get-started/plugin-world-restriction.md +++ b/docs/get-started/plugin-world-restriction.md @@ -10,4 +10,6 @@ This allows Gomint to scale better than many other minecraft server softwares an To not make plugin development unneccessary complex, we created an API that allows plugins to only run in certain worlds. You can set up the worlds of a plugin within the `worlds.yml` file you can find in the folder `plugins/ThePluginName`. +:::caution While plugins are not forced by the server to follow this setting, it is strongly adviced that every plugin uses the easy provided API to follow the `worlds.yml` setting. +::: diff --git a/docs/guides.md b/docs/guides.md index 6bb5ee6..a172efc 100644 --- a/docs/guides.md +++ b/docs/guides.md @@ -6,14 +6,14 @@ sidebar_label: Index of Guides ## Introductory Guides -* [Getting Started](/docs/get-started/getting-started) -* [Configuring Server](/docs/get-started/general-configuration) +* [Getting Started](get-started/getting-started.md) +* [Configuring Server](get-started/general-configuration.md) ## API Guides -* [API Introduction](/docs/development/getting-started) -* [Writing Your First Plugin](/docs/development/creating-first-plugin) -* [Writing Your First Command](/docs/development/creating-your-first-command) +* [Set up your work space](development/getting-started.md) +* [Writing Your First Plugin](development/creating-a-first-plugin.md) +* [Writing Your First Command](development/creating-your-first-command.md) ### Resources * [Javadoc](https://s.janmm14.de/gomint-javadoc) From 36d284849c906089e6b7a96bddd609239f17376c Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Mon, 15 Feb 2021 11:01:56 +0100 Subject: [PATCH 13/14] ignore intellij idea files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b2d6de3..0b03eae 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +.idea/ +*.iml From 6549b73ff370edff76819eb8c5f60bfedf80f68a Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Mon, 1 Mar 2021 16:15:06 +0100 Subject: [PATCH 14/14] Update documentation to latest changes in world multithreading PR. Also done: - Misc improvements - Remove duplicated unfinished documentation in api directory. --- docs/api/api-creating-a-first-plugin.md | 11 ------- docs/api/api-getting-started.md | 32 ------------------- docs/development/creating-a-first-plugin.md | 5 +++ .../creating-your-first-command.md | 16 ++++++---- .../creating-your-first-event-listener.md | 6 ++-- docs/get-started/plugin-world-restriction.md | 2 +- 6 files changed, 18 insertions(+), 54 deletions(-) delete mode 100644 docs/api/api-creating-a-first-plugin.md delete mode 100644 docs/api/api-getting-started.md diff --git a/docs/api/api-creating-a-first-plugin.md b/docs/api/api-creating-a-first-plugin.md deleted file mode 100644 index bfa01fb..0000000 --- a/docs/api/api-creating-a-first-plugin.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -id: api-creating-first-plugin -title: Creating Your First Plugin -sidebar_label: Creating Your First Plugin ---- - -## Prerequisites - -1. Follow the ["API Getting Started" guide](/docs/api/api-getting-started) and -install the API into your classpath. -2. An understanding of the Java programming language is necessary. diff --git a/docs/api/api-getting-started.md b/docs/api/api-getting-started.md deleted file mode 100644 index be96f5e..0000000 --- a/docs/api/api-getting-started.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -id: api-getting-started -title: Introduction to the GoMint API -sidebar_label: Introduction to GoMint API ---- - -## Downloading the API JARs - -## Adding JARs to Eclipse - -### Mac OS Instructions - -Before adding the JAR files to your build path in Eclipse, it's best to place them -in the workspace folder that you are working with, in a designated folder for -dependencies, or somewhere it will not be moved or accidentally deleted. - -1. To begin, create a new Java Project in Eclipse, or click the name of the project -in the project explorer if you have already created it. -2. Click ```File->Properties``` -3. Select "Java Build Path" from the list on the left. -4. Select "Classpath" from the list in the panel. -5. Select the button titled "Add External Jars" -6. Navigate to the JAR using Finder and select it. - -Once you have completed these steps, the API should be installed into your -classpath in Eclipse and ready to use for creating plugins. - -## Accessing the Javadoc - -The GoMint API Javadoc can be found [here](https://s.janmm14.de/gomint-javadoc). -While not every method and class has been documented, the majority have been with -brief explanations as to their functionality. diff --git a/docs/development/creating-a-first-plugin.md b/docs/development/creating-a-first-plugin.md index c422d6b..23254fb 100644 --- a/docs/development/creating-a-first-plugin.md +++ b/docs/development/creating-a-first-plugin.md @@ -90,3 +90,8 @@ The following methods are inherited from [```Plugin```](https://janmm14.de/stati * ```logger()``` - Returns the Logger of this plugin. * ```scheduler()``` - Returns the plugin scheduler. * ```server()``` - Returns an instance of the GoMint server. + +## Next up + +[Create your first command](creating-your-first-command.md) +[Create your first event listener](creating-your-first-event-listener.md) diff --git a/docs/development/creating-your-first-command.md b/docs/development/creating-your-first-command.md index dd70504..01da687 100644 --- a/docs/development/creating-your-first-command.md +++ b/docs/development/creating-your-first-command.md @@ -24,9 +24,6 @@ Commands in GoMint are based on annotations and injection. There are two require |-----------------------|-----------------|----------------------------------------------------------------------------------------|-----------|-------------| | Name | String | The command's name | Yes | No | | Description | String | A description of the command | Yes | No | -| Scope | | Where the command will be available | No | No | -| - `activeWorldsOnly` | boolean | If the command is only available to players in plugin's active worlds. Default: `true` | No | No | -| - `console` | boolean | If the command is available to the console. Default: `true` | No | No | | Alias | String | An alias for the command that will also execute it | No | Yes | | Permission | String | The permission required for the command to execute | No | No | | Overload | ... | See [overload annotation](#overload) information | No | Yes | @@ -70,7 +67,6 @@ public class CommandVelocity extends Command { EntityPlayer player = (EntityPlayer) commandSender; // Now that we have casted the CommandSender to an EntityPlayer, we can use those methods on the object. - // Commands from players are executed on player'S current world thread, so we do not need to care about that for now. player.setVelocity(new Vector(0, 2, 0)); } else if (commandSender instanceof ConsoleCommandSender) { // TODO: Let's add arguments in a moment! @@ -79,6 +75,10 @@ public class CommandVelocity extends Command { } ``` +:::note +Commands from players are executed on player's current world thread. This means manipulating the player and its world is ok to do. +::: + ## Get Plugin class If we need the Plugin class, we can use the [```@InjectPlugin```](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/plugin/injection/InjectPlugin.html) annotation on a field with the type of our Plugin class; this only works in annotation-defined commands. @@ -112,7 +112,9 @@ When using arguments, we can validate their type as well as assign them names. T For arguments, the ```Overload``` annotation is used. Within this annotation, ```Parameter``` annotations can be used to define a name for the arguments passed, a validator to use, and specify whether or not the parameter is optional. -__Note:__ _For each ```Overload``` annotation, your command will have a different way to organize parameters. Multiple ```Overload``` annotations can be summarized by using the ```Overloads``` annotation._ +:::note +For each ```Overload``` annotation, your command will have a different way to organize parameters. Multiple ```Overload``` annotations can (but don't have to) be summarized by using the ```Overloads``` annotation. +::: The parameter annotation accepts the following fields: * ```name``` - String: The name of the parameter (stored as a key in the ```arguments``` map) @@ -158,7 +160,7 @@ The arguments passed when a command is executed by the player/console are passed ``` :::danger -Most player and world access and editing methods require that you call them from the (player's) world's thread. Not doing so will throw an exception in runtime. +Commands issued by the console are not ran in any world's thread. Most player and world access and editing methods require that you call them from the (player's) world's thread. Not doing so will throw an exception in runtime. ::: ## Additional Information @@ -200,7 +202,7 @@ Calling not repeatable methods again will overwrite the existing value. Each call to `overload()` will add a new overload to your method. By default the overload is empty. To add a parameter you have to call the `param(...)` functions on the return `ComandOverload` object. -The param function takes the name of parameter first, next up is the ParamValidator. The third argument is the optional boolean, which is itself optional and defaults to false as well. +The param function takes the name of parameter first, next up is the ParamValidator. The third argument is the optional boolean, which is itself optional and defaults to false. The ParamValidator needs to be instantiated here instead of it's class given. ```java diff --git a/docs/development/creating-your-first-event-listener.md b/docs/development/creating-your-first-event-listener.md index 563213d..be3a835 100644 --- a/docs/development/creating-your-first-event-listener.md +++ b/docs/development/creating-your-first-event-listener.md @@ -23,12 +23,12 @@ For your plugin to get informed when an event happens, you need to create a clas public class MyFirstEventListener implements EventListener {} ``` -Now we marked the class for us and the api as event listener. Then we have to register our class to the API. We do that for example in the `onInstall` method in our `TestPlugin` class. Note that we use the method [`registerActiveWorldsListener`](https://janmm14.de/static/gomint/gomint.api/io/gomint/plugin/Plugin.html#registerActiveWorldsListener(io.gomint.event.EventListener)) which automatically filters events so we only get events taking place in any of the [plugin's active worlds](../get-started/plugin-world-restriction.md). +Now we marked the class for us and the api as event listener. Then we have to register our class to the API. We do that for example in the `onInstall` method in our `TestPlugin` class. Events implementing `WorldEvent` are filtered by gomint so we only get events taking place in any of our [plugin's active worlds](../get-started/plugin-world-restriction.md). ```java @Override public void onInstall() { - registerActiveWorldsListener(new MyFirstEventListener()); + registerListener(new MyFirstEventListener()); } ``` @@ -75,7 +75,7 @@ We changed our minds now and want to prevent explosions from happening. Great th | option | possible values | |-----------------|-----------------| | priority | [EventPriority](https://janmm14.de/static/gomint/index.html?gomint.api/io/gomint/event/EventPriority.html) enum: `LOWEST`, `LOW`, `NORMAL` (default), `HIGH`, `HIGHEST` | -| ignoreCancelled |
  • `true` method will not be called for cancelled events
  • `false` (default) method will be called regardless of event cancelled state
| +| ignoreCancelled |
  • `true` - method will not be called for cancelled events
  • `false` - (default) method will be called regardless of event cancelled state
| ### Details on priority option diff --git a/docs/get-started/plugin-world-restriction.md b/docs/get-started/plugin-world-restriction.md index 7279a8e..1612669 100644 --- a/docs/get-started/plugin-world-restriction.md +++ b/docs/get-started/plugin-world-restriction.md @@ -11,5 +11,5 @@ To not make plugin development unneccessary complex, we created an API that allo You can set up the worlds of a plugin within the `worlds.yml` file you can find in the folder `plugins/ThePluginName`. :::caution -While plugins are not forced by the server to follow this setting, it is strongly adviced that every plugin uses the easy provided API to follow the `worlds.yml` setting. +While plugins are not completely forced by the server to follow this setting, it is strongly adviced that every plugin uses the easy provided API to follow the `worlds.yml` setting. :::