Hello World! - Nukkit插件从0开始
请认准本教程目录篇永久链接:http://www.cnblogs.com/xtypr/p/nukkit_plugin_start_from_0.html ,未经作者许可转载本系列文章任何内容的,视为已向作者支付50元人民币稿酬。作者支付宝账号:237356812@qq.com。
系列作者:粉鞋大妈 文章出处:http://www.cnblogs.com/xtypr 欢迎转载、翻译、收录,也请保留这段声明,不胜感激。
Nukkit插件从0开始:Hello World!
上一篇:搭建环境 | 目录:Nukkit插件从0开始 | 下一篇:命令与权限 |
这里我们以一个简单的插件作为例子,来讲解一个Nukkit插件的开发过程,和一些基本方法的使用。
无中生有:列出功能列表
插件制作之前,我们应该对插件的功能有一个规划。以下是我个人的一些经验和看法,大家可以保持自己的看法。
- 插件作为一个程序,应该有自己实现的功能,如果能在开发前列举这些功能,对开发的速度会有提升,也让你不至于写到一半没了思路。
- 我们列出功能列表的时候,首先要明确这个插件的用途,比如一个pvp小游戏,或者一个锁箱子工具。“一个奇怪的插件”或者“一个游乐园插件”这样的用途不够明确,容易让人产生误解,就算提出功能列表的人和开发者是同一个人。而“一个不用电脑就能开服的插件”或“一个vps到期还能开服的插件”这样几乎不可能实现的东西,就不要尝试去想了,以免浪费青春。
- 现在你明确了这个插件的用途,不过不要急着开始做,你应该先通过论坛、搜索引擎、插件站等各种途径寻找是否有人做过这个用途的插件。如果你的想法相对别人有改进,比如别人的锁箱子插件需要输入指令而你的直接用牌子点击箱子是个很好的优化,你可以试着做自己的插件。如果你的想法没有改进,别人的插件可能比你经历过更长的时间和更多服务器的考验,拥有更少的bug,除非你对这个想法相比别人的有一些改进,不然还是用别人的插件吧,除非是为了学习,不要试着去做/模仿别人做过的东西。
- 如果你如此的有想象力,以至于想出了前无古人的插件点子,恭喜你可以开始细化功能了。细化功能就是把你粗略的插件点子,细化成有哪些主要的操作,再到需要哪些指令和权限。我们来一个头脑风暴,我要设计一个牌子锁箱子工具,该有哪些功能?你可以监听方块被点击的事件,先检查这个方块是不是箱子,再检查这个箱子是不是被别人锁了,再检查你手里是不是拿着牌子,然后就把箱子登记到被锁箱子列表;你一想觉得需要op可以查看所有玩家箱子,又可以添加这个功能;再一想还需要几个玩家共享箱子,还可以加付费锁箱子……哎哟妈呀,功能太多了,一想真停不下来。这时候你可以把细化的功能写到纸上或者干脆记在脑子里,以后做插件的时候就能明确思路了。
- 现在你得到了插件的很多功能,你需要将它们分类。对于一个插件来说,有一些功能是其它功能所依赖/需要的,有一些功能是可开启可关闭或者不影响其它功能使用的,这时候我们需要给这些功能归到一类。那些被其它功能依赖性最强的功能,需要我们优先制作;一些不知道该不该添加的功能,我们可以丢到配置文件让插件的使用者来决定。我们回到锁箱子插件,这个插件有基本的锁箱子功能、op看箱子功能、共享箱子功能,其中后两者需要锁箱子功能的支持,这时候我们需要先制作基本的锁箱子功能,共享箱子放在以后或者以后的插件版本制作,而op看箱子这个功能实在不知道该不该有,我们制作的时候就可以在配置文件里加一行,让腐竹/插件使用者来配置。
我们得到了详细的、分了类的功能,现在可以开始制作了。如果不知道一些功能能不能、该不该实现,可以在以后的学习中慢慢体会。
这里我以使用IDEA制作一个简单的插件为例子,它的功能只有一个:在自己加载和卸载的时候在控制台输出文字。够简单,是不是?我们开始吧。
版*权*声*明**本文*章欢迎转*载 收*录 翻*译 请认*准本教*程目*录*篇永*久*链*接:http://www.cnblogs.com/xtypr/p/nukkit_plugin_start_from_0.html 除该链*接*以外刊*登此文*章的链*接均不*是作*者所撰*写 不*能保*证内*容的最*新性和可*靠性 特*此*声*明 本*段是为防恶*意网*站爬*虫的抄*袭或复*制粘*贴式抄*袭而特*意撰*写 搬*运者和翻*译*者可*以不把这*段搬*运或翻*译
实现愿望:你的第一个插件
创建Java包
首先打开IDEA,IDEA默认打开我们已经配置环境好的插件工程。右键侧边栏的“src”文件夹,点击“New”->“Package”,在弹出的“New Package”中填你的插件应该存放的java包名。这里可以根据java包名的命名习惯,全部使用小写字母开头,前面把你的域名倒过来写,后面跟上后面产品的名字,你可以不参照这个习惯自己写,但是不能和别人的一样,因为java包名的前缀用于区分不同的作者。这里我用了com.cnblogs.xtypr.helloworldplugin,你应该自己定插件的包名。以下几个包名都是可以的:
- com.cnblogs.xtypr.helloworldplugin
- xtypr.helloworldplugin
- net.xtypr.helloworldplugin
另外注意,不要作死的把插件放进cn.nukkit这个包,笔者已为自己的好奇心付出惨痛的代价!
创建好包之后,我们还需要在里面添加主类。
添加和编写主类
右键刚刚创建的包,选择“New”->“Java Class”,在弹出窗口的Name后面写上自己插件的主类的名字,习惯上使用大写开头。个人不提倡用Main或者MainClass这样的名字,因为这会导致不同插件的主类难以区分。另外注意的是,不能用带“nukkit”“minecraft”“mojang”之类的字符串作为插件的名字。插件的运行都是从主类的方法开始的。点击“OK”,完成创建。
主类创建完毕后,IDEA会帮你打开主类的编辑器,这时候你会看到这样的代码(中间IDEA会给你自动创建一个注释,为了节省篇幅我删除了):
package com.cnblogs.xtypr.helloworldplugin; public class HelloWorldPlugin{ }
Nukkit插件必须继承一个叫PluginBase的父类,这个类被存放在cn.nukkit.plugin包内,我们需要让插件继承这个类,于是你的代码变成了这个样子:
package com.cnblogs.xtypr.helloworldplugin; import cn.nukkit.plugin.PluginBase; public class HelloWorldPlugin extends PluginBase{
}
一个Nukkit插件应该有加载、启用和停用这几个方法,这几个方法应该重写PluginBase里的某些方法。让我们看看PluginBase类:
package cn.nukkit.plugin; /* 此处略去若干代码 */ /** * author: MagicDroidX * Nukkit Project */ abstract public class PluginBase implements Plugin { /* 此处略去若干代码 */ public void onLoad() { } public void onEnable() { } public void onDisable() { } /* 此处略去若干代码 */ }
我们发现里面有onLoad(),onEnable()和onDisable()这几个方法。文.章出.自:http://cnblogs.com/xtypr/
- onLoad()。Nukkit服务器在开启的时候,会调用所有插件的onLoad()方法(至于在地图加载前还是后调用我们等一下会讲到),而且服务器开启到停止只会调用一次。我们需要把一些预处理代码放进去,比如检查和创建默认配置文件、初始化数组变量等等。
- onEnale()。所有的onLoad()调用完成后,Nukkit服务器会调用所有的onEnable(),onEnable()方法可能被调用多次(尤其是有插件管理器插件的时候)。我们应该把读取配置文件,连接数据库这样在启动后可能需要停用的方法放在这里。
- onDisbale()。Nukkit服务器关闭,或者一个插件onLoad()或onEnable()时发生问题,会调用插件的onDisable()方法。同onEnable(),onDisable()也可能被调用多次。我们应该把关闭数据库,关闭I/O数据流这样的东西放在这里。由于服务器过卡导致关闭时间太长,Nukkit会直接调用系统杀死自己,而导致一些插件的onDisable()不会被执行,所以我们在插件使用的过程中应该随时保存数据,尽量不要把I/O操作和保存数据部分放在onDisable(),以免意外发生。
这几个方法调用之前,服务器都会在控制台输出类似这样的信息(其中SuchAPlugin是插件名,2.3.3插件是版本号):
13:52:10 [INFO] Loading SuchAPlugin v2.3.3
继承这几个方法后,你的代码应该是这样的:
package com.cnblogs.xtypr.helloworldplugin; import cn.nukkit.plugin.PluginBase; public class HelloWorldPlugin extends PluginBase{ @Override public void onLoad() { } @Override public void onEnable() { } @Override public void onDisable() { } }
接下来我们在方法中添加代码,这个插件的功能很简单,所以我在三个方法中直接添加在控制台打印文字的代码就可以了。
package com.cnblogs.xtypr.helloworldplugin; import cn.nukkit.plugin.PluginBase; public class HelloWorldPlugin extends PluginBase{ @Override public void onLoad() { getLogger().info("Hello Nukkit,I've loaded!"); } @Override public void onEnable() { getLogger().info("Hello Nukkit,I've enabled!"); } @Override public void onDisable() { getLogger().info("Hello Nukkit,I've disabled!"); } }
这里简单介绍一下logger。Nukkit服务器的控制台有很多消息,这些消息都是Logger输出的。所有插件主类的父类PluginBase提供了getLogger()函数,返回当前服务器使用的Logger对象,并转换成PluginLogger对象。当你在插件主类调用
getLogger().info("MDX与Nukkit大法!");
getLogger().warning("狸猫不吃鱼!");
的时候,控制台会输出类似这样的文字(其中NukkitDaFa是插件名):
13:57:38 [INFO] [NukkitDaFa] MDX与Nukkit大法!
13:57:38 [WARNING] [NukkitDaFa] 狸猫不吃鱼!
关于Logger的详细介绍可以参阅本系列教程的番外篇。
使用ctrl+s保存编辑好的主类文件。
为了让Nukkit正常识别,我们还需要添加plugin.yml。
添加和配置plugin.yml
打开侧边栏里我们以前创建的“plugin.yml”文件,在编辑框编写内容。plugin.yml文件需要符合Nukkit规定的格式,下面是一个简单的plugin.yml:
name: HelloWorldPlugin
main: com.cnblogs.xtypr.helloworldplugin.HelloWorldPlugin
version: "1.0.0"
api: ["1.0.0"]
load: POSTWORLD
author: 粉鞋大妈
description: 这是一个简单的Hello World
website: http://www.cnblogs.com/xtypr
#commands: []
#permissions: []
我来逐一解释这个文件的结构。标注必需的,说明这些选项必需要填,剩下的如果用不到可以省略用默认值。
- name必需,你应该填插件的名字,这个在Logger和其他东西里会用到,再次强调名字不能带“nukkit”“minecraft”“mojang”这几个词语。
- main必需,是这个插件的主类,必须填刚才创建的插件主类的完整路径(感谢@Lyw指出),这个将用于nukkit服务器加载你的插件。
- version必需,是这个插件的版本,这里注意如果是数字版本(比如“103”或“1.1.0”)需要加上双引号,这样yaml才能把这里识别成字符串,下面的api版本同理。
- api必需,是这个插件支持的Nukkit API版本,这里注意是一个数组,如果支持多个api版本应该使用 ["1.0.0","1.0.1","1.0.2"] 这样的数组。编译和发布插件前,你需要对尽可能多的api版本进行测试,如果稳定说明你的插件支持这个api版本,那你应该把这个api版本加入这个数组。
- load是插件加载的次序,在Nukkit API 1.0.0中可选择STARTUP或POSTWORLD,STARTUP意味着插件在服务器开启时优先加载,POSTWORLD说明插件会在第一个世界(默认的世界)加载后再加载。有些需要依赖地图的插件,可以选择POSTWORLD。
- author description website这三个,是用于识别你的版权,让其它开发者/插件能识别你。
至于commands和permissions,我们会在后面的内容详细讲解。
关于plugin.yml的详细介绍可以参阅本系列教程的番外篇。
填写plugin.yml后,使用ctrl+s保存文件。现在我们可以调试插件了。
调试插件
点击“Run”->“Debug 'HelloWorldPlugin'”,IDEA会自动编译并开启调试。由于我们已经配置了环境,调试前会自动编译并值nukkit文件夹的plugins里面生成插件的jar包。笔者个人习惯使用shift+F9快捷键开启调试。点击后,我们看到下面出来了一个调试栏,那里是控制台的输出。在调试时,我们应该测试插件的所有功能,并试着在不同的环境中寻找插件的bug,调试失败出exception不要紧,修复了bug之后你的插件会稳定下来,直到可以投入使用。文章出自:http://www.cnblogs.com/xtypr/
从输出我们可以看到,我们的插件已经正常运行,而且输出了我们设置的字符串,功能完美实现无bug(噗)。
调试完毕后,我们发现插件已经可以投入使用了,这时候我们应该把插件打包和发布。
诞生:打包与发布
如果整个插件调试无误了,我们可以打包插件然后发布给别人。
点击菜单栏的“Build”->“Make Project”来编译整个工程。打开jar包,能看到我们的plugin.yml和编译生成的.class文件已经被IDEA打包进jar,所以可以被nukkit正常识别。
你得到了能在任何一台相应版本的nukkit服务器上使用的HelloWorldPlugin.jar。你可以重命名这个jar包的名字(比如HelloWorld_1.0.0.jar)且不影响使用。
现在你可以把jar包发布了。你可以把jar包在贴吧或者论坛上发布,或者丢给需要的腐竹。作为一个合格的插件开发者,你需要从插件使用者获取你未发现的bug,你也可以在新的版本的插件中添加新的功能。一个插件的开发过程应该是永远不会结束的,你可能想不到,你的插件会被一代又一代的腐竹使用,被一代又一代的开发者稳定和完善。你的插件如果唱响大江南北,那将会成为其它插件开发者制作新玩意的动力,也会吸引更多人加入nukkit插件开发的领(tian)域(keng),而你作为开发者也会被腐竹们当大神一样膜拜,被全宇宙的nukkit开发者传唱。
我们制作的第一个nukkit插件,只有在控制台输出文本的简单功能,在以后的章节中我们将会学习更多的有趣的玩法。
上一篇:搭建环境 | 目录:Nukkit插件从0开始 | 下一篇:命令与权限 |