From da10ce05e240796a389e4ce0d59c1c43b8943c57 Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Wed, 29 May 2024 00:57:54 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=E7=BC=93=E5=AD=98=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E3=80=81=E4=BC=98=E5=8C=96=E5=9C=A8=E5=A4=A7=E9=87=8F?= =?UTF-8?q?=E9=A2=86=E5=9C=B0=E6=95=B0=E6=8D=AE=E4=B8=8B=E7=9A=84=E6=A3=80?= =?UTF-8?q?=E7=B4=A2=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../cn/lunadeer/dominion/BlueMapConnect.java | 21 ++- src/main/java/cn/lunadeer/dominion/Cache.java | 162 +++++++----------- .../cn/lunadeer/dominion/DominionNode.java | 62 +++++++ .../lunadeer/dominion/dtos/DominionDTO.java | 4 - .../lunadeer/dominion/tuis/ListDominion.java | 31 +++- 6 files changed, 164 insertions(+), 118 deletions(-) create mode 100644 src/main/java/cn/lunadeer/dominion/DominionNode.java diff --git a/pom.xml b/pom.xml index d608f79..f739663 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer Dominion - 1.28.12-beta + 1.29.0-beta jar Dominion diff --git a/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java b/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java index 7c91ac3..f061af8 100644 --- a/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java +++ b/src/main/java/cn/lunadeer/dominion/BlueMapConnect.java @@ -10,10 +10,7 @@ import de.bluecolored.bluemap.api.markers.MarkerSet; import de.bluecolored.bluemap.api.math.Color; import de.bluecolored.bluemap.api.math.Shape; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; public class BlueMapConnect { public static void render() { @@ -22,14 +19,20 @@ public class BlueMapConnect { } try { BlueMapAPI.getInstance().ifPresent(api -> { - for (Map.Entry> world_dominions : Cache.instance.getWorldDominions().entrySet()) { - api.getWorld(world_dominions.getKey()).ifPresent(world -> { + 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); + } + for (Map.Entry> d : world_dominions.entrySet()) { + api.getWorld(d.getKey()).ifPresent(world -> { MarkerSet markerSet = MarkerSet.builder() .label("Dominion") .build(); - for (Integer id : world_dominions.getValue()) { - DominionDTO dominion = Cache.instance.getDominion(id); + 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)); @@ -58,7 +61,7 @@ public class BlueMapConnect { } for (BlueMapMap map : world.getMaps()) { - map.getMarkerSets().put(world_dominions.getKey() + "-" + markerSet.getLabel(), markerSet); + map.getMarkerSets().put(d.getKey() + "-" + markerSet.getLabel(), markerSet); } }); } diff --git a/src/main/java/cn/lunadeer/dominion/Cache.java b/src/main/java/cn/lunadeer/dominion/Cache.java index 2ce2295..98f9a77 100644 --- a/src/main/java/cn/lunadeer/dominion/Cache.java +++ b/src/main/java/cn/lunadeer/dominion/Cache.java @@ -2,6 +2,7 @@ package cn.lunadeer.dominion; import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.Flag; +import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.minecraftpluginutils.ParticleRender; import cn.lunadeer.minecraftpluginutils.Scheduler; @@ -18,6 +19,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; +import static cn.lunadeer.dominion.DominionNode.getLocInDominionDTO; + public class Cache { public Cache() { @@ -49,24 +52,23 @@ public class Cache { private void loadDominionsExecution() { id_dominions = new ConcurrentHashMap<>(); - world_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 (!dominion_children.containsKey(d.getId())) { - dominion_children.put(d.getId(), new ArrayList<>()); - } - id_dominions.put(d.getId(), d); if (!world_dominions.containsKey(d.getWorld())) { world_dominions.put(d.getWorld(), new ArrayList<>()); } - world_dominions.get(d.getWorld()).add(d.getId()); - if (d.getParentDomId() != -1) { - 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<>()); } + 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(); _last_update_dominion.set(System.currentTimeMillis()); @@ -117,64 +119,50 @@ public class Cache { * @return 玩家当前所在领地 */ public DominionDTO getPlayerCurrentDominion(Player player) { - Integer dominion_id = player_current_dominion_id.get(player.getUniqueId()); - DominionDTO dominion = null; - if (dominion_id != null) { - dominion = id_dominions.get(dominion_id); + Integer last_in_dom_id = player_current_dominion_id.get(player.getUniqueId()); + DominionDTO last_dominion = null; + if (last_in_dom_id != null) { + last_dominion = id_dominions.get(last_in_dom_id); } - if (dominion != null) { - if (!isInDominion(dominion, player)) { - if (dominion.isTopDom()) { - // Dominion.notification.info(player, "您已离开领地:%s", dominion.getName()); - player.sendMessage(Component.text(dominion.getLeaveMessage())); - dominion = null; - } else { - // Dominion.notification.info(player, "您已离开子领地:%s", dominion.getName()); - player.sendMessage(Component.text(dominion.getLeaveMessage())); - dominion = id_dominions.get(dominion.getParentDomId()); - } - update_player_current_dominion(player, dominion); - } else { - // 如果在领地内则检查是否在子领地内 - List children = dominion_children.get(dominion.getId()); - for (Integer child_id : children) { - DominionDTO child = id_dominions.get(child_id); - if (isInDominion(child, player)) { - dominion = child; - // Dominion.notification.info(player, "您正在进入子领地:%s", dominion.getName()); - player.sendMessage(Component.text(dominion.getJoinMessage())); - update_player_current_dominion(player, dominion); - break; - } - } - } + if (last_in_dom_id != null && dominion_children.get(last_in_dom_id).isEmpty() && isInDominion(last_dominion, player)) { + // 如果玩家仍在领地内,且领地没有子领地,则直接返回 + return last_dominion; } - if (dominion == null) { - List in_dominions = getDominionsParentAndChildren(player.getLocation()); - if (in_dominions.size() != 0) { - dominion = in_dominions.get(0); - // Dominion.notification.info(player, "您正在进入领地:%s", dominion.getName()); - player.sendMessage(Component.text(dominion.getJoinMessage())); - } - update_player_current_dominion(player, dominion); + DominionDTO current_dominion = getLocInDominionDTO(world_dominion_tree.get(player.getWorld().getName()), player.getLocation()); + int last_dom_id = last_dominion == null ? -1 : last_dominion.getId(); + int current_dom_id = current_dominion == null ? -1 : current_dominion.getId(); + if (last_dom_id == current_dom_id) { + return last_dominion; + } + if (last_dom_id != -1) { +// if (last_dominion.getParentDomId() == -1) +// Notification.info(player, "您已离开领地:%s", last_dominion.getName()); +// else +// Notification.info(player, "您已离开子领地:%s", last_dominion.getName()); + player.sendActionBar(Component.text(last_dominion.getLeaveMessage())); + } + if (current_dom_id != -1) { +// if (current_dominion.getParentDomId() == -1) +// Notification.info(player, "您正在进入领地:%s", current_dominion.getName()); +// else +// Notification.info(player, "您正在进入子领地:%s", current_dominion.getName()); + player.sendActionBar(Component.text(current_dominion.getJoinMessage())); } - return dominion; - } - private void update_player_current_dominion(Player player, DominionDTO dominion) { - lightOrNot(player, dominion); // 发光检查 - flyOrNot(player, dominion); // 飞行检查 - if (dominion == null) { + lightOrNot(player, current_dominion); // 发光检查 + flyOrNot(player, current_dominion); // 飞行检查 + if (current_dominion == null) { player_current_dominion_id.put(player.getUniqueId(), null); - return; + return null; } - player_current_dominion_id.put(player.getUniqueId(), dominion.getId()); + player_current_dominion_id.put(player.getUniqueId(), current_dominion.getId()); // show border - if (dominion.getFlagValue(Flag.SHOW_BORDER)) { + if (current_dominion.getFlagValue(Flag.SHOW_BORDER)) { ParticleRender.showBoxFace(Dominion.instance, player, - dominion.getLocation1(), - dominion.getLocation2()); + current_dominion.getLocation1(), + current_dominion.getLocation2()); } + return current_dominion; } /** @@ -227,29 +215,24 @@ public class Cache { } } - private List getDominionsParentAndChildren(Location loc) { - // todo: 可能需要进一步优化性能,考虑将领地按照mca文件分组,减少遍历次数 - long start = System.currentTimeMillis(); - String world = loc.getWorld().getName(); - List dominions_id = world_dominions.get(world); - List in_dominions = new ArrayList<>(); - if (dominions_id == null) return in_dominions; - for (Integer id : dominions_id) { - DominionDTO d = id_dominions.get(id); - if (isInDominion(d, loc)) { - in_dominions.add(d); - } - } - in_dominions.sort(Comparator.comparingInt(DominionDTO::getId)); - long end = System.currentTimeMillis(); - // XLogger.debug("getDominionsParentAndChildren: %d ms", end - start); - return in_dominions; + public DominionDTO getDominion(Location loc) { + List tree = world_dominion_tree.get(loc.getWorld().getName()); + if (tree == null) return null; + return getLocInDominionDTO(tree, loc); } - public DominionDTO getDominion(Location loc) { - List in_dominions = getDominionsParentAndChildren(loc); - if (in_dominions.size() == 0) return null; - return in_dominions.get(in_dominions.size() - 1); + public List getDominionTreeByPlayer(String player_name) { + List dominionTree = new ArrayList<>(); + PlayerDTO player = PlayerDTO.select(player_name); + if (player == null) return dominionTree; + for (List tree : world_dominion_tree.values()) { + for (DominionNode node : tree) { + if (node.dominion.getOwner().equals(player.getUuid())) { + dominionTree.add(node); + } + } + } + return dominionTree; } /** @@ -276,21 +259,6 @@ public class Cache { z >= dominion.getZ1() && z <= dominion.getZ2(); } - private static boolean isInDominion(@Nullable DominionDTO dominion, Location location) { - if (dominion == null) return false; - if (!Objects.equals(dominion.getWorld(), location.getWorld().getName())) return false; - double x = location.getX(); - double y = location.getY(); - double z = location.getZ(); - return x >= dominion.getX1() && x <= dominion.getX2() && - y >= dominion.getY1() && y <= dominion.getY2() && - z >= dominion.getZ1() && z <= dominion.getZ2(); - } - - public Map> getWorldDominions() { - return world_dominions; - } - public DominionDTO getDominion(Integer id) { return id_dominions.get(id); } @@ -312,7 +280,7 @@ public class Cache { public static Cache instance; private ConcurrentHashMap id_dominions; - private ConcurrentHashMap> world_dominions; // 所有领地 + private ConcurrentHashMap> world_dominion_tree; private ConcurrentHashMap> player_uuid_to_privilege; // 玩家所有的特权 private final Map player_current_dominion_id; // 玩家当前所在领地 private ConcurrentHashMap> dominion_children; diff --git a/src/main/java/cn/lunadeer/dominion/DominionNode.java b/src/main/java/cn/lunadeer/dominion/DominionNode.java new file mode 100644 index 0000000..1d62048 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/DominionNode.java @@ -0,0 +1,62 @@ +package cn.lunadeer.dominion; + +import cn.lunadeer.dominion.dtos.DominionDTO; +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; + +public class DominionNode { + public DominionDTO dominion; + public List children = new ArrayList<>(); + + public static List BuildNodeTree(Integer rootId, List dominions) { + List dominionTree = new ArrayList<>(); + for (DominionDTO dominion : dominions) { + if (Objects.equals(dominion.getParentDomId(), rootId)) { + DominionNode node = new DominionNode(); + node.dominion = dominion; + node.children = BuildNodeTree(dominion.getId(), dominions); + dominionTree.add(node); + } + } + return dominionTree; + } + + public static DominionNode getLocInDominionNode(@NotNull List nodes, @NotNull Location loc) { + for (DominionNode node : nodes) { + if (isInDominion(node.dominion, loc)) { + if (node.children.isEmpty()) { + return node; + } else { + DominionNode childDominion = getLocInDominionNode(node.children, loc); + if (childDominion == null) { + return node; + } else { + return childDominion; + } + } + } + } + return null; + } + + public static DominionDTO getLocInDominionDTO(@NotNull List nodes, @NotNull Location loc) { + DominionNode dominionNode = getLocInDominionNode(nodes, loc); + return dominionNode == null ? null : dominionNode.dominion; + } + + private static boolean isInDominion(@Nullable DominionDTO dominion, Location location) { + if (dominion == null) return false; + if (!Objects.equals(dominion.getWorld(), location.getWorld().getName())) return false; + double x = location.getX(); + double y = location.getY(); + double z = location.getZ(); + return x >= dominion.getX1() && x <= dominion.getX2() && + y >= dominion.getY1() && y <= dominion.getY2() && + z >= dominion.getZ1() && z <= dominion.getZ2(); + } +} diff --git a/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java b/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java index 5ca6ff6..5e04932 100644 --- a/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java +++ b/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java @@ -334,10 +334,6 @@ public class DominionDTO { return parentDomId; } - public boolean isTopDom() { - return parentDomId == -1; - } - public DominionDTO setParentDomId(Integer parentDomId) { this.parentDomId = parentDomId; return update(this); diff --git a/src/main/java/cn/lunadeer/dominion/tuis/ListDominion.java b/src/main/java/cn/lunadeer/dominion/tuis/ListDominion.java index 73f776e..b7bad99 100644 --- a/src/main/java/cn/lunadeer/dominion/tuis/ListDominion.java +++ b/src/main/java/cn/lunadeer/dominion/tuis/ListDominion.java @@ -1,17 +1,21 @@ package cn.lunadeer.dominion.tuis; +import cn.lunadeer.dominion.Cache; +import cn.lunadeer.dominion.DominionNode; import cn.lunadeer.minecraftpluginutils.stui.ListView; +import cn.lunadeer.minecraftpluginutils.stui.ViewStyles; import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Line; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.ArrayList; import java.util.List; import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.commands.Helper.playerAdminDominions; -import static cn.lunadeer.dominion.commands.Helper.playerOwnDominions; import static cn.lunadeer.dominion.tuis.Apis.getPage; public class ListDominion { @@ -20,20 +24,33 @@ public class ListDominion { if (player == null) return; int page = getPage(args); ListView view = ListView.create(10, "/dominion list"); - List own_dominions = playerOwnDominions(sender); + // 根据id从小到大排序 List admin_dominions = playerAdminDominions(sender); view.title("我的领地列表"); view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("我的领地")); - for (String dominion : own_dominions) { - TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + dominion).build(); - TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + dominion).build(); - view.add(Line.create().append(dominion).append(manage).append(delete)); - } + view.addLines(BuildTreeLines(Cache.instance.getDominionTreeByPlayer(player.getName()), 0)); + view.add(Line.create().append(Component.text("-= 以下为你拥有管理员权限的领地 =-", ViewStyles.main_color))); for (String dominion : admin_dominions) { TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + dominion).build(); view.add(Line.create().append(dominion).append(manage)); } view.showOn(player, page); } + + private static List BuildTreeLines(List dominionTree, Integer depth) { + List lines = new ArrayList<>(); + StringBuilder prefix = new StringBuilder(); + for (int i = 0; i < depth; i++) { + prefix.append(" | "); + } + for (DominionNode node : dominionTree) { + TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.dominion.getName()).build(); + TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.dominion.getName()).build(); + Line line = Line.create().append(prefix + node.dominion.getName()).append(manage).append(delete); + lines.add(line); + lines.addAll(BuildTreeLines(node.children, depth + 1)); + } + return lines; + } }