Merge branch 'mysql-impl'
Java CI-CD with Maven / build (push) Successful in 8m38s Details

# Conflicts:
#	pom.xml
#	src/main/java/cn/lunadeer/dominion/Cache.java
This commit is contained in:
zhangyuheng 2024-06-23 10:10:08 +08:00
commit 9089d7ae34
16 changed files with 750 additions and 578 deletions

View File

@ -30,13 +30,13 @@
## 功能介绍 ## 功能介绍
- 支持 Postgresql 或 sqlite 存储数据; - 支持 Postgresql、Mysql、Sqlite3 存储数据;
- 支持BlueMap卫星地图渲染 - 支持BlueMap卫星地图渲染
- 支持为玩家单独设置特权; - 支持为玩家单独设置特权;
- 支持设置领地管理员; - 支持设置领地管理员;
- 支持子领地; - 支持子领地;
- 采用 TUI 方式进行权限配置交互,简单快捷; - 采用 TUI 方式进行权限配置交互,简单快捷;
- 支持基础价格系统 - 支持经济系统(需要 Vault 前置)
- 领地区域可视化; - 领地区域可视化;
- 管理员可在游戏内使用TUI配置领地系统 - 管理员可在游戏内使用TUI配置领地系统

View File

@ -6,7 +6,7 @@
<groupId>cn.lunadeer</groupId> <groupId>cn.lunadeer</groupId>
<artifactId>Dominion</artifactId> <artifactId>Dominion</artifactId>
<version>1.32.2-beta</version> <version>1.33.4-beta</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Dominion</name> <name>Dominion</name>
@ -82,7 +82,7 @@
<dependency> <dependency>
<groupId>cn.lunadeer</groupId> <groupId>cn.lunadeer</groupId>
<artifactId>MinecraftPluginUtils</artifactId> <artifactId>MinecraftPluginUtils</artifactId>
<version>1.3.2-SNAPSHOT</version> <version>1.3.4-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.BlueMap-Minecraft</groupId> <groupId>com.github.BlueMap-Minecraft</groupId>

View File

@ -1,6 +1,7 @@
package cn.lunadeer.dominion; package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger; import cn.lunadeer.minecraftpluginutils.XLogger;
import com.flowpowered.math.vector.Vector2d; import com.flowpowered.math.vector.Vector2d;
import de.bluecolored.bluemap.api.BlueMapAPI; import de.bluecolored.bluemap.api.BlueMapAPI;
@ -17,112 +18,116 @@ public class BlueMapConnect {
if (!Dominion.config.getBlueMap()) { if (!Dominion.config.getBlueMap()) {
return; return;
} }
try { Scheduler.runTaskAsync(() -> {
BlueMapAPI.getInstance().ifPresent(api -> { try {
Map<String, List<DominionDTO>> world_dominions = new HashMap<>(); BlueMapAPI.getInstance().ifPresent(api -> {
for (DominionDTO dominion : Cache.instance.getDominions()) { Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
if (!world_dominions.containsKey(dominion.getWorld())) { for (DominionDTO dominion : Cache.instance.getDominions()) {
world_dominions.put(dominion.getWorld(), new ArrayList<>()); if (!world_dominions.containsKey(dominion.getWorld())) {
world_dominions.put(dominion.getWorld(), new ArrayList<>());
}
world_dominions.get(dominion.getWorld()).add(dominion);
} }
world_dominions.get(dominion.getWorld()).add(dominion); for (Map.Entry<String, List<DominionDTO>> d : world_dominions.entrySet()) {
} api.getWorld(d.getKey()).ifPresent(world -> {
for (Map.Entry<String, List<DominionDTO>> d : world_dominions.entrySet()) { MarkerSet markerSet = MarkerSet.builder()
api.getWorld(d.getKey()).ifPresent(world -> { .label("Dominion")
MarkerSet markerSet = MarkerSet.builder()
.label("Dominion")
.build();
for (DominionDTO dominion : d.getValue()) {
Collection<Vector2d> 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));
vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ2() - 0.001));
vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ2() - 0.001));
Shape shape = new Shape(vectors);
double x = vectors.iterator().next().getX();
double z = vectors.iterator().next().getY();
double y = dominion.getY1();
int r = dominion.getColorR();
int g = dominion.getColorG();
int b = dominion.getColorB();
Color line = new Color(r, g, b, 0.8F);
Color fill = new Color(r, g, b, 0.2F);
ExtrudeMarker marker = ExtrudeMarker.builder()
.label(dominion.getName())
.position(x, y, z)
.shape(shape, dominion.getY1() + 0.001f, dominion.getY2() - 0.001f)
.lineColor(line)
.fillColor(fill)
.build(); .build();
markerSet.getMarkers()
.put(dominion.getName(), marker);
}
for (BlueMapMap map : world.getMaps()) { for (DominionDTO dominion : d.getValue()) {
map.getMarkerSets().put(d.getKey() + "-" + markerSet.getLabel(), markerSet); Collection<Vector2d> 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));
} vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ2() - 0.001));
}); vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ2() - 0.001));
} catch (NoClassDefFoundError e) { Shape shape = new Shape(vectors);
XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。"); double x = vectors.iterator().next().getX();
XLogger.err(e.getMessage()); double z = vectors.iterator().next().getY();
} double y = dominion.getY1();
int r = dominion.getColorR();
int g = dominion.getColorG();
int b = dominion.getColorB();
Color line = new Color(r, g, b, 0.8F);
Color fill = new Color(r, g, b, 0.2F);
ExtrudeMarker marker = ExtrudeMarker.builder()
.label(dominion.getName())
.position(x, y, z)
.shape(shape, dominion.getY1() + 0.001f, dominion.getY2() - 0.001f)
.lineColor(line)
.fillColor(fill)
.build();
markerSet.getMarkers()
.put(dominion.getName(), marker);
}
for (BlueMapMap map : world.getMaps()) {
map.getMarkerSets().put(d.getKey() + "-" + markerSet.getLabel(), markerSet);
}
});
}
});
} catch (NoClassDefFoundError e) {
XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。");
XLogger.err(e.getMessage());
}
});
} }
public static void renderMCA(Map<String, List<String>> mca_files) { public static void renderMCA(Map<String, List<String>> mca_files) {
if (!Dominion.config.getBlueMap()) { if (!Dominion.config.getBlueMap()) {
return; return;
} }
try { Scheduler.runTaskAsync(() -> {
BlueMapAPI.getInstance().ifPresent(api -> { try {
for (String world : mca_files.keySet()) { BlueMapAPI.getInstance().ifPresent(api -> {
api.getWorld(world).ifPresent(bmWorld -> { for (String world : mca_files.keySet()) {
MarkerSet markerSet = MarkerSet.builder() api.getWorld(world).ifPresent(bmWorld -> {
.label("MCA") MarkerSet markerSet = MarkerSet.builder()
.defaultHidden(true) .label("MCA")
.build(); .defaultHidden(true)
for (String file : mca_files.get(world)) {
// r.-1.-1.mca
int mca_x = Integer.parseInt(file.split("\\.")[1]);
int mca_z = Integer.parseInt(file.split("\\.")[2]);
int world_x1 = mca_x * 512;
int world_x2 = (mca_x + 1) * 512;
int world_z1 = mca_z * 512;
int world_z2 = (mca_z + 1) * 512;
Collection<Vector2d> vectors = new ArrayList<>();
vectors.add(new Vector2d(world_x1 + 0.001, world_z1 + 0.001));
vectors.add(new Vector2d(world_x2 - 0.001, world_z1 + 0.001));
vectors.add(new Vector2d(world_x2 - 0.001, world_z2 - 0.001));
vectors.add(new Vector2d(world_x1 + 0.001, world_z2 - 0.001));
Shape shape = new Shape(vectors);
double x = vectors.iterator().next().getX();
double z = vectors.iterator().next().getY();
double y = -64;
Color line = new Color(0, 204, 0, 0.8F);
Color fill = new Color(0, 204, 0, 0.2F);
ExtrudeMarker marker = ExtrudeMarker.builder()
.label(file)
.position(x, y, z)
.shape(shape, -64, 320)
.lineColor(line)
.fillColor(fill)
.build(); .build();
markerSet.getMarkers() for (String file : mca_files.get(world)) {
.put(file, marker); // r.-1.-1.mca
} int mca_x = Integer.parseInt(file.split("\\.")[1]);
for (BlueMapMap map : bmWorld.getMaps()) { int mca_z = Integer.parseInt(file.split("\\.")[2]);
map.getMarkerSets().put(world + "-" + markerSet.getLabel(), markerSet); int world_x1 = mca_x * 512;
} int world_x2 = (mca_x + 1) * 512;
}); int world_z1 = mca_z * 512;
} int world_z2 = (mca_z + 1) * 512;
}); Collection<Vector2d> vectors = new ArrayList<>();
} catch (NoClassDefFoundError e) { vectors.add(new Vector2d(world_x1 + 0.001, world_z1 + 0.001));
XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。"); vectors.add(new Vector2d(world_x2 - 0.001, world_z1 + 0.001));
XLogger.err(e.getMessage()); vectors.add(new Vector2d(world_x2 - 0.001, world_z2 - 0.001));
} vectors.add(new Vector2d(world_x1 + 0.001, world_z2 - 0.001));
Shape shape = new Shape(vectors);
double x = vectors.iterator().next().getX();
double z = vectors.iterator().next().getY();
double y = -64;
Color line = new Color(0, 204, 0, 0.8F);
Color fill = new Color(0, 204, 0, 0.2F);
ExtrudeMarker marker = ExtrudeMarker.builder()
.label(file)
.position(x, y, z)
.shape(shape, -64, 320)
.lineColor(line)
.fillColor(fill)
.build();
markerSet.getMarkers()
.put(file, marker);
}
for (BlueMapMap map : bmWorld.getMaps()) {
map.getMarkerSets().put(world + "-" + markerSet.getLabel(), markerSet);
}
});
}
});
} catch (NoClassDefFoundError e) {
XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。");
XLogger.err(e.getMessage());
}
});
} }
} }

View File

@ -31,11 +31,14 @@ public class Cache {
/** /**
* 从数据库加载所有领地 * 从数据库加载所有领地
* 如果idToLoad为null则加载所有领地
*
* @param idToLoad 领地ID
*/ */
public void loadDominions() { public void loadDominions(Integer idToLoad) {
if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) { if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadDominionsExecution directly"); XLogger.debug("run loadDominionsExecution directly");
loadDominionsExecution(); loadDominionsExecution(idToLoad);
} else { } else {
if (_update_dominion_is_scheduled.get()) return; if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution"); XLogger.debug("schedule loadDominionsExecution");
@ -43,76 +46,113 @@ public class Cache {
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L; long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> { Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadDominionsExecution scheduled"); XLogger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution(); loadDominionsExecution(idToLoad);
_update_dominion_is_scheduled.set(false); _update_dominion_is_scheduled.set(false);
}, },
delay_tick); delay_tick);
} }
} }
private void loadDominionsExecution() { public void loadDominions() {
long start = System.currentTimeMillis(); loadDominions(null);
id_dominions = new ConcurrentHashMap<>(); }
world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>(); private void loadDominionsExecution(Integer idToLoad) {
List<DominionDTO> dominions = DominionDTO.selectAll(); Scheduler.runTaskAsync(() -> {
Map<String, List<DominionDTO>> world_dominions = new HashMap<>(); long start = System.currentTimeMillis();
for (DominionDTO d : dominions) { int count = 0;
if (!world_dominions.containsKey(d.getWorld())) { if (idToLoad == null) {
world_dominions.put(d.getWorld(), new ArrayList<>()); id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
count = dominions.size();
Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO d : dominions) {
if (!world_dominions.containsKey(d.getWorld())) {
world_dominions.put(d.getWorld(), new ArrayList<>());
}
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<String, List<DominionDTO>> entry : world_dominions.entrySet()) {
world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
} else {
DominionDTO dominion = DominionDTO.select(idToLoad);
if (dominion == null && id_dominions.containsKey(idToLoad)) {
id_dominions.remove(idToLoad);
} else if (dominion != null) {
id_dominions.put(idToLoad, dominion);
count = 1;
}
} }
world_dominions.get(d.getWorld()).add(d); BlueMapConnect.render();
id_dominions.put(d.getId(), d); recheckPlayerState = true;
if (!dominion_children.containsKey(d.getParentDomId())) { _last_update_dominion.set(System.currentTimeMillis());
dominion_children.put(d.getParentDomId(), new ArrayList<>()); XLogger.debug("loadDominionsExecution cost: %d ms for %d dominions"
} , System.currentTimeMillis() - start, count);
dominion_children.get(d.getParentDomId()).add(d.getId()); });
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions.entrySet()) {
world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
BlueMapConnect.render();
recheckPlayerState = true;
_last_update_dominion.set(System.currentTimeMillis());
XLogger.debug("loadDominionsExecution cost: %d ms", System.currentTimeMillis() - start);
} }
/** /**
* 从数据库加载所有玩家特权 * 从数据库加载所有玩家特权
* 如果player_uuid为null则加载所有玩家的特权
*
* @param player_uuid 玩家UUID
*/ */
public void loadPlayerPrivileges() { public void loadPlayerPrivileges(UUID player_uuid) {
if (_last_update_privilege.get() + UPDATE_INTERVAL < System.currentTimeMillis()) { if (_last_update_privilege.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
loadPlayerPrivilegesExecution(); XLogger.debug("run loadPlayerPrivilegesExecution directly");
loadPlayerPrivilegesExecution(player_uuid);
} else { } else {
if (_update_privilege_is_scheduled.get()) return; if (_update_privilege_is_scheduled.get()) return;
XLogger.debug("schedule loadPlayerPrivilegesExecution");
_update_privilege_is_scheduled.set(true); _update_privilege_is_scheduled.set(true);
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L; long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_privilege.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> { Scheduler.runTaskLaterAsync(() -> {
loadPlayerPrivilegesExecution(); XLogger.debug("run loadPlayerPrivilegesExecution scheduled");
loadPlayerPrivilegesExecution(player_uuid);
_update_privilege_is_scheduled.set(false); _update_privilege_is_scheduled.set(false);
}, },
delay_tick); delay_tick);
} }
} }
private void loadPlayerPrivilegesExecution() { public void loadPlayerPrivileges() {
long start = System.currentTimeMillis(); loadPlayerPrivileges(null);
List<PlayerPrivilegeDTO> all_privileges = PlayerPrivilegeDTO.selectAll(); }
if (all_privileges == null) {
XLogger.err("加载玩家特权失败"); private void loadPlayerPrivilegesExecution(UUID player_to_update) {
return; Scheduler.runTaskAsync(() -> {
} long start = System.currentTimeMillis();
player_uuid_to_privilege = new ConcurrentHashMap<>(); List<PlayerPrivilegeDTO> all_privileges;
for (PlayerPrivilegeDTO privilege : all_privileges) { if (player_to_update == null) {
UUID player_uuid = privilege.getPlayerUUID(); all_privileges = PlayerPrivilegeDTO.selectAll();
if (!player_uuid_to_privilege.containsKey(player_uuid)) { player_uuid_to_privilege = new ConcurrentHashMap<>();
player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>()); } else {
all_privileges = PlayerPrivilegeDTO.selectAll(player_to_update);
if (!player_uuid_to_privilege.containsKey(player_to_update)) {
player_uuid_to_privilege.put(player_to_update, new ConcurrentHashMap<>());
}
player_uuid_to_privilege.get(player_to_update).clear();
} }
player_uuid_to_privilege.get(player_uuid).put(privilege.getDomID(), privilege); for (PlayerPrivilegeDTO privilege : all_privileges) {
} UUID player_uuid = privilege.getPlayerUUID();
recheckPlayerState = true; if (!player_uuid_to_privilege.containsKey(player_uuid)) {
_last_update_privilege.set(System.currentTimeMillis()); player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>());
XLogger.debug("loadPlayerPrivilegesExecution cost: %d ms", System.currentTimeMillis() - start); }
player_uuid_to_privilege.get(player_uuid).put(privilege.getDomID(), privilege);
}
recheckPlayerState = true;
_last_update_privilege.set(System.currentTimeMillis());
XLogger.debug("loadPlayerPrivilegesExecution cost: %d ms for %d privileges"
, System.currentTimeMillis() - start, all_privileges.size());
});
} }
/** /**
@ -245,7 +285,7 @@ public class Cache {
if (player == null) return dominionTree; if (player == null) return dominionTree;
for (List<DominionNode> tree : world_dominion_tree.values()) { for (List<DominionNode> tree : world_dominion_tree.values()) {
for (DominionNode node : tree) { for (DominionNode node : tree) {
if (node.dominion.getOwner().equals(player.getUuid())) { if (node.getDominion().getOwner().equals(player.getUuid())) {
dominionTree.add(node); dominionTree.add(node);
} }
} }
@ -318,7 +358,7 @@ public class Cache {
private final AtomicBoolean _update_dominion_is_scheduled = new AtomicBoolean(false); private final AtomicBoolean _update_dominion_is_scheduled = new AtomicBoolean(false);
private final AtomicLong _last_update_privilege = new AtomicLong(0); private final AtomicLong _last_update_privilege = new AtomicLong(0);
private final AtomicBoolean _update_privilege_is_scheduled = new AtomicBoolean(false); private final AtomicBoolean _update_privilege_is_scheduled = new AtomicBoolean(false);
private static final long UPDATE_INTERVAL = 1000 * 5; private static final long UPDATE_INTERVAL = 1000 * 4;
private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态发光飞行 private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态发光飞行
public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>(); public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>();
} }

View File

@ -6,6 +6,8 @@ import cn.lunadeer.dominion.events.SelectPointEvents;
import cn.lunadeer.dominion.managers.ConfigManager; import cn.lunadeer.dominion.managers.ConfigManager;
import cn.lunadeer.dominion.managers.DatabaseTables; import cn.lunadeer.dominion.managers.DatabaseTables;
import cn.lunadeer.minecraftpluginutils.*; import cn.lunadeer.minecraftpluginutils.*;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseType;
import cn.lunadeer.minecraftpluginutils.scui.CuiManager; import cn.lunadeer.minecraftpluginutils.scui.CuiManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -26,8 +28,8 @@ public final class Dominion extends JavaPlugin {
new XLogger(this); new XLogger(this);
config = new ConfigManager(this); config = new ConfigManager(this);
XLogger.setDebug(config.isDebug()); XLogger.setDebug(config.isDebug());
database = new DatabaseManager(this, new DatabaseManager(this,
DatabaseManager.TYPE.valueOf(config.getDbType().toUpperCase()), DatabaseType.valueOf(config.getDbType().toUpperCase()),
config.getDbHost(), config.getDbHost(),
config.getDbPort(), config.getDbPort(),
config.getDbName(), config.getDbName(),
@ -74,12 +76,11 @@ public final class Dominion extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
// Plugin shutdown logic // Plugin shutdown logic
database.close(); DatabaseManager.instance.close();
} }
public static Dominion instance; public static Dominion instance;
public static ConfigManager config; public static ConfigManager config;
public static DatabaseManager database;
public static Map<UUID, Map<Integer, Location>> pointsSelect = new HashMap<>(); public static Map<UUID, Map<Integer, Location>> pointsSelect = new HashMap<>();
private GiteaReleaseCheck giteaReleaseCheck; private GiteaReleaseCheck giteaReleaseCheck;
} }

View File

@ -5,30 +5,52 @@ import org.bukkit.Location;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Objects;
public class DominionNode { public class DominionNode {
public DominionDTO dominion; private Integer dominion_id;
public List<DominionNode> children = new ArrayList<>(); private List<DominionNode> children = new ArrayList<>();
public DominionDTO getDominion() {
return Cache.instance.getDominion(dominion_id);
}
public List<DominionNode> getChildren() {
return children;
}
public static List<DominionNode> BuildNodeTree(Integer rootId, List<DominionDTO> dominions) { public static List<DominionNode> BuildNodeTree(Integer rootId, List<DominionDTO> dominions) {
List<DominionNode> dominionTree = new ArrayList<>(); // 映射父节点ID到其子节点列表
Map<Integer, List<DominionDTO>> parentToChildrenMap = new HashMap<>();
for (DominionDTO dominion : dominions) { for (DominionDTO dominion : dominions) {
if (Objects.equals(dominion.getParentDomId(), rootId)) { parentToChildrenMap
.computeIfAbsent(dominion.getParentDomId(), k -> new ArrayList<>())
.add(dominion);
}
// 递归构建节点树
return buildTree(rootId, parentToChildrenMap);
}
private static List<DominionNode> buildTree(Integer rootId, Map<Integer, List<DominionDTO>> parentToChildrenMap) {
List<DominionNode> dominionTree = new ArrayList<>();
List<DominionDTO> children = parentToChildrenMap.get(rootId);
if (children != null) {
for (DominionDTO dominion : children) {
DominionNode node = new DominionNode(); DominionNode node = new DominionNode();
node.dominion = dominion; node.dominion_id = dominion.getId();
node.children = BuildNodeTree(dominion.getId(), dominions); node.children = buildTree(dominion.getId(), parentToChildrenMap);
dominionTree.add(node); dominionTree.add(node);
} }
} }
return dominionTree; return dominionTree;
} }
public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) { public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) {
for (DominionNode node : nodes) { for (DominionNode node : nodes) {
if (isInDominion(node.dominion, loc)) { if (isInDominion(node.getDominion(), loc)) {
if (node.children.isEmpty()) { if (node.children.isEmpty()) {
return node; return node;
} else { } else {
@ -48,7 +70,7 @@ public class DominionNode {
if (nodes == null) return null; if (nodes == null) return null;
if (nodes.isEmpty()) return null; if (nodes.isEmpty()) return null;
DominionNode dominionNode = getLocInDominionNode(nodes, loc); DominionNode dominionNode = getLocInDominionNode(nodes, loc);
return dominionNode == null ? null : dominionNode.dominion; return dominionNode == null ? null : dominionNode.getDominion();
} }
public static boolean isInDominion(@Nullable DominionDTO dominion, Location location) { public static boolean isInDominion(@Nullable DominionDTO dominion, Location location) {

View File

@ -45,8 +45,8 @@ public class BukkitPlayerOperator implements AbstractOperator {
@Override @Override
public BlockFace getDirection() { public BlockFace getDirection() {
float yaw = player.getYaw(); float yaw = player.getLocation().getYaw();
float pitch = player.getPitch(); float pitch = player.getLocation().getPitch();
if (pitch > -45 && pitch < 45) { if (pitch > -45 && pitch < 45) {
if (yaw > -45 && yaw < 45) { if (yaw > -45 && yaw < 45) {
return BlockFace.SOUTH; return BlockFace.SOUTH;

View File

@ -103,13 +103,17 @@ public class PrivilegeController {
privilege = createPlayerPrivilege(operator, player.getUuid(), dominion); privilege = createPlayerPrivilege(operator, player.getUuid(), dominion);
if (privilege == null) return; if (privilege == null) return;
} }
if (flag.equals("admin") || privilege.getAdmin()) { if ((flag.equals("admin") || privilege.getAdmin()) && notOwner(operator, dominion)) {
if (notOwner(operator, dominion)) { operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他玩家管理员的权限", dominionName));
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他管理员的权限", dominionName)); return;
return; }
} if (flag.equals("admin")) {
privilege.setAdmin(value); privilege.setAdmin(value);
} else { } else {
if (privilege.getAdmin()) {
operator.setResponse(FAIL.addMessage("管理员拥有所有权限,无需单独设置权限"));
return;
}
Flag f = Flag.getFlag(flag); Flag f = Flag.getFlag(flag);
if (f == null) { if (f == null) {
operator.setResponse(FAIL.addMessage("未知的领地权限 %s", flag)); operator.setResponse(FAIL.addMessage("未知的领地权限 %s", flag));

View File

@ -3,54 +3,59 @@ package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.XLogger; import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.FieldType;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import java.awt.*;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.List;
public class DominionDTO { public class DominionDTO {
private static List<DominionDTO> query(String sql, Object... args) { private static List<DominionDTO> query(String sql, Object... args) {
List<DominionDTO> dominions = new ArrayList<>(); List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, args)) { try (ResultSet rs = DatabaseManager.instance.query(sql, args)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) { return getDTOFromRS(rs);
// 如果是更新操作重新加载缓存
Cache.instance.loadDominions();
}
if (rs == null) return dominions;
while (rs.next()) {
Integer id = rs.getInt("id");
UUID owner = UUID.fromString(rs.getString("owner"));
String name = rs.getString("name");
String world = rs.getString("world");
Integer x1 = rs.getInt("x1");
Integer y1 = rs.getInt("y1");
Integer z1 = rs.getInt("z1");
Integer x2 = rs.getInt("x2");
Integer y2 = rs.getInt("y2");
Integer z2 = rs.getInt("z2");
Integer parentDomId = rs.getInt("parent_dom_id");
String tp_location = rs.getString("tp_location");
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getDominionFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
String color = rs.getString("color");
DominionDTO dominion = new DominionDTO(id, owner, name, world, x1, y1, z1, x2, y2, z2, parentDomId,
rs.getString("join_message"),
rs.getString("leave_message"),
flags,
tp_location,
color
);
dominions.add(dominion);
}
} catch (SQLException e) { } catch (SQLException e) {
Dominion.database.handleDatabaseError("数据库操作失败: ", e, sql); DatabaseManager.handleDatabaseError("数据库操作失败: ", e, sql);
}
return dominions;
}
private static List<DominionDTO> getDTOFromRS(ResultSet rs) throws SQLException {
List<DominionDTO> dominions = new ArrayList<>();
if (rs == null) return dominions;
while (rs.next()) {
Integer id = rs.getInt("id");
UUID owner = UUID.fromString(rs.getString("owner"));
String name = rs.getString("name");
String world = rs.getString("world");
Integer x1 = rs.getInt("x1");
Integer y1 = rs.getInt("y1");
Integer z1 = rs.getInt("z1");
Integer x2 = rs.getInt("x2");
Integer y2 = rs.getInt("y2");
Integer z2 = rs.getInt("z2");
Integer parentDomId = rs.getInt("parent_dom_id");
String tp_location = rs.getString("tp_location");
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getDominionFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
String color = rs.getString("color");
DominionDTO dominion = new DominionDTO(id, owner, name, world, x1, y1, z1, x2, y2, z2, parentDomId,
rs.getString("join_message"),
rs.getString("leave_message"),
flags,
tp_location,
color
);
dominions.add(dominion);
} }
return dominions; return dominions;
} }
@ -110,76 +115,33 @@ public class DominionDTO {
} }
public static DominionDTO insert(DominionDTO dominion) { public static DominionDTO insert(DominionDTO dominion) {
StringBuilder sql = new StringBuilder("INSERT INTO dominion (" + InsertRow insert = new InsertRow().returningAll().table("dominion").onConflictDoNothing(new Field("id", null));
"owner, name, world, x1, y1, z1, x2, y2, z2, "); insert.field(dominion.owner)
for (Flag f : Flag.getAllDominionFlags()) { .field(dominion.name)
sql.append(f.getFlagName()).append(", "); .field(dominion.world)
.field(dominion.x1).field(dominion.y1).field(dominion.z1)
.field(dominion.x2).field(dominion.y2).field(dominion.z2)
.field(dominion.parentDomId)
.field(dominion.joinMessage).field(dominion.leaveMessage)
.field(dominion.tp_location);
for (Flag f : Flag.getDominionFlagsEnabled()) {
insert.field(new Field(f.getFlagName(), f.getDefaultValue()));
} }
sql.append("tp_location, join_message, leave_message"); try (ResultSet rs = insert.execute()) {
sql.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, "); Cache.instance.loadDominions();
for (Flag f : Flag.getAllDominionFlags()) { List<DominionDTO> dominions = getDTOFromRS(rs);
sql.append(f.getDefaultValue()).append(", "); if (dominions.size() == 0) return null;
return dominions.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("数据库操作失败: ", e, insert.toString());
return null;
} }
sql.append("'default', ?, ?");
sql.append(") RETURNING *;");
List<DominionDTO> dominions = query(sql.toString(),
dominion.getOwner(),
dominion.getName(),
dominion.getWorld(),
dominion.getX1(),
dominion.getY1(),
dominion.getZ1(),
dominion.getX2(),
dominion.getY2(),
dominion.getZ2(),
"欢迎来到 ${DOM_NAME}",
"你正在离开 ${DOM_NAME},欢迎下次光临~"
);
if (dominions.size() == 0) return null;
return dominions.get(0);
} }
public static void delete(DominionDTO dominion) { public static void delete(DominionDTO dominion) {
String sql = "DELETE FROM dominion WHERE id = ?;"; String sql = "DELETE FROM dominion WHERE id = ?;";
query(sql, dominion.getId()); query(sql, dominion.getId());
} Cache.instance.loadDominions();
private static DominionDTO update(DominionDTO dominion) {
String tp_location;
if (dominion.getTpLocation() == null) {
tp_location = "default";
} else {
Location loc = dominion.getTpLocation();
tp_location = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
}
StringBuilder sql = new StringBuilder("UPDATE dominion SET " +
"owner = ?," +
"name = ?," +
"world = ?," +
"x1 = " + dominion.getX1() + ", " +
"y1 = " + dominion.getY1() + ", " +
"z1 = " + dominion.getZ1() + ", " +
"x2 = " + dominion.getX2() + ", " +
"y2 = " + dominion.getY2() + ", " +
"z2 = " + dominion.getZ2() + ", " +
"parent_dom_id = " + dominion.getParentDomId() + ", " +
"join_message = ?," +
"leave_message = ?," +
"color = ?,");
for (Flag f : Flag.getDominionFlagsEnabled()) {
sql.append(f.getFlagName()).append(" = ").append(dominion.getFlagValue(f)).append(",");
}
sql.append("tp_location = ?" + " WHERE id = ").append(dominion.getId()).append(" RETURNING *;");
List<DominionDTO> dominions = query(sql.toString(),
dominion.getOwner().toString(),
dominion.getName(),
dominion.getWorld(),
dominion.getJoinMessage(),
dominion.getLeaveMessage(),
dominion.getColor(),
tp_location);
if (dominions.size() == 0) return null;
return dominions.get(0);
} }
private DominionDTO(Integer id, UUID owner, String name, String world, private DominionDTO(Integer id, UUID owner, String name, String world,
@ -189,39 +151,39 @@ public class DominionDTO {
Map<Flag, Boolean> flags, Map<Flag, Boolean> flags,
String tp_location, String tp_location,
String color) { String color) {
this.id = id; this.id.value = id;
this.owner = owner; this.owner.value = owner.toString();
this.name = name; this.name.value = name;
this.world = world; this.world.value = world;
this.x1 = x1; this.x1.value = x1;
this.y1 = y1; this.y1.value = y1;
this.z1 = z1; this.z1.value = z1;
this.x2 = x2; this.x2.value = x2;
this.y2 = y2; this.y2.value = y2;
this.z2 = z2; this.z2.value = z2;
this.parentDomId = parentDomId; this.parentDomId.value = parentDomId;
this.joinMessage = joinMessage; this.joinMessage.value = joinMessage;
this.leaveMessage = leaveMessage; this.leaveMessage.value = leaveMessage;
this.flags.putAll(flags); this.flags.putAll(flags);
this.tp_location = tp_location; this.tp_location.value = tp_location;
this.color = color; this.color.value = color;
} }
private DominionDTO(Integer id, UUID owner, String name, String world, private DominionDTO(Integer id, UUID owner, String name, String world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId) { Integer parentDomId) {
this.id = id; this.id.value = id;
this.owner = owner; this.owner.value = owner.toString();
this.name = name; this.name.value = name;
this.world = world; this.world.value = world;
this.x1 = x1; this.x1.value = x1;
this.y1 = y1; this.y1.value = y1;
this.z1 = z1; this.z1.value = z1;
this.x2 = x2; this.x2.value = x2;
this.y2 = y2; this.y2.value = y2;
this.z2 = z2; this.z2.value = z2;
this.parentDomId = parentDomId; this.parentDomId.value = parentDomId;
} }
public DominionDTO(UUID owner, String name, String world, public DominionDTO(UUID owner, String name, String world,
@ -229,154 +191,165 @@ public class DominionDTO {
this(null, owner, name, world, x1, y1, z1, x2, y2, z2, -1); this(null, owner, name, world, x1, y1, z1, x2, y2, z2, -1);
} }
private Integer id; private final Field id = new Field("id", FieldType.INT);
private UUID owner; private final Field owner = new Field("owner", FieldType.STRING);
private String name; private final Field name = new Field("name", FieldType.STRING);
private final String world; private final Field world = new Field("world", FieldType.STRING);
private Integer x1; private final Field x1 = new Field("x1", FieldType.INT);
private Integer y1; private final Field y1 = new Field("y1", FieldType.INT);
private Integer z1; private final Field z1 = new Field("z1", FieldType.INT);
private Integer x2; private final Field x2 = new Field("x2", FieldType.INT);
private Integer y2; private final Field y2 = new Field("y2", FieldType.INT);
private Integer z2; private final Field z2 = new Field("z2", FieldType.INT);
private Integer parentDomId = -1; private final Field parentDomId = new Field("parent_dom_id", -1);
private String joinMessage = "欢迎"; private final Field joinMessage = new Field("join_message", "欢迎来到 ${DOM_NAME}");
private String leaveMessage = "再见"; private final Field leaveMessage = new Field("leave_message", "你正在离开 ${DOM_NAME},欢迎下次光临~");
private final Map<Flag, Boolean> flags = new HashMap<>(); private final Map<Flag, Boolean> flags = new HashMap<>();
private String tp_location; private final Field tp_location = new Field("tp_location", "default");
private String color; private final Field color = new Field("color", "#00BFFF");
// getters and setters // getters and setters
public Integer getId() { public Integer getId() {
return id; return (Integer) id.value;
}
public DominionDTO setId(Integer id) {
this.id = id;
return update(this);
} }
public UUID getOwner() { public UUID getOwner() {
return owner; return UUID.fromString((String) owner.value);
}
private DominionDTO doUpdate(UpdateRow updateRow) {
updateRow.returningAll(id)
.table("dominion")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<DominionDTO> dominions = getDTOFromRS(rs);
if (dominions.size() == 0) return null;
Cache.instance.loadDominions((Integer) id.value);
return dominions.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("更新领地信息失败: ", e, updateRow.toString());
return null;
}
} }
public DominionDTO setOwner(UUID owner) { public DominionDTO setOwner(UUID owner) {
this.owner = owner; this.owner.value = owner.toString();
return update(this); return doUpdate(new UpdateRow().field(this.owner));
} }
public String getName() { public String getName() {
return name; return (String) name.value;
} }
public DominionDTO setName(String name) { public DominionDTO setName(String name) {
this.name = name; this.name.value = name;
return update(this); return doUpdate(new UpdateRow().field(this.name));
} }
public String getWorld() { public String getWorld() {
return world; return (String) world.value;
} }
public Integer getX1() { public Integer getX1() {
return x1; return (Integer) x1.value;
} }
public DominionDTO setX1(Integer x1) { public DominionDTO setX1(Integer x1) {
this.x1 = x1; this.x1.value = x1;
return update(this); return doUpdate(new UpdateRow().field(this.x1));
} }
public Integer getY1() { public Integer getY1() {
return y1; return (Integer) y1.value;
} }
public DominionDTO setY1(Integer y1) { public DominionDTO setY1(Integer y1) {
this.y1 = y1; this.y1.value = y1;
return update(this); return doUpdate(new UpdateRow().field(this.y1));
} }
public Integer getZ1() { public Integer getZ1() {
return z1; return (Integer) z1.value;
} }
public DominionDTO setZ1(Integer z1) { public DominionDTO setZ1(Integer z1) {
this.z1 = z1; this.z1.value = z1;
return update(this); return doUpdate(new UpdateRow().field(this.z1));
} }
public Integer getX2() { public Integer getX2() {
return x2; return (Integer) x2.value;
} }
public DominionDTO setX2(Integer x2) { public DominionDTO setX2(Integer x2) {
this.x2 = x2; this.x2.value = x2;
return update(this); return doUpdate(new UpdateRow().field(this.x2));
} }
public Integer getY2() { public Integer getY2() {
return y2; return (Integer) y2.value;
} }
public DominionDTO setY2(Integer y2) { public DominionDTO setY2(Integer y2) {
this.y2 = y2; this.y2.value = y2;
return update(this); return doUpdate(new UpdateRow().field(this.y2));
} }
public Integer getZ2() { public Integer getZ2() {
return z2; return (Integer) z2.value;
} }
public DominionDTO setZ2(Integer z2) { public DominionDTO setZ2(Integer z2) {
this.z2 = z2; this.z2.value = z2;
return update(this); return doUpdate(new UpdateRow().field(this.z2));
} }
public Integer getSquare() { public Integer getSquare() {
return (x2 - x1 + 1) * (z2 - z1 + 1); return (getX2() - getX1() + 1) * (getZ2() - getZ1() + 1);
} }
public Integer getVolume() { public Integer getVolume() {
return getSquare() * (y2 - y1 + 1); return getSquare() * (getY2() - getY1() + 1);
} }
public Integer getWidthX() { public Integer getWidthX() {
return x2 - x1 + 1; return getX2() - getX1() + 1;
} }
public Integer getHeight() { public Integer getHeight() {
return y2 - y1 + 1; return getY2() - getY1() + 1;
} }
public Integer getWidthZ() { public Integer getWidthZ() {
return z2 - z1 + 1; return getZ2() - getZ1() + 1;
} }
public Integer getParentDomId() { public Integer getParentDomId() {
return parentDomId; return (Integer) parentDomId.value;
} }
public DominionDTO setParentDomId(Integer parentDomId) { public DominionDTO setParentDomId(Integer parentDomId) {
this.parentDomId = parentDomId; this.parentDomId.value = parentDomId;
return update(this); return doUpdate(new UpdateRow().field(this.parentDomId));
} }
public String getJoinMessage() { public String getJoinMessage() {
return joinMessage; return (String) joinMessage.value;
} }
public DominionDTO setJoinMessage(String joinMessage) { public DominionDTO setJoinMessage(String joinMessage) {
this.joinMessage = joinMessage; this.joinMessage.value = joinMessage;
return update(this); return doUpdate(new UpdateRow().field(this.joinMessage));
} }
public String getLeaveMessage() { public String getLeaveMessage() {
return leaveMessage; return (String) leaveMessage.value;
} }
public DominionDTO setLeaveMessage(String leaveMessage) { public DominionDTO setLeaveMessage(String leaveMessage) {
this.leaveMessage = leaveMessage; this.leaveMessage.value = leaveMessage;
return update(this); return doUpdate(new UpdateRow().field(this.leaveMessage));
} }
public Boolean getFlagValue(Flag flag) { public Boolean getFlagValue(Flag flag) {
@ -386,17 +359,18 @@ public class DominionDTO {
public DominionDTO setFlagValue(Flag flag, Boolean value) { public DominionDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value); flags.put(flag, value);
return update(this); Field flagField = new Field(flag.getFlagName(), value);
return doUpdate(new UpdateRow().field(flagField));
} }
public DominionDTO setXYZ(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { public DominionDTO setXYZ(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this.x1 = x1; this.x1.value = x1;
this.y1 = y1; this.y1.value = y1;
this.z1 = z1; this.z1.value = z1;
this.x2 = x2; this.x2.value = x2;
this.y2 = y2; this.y2.value = y2;
this.z2 = z2; this.z2.value = z2;
return update(this); return doUpdate(new UpdateRow().field(this.x1).field(this.y1).field(this.z1).field(this.x2).field(this.y2).field(this.z2));
} }
public Location getTpLocation() { public Location getTpLocation() {
@ -404,8 +378,8 @@ public class DominionDTO {
return null; return null;
} else { } else {
// 0:0:0 // 0:0:0
String[] loc = tp_location.split(":"); String[] loc = ((String) tp_location.value).split(":");
World w = Dominion.instance.getServer().getWorld(world); World w = Dominion.instance.getServer().getWorld(getWorld());
if (loc.length == 3 && w != null) { if (loc.length == 3 && w != null) {
return new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])); return new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
} else { } else {
@ -417,36 +391,36 @@ public class DominionDTO {
} }
public DominionDTO setTpLocation(Location loc) { public DominionDTO setTpLocation(Location loc) {
this.tp_location = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ(); this.tp_location.value = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
return update(this); return doUpdate(new UpdateRow().field(tp_location));
} }
public Location getLocation1() { public Location getLocation1() {
return new Location(Dominion.instance.getServer().getWorld(world), x1, y1, z1); return new Location(Dominion.instance.getServer().getWorld(getWorld()), getX1(), getY1(), getZ1());
} }
public Location getLocation2() { public Location getLocation2() {
return new Location(Dominion.instance.getServer().getWorld(world), x2, y2, z2); return new Location(Dominion.instance.getServer().getWorld(getWorld()), getX2(), getY2(), getZ2());
} }
public DominionDTO setColor(String color) { public DominionDTO setColor(String color) {
this.color = color; this.color.value = color;
return update(this); return doUpdate(new UpdateRow().field(this.color));
} }
public int getColorR() { public int getColorR() {
return Integer.valueOf(color.substring(1, 3), 16); return Integer.valueOf(getColor().substring(1, 3), 16);
} }
public int getColorG() { public int getColorG() {
return Integer.valueOf(color.substring(3, 5), 16); return Integer.valueOf(getColor().substring(3, 5), 16);
} }
public int getColorB() { public int getColorB() {
return Integer.valueOf(color.substring(5, 7), 16); return Integer.valueOf(getColor().substring(5, 7), 16);
} }
public String getColor() { public String getColor() {
return color; return (String) color.value;
} }
} }

View File

@ -1,10 +1,15 @@
package cn.lunadeer.dominion.dtos; package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -31,18 +36,24 @@ public class PlayerDTO {
private static List<PlayerDTO> query(String sql, Object... params) { private static List<PlayerDTO> query(String sql, Object... params) {
List<PlayerDTO> players = new ArrayList<>(); List<PlayerDTO> players = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, params)) { try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
if (rs == null) return players; return getDTOFromRS(rs);
while (rs.next()) {
Integer id = rs.getInt("id");
UUID uuid = UUID.fromString(rs.getString("uuid"));
String lastKnownName = rs.getString("last_known_name");
Long lastJoinAt = rs.getTimestamp("last_join_at").getTime();
PlayerDTO player = new PlayerDTO(id, uuid, lastKnownName, lastJoinAt);
players.add(player);
}
} catch (SQLException e) { } catch (SQLException e) {
Dominion.database.handleDatabaseError("查询玩家信息失败: ", e, sql); DatabaseManager.handleDatabaseError("查询玩家信息失败: ", e, sql);
}
return players;
}
private static List<PlayerDTO> getDTOFromRS(ResultSet rs) throws SQLException {
List<PlayerDTO> players = new ArrayList<>();
if (rs == null) return players;
while (rs.next()) {
Integer id = rs.getInt("id");
UUID uuid = UUID.fromString(rs.getString("uuid"));
String lastKnownName = rs.getString("last_known_name");
Long lastJoinAt = rs.getTimestamp("last_join_at").getTime();
PlayerDTO player = new PlayerDTO(id, uuid, lastKnownName, lastJoinAt);
players.add(player);
} }
return players; return players;
} }
@ -73,24 +84,44 @@ public class PlayerDTO {
} }
private static PlayerDTO insert(PlayerDTO player) { private static PlayerDTO insert(PlayerDTO player) {
String sql = "INSERT INTO player_name (uuid, last_known_name, last_join_at) " + Field uuid = new Field("uuid", player.getUuid().toString());
"VALUES" + Field lastKnownName = new Field("last_known_name", player.getLastKnownName());
" (?, ?, CURRENT_TIMESTAMP) " + Field lastJoinAt = new Field("last_join_at", Timestamp.valueOf(LocalDateTime.now()));
"RETURNING *;"; InsertRow insertRow = new InsertRow()
List<PlayerDTO> players = query(sql, player.getUuid().toString(), player.getLastKnownName()); .table("player_name")
if (players.size() == 0) return null; .field(uuid)
return players.get(0); .field(lastKnownName)
.field(lastJoinAt)
.returningAll()
.onConflictOverwrite(new Field("id", null));
try (ResultSet rs = insertRow.execute()) {
List<PlayerDTO> players = getDTOFromRS(rs);
if (players.size() == 0) return null;
return players.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("插入玩家信息失败: ", e, insertRow.toString());
return null;
}
} }
private static PlayerDTO update(PlayerDTO player) { private static PlayerDTO update(PlayerDTO player) {
String sql = "UPDATE player_name SET " + Field lastKnownName = new Field("last_known_name", player.getLastKnownName());
"last_known_name = ?, " + Field uuid = new Field("uuid", player.getUuid().toString());
"last_join_at = CURRENT_TIMESTAMP " + Field lastJoinAt = new Field("last_join_at", Timestamp.valueOf(LocalDateTime.now()));
"WHERE uuid = ? " + UpdateRow updateRow = new UpdateRow()
"RETURNING *;"; .table("player_name")
List<PlayerDTO> players = query(sql, player.getLastKnownName(), player.getUuid().toString()); .field(lastKnownName)
if (players.size() == 0) return null; .field(lastJoinAt)
return players.get(0); .where("uuid = ?", uuid.value)
.returningAll(uuid);
try (ResultSet rs = updateRow.execute()) {
List<PlayerDTO> players = getDTOFromRS(rs);
if (players.size() == 0) return null;
return players.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("更新玩家信息失败: ", e, updateRow.toString());
return null;
}
} }
private PlayerDTO(Integer id, UUID uuid, String lastKnownName, Long lastJoinAt) { private PlayerDTO(Integer id, UUID uuid, String lastKnownName, Long lastJoinAt) {

View File

@ -1,35 +1,88 @@
package cn.lunadeer.dominion.dtos; package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.*; import java.util.*;
public class PlayerPrivilegeDTO { public class PlayerPrivilegeDTO {
private static List<PlayerPrivilegeDTO> query(String sql, Object... params) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
return getDTOFromRS(rs);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询玩家权限失败: ", e, sql);
}
return players;
}
private static List<PlayerPrivilegeDTO> getDTOFromRS(ResultSet rs) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
if (rs == null) return players;
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
PlayerPrivilegeDTO player = new PlayerPrivilegeDTO(
rs.getInt("id"),
UUID.fromString(rs.getString("player_uuid")),
rs.getBoolean("admin"),
rs.getInt("dom_id"),
flags
);
players.add(player);
}
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询玩家权限失败: ", e, "");
}
return players;
}
private PlayerPrivilegeDTO doUpdate(UpdateRow updateRow) {
Field id = new Field("id", this.id);
updateRow.returningAll(id)
.table("player_privilege")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<PlayerPrivilegeDTO> players = getDTOFromRS(rs);
if (players.size() == 0) return null;
Cache.instance.loadPlayerPrivileges(playerUUID);
return players.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("更新玩家权限失败: ", e, "");
return null;
}
}
public static PlayerPrivilegeDTO insert(PlayerPrivilegeDTO player) { public static PlayerPrivilegeDTO insert(PlayerPrivilegeDTO player) {
StringBuilder sql = new StringBuilder("INSERT INTO player_privilege (player_uuid, admin, dom_id, "); Field playerUUID = new Field("player_uuid", player.getPlayerUUID().toString());
Field admin = new Field("admin", player.getAdmin());
for (Flag f : Flag.getAllPrivilegeFlags()) { Field domID = new Field("dom_id", player.getDomID());
sql.append(f.getFlagName()).append(", "); InsertRow insertRow = new InsertRow().returningAll().onConflictDoNothing(new Field("id", null))
.table("player_privilege")
.field(playerUUID)
.field(admin)
.field(domID);
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
insertRow.field(new Field(f.getFlagName(), player.getFlagValue(f)));
} }
sql = new StringBuilder(sql.substring(0, sql.length() - 2)); try (ResultSet rs = insertRow.execute()) {
Cache.instance.loadPlayerPrivileges(player.getPlayerUUID());
sql.append(") VALUES ('") List<PlayerPrivilegeDTO> players = getDTOFromRS(rs);
.append(player.getPlayerUUID()).append("', ") if (players.size() == 0) return null;
.append(player.getAdmin()).append(", ") return players.get(0);
.append(player.getDomID()).append(", "); } catch (Exception e) {
DatabaseManager.handleDatabaseError("插入玩家权限失败: ", e, "");
for (Flag f : Flag.getAllPrivilegeFlags()) { return null;
sql.append(player.getFlagValue(f)).append(", ");
} }
sql = new StringBuilder(sql.substring(0, sql.length() - 2));
sql.append(") RETURNING *;");
List<PlayerPrivilegeDTO> players = query(sql.toString());
if (players.size() == 0) return null;
return players.get(0);
} }
public static PlayerPrivilegeDTO select(UUID playerUUID, Integer dom_id) { public static PlayerPrivilegeDTO select(UUID playerUUID, Integer dom_id) {
@ -47,6 +100,7 @@ public class PlayerPrivilegeDTO {
public static void delete(UUID player, Integer domID) { public static void delete(UUID player, Integer domID) {
String sql = "DELETE FROM player_privilege WHERE player_uuid = ? AND dom_id = ?;"; String sql = "DELETE FROM player_privilege WHERE player_uuid = ? AND dom_id = ?;";
query(sql, player.toString(), domID); query(sql, player.toString(), domID);
Cache.instance.loadPlayerPrivileges(player);
} }
public static List<PlayerPrivilegeDTO> selectAll() { public static List<PlayerPrivilegeDTO> selectAll() {
@ -89,20 +143,26 @@ public class PlayerPrivilegeDTO {
public PlayerPrivilegeDTO setFlagValue(Flag flag, Boolean value) { public PlayerPrivilegeDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value); flags.put(flag, value);
return update(this); Field f = new Field(flag.getFlagName(), value);
UpdateRow updateRow = new UpdateRow().field(f);
return doUpdate(updateRow);
} }
public PlayerPrivilegeDTO setAdmin(Boolean admin) { public PlayerPrivilegeDTO setAdmin(Boolean admin) {
this.admin = admin; this.admin = admin;
return update(this); Field f = new Field("admin", admin);
UpdateRow updateRow = new UpdateRow().field(f);
return doUpdate(updateRow);
} }
public PlayerPrivilegeDTO applyTemplate(PrivilegeTemplateDTO template) { public PlayerPrivilegeDTO applyTemplate(PrivilegeTemplateDTO template) {
this.admin = template.getAdmin(); this.admin = template.getAdmin();
UpdateRow updateRow = new UpdateRow().field(new Field("admin", admin));
for (Flag f : Flag.getPrivilegeFlagsEnabled()) { for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
this.flags.put(f, template.getFlagValue(f)); this.flags.put(f, template.getFlagValue(f));
updateRow.field(new Field(f.getFlagName(), template.getFlagValue(f)));
} }
return update(this); return doUpdate(updateRow);
} }
private PlayerPrivilegeDTO(Integer id, UUID playerUUID, Boolean admin, Integer domID, Map<Flag, Boolean> flags) { private PlayerPrivilegeDTO(Integer id, UUID playerUUID, Boolean admin, Integer domID, Map<Flag, Boolean> flags) {
@ -123,46 +183,4 @@ public class PlayerPrivilegeDTO {
} }
} }
private static List<PlayerPrivilegeDTO> query(String sql, Object... params) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, params)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadPlayerPrivileges();
}
if (rs == null) return players;
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
PlayerPrivilegeDTO player = new PlayerPrivilegeDTO(
rs.getInt("id"),
UUID.fromString(rs.getString("player_uuid")),
rs.getBoolean("admin"),
rs.getInt("dom_id"),
flags
);
players.add(player);
}
} catch (Exception e) {
Dominion.database.handleDatabaseError("查询玩家权限失败: ", e, sql);
}
return players;
}
private static PlayerPrivilegeDTO update(PlayerPrivilegeDTO player) {
String sql = "UPDATE player_privilege SET " +
"admin = " + player.getAdmin() + ", " +
"dom_id = " + player.getDomID() + ", ";
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
sql += f.getFlagName() + " = " + player.getFlagValue(f) + ", ";
}
sql = sql.substring(0, sql.length() - 2);
sql += " WHERE id = " + player.getId() + " " +
"RETURNING *;";
List<PlayerPrivilegeDTO> players = query(sql);
if (players.size() == 0) return null;
return players.get(0);
}
} }

View File

@ -1,6 +1,9 @@
package cn.lunadeer.dominion.dtos; package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.*; import java.util.*;
@ -9,8 +12,18 @@ public class PrivilegeTemplateDTO {
private static List<PrivilegeTemplateDTO> query(String sql, Object... params) { private static List<PrivilegeTemplateDTO> query(String sql, Object... params) {
List<PrivilegeTemplateDTO> templates = new ArrayList<>(); List<PrivilegeTemplateDTO> templates = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, params)) { try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
if (rs == null) return templates; return getDTOFromRS(rs);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询权限模版失败: ", e, sql);
}
return templates;
}
private static List<PrivilegeTemplateDTO> getDTOFromRS(ResultSet rs) {
List<PrivilegeTemplateDTO> templates = new ArrayList<>();
if (rs == null) return templates;
try {
while (rs.next()) { while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>(); Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) { for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
@ -26,16 +39,41 @@ public class PrivilegeTemplateDTO {
templates.add(template); templates.add(template);
} }
} catch (Exception e) { } catch (Exception e) {
Dominion.database.handleDatabaseError("查询权限模版失败: ", e, sql); DatabaseManager.handleDatabaseError("查询权限模版失败: ", e, null);
} }
return templates; return templates;
} }
public static PrivilegeTemplateDTO create(UUID creator, String name) { public static PrivilegeTemplateDTO create(UUID creator, String name) {
String sql = "INSERT INTO privilege_template (creator, name) VALUES (?, ?) RETURNING *;"; Field creatorField = new Field("creator", creator.toString());
List<PrivilegeTemplateDTO> templates = query(sql, creator.toString(), name); Field nameField = new Field("name", name);
if (templates.size() == 0) return null; InsertRow insertRow = new InsertRow().table("privilege_template").onConflictDoNothing(new Field("id", null))
return templates.get(0); .field(creatorField)
.field(nameField)
.returningAll();
try (ResultSet rs = insertRow.execute()) {
List<PrivilegeTemplateDTO> templates = getDTOFromRS(rs);
if (templates.size() == 0) return null;
return templates.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("创建权限模版失败: ", e, null);
return null;
}
}
private PrivilegeTemplateDTO doUpdate(UpdateRow updateRow) {
Field id = new Field("id", this.id);
updateRow.returningAll(id)
.table("privilege_template")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<PrivilegeTemplateDTO> templates = getDTOFromRS(rs);
if (templates.size() == 0) return null;
return templates.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("更新权限模版失败: ", e, null);
return null;
}
} }
public static PrivilegeTemplateDTO select(UUID creator, String name) { public static PrivilegeTemplateDTO select(UUID creator, String name) {
@ -93,25 +131,12 @@ public class PrivilegeTemplateDTO {
public PrivilegeTemplateDTO setFlagValue(Flag flag, Boolean value) { public PrivilegeTemplateDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value); flags.put(flag, value);
return update(this); return doUpdate(new UpdateRow().field(new Field(flag.getFlagName(), value)));
} }
public PrivilegeTemplateDTO setAdmin(Boolean admin) { public PrivilegeTemplateDTO setAdmin(Boolean admin) {
this.admin = admin; this.admin = admin;
return update(this); return doUpdate(new UpdateRow().field(new Field("admin", admin)));
}
private static PrivilegeTemplateDTO update(PrivilegeTemplateDTO template) {
StringBuilder sql = new StringBuilder("UPDATE privilege_template SET " +
"name = ?, " +
"admin = ?, ");
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
sql.append(f.getFlagName()).append(" = ").append(template.getFlagValue(f)).append(", ");
}
sql = new StringBuilder(sql.substring(0, sql.length() - 2) + " WHERE id = ? RETURNING *;");
List<PrivilegeTemplateDTO> templates = query(sql.toString(), template.getName(), template.getAdmin(), template.getId());
if (templates.size() == 0) return null;
return templates.get(0);
} }
} }

View File

@ -1,107 +1,159 @@
package cn.lunadeer.dominion.managers; package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.FieldType;
import cn.lunadeer.minecraftpluginutils.databse.TableColumn;
import cn.lunadeer.minecraftpluginutils.databse.syntax.AddColumn;
import cn.lunadeer.minecraftpluginutils.databse.syntax.CreateTable;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
public class DatabaseTables { public class DatabaseTables {
public static void migrate() { public static void migrate() {
String sql = "";
// player name // player name
sql = "CREATE TABLE IF NOT EXISTS player_name (" + TableColumn player_name_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
" id SERIAL PRIMARY KEY," + TableColumn player_name_uuid = new TableColumn("uuid", FieldType.STRING, false, false, true, true, "''");
" uuid VARCHAR(36) NOT NULL UNIQUE," + TableColumn player_name_last_known_name = new TableColumn("last_known_name", FieldType.STRING, false, false, true, false, "'unknown'");
" last_known_name TEXT NOT NULL," + TableColumn player_name_last_join_at = new TableColumn("last_join_at", FieldType.DATETIME, false, false, true, false, "CURRENT_TIMESTAMP");
" last_join_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" + CreateTable player_name = new CreateTable().ifNotExists();
");"; player_name.table("player_name")
Dominion.database.query(sql); .field(player_name_id)
.field(player_name_uuid)
.field(player_name_last_known_name)
.field(player_name_last_join_at);
player_name.execute();
// dominion table // dominion table
sql = "CREATE TABLE IF NOT EXISTS dominion (" + TableColumn dominion_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
" id SERIAL PRIMARY KEY," + TableColumn dominion_owner = new TableColumn("owner", FieldType.STRING, false, false, true, false, "''");
" owner VARCHAR(36) NOT NULL," + TableColumn dominion_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
" name TEXT NOT NULL UNIQUE," + TableColumn dominion_world = new TableColumn("world", FieldType.STRING, false, false, true, false, "'world'");
" world TEXT NOT NULL," + TableColumn dominion_x1 = new TableColumn("x1", FieldType.INT, false, false, true, false, 0);
" x1 INT NOT NULL," + TableColumn dominion_y1 = new TableColumn("y1", FieldType.INT, false, false, true, false, 0);
" y1 INT NOT NULL," + TableColumn dominion_z1 = new TableColumn("z1", FieldType.INT, false, false, true, false, 0);
" z1 INT NOT NULL," + TableColumn dominion_x2 = new TableColumn("x2", FieldType.INT, false, false, true, false, 0);
" x2 INT NOT NULL," + TableColumn dominion_y2 = new TableColumn("y2", FieldType.INT, false, false, true, false, 0);
" y2 INT NOT NULL," + TableColumn dominion_z2 = new TableColumn("z2", FieldType.INT, false, false, true, false, 0);
" z2 INT NOT NULL," + TableColumn dominion_parent_dom_id = new TableColumn("parent_dom_id", FieldType.INT, false, false, true, false, -1);
" parent_dom_id INT NOT NULL DEFAULT -1," + TableColumn dominion_join_message = new TableColumn("join_message", FieldType.STRING, false, false, true, false, "'欢迎'");
" join_message TEXT NOT NULL DEFAULT '欢迎', " + TableColumn dominion_leave_message = new TableColumn("leave_message", FieldType.STRING, false, false, true, false, "'再见'");
" leave_message TEXT NOT NULL DEFAULT '再见', " + CreateTable.ForeignKey dominion_owner_fk = new CreateTable.ForeignKey(dominion_owner, "player_name", player_name_uuid, true);
CreateTable.ForeignKey dominion_parent_dom_id_fk = new CreateTable.ForeignKey(dominion_parent_dom_id, "dominion", dominion_id, true);
" FOREIGN KEY (owner) REFERENCES player_name(uuid) ON DELETE CASCADE," + CreateTable dominion = new CreateTable().ifNotExists();
" FOREIGN KEY (parent_dom_id) REFERENCES dominion(id) ON DELETE CASCADE" + dominion.table("dominion")
");"; .field(dominion_id)
Dominion.database.query(sql); .field(dominion_owner)
.field(dominion_name)
.field(dominion_world)
.field(dominion_x1)
.field(dominion_y1)
.field(dominion_z1)
.field(dominion_x2)
.field(dominion_y2)
.field(dominion_z2)
.field(dominion_parent_dom_id)
.field(dominion_join_message)
.field(dominion_leave_message)
.foreignKey(dominion_owner_fk)
.foreignKey(dominion_parent_dom_id_fk);
dominion.execute();
// player privilege // player privilege
sql = "CREATE TABLE IF NOT EXISTS player_privilege (" + TableColumn player_privilege_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
" id SERIAL PRIMARY KEY," + TableColumn player_privilege_player_uuid = new TableColumn("player_uuid", FieldType.STRING, false, false, true, false, "''");
" player_uuid VARCHAR(36) NOT NULL," + TableColumn player_privilege_dom_id = new TableColumn("dom_id", FieldType.INT, false, false, true, false, -1);
" dom_id INT NOT NULL," + TableColumn player_privilege_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, false);
CreateTable.ForeignKey player_privilege_player_uuid_fk = new CreateTable.ForeignKey(player_privilege_player_uuid, "player_name", player_name_uuid, true);
CreateTable.ForeignKey player_privilege_dom_id_fk = new CreateTable.ForeignKey(player_privilege_dom_id, "dominion", dominion_id, true);
CreateTable player_privilege = new CreateTable().ifNotExists();
player_privilege.table("player_privilege")
.field(player_privilege_id)
.field(player_privilege_player_uuid)
.field(player_privilege_dom_id)
.field(player_privilege_admin)
.foreignKey(player_privilege_player_uuid_fk)
.foreignKey(player_privilege_dom_id_fk)
.unique(player_privilege_player_uuid, player_privilege_dom_id);
player_privilege.execute();
" admin BOOLEAN NOT NULL DEFAULT FALSE," + // server root player name
Field server_player_name_id_field = new Field("id", -1);
Field server_player_name_uuid_field = new Field("uuid", "00000000-0000-0000-0000-000000000000");
Field server_player_name_last_known_name_field = new Field("last_known_name", "server");
InsertRow insert_server_player_name = new InsertRow().table("player_name").onConflictDoNothing(server_player_name_id_field)
.field(server_player_name_id_field)
.field(server_player_name_uuid_field)
.field(server_player_name_last_known_name_field);
insert_server_player_name.execute();
" UNIQUE (player_uuid, dom_id)," + // server root dominion
" FOREIGN KEY (player_uuid) REFERENCES player_name(uuid) ON DELETE CASCADE," + Field server_dom_id_field = new Field("id", -1);
" FOREIGN KEY (dom_id) REFERENCES dominion(id) ON DELETE CASCADE" + Field server_dom_owner_field = new Field("owner", "00000000-0000-0000-0000-000000000000");
");"; Field server_dom_name_field = new Field("name", "根领地");
Dominion.database.query(sql); Field server_dom_world_field = new Field("world", "all");
Field server_dom_x1_field = new Field("x1", -2147483648);
sql = "INSERT INTO player_name (" + Field server_dom_y1_field = new Field("y1", -2147483648);
"id, uuid, last_known_name" + Field server_dom_z1_field = new Field("z1", -2147483648);
") VALUES (" + Field server_dom_x2_field = new Field("x2", 2147483647);
"-1, '00000000-0000-0000-0000-000000000000', 'server'" + Field server_dom_y2_field = new Field("y2", 2147483647);
") ON CONFLICT DO NOTHING;"; Field server_dom_z2_field = new Field("z2", 2147483647);
Dominion.database.query(sql); Field server_dom_parent_dom_id_field = new Field("parent_dom_id", -1);
Field server_dom_join_message_field = new Field("join_message", "欢迎");
sql = "INSERT INTO dominion (" + Field server_dom_leave_message_field = new Field("leave_message", "再见");
"id, owner, name, world, x1, y1, z1, x2, y2, z2, parent_dom_id, join_message, leave_message" + InsertRow insert_server_dom = new InsertRow().table("dominion").onConflictDoNothing(server_dom_id_field)
") VALUES (" + .field(server_dom_id_field)
"-1, '00000000-0000-0000-0000-000000000000', '根领地', 'all', " + .field(server_dom_owner_field)
"-2147483648, -2147483648, -2147483648, " + .field(server_dom_name_field)
"2147483647, 2147483647, 2147483647, -1, " + .field(server_dom_world_field)
"'欢迎', '再见'" + .field(server_dom_x1_field)
") ON CONFLICT DO NOTHING;"; .field(server_dom_y1_field)
Dominion.database.query(sql); .field(server_dom_z1_field)
.field(server_dom_x2_field)
.field(server_dom_y2_field)
.field(server_dom_z2_field)
.field(server_dom_parent_dom_id_field)
.field(server_dom_join_message_field)
.field(server_dom_leave_message_field);
insert_server_dom.execute();
for (Flag flag : Flag.getAllDominionFlags()) { for (Flag flag : Flag.getAllDominionFlags()) {
Dominion.database.addColumnIfNotExists("dominion", TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
flag.getFlagName(), new AddColumn(column).table("dominion").ifNotExists().execute();
"BOOLEAN NOT NULL DEFAULT " + flag.getDefaultValue());
} }
for (Flag flag : Flag.getAllPrivilegeFlags()) { for (Flag flag : Flag.getAllPrivilegeFlags()) {
Dominion.database.addColumnIfNotExists("player_privilege", TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
flag.getFlagName(), new AddColumn(column).table("player_privilege").ifNotExists().execute();
"BOOLEAN NOT NULL DEFAULT " + flag.getDefaultValue());
} }
// 1.18.0 // 1.18.0
Dominion.database.addColumnIfNotExists("dominion", "tp_location", "TEXT NOT NULL DEFAULT 'default'"); TableColumn dominion_tp_location = new TableColumn("tp_location", FieldType.STRING, false, false, true, false, "'default'");
new AddColumn(dominion_tp_location).table("dominion").ifNotExists().execute();
// 1.31.0 // 1.31.0
sql = "CREATE TABLE IF NOT EXISTS privilege_template (" + TableColumn privilege_template_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
" id SERIAL PRIMARY KEY," + TableColumn privilege_template_creator = new TableColumn("creator", FieldType.STRING, false, false, true, false, "''");
" creator VARCHAR(36) NOT NULL," + TableColumn privilege_template_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
" name TEXT NOT NULL," + TableColumn privilege_template_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, false);
" admin BOOLEAN NOT NULL DEFAULT FALSE," + CreateTable.ForeignKey privilege_template_creator_fk = new CreateTable.ForeignKey(privilege_template_creator, "player_name", player_name_uuid, true);
CreateTable privilege_template = new CreateTable().ifNotExists();
privilege_template.table("privilege_template")
.field(privilege_template_id)
.field(privilege_template_creator)
.field(privilege_template_name)
.field(privilege_template_admin)
.foreignKey(privilege_template_creator_fk)
.unique(privilege_template_creator, privilege_template_name);
privilege_template.execute();
" UNIQUE (creator, name)," +
" FOREIGN KEY (creator) REFERENCES player_name(uuid) ON DELETE CASCADE" +
");";
Dominion.database.query(sql);
for (Flag flag : Flag.getAllPrivilegeFlags()) { for (Flag flag : Flag.getAllPrivilegeFlags()) {
Dominion.database.addColumnIfNotExists("privilege_template", TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
flag.getFlagName(), new AddColumn(column).table("privilege_template").ifNotExists().execute();
"BOOLEAN NOT NULL DEFAULT " + flag.getDefaultValue());
} }
// 1.31.6 // 1.31.6
Dominion.database.addColumnIfNotExists("dominion", "color", "TEXT NOT NULL DEFAULT '#00BFFF'"); TableColumn dominion_color = new TableColumn("color", FieldType.STRING, false, false, true, false, "'#00BFFF'");
new AddColumn(dominion_color).table("dominion").ifNotExists().execute();
} }
} }

View File

@ -47,11 +47,11 @@ public class ListDominion {
prefix.append(" | "); prefix.append(" | ");
} }
for (DominionNode node : dominionTree) { for (DominionNode node : dominionTree) {
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.dominion.getName()).build(); TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.getDominion().getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.dominion.getName()).build(); TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.getDominion().getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.dominion.getName()); Line line = Line.create().append(delete).append(manage).append(prefix + node.getDominion().getName());
lines.add(line); lines.add(line);
lines.addAll(BuildTreeLines(node.children, depth + 1)); lines.addAll(BuildTreeLines(node.getChildren(), depth + 1));
} }
return lines; return lines;
} }

View File

@ -63,9 +63,9 @@ public class PrivilegeInfo {
view.add(Line.create() view.add(Line.create()
.append(Button.createRed("").setExecuteCommand("/dominion set_privilege " + playerName + " admin true " + dominion.getName() + " " + page).build()) .append(Button.createRed("").setExecuteCommand("/dominion set_privilege " + playerName + " admin true " + dominion.getName() + " " + page).build())
.append("管理员")); .append("管理员"));
} for (Flag flag : Flag.getPrivilegeFlagsEnabled()) {
for (Flag flag : Flag.getPrivilegeFlagsEnabled()) { view.add(createOption(flag, privilege.getFlagValue(flag), playerName, dominion.getName(), page));
view.add(createOption(flag, privilege.getFlagValue(flag), playerName, dominion.getName(), page)); }
} }
view.showOn(player, page); view.showOn(player, page);
} }

View File

@ -1,5 +1,5 @@
Database: Database:
Type: sqlite # pgsql, sqlite Type: sqlite # pgsql, sqlite, mysql
Host: localhost Host: localhost
Port: 5432 Port: 5432
Name: dominion Name: dominion