• 欢迎来到Minecraft插件百科!
  • 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
  • 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289

Event API Reference/en:修订间差异

来自Minecraft插件百科
跳转到导航 跳转到搜索
(修正分类,去除重复内容)
(修复错误的模板使用)
 
(未显示2个用户的19个中间版本)
第1行: 第1行:
{{条目原文}}
{{条目原文}}
Welcome to Bukkit's Event API reference page.
欢迎来到Bukkit提供的EventAPI相关教程页


== Introduction ==
== 简介 ==


'''Events''' are how the CraftBukkit server tells your plugin that something has happened in the world.  Bukkit defines many events, in multiple categories; e.g. player actions (player logged in, player clicked a block, player died, player respawned...), block events (block placed, block broken, block's neighbour changed...), entity events (a mob targeted you, a creeper exploded...), world-wide events (a world loaded or unloaded, a chunk loaded or unloaded), and many more. Due to unknown reasons there is no longer any links to official Javadocs as they have all been taken off line.
'''事件''' 就是你在使用CraftBukkit,或者基于CraftBukkit服务端的其他服务端的时候,服务端会将服务器内发生的事告诉正在监听对应事件的插件。CraftBukkit服务端为插件定义了许多不同的事件,比如玩家登录服务器,玩家进入服务器,玩家点击方块,玩家重生。还有一些可以被取消的事件例如,玩家放置方块,玩家破坏方块,等等。更还有区块卸载区块装载,实体等相关事件。具体请查看API文档:
BukkitAPI:https://hub.spigotmc.org/javadocs/bukkit
SpigotAPI:https://hub.spigotmc.org/javadocs/spigot
这里请注意了,有些事件是Spigot独有事件如果你想兼容CraftBukkit服务端请勿调用,例如PlayerSpawnLocationEvent


== The Basics ==
== 开始使用EventAPI ==
To keep this section simple, we're going to only work with PlayerLoginEvent. Lets start with setting up the method
为了让大家看得懂,这一部分先定个小目标,先只用PlayerLoginEvent做示范


=== Setting up the Method ===
=== 设置监听指定Event的方法 ===
In order for your plugin to handle an event call, you need to create a method for it:
为了监听事件,我们需要创建一个新的方法,并给它加上EventHandler的注解来告诉服务端,这是个监听事件的方法,服务端就会在事件发生的时候调用该方法
方法名可以自己写你自己喜欢的,但传入的参数必须是你想监听的事件类
<source lang="java">@EventHandler
<source lang="java">@EventHandler
public void onLogin(PlayerLoginEvent event) {
public void onLogin(PlayerLoginEvent event) {
     // Your code here...
     // 你在监听到玩家登录时执行的代码
}</source>
}</source>
Before this method can be invoked by Bukkit when the "PlayerLoginEvent" is fired, we need to annotate it. We do this with EventHandlers.
 


=== @EventHandler ===
=== @EventHandler ===
The "@EventHandler" class is an Annotation, which goes just above your method. It looks like this:
"@EventHandler" 是一个注解,用来告诉服务端这是一个监听事件的方法,你只需要把它加在你监听指定事件方法的上面就好,就像下面这样
<source lang="java">@EventHandler // EventPriority.NORMAL by default</source>
<source lang="java">@EventHandler // EventPriority.NORMAL 是默认的监听级别</source>
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:
当然你也可以自己设置事件监听的优先级比如下面这样:
<source lang="java">@EventHandler(priority = EventPriority.HIGHEST) // Makes your method Highest priority
<source lang="java">@EventHandler(priority = EventPriority.HIGHEST) // 将该事件监听的优先级修改到HIGHEST级别
@EventHandler(priority = EventPriority.LOW) // Makes your method Low priority</source>
@EventHandler(priority = EventPriority.LOW) // 将该事件的优先级修改到LOW级别</source>


Here's what it would look like in your class:
现在呢你的监听事件的方法的代码应该像这样:
<source lang="java">@EventHandler
<source lang="java">@EventHandler
public void onLogin(PlayerLoginEvent event) {
public void onLogin(PlayerLoginEvent event) {
第32行: 第36行:
}</source>
}</source>


=== 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.:
为了监听事件,你必须让监听事件的类实现 ''Listener'' (包名是:org.bukkit.event.Listener) 这个接口, e.g.:
<source lang="java">public final class MyPlayerListener implements Listener {
<source lang="java">public final class MyPlayerListener implements Listener {
     @EventHandler
     @EventHandler
第41行: 第45行:
} </source>
} </source>


The name of the method (''onLogin'' in the above example) does not matter;  you may call the method anything you like inside your listener.
上面那个名字叫''onLogin'' 的监听玩家登录事件的方法现在什么都不能干


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: <code>PlayerLoginEvent</code>.
就像我说的,Bukkit通过EventHandler注解来知道你这个方法是用来监听事件的,通过方法需要传入的参数知道要监听的是哪个事件,比如: <code>PlayerLoginEvent</code>.


{{warning|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.:
你必须在你的插件主类里(也就是那个继承JavaPlugin的类)的onEnable方法里加上如下代码:
其实吧也不是非得在onEnable里面加上,在你需要监听事件的时候保证这个监听事件的类被注册过就行
<source lang="java">
<source lang="java">
public class MyPlugin extends JavaPlugin implements Listener {
public class MyPlugin extends JavaPlugin implements Listener {
第57行: 第62行:
   @EventHandler
   @EventHandler
   public void onLogin(PlayerLoginEvent event) {
   public void onLogin(PlayerLoginEvent event) {
     getLogger().log(Level.INFO, "Player " + event.getPlayer().getName() + " is logging in!");
     System.out.println(event.getPlayer().getName()+"登入了服务器");
   }
   }
}
}
</source>
</source>
这里我提醒一下各位读者
玩家登录服务器分四个阶段
HandShake(和服务器握手
PreLogin(预登录阶段,就是正在登录
Login(登入阶段,一般盗版服会直接跳过该阶段,但是是可以监听到的
JoinGame(成功登录服务器


=== EventHandler Parameters ===
=== EventHandler注解的参数 ===
The @EventHandler annotation can take parameters to further define how the event handler behaves. At the moment you can specify:
@EventHandler你可以使用注解来定义事件监听的相关设置


{| class="wikitable" cellspacing="0" cellpadding="5" border="1"
{| class="wikitable" cellspacing="0" cellpadding="5" border="1"
第77行: 第88行:
| EventPriority
| EventPriority
| EventPriority.NORMAL
| EventPriority.NORMAL
| Sets the priority of your method
| 监听事件的优先级
|
|
* EventPriority.MONITOR
* EventPriority.MONITOR
第90行: 第101行:
| boolean
| boolean
| false
| false
| If set to true, your method will not get the event if the event has been cancelled
| 如果你把它设置成true,如果事件被取消这个监听的事件将不再会被监听到
|  
|  
* true
* true
第98行: 第109行:




==== Event Priorities ====
==== 事件优先级 ====
There are six priorities in Bukkit that are called in the following order
Bukkit会按照下面的顺序挨个在事件发生时通知监听该事件的插件
* EventPriority.LOWEST
* EventPriority.LOWEST(最优先
* EventPriority.LOW
* EventPriority.LOW
* EventPriority.NORMAL
* EventPriority.NORMAL
* EventPriority.HIGH
* EventPriority.HIGH
* EventPriority.HIGHEST
* EventPriority.HIGHEST
* EventPriority.MONITOR
* 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.
服务端将会根据这些监听器内EventHandler注解里面的监听优先级按顺序通知监听器,从LOWEST到MONITOR挨个通知插件,你可以通过设置优先级来阻止其他的插件对同等事件进行操作,并在MONITOR优先级的监听器取消后面插件对该事件的监听达到覆盖操作。


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.
要使你插件里包含监听器方法的类被注册,这个监听器才能起效,且包含监听方法的这个类必须实现Listener这个接口
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.
<blockquote><source lang="java">import org.bukkit.event.Listener;
<blockquote><source lang="java">import org.bukkit.event.Listener;


第125行: 第127行:
}</source></blockquote>
}</source></blockquote>


You only need to provide a plugin and a listener to register them in the PluginManager.
你只需要这一行代码来注册监听事件的类
<blockquote><source lang="java">getServer().getPluginManager().registerEvents(Listener, Plugin);</source></blockquote>
<blockquote><source lang="java">getServer().getPluginManager().registerEvents(Listener, Plugin);</source></blockquote>


=== Example Listener ===
=== 监听事件的例子 ===
This listener contains two EventHandlers. One listening on HIGH, and one on NORMAL.
这个监听事件的类包含两个监听器,且监听的是同一个事件,但是一个优先级是HIGH一个是默认的NORMAL
<blockquote><source lang="java">import org.bukkit.event.Listener;
<blockquote><source lang="java">import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventHandler;
第138行: 第140行:
     @EventHandler
     @EventHandler
     public void normalLogin(PlayerLoginEvent event) {
     public void normalLogin(PlayerLoginEvent event) {
         // Some code here
         // 你的代码
     }
     }


     @EventHandler(priority = EventPriority.HIGH)
     @EventHandler(priority = EventPriority.HIGH)
     public void highLogin(PlayerLoginEvent event) {
     public void highLogin(PlayerLoginEvent event) {
         // Some code here
         // 你的代码
     }
     }
}</source></blockquote>
}</source></blockquote>


=== Registering Events in Plugin ===
=== 将监听事件的类在你的插件内起效 ===
The registerEvents method requires a listener and a plugin. Luckily, we already have our LoginListener. Now for the LoginPlugin!
下面代码示范了如何注册你的监听类
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;


第158行: 第160行:




==== Registering Events with Plugin as Listener ====
==== 直接使用插件主类作为监听类 ====
You could even have the events in the main class, for example:
下面的代码示范了如何偷懒直接使用插件主类作为监听类并注册它:
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.Listener;
import org.bukkit.event.Listener;
第172行: 第174行:
     @EventHandler
     @EventHandler
     public void normalLogin(PlayerLoginEvent event) {
     public void normalLogin(PlayerLoginEvent event) {
         // Some code here
         // 你的代码
     }
     }
}</source></blockquote>
}</source></blockquote>


=== 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.
有很多很多不同的方式来注册你的监听类,下面代码示范了如何使用监听类的构造器来注册监听类
<blockquote><source lang="java">import org.bukkit.event.Listener;
<blockquote><source lang="java">import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventHandler;
第190行: 第192行:
     @EventHandler
     @EventHandler
     public void normalLogin(PlayerLoginEvent event) {
     public void normalLogin(PlayerLoginEvent event) {
         // Some code here
         // 你的代码
     }
     }


     @EventHandler(priority = EventPriority.HIGH)
     @EventHandler(priority = EventPriority.HIGH)
     public void highLogin(PlayerLoginEvent event) {
     public void highLogin(PlayerLoginEvent event) {
         // Some code here
         // 你的代码
     }
     }
}</source></blockquote>
}</source></blockquote>


The LoginPlugin would look like this:
现在插件的主类代码应该看起来像这样:
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;


第208行: 第210行:
}</source></blockquote>
}</source></blockquote>


