From 07acadd79e33fcc5a077c507badbabd93feaa35d Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Mon, 5 Feb 2024 17:55:31 +0800 Subject: [PATCH] finish dominion create expand --- .../controllers/DominionController.java | 178 +++++++++++++++++- .../lunadeer/dominion/dtos/DominionDTO.java | 47 ++++- .../java/cn/lunadeer/dominion/utils/Time.java | 12 ++ 3 files changed, 228 insertions(+), 9 deletions(-) create mode 100644 src/main/java/cn/lunadeer/dominion/utils/Time.java diff --git a/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java b/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java index 2da83f2..ecf764a 100644 --- a/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java +++ b/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java @@ -1,18 +1,184 @@ package cn.lunadeer.dominion.controllers; +import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.dtos.DominionDTO; +import cn.lunadeer.dominion.utils.Notification; +import cn.lunadeer.dominion.utils.Time; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; import java.util.List; import java.util.UUID; public class DominionController { - public DominionDTO create(UUID owner, String name, String world, - Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { - // todo 检查冲突 - return DominionDTO.insert(new DominionDTO(owner, name, world, x1, y1, z1, x2, y2, z2)); + + /** + * 创建领地 + */ + public static DominionDTO create(Player owner, String name, Location loc1, Location loc2) { + DominionDTO dominion = createDTO(owner, name, loc1, loc2); + if (dominion == null) return null; + List exist_dominions = DominionDTO.selectAll(owner.getWorld().getName()); + for (DominionDTO exist_dominion : exist_dominions) { + if (isIntersect(exist_dominion, dominion)) { + Notification.error(owner, "与 " + exist_dominion.getName() + " 冲突"); + return null; + } + } + return DominionDTO.insert(dominion); } - public List all(){ - return DominionDTO.selectAll(); + /** + * 创建子领地 + */ + public static DominionDTO create(Player owner, String name, + Location loc1, Location loc2, + String parent_dominion_name) { + DominionDTO dominion = createDTO(owner, name, loc1, loc2); + if (dominion == null) return null; + DominionDTO parent_dominion = DominionDTO.select(parent_dominion_name); + if (parent_dominion == null) { + Notification.error(owner, "父领地 " + parent_dominion_name + " 不存在"); + return null; + } + // 是否是父领地的拥有者 + if (!isOwner(owner, parent_dominion)) { + return null; + } + // 检查是否超出父领地范围 + if (!isContained(dominion, parent_dominion)) { + Notification.error(owner, "超出父领地 " + parent_dominion_name + " 范围"); + return null; + } + // 获取此父领地的所有子领地 + List sub_dominions = DominionDTO.selectByParentId(parent_dominion.getId()); + // 检查是否与其他子领地冲突 + for (DominionDTO sub_dominion : sub_dominions) { + if (isIntersect(sub_dominion, dominion)) { + Notification.error(owner, "与子领地 " + sub_dominion.getName() + " 冲突"); + return null; + } + } + dominion = DominionDTO.insert(dominion); + if (dominion == null) { + Notification.error(owner, "创建失败,详细错误请联系管理员查询日志(当前时间:" + Time.nowStr() + ")"); + return null; + } + return dominion.setParentDomId(parent_dominion.getId()); } + + public static DominionDTO expand(Player operator, Integer size){ + Location location = operator.getLocation(); + List dominions = DominionDTO.selectByLocation(location.getWorld().getName(), + (int) location.getX(), (int) location.getY(), (int) location.getZ()); + if (dominions.size() != 1) { + Notification.error(operator, "你不在一个领地内或在一个子领地内,无法确定你要操作的领地,请手动指定要操作的领地名称"); + return null; + } + return expand(operator, size, dominions.get(0).getName()); + } + + public static DominionDTO expand(Player operator, Integer size, String dominion_name) { + Location location = operator.getLocation(); + BlockFace face = operator.getFacing(); + DominionDTO dominion = DominionDTO.select(dominion_name); + if (dominion == null) { + Notification.error(operator, "领地 " + dominion_name + " 不存在"); + return null; + } + if (!isOwner(operator, dominion)) { + return null; + } + if (!location.getWorld().getName().equals(dominion.getWorld())) { + Notification.error(operator, "禁止跨世界操作"); + return null; + } + Integer x1 = dominion.getX1(); + Integer y1 = dominion.getY1(); + Integer z1 = dominion.getZ1(); + Integer x2 = dominion.getX2(); + Integer y2 = dominion.getY2(); + Integer z2 = dominion.getZ2(); + switch (face) { + case NORTH: + z1 -= size; + break; + case SOUTH: + z2 += size; + break; + case WEST: + x1 -= size; + break; + case EAST: + x2 += size; + break; + case UP: + y2 += size; + break; + case DOWN: + y1 -= size; + break; + default: + Notification.error(operator, "无效的方向"); + return null; + } + List exist_dominions = DominionDTO.selectAll(dominion.getWorld()); + for (DominionDTO exist_dominion : exist_dominions) { + if (isIntersect(exist_dominion, x1, y1, z1, x2, y2, z2)) { + Notification.error(operator, "与 " + exist_dominion.getName() + " 冲突"); + return null; + } + } + return dominion.setXYZ(x1, y1, z1, x2, y2, z2); + } + + + /** + * 判断两个领地是否相交 + */ + private static boolean isIntersect(DominionDTO a, DominionDTO b) { + return a.getX1() < b.getX2() && a.getX2() > b.getX1() && + a.getY1() < b.getY2() && a.getY2() > b.getY1() && + a.getZ1() < b.getZ2() && a.getZ2() > b.getZ1(); + } + + private static boolean isIntersect(DominionDTO a, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { + return a.getX1() < x2 && a.getX2() > x1 && + a.getY1() < y2 && a.getY2() > y1 && + a.getZ1() < z2 && a.getZ2() > z1; + } + + /** + * 判断 sub 是否完全被 parent 包裹 + */ + private static boolean isContained(DominionDTO sub, DominionDTO parent) { + return sub.getX1() >= parent.getX1() && sub.getX2() <= parent.getX2() && + sub.getY1() >= parent.getY1() && sub.getY2() <= parent.getY2() && + sub.getZ1() >= parent.getZ1() && sub.getZ2() <= parent.getZ2(); + } + + public static DominionDTO createDTO(Player owner, String name, + Location loc1, Location loc2) { + if (!loc1.getWorld().equals(loc2.getWorld())) { + Notification.error(owner, "禁止跨世界操作"); + return null; + } + if (!owner.getWorld().equals(loc1.getWorld())) { + Notification.error(owner, "禁止跨世界操作"); + return null; + } + return new DominionDTO(owner.getUniqueId(), name, owner.getWorld().getName(), + (int) Math.min(loc1.getX(), loc2.getX()), (int) Math.min(loc1.getY(), loc2.getY()), + (int) Math.min(loc1.getZ(), loc2.getZ()), (int) Math.max(loc1.getX(), loc2.getX()), + (int) Math.max(loc1.getY(), loc2.getY()), (int) Math.max(loc1.getZ(), loc2.getZ())); + } + + public static boolean isOwner(Player player, DominionDTO dominion) { + if (dominion.getOwner().equals(player.getUniqueId())) return true; + Notification.error(player, "你不是领地 " + dominion.getName() + " 的拥有者,无法执行此操作"); + return false; + } + + } diff --git a/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java b/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java index aa2ddb0..6a3dea8 100644 --- a/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java +++ b/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java @@ -81,16 +81,48 @@ public class DominionDTO { return query(sql); } - public static List search(String name){ + public static List selectAll(String world) { + String sql = "SELECT * FROM dominion WHERE world = '" + world + "'"; + return query(sql); + } + + public static List search(String name) { String sql = "SELECT * FROM dominion WHERE name LIKE '%" + name + "%'"; return query(sql); } - public static List select(UUID owner) { + public static List selectAll(UUID owner) { String sql = "SELECT * FROM dominion WHERE owner = '" + owner.toString() + "'"; return query(sql); } + public static DominionDTO select(Integer id) { + String sql = "SELECT * FROM dominion WHERE id = " + id; + List dominions = query(sql); + if (dominions.size() == 0) return null; + return dominions.get(0); + } + + public static List selectByParentId(Integer parentId) { + String sql = "SELECT * FROM dominion WHERE parent_dom_id = " + parentId; + return query(sql); + } + + public static List selectByLocation(String world, Integer x, Integer y, Integer z) { + String sql = "SELECT * FROM dominion WHERE world = '" + world + "' AND " + + "x1 <= " + x + " AND x2 >= " + x + " AND " + + "y1 <= " + y + " AND y2 >= " + y + " AND " + + "z1 <= " + z + " AND z2 >= " + z; + return query(sql); + } + + public static DominionDTO select(String name) { + String sql = "SELECT * FROM dominion WHERE name = '" + name + "'"; + List dominions = query(sql); + if (dominions.size() == 0) return null; + return dominions.get(0); + } + public static DominionDTO insert(DominionDTO dominion) { String sql = "INSERT INTO dominion (" + "owner, name, world, x1, y1, z1, x2, y2, z2" + @@ -110,7 +142,7 @@ public class DominionDTO { return dominions.get(0); } - public static void delete(DominionDTO dominion){ + public static void delete(DominionDTO dominion) { String sql = "DELETE FROM dominion WHERE id = " + dominion.getId(); query(sql); } @@ -749,4 +781,13 @@ public class DominionDTO { return update(this); } + public DominionDTO setXYZ(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { + this.x1 = x1; + this.y1 = y1; + this.z1 = z1; + this.x2 = x2; + this.y2 = y2; + this.z2 = z2; + return update(this); + } } diff --git a/src/main/java/cn/lunadeer/dominion/utils/Time.java b/src/main/java/cn/lunadeer/dominion/utils/Time.java new file mode 100644 index 0000000..ebbd0c1 --- /dev/null +++ b/src/main/java/cn/lunadeer/dominion/utils/Time.java @@ -0,0 +1,12 @@ +package cn.lunadeer.dominion.utils; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Time { + + public static String nowStr() { + // yyyy-MM-dd HH:mm:ss + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + } +}