diff --git a/src/main/java/Sdf1_login/AreaProtection.java b/src/main/java/Sdf1_login/AreaProtection.java index 97721e9..a4d1904 100644 --- a/src/main/java/Sdf1_login/AreaProtection.java +++ b/src/main/java/Sdf1_login/AreaProtection.java @@ -19,6 +19,7 @@ import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.SignChangeEvent; import org.bukkit.entity.Entity; import org.bukkit.entity.Animals; import org.bukkit.event.player.PlayerInteractAtEntityEvent; @@ -4986,6 +4987,25 @@ public class AreaProtection implements Listener { } } + @EventHandler + public void onSignChange(SignChangeEvent e) { + Player p = e.getPlayer(); + if (p.hasPermission("sdf1.admin")) return; // 管理员跳过 + AreaConfig ac = getArea( + p.getWorld().getName(), + e.getBlock().getX(), + e.getBlock().getY(), + e.getBlock().getZ()); + if (ac == null) return; + if (p.getName().equalsIgnoreCase(ac.owner)) return; // 领地主免检 + if (isAreaAdmin(p)) return; // 插件管理员免检 + + if (getEffectiveDeny(p, ac, "denyBlockPlace")) { + e.setCancelled(true); + p.sendMessage("§c§l[区域防护] §f禁止编辑告示牌"); + } + } + @EventHandler public void onDamage(EntityDamageEvent e) { diff --git a/src/main/java/Sdf1_login/DatabaseManager.java b/src/main/java/Sdf1_login/DatabaseManager.java index a61831c..9efd32f 100644 --- a/src/main/java/Sdf1_login/DatabaseManager.java +++ b/src/main/java/Sdf1_login/DatabaseManager.java @@ -2327,62 +2327,52 @@ public class DatabaseManager { String extra, int level, double experience) { try { - PreparedStatement ps = - db.prepareStatement( - "INSERT INTO inv_backup_auto" - + " (player_name, " - + "contents_b64, " - + "armor_b64, " - + "extra_b64, " - + "level, " - + "experience, " - + "save_time) " - + "VALUES (?,?,?,?,?,?,?)"); - ps.setString(1, name); - ps.setString(2, contents); - ps.setString(3, armor); - ps.setString(4, extra); - ps.setInt(5, level); - ps.setDouble(6, experience); - ps.setLong(7, System.currentTimeMillis()); - ps.executeUpdate(); - ps.close(); + try (PreparedStatement ps = db.prepareStatement( + "INSERT INTO inv_backup_auto " + + "(player_name, contents_b64, armor_b64, " + + "extra_b64, level, experience, save_time) " + + "VALUES (?,?,?,?,?,?,?)")) { + ps.setString(1, name); + ps.setString(2, contents); + ps.setString(3, armor); + ps.setString(4, extra); + ps.setInt(5, level); + ps.setDouble(6, experience); + ps.setLong(7, System.currentTimeMillis()); + ps.executeUpdate(); + } - // 仅保留最近 3 份,删除该玩家更早的备份(先查后删,避免 LIMIT 子查询被优化) - try { - PreparedStatement sel = - db.prepareStatement( - "SELECT id FROM inv_backup_auto " - + "WHERE player_name=? " - + "ORDER BY save_time DESC LIMIT 3"); + // 保留最近 3 份 —— 先查最新 3 个 ID,再删其余 + List keep = new ArrayList<>(); + try (PreparedStatement sel = db.prepareStatement( + "SELECT id FROM inv_backup_auto " + + "WHERE player_name=? " + + "ORDER BY save_time DESC LIMIT 3")) { sel.setString(1, name); - ResultSet rs = sel.executeQuery(); - List keep = new ArrayList<>(); - while (rs.next()) { - keep.add(rs.getInt("id")); + try (ResultSet rs = sel.executeQuery()) { + while (rs.next()) keep.add(rs.getInt("id")); } - rs.close(); - sel.close(); + } - if (keep.size() == 3) { - StringBuilder in = new StringBuilder(); - for (int i = 0; i < keep.size(); i++) { - if (i > 0) in.append(","); - in.append(keep.get(i)); + if (keep.size() == 3) { + StringBuilder in = new StringBuilder(); + for (int i = 0; i < keep.size(); i++) { + if (i > 0) in.append(","); + in.append(keep.get(i)); + } + try (PreparedStatement del = db.prepareStatement( + "DELETE FROM inv_backup_auto " + + "WHERE player_name=? AND id NOT IN (" + + in + ")")) { + del.setString(1, name); + int removed = del.executeUpdate(); + if (removed > 0) { + logger.info("[自动备份] " + name + " 滚动清理 " + removed + " 份旧备份"); } - PreparedStatement del = db.prepareStatement( - "DELETE FROM inv_backup_auto " - + "WHERE player_name=? AND id NOT IN (" - + in.toString() + ")"); - del.setString(1, name); - del.executeUpdate(); - del.close(); } - } catch (SQLException e) { - e.printStackTrace(); } } catch (SQLException e) { - e.printStackTrace(); + logger.warning("[自动备份] 保存/清理失败 (" + name + "): " + e.getMessage()); } } diff --git a/src/main/java/Sdf1_login/InventoryAutoBackup.java b/src/main/java/Sdf1_login/InventoryAutoBackup.java index ceacf09..55bdbff 100644 --- a/src/main/java/Sdf1_login/InventoryAutoBackup.java +++ b/src/main/java/Sdf1_login/InventoryAutoBackup.java @@ -75,5 +75,6 @@ public class InventoryAutoBackup { plugin.getDb().saveAutoBackup( name, contentsB64, armorB64, extraB64, level, experience); + plugin.getLogger().info("[自动备份] " + name + " 背包已备份"); } }