diff --git a/README.md b/README.md new file mode 100644 index 0000000..8dc5d1f --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# AutoDig 自动挖矿模组 + +一个基于 Fabric + Baritone 的 Minecraft 客户端自动挖矿模组,内置 Baritone 1.13.1(无需另行安装),支持主世界鱼骨巷道挖矿与下界自动挖矿返程。 + +## 功能特性 + +### 挖矿任务 +- **主世界模式**:在指定 Y 层沿玩家朝向挖鱼骨巷道(主干 + 两侧侧支),自动返回地表;可自定义挖掘层、巷道长度、目标矿物(默认钻石)。 +- **下界模式**:自动进传送门进入下界挖矿(默认远古残骸),挖够数量 / 背包满 / 血量低 / 装备耐久低时自动回主世界;支持无限挖(目标数量 -1)。 + +### 智能辅助(可逐项开关) +- **自动切换工具**:由 Baritone 自动选择最合适的镐/锹等工具。 +- **自动进食**:饥饿度低时自动吃背包食物,跳过金苹果等特殊/珍贵食物。 +- **自动插火把**:隧道黑暗时自动从背包取火把放置,防止刷怪。 +- **自动换备用装备**:护甲/工具耐久过低时自动从背包换上同类备用装备。 +- **提前丢垃圾**:背包接近满(已用 ≥30 格)时就提前丢弃圆石、深板岩等垃圾,为矿物腾出空间,避免被误判"背包已满需返回"。 +- **杀戮光环**:自动攻击附近真正敌对生物,不误伤铁傀儡、僵尸猪灵、末影人等中立生物。 +- **保命优先**:血线过低时暂停挖矿向上撤离,恢复后自动续任务。 +- **装备耐久保护**:护甲/工具耐久低于阈值时暂停或换装,下界模式直接返程。 +- **死亡重生回点**:重生后自动返回死亡地点继续任务。 +- **实时状态 HUD**:挖矿时屏幕左上角实时显示任务、状态、运行时长、血量、饥饿、背包、进度。 + +## 使用说明 + +1. 将 mod jar 放入 `mods` 文件夹(需 Fabric Loader 与 Fabric API)。 +2. 进入游戏后按 **Ctrl + R**(或在按键设置中查看"打开 AutoDig 界面")打开界面。 +3. 选择任务(主世界 / 下界),按需调整设置,点击"开始"。 + +### 命令 +| 命令 | 说明 | +| --- | --- | +| `/autodig gui` | 打开设置界面 | +| `/autodig start overworld` / `start nether` | 直接启动对应任务 | +| `/autodig stop` | 停止当前任务 | +| `/autodig status` | 查看实时状态(任务/状态/时长/死亡/血量/饥饿) | + +## 配置文件 + +配置文件位于 Fabric 配置目录下的 `autodig.json`,也可在游戏内 GUI 修改。 + +## 版本记录 + +- **v2.2.0**:新增实时状态 HUD、自动插火把、`/autodig status` 命令;自动进食跳过特殊食物;背包接近满提前丢垃圾防误判返程;杀戮光环不再误伤中立生物;GUI 补全进食/保命/攻击范围等设置。 +- **v2.1.0**:自动换备用装备 + 背包满自动丢垃圾。 +- **v2.0.x**:GUI 响应式布局、主世界/下界模式分离、装备耐久保护、自定义矿物。 diff --git a/gradle.properties b/gradle.properties index 0f563a9..7b089d6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ yarn_mappings=1.21.4+build.8 loader_version=0.19.3 # Mod Properties -mod_version=2.1.0 +mod_version=2.2.0 maven_group=autodig archives_base_name=autodig diff --git a/src/main/java/autodig/client/AutoDigModClient.java b/src/main/java/autodig/client/AutoDigModClient.java index 63eb3bc..51df446 100644 --- a/src/main/java/autodig/client/AutoDigModClient.java +++ b/src/main/java/autodig/client/AutoDigModClient.java @@ -7,6 +7,7 @@ import autodig.client.config.DigConfig; import autodig.client.config.MineTask; import autodig.client.controller.DigController; import autodig.client.gui.AutoDigGui; +import autodig.client.gui.StatusHud; import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; @@ -15,6 +16,7 @@ import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallba import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; @@ -79,6 +81,8 @@ public final class AutoDigModClient implements ClientModInitializer { }); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> AutoDigCommands.register(dispatcher)); + // 实时状态 HUD:仅在挖矿任务进行中于左上角渲染 + HudRenderCallback.EVENT.register((context, tickCounter) -> StatusHud.render(context)); } public static AutoDigModClient instance() { diff --git a/src/main/java/autodig/client/command/AutoDigCommands.java b/src/main/java/autodig/client/command/AutoDigCommands.java index da49f18..433318f 100644 --- a/src/main/java/autodig/client/command/AutoDigCommands.java +++ b/src/main/java/autodig/client/command/AutoDigCommands.java @@ -2,17 +2,19 @@ package autodig.client.command; import autodig.client.AutoDigModClient; import autodig.client.config.MineTask; +import autodig.client.controller.DigController; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.client.MinecraftClient; import net.minecraft.text.Text; /** * AutoDig 客户端命令。 * *
提供 {@code /autodig gui}(打开界面)、{@code /autodig start <任务>} - * (直接启动)、{@code /autodig stop}(停止当前任务)三个快捷入口, - * 方便在未绑定的快捷键场景下使用。
+ * (直接启动)、{@code /autodig stop}(停止当前任务)、{@code /autodig status} + * (查看实时状态)四个快捷入口,方便在未绑定的快捷键场景下使用。 */ public final class AutoDigCommands { @@ -51,6 +53,33 @@ public final class AutoDigCommands { mod.bridge().cancelAll(); mod.sendToast("AutoDig: 已停止"); return 1; + })) + .then(com.mojang.brigadier.builder.LiteralArgumentBuilder.仅在挖矿任务进行中(task != NONE)于屏幕左上角渲染一块半透明面板, + * 实时展示:任务、状态机阶段、运行时长、血量百分比(按阈值变色)、 + * 饥饿值、背包占用、挖掘进度(主世界鱼骨 step/total、下界已挖/目标)。 + * 玩家无需打开 GUI 即可对自动化过程一目了然。
+ * + *由 {@link net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback} + * 驱动,在 {@link AutoDigModClient#onInitializeClient()} 中注册。
+ */ +public final class StatusHud { + + private static final int LINE_H = 11; + private static final int X = 4; + private static final int Y = 4; + private static final int PANEL_W = 172; + + private StatusHud() { + } + + /** + * 渲染挖矿状态 HUD(仅在任务进行中显示)。 + * + * @param context 绘制上下文(由 HudRenderCallback 提供) + */ + public static void render(DrawContext context) { + AutoDigModClient mod = AutoDigModClient.instance(); + if (mod == null) { + return; + } + DigConfig config = mod.config(); + if (config.task == MineTask.NONE) { + return; + } + DigController controller = mod.controller(); + MinecraftClient client = MinecraftClient.getInstance(); + if (client.player == null || client.textRenderer == null) { + return; + } + PlayerEntity player = client.player; + + int y = Y; + // 半透明背景面板 + context.fill(X - 3, Y - 3, X + PANEL_W, Y + LINE_H * 8 + 2, 0x80000000); + + // 标题 + context.drawTextWithShadow(client.textRenderer, "\u00A7e== AutoDig ==", X, y, 0xFFFFFF); + y += LINE_H; + + // 任务 + context.drawTextWithShadow(client.textRenderer, "\u00A77\u4efb\u52a1: \u00A7f" + config.task.label(), X, y, 0xFFFFFF); + y += LINE_H; + + // 状态 + context.drawTextWithShadow(client.textRenderer, "\u00A77\u72b6\u6001: \u00A7f" + controller.statusText(), X, y, 0xFFFFFF); + y += LINE_H; + + // 运行时长 + context.drawTextWithShadow(client.textRenderer, "\u00A77\u65f6\u95f4: \u00A7f" + controller.stats().elapsedString(), X, y, 0xFFFFFF); + y += LINE_H; + + // 血量(按阈值变色) + int hp = (int) Math.round(player.getHealth() / Math.max(player.getMaxHealth(), 1.0) * 100); + String hpCode = hp < 30 ? "\u00A7c" : hp < 60 ? "\u00A7e" : "\u00A7a"; + context.drawTextWithShadow(client.textRenderer, "\u00A77\u8840\u91cf: " + hpCode + hp + "%", X, y, 0xFFFFFF); + y += LINE_H; + + // 饥饿 + int food = player.getHungerManager().getFoodLevel(); + String foodCode = food <= config.eatHungerThreshold ? "\u00A7c" : "\u00A7a"; + context.drawTextWithShadow(client.textRenderer, "\u00A77\u9965\u997f: " + foodCode + food + "/20", X, y, 0xFFFFFF); + y += LINE_H; + + // 背包占用 + int used = 0; + for (int i = 0; i < 36; i++) { + if (!player.getInventory().main.get(i).isEmpty()) { + used++; + } + } + String invCode = used >= 36 ? "\u00A7c" : used >= 30 ? "\u00A7e" : "\u00A7f"; + context.drawTextWithShadow(client.textRenderer, "\u00A77\u80cc\u5305: " + invCode + used + "/36", X, y, 0xFFFFFF); + y += LINE_H; + + // 挖掘进度 + String progress; + if (config.task == MineTask.OVERWORLD) { + progress = controller.overworldStep() + "/" + controller.overworldTotal(); + } else if (config.task == MineTask.NETHER) { + int target = config.netherTargetCount; + int mined = controller.netherMinedCount(); + progress = mined + (target > 0 ? "/" + target : ""); + } else { + progress = "--"; + } + context.drawTextWithShadow(client.textRenderer, "\u00A77\u8fdb\u5ea6: \u00A7f" + progress, X, y, 0xFFFFFF); + } +} diff --git a/src/main/java/autodig/client/miner/OverworldMiner.java b/src/main/java/autodig/client/miner/OverworldMiner.java index 27f50b9..a15ec09 100644 --- a/src/main/java/autodig/client/miner/OverworldMiner.java +++ b/src/main/java/autodig/client/miner/OverworldMiner.java @@ -174,6 +174,16 @@ public final class OverworldMiner { return this.done; } + /** @return 当前推进到的计划步数(从 0 开始) */ + public int currentStep() { + return this.step; + } + + /** @return 鱼骨计划总步数 */ + public int totalSteps() { + return this.plan.size(); + } + /** @return 完成原因是否为「背包已满」 */ public boolean isFull() { return this.full; diff --git a/src/main/java/autodig/client/service/AutoEat.java b/src/main/java/autodig/client/service/AutoEat.java index 1a7011c..1d4836b 100644 --- a/src/main/java/autodig/client/service/AutoEat.java +++ b/src/main/java/autodig/client/service/AutoEat.java @@ -2,8 +2,11 @@ package autodig.client.service; import autodig.client.config.DigConfig; import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.item.consume.UseAction; import net.minecraft.util.Hand; @@ -13,11 +16,14 @@ import net.minecraft.util.Hand; *饥饿度低于阈值时,自动从快捷栏/主背包挑选一件食物并持续"使用手指"进食。 * 食物在主背包时,先将其与当前快捷栏槽位交换,下一帧再吃。 * 已在使用物品(正在咀嚼)时不会重复触发,避免打断进食节奏。
+ * + *智能选择:跳过金苹果、附魔金苹果、紫颂果等有特殊效果/珍贵的食物, + * 优先吃普通口粮,避免把保命物品当普通食物浪费。
*/ public final class AutoEat { /** - * 每帧调用。饥饿不够时在快捷栏/主背包里找食物并吃掉。 + * 每帧调用。饥饿不够时在快捷栏/主背包里找普通食物并吃掉。 * * @param config 挖矿配置 */ @@ -26,7 +32,7 @@ public final class AutoEat { if (client.player == null) { return; } - net.minecraft.entity.player.PlayerEntity player = client.player; + PlayerEntity player = client.player; // 已在进食(用于吞咽)时等待,避免反复打断 if (player.isUsingItem()) { return; @@ -36,10 +42,10 @@ public final class AutoEat { return; } PlayerInventory inv = player.getInventory(); - // 快捷栏 + 主背包共 36 格找食物 + // 快捷栏 + 主背包共 36 格找普通食物 for (int slot = 0; slot < 36; slot++) { ItemStack stack = inv.getStack(slot); - if (stack.isEmpty() || stack.getUseAction() != UseAction.EAT) { + if (stack.isEmpty() || !isSafeFood(stack)) { continue; } if (slot >= 9) { @@ -56,4 +62,18 @@ public final class AutoEat { return; } } + + /** + * 是否为可安全自动进食的普通食物。 + * 排除金苹果/附魔金苹果(有再生等特殊效果,价值高)、紫颂果(传送副作用) + * 等特殊物品,避免自动进食把保命物资白白吃掉。 + */ + private static boolean isSafeFood(ItemStack stack) { + Item item = stack.getItem(); + if (item == Items.GOLDEN_APPLE || item == Items.ENCHANTED_GOLDEN_APPLE + || item == Items.CHORUS_FRUIT) { + return false; + } + return stack.getUseAction() == UseAction.EAT; + } } \ No newline at end of file diff --git a/src/main/java/autodig/client/service/AutoTorch.java b/src/main/java/autodig/client/service/AutoTorch.java new file mode 100644 index 0000000..56124ed --- /dev/null +++ b/src/main/java/autodig/client/service/AutoTorch.java @@ -0,0 +1,116 @@ +package autodig.client.service; + +import autodig.client.config.DigConfig; +import autodig.client.config.MineTask; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; + +/** + * 自动火把服务。 + * + *在挖矿任务进行中,每 3 秒检测一次玩家所在位置的亮度;若光照低于阈值(8), + * 自动从背包中取火把并放置在脚下或相邻方块的顶部,防止隧道刷怪。 + * 光照充足时自动跳过,已放火把的区域光照提升后不会再重复放置。
+ * + *放置通过 {@code interactBlock} 走正规网络包,单人/多人均可用。 + * 火把放置的可行性由 {@link BlockState#canPlaceAt} 委托原版逻辑判定, + * 无需自行处理"方块顶部是否可承托"等复杂条件。
+ */ +public final class AutoTorch { + + /** 检查间隔(tick),约 3 秒 */ + private static final int CHECK_INTERVAL = 60; + /** 低于此光照值视为需要插火把(原版刷怪上限是 0,取 8 留余量) */ + private static final int DARK_THRESHOLD = 8; + + private int tickCounter; + + /** 每帧调用。黑暗时自动放置火把。 */ + public void tick(DigConfig config) { + if (!config.autoTorch) { + return; + } + this.tickCounter++; + if (this.tickCounter < CHECK_INTERVAL) { + return; + } + this.tickCounter = 0; + + MinecraftClient client = MinecraftClient.getInstance(); + if (client.player == null || client.world == null || client.interactionManager == null) { + return; + } + // 仅在挖矿任务进行中生效 + if (config.task == MineTask.NONE) { + return; + } + if (client.currentScreen != null) { + return; + } + PlayerEntity player = client.player; + BlockPos feet = player.getBlockPos(); + + // 光照充足则跳过(火把光 14,6 格内光照 >= 8) + if (client.world.getLightLevel(feet) >= DARK_THRESHOLD) { + return; + } + + // 在背包中找火把 + int torchSlot = -1; + for (int i = 0; i < 36; i++) { + ItemStack s = player.getInventory().main.get(i); + if (!s.isEmpty() && s.getItem() == Items.TORCH) { + torchSlot = i; + break; + } + } + if (torchSlot < 0) { + return; + } + + // 找一个可放置火把的位置(先试脚下,再试四相邻) + BlockState torchState = Blocks.TORCH.getDefaultState(); + BlockPos clickPos = null; + BlockPos feetDown = feet.down(); + if (torchState.canPlaceAt(client.world, feet)) { + clickPos = feetDown; + } + if (clickPos == null) { + for (Direction d : new Direction[]{Direction.NORTH, Direction.SOUTH, + Direction.EAST, Direction.WEST}) { + BlockPos place = feet.offset(d); + if (torchState.canPlaceAt(client.world, place)) { + clickPos = place.down(); + break; + } + } + } + if (clickPos == null) { + return; + } + + // 切到火把所在槽位(主背包的先换到快捷栏,下一帧再放) + if (torchSlot >= 9) { + player.getInventory().swapSlotWithHotbar(torchSlot); + return; + } + if (player.getInventory().selectedSlot != torchSlot) { + player.getInventory().selectedSlot = torchSlot; + return; + } + + // 在支撑方块顶面放置火把 + Vec3d hitVec = Vec3d.ofCenter(clickPos).add(0, 0.5, 0); + BlockHitResult hit = new BlockHitResult(hitVec, Direction.UP, clickPos, false); + client.interactionManager.interactBlock(client.player, Hand.MAIN_HAND, hit); + } +} diff --git a/src/main/java/autodig/client/service/AutoTrash.java b/src/main/java/autodig/client/service/AutoTrash.java index 14147a9..b27fb78 100644 --- a/src/main/java/autodig/client/service/AutoTrash.java +++ b/src/main/java/autodig/client/service/AutoTrash.java @@ -19,18 +19,20 @@ import net.minecraft.screen.slot.SlotActionType; /** * 背包垃圾自动清理服务。 * - *背包满时,把 {@code trashItems} 清单里的垃圾物品丢出背包(圆石、凝灰岩、 - * 深板岩等挖掘副产物)。方块类垃圾保留 {@code trashReserve} 个供 Baritone - * 搭路/垫脚使用;若满背时额度之外没有别的垃圾可丢,则只丢一组腾出空间, - * 尽量保住搭路方块。丢弃通过 {@code clickSlot(THROW)} 走正规网络包, - * 单人/多人均可用。
+ *背包接近满(已用格数达到阈值)时就主动把 {@code trashItems} 清单里的 + * 垃圾物品丢出背包(圆石、凝灰岩、深板岩等挖掘副产物),为挖到的矿物提前 + * 腾出空间,避免背包彻底满后触发"背包已满需返回"而中断挖矿。方块类垃圾 + * 保留 {@code trashReserve} 个供 Baritone 搭路/垫脚使用。丢弃通过 + * {@code clickSlot(THROW)} 走正规网络包,单人/多人均可用。
*/ public final class AutoTrash { /** 每 tick 最多丢弃的物品组数,避免一次产生过多数据包 */ private static final int MAX_DROPS_PER_TICK = 4; + /** 背包已用格数达到该值(共 36 格)即开始丢垃圾,留出余量防误判满包 */ + private static final int NEARLY_FULL_SLOTS = 30; - /** 每帧调用:背包满时自动丢弃垃圾物品。 */ + /** 每帧调用:背包接近满时提前丢弃垃圾物品。 */ public void tick(DigConfig config) { MinecraftClient client = MinecraftClient.getInstance(); if (client.player == null || client.world == null || client.interactionManager == null) { @@ -50,7 +52,8 @@ public final class AutoTrash { if (!handler.getCursorStack().isEmpty()) { return; } - if (!this.inventoryFull(player)) { + // 背包接近满才开始丢,避免背包还没满就误丢 + if (this.usedSlots(player) < NEARLY_FULL_SLOTS) { return; } Set在开关开启时,自动攻击以玩家为中心、指定半径内最近的敌对生物 - * ({@link Monster})。攻击前会转向目标方向;"安全模式"开启时, - * 玩家生命过低则停止攻击、保命优先。
+ *在开关开启时,自动攻击以玩家为中心、指定半径内最近的敌对生物。 + * 只攻击真正的敌对生物({@link Monster}),并排除中立生物 + * ({@link Angerable},如僵尸猪灵、末影人、狼等),避免误伤本不会 + * 主动攻击玩家的中立单位;铁傀儡等非 Monster 类天然不在攻击范围。 + * 攻击前会转向目标方向;"安全模式"开启时,玩家生命过低则停止攻击、 + * 保命优先。
*/ public final class KillAura { @@ -72,13 +76,14 @@ public final class KillAura { this.attackCooldownTicks = 3 + ThreadLocalRandom.current().nextInt(4); } - /** 在玩家周围范围内找最近的敌对生物。 */ + /** 在玩家周围范围内找最近的、真正敌对(非中立)的生物。 */ private Entity findNearestHostile(MinecraftClient client, LivingEntity player, double range) { range = Math.max(2.0, range); Box box = player.getBoundingBox().expand(range); Entity best = null; double bestDist = Double.MAX_VALUE; - for (Entity e : client.world.getEntitiesByClass(Entity.class, box, e -> e instanceof Monster && e.isAlive())) { + for (Entity e : client.world.getEntitiesByClass(Entity.class, box, + e -> e instanceof Monster && !(e instanceof Angerable) && e.isAlive())) { double d = e.squaredDistanceTo(player); if (d < bestDist) { bestDist = d; diff --git a/src/main/java/autodig/client/service/SessionStats.java b/src/main/java/autodig/client/service/SessionStats.java new file mode 100644 index 0000000..a3038f0 --- /dev/null +++ b/src/main/java/autodig/client/service/SessionStats.java @@ -0,0 +1,51 @@ +package autodig.client.service; + +/** + * 会话统计服务。 + * + *追踪本次挖矿任务的关键运行指标:开始时间、死亡次数。 + * 在 HUD 与 GUI 中展示,让玩家对自动化过程有直观感知。 + * 任务开始时 {@link #start()},任务结束或停止时 {@link #stop()}。
+ */ +public final class SessionStats { + + private long startTime; + private int deaths; + private boolean active; + + /** 开始一次新的统计会话(清零所有计数器)。 */ + public void start() { + this.startTime = System.currentTimeMillis(); + this.deaths = 0; + this.active = true; + } + + /** 结束当前会话。 */ + public void stop() { + this.active = false; + } + + /** 记录一次死亡。 */ + public void addDeath() { + this.deaths++; + } + + public boolean isActive() { + return this.active; + } + + public int getDeaths() { + return this.deaths; + } + + /** @return 已运行时长字符串(如 "12:34"),未开始时返回 "--" */ + public String elapsedString() { + if (!this.active || this.startTime == 0) { + return "--"; + } + long elapsed = (System.currentTimeMillis() - this.startTime) / 1000; + long m = elapsed / 60; + long s = elapsed % 60; + return m + ":" + (s < 10 ? "0" + s : s); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 07edc65..49df15e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,7 +3,7 @@ "id": "autodig", "version": "${version}", "name": "AutoDig", - "description": "自动挖矿模组(内置 Baritone 1.13.1,无需另行安装):主世界模式与下界模式,均可自定义目标矿物。主世界鱼骨巷道挖矿,下界自动进出传送门挖矿并支持返程。支持自动切换工具、自动进食、杀戮光环、保命优先、优先绕开岩浆、装备耐久保护(自动换备用装备)、背包满自动丢垃圾、死亡重生回点。", + "description": "自动挖矿模组(内置 Baritone 1.13.1,无需另行安装):主世界模式与下界模式,均可自定义目标矿物。主世界鱼骨巷道挖矿,下界自动进出传送门挖矿并支持返程。支持自动切换工具、自动进食(避开特殊食物)、自动插火把防刷怪、杀戮光环(不误伤中立生物)、保命优先、优先绕开岩浆、装备耐久保护(自动换备用装备)、背包近满提前丢垃圾防误判返程、死亡重生回点、实时状态 HUD。", "authors": [], "contact": {}, "license": "All-Rights-Reserved",