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

Event API Reference/en:修订间差异

来自Minecraft插件百科
跳转到导航 跳转到搜索
第302行: 第302行:
}</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;
第338行: 第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>

2017年8月1日 (二) 10:40的版本

欢迎来到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());
}

Video Tutorial

If you would prefer to watch a video tutorial version of this, please click here.