diff --git a/src/main/java/Sdf1_login/AreaCLIManager.java b/src/main/java/Sdf1_login/AreaCLIManager.java index ffe6624..d0a21bf 100644 --- a/src/main/java/Sdf1_login/AreaCLIManager.java +++ b/src/main/java/Sdf1_login/AreaCLIManager.java @@ -938,7 +938,7 @@ public class AreaCLIManager { } // ★ 设为管理员按钮(全局置顶,打印在最后=聊天窗口最底部) - if (isOwner && !targetPlayer.equalsIgnoreCase(land.owner)) { + if ((isOwner || isAdmin) && !targetPlayer.equalsIgnoreCase(land.owner)) { Component adminLine = Component.empty(); adminLine = adminLine.append(Component.text("§7✘ §f身份: §7普通成员")); adminLine = adminLine.append(Component.text(" ")); diff --git a/src/main/java/Sdf1_login/AreaGUIManager.java b/src/main/java/Sdf1_login/AreaGUIManager.java index 847fb7c..cd6456e 100644 --- a/src/main/java/Sdf1_login/AreaGUIManager.java +++ b/src/main/java/Sdf1_login/AreaGUIManager.java @@ -435,14 +435,15 @@ public class AreaGUIManager implements Listener { Map playerPerms = areaProtect.getPlayerPermMap(landId, targetPlayer); int slot = 0; - // ★ 权限检查:只有所有者或管理员能编辑成员权限 + // ★ 权限检查:只有所有者、全局tag管理员、或领地管理员能编辑成员权限 boolean isOwner = p.getName().equalsIgnoreCase(land.owner); + boolean isGlobalAdmin = areaProtect.isAreaAdmin(p); // ★ 管理员状态检测(领地级管理员,非全局tag) boolean isAdmin = areaProtect.isLandAdmin(landName, targetPlayer); - // ★ 管理员提示:非领地主操作管理员时简化显示 - if (isAdmin && !isOwner) { + // ★ 管理员提示:非领地主且非全局tag管理员操作管理员时简化显示 + if (isAdmin && !isOwner && !isGlobalAdmin) { inv.setItem(22, createItem(Material.GOLD_BLOCK, "§6§l管理员权限", "§7该玩家是此领地管理员,自动获得所有权限", "§7点击切换管理员身份")); @@ -871,15 +872,24 @@ public class AreaGUIManager implements Listener { event.setCancelled(true); if (raw < 0 || raw >= 54) return; - // 获取当前页的领地 + // ★ 获取可管理领地列表(和openLandList一致,包含管理员可见领地) + String playerName = p.getName(); + List allManageableLands = new ArrayList<>(areaProtect.getLandsByOwner(playerName)); + if (areaProtect.isAreaAdmin(p)) { + for (AreaProtection.AreaConfig ac : areaProtect.getAllLands().values()) { + if (!allManageableLands.contains(ac)) { + allManageableLands.add(ac); + } + } + } + int page = landListPages.getOrDefault(p.getUniqueId(), 0); - List lands = areaProtect.getLandsByOwner(p.getName()); int start = page * PAGE_SIZE; - int end = Math.min(start + PAGE_SIZE, lands.size()); + int end = Math.min(start + PAGE_SIZE, allManageableLands.size()); if (raw >= 0 && raw < (end - start)) { // 点击领地 - AreaProtection.AreaConfig land = lands.get(start + raw); + AreaProtection.AreaConfig land = allManageableLands.get(start + raw); if (event.isLeftClick() && !event.isShiftClick()) { openLandManage(p, land.name); } else if (event.isRightClick()) { @@ -906,7 +916,7 @@ public class AreaGUIManager implements Listener { } } else if (raw == 45 && page > 0) { openLandList(p, page - 1); - } else if (raw == 53 && page < (int) Math.ceil((double) lands.size() / PAGE_SIZE) - 1) { + } else if (raw == 53 && page < (int) Math.ceil((double) allManageableLands.size() / PAGE_SIZE) - 1) { openLandList(p, page + 1); } else if (raw == 48) { openMainMenu(p); diff --git a/src/main/java/Sdf1_login/WebManager.java b/src/main/java/Sdf1_login/WebManager.java index dc23061..efa01fd 100644 --- a/src/main/java/Sdf1_login/WebManager.java +++ b/src/main/java/Sdf1_login/WebManager.java @@ -3343,6 +3343,9 @@ public class WebManager { // 4. 同步成员权限数据(area_land_permissions → web_area_permissions) syncPermissions(areaProtect); + // 5. ★ 同步插件管理员列表到PHP + syncAdmins(); + plugin.getLogger().fine("[Web通信] 领地数据同步完成"); } catch (Exception e) { plugin.getLogger().warning("[Web通信] 领地同步异常: " + e.getMessage()); @@ -3427,6 +3430,64 @@ public class WebManager { pullUserGroupsFromPHP(); } + /** + * ★ 同步插件管理员列表到PHP + * 收集所有具有areaProtectAdminTag的玩家,推送到PHP的web_plugin_admins表 + */ + private void syncAdmins() { + if (!enabled) return; + try { + // 获取管理员tag名 + String adminTag = plugin.getConfigMgr().areaProtectAdminTag; + if (adminTag == null || adminTag.isEmpty()) adminTag = "admin"; + + // 收集所有在线+离线玩家中具有该tag的玩家 + // ★ 使用Scoreboard获取所有注册过tag的玩家 + java.util.Set adminNames = new java.util.HashSet<>(); + for (org.bukkit.entity.Player player : Bukkit.getOnlinePlayers()) { + if (player.hasPermission("group." + adminTag) || player.isOp()) { + // 检查ScoreboardTag + for (String tag : player.getScoreboardTags()) { + if (tag.equalsIgnoreCase(adminTag)) { + adminNames.add(player.getName().toLowerCase()); + break; + } + } + } + } + + // ★ 也检查AreaProtection的admin列表(如果有的话) + AreaProtection areaProtect = plugin.getAreaProtection(); + if (areaProtect != null) { + // 遍历所有在线玩家检查tag + for (org.bukkit.entity.Player player : Bukkit.getOnlinePlayers()) { + if (areaProtect.isAreaAdmin(player)) { + adminNames.add(player.getName().toLowerCase()); + } + } + } + + // 构建JSON数组 + StringBuilder sb = new StringBuilder("["); + boolean first = true; + for (String name : adminNames) { + if (!first) sb.append(","); + sb.append("\"").append(escapeJson(name)).append("\""); + first = false; + } + sb.append("]"); + + Map params = new LinkedHashMap<>(); + params.put("action", "sync_admins"); + params.put("secret", secretKey); + params.put("admins", sb.toString()); + String resp = httpGet("api/sync.php", params); + plugin.getLogger().fine("[防护-sync] 管理员列表同步: " + adminNames.size() + "人 → " + resp); + } catch (Exception e) { + plugin.getLogger().warning("[防护-sync] 管理员列表同步异常: " + e.getMessage()); + } + } + /** * ★ 从PHP拉取用户组配置到Java本地 * PHP管理后台创建的用户组通过此方法同步到Java