- 欢迎来到Minecraft插件百科!
- 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
- 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289
Event API Reference/en
Welcome to Bukkit's Event API reference page.
简介
事件 就是你在使用CraftBukkit,或者基于CraftBukkit服务端的其他服务端的时候,服务端会将服务器内发生的事告诉正在监听对应事件的插件。CraftBukkit服务端为插件定义了许多不同的事件,比如玩家登录服务器,玩家进入服务器,玩家点击方块,玩家重生。还有一些可以被取消的事件例如,玩家放置方块,玩家破坏方块,等等。更还有区块卸载区块装载,实体等相关事件。具体请查看API文档: BukkitAPI:https://hub.spigotmc.org/javadocs/bukkit SpigotAPI:https://hub.spigotmc.org/javadocs/spigot 这里请注意了,有些事件是Spigot独有事件如果你想兼容CraftBukkit服务端请勿调用,例如PlayerSpawnLocationEvent
开始使用EventAPI
为了让大家看得懂,这一部分先定个小目标,先只用PlayerLoginEvent做示范
设置监听指定Event的方法
为了监听事件,我们需要创建一个新的方法,并给它加上EventHandler的注解来告诉服务端,这是个监听事件的方法,服务端就会在事件发生的时候调用该方法 方法名可以自己写你自己喜欢的,但传入的参数必须是你想监听的事件类
@EventHandler
public void onLogin(PlayerLoginEvent event) {
// 你在监听到玩家登录时执行的代码
}
@EventHandler
The "@EventHandler" class is an Annotation, which goes just above your method. It looks like this:
@EventHandler // EventPriority.NORMAL by default
This marks your method as an EventHandler with the EventPriority as NORMAL.
The EventHandler can take an EventPriority to specify the priority of the method, like so:
@EventHandler(priority = EventPriority.HIGHEST) // Makes your method Highest priority
@EventHandler(priority = EventPriority.LOW) // Makes your method Low priority
Here's what it would look like in your class:
@EventHandler
public void onLogin(PlayerLoginEvent event) {
// Your code here...
}
Adding the listener
In order for Bukkit to be able to register your EventHandler's, the class which contains your event handling methods must implement the Listener (org.bukkit.event.Listener) interface, e.g.:
public final class MyPlayerListener implements Listener {
@EventHandler
public void onLogin(PlayerLoginEvent event) {
// Your code here...
}
}
The name of the method (onLogin in the above example) does not matter; you may call the method anything you like inside your listener.
You may be wondering.. "How does Bukkit know which event to listen to?" It knows that by the event parameter you specify in the method's signature - in the above example: PlayerLoginEvent
.
You must specify a single specific event or Bukkit will not be able to register it
Your main plugin class (i.e. the class which extends JavaPlugin) can also be an event listener, and this might make sense if your plugin is very small. E.g.:
public class MyPlugin extends JavaPlugin implements Listener {
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onLogin(PlayerLoginEvent event) {
getLogger().log(Level.INFO, "Player " + event.getPlayer().getName() + " is logging in!");
}
}
EventHandler Parameters
The @EventHandler annotation can take parameters to further define how the event handler behaves. At the moment you can specify:
Name | Type | Default | Description | Values |
---|---|---|---|---|
priority | EventPriority | EventPriority.NORMAL | Sets the priority of your method |
|
ignoreCancelled | boolean | false | If set to true, your method will not get the event if the event has been cancelled |
|
Event Priorities
There are six priorities in Bukkit that are called in the following order
- EventPriority.LOWEST
- EventPriority.LOW
- EventPriority.NORMAL
- EventPriority.HIGH
- EventPriority.HIGHEST
- EventPriority.MONITOR
Every plugin gets a say in what happens, and every plugin must get a chance to know the outcome of an event. So, we pass events to plugins even after they've been cancelled. A plugin can actually uncancel an event after another plugin cancelled it. This is where priorities become really important.
Let's say a BLOCK_PLACE event is being handled. The lowest priority listener is called to get its say in whether it should be cancelled or not. Then the low priority listener is called to see if it wants to override the lowest, etc. Eventually it hits monitor, and at this point nothing should change the outcome of the event. Monitor should be used to see the outcome of an event, without changing any aspect of it. If we have three plugins enabled; one is a basic area protection plugin, one is a fancy plugin using signs, and another is a logging plugin. The protection plugin listens on Priority.LOWEST. It says they can't place blocks in this area, and cancels the event. The fancy sign plugin listens on Priority.NORMAL. It says they can place signs here, and uncancels the event. The log plugin listens on Priority.MONITOR. It sees that the event was actually allowed, and logs it.
If you want to change the outcome of an event, choose very carefully from LOWEST to HIGHEST. Suggested generalized protection plugins on lowest, more specific plugins on normal, and override plugins on high. If you want to act when an event happens, but not change the outcome, use MONITOR. It's really really important that you use MONITOR, or an event might get cancelled after you've acted on it, and it's even more important that you don't change the outcome of the event on MONITOR or it'll break other plugins.
Registering Events
To register your methods, the class containing the EventHandler(s) must implement the Listener class.
import org.bukkit.event.Listener; public final class LoginListener implements Listener { }
You only need to provide a plugin and a listener to register them in the PluginManager.
getServer().getPluginManager().registerEvents(Listener, Plugin);
Example Listener
This listener contains two EventHandlers. One listening on HIGH, and one on NORMAL.
import org.bukkit.event.Listener; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerLoginEvent; public final class LoginListener implements Listener { @EventHandler public void normalLogin(PlayerLoginEvent event) { // Some code here } @EventHandler(priority = EventPriority.HIGH) public void highLogin(PlayerLoginEvent event) { // Some code here } }
Registering Events in Plugin
The registerEvents method requires a listener and a plugin. Luckily, we already have our LoginListener. Now for the LoginPlugin!
import org.bukkit.plugin.java.JavaPlugin; public final class LoginPlugin extends JavaPlugin { public void onEnable() { getServer().getPluginManager().registerEvents(new LoginListener(), this); } }
Registering Events with Plugin as Listener
You could even have the events in the main class, for example:
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.event.Listener; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerLoginEvent; public final class LoginPlugin extends JavaPlugin implements Listener { public void onEnable() { getServer().getPluginManager().registerEvents(this, this); } @EventHandler public void normalLogin(PlayerLoginEvent event) { // Some code here } }
Registering Events in your Listener
There are many ways to register your events. Here's an example where you register them in your listener class.
import org.bukkit.event.Listener; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerLoginEvent; public final class LoginListener implements Listener { public LoginListener(LoginPlugin plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); } @EventHandler public void normalLogin(PlayerLoginEvent event) { // Some code here } @EventHandler(priority = EventPriority.HIGH) public void highLogin(PlayerLoginEvent event) { // Some code here } }
The LoginPlugin would look like this:
import org.bukkit.plugin.java.JavaPlugin; public final class LoginPlugin extends JavaPlugin { public void onEnable() { new LoginListener(this); } }
Un-registering events or listeners
You can un-register individual events, entire listener classes or all events registered by your plugin or even by other plugins!
Un-register specific event
Each event class has the getHandlerList() static method, call that and then you can use .unregister() method. Example:
PlayerInteractEvent.getHandlerList().unregister(plugin); // this will unregister all PlayerInteractEvent instances from the plugin // you can also specify a listener class instead of plugin.
Now you know why you'll need the getHandlerList() in your custom events.
Un-register all events
Using the HandlerList class and its unregisterAll() static method you can easily unregister events from listener classes or plugins. Example:
HandlerList.unregisterAll(plugin); // this will unregister all events from the specified plugin // you can also specify a listener class instead of plugin.
Creating Custom Events
Creating custom events is very simple, you can use the same system that Bukkit uses without ruining performance.
There are two (2) things to keep in mind when you create a Custom Event. They are "extend Event" and "static handlers." With static handlers, you must input the following code into your custom event:
private static final HandlerList handlers = new HandlerList(); public HandlerList getHandlers() { return handlers; } public static HandlerList getHandlerList() { return handlers; }
This block of code makes the EventHandlers contained inside your own event, keeping any unrelated events completely separated.
Custom Event Example
The following example shows how easy it is to create your own "CustomEvent."
import org.bukkit.event.Event; import org.bukkit.event.HandlerList; public final class CustomEvent extends Event { private static final HandlerList handlers = new HandlerList(); private String message; public CustomEvent(String example) { message = example; } public String getMessage() { return message; } public HandlerList getHandlers() { return handlers; } public static HandlerList getHandlerList() { return handlers; } }
Calling your Custom Event
You are in control of creating and calling your events, where you call it is completely up to you. Here's an example
// Create the event here CustomEvent event = new CustomEvent("Sample Message"); // Call the event Bukkit.getServer().getPluginManager().callEvent(event); // Now you do the event Bukkit.getServer().broadcastMessage(event.getMessage());
Remember: You are in control of your events. If you don't call it, and act upon it, it doesn't happen!
Listening to a Custom Event
How do you listen to a custom event you say? Simple, the same way as listening to a normal event!
import org.bukkit.event.Listener; import org.bukkit.event.EventHandler; public final class CustomListener implements Listener { @EventHandler public void normalLogin(CustomEvent event) { // Some code here } }
Making your CustomEvent Cancellable
If you ever want to make your event cancellable, remember one thing: "implements Cancellable." Just like you would import Listener. It's really that simple, let me show you an example!
import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.event.Cancellable; public final class CustomEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); private String message; private boolean cancelled; public CustomEvent(String example) { message = example; } public String getMessage() { return message; } public boolean isCancelled() { return cancelled; } public void setCancelled(boolean cancel) { cancelled = cancel; } public HandlerList getHandlers() { return handlers; } public static HandlerList getHandlerList() { return handlers; } }
Afterwards, you would check if a plugin had cancelled the event in your code, before processing normally
// Create the event here CustomEvent event = new CustomEvent("Sample Message"); // Call the event Bukkit.getServer().getPluginManager().callEvent(event); // Check if the event is not cancelled if (!event.isCancelled()) { // Now you do the event Bukkit.getServer().broadcastMessage(event.getMessage()); }
Video Tutorial
If you would prefer to watch a video tutorial version of this, please click here.