fix: CLI/GUI交互优化 + 用户组PHP双向同步
1. CLI用户组列表:空列表时显示可点击创建链接,有列表时也显示创建入口 2. CLI公共建筑列表:每项显示可点击[传送到此]按钮,直接传送 3. GUI公共设施传送:改为打开GUI面板,点击建筑物品直接传送(非执行命令) 4. GUI管理员面板:新增用户组管理入口(slot31),显示组数量 5. Java pollAdminChanges:新增group_change类型处理,PHP变更后自动重载用户组 6. AreaProtection:补全Adventure API imports
This commit is contained in:
@@ -66,6 +66,7 @@ public class AreaGUIManager implements Listener {
|
|||||||
*/
|
*/
|
||||||
// ★ 管理员面板标题
|
// ★ 管理员面板标题
|
||||||
private static final String T_ADMIN_PANEL = "§6§l管理员配置面板";
|
private static final String T_ADMIN_PANEL = "§6§l管理员配置面板";
|
||||||
|
private static final String T_PUBLIC_BUILDING = "§b§l公共建筑传送";
|
||||||
|
|
||||||
public void openMainMenu(Player p) {
|
public void openMainMenu(Player p) {
|
||||||
Inventory inv = Bukkit.createInventory(null, 54, T_MAIN);
|
Inventory inv = Bukkit.createInventory(null, 54, T_MAIN);
|
||||||
@@ -798,9 +799,9 @@ public class AreaGUIManager implements Listener {
|
|||||||
p.sendMessage("§cCLI管理器未初始化");
|
p.sendMessage("§cCLI管理器未初始化");
|
||||||
}
|
}
|
||||||
} else if (raw == 41) {
|
} else if (raw == 41) {
|
||||||
// ★ 公共设施传送
|
// ★ 公共设施传送 - 打开GUI直接传送
|
||||||
p.closeInventory();
|
event.setCancelled(true);
|
||||||
p.performCommand("protect listpublic");
|
openPublicBuildingList(p);
|
||||||
} else if (raw == 49) {
|
} else if (raw == 49) {
|
||||||
plugin.getGui().openMain(p);
|
plugin.getGui().openMain(p);
|
||||||
}
|
}
|
||||||
@@ -1160,6 +1161,40 @@ public class AreaGUIManager implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ★ 公共建筑传送
|
||||||
|
if (T_PUBLIC_BUILDING.equals(title)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
if (raw == 49) {
|
||||||
|
openMainMenu(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (raw < 0 || raw >= 45) return;
|
||||||
|
// 获取公共建筑列表
|
||||||
|
java.util.List<AreaProtection.AreaConfig> publicLands = new ArrayList<>();
|
||||||
|
for (AreaProtection.AreaConfig ac : areaProtect.getAllLands().values()) {
|
||||||
|
if (ac.isPublicBuilding) publicLands.add(ac);
|
||||||
|
}
|
||||||
|
if (raw < publicLands.size()) {
|
||||||
|
AreaProtection.AreaConfig target = publicLands.get(raw);
|
||||||
|
p.closeInventory();
|
||||||
|
// 传送(优先传送点,否则领地中心)
|
||||||
|
org.bukkit.Location dest;
|
||||||
|
if (target.warpX != 0 || target.warpZ != 0 || target.warpY != 0) {
|
||||||
|
org.bukkit.World w = Bukkit.getWorld(target.warpWorld != null && !target.warpWorld.isEmpty() ? target.warpWorld : p.getWorld().getName());
|
||||||
|
if (w == null) w = p.getWorld();
|
||||||
|
dest = new org.bukkit.Location(w, target.warpX + 0.5, target.warpY, target.warpZ + 0.5, target.warpYaw, target.warpPitch);
|
||||||
|
} else {
|
||||||
|
dest = new org.bukkit.Location(p.getWorld(),
|
||||||
|
(target.x1 + target.x2) / 2.0 + 0.5,
|
||||||
|
p.getWorld().getHighestBlockYAt((target.x1 + target.x2) / 2, (target.z1 + target.z2) / 2) + 1,
|
||||||
|
(target.z1 + target.z2) / 2.0 + 0.5);
|
||||||
|
}
|
||||||
|
p.teleport(dest);
|
||||||
|
p.sendMessage("§a已传送至公共建筑: §f" + target.name);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 效果选择列表
|
// 效果选择列表
|
||||||
if (title.startsWith("§a§l选择效果 - ")) {
|
if (title.startsWith("§a§l选择效果 - ")) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
@@ -1336,6 +1371,15 @@ public class AreaGUIManager implements Listener {
|
|||||||
"",
|
"",
|
||||||
"§e左键+600 / 右键-600"));
|
"§e左键+600 / 右键-600"));
|
||||||
|
|
||||||
|
// ★ 用户组管理(位置31)
|
||||||
|
UserGroupManager ugm = plugin.getUserGroup();
|
||||||
|
int groupCount = (ugm != null) ? ugm.getGroupConfigs().size() : 0;
|
||||||
|
inv.setItem(31, createItem(Material.PLAYER_HEAD, "§6§l用户组管理",
|
||||||
|
"§7当前: §f" + groupCount + " 个用户组",
|
||||||
|
"§7管理用户组的独立价格、上限和默认权限",
|
||||||
|
"",
|
||||||
|
"§e点击进入管理"));
|
||||||
|
|
||||||
// 返回按钮(位置48)
|
// 返回按钮(位置48)
|
||||||
inv.setItem(48, createItem(Material.ARROW, "§c§l返回主菜单", ""));
|
inv.setItem(48, createItem(Material.ARROW, "§c§l返回主菜单", ""));
|
||||||
|
|
||||||
@@ -1412,9 +1456,50 @@ public class AreaGUIManager implements Listener {
|
|||||||
areaProtect.setPendingConfigInput(p.getUniqueId(), "peace_mode_max_duration");
|
areaProtect.setPendingConfigInput(p.getUniqueId(), "peace_mode_max_duration");
|
||||||
} else if (raw == 48) {
|
} else if (raw == 48) {
|
||||||
openMainMenu(p);
|
openMainMenu(p);
|
||||||
|
} else if (raw == 31) {
|
||||||
|
// ★ 用户组管理 - 打开CLI交互(GUI暂不支持复杂交互)
|
||||||
|
p.closeInventory();
|
||||||
|
p.performCommand("protect grouplist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 公共建筑传送 GUI ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开公共建筑列表,点击直接传送
|
||||||
|
*/
|
||||||
|
public void openPublicBuildingList(Player p) {
|
||||||
|
// 收集所有公共建筑
|
||||||
|
java.util.List<AreaProtection.AreaConfig> publicLands = new ArrayList<>();
|
||||||
|
for (AreaProtection.AreaConfig ac : areaProtect.getAllLands().values()) {
|
||||||
|
if (ac.isPublicBuilding) publicLands.add(ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
Inventory inv = Bukkit.createInventory(null, 54, T_PUBLIC_BUILDING);
|
||||||
|
|
||||||
|
if (publicLands.isEmpty()) {
|
||||||
|
inv.setItem(22, createItem(Material.BARRIER, "§7暂无公共建筑设施",
|
||||||
|
"§7管理员可通过 /protect public <领地标记> 创建"));
|
||||||
|
} else {
|
||||||
|
int slot = 0;
|
||||||
|
for (AreaProtection.AreaConfig ac : publicLands) {
|
||||||
|
if (slot >= 45) break;
|
||||||
|
String warpInfo = (ac.warpX != 0 || ac.warpZ != 0) ? "§a有传送点" : "§7无传送点(将传送到领地中心)";
|
||||||
|
inv.setItem(slot, createItem(Material.BELL, "§b§l" + ac.name,
|
||||||
|
"§7所有者: §f" + ac.owner,
|
||||||
|
"§7传送: " + warpInfo,
|
||||||
|
"",
|
||||||
|
"§e点击传送到此公共建筑"));
|
||||||
|
slot++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回按钮
|
||||||
|
inv.setItem(49, createItem(Material.ARROW, "§c§l返回主菜单", ""));
|
||||||
|
|
||||||
|
p.openInventory(inv);
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 效果管理 GUI ====================
|
// ==================== 效果管理 GUI ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ import java.util.*;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
@@ -5841,10 +5845,15 @@ public class AreaProtection implements Listener {
|
|||||||
int idx = 1;
|
int idx = 1;
|
||||||
for (AreaConfig ac : publicLands) {
|
for (AreaConfig ac : publicLands) {
|
||||||
String warpInfo = (ac.warpX != 0 || ac.warpZ != 0) ? "§a[有传送点]" : "§7[无传送点]";
|
String warpInfo = (ac.warpX != 0 || ac.warpZ != 0) ? "§a[有传送点]" : "§7[无传送点]";
|
||||||
sender.sendMessage("§e" + idx + ". §f" + ac.name + " §7所有者:" + ac.owner + " " + warpInfo);
|
// 可点击传送的列表项
|
||||||
|
p.sendMessage(Component.empty()
|
||||||
|
.append(Component.text("§e" + idx + ". §f" + ac.name + " §7所有者:" + ac.owner + " " + warpInfo))
|
||||||
|
.append(Component.text(" §a[传送到此]"))
|
||||||
|
.hoverEvent(HoverEvent.showText(Component.text("§e点击传送到 " + ac.name)))
|
||||||
|
.clickEvent(ClickEvent.runCommand("/protect tpb " + ac.name))
|
||||||
|
);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
sender.sendMessage("§7使用 /protect tpb <序号或名字> 传送");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (sub.equals("tpb") || sub.equals("传送公共")) {
|
if (sub.equals("tpb") || sub.equals("传送公共")) {
|
||||||
@@ -5898,6 +5907,17 @@ public class AreaProtection implements Listener {
|
|||||||
Map<String, UserGroupManager.UserGroupConfig> groups = ugm.getGroupConfigs();
|
Map<String, UserGroupManager.UserGroupConfig> groups = ugm.getGroupConfigs();
|
||||||
if (groups.isEmpty()) {
|
if (groups.isEmpty()) {
|
||||||
sender.sendMessage("§e暂无用户组定义");
|
sender.sendMessage("§e暂无用户组定义");
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
Player pp = (Player) sender;
|
||||||
|
if (pp.hasPermission("sdf1.admin")) {
|
||||||
|
pp.sendMessage(Component.empty()
|
||||||
|
.append(Component.text("§a点击此处"))
|
||||||
|
.append(Component.text("§e创建第一个用户组"))
|
||||||
|
.hoverEvent(HoverEvent.showText(Component.text("§e点击开始交互式创建")))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand("/protect groupset "))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("§a§l=== 用户组列表 ===");
|
sender.sendMessage("§a§l=== 用户组列表 ===");
|
||||||
for (UserGroupManager.UserGroupConfig cfg : groups.values()) {
|
for (UserGroupManager.UserGroupConfig cfg : groups.values()) {
|
||||||
@@ -5907,6 +5927,15 @@ public class AreaProtection implements Listener {
|
|||||||
+ " §7(name=" + cfg.name + ", 优先级=" + cfg.priority
|
+ " §7(name=" + cfg.name + ", 优先级=" + cfg.priority
|
||||||
+ ", 价格=" + priceStr + ", 上限=" + maxStr + ")");
|
+ ", 价格=" + priceStr + ", 上限=" + maxStr + ")");
|
||||||
}
|
}
|
||||||
|
if (sender instanceof Player && ((Player) sender).hasPermission("sdf1.admin")) {
|
||||||
|
Player pp = (Player) sender;
|
||||||
|
pp.sendMessage(Component.empty()
|
||||||
|
.append(Component.text("§a点击此处"))
|
||||||
|
.append(Component.text("§e创建新用户组"))
|
||||||
|
.hoverEvent(HoverEvent.showText(Component.text("§e点击开始交互式创建")))
|
||||||
|
.clickEvent(ClickEvent.suggestCommand("/protect groupset "))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3162,6 +3162,16 @@ public class WebManager {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "group_change": {
|
||||||
|
// ★ PHP端用户组变更 → 重新加载本地用户组配置
|
||||||
|
UserGroupManager ugm = plugin.getUserGroup();
|
||||||
|
if (ugm != null) {
|
||||||
|
ugm.loadGroupConfigs();
|
||||||
|
plugin.getLogger().info("[Web通信] PHP端用户组变更,已重新加载用户组配置");
|
||||||
|
applied = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
plugin.getLogger().fine("[Web通信] 未知变更类型: " + changeType);
|
plugin.getLogger().fine("[Web通信] 未知变更类型: " + changeType);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user