/* * 本文件由 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 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; settings.avoidance.value = config.avoidMobs; } /** * 让 Baritone 寻路前往指定区块(以“到达区块内”为完成条件)。 * * @param chunk 目标区块 */ public void pathTo(ChunkPos chunk) { IBaritone baritone = this.primary(); if (baritone == null) { return; } // 使用自定义 ChunkGoal:完成条件为“玩家脚下方块落在目标区块内”, // 与控制器 playerChunk.equals(target) 的判定一致。避免 Baritone 自带 // GoalXZ(容差 0,精确到区块中心单格)在中心不可达时停在相邻区块, // 造成目标区块错位与反复寻路。 baritone.getCustomGoalProcess().setGoalAndPath(new ChunkGoal(chunk)); } /** 强制取消当前寻路任务。 */ 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; } } }