== 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.
无一例外,所有事件都有一个静态方法:getHandlerList(),你可以使用这个方法下面的unregister()方法来对一个插件内所有的这个事件的监听器进行注销
Example:
比如这样搞:
<blockquote><source lang="java">
<blockquote><source lang="java">
PlayerInteractEvent.getHandlerList().unregister(plugin);
PlayerInteractEvent.getHandlerList().unregister(plugin);
// this will unregister all PlayerInteractEvent instances from the plugin
// 这样就代表会注销plugin这个插件内所有监听PlayerInteractEvent这个事件的监听器
// you can also specify a listener class instead of plugin.
// 当然了你也可以单独在plugin那个参数里面写入要注销指定监听器的类
</source></blockquote>
</source></blockquote>
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.
你可以使用HandlerList类下面的unregisterAll()这个静态方法来对一个插件所监听的所有事件的监听器进行注销
Example:
比如下面这样:
<blockquote><source lang="java">
<blockquote><source lang="java">
HandlerList.unregisterAll(plugin);
HandlerList.unregisterAll(plugin);
// this will unregister all events from the specified plugin
// 这将会注销这个插件监听这个事件的所有监听器
// you can also specify a listener class instead of plugin.
// 当然这里的参数也可以用一个指定的监听类来代替,可以单独注销一个监听器
</source></blockquote>
</source></blockquote>


