/* * 本文件由 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使用 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; } } }