#minecraft #minecraft-mod #datapack #mcfunction #vanilla

bin+lib mcfunction-debugger

一款无需任何 Minecraft 模组的 Minecraft *.mcfunction 文件调试器

4 个版本 (稳定)

2.0.0 2024 年 1 月 2 日
1.0.3 2023 年 2 月 3 日
1.0.2 2023 年 1 月 29 日
0.1.0 2021 年 12 月 17 日

#109调试

每月 41 次下载
mcfunction-debug-adapter 中使用

GPL-3.0 或更新版

315KB
7.5K SLoC

Minecraft: Java Edition 1.14.1 - 1.19.4 Minecraft: Bedrock Edition unsupported
crates.io Build Status

Mcfunction-Debugger

Mcfunction-Debugger 是一款无需任何 Minecraft 模组的 Minecraft *.mcfunction 文件调试器。

Mcfunction-Debugger 实现了 调试适配器协议,以便与不同的 IDE(如 Eclipse 或 Vim)轻松集成(请参阅支持 IDE 列表)。相应的 Visual Studio Code 扩展程序可以在这里找到:https://codeberg.org/vanilla-technologies/mcfunction-debugger-vscode

如果您想为其他 IDE 实现此类集成,您可以在开发者章节中找到文档。

内容

  1. 调试数据包
  2. 功能
  3. 注意事项
  4. 安装
  5. 开发者指南

调试数据包

