From 278ce8a68683e3df781c301185b9f1227444c7f2 Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Fri, 21 Jun 2024 14:33:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=88=90=E5=91=98=E6=9D=83?= =?UTF-8?q?=E9=99=90=E7=BC=93=E5=AD=98=E6=9B=B4=E6=96=B0=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E7=AD=96=E7=95=A5=EF=BC=8C=E6=8F=90=E9=AB=98=E6=95=88=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../cn/lunadeer/dominion/BlueMapConnect.java | 199 +++++++++--------- src/main/java/cn/lunadeer/dominion/Cache.java | 105 +++++---- .../cn/lunadeer/dominion/DominionNode.java | 26 ++- .../controllers/PrivilegeController.java | 17 +- .../dominion/dtos/PlayerPrivilegeDTO.java | 5 +- 6 files changed, 194 insertions(+), 160 deletions(-) diff --git a/pom.xml b/pom.xml index e0c94b9..e2d1871 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer Dominion - 1.33.2-mysql-beta + 1.33.3-mysql-beta jar Dominion diff --git a/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java b/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java index 0622a40..cee9369 100644 --- a/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java +++ b/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java @@ -1,6 +1,7 @@ package cn.lunadeer.dominion; import cn.lunadeer.dominion.dtos.DominionDTO; +import cn.lunadeer.minecraftpluginutils.Scheduler; import cn.lunadeer.minecraftpluginutils.XLogger; import com.flowpowered.math.vector.Vector2d; import de.bluecolored.bluemap.api.BlueMapAPI; @@ -17,112 +18,116 @@ public class BlueMapConnect { if (!Dominion.config.getBlueMap()) { return; } - try { - BlueMapAPI.getInstance().ifPresent(api -> { - Map> world_dominions = new HashMap<>(); - for (DominionDTO dominion : Cache.instance.getDominions()) { - if (!world_dominions.containsKey(dominion.getWorld())) { - world_dominions.put(dominion.getWorld(), new ArrayList<>()); + Scheduler.runTaskAsync(() -> { + try { + BlueMapAPI.getInstance().ifPresent(api -> { + Map> world_dominions = new HashMap<>(); + for (DominionDTO dominion : Cache.instance.getDominions()) { + if (!world_dominions.containsKey(dominion.getWorld())) { + world_dominions.put(dominion.getWorld(), new ArrayList<>()); + } + world_dominions.get(dominion.getWorld()).add(dominion); } - world_dominions.get(dominion.getWorld()).add(dominion); - } - for (Map.Entry> d : world_dominions.entrySet()) { - api.getWorld(d.getKey()).ifPresent(world -> { - MarkerSet markerSet = MarkerSet.builder() - .label("Dominion") - .build(); - - for (DominionDTO dominion : d.getValue()) { - Collection vectors = new ArrayList<>(); - vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ1() + 0.001)); - vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ1() + 0.001)); - vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ2() - 0.001)); - vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ2() - 0.001)); - Shape shape = new Shape(vectors); - double x = vectors.iterator().next().getX(); - double z = vectors.iterator().next().getY(); - double y = dominion.getY1(); - - int r = dominion.getColorR(); - int g = dominion.getColorG(); - int b = dominion.getColorB(); - - Color line = new Color(r, g, b, 0.8F); - Color fill = new Color(r, g, b, 0.2F); - ExtrudeMarker marker = ExtrudeMarker.builder() - .label(dominion.getName()) - .position(x, y, z) - .shape(shape, dominion.getY1() + 0.001f, dominion.getY2() - 0.001f) - .lineColor(line) - .fillColor(fill) + for (Map.Entry> d : world_dominions.entrySet()) { + api.getWorld(d.getKey()).ifPresent(world -> { + MarkerSet markerSet = MarkerSet.builder() + .label("Dominion") .build(); - markerSet.getMarkers() - .put(dominion.getName(), marker); - } - for (BlueMapMap map : world.getMaps()) { - map.getMarkerSets().put(d.getKey() + "-" + markerSet.getLabel(), markerSet); - } - }); - } - }); - } catch (NoClassDefFoundError e) { - XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。"); - XLogger.err(e.getMessage()); - } + for (DominionDTO dominion : d.getValue()) { + Collection vectors = new ArrayList<>(); + vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ1() + 0.001)); + vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ1() + 0.001)); + vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ2() - 0.001)); + vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ2() - 0.001)); + Shape shape = new Shape(vectors); + double x = vectors.iterator().next().getX(); + double z = vectors.iterator().next().getY(); + double y = dominion.getY1(); + + int r = dominion.getColorR(); + int g = dominion.getColorG(); + int b = dominion.getColorB(); + + Color line = new Color(r, g, b, 0.8F); + Color fill = new Color(r, g, b, 0.2F); + ExtrudeMarker marker = ExtrudeMarker.builder() + .label(dominion.getName()) + .position(x, y, z) + .shape(shape, dominion.getY1() + 0.001f, dominion.getY2() - 0.001f) + .lineColor(line) + .fillColor(fill) + .build(); + markerSet.getMarkers() + .put(dominion.getName(), marker); + } + + for (BlueMapMap map : world.getMaps()) { + map.getMarkerSets().put(d.getKey() + "-" + markerSet.getLabel(), markerSet); + } + }); + } + }); + } catch (NoClassDefFoundError e) { + XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。"); + XLogger.err(e.getMessage()); + } + }); } public static void renderMCA(Map> mca_files) { if (!Dominion.config.getBlueMap()) { return; } - try { - BlueMapAPI.getInstance().ifPresent(api -> { - for (String world : mca_files.keySet()) { - api.getWorld(world).ifPresent(bmWorld -> { - MarkerSet markerSet = MarkerSet.builder() - .label("MCA") - .defaultHidden(true) - .build(); - for (String file : mca_files.get(world)) { - // r.-1.-1.mca - int mca_x = Integer.parseInt(file.split("\\.")[1]); - int mca_z = Integer.parseInt(file.split("\\.")[2]); - int world_x1 = mca_x * 512; - int world_x2 = (mca_x + 1) * 512; - int world_z1 = mca_z * 512; - int world_z2 = (mca_z + 1) * 512; - Collection vectors = new ArrayList<>(); - vectors.add(new Vector2d(world_x1 + 0.001, world_z1 + 0.001)); - vectors.add(new Vector2d(world_x2 - 0.001, world_z1 + 0.001)); - vectors.add(new Vector2d(world_x2 - 0.001, world_z2 - 0.001)); - vectors.add(new Vector2d(world_x1 + 0.001, world_z2 - 0.001)); - Shape shape = new Shape(vectors); - double x = vectors.iterator().next().getX(); - double z = vectors.iterator().next().getY(); - double y = -64; - - Color line = new Color(0, 204, 0, 0.8F); - Color fill = new Color(0, 204, 0, 0.2F); - ExtrudeMarker marker = ExtrudeMarker.builder() - .label(file) - .position(x, y, z) - .shape(shape, -64, 320) - .lineColor(line) - .fillColor(fill) + Scheduler.runTaskAsync(() -> { + try { + BlueMapAPI.getInstance().ifPresent(api -> { + for (String world : mca_files.keySet()) { + api.getWorld(world).ifPresent(bmWorld -> { + MarkerSet markerSet = MarkerSet.builder() + .label("MCA") + .defaultHidden(true) .build(); - markerSet.getMarkers() - .put(file, marker); - } - for (BlueMapMap map : bmWorld.getMaps()) { - map.getMarkerSets().put(world + "-" + markerSet.getLabel(), markerSet); - } - }); - } - }); - } catch (NoClassDefFoundError e) { - XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。"); - XLogger.err(e.getMessage()); - } + for (String file : mca_files.get(world)) { + // r.-1.-1.mca + int mca_x = Integer.parseInt(file.split("\\.")[1]); + int mca_z = Integer.parseInt(file.split("\\.")[2]); + int world_x1 = mca_x * 512; + int world_x2 = (mca_x + 1) * 512; + int world_z1 = mca_z * 512; + int world_z2 = (mca_z + 1) * 512; + Collection vectors = new ArrayList<>(); + vectors.add(new Vector2d(world_x1 + 0.001, world_z1 + 0.001)); + vectors.add(new Vector2d(world_x2 - 0.001, world_z1 + 0.001)); + vectors.add(new Vector2d(world_x2 - 0.001, world_z2 - 0.001)); + vectors.add(new Vector2d(world_x1 + 0.001, world_z2 - 0.001)); + Shape shape = new Shape(vectors); + double x = vectors.iterator().next().getX(); + double z = vectors.iterator().next().getY(); + double y = -64; + + Color line = new Color(0, 204, 0, 0.8F); + Color fill = new Color(0, 204, 0, 0.2F); + ExtrudeMarker marker = ExtrudeMarker.builder() + .label(file) + .position(x, y, z) + .shape(shape, -64, 320) + .lineColor(line) + .fillColor(fill) + .build(); + markerSet.getMarkers() + .put(file, marker); + } + for (BlueMapMap map : bmWorld.getMaps()) { + map.getMarkerSets().put(world + "-" + markerSet.getLabel(), markerSet); + } + }); + } + }); + } catch (NoClassDefFoundError e) { + XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。"); + XLogger.err(e.getMessage()); + } + }); } } diff --git a/src/main/java/cn/lunadeer/dominion/Cache.java b/src/main/java/cn/lunadeer/dominion/Cache.java index 7b4b7f6..793ddf2 100644 --- a/src/main/java/cn/lunadeer/dominion/Cache.java +++ b/src/main/java/cn/lunadeer/dominion/Cache.java @@ -51,68 +51,85 @@ public class Cache { } private void loadDominionsExecution() { - long start = System.currentTimeMillis(); - id_dominions = new ConcurrentHashMap<>(); - world_dominion_tree = new ConcurrentHashMap<>(); - dominion_children = new ConcurrentHashMap<>(); - List dominions = DominionDTO.selectAll(); - Map> world_dominions = new HashMap<>(); - for (DominionDTO d : dominions) { - if (!world_dominions.containsKey(d.getWorld())) { - world_dominions.put(d.getWorld(), new ArrayList<>()); + Scheduler.runTaskAsync(() -> { + long start = System.currentTimeMillis(); + id_dominions = new ConcurrentHashMap<>(); + world_dominion_tree = new ConcurrentHashMap<>(); + dominion_children = new ConcurrentHashMap<>(); + List dominions = DominionDTO.selectAll(); + Map> world_dominions = new HashMap<>(); + for (DominionDTO d : dominions) { + if (!world_dominions.containsKey(d.getWorld())) { + world_dominions.put(d.getWorld(), new ArrayList<>()); + } + world_dominions.get(d.getWorld()).add(d); + id_dominions.put(d.getId(), d); + if (!dominion_children.containsKey(d.getParentDomId())) { + dominion_children.put(d.getParentDomId(), new ArrayList<>()); + } + dominion_children.get(d.getParentDomId()).add(d.getId()); } - world_dominions.get(d.getWorld()).add(d); - id_dominions.put(d.getId(), d); - if (!dominion_children.containsKey(d.getParentDomId())) { - dominion_children.put(d.getParentDomId(), new ArrayList<>()); + for (Map.Entry> entry : world_dominions.entrySet()) { + world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue())); } - dominion_children.get(d.getParentDomId()).add(d.getId()); - } - for (Map.Entry> entry : world_dominions.entrySet()) { - world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue())); - } - BlueMapConnect.render(); - recheckPlayerState = true; - _last_update_dominion.set(System.currentTimeMillis()); - XLogger.debug("loadDominionsExecution cost: %d ms", System.currentTimeMillis() - start); + BlueMapConnect.render(); + recheckPlayerState = true; + _last_update_dominion.set(System.currentTimeMillis()); + XLogger.debug("loadDominionsExecution cost: %d ms for %d dominions" + , System.currentTimeMillis() - start, dominions.size()); + }); } /** * 从数据库加载所有玩家特权 + * 如果player_uuid为null,则加载所有玩家的特权 + * + * @param player_uuid 玩家UUID */ - public void loadPlayerPrivileges() { + public void loadPlayerPrivileges(UUID player_uuid) { if (_last_update_privilege.get() + UPDATE_INTERVAL < System.currentTimeMillis()) { - loadPlayerPrivilegesExecution(); + XLogger.debug("run loadPlayerPrivilegesExecution directly"); + loadPlayerPrivilegesExecution(player_uuid); } else { if (_update_privilege_is_scheduled.get()) return; + XLogger.debug("schedule loadPlayerPrivilegesExecution"); _update_privilege_is_scheduled.set(true); - long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L; + long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_privilege.get())) / 1000 * 20L; Scheduler.runTaskLaterAsync(() -> { - loadPlayerPrivilegesExecution(); + XLogger.debug("run loadPlayerPrivilegesExecution scheduled"); + loadPlayerPrivilegesExecution(player_uuid); _update_privilege_is_scheduled.set(false); }, delay_tick); } } - private void loadPlayerPrivilegesExecution() { - long start = System.currentTimeMillis(); - List all_privileges = PlayerPrivilegeDTO.selectAll(); - if (all_privileges == null) { - XLogger.err("加载玩家特权失败"); - return; - } - player_uuid_to_privilege = new ConcurrentHashMap<>(); - for (PlayerPrivilegeDTO privilege : all_privileges) { - UUID player_uuid = privilege.getPlayerUUID(); - if (!player_uuid_to_privilege.containsKey(player_uuid)) { - player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>()); + public void loadPlayerPrivileges() { + loadPlayerPrivileges(null); + } + + private void loadPlayerPrivilegesExecution(UUID player_to_update) { + Scheduler.runTaskAsync(() -> { + long start = System.currentTimeMillis(); + List all_privileges = new ArrayList<>(); + if (player_to_update == null) { + all_privileges = PlayerPrivilegeDTO.selectAll(); + player_uuid_to_privilege = new ConcurrentHashMap<>(); + } else { + all_privileges = PlayerPrivilegeDTO.selectAll(player_to_update); } - player_uuid_to_privilege.get(player_uuid).put(privilege.getDomID(), privilege); - } - recheckPlayerState = true; - _last_update_privilege.set(System.currentTimeMillis()); - XLogger.debug("loadPlayerPrivilegesExecution cost: %d ms", System.currentTimeMillis() - start); + for (PlayerPrivilegeDTO privilege : all_privileges) { + UUID player_uuid = privilege.getPlayerUUID(); + if (!player_uuid_to_privilege.containsKey(player_uuid)) { + player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>()); + } + player_uuid_to_privilege.get(player_uuid).put(privilege.getDomID(), privilege); + } + recheckPlayerState = true; + _last_update_privilege.set(System.currentTimeMillis()); + XLogger.debug("loadPlayerPrivilegesExecution cost: %d ms for %d privileges" + , System.currentTimeMillis() - start, all_privileges.size()); + }); } /** @@ -318,7 +335,7 @@ public class Cache { private final AtomicBoolean _update_dominion_is_scheduled = new AtomicBoolean(false); private final AtomicLong _last_update_privilege = new AtomicLong(0); private final AtomicBoolean _update_privilege_is_scheduled = new AtomicBoolean(false); - private static final long UPDATE_INTERVAL = 1000 * 5; + private static final long UPDATE_INTERVAL = 1000 * 4; private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态(发光、飞行) public final Map NextTimeAllowTeleport = new java.util.HashMap<>(); } diff --git a/src/main/java/cn/lunadeer/dominion/DominionNode.java b/src/main/java/cn/lunadeer/dominion/DominionNode.java index 1ec848f..34db479 100644 --- a/src/main/java/cn/lunadeer/dominion/DominionNode.java +++ b/src/main/java/cn/lunadeer/dominion/DominionNode.java @@ -5,24 +5,38 @@ import org.bukkit.Location; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import java.util.*; public class DominionNode { public DominionDTO dominion; public List children = new ArrayList<>(); public static List BuildNodeTree(Integer rootId, List dominions) { - List dominionTree = new ArrayList<>(); + // 映射父节点ID到其子节点列表 + Map> parentToChildrenMap = new HashMap<>(); for (DominionDTO dominion : dominions) { - if (Objects.equals(dominion.getParentDomId(), rootId)) { + parentToChildrenMap + .computeIfAbsent(dominion.getParentDomId(), k -> new ArrayList<>()) + .add(dominion); + } + + // 递归构建节点树 + return buildTree(rootId, parentToChildrenMap); + } + + private static List buildTree(Integer rootId, Map> parentToChildrenMap) { + List dominionTree = new ArrayList<>(); + List children = parentToChildrenMap.get(rootId); + + if (children != null) { + for (DominionDTO dominion : children) { DominionNode node = new DominionNode(); node.dominion = dominion; - node.children = BuildNodeTree(dominion.getId(), dominions); + node.children = buildTree(dominion.getId(), parentToChildrenMap); dominionTree.add(node); } } + return dominionTree; } diff --git a/src/main/java/cn/lunadeer/dominion/controllers/PrivilegeController.java b/src/main/java/cn/lunadeer/dominion/controllers/PrivilegeController.java index 218e909..5ea74c7 100644 --- a/src/main/java/cn/lunadeer/dominion/controllers/PrivilegeController.java +++ b/src/main/java/cn/lunadeer/dominion/controllers/PrivilegeController.java @@ -103,18 +103,17 @@ public class PrivilegeController { privilege = createPlayerPrivilege(operator, player.getUuid(), dominion); if (privilege == null) return; } - if (privilege.getAdmin()) { - if (notOwner(operator, dominion)) { - operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他管理员的权限", dominionName)); - return; - } - if (flag.equals("admin")) { - privilege.setAdmin(value); - } else { + if ((flag.equals("admin") || privilege.getAdmin()) && notOwner(operator, dominion)) { + operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他玩家管理员的权限", dominionName)); + return; + } + if (flag.equals("admin")) { + privilege.setAdmin(value); + } else { + if (privilege.getAdmin()) { operator.setResponse(FAIL.addMessage("管理员拥有所有权限,无需单独设置权限")); return; } - } else { Flag f = Flag.getFlag(flag); if (f == null) { operator.setResponse(FAIL.addMessage("未知的领地权限 %s", flag)); diff --git a/src/main/java/cn/lunadeer/dominion/dtos/PlayerPrivilegeDTO.java b/src/main/java/cn/lunadeer/dominion/dtos/PlayerPrivilegeDTO.java index eaa2338..331a99c 100644 --- a/src/main/java/cn/lunadeer/dominion/dtos/PlayerPrivilegeDTO.java +++ b/src/main/java/cn/lunadeer/dominion/dtos/PlayerPrivilegeDTO.java @@ -44,7 +44,7 @@ public class PlayerPrivilegeDTO { try (ResultSet rs = updateRow.execute()) { List players = getDTOFromRS(rs); if (players.size() == 0) return null; - Cache.instance.loadPlayerPrivileges(); + Cache.instance.loadPlayerPrivileges(playerUUID); return players.get(0); } catch (Exception e) { DatabaseManager.handleDatabaseError("更新玩家权限失败: ", e, ""); @@ -65,7 +65,7 @@ public class PlayerPrivilegeDTO { insertRow.field(new Field(f.getFlagName(), player.getFlagValue(f))); } try (ResultSet rs = insertRow.execute()) { - Cache.instance.loadPlayerPrivileges(); + Cache.instance.loadPlayerPrivileges(player.getPlayerUUID()); List players = getDTOFromRS(rs); if (players.size() == 0) return null; return players.get(0); @@ -134,7 +134,6 @@ public class PlayerPrivilegeDTO { flags.put(flag, value); Field f = new Field(flag.getFlagName(), value); UpdateRow updateRow = new UpdateRow().field(f); - XLogger.debug("setFlagValue: " + updateRow.toString()); return doUpdate(updateRow); }