== Creating Custom Events ==
== 创建自定义事件 ==
Creating custom events is very simple, you can use the same system that Bukkit uses without ruining performance.
要创建一个自定义的事件是很简单的,而且不会和Bukkit所自带的事件冲突
 
要创建你的自定义事件,有下面的几点是需要注意的
你的自定义事件的类必须继承Event类,并且必须要有
HandlerList这个静态常量和getHandlers这个方法
所以你的一个基础的自定义事件的类应该看起来像下面这样:


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:


<blockquote><source lang="java">private static final HandlerList handlers = new HandlerList();
<blockquote><source lang="java">private static final HandlerList handlers = new HandlerList();
第244行: 第250行:
     return handlers;
     return handlers;
}</source></blockquote>
}</source></blockquote>
This block of code makes the EventHandlers contained inside your own event, keeping any unrelated events completely separated.
因为为了不和别的事件起冲突,你必须要拥有自己的HandlerList才可以.


=== Custom Event Example ===
=== 自定义事件的一个小例子 ===
The following example shows how easy it is to create your own "CustomEvent."
下面得到代码示范了如何快速简单的创建一个自定义的事件的类:
CustomEvent是类名,可以根据自己的事件类型进行更改
<blockquote><source lang="java">import org.bukkit.event.Event;
<blockquote><source lang="java">import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.HandlerList;
第272行: 第279行:
}</source></blockquote>
}</source></blockquote>


