diff --git a/.gitignore b/.gitignore index 1baf1b3..3599fd1 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ txt/ backup/ 新建*.txt 群戏归类.txt +upload_sftp.py # PHP Web 后端 web/Web.db diff --git a/src/main/java/Sdf1_login/AreaCLIManager.java b/src/main/java/Sdf1_login/AreaCLIManager.java index 76aff45..b64d29e 100644 --- a/src/main/java/Sdf1_login/AreaCLIManager.java +++ b/src/main/java/Sdf1_login/AreaCLIManager.java @@ -645,6 +645,14 @@ public class AreaCLIManager { return; } + // ★ 权限检查:只有所有者或管理员能编辑成员权限 + boolean isOwner = p.getName().equalsIgnoreCase(land.owner); + boolean isAdmin = areaProtect.isAreaAdmin(p); + if (!isOwner && !isAdmin) { + p.sendMessage(Component.text("§c需要领地所有者或管理员权限")); + return; + } + // 获取成员列表 Set members = areaProtect.getAreaMembers(landName); if (members == null || members.isEmpty()) { @@ -668,9 +676,9 @@ public class AreaCLIManager { for (int i = start; i < end; i++) { String member = memberList.get(i); - boolean isOwner = member.equalsIgnoreCase(land.owner); + boolean isMemberOwner = member.equalsIgnoreCase(land.owner); - String roleTag = isOwner ? " §c[所有者]" : ""; + String roleTag = isMemberOwner ? " §c[所有者]" : ""; Component line = Component.empty(); line = line.append(Component.text("§e● " + member + roleTag)); line = line.append(Component.text(" ")); @@ -720,6 +728,14 @@ public class AreaCLIManager { return; } + // ★ 权限检查:只有所有者或管理员能编辑成员权限 + boolean isOwner = p.getName().equalsIgnoreCase(land.owner); + boolean isAdmin = areaProtect.isAreaAdmin(p); + if (!isOwner && !isAdmin) { + p.sendMessage(Component.text("§c需要领地所有者或管理员权限")); + return; + } + int landId = areaProtect.getLandIdFromDb(landName); if (landId <= 0) { p.sendMessage(Component.text("§c领地数据库ID获取失败")); diff --git a/src/main/java/Sdf1_login/AreaGUIManager.java b/src/main/java/Sdf1_login/AreaGUIManager.java index 05efcaa..09ef220 100644 --- a/src/main/java/Sdf1_login/AreaGUIManager.java +++ b/src/main/java/Sdf1_login/AreaGUIManager.java @@ -698,7 +698,7 @@ public class AreaGUIManager implements Listener { (land.z1 + land.z2) / 2.0 ); p.teleport(tpLoc); - p.sendMessage("§a已传送到领地: " + land.name); + // ★ GUI模式不发送聊天消息 } } else if (raw == 45 && page > 0) { openLandList(p, page - 1); @@ -737,7 +737,7 @@ public class AreaGUIManager implements Listener { (land.z1 + land.z2) / 2.0 ); p.teleport(tpLoc); - p.sendMessage("§a已传送到领地: " + landName); + // ★ GUI模式不发送聊天消息 } } else if (raw == 48) { openLandList(p, 0); @@ -765,7 +765,7 @@ public class AreaGUIManager implements Listener { } else if (event.isRightClick()) { // 右键:移除成员 areaProtect.removeLandMember(landName, member); - p.sendMessage("§a已移除成员: " + member); + // ★ GUI模式不发送聊天消息 openMemberList(p, landName, page); } } else if (raw == 45) { @@ -797,7 +797,7 @@ public class AreaGUIManager implements Listener { if (raw >= 0 && raw < (end - start)) { PermEntry perm = perms.get(start + raw); togglePerm(land, perm.name); - p.sendMessage("§a已切换权限: " + perm.name); + // ★ GUI模式不发送聊天消息(视觉反馈已在GUI中体现) openVisitorPerm(p, landName, page); } else if (raw == 45 && page > 0) { openVisitorPerm(p, landName, page - 1); @@ -871,13 +871,13 @@ public class AreaGUIManager implements Listener { : getLandDefaultVal(land, field); boolean newVal = !currentVal; areaProtect.setPlayerPerm(landId, targetPlayer, field, newVal); - p.sendMessage("§a已设置 §e" + targetPlayer + " §a的权限"); + // ★ GUI模式不发送聊天消息 openPlayerPerm(p, landName, targetPlayer); } } else if (raw == 48) { // 清除所有自定义权限 areaProtect.setPlayerPermJson(landId, targetPlayer, ""); - p.sendMessage("§a已清除 §e" + targetPlayer + " §a的所有自定义权限"); + // ★ GUI模式不发送聊天消息 openMemberPermList(p, landName); } else if (raw == 49) { // 返回成员列表 @@ -900,7 +900,7 @@ public class AreaGUIManager implements Listener { String playerName = meta.getDisplayName() .replaceAll("§[0-9a-fk-orA-FK-OR]", ""); areaProtect.addLandMember(landName, playerName); - p.sendMessage("§a已添加成员: " + playerName); + // ★ GUI模式不发送聊天消息 openAddMember(p, landName); } } @@ -923,13 +923,13 @@ public class AreaGUIManager implements Listener { // 切换公告 land.enableAnnounce = !land.enableAnnounce; areaProtect.saveAreaToDb(land); - p.sendMessage("§a领地公告: " + (land.enableAnnounce ? "§a已启用" : "§c已禁用")); + // ★ GUI模式不发送聊天消息 openLandSettings(p, landName); } else if (raw == 13) { // 切换和平模式 land.peaceMode = !land.peaceMode; areaProtect.saveAreaToDb(land); - p.sendMessage("§a和平模式: " + (land.peaceMode ? "§a已启用" : "§c已禁用")); + // ★ GUI模式不发送聊天消息 openLandSettings(p, landName); } else if (raw == 15) { // 切换强制游戏模式 @@ -1103,7 +1103,7 @@ public class AreaGUIManager implements Listener { } } p.getInventory().addItem(wand); - p.sendMessage("§a已获取圈地工具(木棍),左键/右键选择区域边界"); + // ★ GUI模式不发送聊天消息 areaProtect.wandCooldownMap.put(p.getUniqueId(), now); } diff --git a/src/main/java/Sdf1_login/AreaProtection.java b/src/main/java/Sdf1_login/AreaProtection.java index 5b94641..b6a30b2 100644 --- a/src/main/java/Sdf1_login/AreaProtection.java +++ b/src/main/java/Sdf1_login/AreaProtection.java @@ -101,7 +101,7 @@ public class AreaProtection implements Listener { private int globalDefaultHeight = 255; // 默认高度 // 选地 - private static final Material WAND = Material.BREEZE_ROD; + private static final Material WAND = Material.BLAZE_ROD; private final Map pos1 = new ConcurrentHashMap<>(); @@ -4165,7 +4165,7 @@ public class AreaProtection implements Listener { if (hand == null) return; // ===== 选区工具 ===== - if (hand.getType() == Material.BREEZE_ROD) { + if (hand.getType() == Material.BLAZE_ROD) { ItemMeta meta = hand.getItemMeta(); if (meta != null && meta.getDisplayName() != null && meta.getDisplayName().contains("区域选择")) { @@ -5339,29 +5339,33 @@ public class AreaProtection implements Listener { try { switch (key) { case "create_price": - globalCreatePricePerSqm = Integer.parseInt(value); - updateAreaConfig("create_price_per_sqm", value); - sender.sendMessage("§a创建价格已更新为: " + value + "/㎡"); + globalCreatePricePerSqm = parseSmartNumber(value, globalCreatePricePerSqm, 0); + updateAreaConfig("create_price_per_sqm", String.valueOf(globalCreatePricePerSqm)); break; case "max_lands": - globalMaxLandsPerPlayer = Integer.parseInt(value); - updateAreaConfig("max_lands_per_player", value); - sender.sendMessage("§a每人最大领地数已更新为: " + value); + globalMaxLandsPerPlayer = parseSmartNumber(value, globalMaxLandsPerPlayer, 1); + updateAreaConfig("max_lands_per_player", String.valueOf(globalMaxLandsPerPlayer)); break; case "default_height": - updateAreaConfig("default_height", value); - sender.sendMessage("§a默认高度已更新为: " + value); + int newHeight = parseSmartNumber(value, 255, 1); + updateAreaConfig("default_height", String.valueOf(newHeight)); break; case "peace_duration": - updateAreaConfig("peace_mode_max_duration", value); - sender.sendMessage("§a和平模式最大时长已更新为: " + value + "秒"); + int newDuration = parseSmartNumber(value, 3600, 0); + updateAreaConfig("peace_mode_max_duration", String.valueOf(newDuration)); break; default: sender.sendMessage("§c未知配置项: " + key); - break; + return true; } - } catch (NumberFormatException e) { - sender.sendMessage("§c值必须是数字"); + // ★ 更新后显示完整配置页面(而非仅打印"已更新") + if (plugin.areaCLIManager != null) { + plugin.areaCLIManager.showConfigPage((Player) sender); + } else { + sender.sendMessage("§a配置已更新"); + } + } catch (Exception e) { + sender.sendMessage("§c无效的值: " + value + "(支持: 纯数字、+/-前缀、中文数字、罗马数字、英文数字)"); } return true; } @@ -6935,6 +6939,49 @@ public class AreaProtection implements Listener { if (input == null || input.isEmpty()) return null; input = input.trim().toLowerCase(); + // ★ 支持 +/- 前缀(相对增减) + if (input.startsWith("+") || input.startsWith("-")) { + // +/- 前缀需要有后续数字 + String numPart = input.substring(1).trim(); + if (numPart.isEmpty()) return null; + Integer delta = parseSmartNumberBase(numPart); + if (delta == null) return null; + return input.startsWith("-") ? -delta : delta; + } + + return parseSmartNumberBase(input); + } + + /** + * ★ 智能数字解析(带默认值和下限) + * @param input 用户输入 + * @param current 当前值(用于 +/- 计算) + * @param floor 最小值(封底) + */ + public static int parseSmartNumber(String input, int current, int floor) { + if (input == null || input.isEmpty()) return current; + input = input.trim().toLowerCase(); + + // ★ 支持 +/- 前缀(相对增减) + if (input.startsWith("+") || input.startsWith("-")) { + String numPart = input.substring(1).trim(); + if (numPart.isEmpty()) return current; + Integer delta = parseSmartNumberBase(numPart); + if (delta == null) return current; + int result = input.startsWith("-") ? current - delta : current + delta; + return Math.max(result, floor); + } + + // 纯数字(绝对值) + Integer abs = parseSmartNumberBase(input); + if (abs == null) return current; + return Math.max(abs, floor); + } + + private static Integer parseSmartNumberBase(String input) { + if (input == null || input.isEmpty()) return null; + input = input.trim().toLowerCase(); + // 1. 纯数字 try { return Integer.parseInt(input); diff --git a/upload_sftp.py b/upload_sftp.py deleted file mode 100644 index abb4d1c..0000000 --- a/upload_sftp.py +++ /dev/null @@ -1,16 +0,0 @@ -import paramiko -import sys - -ssh = paramiko.SSHClient() -ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) -try: - ssh.connect('sfe4-connect.simpfun.cn', port=2046, username='sfe3192491.df7d2f7f', password='5350427807', timeout=30) - sftp = ssh.open_sftp() - sftp.put('D:/桌面/源码/mc_plugn/Sdf1_login/target/Sdf1_login.jar', '/plugins/Sdf1_login.jar') - sftp.close() - print('SFTP upload success') -except Exception as e: - print(f'Error: {e}', file=sys.stderr) - sys.exit(1) -finally: - ssh.close()