跳转到内容
logo
我的世界XyeBBS论坛3群 进群吹水聊天!众多整合包作者、插件作者、玩家在内哦!不定时发福利,公布重要通知!

[1.21.1 KubeJS7]如何更好的用指令去执行KubeJS代码

icon教程-KubeJS教程浏览 877回复 0
发布于 2025-07-21 21:10:31

本帖子用到的模组

kubejs-neoforge-2101.7.1-build.181

rhino-2101.2.7-build.74

功能预览

5ea89a26

作用

  1. 可以更好的调试KubeJS里的方法和测试功能。

  2. 一些数据驱动的模组只能回调指令而不能执行KubeJS里的方法,这个功能就完全可以成为连接指令和KubeJS的桥梁

    功能介绍

    完整代码展示

    {
      let namespaces = {}
      let GetNamespace = function (/**@type {$ServerPlayer_}*/ player) {
        let key = player.stringUuid
        if (!namespaces[key]) namespaces[key] = {}
        return namespaces[key]
      }
      let DoEval = function (code, player) {
        getServer().tell(Text.gold('Code:').append(Text.white(code)).clickCopy(code).hover(Text.translate('chat.copy.click')))
        let ns = GetNamespace(player)
        let ray = player.rayTrace()
        let entity = ray.entity
        let block = ray.block
        try {
          let tmp
          with (ns) {
            with (global) {
              tmp = eval(code)
              getServer().tell(Text.green('Result:').append(Text.white(tmp)).clickCopy(tmp).hover(Text.translate('chat.copy.click')))
            }
          }
          ns.res = tmp
        } catch (e) {
          getServer().tell(Text.red('Error:').append(Text.white(e)).clickCopy(e).hover(Text.translate('chat.copy.click')))
        }
      }
    
      ServerEvents.commandRegistry(event => {
        let { dispatcher, commands, arguments } = event
        dispatcher.register(commands.literal('eval')
          .then(commands.literal('test')
            .then(commands.argument('code', arguments.GREEDY_STRING.create(event))
              .executes(ctx => {
                let { source: { player } } = ctx
                let code = String(arguments.GREEDY_STRING.getResult(ctx, 'code'))
                DoEval(code, player)
                return 1
              })
            )
          )
          .then(commands.literal('local')
            .then(commands.argument('code', arguments.GREEDY_STRING.create(event))
              .executes(ctx => {
                let { source: { player } } = ctx
                let ray = player.rayTrace()
                let entity = ray.entity
                let block = ray.block
                let code = String(arguments.GREEDY_STRING.getResult(ctx, 'code'))
                eval(code)
                return 1
              })
            )
          )
        )
      })
    }
    
    let $ServerLifecycleHooks = Java.loadClass("net.neoforged.neoforge.server.ServerLifecycleHooks")
    
    /**
     * 获取MinecraftServer实例
     * @returns {$MinecraftServer_}
     */
    function getServer() {
      return $ServerLifecycleHooks.getCurrentServer()
    }
    

    根据代码可以看到我是注册了2个指令,一个是/eval test <code>,这个指令在使用的时候会在聊天栏中展示代码执行的结果,如果报错了则会返回报错的内容。另一个就是/eval local <code>,本质上这个指令实现的功能没啥区别,这个指令执行后不会在执行的玩家的聊天栏展示调试的结果,更适合实际的使用。

    在使用指令的时候,你可以直接使用3个变量player:执行当前指令的玩家ServerPlayer,entity:执行指令的玩家看着的实体Entity,block:执行指令的玩家看着的方块BlockContainerJS,这3个变量已经可以适用于很多场景的调试和使用了。

    参考文献

    https://github.com/YukkuriC/kubejs_playground/blob/main/server_scripts/commands/Eval.js 作者:YukkuriC

    https://github.com/YukkuriC/kubejs_playground/blob/nf1.21/server_scripts/commands/Eval.js 作者:YukkuriC

    Ps:需注意的是这里作者获取MinecraftServer的方式都是不一样的,在1.20.1的时候作者通过Utils.server获取,而这个方法在1.21.1并不存在,所以作者换了一种方式获取server,而我这里的获取方式是通过NeoForge的ServerLifecycleHooks来获取的。

帖子打赏
参与人数打赏物品(0)

正在加载内容…
回复帖子善语结善缘,恶语伤人心。要记得文明发言哦!
登录后参与讨论登录账号后即可发表您的回复和看法