==== 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
你现在可以自如掌握如何创建与触发你的自定义事件了。下面是一个例子:
<blockquote><source lang="java">// Create the event here
<blockquote><source lang="java">// 创建你的自定义事件对象
CustomEvent event = new CustomEvent("Sample Message");
CustomEvent event = new CustomEvent("Sample Message");
// Call the event
// 触发事件
Bukkit.getServer().getPluginManager().callEvent(event);
Bukkit.getServer().getPluginManager().callEvent(event);
// Now you do the event
// 现在来对你的事件做点什么
Bukkit.getServer().broadcastMessage(event.getMessage());</source></blockquote>
Bukkit.getServer().broadcastMessage(event.getMessage());</source></blockquote>


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!
如何来监听一个自定义事件呢? 通常情况下,监听自定义事件与其他普通的事件是一样的!
<blockquote><source lang="java">import org.bukkit.event.Listener;
<blockquote><source lang="java">import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventHandler;
第291行: 第298行:
     @EventHandler
     @EventHandler
     public void normalLogin(CustomEvent event) {
     public void normalLogin(CustomEvent event) {
         // Some code here
         // 你的代码
     }
     }
}</source></blockquote>
}</source></blockquote>


==== 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!
如果你希望你的自定义事件可以被取消,记住,要"implements Cancellable."(实现Cancelled类),就像你去实现Listener类一样,是非常简单的,下面是一个例子:
<blockquote><source lang="java">import org.bukkit.event.Event;
<blockquote><source lang="java">import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.HandlerList;
第331行: 第338行:
}</source></blockquote>
}</source></blockquote>


Afterwards, you would check if a plugin had cancelled the event in your code, before processing normally
之后你需要留意,在做些什么之前,你需要在你的代码中检查是否有插件取消了这个事件。就像这样:
<blockquote><source lang="java">// Create the event here
<blockquote><source lang="java">// 创建一个事件对象
CustomEvent event = new CustomEvent("Sample Message");
CustomEvent event = new CustomEvent("Sample Message");
// Call the event
// 触发事件
Bukkit.getServer().getPluginManager().callEvent(event);
Bukkit.getServer().getPluginManager().callEvent(event);
// Check if the event is not cancelled
// 检查他是不是被取消了
if (!event.isCancelled()) {
if (!event.isCancelled()) {
     // Now you do the event
     // 现在你就可以做些什么了!
     Bukkit.getServer().broadcastMessage(event.getMessage());
     Bukkit.getServer().broadcastMessage(event.getMessage());
}</source></blockquote>
}</source></blockquote>


