帐号不存在 发表于 2020-6-27 22:21:54

【原创】Bukkit插件开发教程 —— 第三节 监听器

本帖最后由 主世界 于 2020-8-14 19:24 编辑




Bukkit 插件开发 入门教程第三节 监听器




https://s1.ax1x.com/2020/06/27/NcnTRs.png

监听器

在一切就绪之后,我们终于可以开始写代码了!不过,接下来,基本没图片了!你将看到的是大段的文字和长串的代码。
监听器相当于一个检测装置,能检测服务器及服务器中玩家的一举一动,就像侦测器(Observer)能检测自己面前方块的变动一样。
要使一个监听器能够运行,我们需要在项目中新建一个类、注册EventHandler并让它实现Listener接口。这突然冒出了一堆概念,是不是让你不知所措?下面,让我们一起来写一个监听器,并更好地理解监听器的写法吧!
Bukkit中所有已制作好的事件大全(第一个是Bukkit官方网站,第二个是第三方搭建网站,第二个便于国内访问):

[*]https://hub.spigotmc.org/javadocs/bukkit
[*]https://bukkit.windit.net/javadoc
现在,我们来通过监听器实现一个“当玩家进入服务器时,玩家自动执行/help命令”的功能吧。
OnJoin类(类名随意):
package com.gmail.zhushijie.myplugin;

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

public class onLogin implements Listener {
    @EventHandler
    public void OnPlayerJoin(PlayerLoginEvent event){
      Player player = event.getPlayer();
      player.chat("/help");
    }
}“player.chat("/help");”是玩家向聊天栏中发送信息,若前面不带反斜杠则玩家就是在聊天。该语句还可以用玩家执行指令的代码来替代:player.performCommand("help");注意这样指令前面就不能带反斜杠了哦。
插件主类:package com.gmail.zhushijie.myplugin;

import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;

public final class MyPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
      // Plugin startup logic
      Bukkit.getServer().getPluginManager().registerEvents(new onLogin(),this);
    }

    @Override
    public void onDisable() {
      // Plugin shutdown logic
      PlayerLoginEvent.getHandlerList().unregister(this);
    }
}一个监听器就这么完成并在插件启用时注册了。
监听器类的万能模板(“<>”中的是可改变的内容):package <包名>;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import <相应的包>;

