插件管理员可协助管理其他领地成员权限
- GUI领地列表:tag管理员可见所有领地,点击索引修正(allManageableLands替代getLandsByOwner) - openPlayerPerm:tag管理员(isAreaAdmin)看到完整权限编辑视图,不再简化 - CLI showPlayerPerm:设为管理员按钮对tag管理员也可用 - WebManager:新增syncAdmins(),将tag管理员名单同步到PHP的web_plugin_admins表 需要PHP端配合:land_api.php新增canManageLand/isPluginAdmin逻辑
This commit is contained in:
@@ -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(" "));
|
||||
|
||||
@@ -435,14 +435,15 @@ public class AreaGUIManager implements Listener {
|
||||
Map<String, Boolean> 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<AreaProtection.AreaConfig> 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<AreaProtection.AreaConfig> 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);
|
||||
|
||||
@@ -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<String> 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<String, String> 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
|
||||
|
||||
Reference in New Issue
Block a user