v1.1.9: 寻路超时改为重新寻路/跳过目标而非回城
这个提交包含在:
@@ -7,12 +7,14 @@
|
|||||||
- 从远程 `markers.json` 拉取各国领土边界
|
- 从远程 `markers.json` 拉取各国领土边界
|
||||||
- 四种扩地策略:方形外扩、区域扩地、玩家周围、绕国一圈
|
- 四种扩地策略:方形外扩、区域扩地、玩家周围、绕国一圈
|
||||||
- 区域扩地采用 S 形扫描:从与己方领土接壤的区块开始,横向/纵向 S 形扫过整个矩形,不沿邦国边界,但保证每个新占领区块都与**己方领土**接壤(仅四个正方向,不把其他邦国领土计入接壤)
|
- 区域扩地采用 S 形扫描:从与己方领土接壤的区块开始,横向/纵向 S 形扫过整个矩形,不沿邦国边界,但保证每个新占领区块都与**己方领土**接壤(仅四个正方向,不把其他邦国领土计入接壤)
|
||||||
- 自动寻路(Baritone)前往目标区块,寻路优先走地面减少走入矿洞,超时自动 `/u return` 回城自救
|
- 自动寻路(Baritone)前往目标区块;监听 Baritone 路径事件,目标不可达(CALC_FAILED,如被悬崖/高山/水体隔断)时立即跳过;寻路超时则重新寻路(不立即回城),重试耗尽才跳过当前目标
|
||||||
- 目标有效性校验:寻路/等待/重试前实时校验目标是否仍未被他人占领,已被占领则跳过并重新规划
|
- 运行时接壤校验:寻路/等待阶段每帧校验目标是否仍与己方领土接壤,地图刷新导致边界变化时立即跳过
|
||||||
|
- 目标有效性校验:目标若已被其他邦国占领则立即跳过
|
||||||
- 自动进食(饥饿时自动吃背包食物)
|
- 自动进食(饥饿时自动吃背包食物)
|
||||||
- 实时地图 GUI(通过 Ctrl+R 打开)
|
- 实时地图 GUI(通过 Ctrl+R 打开)
|
||||||
- 监听聊天/字幕消息判断开垦结果
|
- 监听聊天/字幕消息判断开垦结果
|
||||||
- 刷新地图时与最新 `markers.json` 核对已占领区块,丢弃地图未确认的超期假占领,避免高地扩地残留空洞
|
- 刷新地图时与最新 `markers.json` 核对已占领区块,丢弃地图未确认的超期假占领,避免高地扩地残留空洞
|
||||||
|
- 日志导出:GUI 右上角“导出日志”按钮,或 `/autostore log` 命令,记录寻路、坐标、状态、路径事件等
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
|
|||||||
@@ -80,12 +80,6 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
|||||||
private int retryCount;
|
private int retryCount;
|
||||||
/** 当前阶段(寻路/等待)的开始时间戳 */
|
/** 当前阶段(寻路/等待)的开始时间戳 */
|
||||||
private long stageStartedMillis;
|
private long stageStartedMillis;
|
||||||
/** 发送 "/u return" 回城指令的时间戳;0 表示当前未处于回城恢复等待中 */
|
|
||||||
private long returnCommandAtMillis;
|
|
||||||
/** 回城后是否需要跳过当前目标(重试次数已耗尽则为 true) */
|
|
||||||
private boolean skipTargetAfterReturn;
|
|
||||||
/** 回城等待时长:发送 "/u return" 后等待传送回王城的毫秒数 */
|
|
||||||
private static final long RETURN_WAIT_MS = 10_000L;
|
|
||||||
/** 最近一次开垦进度(0-100) */
|
/** 最近一次开垦进度(0-100) */
|
||||||
private int lastProgress;
|
private int lastProgress;
|
||||||
/** 当前目标区块的哈希集合,用于去重(防止重复计数) */
|
/** 当前目标区块的哈希集合,用于去重(防止重复计数) */
|
||||||
@@ -188,8 +182,6 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
|||||||
this.claimedSet.clear();
|
this.claimedSet.clear();
|
||||||
this.target = null;
|
this.target = null;
|
||||||
this.eating = false;
|
this.eating = false;
|
||||||
this.returnCommandAtMillis = 0L;
|
|
||||||
this.skipTargetAfterReturn = false;
|
|
||||||
this.baritoneBridge.applyConfig(this.config);
|
this.baritoneBridge.applyConfig(this.config);
|
||||||
this.setState(State.PLANNING, "\u6b63\u5728\u751f\u6210\u6269\u5f20\u8ba1\u5212");
|
this.setState(State.PLANNING, "\u6b63\u5728\u751f\u6210\u6269\u5f20\u8ba1\u5212");
|
||||||
this.log("\u5f00\u59cb\u81ea\u52a8\u6269\u5730\uff0c\u90a6\u56fd\uff1a" + this.model.selfStateName());
|
this.log("\u5f00\u59cb\u81ea\u52a8\u6269\u5730\uff0c\u90a6\u56fd\uff1a" + this.model.selfStateName());
|
||||||
@@ -204,8 +196,6 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
|||||||
}
|
}
|
||||||
this.baritoneBridge.cancel();
|
this.baritoneBridge.cancel();
|
||||||
this.eating = false;
|
this.eating = false;
|
||||||
this.returnCommandAtMillis = 0L;
|
|
||||||
this.skipTargetAfterReturn = false;
|
|
||||||
this.setState(State.STOPPED, "\u5df2\u624b\u52a8\u505c\u6b62");
|
this.setState(State.STOPPED, "\u5df2\u624b\u52a8\u505c\u6b62");
|
||||||
this.log("\u5df2\u624b\u52a8\u505c\u6b62");
|
this.log("\u5df2\u624b\u52a8\u505c\u6b62");
|
||||||
}
|
}
|
||||||
@@ -302,33 +292,13 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 寻路阶段每帧逻辑:到达目标区块后进入等待开垦状态;
|
* 寻路阶段每帧逻辑:到达目标区块后进入等待开垦状态;
|
||||||
* 若寻路超时则重试,超过重试次数则跳过该目标。
|
* 若寻路超时则重新寻路(而非回城),超过重试次数则跳过该目标。
|
||||||
*/
|
*/
|
||||||
private void tickPathing() {
|
private void tickPathing() {
|
||||||
if (this.target == null) {
|
if (this.target == null) {
|
||||||
this.setState(State.NEXT, "\u76ee\u6807\u4e3a\u7a7a");
|
this.setState(State.NEXT, "\u76ee\u6807\u4e3a\u7a7a");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 正处于"回城恢复等待"中(已发送 /u return):等待传送回王城,暂不处理超时/到达
|
|
||||||
if (this.returnCommandAtMillis > 0L) {
|
|
||||||
// 等待窗口未结束:静默等待,让 /u return 完成传送
|
|
||||||
if (System.currentTimeMillis() - this.returnCommandAtMillis < RETURN_WAIT_MS) {
|
|
||||||
this.status = "\u5bfb\u8def\u8d85\u65f6\uff0c\u6b63\u5728\u56de\u57ce\uff08/u return\uff09";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 等待窗口结束:取消回城等待;据重试次数决定重寻路或跳过
|
|
||||||
this.returnCommandAtMillis = 0L;
|
|
||||||
if (this.skipTargetAfterReturn) {
|
|
||||||
this.skipTargetAfterReturn = false;
|
|
||||||
this.log("\u5bfb\u8def\u8d85\u65f6\uff0c\u56de\u57ce\u540e\u8df3\u8fc7 " + this.target.x() + "," + this.target.z());
|
|
||||||
this.setState(State.FAIL, "\u5bfb\u8def\u8d85\u65f6");
|
|
||||||
this.dataService.refreshAsync();
|
|
||||||
} else {
|
|
||||||
this.log("\u5df2\u56de\u57ce\uff0c\u91cd\u65b0\u5bfb\u8def\u524d\u5f80 " + this.target.x() + "," + this.target.z());
|
|
||||||
this.retrySameTarget("\u5df2\u56de\u57ce\uff0c\u91cd\u65b0\u524d\u5f80 " + this.target.x() + "," + this.target.z());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 目标已被他人占领(地图刷新后发现):立即跳过,避免继续寻路到无效区块
|
// 目标已被他人占领(地图刷新后发现):立即跳过,避免继续寻路到无效区块
|
||||||
if (this.skipIfTargetClaimed("\u76ee\u6807\u5df2\u88ab\u5360\u9886")) {
|
if (this.skipIfTargetClaimed("\u76ee\u6807\u5df2\u88ab\u5360\u9886")) {
|
||||||
return;
|
return;
|
||||||
@@ -354,16 +324,17 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
|||||||
long elapsedSeconds = (System.currentTimeMillis() - this.stageStartedMillis) / 1000L;
|
long elapsedSeconds = (System.currentTimeMillis() - this.stageStartedMillis) / 1000L;
|
||||||
if (elapsedSeconds >= this.config.waitTimeoutSeconds) {
|
if (elapsedSeconds >= this.config.waitTimeoutSeconds) {
|
||||||
++this.retryCount;
|
++this.retryCount;
|
||||||
// 主动刷新地图,尽快同步"区块已被占领"的最新状态,避免玩家被困
|
// 主动刷新地图,尽快同步最新领土状态
|
||||||
this.dataService.refreshAsync();
|
this.dataService.refreshAsync();
|
||||||
// 寻路超时:发送 /u return 回城,等待传送回王城后重新寻路;重试次数耗尽则回城后跳过
|
if (this.retryCount >= this.config.retries) {
|
||||||
this.skipTargetAfterReturn = this.retryCount >= this.config.retries;
|
// 重试耗尽:跳过当前目标(不再回城),交给下一个目标
|
||||||
if (this.skipTargetAfterReturn) {
|
this.log("\u5bfb\u8def\u8d85\u65f6\uff0c\u8df3\u8fc7 " + this.target.x() + "," + this.target.z());
|
||||||
this.log("\u5bfb\u8def\u8d85\u65f6\uff0c\u56de\u57ce\u540e\u8df3\u8fc7 " + this.target.x() + "," + this.target.z());
|
this.setState(State.FAIL, "\u5bfb\u8def\u8d85\u65f6");
|
||||||
} else {
|
} else {
|
||||||
this.log("\u5bfb\u8def\u8d85\u65f6\uff0c\u56de\u57ce\u91cd\u8bd5 " + this.retryCount + "/" + this.config.retries);
|
// 重新寻路(而非回城):取消旧路径并重新计算,往往“在边上走走”就能走出困境
|
||||||
|
this.log("\u5bfb\u8def\u8d85\u65f6\uff0c\u91cd\u65b0\u5bfb\u8def " + this.retryCount + "/" + this.config.retries);
|
||||||
|
this.retrySameTarget("\u5bfb\u8def\u8d85\u65f6\uff0c\u91cd\u65b0\u5bfb\u8def");
|
||||||
}
|
}
|
||||||
this.issueReturnCommand();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,21 +372,6 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送 "/u return" 回城指令,取消当前寻路,并记录发送时刻以进入回城恢复等待。
|
|
||||||
* 服务器会在约 10 秒后将玩家传送回邦国王城,届时由 tickPathing 重新寻路。
|
|
||||||
*/
|
|
||||||
private void issueReturnCommand() {
|
|
||||||
this.baritoneBridge.cancel();
|
|
||||||
MinecraftClient client = MinecraftClient.getInstance();
|
|
||||||
if (client != null && client.player != null && client.player.networkHandler != null) {
|
|
||||||
// sendChatCommand 需传不带斜杠的命令("/u return" -> "u return")
|
|
||||||
client.player.networkHandler.sendChatCommand("u return");
|
|
||||||
}
|
|
||||||
this.returnCommandAtMillis = System.currentTimeMillis();
|
|
||||||
this.status = "\u5bfb\u8def\u8d85\u65f6\uff0c\u5df2\u53d1\u9001 /u return \u56de\u57ce";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 重试当前目标:取消旧寻路,重新让 Baritone 前往同一目标区块 */
|
/** 重试当前目标:取消旧寻路,重新让 Baritone 前往同一目标区块 */
|
||||||
private void retrySameTarget(String statusText) {
|
private void retrySameTarget(String statusText) {
|
||||||
// 目标已被他人占领(地图刷新后发现):不再重试,直接跳过,避免玩家被困在已占领区块
|
// 目标已被他人占领(地图刷新后发现):不再重试,直接跳过,避免玩家被困在已占领区块
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户