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;
+ }
}