Compare commits

...

8 Commits

Author SHA1 Message Date
a4c61f183c 将项目迁移到GitHub https://github.com/DeerGiteaMirror/Dominion
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m55s
2024-08-25 11:13:02 +08:00
eeb0f1adc7 实现了采用world uid存储世界而不是name(如果使用此版本出现问题请不要回退版本!请立即和作者取得联系!)
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m4s
2024-08-24 20:53:07 +08:00
87fc89407d 完成了DTO的修改 2024-08-24 19:50:12 +08:00
85b9becfab 更新版本
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m14s
2024-08-24 19:22:41 +08:00
2e589287b5 Merge remote-tracking branch 'origin/master' 2024-08-24 19:20:12 +08:00
ba495d9bd7 修复了部分领地tp点报错未捕获异常问题 2024-08-24 19:15:07 +08:00
bbb97b0859 修复了漏斗可以偷领地内箱子的漏洞
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 5m33s
修复了活塞可以跨领地推东西导致潜在破坏的漏洞
2024-08-23 19:42:19 +08:00
150939dc45 修复了领地管理员权限组可能无法管理领地玩家的问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 5m11s
2024-08-22 10:44:49 +08:00
19 changed files with 261 additions and 112 deletions

View File

@ -16,16 +16,12 @@ jobs:
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
distribution: 'zulu'
cache: gradle
- name: "Build with Gradle"
run: ./gradlew buildPlugin
- name: "Copy jar to staging"
run: mkdir staging && cp build/libs/*.jar staging/
# 设置 jobs Maven pom 版本环境变量
- name: Set Release version env variable
run: |
echo "RELEASE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV
- name: "Build & test"
run: |
echo "done!"
@ -34,6 +30,5 @@ jobs:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: false
title: "Release ${{ env.RELEASE_VERSION }}"
files: |
staging/*.jar

View File

@ -2,7 +2,7 @@
<img src="https://ssl.lunadeer.cn:14437/i/2024/03/28/6604f0cec0f0e.png" alt="" width="70%">
### [开源地址](https://ssl.lunadeer.cn:14446/zhangyuheng/Dominion) | [文档地址](https://ssl.lunadeer.cn:14448/doc/23/)
### [开源地址](https://github.com/DeerGiteaMirror/Dominion) | [文档地址](https://ssl.lunadeer.cn:14448/doc/23/)
### [下载页面](https://ssl.lunadeer.cn:14446/zhangyuheng/Dominion/releases)

View File

@ -4,7 +4,7 @@ plugins {
}
group = "cn.lunadeer"
version = "2.2.1-beta"
version = "2.3.0-beta"
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))

View File

@ -10,6 +10,7 @@ import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -463,10 +464,10 @@ public class Cache {
B | A
*/
private ConcurrentHashMap<String, List<DominionNode>> world_dominion_tree_sector_a; // x >= 0, z >= 0
private ConcurrentHashMap<String, List<DominionNode>> world_dominion_tree_sector_b; // x <= 0, z >= 0
private ConcurrentHashMap<String, List<DominionNode>> world_dominion_tree_sector_c; // x >= 0, z <= 0
private ConcurrentHashMap<String, List<DominionNode>> world_dominion_tree_sector_d; // x <= 0, z <= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_a; // x >= 0, z >= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_b; // x <= 0, z >= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_c; // x >= 0, z <= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_d; // x <= 0, z <= 0
public DominionDTO getLocInDominionDTO(@NotNull Location loc) {
try (AutoTimer ignored = new AutoTimer(Dominion.config.TimerEnabled())) {
@ -479,11 +480,15 @@ public class Cache {
}
public List<DominionNode> getNodes(Location loc) {
return getNodes(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockZ());
public List<DominionNode> getNodes(@NotNull Location loc) {
return getNodes(loc.getWorld().getUID(), loc.getBlockX(), loc.getBlockZ());
}
public List<DominionNode> getNodes(String world, int x, int z) {
public List<DominionNode> getNodes(World world, int x, int z) {
return getNodes(world.getUID(), x, z);
}
public List<DominionNode> getNodes(UUID world, int x, int z) {
if (x >= 0 && z >= 0) {
return world_dominion_tree_sector_a.get(world);
}
@ -507,64 +512,64 @@ public class Cache {
world_dominion_tree_sector_c = new ConcurrentHashMap<>();
world_dominion_tree_sector_d = new ConcurrentHashMap<>();
Map<String, List<DominionDTO>> world_dominions_sector_a = new HashMap<>();
Map<String, List<DominionDTO>> world_dominions_sector_b = new HashMap<>();
Map<String, List<DominionDTO>> world_dominions_sector_c = new HashMap<>();
Map<String, List<DominionDTO>> world_dominions_sector_d = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_a = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_b = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_c = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_d = new HashMap<>();
for (DominionDTO d : dominions) {
// 对每个世界的领地进行四个象限的划分
if (!world_dominions_sector_a.containsKey(d.getWorld()) ||
!world_dominions_sector_b.containsKey(d.getWorld()) ||
!world_dominions_sector_c.containsKey(d.getWorld()) ||
!world_dominions_sector_d.containsKey(d.getWorld())) {
world_dominions_sector_a.put(d.getWorld(), new ArrayList<>());
world_dominions_sector_b.put(d.getWorld(), new ArrayList<>());
world_dominions_sector_c.put(d.getWorld(), new ArrayList<>());
world_dominions_sector_d.put(d.getWorld(), new ArrayList<>());
if (!world_dominions_sector_a.containsKey(d.getWorldUid()) ||
!world_dominions_sector_b.containsKey(d.getWorldUid()) ||
!world_dominions_sector_c.containsKey(d.getWorldUid()) ||
!world_dominions_sector_d.containsKey(d.getWorldUid())) {
world_dominions_sector_a.put(d.getWorldUid(), new ArrayList<>());
world_dominions_sector_b.put(d.getWorldUid(), new ArrayList<>());
world_dominions_sector_c.put(d.getWorldUid(), new ArrayList<>());
world_dominions_sector_d.put(d.getWorldUid(), new ArrayList<>());
}
if (d.getX1() >= 0 && d.getZ1() >= 0) {
world_dominions_sector_a.get(d.getWorld()).add(d);
world_dominions_sector_a.get(d.getWorldUid()).add(d);
} else if (d.getX1() <= 0 && d.getZ1() >= 0) {
if (d.getX2() >= 0) {
world_dominions_sector_a.get(d.getWorld()).add(d);
world_dominions_sector_b.get(d.getWorld()).add(d);
world_dominions_sector_a.get(d.getWorldUid()).add(d);
world_dominions_sector_b.get(d.getWorldUid()).add(d);
} else {
world_dominions_sector_b.get(d.getWorld()).add(d);
world_dominions_sector_b.get(d.getWorldUid()).add(d);
}
} else if (d.getX1() >= 0 && d.getZ1() <= 0) {
if (d.getZ2() >= 0) {
world_dominions_sector_a.get(d.getWorld()).add(d);
world_dominions_sector_c.get(d.getWorld()).add(d);
world_dominions_sector_a.get(d.getWorldUid()).add(d);
world_dominions_sector_c.get(d.getWorldUid()).add(d);
} else {
world_dominions_sector_c.get(d.getWorld()).add(d);
world_dominions_sector_c.get(d.getWorldUid()).add(d);
}
} else {
if (d.getX2() >= 0 && d.getZ2() >= 0) {
world_dominions_sector_a.get(d.getWorld()).add(d);
world_dominions_sector_b.get(d.getWorld()).add(d);
world_dominions_sector_c.get(d.getWorld()).add(d);
world_dominions_sector_d.get(d.getWorld()).add(d);
world_dominions_sector_a.get(d.getWorldUid()).add(d);
world_dominions_sector_b.get(d.getWorldUid()).add(d);
world_dominions_sector_c.get(d.getWorldUid()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
} else if (d.getX2() >= 0 && d.getZ2() <= 0) {
world_dominions_sector_c.get(d.getWorld()).add(d);
world_dominions_sector_d.get(d.getWorld()).add(d);
world_dominions_sector_c.get(d.getWorldUid()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
} else if (d.getZ2() >= 0 && d.getX2() <= 0) {
world_dominions_sector_b.get(d.getWorld()).add(d);
world_dominions_sector_d.get(d.getWorld()).add(d);
world_dominions_sector_b.get(d.getWorldUid()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
} else {
world_dominions_sector_d.get(d.getWorld()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
}
}
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions_sector_a.entrySet()) {
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_a.entrySet()) {
world_dominion_tree_sector_a.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions_sector_b.entrySet()) {
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_b.entrySet()) {
world_dominion_tree_sector_b.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions_sector_c.entrySet()) {
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_c.entrySet()) {
world_dominion_tree_sector_c.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions_sector_d.entrySet()) {
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_d.entrySet()) {
world_dominion_tree_sector_d.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
}

View File

@ -55,20 +55,16 @@ public class DominionNode {
return node;
} else {
DominionNode childDominion = getLocInDominionNode(node.children, loc);
if (childDominion == null) {
return node;
} else {
return childDominion;
}
return Objects.requireNonNullElse(childDominion, node);
}
}
}
return null;
}
public static boolean isInDominion(@Nullable DominionDTO dominion, Location location) {
public static boolean isInDominion(@Nullable DominionDTO dominion, @NotNull Location location) {
if (dominion == null) return false;
if (!Objects.equals(dominion.getWorld(), location.getWorld().getName())) return false;
if (!Objects.equals(dominion.getWorldUid(), location.getWorld().getUID())) return false;
double x = location.getX();
double y = location.getY();
double z = location.getZ();

View File

@ -391,7 +391,11 @@ public class DominionOperate {
if (location == null) {
int x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld());
World world = dominionDTO.getWorld();
if (world == null) {
Notification.error(sender, "领地所在世界不存在");
return;
}
location = new Location(world, x, player.getLocation().getY(), z);
XLogger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
}
@ -459,7 +463,11 @@ public class DominionOperate {
Location location = dominionDTO.getTpLocation();
int center_x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int center_z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld());
World world = dominionDTO.getWorld();
if (world == null) {
Notification.error(player, "领地所在世界不存在");
return;
}
if (location == null) {
location = new Location(world, center_x, player.getLocation().getY(), center_z);
Notification.warn(player, "领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());

View File

@ -52,8 +52,11 @@ public class Operator {
Map<String, List<String>> mca_cords = new HashMap<>();
List<DominionDTO> doms = Cache.instance.getDominions();
for (DominionDTO dom : doms) {
if (!mca_cords.containsKey(dom.getWorld())) {
mca_cords.put(dom.getWorld(), new ArrayList<>());
if (dom.getWorld() == null) {
continue;
}
if (!mca_cords.containsKey(dom.getWorld().getName())) {
mca_cords.put(dom.getWorld().getName(), new ArrayList<>());
}
Integer world_x1 = dom.getX1();
Integer world_x2 = dom.getX2();
@ -66,10 +69,10 @@ public class Operator {
for (int x = mca_x1; x <= mca_x2; x++) {
for (int z = mca_z1; z <= mca_z2; z++) {
String file_name = "r." + x + "." + z + ".mca";
if (mca_cords.get(dom.getWorld()).contains(file_name)) {
if (mca_cords.get(dom.getWorld().getName()).contains(file_name)) {
continue;
}
mca_cords.get(dom.getWorld()).add(file_name);
mca_cords.get(dom.getWorld().getName()).add(file_name);
}
}
}

View File

@ -92,7 +92,7 @@ public class DominionController {
operator.setResponse(FAIL.addMessage("已经存在名称为 %s 的领地", name));
return;
}
if (!loc1.getWorld().equals(loc2.getWorld())) {
if (!loc1.getWorld().getUID().equals(loc2.getWorld().getUID())) {
operator.setResponse(FAIL.addMessage("选点世界不一致"));
return;
}
@ -137,10 +137,10 @@ public class DominionController {
}
}
// 创建 dominion (此步骤不会写入数据)
DominionDTO dominion = DominionDTO.create(parent_dominion.getId() == -1 ? operator.getUniqueId() : parent_dominion.getOwner(), name, loc1.getWorld().getName(),
DominionDTO dominion = DominionDTO.create(parent_dominion.getId() == -1 ? operator.getUniqueId() : parent_dominion.getOwner(), name, loc1.getWorld(),
minX, minY, minZ, maxX, maxY, maxZ, parent_dominion);
// 如果parent_dominion不为-1 检查是否在同一世界
if (parent_dominion.getId() != -1 && !parent_dominion.getWorld().equals(dominion.getWorld())) {
if (parent_dominion.getId() != -1 && !parent_dominion.getWorldUid().equals(dominion.getWorldUid())) {
operator.setResponse(FAIL.addMessage("父领地与子领地不在同一世界。"));
return;
}
@ -154,7 +154,7 @@ public class DominionController {
return;
}
// 获取此领地的所有同级领地
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), parent_dominion.getId());
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), parent_dominion.getId());
// 检查是否与出生点保护冲突
if (isIntersectSpawn(operator, dominion)) {
operator.setResponse(FAIL.addMessage("与出生点保护冲突"));
@ -191,7 +191,7 @@ public class DominionController {
if (radius == -1) {
return false;
}
World world = Dominion.instance.getServer().getWorld(dominion.getWorld());
World world = dominion.getWorld();
if (world == null) {
return false;
}
@ -200,7 +200,7 @@ public class DominionController {
, spawn.getBlockX() + radius, spawn.getBlockY() + radius, spawn.getBlockZ() + radius);
}
private static boolean isIntersectSpawn(AbstractOperator operator, String world, int[] cords) {
private static boolean isIntersectSpawn(AbstractOperator operator, @NotNull World world, int[] cords) {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false;
}
@ -208,7 +208,7 @@ public class DominionController {
if (radius == -1) {
return false;
}
Location spawn = Objects.requireNonNull(Dominion.instance.getServer().getWorld(world)).getSpawnLocation();
Location spawn = world.getSpawnLocation();
return isIntersect(cords, spawn.getBlockX() - radius, spawn.getBlockY() - radius, spawn.getBlockZ() - radius
, spawn.getBlockX() + radius, spawn.getBlockY() + radius, spawn.getBlockZ() + radius);
}
@ -263,7 +263,7 @@ public class DominionController {
return;
}
// 获取同世界下的所有同级领地
List<DominionDTO> exist_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getParentDomId());
List<DominionDTO> exist_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), dominion.getParentDomId());
for (DominionDTO exist_dominion : exist_dominions) {
if (isIntersect(exist_dominion, newCords)) {
// 如果是自己跳过
@ -317,7 +317,7 @@ public class DominionController {
return;
}
// 获取所有的子领地
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId());
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), dominion.getId());
for (DominionDTO sub_dominion : sub_dominions) {
if (!isContained(sub_dominion, newCords)) {
operator.setResponse(FAIL.addMessage("缩小后的领地无法包含子领地 %s", sub_dominion.getName()));
@ -478,9 +478,9 @@ public class DominionController {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "领地 %s 不存在", dominion_name));
return;
}
World world = Dominion.instance.getServer().getWorld(dominion.getWorld());
World world = dominion.getWorld();
if (world == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "世界 %s 不存在", dominion.getWorld()));
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "领地所在世界不存在"));
return;
}
Location loc = new Location(world, x, y, z);
@ -679,7 +679,7 @@ public class DominionController {
}
private static List<DominionDTO> getSubDominionsRecursive(DominionDTO dominion) {
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId());
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), dominion.getId());
List<DominionDTO> sub_sub_dominions = new ArrayList<>();
for (DominionDTO sub_dominion : sub_dominions) {
sub_sub_dominions.addAll(getSubDominionsRecursive(sub_dominion));
@ -777,11 +777,11 @@ public class DominionController {
return Cache.instance.getPlayerDominionCount(operator.getUniqueId()) >= Dominion.config.getLimitAmount(operator.getPlayer()) && Dominion.config.getLimitAmount(operator.getPlayer()) != -1;
}
private static boolean worldNotValid(AbstractOperator operator, String world) {
private static boolean worldNotValid(AbstractOperator operator, String worldName) {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false;
}
return Dominion.config.getWorldBlackList(operator.getPlayer()).contains(world);
return Dominion.config.getWorldBlackList(operator.getPlayer()).contains(worldName);
}
private static DominionDTO getExistDomAndIsOwner(AbstractOperator operator, String dominion_name) {
@ -854,7 +854,7 @@ public class DominionController {
operator.setResponse(FAIL.addMessage("无法获取你的位置"));
return null;
}
if (!operator.getLocation().getWorld().getName().equals(dominion.getWorld())) {
if (!operator.getLocation().getWorld().getUID().equals(dominion.getWorldUid())) {
operator.setResponse(FAIL.addMessage("禁止跨世界操作"));
return null;
}
@ -929,7 +929,7 @@ public class DominionController {
for (DominionDTO sub_dominion : sub_dominions) {
sub_names = sub_dominion.getName() + ", ";
}
if (sub_dominions.size() > 0) {
if (!sub_dominions.isEmpty()) {
sub_names = sub_names.substring(0, sub_names.length() - 2);
WARNING.addMessage("(子领地:%s)", sub_names);
}

View File

@ -2,8 +2,7 @@ package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.dtos.*;
import static cn.lunadeer.dominion.utils.ControllerUtils.noAuthToChangeFlags;
import static cn.lunadeer.dominion.utils.ControllerUtils.notOwner;
import static cn.lunadeer.dominion.utils.ControllerUtils.*;
public class MemberController {
@ -33,7 +32,7 @@ public class MemberController {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员", player_name, dominionName));
return;
}
if (privilege.getAdmin() && notOwner(operator, dominion)) {
if (isAdmin(privilege) && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法移除一个领地管理员", dominionName));
return;
}
@ -69,7 +68,12 @@ public class MemberController {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员", player_name, dominionName));
return;
}
if ((flag.equals("admin") || privilege.getAdmin()) && notOwner(operator, dominion)) {
GroupDTO group = GroupDTO.select(privilege.getGroupId());
if (group != null) {
operator.setResponse(FAIL.addMessage("玩家 %s 属于 %s 权限组,无法单独设置权限", player_name, group.getName()));
return;
}
if ((flag.equals("admin") || isAdmin(privilege)) && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他玩家管理员的权限", dominionName));
return;
}
@ -141,7 +145,7 @@ public class MemberController {
operator.setResponse(FAIL.addMessage("模板 %s 不存在", templateName));
return;
}
if (notOwner(operator, dominion) && privilege.getAdmin()) {
if (notOwner(operator, dominion) && (isAdmin(privilege) || template.getAdmin())) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他管理员的权限", dominionName));
return;
}

View File

@ -10,6 +10,8 @@ import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -33,7 +35,7 @@ public class DominionDTO {
Integer id = rs.getInt("id");
UUID owner = UUID.fromString(rs.getString("owner"));
String name = rs.getString("name");
String world = rs.getString("world");
UUID world_uid = UUID.fromString(rs.getString("world_uid"));
Integer x1 = rs.getInt("x1");
Integer y1 = rs.getInt("y1");
Integer z1 = rs.getInt("z1");
@ -48,7 +50,7 @@ public class DominionDTO {
}
String color = rs.getString("color");
DominionDTO dominion = new DominionDTO(id, owner, name, world, x1, y1, z1, x2, y2, z2, parentDomId,
DominionDTO dominion = new DominionDTO(id, owner, name, world_uid, x1, y1, z1, x2, y2, z2, parentDomId,
rs.getString("join_message"),
rs.getString("leave_message"),
flags,
@ -79,7 +81,7 @@ public class DominionDTO {
if (id == -1) {
return new DominionDTO(-1,
UUID.fromString("00000000-0000-0000-0000-000000000000"),
"根领地", "all",
"根领地", UUID.fromString("00000000-0000-0000-0000-000000000000"),
-2147483648, -2147483648, -2147483648,
2147483647, 2147483647, 2147483647, -1);
}
@ -89,17 +91,21 @@ public class DominionDTO {
return dominions.getFirst();
}
public static List<DominionDTO> selectByParentId(String world, Integer parentId) {
String sql = "SELECT * FROM dominion WHERE world = ? AND parent_dom_id = ? AND id > 0;";
return query(sql, world, parentId);
public static List<DominionDTO> selectByParentId(World world, Integer parentId){
return selectByParentId(world.getUID(), parentId);
}
public static List<DominionDTO> selectByLocation(String world, Integer x, Integer y, Integer z) {
String sql = "SELECT * FROM dominion WHERE world = ? AND " +
public static List<DominionDTO> selectByParentId(UUID world_uid, Integer parentId) {
String sql = "SELECT * FROM dominion WHERE world_uid = ? AND parent_dom_id = ? AND id > 0;";
return query(sql, world_uid.toString(), parentId);
}
public static List<DominionDTO> selectByLocation(UUID world_uid, Integer x, Integer y, Integer z) {
String sql = "SELECT * FROM dominion WHERE world_uid = ? AND " +
"x1 <= ? AND x2 >= ? AND " +
"y1 <= ? AND y2 >= ? AND " +
"z1 <= ? AND z2 >= ? AND " + "id > 0;";
return query(sql, world, x, x, y, y, z, z);
return query(sql, world_uid.toString(), x, x, y, y, z, z);
}
public static DominionDTO select(String name) {
@ -113,7 +119,7 @@ public class DominionDTO {
InsertRow insert = new InsertRow().returningAll().table("dominion").onConflictDoNothing(new Field("id", null));
insert.field(dominion.owner)
.field(dominion.name)
.field(dominion.world)
.field(dominion.world_uid)
.field(dominion.x1).field(dominion.y1).field(dominion.z1)
.field(dominion.x2).field(dominion.y2).field(dominion.z2)
.field(dominion.parentDomId)
@ -139,7 +145,7 @@ public class DominionDTO {
Cache.instance.loadDominions();
}
private DominionDTO(Integer id, UUID owner, String name, String world,
private DominionDTO(Integer id, UUID owner, String name, UUID world_uid,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId,
String joinMessage, String leaveMessage,
@ -149,7 +155,7 @@ public class DominionDTO {
this.id.value = id;
this.owner.value = owner.toString();
this.name.value = name;
this.world.value = world;
this.world_uid.value = world_uid.toString();
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
@ -165,13 +171,13 @@ public class DominionDTO {
}
private DominionDTO(Integer id, UUID owner, String name, String world,
private DominionDTO(Integer id, UUID owner, String name, UUID world_uid,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId) {
this.id.value = id;
this.owner.value = owner.toString();
this.name.value = name;
this.world.value = world;
this.world_uid.value = world_uid.toString();
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
@ -181,20 +187,19 @@ public class DominionDTO {
this.parentDomId.value = parentDomId;
}
public DominionDTO(UUID owner, String name, String world,
public DominionDTO(UUID owner, String name, @NotNull World world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this(null, owner, name, world, x1, y1, z1, x2, y2, z2, -1);
this(null, owner, name, world.getUID(), x1, y1, z1, x2, y2, z2, -1);
}
public static DominionDTO create(UUID owner, String name, String world,
public static DominionDTO create(UUID owner, String name, @NotNull World world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, DominionDTO parent) {
return new DominionDTO(null, owner, name, world, x1, y1, z1, x2, y2, z2, parent == null ? -1 : parent.getId());
return new DominionDTO(null, owner, name, world.getUID(), x1, y1, z1, x2, y2, z2, parent == null ? -1 : parent.getId());
}
private final Field id = new Field("id", FieldType.INT);
private final Field owner = new Field("owner", FieldType.STRING);
private final Field name = new Field("name", FieldType.STRING);
private final Field world = new Field("world", FieldType.STRING);
private final Field x1 = new Field("x1", FieldType.INT);
private final Field y1 = new Field("y1", FieldType.INT);
private final Field z1 = new Field("z1", FieldType.INT);
@ -207,6 +212,7 @@ public class DominionDTO {
private final Map<Flag, Boolean> flags = new HashMap<>();
private final Field tp_location = new Field("tp_location", "default");
private final Field color = new Field("color", "#00BFFF");
private final Field world_uid = new Field("world_uid", FieldType.STRING);
// getters and setters
@ -247,8 +253,12 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.name));
}
public String getWorld() {
return (String) world.value;
public @Nullable World getWorld() {
return Dominion.instance.getServer().getWorld(getWorldUid());
}
public UUID getWorldUid() {
return UUID.fromString((String) world_uid.value);
}
public Integer getX1() {
@ -384,12 +394,12 @@ public class DominionDTO {
} else {
// 0:0:0
String[] loc = ((String) tp_location.value).split(":");
World w = Dominion.instance.getServer().getWorld(getWorld());
World w = getWorld();
if (loc.length == 3 && w != null) {
return new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
} else {
XLogger.warn("领地传送点数据异常: %s", tp_location);
XLogger.debug("world: %s, loc.length: %d", world, loc.length);
XLogger.debug("world: %s, loc.length: %d", getWorld(), loc.length);
return null;
}
}
@ -401,11 +411,11 @@ public class DominionDTO {
}
public Location getLocation1() {
return new Location(Dominion.instance.getServer().getWorld(getWorld()), getX1(), getY1(), getZ1());
return new Location(getWorld(), getX1(), getY1(), getZ1());
}
public Location getLocation2() {
return new Location(Dominion.instance.getServer().getWorld(getWorld()), getX2(), getY2(), getZ2());
return new Location(getWorld(), getX2(), getY2(), getZ2());
}
public DominionDTO setColor(String color) {

View File

@ -46,6 +46,7 @@ public enum Flag {
HONEY("honey", "蜂巢交互", "是否可以采蜂蜜", false, false, true),
HOOK("hook", "使用钓钩", "是否可以使用钓钩", false, false, true),
HOPPER("hopper", "特殊容器", "包含:漏斗/熔炉/发射器/投掷器/高炉/烟熏炉", false, false, true),
HOPPER_OUTSIDE("hopper_outside", "领地外漏斗对领地内箱子是否生效", "领地外的漏斗是否可以对领地内的箱子生效", false, true, true),
IGNITE("ignite", "点燃", "是否可以使用打火石点火", false, false, true),
ITEM_FRAME_INTERACTIVE("item_frame_interactive", "展示框交互", "是否可以与物品展示框交互(旋转展示框的东西)", false, false, true),
ITEM_FRAME_PROJ_DAMAGE("item_frame_proj_damage", "投掷物是否可以破坏展示框/画", "非玩家发出的投掷物是否可以破坏展示框/画等悬挂物", false, true, true),
@ -56,6 +57,7 @@ public enum Flag {
MOVE("move", "移动", "是否可以移动", true, false, true),
NOTE_BLOCK("note_block", "点击音符盒", "红石音乐或者某些红石机器会用到...", false, false, true),
PLACE("place", "放置方块", "是否可以放置方块(包括:一般方块、展示框、岩浆、水)", false, false, true),
PISTON_OUTSIDE("piston_outside", "活塞是否可以跨领地推动方块", "活塞是否可以往领地内推东西或推东西到领地外", false, true, true),
PRESSURE("pressure", "压力板交互", "是否可以触发各种材质的压力板", false, false, true),
RIDING("riding", "骑乘载具", "是否可以骑乘各种载具", false, false, true),
REPEATER("repeater", "中继器交互", "是否可以与中继器交互", false, false, true),

View File

@ -1,12 +1,16 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.databse.*;
import cn.lunadeer.minecraftpluginutils.databse.syntax.AddColumn;
import cn.lunadeer.minecraftpluginutils.databse.syntax.CreateTable;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.RemoveColumn;
import org.bukkit.World;
import java.sql.ResultSet;
import java.util.List;
public class DatabaseTables {
public static void migrate() {
@ -242,5 +246,18 @@ public class DatabaseTables {
TableColumn player_name_using_group_title_id = new TableColumn("using_group_title_id", FieldType.INT, false, false, true, false, -1);
new AddColumn(player_name_using_group_title_id).table("player_name").ifNotExists().execute();
}
// 2.3.0 change world name to world uid
if (!Common.IsFieldExist("dominion", "world_uid")) {
TableColumn dominion_world_uid = new TableColumn("world_uid", FieldType.STRING, false, false, true, false, "'00000000-0000-0000-0000-000000000000'");
new AddColumn(dominion_world_uid).table("dominion").ifNotExists().execute();
List<World> worlds = Dominion.instance.getServer().getWorlds();
for (World world : worlds) {
String sql = String.format("UPDATE dominion SET world_uid = '%s' WHERE world = '%s';", world.getUID().toString(), world.getName());
DatabaseManager.instance.query(sql);
}
DatabaseManager.instance.query("UPDATE dominion SET world_uid = '00000000-0000-0000-0000-000000000000' WHERE world = 'all';");
new RemoveColumn("world").table("dominion").IfExists().execute();
}
}
}

View File

@ -21,10 +21,13 @@ public class BlueMapConnect {
BlueMapAPI.getInstance().ifPresent(api -> {
Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO dominion : Cache.instance.getDominions()) {
if (!world_dominions.containsKey(dominion.getWorld())) {
world_dominions.put(dominion.getWorld(), new ArrayList<>());
if (dominion.getWorld() == null) {
continue;
}
world_dominions.get(dominion.getWorld()).add(dominion);
if (!world_dominions.containsKey(dominion.getWorld().getName())) {
world_dominions.put(dominion.getWorld().getName(), new ArrayList<>());
}
world_dominions.get(dominion.getWorld().getName()).add(dominion);
}
for (Map.Entry<String, List<DominionDTO>> d : world_dominions.entrySet()) {
api.getWorld(d.getKey()).ifPresent(world -> {

View File

@ -4,8 +4,10 @@ import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
public class ControllerUtils {
@ -51,4 +53,20 @@ public class ControllerUtils {
}
}
/**
* 检查一个成员是否是管理员
* 此方法会同时尝试搜索玩家所在的权限组是否是管理员
*
* @param member 成员权限
* @return 是否是管理员
*/
public static boolean isAdmin(@NotNull MemberDTO member) {
GroupDTO group = GroupDTO.select(member.getGroupId());
if (group == null) {
return member.getAdmin();
} else {
return group.getAdmin();
}
}
}

View File

@ -42,11 +42,14 @@ public class DynmapConnect extends DynmapCommonAPIListener {
String nameLabel = "<div>" + dominion.getName() + "</div>";
double[] xx = {dominion.getX1(), dominion.getX2()};
double[] zz = {dominion.getZ1(), dominion.getZ2()};
if (dominion.getWorld() == null) {
return;
}
AreaMarker marker = this.markerSet_dominion.createAreaMarker(
dominion.getId().toString(),
nameLabel,
true,
dominion.getWorld(),
dominion.getWorld().getName(),
xx,
zz,
false

View File

@ -7,6 +7,7 @@ import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Location;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -14,10 +15,13 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.entity.*;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import java.util.Objects;
@ -305,4 +309,42 @@ public class EnvironmentEvents implements Listener {
DominionDTO dom = Cache.instance.getDominionByLoc(entity.getLocation());
checkFlag(dom, Flag.VILLAGER_SPAWN, event);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onHopper(InventoryMoveItemEvent event) {
Inventory hopper = event.getDestination();
Inventory inventory = event.getSource();
DominionDTO hopperDom = Cache.instance.getDominionByLoc(hopper.getLocation());
DominionDTO inventoryDom = Cache.instance.getDominionByLoc(inventory.getLocation());
if (hopperDom == null && inventoryDom != null) {
checkFlag(inventoryDom, Flag.HOPPER_OUTSIDE, event);
}
if (hopperDom != null && inventoryDom != null) {
if (!hopperDom.getId().equals(inventoryDom.getId())) {
checkFlag(inventoryDom, Flag.HOPPER_OUTSIDE, event);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockPushedByPiston(BlockPistonExtendEvent event) {
Block piston = event.getBlock();
DominionDTO pistonDom = Cache.instance.getDominionByLoc(piston.getLocation());
BlockFace direction = event.getDirection();
Block endBlockAfterPush = piston.getRelative(direction, event.getBlocks().size() + 1);
DominionDTO endBlockDom = Cache.instance.getDominionByLoc(endBlockAfterPush.getLocation());
if (pistonDom != null && endBlockDom == null) {
checkFlag(pistonDom, Flag.PISTON_OUTSIDE, event);
}
if (pistonDom == null && endBlockDom != null) {
checkFlag(endBlockDom, Flag.PISTON_OUTSIDE, event);
}
if (pistonDom != null && endBlockDom != null) {
if (!pistonDom.getId().equals(endBlockDom.getId())) {
if (!endBlockDom.getFlagValue(Flag.PISTON_OUTSIDE) || !pistonDom.getFlagValue(Flag.PISTON_OUTSIDE)) {
event.setCancelled(true);
}
}
}
}
}

View File

@ -78,7 +78,7 @@ public class SelectPointEvents implements Listener {
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()) + 1;
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()) + 1;
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()) + 1;
DominionDTO dominion = new DominionDTO(player.getUniqueId(), "", loc1.getWorld().getName(),
DominionDTO dominion = new DominionDTO(player.getUniqueId(), "", loc1.getWorld(),
minX, minY, minZ, maxX, maxY, maxZ);
if (Dominion.config.getEconomyEnable()) {
if (!VaultConnect.instance.economyAvailable()) {

View File

@ -7,6 +7,7 @@ import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Location;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -14,10 +15,13 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.entity.*;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import java.util.Objects;
@ -305,4 +309,43 @@ public class EnvironmentEvents implements Listener {
DominionDTO dom = Cache.instance.getDominionByLoc(entity.getLocation());
checkFlag(dom, Flag.VILLAGER_SPAWN, event);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onHopper(InventoryMoveItemEvent event) {
Inventory hopper = event.getDestination();
Inventory inventory = event.getSource();
DominionDTO hopperDom = Cache.instance.getDominionByLoc(hopper.getLocation());
DominionDTO inventoryDom = Cache.instance.getDominionByLoc(inventory.getLocation());
if (hopperDom == null && inventoryDom != null) {
checkFlag(inventoryDom, Flag.HOPPER_OUTSIDE, event);
}
if (hopperDom != null && inventoryDom != null) {
if (!hopperDom.getId().equals(inventoryDom.getId())) {
checkFlag(inventoryDom, Flag.HOPPER_OUTSIDE, event);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockPushedByPiston(BlockPistonExtendEvent event) {
Block piston = event.getBlock();
DominionDTO pistonDom = Cache.instance.getDominionByLoc(piston.getLocation());
BlockFace direction = event.getDirection();
Block endBlockAfterPush = piston.getRelative(direction, event.getBlocks().size() + 1);
DominionDTO endBlockDom = Cache.instance.getDominionByLoc(endBlockAfterPush.getLocation());
if (pistonDom != null && endBlockDom == null) {
checkFlag(pistonDom, Flag.PISTON_OUTSIDE, event);
}
if (pistonDom == null && endBlockDom != null) {
checkFlag(endBlockDom, Flag.PISTON_OUTSIDE, event);
}
if (pistonDom != null && endBlockDom != null) {
if (!pistonDom.getId().equals(endBlockDom.getId())) {
if (!endBlockDom.getFlagValue(Flag.PISTON_OUTSIDE) || !pistonDom.getFlagValue(Flag.PISTON_OUTSIDE)) {
event.setCancelled(true);
}
}
}
}
}

View File

@ -78,7 +78,7 @@ public class SelectPointEvents implements Listener {
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()) + 1;
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()) + 1;
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()) + 1;
DominionDTO dominion = new DominionDTO(player.getUniqueId(), "", loc1.getWorld().getName(),
DominionDTO dominion = new DominionDTO(player.getUniqueId(), "", loc1.getWorld(),
minX, minY, minZ, maxX, maxY, maxZ);
if (Dominion.config.getEconomyEnable()) {
if (!VaultConnect.instance.economyAvailable()) {