7.7 KiB
第一部分 第二章 插件要素
参与编写者: MagicLu550
建议学习时间: 50分钟
学习要点: 了解nukkit的项目结构,认识一些普通组件的定义和注册
插件要素这章会概括性的介绍nukkit的一些主要组件,后面的章节将会对他们系统的介绍。
所有的插件式编程都有它的一套运行标准,如maven插件,PocketMine插件,以及我们的nukkit插件等。
我称插件的规则元素为一个插件的要素,主要是运行的主类所依托的父类或一个动作所依托的父类(PluginBase等),它 用于对服务器阅读的参数表(如web.xml,plugin.yml等),以及执行一系列动作的附件(如监听器,Servlet,过滤器,命令等)
nukkit的插件以PluginBase的代表,以plugin.yml为运行依据,以监听器等附件为动作,这些动作基于在PluginBase里 注册,所以nukkit的结构主要为这些
1. plugin.yml [必须有]
2. 继承于PluginBase的主类 [必须有]
3. Listener(监听器),Command(命令),Timer(计时器)
nukkit允许主类和监听器重叠,当我们制作简单的插件,为避免复杂,可以一个类担当主类和监听器的角色 并且我们也可以使用简单的方式来执行我们的命令。复杂项目中,我们不建议这么做
- 注册一个监听器
package net.noyark.www;
import cn.nukkit.event.Listener;
import cn.nukkit.plugin.PluginBase;
/**
* 实现一个Listener代表了一个监听器,注册时,监听器才真正生效
* 另外,Listener是一个接口,我们需要实现(implements)它
*/
public class Example extends PluginBase implements Listener {
@Override
public void onEnable() {
//插件的管理由PluginManager实现,后期会讲解这个组件
//listener为一个监听器对象,这里我们将服务器事先生成的主类对象传入
//若要调用服务器生成的PluginBase对象,我们必须要传入this而不是再new一个
//当然,注册监听器时您可以再new一个,但是不建议这么做
//第二个plugin对象是主类对象,这个必须要传入this的
//可能有人疑惑,那在其他类里该怎么调用之前生成的对象呢?这个疑惑将会在接下来代码实现
this.getServer().getPluginManager().registerEvents(this,this);
}
}
如果跨类如何做这件事?
我们这里定义了一个Example类和一个OtherListener类。
OtherListener实现了Listener接口。
如图所示实现了跨类的注册
那么如何实现在监听器使用实现注册好的主类对象?
下面代码解决了这个问题,要注意,plugin = this这段代码
要定义在监听器对象被定义之前,这样定义一个getPlugin方法就可以在监听器获取到了
package net.noyark.www;
import cn.nukkit.plugin.PluginBase;
public class Example extends PluginBase{
private static Example plugin;
@Override
public void onEnable() {
plugin = this;
this.getServer().getPluginManager().registerEvents(new OtherListener(),this);
}
public static Example getPlugin() {
return plugin;
}
}
在监听器中调用
package net.noyark.www;
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.Listener;
import cn.nukkit.event.player.PlayerJoinEvent;
public class OtherListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e){
Example.getPlugin().getServer();
}
}
监听器具体内容将在后面讲解
- 注册一个命令 其实注册个命令就很简单,如何跨类等等和上面基本一样,但是主类是不能注册一个命令对象的 (因为命令是继承Command对象) 但是也有简便的方法
第一种: [1]
package net.noyark.www;
import cn.nukkit.command.Command;
import cn.nukkit.command.CommandSender;
import cn.nukkit.plugin.PluginBase;
public class Example extends PluginBase{
private static Example plugin;
@Override
public void onEnable() {
plugin = this;
this.getServer().getPluginManager().registerEvents(new OtherListener(),this);
}
public static Example getPlugin() {
return plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
//这里返回true代表执行成功,false则不成功
//sender 是发送命令的对象
//command 命令对象
// [1]
//label 是标签,如果注册命令时label为null,就会默认为命令名,label的组成是fallBackPrefix+:+label
//label这个地方其实也不是很懂。一般注册时都是""或者null
//通过源码推测label和fallBackPrefix的组合是命令的唯一标识
//
//args 命令参数,比如/hello 1 2的参数为1和2,存储在数组中
//这里使用命令通过equals
//如何得到指令名称个人习惯原因
if("hello".equals(command.getName())){
//执行相关操作
return true;//最好加上
}
//这种方式虽然方便,但是命令多,且命令功能复杂时会难以维护
//少部分命令可以使用它
return true;
}
}
当然第一种方式,命令要真正被监听,我们还要在plugin.yml里声明
permissions: #这个标签我们只写一次就ok了
plugin.hello:
description: 你好
default: op #权限组,后期会讲到
commands: #这个标签我们只写一次就ok了
hello:
description: 你好
usage: "/hello"
permission: plugin.hello
第二种是创建命令类 这个其实不用多说,和前面一样使用
package net.noyark.www;
import cn.nukkit.command.Command;
import cn.nukkit.command.CommandSender;
public class MyCommand extends Command {
//hello为指令名字,后面description是它的介绍,其他功能将后期讲解
public MyCommand() {
super("hello","一个测试指令");
}
@Override
public boolean execute(CommandSender commandSender, String label, String[] strings) {
return true;
}
}
注册很简单,第一个参数后面会讲解
package net.noyark.www;
import cn.nukkit.plugin.PluginBase;
public class Example extends PluginBase{
@Override
public void onEnable() {
this.getServer().getCommandMap().register("",new MyCommand());
}
}
3.计时器部分我们将在后面讲解,它的体系较复杂一些
计时器主要形同java的Runnable,线程池等等,他们本质也是实现多线程。 也是开发者使用最广泛的一类组件。
-
如何写plugin.yml plugin.yml第一章提到过,plugin.yml最主要的是
name: FirstPlugin main: net.noyark.www.Example version: "0.0.1" author: myName api: ["1.0.8"] description: My first plugin
snake1999曾说: 缺少他们的插件是不被nukkit运行的。 这些都是不能缺少的,在接下来章节中,将会系统的介绍里面常用的标签 目前从现在的维护者知悉,api写什么其实并不重要,因为nukkit向下兼容,不像 pocketMine一样变动很大,nukkit会淘汰掉过时的函数,不会删除,因此 可以保证老插件运行,但值得注意的是,不代表淘汰函数会完美运行,能 运行插件不代表不会出现bug,但这也是相对pocketMine最方便的优势了。