开启辅助访问      

站内搜索

搜索
热搜: 下载 1.19 1.20

Minecraft(我的世界)苦力怕论坛

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

发表于 2020-6-27 22:21:54 | 显示全部楼层 |阅读模式 IP:广东省
本帖最后由 主世界 于 2020-8-14 19:24 编辑

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




监听器

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

  2. import org.bukkit.event.EventHandler;
  3. import org.bukkit.event.Listener;
  4. import org.bukkit.event.player.PlayerLoginEvent;

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

  2. import org.bukkit.Bukkit;
  3. import org.bukkit.event.HandlerList;
  4. import org.bukkit.event.player.PlayerLoginEvent;
  5. import org.bukkit.plugin.java.JavaPlugin;

  6. public final class MyPlugin extends JavaPlugin {

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

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

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

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

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



自制事件

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

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

  4. public final class MyEvent extends Event {
  5.    
  6.     private static final HandlerList handlers = new HandlerList();
  7.     private String var1;
  8.    
  9.     public CustomEvent(String var2) {
  10.         var1 = var2;
  11.     }

  12.     public String getMessage() {
  13.         return var1;
  14.     }

  15.     public HandlerList getHandlers() {
  16.         return handlers;
  17.     }

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

  4.     public void setCancelled(boolean <另一个变量名>) {
  5.         <变量名> = <另一个变量名>;
  6.     }
复制代码

添加如下代码:
  1. // 实例化该可撤销的自定义事件
  2. CustomEvent event = new MyEvent("Sample Message");
  3. // 触发该事件
  4. Bukkit.getServer().getPluginManager().callEvent(event);
  5. // 检测该自定义事件有没有被撤销,若被撤销则运行“下方代码”
  6. if (!event.isCancelled()) {
  7.     // 在这里输入“下方代码”
  8.     Bukkit.getServer().broadcastMessage(event.getMessage());
  9. }
复制代码
一个自制的自定义事件就完整了。
自制事件参考:https://bukkit.gamepedia.com/Configuration_API_Reference

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


作者:主世界.png
苦力怕论坛,感谢有您~
回复

使用道具 举报

发表于 2020-6-29 03:54:35 来自手机 | 显示全部楼层 IP:安徽省
学废了,电脑哪里领{:12_304:}
2# 2020-6-29 03:54:35 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

发表于 2021-8-15 06:33:54 | 显示全部楼层 IP:辽宁省
玩腻了教css和js吧
3# 2021-8-15 06:33:54 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

 楼主| 发表于 2021-8-15 16:35:47 | 显示全部楼层 IP:广东省
lhn254600 发表于 2021-8-15 06:33
玩腻了教css和js吧

css和js跟Minecraft有什么关系???
4# 2021-8-15 16:35:47 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

发表于 2021-12-11 19:28:38 | 显示全部楼层 IP:四川省
下一节去哪了(

5# 2021-12-11 19:28:38 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

发表于 2022-1-30 17:59:38 | 显示全部楼层 IP:广东省
我以前看的教程都是先讲命令执行的
,作者加油qwq
6# 2022-1-30 17:59:38 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

发表于 2022-10-17 18:09:23 | 显示全部楼层 IP:广东省
求求大佬们了
为啥我的照着上面写的,可是getLogger().info("MyPlugin插件已成功加载!");是可以的
然后监听器不行
文件在下面求大佬看看


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


image.png

MyFirstPlugin.zip

15.65 KB, 下载次数: 0

7# 2022-10-17 18:09:23 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

发表于 2022-10-17 20:11:13 | 显示全部楼层 IP:广东省
Dxggu 发表于 2022-10-17 18:09
求求大佬们了
为啥我的照着上面写的,可是getLogger().info("MyPlugin插件已成功加载!");是可以的
然后监 ...

多说明一下啊
使用来测试的服务端是Spigot的1.18.2
使用的Java是17.04的
8# 2022-10-17 20:11:13 回复 收起回复
苦力怕论坛,感谢有您~
回复 支持

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

本站
关于我们
联系我们
坛史纲要
官方
哔哩哔哩
技术博客
下载
网易版
安卓版
JAVA
反馈
意见建议
教程中心
更多
捐助本站
QQ群
QQ群

QQ群

访问手机版

访问手机版

手机版|小黑屋|系统状态|klpbbs.com

粤公网安备 44200002445329号 | 由 木韩网络 提供云服务 | GMT+8, 2024-3-29 18:52

声明:本站与Mojang以及微软公司没有从属关系

Powered by Discuz! X3.4 粤ICP备2023071842号