From 529b83666cbe67d555b905b4d6e4152cee481706 Mon Sep 17 00:00:00 2001 From: youpaishidifu Date: Sun, 12 Jul 2026 23:08:32 +0800 Subject: [PATCH] =?UTF-8?q?R23:=20=E4=BF=AE=E5=A4=8D4=E9=A1=B9=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20-=20=E6=94=B9=E5=90=8D=E5=86=B7=E5=8D=B4=E9=80=BB?= =?UTF-8?q?=E8=BE=91(=E4=BB=85=E8=BE=BE=E4=B8=8A=E9=99=90=E6=89=8D?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E5=86=B7=E5=8D=B4)=20+=20=E6=8B=A6=E6=88=AA?= =?UTF-8?q?=E5=8E=9F=E7=89=88/ban=E3=80=81/ban-ip=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E5=B9=BF=E6=92=AD=E5=B0=81=E7=A6=81=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Sdf1_login/AreaProtection.java | 3 + src/main/java/Sdf1_login/Main.java | 64 ++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/main/java/Sdf1_login/AreaProtection.java b/src/main/java/Sdf1_login/AreaProtection.java index 2ba0afb..4bf5a4d 100644 --- a/src/main/java/Sdf1_login/AreaProtection.java +++ b/src/main/java/Sdf1_login/AreaProtection.java @@ -9031,6 +9031,9 @@ public class AreaProtection implements Listener { int used = timestamps.size(); if (used == 0) return null; + // ★ 仅在达到上限时才提示冷却,未达上限时只显示剩余次数 + if (used < RENAME_LIMIT) return null; + long firstInWindow = timestamps.get(0); long unlockTime = firstInWindow + RENAME_WINDOW_MS; if (now >= unlockTime) return null; // 已解锁 diff --git a/src/main/java/Sdf1_login/Main.java b/src/main/java/Sdf1_login/Main.java index df4ffbf..53a79d7 100644 --- a/src/main/java/Sdf1_login/Main.java +++ b/src/main/java/Sdf1_login/Main.java @@ -91,6 +91,9 @@ public class Main extends JavaPlugin new HashMap<>(); public MenuManager menu; + // ★ 自身发起的封禁标记(防止PlayerBanEvent双重广播) + private final Set selfInitiatedBans = ConcurrentHashMap.newKeySet(); + private final Set loggedIn = new TreeSet<>( String.CASE_INSENSITIVE_ORDER); @@ -1030,12 +1033,19 @@ public class Main extends JavaPlugin org.bukkit.BanList.Type type = isIpTarget(target) ? org.bukkit.BanList.Type.IP : org.bukkit.BanList.Type.NAME; + // ★ 标记为自身发起(防止PlayerBanEvent双重广播) + selfInitiatedBans.add(target.toLowerCase()); + Bukkit.getBanList(type).addBan(target, reason, expireMs == null ? null : new java.util.Date(expireMs), sender.getName()); // ★ 公屏广播封禁警告 broadcastBanWarning(target, type, reason, expireMs, sender.getName()); + + // ★ 清除标记(延迟1秒,确保事件已触发) + String tgt = target.toLowerCase(); + Bukkit.getScheduler().runTaskLater(this, () -> selfInitiatedBans.remove(tgt), 20L); } /** @@ -2855,6 +2865,60 @@ public class Main extends JavaPlugin } } + // ★ 拦截原版 /ban、/ban-ip 命令,补充广播封禁警告(覆盖永久/临时封禁) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerCommandPreprocess(org.bukkit.event.player.PlayerCommandPreprocessEvent e) { + if (e.isCancelled()) return; + String msg = e.getMessage().trim(); + String lower = msg.toLowerCase(); + + boolean isNameBan = lower.equals("/ban") || lower.startsWith("/ban "); + boolean isIpBan = lower.equals("/ban-ip") || lower.startsWith("/ban-ip ") + || lower.equals("/banip") || lower.startsWith("/banip "); + if (!isNameBan && !isIpBan) return; + + // 解析 /ban [reason...] 或 /ban-ip [reason...] + String[] parts = msg.split("\\s+"); + if (parts.length < 2) return; + String target = parts[1]; + + // ★ 延迟2tick执行(等Vanilla ban完成后读取BanList) + Bukkit.getScheduler().runTaskLater(this, () -> { + try { + // 检查是否已被自身插件处理(防御重复广播) + if (selfInitiatedBans.remove(target.toLowerCase())) return; + + if (isNameBan) { + org.bukkit.BanList banList = Bukkit.getBanList(org.bukkit.BanList.Type.NAME); + org.bukkit.BanEntry entry = banList.getBanEntry(target); + if (entry == null) return; + String reason = entry.getReason() != null ? entry.getReason() : "已被服务器封禁"; + String source = entry.getSource() != null ? entry.getSource() : "Server"; + java.util.Date expireDate = entry.getExpiration(); + long expireMs = expireDate != null ? expireDate.getTime() : null; + broadcastBanWarning(target, org.bukkit.BanList.Type.NAME, reason, expireMs, source); + } else { + // IP封禁:target可能是玩家名或IP,尝试解析为IP + String ip = target; + org.bukkit.entity.Player tp = Bukkit.getPlayerExact(target); + if (tp != null && tp.getAddress() != null && tp.getAddress().getAddress() != null) { + ip = tp.getAddress().getAddress().getHostAddress(); + } + org.bukkit.BanList ipList = Bukkit.getBanList(org.bukkit.BanList.Type.IP); + org.bukkit.BanEntry entry = ipList.getBanEntry(ip); + if (entry == null) return; + String reason = entry.getReason() != null ? entry.getReason() : "已被服务器封禁"; + String source = entry.getSource() != null ? entry.getSource() : "Server"; + java.util.Date expireDate = entry.getExpiration(); + long expireMs = expireDate != null ? expireDate.getTime() : null; + broadcastBanWarning(ip, org.bukkit.BanList.Type.IP, reason, expireMs, source); + } + } catch (Exception ex) { + getLogger().warning("[封禁广播] 拦截ban命令异常: " + ex.getMessage()); + } + }, 2L); + } + @EventHandler(priority = EventPriority.HIGHEST) public void onProjectileLaunch( org.bukkit.event.entity.ProjectileLaunchEvent e) {