public class <监听器类名> implements Listener {
    @EventHandler
    public void <方法名称随便取>(PlayerLoginEvent <可不写,随便取>){
      <你的代码>
    }
}其中,“<可不写,随便取>”若方法中用不到就可以省略,省略时写作public void <方法名称随便取>(PlayerLoginEvent)若方法中有语句要用整个方法来执行,则用得到。用得到的时候需要上下一致,就像上面我们写的public void OnPlayerJoin(PlayerLoginEvent event){
      Player player = event.getPlayer();一样,这里上下两个event是一致的。
上面主类OnEnable中的Bukkit.getServer().getPluginManager().registerEvents(new onLogin(),this);就是注册了我们这个onLogin监听器类,而OnDisable中的PlayerLoginEvent.getHandlerList().unregister(this);是注销了onLogin监听器类,其实可以不写,但为了安全,个人建议还是写上。
必须注册监听器。否则该监听器只是个摆设,无实际作用,也不会运行。
在注销的时候监听器太多,一个个注销很麻烦怎么办?这里有个“偷懒”的方法,即一条语句注销插件中的所有监听器:      HandlerList.unregisterAll(this);这样就不用一个个地去注销了。注意,注册监听器的时候不能这么干!因为插件根本不知道你有几个监听器,也不知道你要在什么时候、什么情况下注册监听器。
“@EventHandler”是优先级的批注,可将其改变为以下的任意一个代码来改变其之下的监听器的优先级://优先级从高到低排序
@EventHandler(priority = EventPriority.MONITOR)
@EventHandler(priority = EventPriority.HIGHEST)
@EventHandler(priority = EventPriority.HIGH)
@EventHandler(priority = EventPriority.NORMAL)
@EventHandler(priority = EventPriority.LOW)
@EventHandler(priority = EventPriority.LOWEST)

//若此处设为true,则事件被其它监听器关闭时,当前的监听器也停止监听该事件
@EventHandler(ignoreCancelled = boolean.true)
@EventHandler(ignoreCancelled = boolean.false)

自制事件

Bukkit中的事件虽然很多,但远远不只这些。除了Bukkit已经为我们制作好的事件外,你还可以加入一个属性(private static final)private static final HandlerList handlers = new HandlerList();一个动态方法public HandlerList getHandlers() {
    return handlers;
}和一个静态(static)方法public static HandlerList getHandlerList() {
    return handlers;
}来创建属于自己的事件(要新建一个类,名字随意),如下创建了一个名为“MyEvent”的事件:package <包名>;

import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;

public final class MyEvent extends Event {
   
    private static final HandlerList handlers = new HandlerList();
    private String var1;
   
    public CustomEvent(String var2) {
      var1 = var2;
    }

    public String getMessage() {
      return var1;
    }

    public HandlerList getHandlers() {
      return handlers;
    }

    public static HandlerList getHandlerList() {
      return handlers;
    }
}一定要导入org.bukkit.event.HandlerList,不要忘记了。
MyEvent事件创建好之后,我们要触发这个事件,如果不触发,就跟我们没在插件启用时注册事件一样无实际意义:// 实例化该自定义事件
MyEvent event = new MyEvent("Sample Message");
// 触发该事件
Bukkit.getServer().getPluginManager().callEvent(event);
// 继续执行事件中的内容
Bukkit.getServer().broadcastMessage(event.getMessage());写完上面两段代码后,一个自制的自定义事件就创建好了。接下来,跟对待Bukkit为我们制作好的事件一样去对待它就可以了。
下面还有什么呢?Bukkit中一般的事件都具有“撤销性”,例如玩家破坏了个方块,而破坏方块是个事件,我们可以撤销这个事件,使这个方块复原。
创建一个boolean(只有true和false这两个值的)变量:    private boolean <变量名>;接着,在之前    public String getMessage() {
      return var1;
    }的后面添加如下代码:    public boolean isCancelled() {
      return <变量名>;
    }

    public void setCancelled(boolean <另一个变量名>) {
      <变量名> = <另一个变量名>;
    }
添加如下代码:// 实例化该可撤销的自定义事件
CustomEvent event = new MyEvent("Sample Message");
// 触发该事件
Bukkit.getServer().getPluginManager().callEvent(event);
// 检测该自定义事件有没有被撤销,若被撤销则运行“下方代码”
if (!event.isCancelled()) {
    // 在这里输入“下方代码”
    Bukkit.getServer().broadcastMessage(event.getMessage());
}一个自制的自定义事件就完整了。
自制事件参考:https://bukkit.gamepedia.com/Configuration_API_Reference

花费好大精力和时间才写完这一节,欢迎在下方回复和提问问题哦~
教程纯手写,若有错误欢迎批评指正!
本帖未经作者允许严禁转载!





上一节返回目录下一节


哈哈哈哈yuyutu 发表于 2020-6-29 03:54:35

学废了,电脑哪里领{:12_304:}

小尽喵~ 发表于 2021-8-15 06:33:54

玩腻了教css和js吧

帐号不存在 发表于 2021-8-15 16:35:47

lhn254600 发表于 2021-8-15 06:33
玩腻了教css和js吧

css和js跟Minecraft有什么关系???

HaPi_r 发表于 2021-12-11 19:28:38

下一节去哪了(

饭团团 发表于 2022-1-30 17:59:38

我以前看的教程都是先讲命令执行的
,作者加油qwq

Dxggu 发表于 2022-10-17 18:09:23

求求大佬们了
为啥我的照着上面写的,可是getLogger().info("MyPlugin插件已成功加载!");是可以的
然后监听器不行
文件在下面求大佬看看


只有在\MyFirstPlugin\src\main\java\myfirstplugin\myfirstplugin下的才是源码
JDK版本17.04
SDK选择17.04
插件版本选择Bukkit,版本1.15.2
求求了


3614611048

Dxggu 发表于 2022-10-17 20:11:13

Dxggu 发表于 2022-10-17 18:09
求求大佬们了
为啥我的照着上面写的,可是getLogger().info("MyPlugin插件已成功加载!");是可以的
然后监 ...

多说明一下啊
使用来测试的服务端是Spigot的1.18.2
使用的Java是17.04的
页: [1]
查看完整版本: 【原创】Bukkit插件开发教程 —— 第三节 监听器