== Video Tutorial ==
== 视频资料 ==
If you would prefer to watch a video tutorial version of this, please click [http://www.youtube.com/watch?v=PWQNsqwD-AY here].
如果你更希望观看视频版的本教程,请点击 [http://www.youtube.com/watch?v=PWQNsqwD-AY 这里!].


[[Category: 条目原文]] [[分类:开发教程]]
[[Category: 条目原文]] [[分类:开发教程]]

2024年4月1日 (一) 09:14的最新版本

欢迎来到Event API Reference/en的原文存档

本页面作用

  • 翻译者查阅原文
  • 阅读者直接查看(对于开发文档,有些时候查看原文理解更快)
  • 更新姬对照查看是否有内容更新
  • 留作存档

本页面可直接访问,也可从主页面上方点击进入

当原文更新时可编辑此页面并添加{{待翻译}},翻译者请注意在主页面更新对应翻译,切勿直接翻译本页面

欢迎来到Bukkit提供的EventAPI相关教程页

简介

事件 就是你在使用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

"@EventHandler" 是一个注解,用来告诉服务端这是一个监听事件的方法,你只需要把它加在你监听指定事件方法的上面就好,就像下面这样

@EventHandler // EventPriority.NORMAL 是默认的监听级别

这样就告诉了服务端你这个监听事件的方法,优先级是普通的。

当然你也可以自己设置事件监听的优先级比如下面这样:

@EventHandler(priority = EventPriority.HIGHEST) // 将该事件监听的优先级修改到HIGHEST级别
@EventHandler(priority = EventPriority.LOW) // 将该事件的优先级修改到LOW级别

现在呢你的监听事件的方法的代码应该像这样:

@EventHandler
public void onLogin(PlayerLoginEvent event) {
    // Your code here...
}

添加一个监听器

为了监听事件,你必须让监听事件的类实现 Listener (包名是:org.bukkit.event.Listener) 这个接口, e.g.:

public final class MyPlayerListener implements Listener {
    @EventHandler
    public void onLogin(PlayerLoginEvent event) {
        // Your code here...
    }
}

上面那个名字叫onLogin 的监听玩家登录事件的方法现在什么都不能干

就像我说的,Bukkit通过EventHandler注解来知道你这个方法是用来监听事件的,通过方法需要传入的参数知道要监听的是哪个事件,比如: PlayerLoginEvent.

特别提醒:要想监听事件,你还必须得执行一个注册监听事件类的方法才能让插件正常监听事件

你必须在你的插件主类里(也就是那个继承JavaPlugin的类)的onEnable方法里加上如下代码: 其实吧也不是非得在onEnable里面加上,在你需要监听事件的时候保证这个监听事件的类被注册过就行

public class MyPlugin extends JavaPlugin implements Listener {
  @Override
  public void onEnable() {
    getServer().getPluginManager().registerEvents(this, this);
  }

  @EventHandler
  public void onLogin(PlayerLoginEvent event) {
    System.out.println(event.getPlayer().getName()+"登入了服务器");
  }
}

这里我提醒一下各位读者 玩家登录服务器分四个阶段 HandShake(和服务器握手 PreLogin(预登录阶段,就是正在登录 Login(登入阶段,一般盗版服会直接跳过该阶段,但是是可以监听到的 JoinGame(成功登录服务器

EventHandler注解的参数

@EventHandler你可以使用注解来定义事件监听的相关设置

Name Type Default Description Values
priority EventPriority EventPriority.NORMAL 监听事件的优先级
  • EventPriority.MONITOR
  • EventPriority.HIGHEST
  • EventPriority.HIGH
  • EventPriority.NORMAL
  • EventPriority.LOW
  • EventPriority.LOWEST
ignoreCancelled boolean false 如果你把它设置成true,如果事件被取消这个监听的事件将不再会被监听到
  • true
  • false


事件优先级

Bukkit会按照下面的顺序挨个在事件发生时通知监听该事件的插件

  • EventPriority.LOWEST(最优先
  • EventPriority.LOW
  • EventPriority.NORMAL
  • EventPriority.HIGH
  • EventPriority.HIGHEST
  • EventPriority.MONITOR(最后

服务端将会根据这些监听器内EventHandler注解里面的监听优先级按顺序通知监听器,从LOWEST到MONITOR挨个通知插件,你可以通过设置优先级来阻止其他的插件对同等事件进行操作,并在MONITOR优先级的监听器取消后面插件对该事件的监听达到覆盖操作。

注册监听事件的类

要使你插件里包含监听器方法的类被注册,这个监听器才能起效,且包含监听方法的这个类必须实现Listener这个接口

import org.bukkit.event.Listener;

public final class LoginListener implements Listener {
}

你只需要这一行代码来注册监听事件的类

getServer().getPluginManager().registerEvents(Listener, Plugin);

监听事件的例子

这个监听事件的类包含两个监听器,且监听的是同一个事件,但是一个优先级是HIGH一个是默认的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) {
        // 你的代码
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void highLogin(PlayerLoginEvent event) {
        // 你的代码
    }
}

将监听事件的类在你的插件内起效

下面代码示范了如何注册你的监听类

import org.bukkit.plugin.java.JavaPlugin;

public final class LoginPlugin extends JavaPlugin {
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new LoginListener(), this);
    }
}


直接使用插件主类作为监听类

下面的代码示范了如何偷懒直接使用插件主类作为监听类并注册它:

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) {
        // 你的代码
    }
}

用监听类的构造器注册监听类

有很多很多不同的方式来注册你的监听类,下面代码示范了如何使用监听类的构造器来注册监听类

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) {
        // 你的代码
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void highLogin(PlayerLoginEvent event) {
        // 你的代码
    }
}

现在插件的主类代码应该看起来像这样:

import org.bukkit.plugin.java.JavaPlugin;

public final class LoginPlugin extends JavaPlugin {
    public void onEnable() {
        new LoginListener(this);
    }
}

注销你的监听器

前面提到了如何去创建并且注册监听器使之生效,同样的服务端也提供了注销监听器的方法,你可以注销一个插件里所有的监听器,也可以注销一个插件里所有指定事件的监听器

注销一个插件内指定事件的监听器

无一例外,所有事件都有一个静态方法:getHandlerList(),你可以使用这个方法下面的unregister()方法来对一个插件内所有的这个事件的监听器进行注销 比如这样搞:

PlayerInteractEvent.getHandlerList().unregister(plugin);
// 这样就代表会注销plugin这个插件内所有监听PlayerInteractEvent这个事件的监听器
// 当然了你也可以单独在plugin那个参数里面写入要注销指定监听器的类

下面我们将会学习自定义事件

注销一个插件所有的监听器

你可以使用HandlerList类下面的unregisterAll()这个静态方法来对一个插件所监听的所有事件的监听器进行注销 比如下面这样:

HandlerList.unregisterAll(plugin);
// 这将会注销这个插件监听这个事件的所有监听器
// 当然这里的参数也可以用一个指定的监听类来代替,可以单独注销一个监听器

创建自定义事件

要创建一个自定义的事件是很简单的,而且不会和Bukkit所自带的事件冲突

要创建你的自定义事件,有下面的几点是需要注意的 你的自定义事件的类必须继承Event类,并且必须要有 HandlerList这个静态常量和getHandlers这个方法 所以你的一个基础的自定义事件的类应该看起来像下面这样:


private static final HandlerList handlers = new HandlerList();

public HandlerList getHandlers() {
    return handlers;
}

public static HandlerList getHandlerList() {
    return handlers;
}

因为为了不和别的事件起冲突,你必须要拥有自己的HandlerList才可以.

自定义事件的一个小例子

下面得到代码示范了如何快速简单的创建一个自定义的事件的类: 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;
    }
}

