1-3 程序的入口点
上一节中介绍了 plugin.yml,那算是插件的『简历』。但是光有简历可不够,一个插件要能够做些有意义的事情,就必须有点『真才实学』 —— 有可执行的代码才行!YAML 不过是用于表示数据(确切说是一张或多张表)的形式之一,它能描述『是什么』,却不能够描述『做什么』。能做到后者的,正是我们的 Kotlin,这些代码是真正在服务器上执行的代码。
这一节会使用到一些 Kotlin 语言知识,所以可能看上去比较难懂。不过,你并不需要现在就打开搜索引擎查找『Kotlin 从入门到放弃』之类的内容(笑)。实际上,即使完全无法理解这些代码也不要紧,只需要跟着复制粘贴代码就好。在下一章中我们会详细地介绍 Kotlin 代码的写法。
开始了。
打开 src/main/kotlin/Main.kt,这是项目中目前唯一的代码文件。
在 IDEA 中,Kotlin 代码的扩展名默认是隐藏的,因此展开 src/main/kotlin 后你可能只会看到 Main 而不是 Main.kt,双击打开 Main 即可。
它的内容如下:
class Main : org.bukkit.plugin.java.JavaPlugin() {
}
在这里我们使用 class Main 定义了一个类(Class)。这个词是什么意思?可以把它理解为『图纸』、『投影』或者『框架』,也就是说,我们在这里画了一张名为 Main 的图纸,不过是用代码而已。
Main 后面跟随的 : 代表继承(Inheritance),也就是『把后面的东西复制过来』的意思。这就是在说,把 org.bukkit.plugin.java.JavaPlugin 这张『图纸』的所有东西,复制给我们的 Main。org.bukkit.plugin.java.JavaPlugin 包含了一个 Bukkit 插件所需要的基础代码。所以,其实我们的第一个插件所做的事情,不过就是把 Bukkit 提供给我们的模板复制一份,改名叫做 Main,然后包装成所谓的插件,交给了 Paper 而已。这听上去有种『转载投自制』的味道,不过这是必要的步骤,正义感很强的读者请忍耐一下吧(笑)。
剩下的部分,包括 () 以及分成两行写的 {},都是固定写法,暂且这么记住就行。要注意的是,{} 中的内容(目前还是空的)将构成『图纸』 Main 的内容,因此后续的插件启动之类的代码需要写在这里。
对了,顺便一提,这张『图纸』的名字 Main,正是 plugin.yml 中 main: Main 的来源。一个插件中可能有非常多的类用来做各种各样的事情,所以我们必须告诉 Bukkit(和 Paper):Main 才是插件真正的入口点。
增加一点内容
只是复制粘贴别人的东西可没什么意思!所以我们现在来添加点代码,将 Main.kt 修改成这样:
class Main : org.bukkit.plugin.java.JavaPlugin() {
override fun onEnable() {
// 要做之事
}
}
以 // 标注的行是注释(Comment),它们是便于开发者描述代码的,会被 Kotlin 编译器忽略。因此,如果你不是复制粘贴而是手动键入代码,那么就不需要辛辛苦苦地切换到中文输入法再键入 // 要做之事 这部分了。
这里 override fun onEnable 是什么意思?override 的意思是『替换』,fun 是函数(Function),也称方法(Method),通俗来说就是『行为』,而 onEnable 则是 Bukkit 定义的名字,代表『插件启用的时候』。因此,新添加的内容就是替换插件启用时的行为,再白话一点来说,就是『当插件启动时,做这件事』的意思。
『好吧,但是程序不应该是从 main 函数之类的地方开始的吗?』有这种想法,说明你肯定曾经是个 C 语言或者 Java 开发者。不过 Bukkit 插件并不是独立运行的程序(和你电脑上的那些 .exe 不一样),插件只有在服务器启动后才有意义,你不能直接执行一个插件,这件事需要由 Bukkit 来完成。Bukkit 会在服务器启动后的某个时刻启用我们的插件,它会执行 onEnable 中定义的行为。
所以总的来说,只要向 onEnable 中添加内容(即在 {} 中添加代码),它们就会在插件启用时被执行。
这件事很重要,你可能会想在浏览器的这一页加个书签,以便随时回来查阅。
自动关服器(初级)
下面就来添加一个真正有用的功能吧!我们来让服务器启动时自动关闭(笑)。向 onEnable 中添加如下代码:
server.shutdown()
最终的代码会变成这样:
class Main : org.bukkit.plugin.java.JavaPlugin() {
override fun onEnable() {
server.shutdown()
}
}
不像 YAML,Kotlin 并不严格要求缩进,这段代码中每一行都可以顶着编辑器左侧写,只是那样会很难看。
如果你不手动缩进代码,代码可能会变成这样:
class Main : org.bukkit.plugin.java.JavaPlugin() {
override fun onEnable() {
server.shutdown()
}
}这看上去不美观,读起来也费劲,你可以按下键盘上的 Ctrl + Alt + L,IDEA 会把代码排列得好看一些。
这就 OK 了!构建插件,然后把它复制到 plugins 文件夹中,启动服务器,你会发现服务器在启动一小会后就会自动关闭,完全没办法正常运行。很不错吧?话说,明明是软件不能正常运行,大家还开心得不得了,真是一群奇怪的人(笑)。
关闭服务器的核心代码就是 server.shutdown(),语法什么的暂且放在一边,这行代码的含义很好理解:
server就是指服务器。.shutdown()就是指关闭。
如果用你熟悉的 Minecraft 命令来写,大概就是:
/server shutdown
是不是一下就看懂了呢?
这行代码写在 onEnable 中,前面已经提到,onEnable 中的内容会在插件被启用时执行,而 Bukkit 会在服务器的一些准备工作做完后就开始启用插件,它一启用我们的插件,我们就将服务器关掉,于是服务器开启后,过不了多久就会被我们的插件直接关闭,很简单对不对?
到目前为止,你的第一个插件就算完成了!我们没花多少功夫就做出来了一个插件,而且还不是那种什么也不做,或者只能在日志里简单留下几行字的插件,它真的能关闭服务器呢(笑)!你可以把构建出来的 .jar 文件拿去『祸害』一下朋友的服务器,不过切记不要在任何正式的服务器上这么做,可能会损坏数据。
现在来看看我们前面所做的事情:
- 为了管理项目文件,需要用 IDEA 创建新项目。
- 创建
plugin.yml描述插件信息,它是 YAML 格式,其实就是一张表。 - 创建
Main.kt包含插件要做事情的的 Kotlin 代码,其中onEnable中的内容会在插件启用时执行。 - 要把源代码转换成
.jar文件,需要使用 IDEA 中的 Gradle 面板和jar任务。 - 把插件从
build/libs复制到服务器的plugins目录下,重启服务器,插件才能生效。
我们没有用什么深奥的概念或者复杂的技术就搞定了这么多东西!都说万事开头难,相信大家在制作了第一个有实际功能的插件之后,能够打消对插件开发未知的恐惧或者担忧,转而开始享受创造的乐趣。那么,我们在下一章再见了!