/* * 本文件由 autostore-1.0-SNAPSHOT.jar 反编译并整理而来(CFR 0.152), * 混淆名已替换为 Minecraft 1.21.4 Yarn 可读映射,并补充中文注释。 */ package autostore.client.bridge; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.event.events.PathEvent; import baritone.api.event.listener.AbstractGameEventListener; import autostore.client.config.ExpansionConfig; import autostore.client.territory.ChunkPos; import baritone.api.pathing.goals.GoalXZ; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; /** * Baritone API 封装(桥接层)。 * *

将模组对 Baritone 寻路机器人的调用集中在此类中,包括:应用寻路行为配置、 * 前往目标区块、取消寻路、查询寻路状态等。所有调用都做了空安全保护, * 当 Baritone 未加载时相关操作会安全地静默失败。

*/ @Environment(EnvType.CLIENT) public final class BaritoneBridge { /** * 寻路事件回调:用于把 Baritone 的路径事件(如计算失败、到达目标)转发给控制器, * 使控制器能及时识别“目标不可达”并跳过,而不是傻等到超时。 */ public interface PathListener { void onPathEvent(PathEvent event); } /** 已注册的路径事件监听器集合(线程安全) */ private final Set pathListeners = ConcurrentHashMap.newKeySet(); /** 是否已向 Baritone 注册事件监听器(只注册一次) */ private volatile boolean eventListenerRegistered; /** 注册一个路径事件监听器;同时确保已向 Baritone 事件总线挂载转发器 */ public void addPathListener(PathListener listener) { this.pathListeners.add(listener); this.primary(); } /** * 将模组配置同步到 Baritone 的全局设置。 * * @param config 扩地配置 */ public void applyConfig(ExpansionConfig config) { Settings settings = BaritoneAPI.getSettings(); settings.allowSprint.value = config.allowSprint; settings.allowBreak.value = config.allowBreak; settings.allowPlace.value = config.allowPlace; // 跳跃(跑酷)前进:开启放置时也允许跳跃搭路,避免过河/过缝时必须纯步行 settings.allowParkour.value = config.allowJump || config.allowPlace; // 关键修复:开启放置时,配套允许“跑酷搭路放方块”。 // 若仅开 allowPlace 而不给 allowParkourPlace,Baritone 在边缘会把 // “下蹲放方块”与“跳跃过去”两条腿计划打架:想放又判定不该放, // 于是原地反复下蹲+跳跃却始终放不出方块(用户观察到的“原地抽搐”)。 settings.allowParkourPlace.value = config.allowPlace; // 降低放方块的路径代价:Baritone 默认对搭路惩罚较高,会倾向犹豫/绕行; // 归零后它更愿意稳定搭路,而不是在缺口边反复空跳。 settings.blockPlacementPenalty.value = 0.0; settings.avoidance.value = config.avoidMobs; } /** * 让 Baritone 寻路前往指定区块中心。 * *

使用 Baritone 原生{@link GoalXZ}(目标区块中心单格):原生 GoalXZ 对 * 可达地形几乎不会误判“目标不可达”,是最好的默认选择。早期用自定义 * {@code ChunkGoal}(曾加入高度硬约束)疑似是“平原上一按 W 就能走、Baritone 却秒 * CALC_FAILED”的根因——自定义 Goal 在某些站位/边界下会把可达目标判成不可达。 * 到达判定仍由控制器 {@code playerChunk.equals(target)} 保证,与 Goal 自身容差无关。

* * @param chunk 目标区块 */ public void pathTo(ChunkPos chunk) { IBaritone baritone = this.primary(); if (baritone == null) { return; } baritone.getCustomGoalProcess().setGoalAndPath(new GoalXZ(chunk.centerBlockX(), chunk.centerBlockZ())); } /** 强制取消当前寻路任务。 */ public void cancel() { IBaritone baritone = this.primary(); if (baritone == null) { return; } baritone.getPathingBehavior().forceCancel(); } /** @return 当前是否正在寻路 */ public boolean isPathing() { IBaritone baritone = this.primary(); return baritone != null && baritone.getPathingBehavior().isPathing(); } /** @return Baritone 是否可用(已加载并存在主实例) */ public boolean isAvailable() { return this.primary() != null; } /** * 获取 Baritone 主实例;加载失败或异常时返回 null。 * 首次成功获取时,向 Baritone 事件总线注册一个转发器, * 把路径事件分发给所有已注册的 {@link PathListener}。 * * @return 主 Baritone 实例,或 null */ private IBaritone primary() { try { IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone(); if (baritone != null && !this.eventListenerRegistered) { this.eventListenerRegistered = true; baritone.getGameEventHandler().registerEventListener(new AbstractGameEventListener() { @Override public void onPathEvent(PathEvent event) { for (PathListener listener : BaritoneBridge.this.pathListeners) { try { listener.onPathEvent(event); } catch (Throwable ignored) { // 单个监听器异常不影响其他监听器 } } } }); } return baritone; } catch (Throwable ignored) { return null; } } }