diff --git a/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java b/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java index ecf764a..c6bd1f8 100644 --- a/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java +++ b/src/main/java/cn/lunadeer/dominion/controllers/DominionController.java @@ -2,8 +2,10 @@ package cn.lunadeer.dominion.controllers; import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.dtos.DominionDTO; +import cn.lunadeer.dominion.utils.Database; import cn.lunadeer.dominion.utils.Notification; import cn.lunadeer.dominion.utils.Time; +import cn.lunadeer.dominion.utils.XLogger; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; @@ -15,35 +17,62 @@ public class DominionController { /** * 创建领地 + * + * @param owner 拥有者 + * @param name 领地名称 + * @param loc1 位置1 + * @param loc2 位置2 + * @return 创建的领地 */ 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); + return create(owner, name, loc1, loc2, ""); } /** * 创建子领地 + * + * @param owner 拥有者 + * @param name 领地名称 + * @param loc1 位置1 + * @param loc2 位置2 + * @param parent_dominion_name 父领地名称 + * @return 创建的领地 */ 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 (!loc1.getWorld().equals(loc2.getWorld())) { + Notification.error(owner, "禁止跨世界操作"); + return null; + } + if (!owner.getWorld().equals(loc1.getWorld())) { + Notification.error(owner, "禁止跨世界操作"); + return null; + } + DominionDTO dominion = 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())); + DominionDTO parent_dominion; + if (parent_dominion_name.isEmpty()) { + parent_dominion = DominionDTO.select(-1); + } else { + parent_dominion = DominionDTO.select(parent_dominion_name); + } if (parent_dominion == null) { Notification.error(owner, "父领地 " + parent_dominion_name + " 不存在"); + if (parent_dominion_name.isEmpty()) { + XLogger.err("根领地丢失!"); + } return null; } // 是否是父领地的拥有者 - if (!isOwner(owner, parent_dominion)) { + if (!isOwner(owner, parent_dominion) && parent_dominion.getId() != -1) { + return null; + } + // 如果parent_dominion不为-1 检查是否在同一世界 + if (parent_dominion.getId() != -1 && !parent_dominion.getWorld().equals(dominion.getWorld())) { + Notification.error(owner, "禁止跨世界操作"); return null; } // 检查是否超出父领地范围 @@ -52,11 +81,11 @@ public class DominionController { return null; } // 获取此父领地的所有子领地 - List sub_dominions = DominionDTO.selectByParentId(parent_dominion.getId()); + List sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), parent_dominion.getId()); // 检查是否与其他子领地冲突 for (DominionDTO sub_dominion : sub_dominions) { if (isIntersect(sub_dominion, dominion)) { - Notification.error(owner, "与子领地 " + sub_dominion.getName() + " 冲突"); + Notification.error(owner, "与领地 " + sub_dominion.getName() + " 冲突"); return null; } } @@ -68,7 +97,16 @@ public class DominionController { return dominion.setParentDomId(parent_dominion.getId()); } - public static DominionDTO expand(Player operator, Integer size){ + /** + * 向一个方向扩展领地 + * 会尝试对操作者当前所在的领地进行操作,当操作者不在一个领地内或者在子领地内时 + * 需要手动指定要操作的领地名称 + * + * @param operator 操作者 + * @param size 扩展的大小 + * @return 扩展后的领地 + */ + 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()); @@ -79,6 +117,14 @@ public class DominionController { return expand(operator, size, dominions.get(0).getName()); } + /** + * 向一个方向扩展领地 + * + * @param operator 操作者 + * @param size 扩展的大小 + * @param dominion_name 领地名称 + * @return 扩展后的领地 + */ public static DominionDTO expand(Player operator, Integer size, String dominion_name) { Location location = operator.getLocation(); BlockFace face = operator.getFacing(); @@ -123,9 +169,22 @@ public class DominionController { Notification.error(operator, "无效的方向"); return null; } - List exist_dominions = DominionDTO.selectAll(dominion.getWorld()); + // 校验是否超出父领地范围 + DominionDTO parent_dominion = DominionDTO.select(dominion.getParentDomId()); + if (parent_dominion == null) { + Notification.error(operator, "父领地丢失"); + return null; + } + if (!isContained(x1, y1, z1, x2, y2, z2, parent_dominion)) { + Notification.error(operator, "超出父领地 " + parent_dominion.getName() + " 范围"); + return null; + } + // 获取同世界下的所有同级领地 + List exist_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getParentDomId()); for (DominionDTO exist_dominion : exist_dominions) { if (isIntersect(exist_dominion, x1, y1, z1, x2, y2, z2)) { + // 如果是自己,跳过 + if (exist_dominion.getId().equals(dominion.getId())) continue; Notification.error(operator, "与 " + exist_dominion.getName() + " 冲突"); return null; } @@ -133,6 +192,94 @@ public class DominionController { return dominion.setXYZ(x1, y1, z1, x2, y2, z2); } + /** + * 缩小领地 + * 会尝试对操作者当前所在的领地进行操作,当操作者不在一个领地内或者在子领地内时 + * 需要手动指定要操作的领地名称 + * + * @param operator 操作者 + * @param size 缩小的大小 + * @return 缩小后的领地 + */ + public static DominionDTO contract(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 contract(operator, size, dominions.get(0).getName()); + } + + /** + * 缩小领地 + * + * @param operator 操作者 + * @param size 缩小的大小 + * @param dominion_name 领地名称 + * @return 缩小后的领地 + */ + public static DominionDTO contract(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: + z2 -= size; + break; + case SOUTH: + z1 += size; + break; + case WEST: + x2 -= size; + break; + case EAST: + x1 += size; + break; + case UP: + y2 -= size; + break; + case DOWN: + y1 += size; + break; + default: + Notification.error(operator, "无效的方向"); + return null; + } + // 校验第二组坐标是否小于第一组坐标 + if (x1 >= x2 || y1 >= y2 || z1 >= z2) { + Notification.error(operator, "缩小后的领地无效"); + return null; + } + // 获取所有的子领地 + List sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId()); + for (DominionDTO sub_dominion : sub_dominions) { + if (!isContained(sub_dominion, x1, y1, z1, x2, y2, z2)) { + Notification.error(operator, "缩小后的领地 " + dominion_name + " 无法包含子领地 " + sub_dominion.getName()); + return null; + } + } + return dominion.setXYZ(x1, y1, z1, x2, y2, z2); + } + /** * 判断两个领地是否相交 @@ -158,20 +305,16 @@ public class DominionController { 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())); + private static boolean isContained(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, DominionDTO parent) { + return x1 >= parent.getX1() && x2 <= parent.getX2() && + y1 >= parent.getY1() && y2 <= parent.getY2() && + z1 >= parent.getZ1() && z2 <= parent.getZ2(); + } + + private static boolean isContained(DominionDTO sub, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { + return sub.getX1() >= x1 && sub.getX2() <= x2 && + sub.getY1() >= y1 && sub.getY2() <= y2 && + sub.getZ1() >= z1 && sub.getZ2() <= z2; } public static boolean isOwner(Player player, DominionDTO dominion) { diff --git a/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java b/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java index 6a3dea8..7bd0bf7 100644 --- a/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java +++ b/src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java @@ -77,34 +77,41 @@ public class DominionDTO { } public static List selectAll() { - String sql = "SELECT * FROM dominion"; + String sql = "SELECT * FROM dominion WHERE id > 0"; return query(sql); } public static List selectAll(String world) { - String sql = "SELECT * FROM dominion WHERE world = '" + world + "'"; + String sql = "SELECT * FROM dominion WHERE world = '" + world + "' AND id > 0"; return query(sql); } public static List search(String name) { - String sql = "SELECT * FROM dominion WHERE name LIKE '%" + name + "%'"; + String sql = "SELECT * FROM dominion WHERE name LIKE '%" + name + "%' AND id > 0"; return query(sql); } public static List selectAll(UUID owner) { - String sql = "SELECT * FROM dominion WHERE owner = '" + owner.toString() + "'"; + String sql = "SELECT * FROM dominion WHERE owner = '" + owner.toString() + "' AND id > 0"; return query(sql); } public static DominionDTO select(Integer id) { + if (id == -1) { + return new DominionDTO(-1, + UUID.fromString("00000000-0000-0000-0000-000000000000"), + "根领地", "all", + -2147483648, -2147483648, -2147483648, + 2147483647, 2147483647, 2147483647, -1); + } 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; + public static List selectByParentId(String world, Integer parentId) { + String sql = "SELECT * FROM dominion WHERE world = '" + world + "' AND parent_dom_id = " + parentId + " AND id > 0"; return query(sql); } @@ -112,12 +119,12 @@ public class DominionDTO { 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; + "z1 <= " + z + " AND z2 >= " + z + " AND " + "id > 0"; return query(sql); } public static DominionDTO select(String name) { - String sql = "SELECT * FROM dominion WHERE name = '" + name + "'"; + String sql = "SELECT * FROM dominion WHERE name = '" + name + "' AND id > 0"; List dominions = query(sql); if (dominions.size() == 0) return null; return dominions.get(0);