From 6c738d484f07debe4596096b66a2a8c43c364afe Mon Sep 17 00:00:00 2001 From: youpaishidifu Date: Sat, 27 Jun 2026 22:03:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20pollAdminChanges=E5=8E=BB=E9=87=8D+ack?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=8C=E9=98=B2=E6=AD=A2owner=5Fchange?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Sdf1_login/WebManager.java | 40 ++++++++++++++++++------ 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/Sdf1_login/WebManager.java b/src/main/java/Sdf1_login/WebManager.java index 8b74614..f230055 100644 --- a/src/main/java/Sdf1_login/WebManager.java +++ b/src/main/java/Sdf1_login/WebManager.java @@ -3041,6 +3041,8 @@ public class WebManager { * 轮询PHP管理员变更(所有者变更、权限清除等) */ private long lastPollAdminChangesId = 0; + /** 已处理过的变更ID集合(防重复打印),最多保留500条 */ + private final java.util.HashSet processedChangeIds = new java.util.HashSet<>(); public void pollAdminChanges() { if (!enabled) return; @@ -3060,9 +3062,8 @@ public class WebManager { List> changes = (List>) result.get("changes"); if (changes == null || changes.isEmpty()) return; - // 无变更静默 - boolean hadChange = false; List ackedIds = new ArrayList<>(); + int maxId = 0; for (Map change : changes) { int id = ((Number) change.getOrDefault("id", 0)).intValue(); @@ -3070,10 +3071,19 @@ public class WebManager { String targetName = String.valueOf(change.getOrDefault("target_name", "")); String changeDataStr = String.valueOf(change.getOrDefault("change_data", "{}")); + if (id > maxId) maxId = id; + + // ★ 去重:已处理过的变更不再打印/执行 + if (processedChangeIds.contains(id)) { + ackedIds.add(id); + continue; + } + Map changeData = parseJson(changeDataStr); if (changeData == null) changeData = new HashMap<>(); try { + boolean applied = false; switch (changeType) { case "owner_change": { String newOwner = String.valueOf(changeData.getOrDefault("new_owner", "")); @@ -3081,7 +3091,7 @@ public class WebManager { if (!newOwner.isEmpty() && !landName.isEmpty()) { areaProtect.setLandOwnerFromWeb(landName, newOwner); plugin.getLogger().info("[Web通信] PHP端领地所有者变更: " + landName + " → " + newOwner); - hadChange = true; + applied = true; } break; } @@ -3091,7 +3101,7 @@ public class WebManager { if (!playerName.isEmpty() && !landNameJson.isEmpty()) { areaProtect.clearPlayerPermFromWeb(landNameJson, playerName); plugin.getLogger().info("[Web通信] PHP端清除成员权限: " + playerName + " @ " + landNameJson); - hadChange = true; + applied = true; } break; } @@ -3102,7 +3112,7 @@ public class WebManager { if (!playerName.isEmpty() && !landNameJson.isEmpty()) { areaProtect.updateVisitorPermFromWeb(landNameJson, playerName, permsJson); plugin.getLogger().info("[Web通信] PHP端更新访客权限: " + playerName + " @ " + landNameJson); - hadChange = true; + applied = true; } break; } @@ -3112,7 +3122,7 @@ public class WebManager { if (!field.isEmpty() && !targetName.isEmpty()) { areaProtect.updateLandFieldFromWeb(targetName, field, value); plugin.getLogger().info("[Web通信] PHP端更新领地字段: " + targetName + "." + field); - hadChange = true; + applied = true; } break; } @@ -3122,27 +3132,39 @@ public class WebManager { if (!configKey.isEmpty()) { areaProtect.setAreaConfigValue(configKey, configValue); plugin.getLogger().info("[Web通信] PHP端更新全局配置: " + configKey + " = " + configValue); - hadChange = true; + applied = true; } break; } default: plugin.getLogger().fine("[Web通信] 未知变更类型: " + changeType); } + // ★ 标记已处理(无论applied与否,防止无效条目反复拉取) + processedChangeIds.add(id); ackedIds.add(id); } catch (Exception e) { plugin.getLogger().warning("[Web通信] 处理变更失败(id=" + id + "): " + e.getMessage()); + processedChangeIds.add(id); + ackedIds.add(id); } } - if (!hadChange) return; // 无实际变更则静默 + // ★ 更新lastId游标,下次跳过已处理的 + if (maxId > lastPollAdminChangesId) { + lastPollAdminChangesId = maxId; + } - // 确认已处理的变更 + // ★ 无论是否有实际变更,都发送ack(防止无效条目永久堆积) if (!ackedIds.isEmpty()) { String idsStr = String.join(",", ackedIds.stream().map(String::valueOf).collect(Collectors.toList())); String ackUrl = webBaseUrl + "/api/land_api.php?action=ack_admin_changes&secret=" + java.net.URLEncoder.encode(secretKey, "UTF-8") + "&ids=" + java.net.URLEncoder.encode(idsStr, "UTF-8"); doGet(ackUrl); } + + // ★ 清理去重集合,防止内存泄漏 + if (processedChangeIds.size() > 500) { + processedChangeIds.clear(); + } } catch (Exception e) { plugin.getLogger().warning("[Web通信] 轮询PHP管理员变更异常: " + e.getMessage()); }