Minecraft(我的世界)中文论坛

标题: [原创][工具]NukkitScript —— 使用脚本编写Nukkit插件 [全版本]

作者: xiaolu550    时间: 2020-2-21 20:44
标题: [原创][工具]NukkitScript —— 使用脚本编写Nukkit插件 [全版本]
本帖最后由 xiaolu550 于 2020-2-25 21:07 编辑

NKScript - 简化Nk插件的开发模式,使用脚本化编程,无需编译直接运行

NKScript 脚本化编程方案
NKScript的目的是以简化开发为主,并且更好的调试插件。

对于项目结构和调用文件
NKScript主要分为5个模块
  • info.ns
  • main.ns
  • listener
  • command
  • other
info.ns类似于nukkit的plugin.yml,其内容和plugin.yml也基本类似。 其中特殊的元素为id元素,是为了防止多个插件冲突而设计的,它会作为注册文件的类根目录。 在调用脚本时,格式就是id.脚本文件名称 例如id为net.noyark,则脚本hello.ns写作
  1. class hello{
  2.     ///...
  3. }
复制代码

调用的时候
  1. import net.noyark.hello
复制代码

当然在写主类和监听器的时候,packageclass可以省略 如main.ns
  1. @Override
  2. void onLoad(){
  3.     //...
  4. }
复制代码

listener.ns
  1. @EventHandler
  2. void onJoin(PlayerJoinEvent e){
  3.    
  4. }
复制代码
脚本的主文件必须为main.ns,调用主文件的时候,则是import 你的id.插件名 如插件名为Hello,id为net.noyark
  1. //导入主类
  2. import net.noyark.Hello
复制代码
info.ns书写

  1. info{
  2.       name "Hello" //插件名称,必须有
  3.       version "1.0.0" //版本,可不写,不写默认为1.0.0
  4.       author "MagicLu" //作者名 可不写
  5.       listeners ["listener.ns"] //注册的监听器 如果没有可不写
  6.       commandsMap ["command.ns"] //注册的指令 如果没有可不写
  7.       id "net.noyark.www" //id号,意义如同前面所讲
  8.       description "" //介绍,可不写
  9.       permissions ([
  10.            "FirstPlugin.fp" : [
  11.                   description : "",
  12.                   default : "op"
  13.            ]
  14.       ]) //和nk插件的plugin.yml结构相同
  15.       commands ([
  16.           fp : [
  17.               "usage" : "/fp help",
  18.               "description" : "指令介绍",
  19.               "permission" : "FirstPlugin.fp"
  20.           ]
  21.       ]) //和nk插件的plugin.yml结构相同
  22. }
  23. depends{ //依赖
  24.     softDepend ([])
  25.     depend ([])
  26.     loadBefore([])
  27. }
复制代码


具体使用方法参见README.md
基本和NK相同,采用groovy语法,并且支持java的写法,注册监听器和指令同样可以 使用原来的方法。 默认的指令则是使用了SimpleCommand,使用可以参见example文件

脚本的文件夹直接丢到NKScript的配置文件夹下即可加载

其他问题:
Groovy脚本效率很低怎么办?
您可以抛弃动态类型,因为Groovy依然是强类型的,它可以使用@CompileStatic注解使得您的代码静态编译,但是需要您抛弃动态类型,类似于这样
  1. @Command(name = "hello",description = "233",usageMessage = "/hello")
  2. @Arguments(max = 10,min = 0)
  3. @CompileStatic
  4. boolean onHelloCommand(CommandSender sender, String label, String[] args){
  5.     //这里写指令处理代码
  6.     base.logger.info("hello,world")
  7.     return true
  8. }
复制代码




更新 v1.0.1
支持脚本前置,修复大量bug,且其他类可以省略包名,支持预加载类
参见 https://github.com/MagicLu550/nkscript/releases/tag/1.0.1
更新 v1.0.2
支持自动主类注入和默认静态对象方法,具体参见README新增
参见 https://github.com/MagicLu550/nkscript/releases/tag/1.0.2
更新 v1.0.3
参见 https://github.com/MagicLu550/nkscript/releases/tag/1.0.3
在脚本根文件夹下libs文件夹下添加jar包即可被加载,具体参见README
更新 v1.0.4
使用了静态编译,插件运行效率提高: @CompileStatic
参见
https://github.com/MagicLu550/nkscript/releases/tag/1.0.4
更新 v1.0.5
对于命令.ns和监听器.ns支持了自动包名检测
参见 https://github.com/MagicLu550/nkscript/releases/tag/1.0.4
更新 v1.0.6
info.retain设置为true,可以对主类不进行套壳编译。
参见 https://github.com/MagicLu550/nkscript/releases/tag/1.0.6













