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

# 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卫星地图渲染
- 支持为玩家单独设置特权;
- 支持设置领地管理员;
- 支持子领地;
- 采用 TUI 方式进行权限配置交互,简单快捷;
- 支持基础价格系统
- 支持经济系统(需要 Vault 前置)
- 领地区域可视化;
- 管理员可在游戏内使用TUI配置领地系统

View File

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

View File

@ -1,6 +1,7 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import com.flowpowered.math.vector.Vector2d;
import de.bluecolored.bluemap.api.BlueMapAPI;
@ -17,112 +18,116 @@ public class BlueMapConnect {
if (!Dominion.config.getBlueMap()) {
return;
}
try {
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<>());
Scheduler.runTaskAsync(() -> {
try {
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<>());
}
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 -> {
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)
for (Map.Entry<String, List<DominionDTO>> d : world_dominions.entrySet()) {
api.getWorld(d.getKey()).ifPresent(world -> {
MarkerSet markerSet = MarkerSet.builder()
.label("Dominion")
.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());
}
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();
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) {
if (!Dominion.config.getBlueMap()) {
return;
}
try {
BlueMapAPI.getInstance().ifPresent(api -> {
for (String world : mca_files.keySet()) {
api.getWorld(world).ifPresent(bmWorld -> {
MarkerSet markerSet = MarkerSet.builder()
.label("MCA")
.defaultHidden(true)
.build();
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)
Scheduler.runTaskAsync(() -> {
try {
BlueMapAPI.getInstance().ifPresent(api -> {
for (String world : mca_files.keySet()) {
api.getWorld(world).ifPresent(bmWorld -> {
MarkerSet markerSet = MarkerSet.builder()
.label("MCA")
.defaultHidden(true)
.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());
}
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();
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()) {
XLogger.debug("run loadDominionsExecution directly");
loadDominionsExecution();
loadDominionsExecution(idToLoad);
} else {
if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution");
@ -43,76 +46,113 @@ public class Cache {
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution();
loadDominionsExecution(idToLoad);
_update_dominion_is_scheduled.set(false);
},
delay_tick);
}
}
private void loadDominionsExecution() {
long start = System.currentTimeMillis();
id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
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<>());
public void loadDominions() {
loadDominions(null);
}
private void loadDominionsExecution(Integer idToLoad) {
Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis();
int count = 0;
if (idToLoad == null) {
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);
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()));
}
BlueMapConnect.render();
recheckPlayerState = true;
_last_update_dominion.set(System.currentTimeMillis());
XLogger.debug("loadDominionsExecution cost: %d ms", System.currentTimeMillis() - start);
BlueMapConnect.render();
recheckPlayerState = true;
_last_update_dominion.set(System.currentTimeMillis());
XLogger.debug("loadDominionsExecution cost: %d ms for %d dominions"
, System.currentTimeMillis() - start, count);
});
}
/**
* 从数据库加载所有玩家特权
* 如果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()) {
loadPlayerPrivilegesExecution();
XLogger.debug("run loadPlayerPrivilegesExecution directly");
loadPlayerPrivilegesExecution(player_uuid);
} else {
if (_update_privilege_is_scheduled.get()) return;
XLogger.debug("schedule loadPlayerPrivilegesExecution");
_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(() -> {
loadPlayerPrivilegesExecution();
XLogger.debug("run loadPlayerPrivilegesExecution scheduled");
loadPlayerPrivilegesExecution(player_uuid);
_update_privilege_is_scheduled.set(false);
},
delay_tick);
}
}
private void loadPlayerPrivilegesExecution() {
long start = System.currentTimeMillis();
List<PlayerPrivilegeDTO> all_privileges = PlayerPrivilegeDTO.selectAll();
if (all_privileges == null) {
XLogger.err("加载玩家特权失败");
return;
}
player_uuid_to_privilege = new ConcurrentHashMap<>();
for (PlayerPrivilegeDTO privilege : all_privileges) {
UUID player_uuid = privilege.getPlayerUUID();
if (!player_uuid_to_privilege.containsKey(player_uuid)) {
player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>());
public void loadPlayerPrivileges() {
loadPlayerPrivileges(null);
}
private void loadPlayerPrivilegesExecution(UUID player_to_update) {
Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis();
List<PlayerPrivilegeDTO> all_privileges;
if (player_to_update == null) {
all_privileges = PlayerPrivilegeDTO.selectAll();
player_uuid_to_privilege = 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);
}
recheckPlayerState = true;
_last_update_privilege.set(System.currentTimeMillis());
XLogger.debug("loadPlayerPrivilegesExecution cost: %d ms", System.currentTimeMillis() - start);
for (PlayerPrivilegeDTO privilege : all_privileges) {
UUID player_uuid = privilege.getPlayerUUID();
if (!player_uuid_to_privilege.containsKey(player_uuid)) {
player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>());
}
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;
for (List<DominionNode> tree : world_dominion_tree.values()) {
for (DominionNode node : tree) {
if (node.dominion.getOwner().equals(player.getUuid())) {
if (node.getDominion().getOwner().equals(player.getUuid())) {
dominionTree.add(node);
}
}
@ -318,7 +358,7 @@ public class Cache {
private final AtomicBoolean _update_dominion_is_scheduled = new AtomicBoolean(false);
private final AtomicLong _last_update_privilege = new AtomicLong(0);
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; // 是否需要重新检查玩家状态发光飞行
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.DatabaseTables;
import cn.lunadeer.minecraftpluginutils.*;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseType;
import cn.lunadeer.minecraftpluginutils.scui.CuiManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -26,8 +28,8 @@ public final class Dominion extends JavaPlugin {
new XLogger(this);
config = new ConfigManager(this);
XLogger.setDebug(config.isDebug());
database = new DatabaseManager(this,
DatabaseManager.TYPE.valueOf(config.getDbType().toUpperCase()),
new DatabaseManager(this,
DatabaseType.valueOf(config.getDbType().toUpperCase()),
config.getDbHost(),
config.getDbPort(),
config.getDbName(),
@ -74,12 +76,11 @@ public final class Dominion extends JavaPlugin {
@Override
public void onDisable() {
// Plugin shutdown logic
database.close();
DatabaseManager.instance.close();
}
public static Dominion instance;
public static ConfigManager config;
public static DatabaseManager database;
public static Map<UUID, Map<Integer, Location>> pointsSelect = new HashMap<>();
private GiteaReleaseCheck giteaReleaseCheck;
}

View File

@ -5,30 +5,52 @@ import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.*;
public class DominionNode {
public DominionDTO dominion;
public List<DominionNode> children = new ArrayList<>();
private Integer dominion_id;
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) {
List<DominionNode> dominionTree = new ArrayList<>();
// 映射父节点ID到其子节点列表
Map<Integer, List<DominionDTO>> parentToChildrenMap = new HashMap<>();
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();
node.dominion = dominion;
node.children = BuildNodeTree(dominion.getId(), dominions);
node.dominion_id = dominion.getId();
node.children = buildTree(dominion.getId(), parentToChildrenMap);
dominionTree.add(node);
}
}
return dominionTree;
}
public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) {
for (DominionNode node : nodes) {
if (isInDominion(node.dominion, loc)) {
if (isInDominion(node.getDominion(), loc)) {
if (node.children.isEmpty()) {
return node;
} else {
@ -48,7 +70,7 @@ public class DominionNode {
if (nodes == null) return null;
if (nodes.isEmpty()) return null;
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) {

View File

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

View File

@ -103,13 +103,17 @@ public class PrivilegeController {
privilege = createPlayerPrivilege(operator, player.getUuid(), dominion);
if (privilege == null) return;
}
if (flag.equals("admin") || privilege.getAdmin()) {
if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他管理员的权限", dominionName));
return;
}
if ((flag.equals("admin") || privilege.getAdmin()) && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他玩家管理员的权限", dominionName));
return;
}
if (flag.equals("admin")) {
privilege.setAdmin(value);
} else {
if (privilege.getAdmin()) {
operator.setResponse(FAIL.addMessage("管理员拥有所有权限,无需单独设置权限"));
return;
}
Flag f = Flag.getFlag(flag);
if (f == null) {
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.Dominion;
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.World;
import java.awt.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.List;
public class DominionDTO {
private static List<DominionDTO> query(String sql, Object... args) {
List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, args)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
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);
}
try (ResultSet rs = DatabaseManager.instance.query(sql, args)) {
return getDTOFromRS(rs);
} 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;
}
@ -110,76 +115,33 @@ public class DominionDTO {
}
public static DominionDTO insert(DominionDTO dominion) {
StringBuilder sql = new StringBuilder("INSERT INTO dominion (" +
"owner, name, world, x1, y1, z1, x2, y2, z2, ");
for (Flag f : Flag.getAllDominionFlags()) {
sql.append(f.getFlagName()).append(", ");
InsertRow insert = new InsertRow().returningAll().table("dominion").onConflictDoNothing(new Field("id", null));
insert.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.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");
sql.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ");
for (Flag f : Flag.getAllDominionFlags()) {
sql.append(f.getDefaultValue()).append(", ");
try (ResultSet rs = insert.execute()) {
Cache.instance.loadDominions();
List<DominionDTO> dominions = getDTOFromRS(rs);
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) {
String sql = "DELETE FROM dominion WHERE id = ?;";
query(sql, dominion.getId());
}
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);
Cache.instance.loadDominions();
}
private DominionDTO(Integer id, UUID owner, String name, String world,
@ -189,39 +151,39 @@ public class DominionDTO {
Map<Flag, Boolean> flags,
String tp_location,
String color) {
this.id = id;
this.owner = owner;
this.name = name;
this.world = world;
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
this.parentDomId = parentDomId;
this.joinMessage = joinMessage;
this.leaveMessage = leaveMessage;
this.id.value = id;
this.owner.value = owner.toString();
this.name.value = name;
this.world.value = world;
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
this.parentDomId.value = parentDomId;
this.joinMessage.value = joinMessage;
this.leaveMessage.value = leaveMessage;
this.flags.putAll(flags);
this.tp_location = tp_location;
this.color = color;
this.tp_location.value = tp_location;
this.color.value = color;
}
private DominionDTO(Integer id, UUID owner, String name, String world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId) {
this.id = id;
this.owner = owner;
this.name = name;
this.world = world;
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
this.parentDomId = parentDomId;
this.id.value = id;
this.owner.value = owner.toString();
this.name.value = name;
this.world.value = world;
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
this.parentDomId.value = parentDomId;
}
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);
}
private Integer id;
private UUID owner;
private String name;
private final String world;
private Integer x1;
private Integer y1;
private Integer z1;
private Integer x2;
private Integer y2;
private Integer z2;
private Integer parentDomId = -1;
private String joinMessage = "欢迎";
private String leaveMessage = "再见";
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);
private final Field x2 = new Field("x2", FieldType.INT);
private final Field y2 = new Field("y2", FieldType.INT);
private final Field z2 = new Field("z2", FieldType.INT);
private final Field parentDomId = new Field("parent_dom_id", -1);
private final Field joinMessage = new Field("join_message", "欢迎来到 ${DOM_NAME}");
private final Field leaveMessage = new Field("leave_message", "你正在离开 ${DOM_NAME},欢迎下次光临~");
private final Map<Flag, Boolean> flags = new HashMap<>();
private String tp_location;
private String color;
private final Field tp_location = new Field("tp_location", "default");
private final Field color = new Field("color", "#00BFFF");
// getters and setters
public Integer getId() {
return id;
}
public DominionDTO setId(Integer id) {
this.id = id;
return update(this);
return (Integer) id.value;
}
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) {
this.owner = owner;
return update(this);
this.owner.value = owner.toString();
return doUpdate(new UpdateRow().field(this.owner));
}
public String getName() {
return name;
return (String) name.value;
}
public DominionDTO setName(String name) {
this.name = name;
return update(this);
this.name.value = name;
return doUpdate(new UpdateRow().field(this.name));
}
public String getWorld() {
return world;
return (String) world.value;
}
public Integer getX1() {
return x1;
return (Integer) x1.value;
}
public DominionDTO setX1(Integer x1) {
this.x1 = x1;
return update(this);
this.x1.value = x1;
return doUpdate(new UpdateRow().field(this.x1));
}
public Integer getY1() {
return y1;
return (Integer) y1.value;
}
public DominionDTO setY1(Integer y1) {
this.y1 = y1;
return update(this);
this.y1.value = y1;
return doUpdate(new UpdateRow().field(this.y1));
}
public Integer getZ1() {
return z1;
return (Integer) z1.value;
}
public DominionDTO setZ1(Integer z1) {
this.z1 = z1;
return update(this);
this.z1.value = z1;
return doUpdate(new UpdateRow().field(this.z1));
}
public Integer getX2() {
return x2;
return (Integer) x2.value;
}
public DominionDTO setX2(Integer x2) {
this.x2 = x2;
return update(this);
this.x2.value = x2;
return doUpdate(new UpdateRow().field(this.x2));
}
public Integer getY2() {
return y2;
return (Integer) y2.value;
}
public DominionDTO setY2(Integer y2) {
this.y2 = y2;
return update(this);
this.y2.value = y2;
return doUpdate(new UpdateRow().field(this.y2));
}
public Integer getZ2() {
return z2;
return (Integer) z2.value;
}
public DominionDTO setZ2(Integer z2) {
this.z2 = z2;
return update(this);
this.z2.value = z2;
return doUpdate(new UpdateRow().field(this.z2));
}
public Integer getSquare() {
return (x2 - x1 + 1) * (z2 - z1 + 1);
return (getX2() - getX1() + 1) * (getZ2() - getZ1() + 1);
}
public Integer getVolume() {
return getSquare() * (y2 - y1 + 1);
return getSquare() * (getY2() - getY1() + 1);
}
public Integer getWidthX() {
return x2 - x1 + 1;
return getX2() - getX1() + 1;
}
public Integer getHeight() {
return y2 - y1 + 1;
return getY2() - getY1() + 1;
}
public Integer getWidthZ() {
return z2 - z1 + 1;
return getZ2() - getZ1() + 1;
}
public Integer getParentDomId() {
return parentDomId;
return (Integer) parentDomId.value;
}
public DominionDTO setParentDomId(Integer parentDomId) {
this.parentDomId = parentDomId;
return update(this);
this.parentDomId.value = parentDomId;
return doUpdate(new UpdateRow().field(this.parentDomId));
}
public String getJoinMessage() {
return joinMessage;
return (String) joinMessage.value;
}
public DominionDTO setJoinMessage(String joinMessage) {
this.joinMessage = joinMessage;
return update(this);
this.joinMessage.value = joinMessage;
return doUpdate(new UpdateRow().field(this.joinMessage));
}
public String getLeaveMessage() {
return leaveMessage;
return (String) leaveMessage.value;
}
public DominionDTO setLeaveMessage(String leaveMessage) {
this.leaveMessage = leaveMessage;
return update(this);
this.leaveMessage.value = leaveMessage;
return doUpdate(new UpdateRow().field(this.leaveMessage));
}
public Boolean getFlagValue(Flag flag) {
@ -386,17 +359,18 @@ public class DominionDTO {
public DominionDTO setFlagValue(Flag flag, Boolean 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) {
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
return update(this);
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
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() {
@ -404,8 +378,8 @@ public class DominionDTO {
return null;
} else {
// 0:0:0
String[] loc = tp_location.split(":");
World w = Dominion.instance.getServer().getWorld(world);
String[] loc = ((String) tp_location.value).split(":");
World w = Dominion.instance.getServer().getWorld(getWorld());
if (loc.length == 3 && w != null) {
return new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
} else {
@ -417,36 +391,36 @@ public class DominionDTO {
}
public DominionDTO setTpLocation(Location loc) {
this.tp_location = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
return update(this);
this.tp_location.value = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
return doUpdate(new UpdateRow().field(tp_location));
}
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() {
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) {
this.color = color;
return update(this);
this.color.value = color;
return doUpdate(new UpdateRow().field(this.color));
}
public int getColorR() {
return Integer.valueOf(color.substring(1, 3), 16);
return Integer.valueOf(getColor().substring(1, 3), 16);
}
public int getColorG() {
return Integer.valueOf(color.substring(3, 5), 16);
return Integer.valueOf(getColor().substring(3, 5), 16);
}
public int getColorB() {
return Integer.valueOf(color.substring(5, 7), 16);
return Integer.valueOf(getColor().substring(5, 7), 16);
}
public String getColor() {
return color;
return (String) color.value;
}
}

View File

@ -1,10 +1,15 @@
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 java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@ -31,18 +36,24 @@ public class PlayerDTO {
private static List<PlayerDTO> query(String sql, Object... params) {
List<PlayerDTO> players = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, params)) {
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);
}
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
return getDTOFromRS(rs);
} 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;
}
@ -73,24 +84,44 @@ public class PlayerDTO {
}
private static PlayerDTO insert(PlayerDTO player) {
String sql = "INSERT INTO player_name (uuid, last_known_name, last_join_at) " +
"VALUES" +
" (?, ?, CURRENT_TIMESTAMP) " +
"RETURNING *;";
List<PlayerDTO> players = query(sql, player.getUuid().toString(), player.getLastKnownName());
if (players.size() == 0) return null;
return players.get(0);
Field uuid = new Field("uuid", player.getUuid().toString());
Field lastKnownName = new Field("last_known_name", player.getLastKnownName());
Field lastJoinAt = new Field("last_join_at", Timestamp.valueOf(LocalDateTime.now()));
InsertRow insertRow = new InsertRow()
.table("player_name")
.field(uuid)
.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) {
String sql = "UPDATE player_name SET " +
"last_known_name = ?, " +
"last_join_at = CURRENT_TIMESTAMP " +
"WHERE uuid = ? " +
"RETURNING *;";
List<PlayerDTO> players = query(sql, player.getLastKnownName(), player.getUuid().toString());
if (players.size() == 0) return null;
return players.get(0);
Field lastKnownName = new Field("last_known_name", player.getLastKnownName());
Field uuid = new Field("uuid", player.getUuid().toString());
Field lastJoinAt = new Field("last_join_at", Timestamp.valueOf(LocalDateTime.now()));
UpdateRow updateRow = new UpdateRow()
.table("player_name")
.field(lastKnownName)
.field(lastJoinAt)
.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) {

View File

@ -1,35 +1,88 @@
package cn.lunadeer.dominion.dtos;
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.util.*;
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) {
StringBuilder sql = new StringBuilder("INSERT INTO player_privilege (player_uuid, admin, dom_id, ");
for (Flag f : Flag.getAllPrivilegeFlags()) {
sql.append(f.getFlagName()).append(", ");
Field playerUUID = new Field("player_uuid", player.getPlayerUUID().toString());
Field admin = new Field("admin", player.getAdmin());
Field domID = new Field("dom_id", player.getDomID());
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));
sql.append(") VALUES ('")
.append(player.getPlayerUUID()).append("', ")
.append(player.getAdmin()).append(", ")
.append(player.getDomID()).append(", ");
for (Flag f : Flag.getAllPrivilegeFlags()) {
sql.append(player.getFlagValue(f)).append(", ");
try (ResultSet rs = insertRow.execute()) {
Cache.instance.loadPlayerPrivileges(player.getPlayerUUID());
List<PlayerPrivilegeDTO> players = getDTOFromRS(rs);
if (players.size() == 0) return null;
return players.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("插入玩家权限失败: ", e, "");
return null;
}
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) {
@ -47,6 +100,7 @@ public class PlayerPrivilegeDTO {
public static void delete(UUID player, Integer domID) {
String sql = "DELETE FROM player_privilege WHERE player_uuid = ? AND dom_id = ?;";
query(sql, player.toString(), domID);
Cache.instance.loadPlayerPrivileges(player);
}
public static List<PlayerPrivilegeDTO> selectAll() {
@ -89,20 +143,26 @@ public class PlayerPrivilegeDTO {
public PlayerPrivilegeDTO setFlagValue(Flag flag, Boolean 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) {
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) {
this.admin = template.getAdmin();
UpdateRow updateRow = new UpdateRow().field(new Field("admin", admin));
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
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) {
@ -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;
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.util.*;
@ -9,8 +12,18 @@ public class PrivilegeTemplateDTO {
private static List<PrivilegeTemplateDTO> query(String sql, Object... params) {
List<PrivilegeTemplateDTO> templates = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, params)) {
if (rs == null) return templates;
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
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()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
@ -26,16 +39,41 @@ public class PrivilegeTemplateDTO {
templates.add(template);
}
} catch (Exception e) {
Dominion.database.handleDatabaseError("查询权限模版失败: ", e, sql);
DatabaseManager.handleDatabaseError("查询权限模版失败: ", e, null);
}
return templates;
}
public static PrivilegeTemplateDTO create(UUID creator, String name) {
String sql = "INSERT INTO privilege_template (creator, name) VALUES (?, ?) RETURNING *;";
List<PrivilegeTemplateDTO> templates = query(sql, creator.toString(), name);
if (templates.size() == 0) return null;
return templates.get(0);
Field creatorField = new Field("creator", creator.toString());
Field nameField = new Field("name", name);
InsertRow insertRow = new InsertRow().table("privilege_template").onConflictDoNothing(new Field("id", null))
.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) {
@ -93,25 +131,12 @@ public class PrivilegeTemplateDTO {
public PrivilegeTemplateDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value);
return update(this);
return doUpdate(new UpdateRow().field(new Field(flag.getFlagName(), value)));
}
public PrivilegeTemplateDTO setAdmin(Boolean admin) {
this.admin = admin;
return update(this);
}
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);
return doUpdate(new UpdateRow().field(new Field("admin", admin)));
}
}

View File

@ -1,107 +1,159 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
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 static void migrate() {
String sql = "";
// player name
sql = "CREATE TABLE IF NOT EXISTS player_name (" +
" id SERIAL PRIMARY KEY," +
" uuid VARCHAR(36) NOT NULL UNIQUE," +
" last_known_name TEXT NOT NULL," +
" last_join_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" +
");";
Dominion.database.query(sql);
TableColumn player_name_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn player_name_uuid = new TableColumn("uuid", FieldType.STRING, false, false, true, true, "''");
TableColumn player_name_last_known_name = new TableColumn("last_known_name", FieldType.STRING, false, false, true, false, "'unknown'");
TableColumn player_name_last_join_at = new TableColumn("last_join_at", FieldType.DATETIME, false, false, true, false, "CURRENT_TIMESTAMP");
CreateTable player_name = new CreateTable().ifNotExists();
player_name.table("player_name")
.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
sql = "CREATE TABLE IF NOT EXISTS dominion (" +
" id SERIAL PRIMARY KEY," +
" owner VARCHAR(36) NOT NULL," +
" name TEXT NOT NULL UNIQUE," +
" world TEXT NOT NULL," +
" x1 INT NOT NULL," +
" y1 INT NOT NULL," +
" z1 INT NOT NULL," +
" x2 INT NOT NULL," +
" y2 INT NOT NULL," +
" z2 INT NOT NULL," +
" parent_dom_id INT NOT NULL DEFAULT -1," +
" join_message TEXT NOT NULL DEFAULT '欢迎', " +
" leave_message TEXT NOT NULL DEFAULT '再见', " +
" FOREIGN KEY (owner) REFERENCES player_name(uuid) ON DELETE CASCADE," +
" FOREIGN KEY (parent_dom_id) REFERENCES dominion(id) ON DELETE CASCADE" +
");";
Dominion.database.query(sql);
TableColumn dominion_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn dominion_owner = new TableColumn("owner", FieldType.STRING, false, false, true, false, "''");
TableColumn dominion_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
TableColumn dominion_world = new TableColumn("world", FieldType.STRING, false, false, true, false, "'world'");
TableColumn dominion_x1 = new TableColumn("x1", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_y1 = new TableColumn("y1", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_z1 = new TableColumn("z1", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_x2 = new TableColumn("x2", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_y2 = new TableColumn("y2", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_z2 = new TableColumn("z2", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_parent_dom_id = new TableColumn("parent_dom_id", FieldType.INT, false, false, true, false, -1);
TableColumn dominion_join_message = new TableColumn("join_message", FieldType.STRING, false, false, true, false, "'欢迎'");
TableColumn dominion_leave_message = new TableColumn("leave_message", FieldType.STRING, false, false, true, false, "'再见'");
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);
CreateTable dominion = new CreateTable().ifNotExists();
dominion.table("dominion")
.field(dominion_id)
.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
sql = "CREATE TABLE IF NOT EXISTS player_privilege (" +
" id SERIAL PRIMARY KEY," +
" player_uuid VARCHAR(36) NOT NULL," +
" dom_id INT NOT NULL," +
TableColumn player_privilege_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn player_privilege_player_uuid = new TableColumn("player_uuid", FieldType.STRING, false, false, true, false, "''");
TableColumn player_privilege_dom_id = new TableColumn("dom_id", FieldType.INT, false, false, true, false, -1);
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)," +
" FOREIGN KEY (player_uuid) REFERENCES player_name(uuid) ON DELETE CASCADE," +
" FOREIGN KEY (dom_id) REFERENCES dominion(id) ON DELETE CASCADE" +
");";
Dominion.database.query(sql);
sql = "INSERT INTO player_name (" +
"id, uuid, last_known_name" +
") VALUES (" +
"-1, '00000000-0000-0000-0000-000000000000', 'server'" +
") ON CONFLICT DO NOTHING;";
Dominion.database.query(sql);
sql = "INSERT INTO dominion (" +
"id, owner, name, world, x1, y1, z1, x2, y2, z2, parent_dom_id, join_message, leave_message" +
") VALUES (" +
"-1, '00000000-0000-0000-0000-000000000000', '根领地', 'all', " +
"-2147483648, -2147483648, -2147483648, " +
"2147483647, 2147483647, 2147483647, -1, " +
"'欢迎', '再见'" +
") ON CONFLICT DO NOTHING;";
Dominion.database.query(sql);
// server root dominion
Field server_dom_id_field = new Field("id", -1);
Field server_dom_owner_field = new Field("owner", "00000000-0000-0000-0000-000000000000");
Field server_dom_name_field = new Field("name", "根领地");
Field server_dom_world_field = new Field("world", "all");
Field server_dom_x1_field = new Field("x1", -2147483648);
Field server_dom_y1_field = new Field("y1", -2147483648);
Field server_dom_z1_field = new Field("z1", -2147483648);
Field server_dom_x2_field = new Field("x2", 2147483647);
Field server_dom_y2_field = new Field("y2", 2147483647);
Field server_dom_z2_field = new Field("z2", 2147483647);
Field server_dom_parent_dom_id_field = new Field("parent_dom_id", -1);
Field server_dom_join_message_field = new Field("join_message", "欢迎");
Field server_dom_leave_message_field = new Field("leave_message", "再见");
InsertRow insert_server_dom = new InsertRow().table("dominion").onConflictDoNothing(server_dom_id_field)
.field(server_dom_id_field)
.field(server_dom_owner_field)
.field(server_dom_name_field)
.field(server_dom_world_field)
.field(server_dom_x1_field)
.field(server_dom_y1_field)
.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()) {
Dominion.database.addColumnIfNotExists("dominion",
flag.getFlagName(),
"BOOLEAN NOT NULL DEFAULT " + flag.getDefaultValue());
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("dominion").ifNotExists().execute();
}
for (Flag flag : Flag.getAllPrivilegeFlags()) {
Dominion.database.addColumnIfNotExists("player_privilege",
flag.getFlagName(),
"BOOLEAN NOT NULL DEFAULT " + flag.getDefaultValue());
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("player_privilege").ifNotExists().execute();
}
// 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
sql = "CREATE TABLE IF NOT EXISTS privilege_template (" +
" id SERIAL PRIMARY KEY," +
" creator VARCHAR(36) NOT NULL," +
" name TEXT NOT NULL," +
" admin BOOLEAN NOT NULL DEFAULT FALSE," +
TableColumn privilege_template_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn privilege_template_creator = new TableColumn("creator", FieldType.STRING, false, false, true, false, "''");
TableColumn privilege_template_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
TableColumn privilege_template_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, 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()) {
Dominion.database.addColumnIfNotExists("privilege_template",
flag.getFlagName(),
"BOOLEAN NOT NULL DEFAULT " + flag.getDefaultValue());
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("privilege_template").ifNotExists().execute();
}
// 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(" | ");
}
for (DominionNode node : dominionTree) {
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.dominion.getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.dominion.getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.dominion.getName());
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.getDominion().getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.getDominion().getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.getDominion().getName());
lines.add(line);
lines.addAll(BuildTreeLines(node.children, depth + 1));
lines.addAll(BuildTreeLines(node.getChildren(), depth + 1));
}
return lines;
}

View File

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

View File

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