-
-
Notifications
You must be signed in to change notification settings - Fork 160
Event API documentation #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import DocCardList from "@theme/DocCardList"; | ||
import { useCurrentSidebarCategory } from "@docusaurus/theme-common"; | ||
|
||
# Paper Event API | ||
|
||
Welcome to the Paper Event API Guide! | ||
This guide includes information for developers to use events inside Paper plugins. | ||
|
||
--- | ||
|
||
<DocCardList items={useCurrentSidebarCategory().items} /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
--- | ||
slug: /dev/custom-events | ||
--- | ||
|
||
# Custom Events | ||
|
||
Creating custom events is a great way to add functionality to your plugin. | ||
This will allow for other people to listen for your custom events and add functionality to your plugin. | ||
|
||
## Creating a custom event | ||
|
||
To create a custom event, you need to create a class that extends `Event`. Each event has a `HandlerList` that contains all the listeners that are listening for that event. | ||
|
||
This list is used to call the listeners when the event is called. | ||
|
||
olijeffers0n marked this conversation as resolved.
Show resolved
Hide resolved
|
||
:::info `getHandlerList` | ||
|
||
Although it is not inherited from `Event`, you need to add a static `getHandlerList()` method and return the `HandlerList` for your event. | ||
Both methods are required for your event to work. | ||
|
||
::: | ||
|
||
```java title="PaperIsCoolEvent.java" | ||
public class PaperIsCoolEvent extends Event { | ||
|
||
private static final HandlerList HANDLER_LIST = new HandlerList(); | ||
|
||
public static HandlerList getHandlerList() { | ||
return HANDLER_LIST; | ||
} | ||
|
||
@Override | ||
public HandlerList getHandlers() { | ||
return HANDLER_LIST; | ||
} | ||
olijeffers0n marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
``` | ||
|
||
Now that we have created our event, we can add some functionality to it. | ||
Perhaps this will contain a message that will be broadcast to the server when the event is called. | ||
|
||
```java title="PaperIsCoolEvent.java" | ||
public class PaperIsCoolEvent extends Event { | ||
|
||
private static final HandlerList HANDLER_LIST = new HandlerList(); | ||
private Component message; | ||
|
||
public PaperIsCoolEvent(Component message) { | ||
this.message = message; | ||
} | ||
|
||
public static HandlerList getHandlerList() { | ||
return HANDLER_LIST; | ||
} | ||
|
||
@Override | ||
public HandlerList getHandlers() { | ||
return HANDLER_LIST; | ||
} | ||
|
||
public Component getMessage() { | ||
return this.message; | ||
} | ||
|
||
public void setMessage(Component message) { | ||
this.message = message; | ||
} | ||
} | ||
``` | ||
|
||
## Calling the event | ||
|
||
Now that we have created our event, we can call it. | ||
|
||
```java title="ExamplePlugin.java" | ||
public class ExamplePlugin extends JavaPlugin { | ||
|
||
// ... | ||
|
||
public void callCoolPaperEvent() { | ||
PaperIsCoolEvent coolEvent = new PaperIsCoolEvent(Component.text("Paper is cool!")) | ||
coolEvent.callEvent(); | ||
// Plugins could have changed the message from inside their listeners here. So we need to get the message again. | ||
// This event structure allows for other plugins to change the message to their taste. | ||
// Like, for example, a plugin that adds a prefix to all messages. | ||
Bukkit.broadcast(coolEvent.getMessage()); | ||
} | ||
} | ||
``` | ||
|
||
## Implementing cancellation | ||
|
||
If you want to allow your event to be cancelled, you can implement the `Cancellable` interface. | ||
|
||
```java title="PaperIsCoolEvent.java" | ||
public class PaperIsCoolEvent extends Event implements Cancellable { | ||
|
||
private static final HandlerList HANDLER_LIST = new HandlerList(); | ||
private Component message; | ||
private boolean cancelled; | ||
|
||
// ... | ||
|
||
@Override | ||
public boolean isCancelled() { | ||
return this.cancelled; | ||
} | ||
|
||
@Override | ||
public void setCancelled(boolean cancelled) { | ||
this.cancelled = cancelled; | ||
} | ||
} | ||
``` | ||
|
||
Now, when the event is called, you can check if it is cancelled and act accordingly. | ||
|
||
```java title="ExamplePlugin.java" | ||
public class ExamplePlugin extends JavaPlugin { | ||
|
||
// ... | ||
|
||
public void callCoolPaperEvent() { | ||
PaperIsCoolEvent coolEvent = new PaperIsCoolEvent(Component.text("Paper is cool!")) | ||
coolEvent.callEvent(); | ||
if (!coolEvent.isCancelled()) { | ||
Bukkit.broadcast(coolEvent.getMessage()); | ||
} | ||
} | ||
} | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
slug: /dev/event-listeners | ||
--- | ||
|
||
# Event Listeners | ||
|
||
Events are an efficient way to listen for specific actions that happen in the game. They can be called by the server, or by plugins. | ||
These are called by the server or plugins when something happens, such as a player joining the server, or a block being broken. | ||
Plugins are able to call custom events, such as a player completing a quest, for other plugins to listen for. | ||
|
||
## Your listener class | ||
|
||
To listen for events, you need to create a class that implements `Listener`. | ||
This class can be called anything you want, but it is recommended to name it something related to the events you are listening for. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
// ... | ||
} | ||
``` | ||
|
||
## `@EventHandler` | ||
|
||
To listen for an event, you need to create a method that is annotated with `@EventHandler`. | ||
This method can be named anything you want, but it is recommended to name it something meaningful related to the event it is listening for. | ||
|
||
## The listener method | ||
|
||
The method body does not need to return any data, for this reason use `void` as the return type. | ||
Listeners take in a single parameter, which is the event that is being listened for. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
|
||
@EventHandler | ||
public void onPlayerJoin(PlayerJoinEvent event) { | ||
// ... | ||
} | ||
} | ||
``` | ||
|
||
:::note Events | ||
|
||
There is no list of events that can be listened for, however take a look | ||
[here](https://jd.papermc.io/paper/1.19/org/bukkit/event/Event.html) to see all events that extend `Event`. | ||
|
||
::: | ||
|
||
## Registering the listener | ||
|
||
To register the listener, you need to call `Bukkit.getPluginManager().registerEvents()` | ||
and pass in your listener class instance and an instance of your plugin. | ||
|
||
This will register your listener class and allow it to listen for events. | ||
This is commonly done in the `onEnable()` method of your plugin so that it is registered when the server starts ticking. | ||
|
||
```java title="ExamplePlugin.java" | ||
public class ExamplePlugin extends JavaPlugin { | ||
|
||
@Override | ||
public void onEnable() { | ||
getServer().getPluginManager().registerEvents(new ExampleListener(), this); | ||
} | ||
} | ||
``` | ||
|
||
## Event priority | ||
|
||
You can also specify the priority of the event. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
|
||
@EventHandler(priority = EventPriority.HIGH) | ||
public void onPlayerJoin(PlayerJoinEvent event) { | ||
// ... | ||
} | ||
} | ||
``` | ||
There are six different priorities that you can use: | ||
- `EventPriority.LOWEST` | ||
- `EventPriority.LOW` | ||
- `EventPriority.NORMAL` | ||
- `EventPriority.HIGH` | ||
- `EventPriority.HIGHEST` | ||
- `EventPriority.MONITOR` | ||
|
||
The order of the priorities is somewhat counter-intuitive. The **higher** the priority, the **later** the event is called. | ||
For example, If it is important that your plugin has the last say in a certain event - to avoid it being changed - you | ||
should use `EventPriority.HIGHEST`. | ||
|
||
:::note | ||
|
||
The `MONITOR` priority is used to monitor the event, but not change it. It is called after all other priorities have been called. | ||
This means you can get the result of any plugin interaction such as cancellation or modification. | ||
|
||
::: | ||
|
||
## Event cancellation | ||
|
||
Some events can be cancelled, preventing the given action from being completed. These events implement `Cancellable`. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
|
||
@EventHandler | ||
public void onPlayerJoin(PlayerJoinEvent event) { | ||
event.setCancelled(true); | ||
} | ||
} | ||
``` | ||
|
||
:::warning | ||
|
||
It is important to consider that another plugin could have cancelled or changed the event before your plugin is called. | ||
Always check the event before doing anything with it. | ||
|
||
::: | ||
|
||
The above example will cancel the event, meaning that the player will not be able to join the server. | ||
Once an event is cancelled, it will continue to call any other listeners for that event unless they add | ||
`ignoreCancelled = true` to the `@EventHandler` annotation to ignore cancelled events. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
|
||
@EventHandler(ignoreCancelled = true) | ||
public void onPlayerJoin(PlayerJoinEvent event) { | ||
// ... | ||
} | ||
} | ||
``` | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
slug: /dev/handler-lists | ||
--- | ||
|
||
# Handler Lists | ||
|
||
Every `Event` has a `HandlerList` that contains all the listeners that are listening for that event. | ||
This list is used to call the listeners when the event is called. | ||
|
||
## Getting the handler list for an event | ||
|
||
To get the handler list for an event, you can call `getHandlerList()` on the specific event class. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
|
||
@EventHandler | ||
public void onPlayerJoin(PlayerJoinEvent event) { | ||
HandlerList handlerList = event.getHandlerList(); | ||
// ... | ||
} | ||
|
||
// Or: | ||
|
||
public ExampleListener() { | ||
// Access the handler list through the static getter | ||
HandlerList handlerList = PlayerJoinEvent.getHandlerList(); | ||
// ... | ||
} | ||
} | ||
``` | ||
|
||
## Unregistering a listener | ||
|
||
To unregister a listener, you can call `unregister()` on the `HandlerList` that the listener is registered to. | ||
|
||
```java title="ExampleListener.java" | ||
public class ExampleListener implements Listener { | ||
|
||
@EventHandler | ||
public void onPlayerJoin(PlayerJoinEvent event) { | ||
HandlerList handlerList = event.getHandlerList(); | ||
handlerList.unregister(this); | ||
// ... | ||
} | ||
|
||
// Or: | ||
|
||
public ExampleListener() { | ||
// Access the handler list through the static getter | ||
HandlerList handlerList = PlayerJoinEvent.getHandlerList(); | ||
handlerList.unregister(this); | ||
// Granted this is a pretty stupid example... | ||
} | ||
} | ||
``` | ||
|
||
You can unregister based on `Listener` or `Plugin` for more convenience. | ||
Likewise, you can also unregister all listeners for a specific event by calling `unregisterAll()` on the `HandlerList`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import DocCardList from "@theme/DocCardList"; | ||
import { useCurrentSidebarCategory } from "@docusaurus/theme-common"; | ||
|
||
# Development Guide | ||
|
||
Welcome to the Paper Development Guide! This guide includes information and tutorials for | ||
how to start developing plugins for Paper. | ||
|
||
--- | ||
|
||
<DocCardList items={useCurrentSidebarCategory().items} /> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.