[groupid=1708]Pioneer Group[/groupid]
作者: Kenneth_z    时间: 2020-2-21 23:36
很强大的工具 方便开发者
作者: xiaolu550    时间: 2020-2-22 22:25
1.0.2更新
https://github.com/MagicLu550/nkscript/releases/tag/1.0.2

原生getInstance和注入赋值
主文件默认带一个静态的getInstance方法,可以直接获得当前的对象 如listener.ns,如果我的插件名称是HelloWorld,id是net.noyark.www

  1. import net.noyark.www.HelloWorld

  2. import cn.nukkit.event.EventHandler
  3. import cn.nukkit.event.player.PlayerJoinEvent

  4. @EventHandler
  5. void onPlayerJoin(PlayerJoinEvent e){
  6.     //getInstance()是HelloWorld的自带方法
  7.     PluginBase base = HelloWorld.getInstance()
  8.    
  9. }
复制代码

自动化赋值 您可以通过@MainPlugin直接获得主类对象,当然只能使用于主类,监听器类,命令类 如listener.ns

  1. import net.noyark.www.HelloWorld

  2. import cn.nukkit.event.EventHandler
  3. import cn.nukkit.event.player.PlayerJoinEvent

  4. @MainPlugin
  5. PluginBase base

  6. @EventHandler
  7. void onPlayerJoin(PlayerJoinEvent e){
  8.     base.logger.info("hello,world") //这里可以直接调用
  9.    
  10. }
复制代码

作者: VichainLee    时间: 2020-2-22 23:00
ohhhhh前排支持黑科技
作者: xiaolu550    时间: 2020-2-22 23:14
VichainLee 发表于 2020-2-22 23:00
ohhhhh前排支持黑科技

谢谢支持!
作者: Kenneth_z    时间: 2020-2-23 11:56
恭喜优秀
作者: xiaolu550    时间: 2020-2-23 12:12
更新v1.0.3 在脚本根文件夹下libs文件夹下添加jar包即可被加载
开发者可能多少会被ClassNotFound给烦到,脚本支持了第三方库直接导入。
即在脚本根文件夹下直接放入jar包,这样,您的jar包默认视为被导入。
具体参见README.md第三方库导入部分
作者: xiaolu550    时间: 2020-2-24 09:24
更新v1.0.4 提高运行效率

在这里顺提一下,如果groovy效率比较低,您可以使用@CompileStatic注解在您方法上,这样您编译后的字节码几乎和java的相似,效率不会有很大衰减
作者: xiaolu550    时间: 2020-2-25 21:07
更新v1.0.6 支持info.retain
nfo.retain设置为true,可以对主类不进行套壳编译。

info.ns

  1. info{
  2.       name "Game"
  3.       version "1.0.0"
  4.       author "MagicLu"
  5.       listeners (["PlayerListener.ns"])
  6.       retain true
  7.       id "net.noyark.www"
  8.       description ""
  9.       permissions ([
  10.            "FirstPlugin.fp" : [
  11.                   description : "",
  12.                   default : "op"
  13.            ]
  14.       ])
  15.       commands ([
  16.           fp : [
  17.               "usage" : "/fp help",
  18.               "description" : "指令介绍",
  19.               "permission" : "FirstPlugin.fp"
  20.           ]
  21.       ])
  22. }
复制代码

main.ns只能写成

  1. class Game extends PluginBase{
  2.     void onLoad(){
  3.         this.logger.info("MagicLu's script example02,the simple pvp game")
  4.     }

  5.     void onEnable(){
  6.         this.logger.info("插件已经加载")
  7.     }

  8.     void onDisable(){

  9.     }
  10. }
复制代码

设计这个的意义: 有些人可能为了使用ide的补全功能,可以开启它
作者: DouYu-FengYe    时间: 2020-5-10 16:31
可以可以