触发你的自定义事件

你现在可以自如掌握如何创建与触发你的自定义事件了。下面是一个例子:

// 创建你的自定义事件对象
CustomEvent event = new CustomEvent("Sample Message");
// 触发事件
Bukkit.getServer().getPluginManager().callEvent(event);
// 现在来对你的事件做点什么
Bukkit.getServer().broadcastMessage(event.getMessage());

请您记住:你现在正在控制你的事件,如果你不去触发他,他就没有办法正常工作,什么都不会发生!

监听自定义事件

如何来监听一个自定义事件呢? 通常情况下,监听自定义事件与其他普通的事件是一样的!

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;

public final class CustomListener implements Listener {
    @EventHandler
    public void normalLogin(CustomEvent event) {
        // 你的代码
    }
}

让你的自定义事件可以被取消

如果你希望你的自定义事件可以被取消,记住,要"implements Cancellable."(实现Cancelled类),就像你去实现Listener类一样,是非常简单的,下面是一个例子:

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;
    }
}

之后你需要留意,在做些什么之前,你需要在你的代码中检查是否有插件取消了这个事件。就像这样:

// 创建一个事件对象
CustomEvent event = new CustomEvent("Sample Message");
// 触发事件
Bukkit.getServer().getPluginManager().callEvent(event);
// 检查他是不是被取消了
if (!event.isCancelled()) {
    // 现在你就可以做些什么了!
    Bukkit.getServer().broadcastMessage(event.getMessage());
}

视频资料

如果你更希望观看视频版的本教程,请点击 这里!.