From d2a52199ae53336c02168c3a2da7fc39152d7a38 Mon Sep 17 00:00:00 2001 From: lyizai <3945107889@qq.com> Date: Tue, 18 Aug 2026 18:59:59 +0800 Subject: [PATCH] =?UTF-8?q?v1.1.8:=20=E5=88=B7=E6=96=B0=E5=9C=B0=E5=9B=BE?= =?UTF-8?q?=E6=97=B6=E6=A0=B8=E5=AF=B9=E5=B7=B2=E5=8D=A0=E9=A2=86=E5=8C=BA?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E4=B8=A2=E5=BC=83=E5=9C=B0=E5=9B=BE=E6=9C=AA?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E7=9A=84=E8=B6=85=E6=9C=9F=E5=81=87=E5=8D=A0?= =?UTF-8?q?=E9=A2=86=EF=BC=8C=E4=BF=AE=E5=A4=8D=E9=AB=98=E5=9C=B0=E7=A9=BA?= =?UTF-8?q?=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../territory/TerritoryDataService.java | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/main/java/autostore/client/territory/TerritoryDataService.java b/src/main/java/autostore/client/territory/TerritoryDataService.java index 8c3dc21..17fc798 100644 --- a/src/main/java/autostore/client/territory/TerritoryDataService.java +++ b/src/main/java/autostore/client/territory/TerritoryDataService.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -65,6 +66,16 @@ public final class TerritoryDataService { private volatile long lastSuccessfulFetchMillis; /** 最近一次尝试拉取的时间戳(毫秒) */ private volatile long lastAttemptMillis; + /** 会话内新占领区块的本地记录时间(毫秒),用于刷新时判断该占领是否已被地图数据确认 */ + private final Map sessionClaimTimes = new ConcurrentHashMap<>(); + /** + * 会话占领"确认宽限"时长(毫秒)。 + * + *

占领成功后,服务器动态地图(Dynmap/markers.json)可能尚未同步该区块, + * 因此在宽限期内即使地图未确认也先保留"会话占领"标记,避免刚占领的区块被误判为假占领。 + * 超过宽限期仍未在地图中确认的,视为未真正占领并丢弃,使空洞区块能重新进入规划。 + */ + private static final long CLAIM_CONFIRM_GRACE_MS = 120_000L; public TerritoryDataService() { this.executor = TerritoryDataService.newExecutor(); @@ -111,8 +122,8 @@ public final class TerritoryDataService { /** * 异步刷新领土数据(在调度线程中执行)。 - * 拉取成功后解析 JSON,并把上一份模型中的"会话新占领区块"合并进新模型, - * 避免刷新覆盖掉本次会话的占领记录。 + * 拉取成功后解析 JSON,并把上一份模型中的"会话新占领区块"与刚拉取的最新地图数据仔细核对, + * 只保留"已被地图确认"或"刚占领未超宽限期"的占领记录,避免刷新时把假占领永久留在模型里。 */ public void refreshAsync() { this.executor.execute(() -> { @@ -127,8 +138,25 @@ public final class TerritoryDataService { TerritoryModel parsed = TerritoryDataService.parse(response.body()); TerritoryModel previous = this.model; if (previous != null) { + long now = System.currentTimeMillis(); + // 本次拉取到的己方领土区块(地图数据即最终依据,无需缓存旧数据) + Set freshOwn = new HashSet<>(); + TerritoryState freshSelf = parsed.state(this.selectedStateName); + if (freshSelf != null) { + freshOwn.addAll(freshSelf.chunks()); + } for (ChunkPos sessionClaim : previous.sessionClaims()) { - parsed.addSessionClaim(sessionClaim); + Long claimTime = this.sessionClaimTimes.get(sessionClaim); + boolean confirmed = freshOwn.contains(sessionClaim); + boolean withinGrace = claimTime != null && now - claimTime < CLAIM_CONFIRM_GRACE_MS; + if (confirmed || withinGrace) { + // 地图已确认,或尚在宽限期(Dynmap 可能还没同步):保留会话占领标记 + parsed.addSessionClaim(sessionClaim); + } else if (claimTime != null) { + // 地图始终未确认且超时:判定为假占领并移除,使空洞区块重新进入规划 + this.sessionClaimTimes.remove(sessionClaim); + } + // claimTime 为 null(从未在本服务记录)也视为未确认:不保留 } } parsed.setSelfStateName(this.selectedStateName); @@ -163,6 +191,7 @@ public final class TerritoryDataService { } public void addSessionClaim(ChunkPos chunk) { + this.sessionClaimTimes.put(chunk, System.currentTimeMillis()); TerritoryModel current = this.model; if (current != null) { current.addSessionClaim(chunk);