要调试一个函数,mcfunction文件必须包含在数据包中,并且数据包不能是zip文件。数据包不必加载到Minecraft世界中,因为仍然会生成可调试的数据包版本。特殊函数标签 minecraft:load(定义在 data/minecraft/tags/functions/load.json)和 minecraft:tick(定义在 data/minecraft/tags/functions/tick.json)目前被忽略(见 #8),因此要开始调试,您必须指定一个函数。

函数将使用 schedule 命令执行,因此它将在世界的原点位置没有 @s 实体的位置上运行。要更改此设置,您可以创建一个新的函数,在该函数中以玩家身份或在不同位置执行您的函数,然后调试该新函数。例如

execute as @p at @s run function my_namespace:my_function

由于调试的函数使用 schedule 命令执行,因此它可能与通过Minecraft聊天或服务器控制台由玩家执行的函数略有不同。与手动执行的命令不同,通过 schedule 或命令方块执行的命令将在实体年龄增加之前运行。因此,如果在通过调试器和手动执行函数时注意到不同的行为,请尝试手动安排函数以查看是否有所改变。

功能

Mcfunction-Debugger允许在单人和多人世界中调试各种Minecraft版本的数据包。这是通过使用 Minect 连接到纯净的Minecraft实例来实现的。

调用函数

函数可以带或不带执行来调用,但目前还不支持对函数标签的调用(见 #12)。

几乎所有的execute(执行为、执行在、...)变体都完全受支持。唯一的例外是用于函数调用的 execute store(见 #11),它将目前存储一个任意的 result/success 值。

# Supported
function my_namespace:my_function
execute ... run function my_namespace:my_function

# Not supported
execute store result score my_target my_objective run function my_namespace:my_function
function #my_namespace:my_function_tag
execute ... run function #my_namespace:my_function

实体选择器

Mcfunction-Debugger完全支持使用实体选择器(如 execute as @e run function ...)调用函数。就像在常规Minecraft中一样,被调用的函数将完全为第一个实体执行,然后为第二个实体执行,依此类推。这与使用命令块进行调试的方法不同,命令块会为所有实体执行被调用函数的第一个命令,然后为所有实体执行第二个命令,依此类推。

函数执行上下文

函数总是在调用函数时定义的上下文中执行。这个上下文包括

  • executor:执行函数的实体通过实体选择器 @s 来引用。当使用 execute as 调用函数时,它会改变。
  • position:函数在Minecraft世界中执行的坐标位置通过相对坐标如 ~ ~ ~ 来引用。当使用 execute positionedexecute at 调用函数时,它会改变。
  • 旋转:当调用带有 execute rotatedexecute at 的函数时,函数的观察旋转会发生变化。它会影响局部坐标,例如 ^ ^1 ^
  • 维度:函数执行的维度,如 overworldthe_netherthe_end。当调用带有 execute inexecute at 的函数时,它会发生变化。
  • 锚点:锚点(eyesfeet)定义了局部坐标的起点。它定义了像 ^ ^ ^ 这样的局部位置是否相对于执行者的眼睛或脚部。当调用带有 execute anchored 的函数时,它会发生变化。

Mcfunction-Debugger 正确地存储和恢复整个函数的执行上下文,在整个调试会话中。

当执行暂停时,使用粒子标记位置和旋转

view position and rotation

缺失和无效的函数

Minecraft 和 Mcfunction-Debugger 完全跳过执行缺失或包含无效命令的函数。这意味着在无效函数中的断点将被忽略。为了强调这一点,每当跳过一个函数调用时,Mcfunction-Debugger 都会在调试控制台中进行写入。

计划和时间

计划命令完全受支持。在执行暂停时,所有计划计时器也会暂停,因此数据包不会因为遇到断点而表现不同。此外,所有区域效果云的年龄被冻结,以确保它们不会死亡。其他实体和游戏时间的年龄目前没有被冻结(参见 #24#18),并且随机时钟速度尚未设置为零(参见 #14)。

内部调试实体被隐藏

Mcfunction-Debugger 内部使用各种实体。为了确保它们不会干扰调试的数据包,这些内部实体被从所有实体选择器中隐藏。

有一个例外,那就是 Minects 连接实体。Minect 需要一个标记为 minect_connection 的区域效果云才能运行。我们在使用调试器时不会隐藏这个实体,因为它在玩家手动执行函数时也是可见的。可以安全地杀死连接实体,因为它们将在下一刻重新创建。

所以,如果你的数据包包含 kill @e[type=!player] 这样的命令是没有问题的。只需注意,一旦安装了 Minect,像 execute as @e run ... 这样的命令将针对一个额外的实体。

注意事项

遗憾的是,当程序被调试时,它总是可能略有不同。以下是一些您可能会遇到的问题。

尚不支持在其他数据包中调用函数

目前,Mcfunction-Debugger 只考虑包含调试函数的数据包(参见 #9)。这意味着对其他数据包中函数的调用将被跳过,就像函数缺失一样。

为了解决这个问题,您可以在调试之前将所有数据包合并为一个大数据包。

操作已死亡的实体

在 Minecraft 函数中,您可以杀死一个实体然后继续使用它。例如,考虑以下数据包

example:sacrifice_pig:

summon pig ~ ~ ~ {Tags: [sacrifice]}
execute as @e[type=pig,tag=sacrifice] run function example:perform_necromancy

example:执行招魂术:

say I am still alive
function example:kill_me
say I am dead inside

example:杀了我:

kill @s

在执行了函数 example:kill_me 之后,猪死了,但它从另一个世界对我们说话。目前调试器无法处理这种情况。如果您尝试调试函数 example:sacrifice_pig,它将会崩溃

[Info] Started debugging example:sacrifice_pig
[Pig] I am still alive
[Error] Selected entity was killed!

达到最大命令链长度

默认情况下,Minecraft 每个tick只执行最多 65536 条命令。由于调试器需要运行许多额外的命令,您可能会在调试非常大的数据包时达到这个限制。当发生这种情况时,调试会话将处于未定义的状态。如果没有计划,开发工具将无限期等待,您需要手动终止调试会话。如果有即将到来的计划,它们可能会使调试会话崩溃或表现出意外的行为。

为了避免达到命令限制,您可以添加更多的断点,逐行执行函数,或者增加命令限制

/gamerule maxCommandChainLength 2147483647

区块加载

如果在执行断点暂停的函数时,需要调试的实体所在的区块被卸载,那么当您尝试恢复执行时,调试会话将会崩溃。

例如,这可能会发生如果您走得很远,或者如果函数在仅临时加载的区块中运行(例如,通过 teleport 命令或通过传送门)。

安装

使用预编译的二进制文件

预编译的二进制文件可以在 发布 下找到。

从源代码安装

Mcfunction-Debugger是用Rust编写的,因此要从源代码构建它,您需要 安装Rust

然后,您可以通过运行以下命令从 crates.io 安装它:

cargo install mcfunction-debugger

或者从 Codeberg 通过运行以下命令安装:

cargo install --git https://codeberg.org/vanilla-technologies/mcfunction-debugger.git

要卸载,请运行以下命令:

cargo uninstall mcfunction-debugger

开发者指南

Mcfunction-Debugger仅支持通过 stdinstdout 进行通信的 单会话模式。为了开始执行 mcfunction 文件,开发工具需要发送一个 launch 请求(attach 请求 不支持)。

启动参数

为了使调试适配器连接到 Minecraft,它需要一些作为 launch 请求一部分的参数。

程序

要调试的 mcfunction 文件的路径。mcfunction 文件必须包含在具有 pack.mcmeta 文件的数据包中。

minecraftWorldDir

调试适配器应连接到的 Minecraft 世界的目录。

对于单人游戏,这通常是保存目录内的一个目录

  • Windows: %appdata%\.minecraft\saves\
  • GNU/Linux: ~/.minecraft/saves/
  • Mac: ~/Library/Application Support/minecraft/saves/

对于服务器,它指定在 server.properties 中。

minecraftLogFile

Minecraft 的日志文件路径。

对于单人游戏,通常位于以下位置

  • Windows: %appdata%\.minecraft\logs\latest.log
  • GNU/Linux: ~/.minecraft/logs/latest.log
  • Mac: ~/Library/Application Support/minecraft/logs/latest.log

对于服务器,它位于服务器目录中的 logs/latest.log

示例

{
  "program": "C:/Users/Herobrine/my_datapack/data/my_namespace/functions/main.mcfunction",
  "minecraftWorldDir": "C:/Users/Herobrine/AppData/Roaming/.minecraft/saves/New World",
  "minecraftLogFile": "C:/Users/Herobrine/AppData/Roaming/.minecraft/logs/latest.log"
}

命令行界面

mcfunction-调试器[标志] [选项]

标志

--help

打印帮助信息。

--version

打印版本信息。

选项

--log-file

日志文件的路径。如果指定,调试适配器将在启动时创建此文件并将日志消息写入其中。

--log-level

日志级别也可以通过环境变量 LOG_LEVEL 进行配置。默认为 INFO

依赖关系

~11–22MB
~356K SLoC