优化了一些ui
Java CI-CD with Maven / build (push) Successful in 21m34s Details

新增限制控制
This commit is contained in:
zhangyuheng 2024-03-30 02:50:21 +08:00
parent 02839f7f3b
commit 0a670b1a45
17 changed files with 284 additions and 91 deletions

View File

@ -170,14 +170,22 @@ Database:
User: dominion
Pass: dominion
# -1 表示不开启
AutoCreateRadius: 10
MaxX: 128
MaxY: 64
MaxZ: 128
AutoClean:
Enabled: false
AfterDays: 180
# -1 表示不限制
Limit:
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Amount: 10
Depth: 3 # 子领地深度 0不允许子领地 -1不限制
WorldBlackList: []
# -1 表示不开启
AutoCleanAfterDays: 180
BlueMap: true

View File

@ -6,7 +6,7 @@
<groupId>cn.lunadeer</groupId>
<artifactId>Dominion</artifactId>
<version>1.13.6-beta</version>
<version>1.14.6-beta</version>
<packaging>jar</packaging>
<name>Dominion</name>

View File

@ -8,7 +8,7 @@ import java.util.List;
public class AutoClean {
public static void run() {
if (!Dominion.config.getAutoCleanEnable()) {
if (Dominion.config.getAutoCleanAfterDays() < 0) {
return;
}
XLogger.info("开始自动清理长时间未登录玩家领地数据");

View File

@ -206,6 +206,18 @@ public class Cache {
return id_dominions.get(id);
}
public int getPlayerDominionCount(Player player) {
UUID player_uuid = player.getUniqueId();
int count = 0;
for (Integer id : world_dominions.get(player.getWorld().getName())) {
DominionDTO dominion = id_dominions.get(id);
if (dominion.getOwner().equals(player_uuid)) {
count++;
}
}
return count;
}
public List<DominionDTO> getDominions() {
return new ArrayList<>(id_dominions.values());
}

View File

@ -134,6 +134,9 @@ public class Commands implements TabExecutor {
case "reload_cache":
Operator.reloadCache(sender, args);
break;
case "reload_config":
Operator.reloadConfig(sender, args);
break;
case "export_mca":
Operator.exportMca(sender, args);
break;
@ -167,6 +170,7 @@ public class Commands implements TabExecutor {
"rename",
"give",
"reload_cache",
"reload_config",
"export_mca"
);
}

View File

@ -28,6 +28,7 @@ public final class Dominion extends JavaPlugin {
dbConnection = Database.createConnection();
Database.migrate();
scheduler = new Scheduler(this);
AutoClean.run();
Cache.instance = new Cache();
Bukkit.getPluginManager().registerEvents(new PlayerEvents(), this);
@ -48,10 +49,6 @@ public final class Dominion extends JavaPlugin {
XLogger.info(" |_____/ \\___/|_| |_| |_|_|_| |_|_|\\___/|_| |_|");
XLogger.info(" ");
scheduler.async.runDelayed(this, scheduledTask -> {
AutoClean.run();
}, 30, TimeUnit.SECONDS);
scheduler.async.runDelayed(this, scheduledTask -> {
BlueMapConnect.render();
}, 40, TimeUnit.SECONDS);

View File

@ -88,6 +88,10 @@ public class DominionOperate {
Notification.error(sender, "用法: /dominion auto_create <领地名称>");
return;
}
if (Dominion.config.getAutoCreateRadius() < 0) {
Notification.error(sender, "自动创建领地功能已关闭");
return;
}
autoPoints(player);
createDominion(sender, args);
}
@ -107,6 +111,10 @@ public class DominionOperate {
Notification.error(sender, "用法: /dominion auto_create_sub <子领地名称> [父领地名称]");
return;
}
if (Dominion.config.getAutoCreateRadius() < 0) {
Notification.error(sender, "自动创建领地功能已关闭");
return;
}
autoPoints(player);
createSubDominion(sender, args);
}

View File

@ -103,6 +103,15 @@ public class Operator {
});
}
public static void reloadConfig(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return;
Dominion.scheduler.async.runNow(Dominion.instance, ScheduledTask -> {
Notification.info(sender, "正在重新加载配置文件...");
Dominion.config.reload();
Notification.info(sender, "配置文件已重新加载");
});
}
private static int convertWorld2Mca(int world) {
return world < 0 ? world / 512 - 1 : world / 512;
}

View File

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
@ -69,15 +70,20 @@ public class DominionController {
Notification.error(owner, "禁止跨世界操作");
return null;
}
int x_length = Math.abs((int) (loc1.getX() - loc2.getX()));
int y_length = Math.abs((int) (loc1.getY() - loc2.getY()));
int z_length = Math.abs((int) (loc1.getZ() - loc2.getZ()));
if (x_length < 4 || y_length < 4 || z_length < 4) {
Notification.error(owner, "领地的任意一边长度不得小于4");
// 检查世界是否可以创建
if (Dominion.config.getWorldBlackList().contains(owner.getWorld().getName())) {
Notification.error(owner, "禁止在世界 " + owner.getWorld().getName() + " 创建领地");
return null;
}
if (x_length > Dominion.config.getMaxX() || y_length > Dominion.config.getMaxY() || z_length > Dominion.config.getMaxZ()) {
Notification.error(owner, "领地尺寸不能超过 " + Dominion.config.getMaxX() + " x " + Dominion.config.getMaxY() + " x " + Dominion.config.getMaxZ());
// 检查领地数量是否达到上限
if (Cache.instance.getPlayerDominionCount(owner) >= Dominion.config.getLimitAmount() && Dominion.config.getLimitAmount() > 0) {
Notification.error(owner, "你的领地数量已达上限,当前上限为 " + Dominion.config.getLimitAmount());
return null;
}
// 检查领地大小是否合法
if (sizeNotValid(owner,
loc1.getBlockX(), loc1.getBlockY(), loc1.getBlockZ(),
loc2.getBlockX(), loc2.getBlockY(), loc2.getBlockZ())) {
return null;
}
DominionDTO dominion = new DominionDTO(owner.getUniqueId(), name, owner.getWorld().getName(),
@ -108,6 +114,10 @@ public class DominionController {
Notification.error(owner, "禁止跨世界操作");
return null;
}
// 检查深度是否达到上限
if (depthNotValid(owner, parent_dominion)) {
return null;
}
// 检查是否超出父领地范围
if (!isContained(dominion, parent_dominion)) {
Notification.error(owner, "超出父领地 " + parent_dominion_name + " 范围");
@ -199,11 +209,7 @@ public class DominionController {
Notification.error(operator, "无效的方向");
return null;
}
int x_length = x2 - x1;
int y_length = y2 - y1;
int z_length = z2 - z1;
if (x_length > Dominion.config.getMaxX() || y_length > Dominion.config.getMaxY() || z_length > Dominion.config.getMaxZ()) {
Notification.error(operator, "领地尺寸不能超过 " + Dominion.config.getMaxX() + " x " + Dominion.config.getMaxY() + " x " + Dominion.config.getMaxZ());
if (sizeNotValid(operator, x1, y1, z1, x2, y2, z2)) {
return null;
}
// 校验是否超出父领地范围
@ -303,6 +309,9 @@ public class DominionController {
Notification.error(operator, "缩小后的领地无效");
return null;
}
if (sizeNotValid(operator, x1, y1, z1, x2, y2, z2)) {
return null;
}
// 获取所有的子领地
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId());
for (DominionDTO sub_dominion : sub_dominions) {
@ -517,12 +526,18 @@ public class DominionController {
* 判断 sub 是否完全被 parent 包裹
*/
private static boolean isContained(DominionDTO sub, DominionDTO parent) {
if (parent.getId() == -1) {
return true;
}
return sub.getX1() >= parent.getX1() && sub.getX2() <= parent.getX2() &&
sub.getY1() >= parent.getY1() && sub.getY2() <= parent.getY2() &&
sub.getZ1() >= parent.getZ1() && sub.getZ2() <= parent.getZ2();
}
private static boolean isContained(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, DominionDTO parent) {
if (parent.getId() == -1) {
return true;
}
return x1 >= parent.getX1() && x2 <= parent.getX2() &&
y1 >= parent.getY1() && y2 <= parent.getY2() &&
z1 >= parent.getZ1() && z2 <= parent.getZ2();
@ -543,4 +558,74 @@ public class DominionController {
sub_dominions.addAll(sub_sub_dominions);
return sub_dominions;
}
private static boolean sizeNotValid(Player operator, int x1, int y1, int z1, int x2, int y2, int z2) {
// 如果 1 > 2 则交换
if (x1 > x2) {
int temp = x1;
x1 = x2;
x2 = temp;
}
if (y1 > y2) {
int temp = y1;
y1 = y2;
y2 = temp;
}
if (z1 > z2) {
int temp = z1;
z1 = z2;
z2 = temp;
}
int x_length = x2 - x1;
int y_length = y2 - y1;
int z_length = z2 - z1;
if (x_length < 4 || y_length < 4 || z_length < 4) {
Notification.error(operator, "领地的任意一边长度不得小于4");
return true;
}
if (x_length > Dominion.config.getLimitSizeX() && Dominion.config.getLimitSizeX() > 0) {
Notification.error(operator, "领地X方向长度不能超过 " + Dominion.config.getLimitSizeX());
return true;
}
if (y_length > Dominion.config.getLimitSizeY() && Dominion.config.getLimitSizeY() > 0) {
Notification.error(operator, "领地Y方向高度不能超过 " + Dominion.config.getLimitSizeY());
return true;
}
if (z_length > Dominion.config.getLimitSizeZ() && Dominion.config.getLimitSizeZ() > 0) {
Notification.error(operator, "领地Z方向长度不能超过 " + Dominion.config.getLimitSizeZ());
return true;
}
if (y2 > Dominion.config.getLimitMaxY() && Dominion.config.getLimitMaxY() > 0) {
Notification.error(operator, "领地Y坐标不能超过 " + Dominion.config.getLimitMaxY());
return true;
}
if (y1 < Dominion.config.getLimitMinY() && Dominion.config.getLimitMinY() > 0) {
Notification.error(operator, "领地Y坐标不能低于 " + Dominion.config.getLimitMinY());
return true;
}
return false;
}
private static boolean depthNotValid(Player operator, DominionDTO parent_dom) {
if (Dominion.config.getLimitDepth() < 0) {
return false;
}
if (parent_dom.getId() != -1 && Dominion.config.getLimitDepth() == 0) {
Notification.error(operator, "不允许创建子领地");
return true;
}
if (parent_dom.getId() == -1) {
return false;
}
int level = 0;
while (parent_dom.getParentDomId() != -1) {
parent_dom = Cache.instance.getDominion(parent_dom.getParentDomId());
level++;
}
if (level >= Dominion.config.getLimitDepth()) {
Notification.error(operator, "子领地嵌套深度不能超过 " + Dominion.config.getLimitDepth());
return true;
}
return false;
}
}

View File

@ -15,6 +15,10 @@ public class DominionDTO {
private static List<DominionDTO> query(String sql) {
List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = Database.query(sql)) {
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");
@ -78,10 +82,6 @@ public class DominionDTO {
);
dominions.add(dominion);
}
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadDominions();
}
} catch (SQLException e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);

View File

@ -572,6 +572,10 @@ public class PlayerPrivilegeDTO {
private static List<PlayerPrivilegeDTO> query(String sql) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
try (ResultSet rs = Database.query(sql)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadPlayerPrivileges();
}
if (rs == null) return players;
while (rs.next()) {
PlayerPrivilegeDTO player = new PlayerPrivilegeDTO(
@ -618,10 +622,6 @@ public class PlayerPrivilegeDTO {
);
players.add(player);
}
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadPlayerPrivileges();
}
} catch (Exception e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);

View File

@ -74,7 +74,7 @@ public class Apis {
Player player = playerOnly(sender);
if (player == null) return;
int page = getPage(args);
ListView view = ListView.create(5, "/dominion help");
ListView view = ListView.create(10, "/dominion help");
view.title("领地插件命令帮助 <>表示必填参数 []表示可选参数")
.add(Line.create().append("打开交互菜单").append(Button.create("/dominion menu", "/dominion menu")))
.add(Line.create().append("查看帮助").append(Button.create("/dominion help [页码]", "/dominion help 1")))

View File

@ -4,6 +4,7 @@ import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
import cn.lunadeer.dominion.utils.STUI.View;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -31,15 +32,15 @@ public class DominionManage {
Line privilege_list = Line.create()
.append(Button.create("玩家权限", "/dominion privilege_list " + dominion.getName()))
.append("管理玩家特权");
View view = View.create();
ListView view = ListView.create(10, "/dominion manage " + dominion.getName());
view.title("领地 " + dominion.getName() + " 管理界面")
.navigator(Line.create()
.append(Button.create("主菜单", "/dominion menu"))
.append(Button.create("我的领地", "/dominion list"))
.append(dominion.getName()))
.addLine(size_info)
.addLine(flag_info)
.addLine(privilege_list)
.showOn(player);
.add(size_info)
.add(flag_info)
.add(privilege_list)
.showOn(player, 1);
}
}

View File

@ -1,9 +1,6 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.View;
import cn.lunadeer.dominion.utils.STUI.ViewStyles;
import cn.lunadeer.dominion.utils.STUI.*;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import org.bukkit.command.CommandSender;
@ -28,15 +25,15 @@ public class Menu {
Line reload = Line.create()
.append(Button.create("重载缓存", "/dominion reload_cache"))
.append("手动刷新缓存可解决一些玩家操作无效问题,不建议频繁操作");
View view = View.create();
ListView view = ListView.create(10, "/dominion");
view.title("Dominion 领地系统")
.navigator(Line.create().append("主菜单"))
.addLine(list)
.addLine(help)
.addLine(link);
.add(list)
.add(help)
.add(link);
if (player.isOp()) {
view.addLine(reload);
view.add(reload);
}
view.showOn(player);
view.showOn(player, 1);
}
}

View File

@ -26,7 +26,8 @@ public class SelectPlayer {
}
String dominion_name = args[1];
ListView view = ListView.create(10, "/dominion select_player_create_privilege " + dominion_name);
view.title("选择玩家以创建特权").subtitle("只能选择已经登录过的玩家");
Line sub = Line.create().append("只能选择已经登录过的玩家").append(Button.create("返回", "/dominion privilege_list " + dominion_name));
view.title("选择玩家以创建特权").subtitle(sub);
List<PlayerDTO> players = PlayerController.allPlayers();
for (PlayerDTO p : players) {
if (p.getUuid() == player.getUniqueId()) {

View File

@ -3,6 +3,8 @@ package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Dominion;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.List;
public class ConfigManager {
public ConfigManager(Dominion plugin) {
_plugin = plugin;
@ -21,12 +23,36 @@ public class ConfigManager {
_db_user = _file.getString("Database.User", "postgres");
_db_pass = _file.getString("Database.Pass", "postgres");
_auto_create_radius = _file.getInt("AutoCreateRadius", 10);
_max_x = _file.getInt("MaxX", 128);
_max_y = _file.getInt("MaxY", 64);
_max_z = _file.getInt("MaxZ", 128);
if (_auto_create_radius == 0) {
XLogger.err("AutoCreateRadius 不能等于 0已重置为 10");
setAutoCreateRadius(10);
}
_limit_size_x = _file.getInt("Limit.SizeX", 128);
if (_limit_size_x <= 4) {
XLogger.err("Limit.SizeX 尺寸不能小于 4已重置为 128");
setLimitSizeX(128);
}
_limit_size_y = _file.getInt("Limit.SizeY", 64);
if (_limit_size_y <= 4) {
XLogger.err("Limit.SizeY 尺寸不能小于 4已重置为 64");
setLimitSizeY(64);
}
_limit_size_z = _file.getInt("Limit.SizeZ", 128);
if (_limit_size_z <= 4) {
XLogger.err("Limit.SizeZ 尺寸不能小于 4已重置为 128");
setLimitSizeZ(128);
}
_blue_map = _file.getBoolean("BlueMap", true);
_auto_clean_enable = _file.getBoolean("AutoClean.Enable", false);
_auto_clean_after_days = _file.getInt("AutoClean.AfterDays", 180);
_auto_clean_after_days = _file.getInt("AutoCleanAfterDays", 180);
if (_auto_clean_after_days == 0) {
XLogger.err("AutoCleanAfterDays 不能等于 0已重置为 180");
setAutoCleanAfterDays(180);
}
_limit_min_y = _file.getInt("Limit.MinY", -64);
_limit_max_y = _file.getInt("Limit.MaxY", 320);
_limit_amount = _file.getInt("Limit.Amount", 10);
_limit_depth = _file.getInt("Limit.Depth", 10);
_world_black_list = _file.getStringList("WorldBlackList");
}
public Boolean isDebug() {
@ -70,33 +96,33 @@ public class ConfigManager {
return _db_pass;
}
public Integer getMaxX() {
return _max_x;
public Integer getLimitSizeX() {
return _limit_size_x;
}
public void setMaxX(Integer max_x) {
_max_x = max_x;
_file.set("MaxX", max_x);
public void setLimitSizeX(Integer max_x) {
_limit_size_x = max_x;
_file.set("Limit.SizeX", max_x);
_plugin.saveConfig();
}
public Integer getMaxY() {
return _max_y;
public Integer getLimitSizeY() {
return _limit_size_y;
}
public void setMaxY(Integer max_y) {
_max_y = max_y;
_file.set("MaxY", max_y);
public void setLimitSizeY(Integer max_y) {
_limit_size_y = max_y;
_file.set("Limit.SizeY", max_y);
_plugin.saveConfig();
}
public Integer getMaxZ() {
return _max_z;
public Integer getLimitSizeZ() {
return _limit_size_z;
}
public void setMaxZ(Integer max_z) {
_max_z = max_z;
_file.set("MaxZ", max_z);
public void setLimitSizeZ(Integer max_z) {
_limit_size_z = max_z;
_file.set("Limit.SizeZ", max_z);
_plugin.saveConfig();
}
@ -120,26 +146,60 @@ public class ConfigManager {
_plugin.saveConfig();
}
public Boolean getAutoCleanEnable() {
return _auto_clean_enable;
}
public void setAutoCleanEnable(Boolean auto_clean_enable) {
_auto_clean_enable = auto_clean_enable;
_file.set("AutoClean.Enable", auto_clean_enable);
_plugin.saveConfig();
}
public Integer getAutoCleanAfterDays() {
return _auto_clean_after_days;
}
public void setAutoCleanAfterDays(Integer auto_clean_after_days) {
_auto_clean_after_days = auto_clean_after_days;
_file.set("AutoClean.AfterDays", auto_clean_after_days);
_file.set("AutoCleanAfterDays", auto_clean_after_days);
_plugin.saveConfig();
}
public Integer getLimitMinY() {
return _limit_min_y;
}
public void setLimitMinY(Integer limit_bottom) {
_limit_min_y = limit_bottom;
_file.set("Limit.MinY", limit_bottom);
_plugin.saveConfig();
}
public Integer getLimitMaxY() {
return _limit_max_y;
}
public void setLimitMaxY(Integer limit_top) {
_limit_max_y = limit_top;
_file.set("Limit.MaxY", limit_top);
_plugin.saveConfig();
}
public Integer getLimitAmount() {
return _limit_amount;
}
public void setLimitAmount(Integer limit_amount) {
_limit_amount = limit_amount;
_file.set("Limit.Amount", limit_amount);
_plugin.saveConfig();
}
public Integer getLimitDepth() {
return _limit_depth;
}
public void setLimitDepth(Integer limit_depth) {
_limit_depth = limit_depth;
_file.set("Limit.Depth", limit_depth);
_plugin.saveConfig();
}
public List<String> getWorldBlackList() {
return _world_black_list;
}
private final Dominion _plugin;
private FileConfiguration _file;
@ -153,12 +213,15 @@ public class ConfigManager {
private Integer _auto_create_radius;
private Integer _max_x;
private Integer _max_y;
private Integer _max_z;
private Integer _limit_size_x;
private Integer _limit_size_y;
private Integer _limit_size_z;
private Boolean _blue_map;
private Boolean _auto_clean_enable;
private Integer _auto_clean_after_days;
private Integer _limit_min_y;
private Integer _limit_max_y;
private Integer _limit_amount;
private Integer _limit_depth;
private List<String> _world_black_list;
}

View File

@ -5,14 +5,22 @@ Database:
User: dominion
Pass: dominion
# -1 表示不开启
AutoCreateRadius: 10
MaxX: 128
MaxY: 64
MaxZ: 128
AutoClean:
Enabled: false
AfterDays: 180
# -1 表示不限制
Limit:
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Amount: 10
Depth: 3 # 子领地深度 0不允许子领地 -1不限制
WorldBlackList: []
# -1 表示不开启
AutoCleanAfterDays: 180
BlueMap: true