From 08e15ffc9be44c190b229c66c6179059c5aa5504 Mon Sep 17 00:00:00 2001 From: lyizai <3945107889@qq.com> Date: Fri, 21 Aug 2026 16:10:02 +0800 Subject: [PATCH] =?UTF-8?q?v1.2.4:=20=E8=BF=9E=E7=BB=AD=E5=AF=BB=E8=B7=AF?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E8=B6=85=E8=BF=871=E5=88=86=E9=92=9F?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=8F=91=E9=80=81/u=20return=E5=9B=9E?= =?UTF-8?q?=E5=9F=8E=EF=BC=8C=E4=BC=A0=E9=80=81=E5=90=8E=E4=BB=8E=E6=9C=80?= =?UTF-8?q?=E9=AB=98=E4=BC=98=E5=85=88=E7=BA=A7=E5=8C=BA=E5=9D=97=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E6=89=A9=E5=9C=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- gradle.properties | 2 +- .../client/config/ExpansionConfig.java | 8 +++ .../controller/ExpansionController.java | 60 ++++++++++++++++++- src/main/resources/fabric.mod.json | 2 +- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bb3dce9..7157cf3 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ - 四种扩地策略:方形外扩、区域扩地、玩家周围、绕国一圈 - 区域扩地采用 S 形扫描:从与己方领土接壤的区块开始,横向/纵向 S 形扫过整个矩形,不沿邦国边界,但保证每个新占领区块都与**己方领土**接壤(仅四个正方向,不把其他邦国领土计入接壤) - 自动寻路(Baritone)前往目标区块;监听 Baritone 路径事件,目标不可达(CALC_FAILED,如被悬崖/高山/水体隔断)时立即跳过;寻路超时则重新寻路(不立即回城),重试耗尽才跳过当前目标 +- 连续寻路超时回城:连续寻路超时累计超过 1 分钟(可配置)时自动发送 `/u return`,约 10 秒后传送到可寻路位置,随后重新规划并从最高优先级区块重新开始扩地 - 运行时接壤校验:寻路/等待阶段每帧校验目标是否仍与己方领土接壤,地图刷新导致边界变化时立即跳过 - 目标有效性校验:目标若已被其他邦国占领则立即跳过 - 现实时间限制:仅 11:00-22:00(本地现实时间)允许开拓,其余时段启动会被拒绝、运行中到点自动停止 @@ -24,7 +25,7 @@ ## 安装 1. 安装 Fabric Loader 0.16.14+ 和 Fabric API -2. 将 `autostore-1.2.3.jar` 放入 `.minecraft/mods/` 目录 +2. 将 `autostore-1.2.4.jar` 放入 `.minecraft/mods/` 目录 3. 启动游戏,按 `Ctrl+R` 打开 GUI ## 构建 @@ -34,7 +35,7 @@ ./build_mod.sh ``` -输出文件:`autostore-1.2.3.jar` +输出文件:`autostore-1.2.4.jar` ## 赞助支持 diff --git a/gradle.properties b/gradle.properties index 1f5ee24..259d9ee 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=1.2.3 +mod_version=1.2.4 maven_group=autostore archives_base_name=autostore diff --git a/src/main/java/autostore/client/config/ExpansionConfig.java b/src/main/java/autostore/client/config/ExpansionConfig.java index 0b5f88b..54d1676 100644 --- a/src/main/java/autostore/client/config/ExpansionConfig.java +++ b/src/main/java/autostore/client/config/ExpansionConfig.java @@ -31,6 +31,12 @@ public class ExpansionConfig { /** 超时后的最大重试次数 */ public int retries = 2; + /** 连续寻路超时累计达到该秒数后,发送 /u return 回城传送并重新开始(默认 60 秒) */ + public int returnThresholdSeconds = 60; + + /** 发送 /u return 后等待传送完成的时间(秒);默认 12 秒,覆盖 10 秒传送延迟并留余量 */ + public int returnWaitSeconds = 12; + /** 区域扩地策略的中心 X 坐标(区块) */ public int regionCenterX; @@ -94,6 +100,8 @@ public class ExpansionConfig { c.targetCount = this.targetCount; c.waitTimeoutSeconds = this.waitTimeoutSeconds; c.retries = this.retries; + c.returnThresholdSeconds = this.returnThresholdSeconds; + c.returnWaitSeconds = this.returnWaitSeconds; c.regionCenterX = this.regionCenterX; c.regionCenterZ = this.regionCenterZ; c.regionRadius = this.regionRadius; diff --git a/src/main/java/autostore/client/controller/ExpansionController.java b/src/main/java/autostore/client/controller/ExpansionController.java index a74001d..525d5c7 100644 --- a/src/main/java/autostore/client/controller/ExpansionController.java +++ b/src/main/java/autostore/client/controller/ExpansionController.java @@ -95,6 +95,10 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { private volatile boolean pathCalcFailed; /** 等待开拓时段自动开始:不在 11:00-22:00 时点击开始会暂存配置,进入时段后自动启动(null 表示无等待任务) */ private ExpansionConfig pendingStart; + /** 连续寻路超时累计时长(毫秒):多次寻路超时逐次累加,达到阈值触发 /u return 回城传送 */ + private long consecutiveTimeoutMillis; + /** 发送 /u return 回城指令的时间戳(RETURNING 状态使用,用于等待传送完成) */ + private long returnStartMillis; public ExpansionController(TerritoryDataService dataService) { this.dataService = dataService; @@ -211,6 +215,7 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { } this.completedClaims = 0; this.retryCount = 0; + this.consecutiveTimeoutMillis = 0L; this.queue.clear(); this.claimedSet.clear(); this.target = null; @@ -298,6 +303,10 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { this.tickNext(); break; } + case 7: { + this.tickReturning(); + break; + } } } @@ -379,6 +388,8 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { } if (this.playerChunk.equals(this.target)) { this.baritoneBridge.cancel(); + // 成功到达目标:寻路不再卡死,清零连续超时计数 + this.consecutiveTimeoutMillis = 0L; this.stageStartedMillis = System.currentTimeMillis(); this.setState(State.WAITING, "\u5df2\u5230\u8fbe\uff0c\u7b49\u5f85\u9886\u5730\u5f00\u62d3"); this.log("\u5df2\u5230\u8fbe\u76ee\u6807 " + this.target.x() + "," + this.target.z() + "\uff0c\u5f00\u59cb\u7b49\u5f85\u5f00\u57a6"); @@ -389,7 +400,12 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { ++this.retryCount; // 主动刷新地图,尽快同步最新领土状态 this.dataService.refreshAsync(); - if (this.retryCount >= this.config.retries) { + // 累计"连续寻路超时"时长:连续多次寻路都超时说明玩家被地形/缝隙卡死走不到目标, + // 累计达到阈值后发送 /u return 回城(约 10 秒后传送到可寻路位置),传送后重新规划。 + this.consecutiveTimeoutMillis += (long)this.config.waitTimeoutSeconds * 1000L; + if (this.consecutiveTimeoutMillis >= (long)this.config.returnThresholdSeconds * 1000L) { + this.sendReturnCommand(); + } else if (this.retryCount >= this.config.retries) { // 重试耗尽:跳过当前目标(不再回城),交给下一个目标 this.log("\u5bfb\u8def\u8d85\u65f6\uff0c\u8df3\u8fc7 " + this.target.x() + "," + this.target.z()); this.setState(State.FAIL, "\u5bfb\u8def\u8d85\u65f6"); @@ -401,6 +417,43 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { } } + /** + * 连续寻路超时达到阈值时触发回城: + * 取消当前寻路,向服务器发送 /u return 指令(约 10 秒后自动传送回可寻路的安全位置), + * 随后进入 RETURNING 状态等待传送完成,传送后由 {@link #tickReturning()} 重新规划并从头开始。 + */ + private void sendReturnCommand() { + this.baritoneBridge.cancel(); + MinecraftClient client = MinecraftClient.getInstance(); + if (client != null && client.player != null) { + this.log("\u8fde\u7eed\u5bfb\u8def\u8d85\u65f6\u8d85\u8fc7 " + this.config.returnThresholdSeconds + " \u79d2\uff0c\u53d1\u9001 /u return \u56de\u57ce\uff0c10 \u79d2\u540e\u81ea\u52a8\u4f20\u9001"); + // 通过玩家网络处理器发送聊天指令 /u return(Yarn 映射:sendChatCommand 自动带上前缀斜杠) + client.player.networkHandler.sendChatCommand("u return"); + client.player.sendMessage(Text.literal("[AutoStore] \u8fde\u7eed\u5bfb\u8def\u8d85\u65f6\uff0c\u5df2\u53d1\u9001 /u return\uff0c\u7b49\u5f85\u4f20\u9001\u540e\u91cd\u65b0\u6269\u5730"), false); + } else { + this.log("\u8fde\u7eed\u5bfb\u8def\u8d85\u65f6\uff0c\u4f46\u73a9\u5bb6\u4e0d\u5728\u4e16\u754c\uff0c\u8df3\u8fc7"); + } + this.returnStartMillis = System.currentTimeMillis(); + this.setState(State.RETURNING, "\u7b49\u5f85\u56de\u57ce\u4f20\u9001\uff0810 \u79d2\u540e\u81ea\u52a8\u4f20\u9001\uff09"); + } + + /** + * 回城传送等待阶段每帧逻辑: + * 发送 /u return 后服务器约 10 秒把玩家传送回安全位置。等待 {@code returnWaitSeconds} + * 秒(覆盖传送延迟并留余量)后,清零连续超时计数并重新规划扩地计划, + * 从最高优先级区块(队首)重新开始寻路。 + */ + private void tickReturning() { + long elapsedMillis = System.currentTimeMillis() - this.returnStartMillis; + if (elapsedMillis < (long)this.config.returnWaitSeconds * 1000L) { + return; + } + this.consecutiveTimeoutMillis = 0L; + this.log("\u56de\u57ce\u4f20\u9001\u5b8c\u6210\uff0c\u91cd\u65b0\u89c4\u5212\u5e76\u4ece\u6700\u9ad8\u4f18\u5148\u7ea7\u533a\u5757\u5f00\u59cb"); + // 重新规划:清空队列重新生成计划,从队首(最高优先级)区块开始寻路 + this.plan(); + } + /** 等待开垦阶段每帧逻辑:玩家离开目标区块则重新寻路;等待超时则重试或跳过当前目标 */ private void tickWaiting() { if (this.target == null) { @@ -622,6 +675,8 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { // 缩短"会话占领等待确认"窗口,避免假占领长时间残留 this.dataService.refreshAsync(); ++this.completedClaims; + // 开垦成功:寻路/等待恢复正常,清零连续超时计数 + this.consecutiveTimeoutMillis = 0L; this.target = chunk; this.lastProgress = 100; this.log("\u5360\u9886\u6210\u529f " + chunk.x() + "," + chunk.z() + "\uff08\u533a\u5757 " + chunk.x() + "," + chunk.z() + " / \u4e16\u754c " + blockX + "," + blockZ + "\uff09"); @@ -652,6 +707,8 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { // 占领成功后立即触发一次地图刷新,尽快确认该区块 this.dataService.refreshAsync(); ++this.completedClaims; + // 开垦成功:寻路/等待恢复正常,清零连续超时计数 + this.consecutiveTimeoutMillis = 0L; this.lastProgress = 100; this.log("\u5360\u9886\u6210\u529f " + this.target.x() + "," + this.target.z()); this.setState(State.SUCCESS, "\u7586\u571f\u5df2\u5f00\u62d3 " + this.target.x() + "," + this.target.z()); @@ -826,6 +883,7 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener { SUCCESS, FAIL, NEXT, + RETURNING, COMPLETE, STOPPED; diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4dd5cda..6c5fb4c 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1 +1 @@ -{"schemaVersion":1,"id":"autostore","version":"1.2.3","name":"AutoStore","description":"","authors":[],"contact":{},"license":"All-Rights-Reserved","environment":"client","entrypoints":{"fabric-datagen":["autostore.client.AutoStoreModDataGenerator"],"client":["autostore.client.AutoStoreModClient"],"main":["autostore.AutoStoreMod"]},"mixins":["autostore.mixins.json",{"config":"autostore.client.mixins.json","environment":"client"}],"depends":{"fabricloader":">=0.16.14","fabric-api":"*","minecraft":"1.21.4"},"jars":[{"file":"META-INF/jars/baritone-api-fabric-1.13.1.jar"}]} \ No newline at end of file +{"schemaVersion":1,"id":"autostore","version":"1.2.4","name":"AutoStore","description":"","authors":[],"contact":{},"license":"All-Rights-Reserved","environment":"client","entrypoints":{"fabric-datagen":["autostore.client.AutoStoreModDataGenerator"],"client":["autostore.client.AutoStoreModClient"],"main":["autostore.AutoStoreMod"]},"mixins":["autostore.mixins.json",{"config":"autostore.client.mixins.json","environment":"client"}],"depends":{"fabricloader":">=0.16.14","fabric-api":"*","minecraft":"1.21.4"},"jars":[{"file":"META-INF/jars/baritone-api-fabric-1.13.1.jar"}]} \ No newline at end of file