Compare commits

...

38 Commits

Author SHA1 Message Date
11123822e4 add javadoc addr to doc 2024-10-17 21:04:48 +08:00
3f6b7c8a92 add api as submodule 2024-10-17 21:01:21 +08:00
3b09e6c885 remove api to standalone repo 2024-10-17 20:58:24 +08:00
2d2fb9a233 Enforce some api capabilities. 2024-10-17 15:25:27 +08:00
8e490ec57a Fix NoClassDefFoundError when using BlueMap-5.4 2024-10-15 17:35:39 +08:00
f1116fa281 Add InfoTool, which can be used to query dom info by click 2024-10-14 14:24:24 +08:00
dcf39f4097 add gitea ci-cd script with java 17 2024-10-14 10:48:57 +08:00
76a9b27ebd 优化文档 2024-10-14 01:42:22 +08:00
1b48eba6c7 修复了在1.21+版本下无法打开铁砧文本输入UI的问题 2024-10-12 15:19:13 +08:00
01b329a3e7 增强了DominionDTO的api能力,现支持修改信息 2024-10-12 11:01:49 +08:00
7fff24dacf 更新示例api插件地址 2024-10-11 11:52:03 +08:00
8e251504fa 修复了在迁移领地数据到新服务器后无法索引到世界的问题 2024-10-11 11:06:01 +08:00
5732fe0182 丰富了api的相关文档 javadoc,优化了部分api接口命名 2024-10-10 15:21:19 +08:00
a53733a0fb 修正文档错误 2024-10-09 17:25:43 +08:00
5734c97a58 修复一系列bug:
1. 修复在1.21下的CUI报错;
2. 现支持在1.20.1使用java17运行;
2024-10-09 14:45:59 +08:00
a86ce4624f 补充api javadoc 2024-10-08 10:28:49 +08:00
6f4d716d95 修复了lite不自动下载依赖的问题 2024-10-07 17:51:32 +08:00
9017402d06 修补cicd脚本 2024-10-07 16:38:19 +08:00
af7c4ad6b2 修补cicd脚本 2024-10-07 16:15:51 +08:00
6e57cada94 修补cicd脚本 2024-10-07 16:12:13 +08:00
d287b611ad 精简项目结构,提供两种不同下载版本 2024-10-07 16:10:19 +08:00
7046ef0391 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	build.gradle.kts
2024-10-07 16:09:57 +08:00
9eb69a4ecc 精简项目结构,提供两种不同下载版本 2024-10-07 16:09:10 +08:00
7f4ed745d7 文档增加笨蛋文档地址 2024-10-04 17:12:58 +08:00
7bf81b753d 文档增加示例项目地址 2024-10-04 16:27:59 +08:00
086e468f03 更新了API实现方案以支持扩展更多功能 2024-10-04 15:23:36 +08:00
e0e713c097 修复了spigot下偶发的多并发问题 2024-10-03 23:56:50 +08:00
be496aac0d 配置文件新增支持配置圈地最小限制 #28 2024-10-01 00:23:22 +08:00
ed6dc7c878
Merge pull request #27 from yunshuangqwq/patch-1 2024-09-28 16:27:05 +08:00
云霜
901be9f9af
只改了一个字 global-tp.md
厂里没人闲着无聊看了看文档发现了文档的有一个字错了
原:改
现:该
这下读着顺畅多了
2024-09-28 07:42:05 +08:00
897c6f17fd 新增数据库导入导出功能,便于迁移、备份数据库 2024-09-27 17:54:59 +08:00
ab838c5596 优化 en-us 语言文件除 Messages Config Flags 段落外的所有翻译。 2024-09-25 11:42:46 +08:00
1b2e193280 文档:修改配置文件中的部分默认值 2024-09-24 17:03:38 +08:00
d58b343b7c 修改配置文件中的部分默认值 2024-09-24 17:02:38 +08:00
c132f52f99 领地提示消息新增特殊占位符 #26 #19
- `{OWNER}`:会被自动替换为领地主人的名字;
- `{DOM}`:会被自动替换为领地名称;
2024-09-24 16:56:20 +08:00
5cc0750ee9 文档补充:新增允许配置领地默认提示消息 #26 2024-09-24 16:23:36 +08:00
458fc530df 新增允许配置领地默认提示消息 #26 2024-09-24 16:20:24 +08:00
ca2b42a84d 修复不打开权限组称号无法使用Papi的问题 2024-09-24 15:30:26 +08:00
67 changed files with 1289 additions and 1082 deletions

View File

@ -13,6 +13,12 @@ jobs:
uses: https://ssl.lunadeer.cn:14446/actions/checkout@v3
with:
fetch-depth: 0
- name: "Set up JDK 17"
uses: https://ssl.lunadeer.cn:14446/actions/setup-java@v3
with:
java-version: '17'
distribution: 'zulu'
cache: gradle
- name: "Set up JDK 21"
uses: https://ssl.lunadeer.cn:14446/actions/setup-java@v3
with:
@ -21,9 +27,13 @@ jobs:
cache: gradle
- name: "Build with Gradle"
run: |
./gradlew buildPlugin
- name: "Copy jar to staging"
run: mkdir staging && cp build/libs/*.jar staging/
./gradlew clean
./gradlew shadowJar -PBuildFull=false
./gradlew shadowJar -PBuildFull=true
- name: "Stage"
run: |
mkdir -p staging
mv build/libs/*.jar staging/
- name: "Build & test"
run: |
echo "done!"
@ -36,7 +46,7 @@ jobs:
- name: "Release"
uses: https://ssl.lunadeer.cn:14446/zhangyuheng/release-action@main
with:
note: " - 带 `original-` 前缀的文件无法用于运行,请下载不带此前缀的版本。"
note: " - `full` 后缀包含所有依赖直接安装即可使用,`lite` 后缀不包含任何依赖,会在第一次安装后启动时自动下载"
files: |-
staging/*.jar
api_key: '${{secrets.RELEASE_TOKEN}}'

View File

@ -19,10 +19,14 @@ jobs:
distribution: 'zulu'
cache: gradle
- name: "Build with Gradle"
run: ./gradlew buildPlugin
- name: "Copy jar to staging"
run: |
mkdir staging && cp build/libs/*.jar staging/
./gradlew clean
./gradlew shadowJar -PBuildFull=false
./gradlew shadowJar -PBuildFull=true
- name: "Stage"
run: |
mkdir -p staging
mv build/libs/*.jar staging/
- name: "Build & test"
run: |
TAG=$(echo $GITHUB_REF | sed 's/refs\/tags\///')
@ -46,7 +50,7 @@ jobs:
game_versions: 1.20.1:1.20.6,1.21,1.21.1
version_number: ${{ env.AUTOMATIC_RELEASES_TAG }}
files: |
staging/*.jar
staging/*-lite.jar
changelog: "See https://github.com/ColdeZhang/Dominion/releases/tag/${{ env.AUTOMATIC_RELEASES_TAG }}"
version_type: beta
featured: false
@ -55,5 +59,4 @@ jobs:
- name: "Hangar Release"
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_API_TOKEN }}
run: ./gradlew build publishPluginPublicationToHangar --stacktrace
continue-on-error: true
run: ./gradlew build publishPluginPublicationToHangar -PBuildFull=false

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "api"]
path = api
url = https://github.com/ColdeZhang/DominionAPI.git

View File

@ -30,9 +30,6 @@ For detail functions and features of Dominion, you can view [Introduction](intro
- 1.20.1+ (Bukkit、Spigot、Paper、Folia)
> You need to use Java21 to run your server. If you are still using Java17, you can safely replace it with Java21. In
> theory, version 1.20.1+ can be directly upgraded to Java21.
> Although this plugin supports Spigot, we strongly recommend that you upgrade your core to Paper or its forked (such as
> Purpur) for a better performance experience.

View File

@ -29,9 +29,6 @@ Dominion 是一个完全开源、免费,专为高版本开发,面向未来
- 1.20.1+ (Bukkit、Spigot、Paper、Folia)
> 需要使用 Java21 运行你的服务端,如果你还在使用 Java17 可以放心替换为 Java21理论上 1.20.1+ 版本的服务端核心可以直接升级到
> Java21 启动。
> 虽然本插件支持 Spigot但是我们强烈建议您将您的核心升级到 Paper 或其分支核心(如 Purpur以获得更好的性能体验。
## 帮助我们不断改进

1
api Submodule

@ -0,0 +1 @@
Subproject commit 9a22a3e453ef0391741b6282a5b7f7219bfbbb0c

View File

@ -1,42 +0,0 @@
plugins {
id("java")
id("maven-publish")
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}
// utf-8
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
dependencies {
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
}
tasks.jar {
archiveClassifier.set("sources")
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
groupId = "cn.lunadeer"
artifactId = "DominionAPI"
version = "1.5-SNAPSHOT"
from(components["java"])
}
}
repositories {
maven {
url = uri("https://ssl.lunadeer.cn:14454/repository/maven-snapshots/")
credentials {
// from m2 settings.xml
username = project.findProperty("nexusUsername")?.toString()
password = project.findProperty("nexusPassword")?.toString()
}
}
}
}

View File

@ -1,19 +0,0 @@
package cn.lunadeer.dominion.api;
import org.bukkit.Bukkit;
public class Dominion {
public static DominionAPI getInstance() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
// 通过反射获取 Cache 类中的 instance 字段
var instanceField = Class.forName("cn.lunadeer.dominion.Cache").getDeclaredField("instance");
// 设置可访问
instanceField.setAccessible(true);
// 返回 Cache 的实例
return (DominionAPI) instanceField.get(null);
}
public static boolean isDominionEnabled() {
return Bukkit.getPluginManager().isPluginEnabled("Dominion");
}
}

View File

@ -1,80 +0,0 @@
package cn.lunadeer.dominion.api;
import cn.lunadeer.dominion.api.dtos.DominionDTO;
import cn.lunadeer.dominion.api.dtos.GroupDTO;
import cn.lunadeer.dominion.api.dtos.MemberDTO;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.UUID;
public interface DominionAPI {
/**
* 获取所有领地信息
*
* @return 所有领地信息
*/
@NotNull List<DominionDTO> getAllDominions();
/**
* 获取玩家当前所在领地
*
* @param player 玩家
* @return 玩家当前所在领地 如果玩家不在任何领地内则返回null
*/
@Nullable DominionDTO getPlayerCurrentDominion(@NotNull Player player);
/**
* 获取指定位置的领地信息
*
* @param loc 位置
* @return 领地信息 如果位置不在任何领地内则返回null
*/
@Nullable DominionDTO getDominionByLoc(@NotNull Location loc);
/**
* 根据 ID 获取权限组对象
*
* @param id 权限组 ID
* @return 权限组对象 如果权限组不存在则返回null
*/
@Nullable GroupDTO getGroup(@NotNull Integer id);
/**
* 获取玩家在指定领地的成员信息
*
* @param player 玩家
* @param dominion 领地
* @return 玩家在指定领地的成员信息 如果玩家不属于领地成员则返回null
*/
@Nullable MemberDTO getMember(@NotNull Player player, @NotNull DominionDTO dominion);
/**
* 获取玩家在指定领地的成员信息
*
* @param player_uuid 玩家 UUID
* @param dominion 领地
* @return 玩家在指定领地的成员信息 如果玩家不属于领地成员则返回null
*/
@Nullable MemberDTO getMember(@NotNull UUID player_uuid, @NotNull DominionDTO dominion);
/**
* 获取指定 ID 的领地信息
*
* @param id 领地 ID
* @return 领地信息 如果领地不存在则返回null
*/
@Nullable DominionDTO getDominion(@NotNull Integer id);
/**
* 获取玩家当前正在使用的权限组称号
*
* @param uuid 玩家 UUID
* @return 权限组对象 如果玩家没有使用任何权限组则返回null
*/
@Nullable GroupDTO getPlayerUsingGroupTitle(@NotNull UUID uuid);
}

View File

@ -1,131 +0,0 @@
package cn.lunadeer.dominion.api.dtos;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public interface DominionDTO {
/**
* 获取领地 ID
*
* @return 领地 ID
*/
Integer getId();
/**
* 获取领地所有者 UUID
*
* @return 领地所有者 UUID
*/
UUID getOwner();
/**
* 获取领地名称
*
* @return 领地名称
*/
String getName();
/**
* 获取领地所在世界
*
* @return 领地所在世界 如果世界不存在则返回null
*/
@Nullable World getWorld();
/**
* 获取领地所在世界 UUID
*
* @return 领地所在世界 UUID
*/
UUID getWorldUid();
Integer getX1();
Integer getY1();
Integer getZ1();
Integer getX2();
Integer getY2();
Integer getZ2();
/**
* 获取领地面积
*
* @return 领地面积
*/
Integer getSquare();
/**
* 获取领地体积
*
* @return 领地体积
*/
Integer getVolume();
/**
* 获取领地X轴向东西向宽度
*
* @return 领地X轴向东西向宽度
*/
Integer getWidthX();
/**
* 获取领地Y轴向上下向高度
*
* @return 领地Y轴向上下向高度
*/
Integer getHeight();
/**
* 获取领地Z轴向南北向宽度
*
* @return 领地Z轴向南北向宽度
*/
Integer getWidthZ();
/**
* 获取父领地 ID
*
* @return 父领地 ID 如果没有父领地则返回 -1
*/
Integer getParentDomId();
String getJoinMessage();
String getLeaveMessage();
/**
* 获取领地某个权限的值
*
* @param flag 权限
* @return 权限值
*/
Boolean getFlagValue(Flag flag);
/**
* 获取领地传送点坐标
*
* @return 领地传送点坐标 如果没有设置传送点则返回null
*/
@Nullable Location getTpLocation();
Location getLocation1();
Location getLocation2();
int getColorR();
int getColorG();
int getColorB();
String getColor();
int getColorHex();
}

View File

@ -1,40 +0,0 @@
package cn.lunadeer.dominion.api.dtos;
public interface Flag {
/**
* 权限名称英文
*
* @return 权限名称
*/
String getFlagName();
/**
* 权限显示名称中文
* 该名称从languages文件中加载
*
* @return 权限显示名称
*/
String getDisplayName();
/**
* 权限描述
* 该描述从languages文件中加载
*
* @return 权限描述
*/
String getDescription();
/**
* 获取权限默认值
*
* @return 权限默认值
*/
Boolean getDefaultValue();
/**
* 获取权限是否启用
*
* @return 权限是否启用
*/
Boolean getEnable();
}

View File

@ -1,55 +0,0 @@
package cn.lunadeer.dominion.api.dtos;
import net.kyori.adventure.text.Component;
public interface GroupDTO {
/**
* 获取权限组 ID
*
* @return 权限组 ID
*/
Integer getId();
/**
* 获取权限组所属领地 ID
*
* @return 权限组所属领地 ID
*/
Integer getDomID();
/**
* 获取权限组名称
*
* @return 权限组名称
*/
String getName();
/**
* 获取权限组名称带颜色 kyori.adventure.text.Component
*
* @return 权限组名称带颜色
*/
Component getNameColoredComponent();
/**
* 获取权限组名称带颜色 Bukkit
*
* @return 权限组名称带颜色
*/
String getNameColoredBukkit();
/**
* 获取权限组是否为管理员组
*
* @return 是否为管理员组
*/
Boolean getAdmin();
/**
* 获取权限组某个权限配置
*
* @param flag 权限
* @return 权限配置值
*/
Boolean getFlagValue(Flag flag);
}

View File

@ -1,48 +0,0 @@
package cn.lunadeer.dominion.api.dtos;
import java.util.UUID;
public interface MemberDTO {
/**
* 获取成员 ID
*
* @return 成员 ID
*/
Integer getId();
/**
* 获取成员 UUID
*
* @return 成员 UUID
*/
UUID getPlayerUUID();
/**
* 成员是否为管理员
*
* @return 是否为管理员
*/
Boolean getAdmin();
/**
* 获取成员所属领地 ID
*
* @return 领地 ID
*/
Integer getDomID();
/**
* 获取成员所属权限组 ID
*
* @return 权限组 ID 如果成员不属于任何权限组则返回-1
*/
Integer getGroupId();
/**
* 获取成员某个权限配置
*
* @param flag 权限
* @return 权限配置值
*/
Boolean getFlagValue(Flag flag);
}

View File

@ -6,11 +6,15 @@ plugins {
id("io.papermc.hangar-publish-plugin") version "0.1.2"
}
var BuildFull = properties["BuildFull"].toString() == "true"
var libraries = listOf<String>()
libraries = libraries + "cn.lunadeer:MinecraftPluginUtils:2.0.7"
group = "cn.lunadeer"
version = "2.9.0-beta"
version = "2.14.1-beta"
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
// utf-8
@ -29,7 +33,6 @@ allprojects {
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://jitpack.io")
maven("https://repo.mikeprimm.com/")
maven("https://ssl.lunadeer.cn:14454/repository/maven-snapshots/")
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
}
@ -38,8 +41,15 @@ allprojects {
compileOnly("us.dynmap:DynmapCoreAPI:3.4")
compileOnly("me.clip:placeholderapi:2.11.6")
implementation("cn.lunadeer:MinecraftPluginUtils:1.3.9-SNAPSHOT")
implementation("org.yaml:snakeyaml:2.0")
if (!BuildFull) {
libraries.forEach {
compileOnly(it)
}
} else {
libraries.forEach {
implementation(it)
}
}
}
tasks.processResources {
@ -53,6 +63,15 @@ allprojects {
filter {
it.replace("@version@", rootProject.version.toString())
}
if (!BuildFull) {
var libs = "libraries: ["
libraries.forEach {
libs += "$it,"
}
filter {
it.replace("libraries: [ ]", libs.substring(0, libs.length - 1) + "]")
}
}
}
}
@ -60,6 +79,8 @@ allprojects {
archiveClassifier.set("")
archiveVersion.set(project.version.toString())
dependsOn(tasks.withType<ProcessResources>())
// add -lite to the end of the file name if BuildLite is true or -full if BuildLite is false
archiveFileName.set("${project.name}-${project.version}${if (BuildFull) "-full" else "-lite"}.jar")
}
}
@ -74,7 +95,7 @@ tasks.shadowJar {
archiveVersion.set(project.version.toString())
}
tasks.register("buildPlugin") { // <<<< RUN THIS TASK TO BUILD PLUGIN
tasks.register("Clean&Build") { // <<<< RUN THIS TASK TO BUILD PLUGIN
dependsOn(tasks.clean)
dependsOn(tasks.shadowJar)
}

View File

@ -3,7 +3,7 @@ plugins {
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
// utf-8

View File

@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicLong;
import static cn.lunadeer.dominion.DominionNode.getLocInDominionNode;
import static cn.lunadeer.dominion.DominionNode.isInDominion;
public class Cache implements DominionAPI {
public class Cache {
public Cache() {
player_current_dominion_id = new HashMap<>();
@ -206,7 +206,6 @@ public class Cache implements DominionAPI {
});
}
@Override
public DominionDTO getPlayerCurrentDominion(@NotNull Player player) {
try (AutoTimer ignored = new AutoTimer(Dominion.config.TimerEnabled())) {
Integer last_in_dom_id = player_current_dominion_id.get(player.getUniqueId());
@ -232,10 +231,18 @@ public class Cache implements DominionAPI {
return last_dominion;
}
if (last_dom_id != -1) {
MessageDisplay.show(player, Dominion.config.getMessageDisplayJoinLeave(), last_dominion.getLeaveMessage());
MessageDisplay.show(player, Dominion.config.getMessageDisplayJoinLeave(),
last_dominion.getLeaveMessage()
.replace("{DOM}", last_dominion.getName())
.replace("{OWNER}", getPlayerName(last_dominion.getOwner()))
);
}
if (current_dom_id != -1) {
MessageDisplay.show(player, Dominion.config.getMessageDisplayJoinLeave(), current_dominion.getJoinMessage());
MessageDisplay.show(player, Dominion.config.getMessageDisplayJoinLeave(),
current_dominion.getJoinMessage()
.replace("{DOM}", current_dominion.getName())
.replace("{OWNER}", getPlayerName(current_dominion.getOwner()))
);
}
lightOrNot(player, current_dominion); // 发光检查
@ -253,7 +260,6 @@ public class Cache implements DominionAPI {
}
}
@Override
public DominionDTO getDominionByLoc(@NotNull Location loc) {
return dominion_trees.getLocInDominionDTO(loc);
}
@ -337,18 +343,15 @@ public class Cache implements DominionAPI {
}
}
@Override
public GroupDTO getGroup(@NotNull Integer id) {
return id_groups.get(id);
}
@Override
public MemberDTO getMember(@NotNull Player player, cn.lunadeer.dominion.api.dtos.@NotNull DominionDTO dominion) {
if (!player_uuid_to_member.containsKey(player.getUniqueId())) return null;
return player_uuid_to_member.get(player.getUniqueId()).get(dominion.getId());
}
@Override
public MemberDTO getMember(@NotNull UUID player_uuid, cn.lunadeer.dominion.api.dtos.@NotNull DominionDTO dominion) {
if (!player_uuid_to_member.containsKey(player_uuid)) return null;
return player_uuid_to_member.get(player_uuid).get(dominion.getId());
@ -368,11 +371,20 @@ public class Cache implements DominionAPI {
return groups;
}
@Override
public DominionDTO getDominion(@NotNull Integer id) {
return id_dominions.get(id);
}
public String getPlayerName(UUID uuid) {
if (!player_name_cache.containsKey(uuid)) {
PlayerDTO playerDTO = PlayerDTO.select(uuid);
if (playerDTO != null) {
player_name_cache.put(uuid, playerDTO.getLastKnownName());
}
}
return player_name_cache.getOrDefault(uuid, "Unknown");
}
public int getPlayerDominionCount(UUID player_uuid) {
int count = 0;
for (DominionDTO dominion : id_dominions.values()) {
@ -402,7 +414,6 @@ public class Cache implements DominionAPI {
return residence_data.get(player_uuid);
}
@Override
public @NotNull List<cn.lunadeer.dominion.api.dtos.DominionDTO> getAllDominions() {
return new ArrayList<>(id_dominions.values());
}
@ -439,6 +450,7 @@ public class Cache implements DominionAPI {
private static final long UPDATE_INTERVAL = 1000 * 4;
private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态发光飞行
public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>();
private final Map<UUID, String> player_name_cache = new HashMap<>();
private Map<UUID, List<ResMigration.ResidenceNode>> residence_data = null;
@ -582,7 +594,6 @@ public class Cache implements DominionAPI {
}
}
@Override
public @Nullable GroupDTO getPlayerUsingGroupTitle(@NotNull UUID uuid) {
if (!Dominion.config.getGroupTitleEnable()) {
return null;

View File

@ -118,6 +118,12 @@ public class Commands implements TabExecutor {
case "export_mca":
Operator.exportMca(sender, args);
break;
case "export_db":
Operator.exportDatabase(sender, args);
break;
case "import_db":
Operator.importDatabase(sender, args);
break;
// case "set_config":
// SetConfig.handler(sender, args);
// break;
@ -216,6 +222,9 @@ public class Commands implements TabExecutor {
"reload_cache",
"reload_config",
"export_mca",
"export_db",
"import_db",
"version",
"sys_config",
"all_dominion",
"set_map_color",

View File

@ -39,15 +39,15 @@ public final class Dominion extends JavaPlugin {
new Scheduler(this);
AutoClean.run();
Cache.instance = new Cache();
DominionInterface.instance = new DominionInterface();
if (config.getGroupTitleEnable()) {
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
new PlaceHolderApi(this);
} else {
}
if (config.getGroupTitleEnable() && !Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
XLogger.warn(Translation.Messages_PlaceholderAPINotFound);
config.setGroupTitleEnable(false);
}
}
new EventsRegister(this);
Objects.requireNonNull(Bukkit.getPluginCommand("dominion")).setExecutor(new Commands());

View File

@ -0,0 +1,76 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.api.DominionAPI;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class DominionInterface implements DominionAPI {
public static DominionInterface instance;
@Override
public DominionDTO getPlayerCurrentDominion(@NotNull Player player) {
return Cache.instance.getPlayerCurrentDominion(player);
}
@Override
public DominionDTO getDominionByLoc(@NotNull Location loc) {
return Cache.instance.getDominionByLoc(loc);
}
@Override
public GroupDTO getGroup(@NotNull Integer id) {
return Cache.instance.getGroup(id);
}
@Override
public MemberDTO getMember(@NotNull Player player, cn.lunadeer.dominion.api.dtos.@NotNull DominionDTO dominion) {
return Cache.instance.getMember(player.getUniqueId(), dominion);
}
@Override
public MemberDTO getMember(@NotNull UUID player_uuid, cn.lunadeer.dominion.api.dtos.@NotNull DominionDTO dominion) {
return Cache.instance.getMember(player_uuid, dominion);
}
@Override
public DominionDTO getDominion(@NotNull Integer id) {
return Cache.instance.getDominion(id);
}
@Override
public @NotNull List<cn.lunadeer.dominion.api.dtos.DominionDTO> getAllDominions() {
return Cache.instance.getAllDominions();
}
@Override
public @Nullable GroupDTO getPlayerUsingGroupTitle(@NotNull UUID uuid) {
return Cache.instance.getPlayerUsingGroupTitle(uuid);
}
@Override
public @NotNull List<cn.lunadeer.dominion.api.dtos.Flag> getEnvironmentFlagsEnabled() {
return new ArrayList<>(Flag.getEnvironmentFlagsEnabled());
}
@Override
public @NotNull List<cn.lunadeer.dominion.api.dtos.Flag> getPrivilegeFlagsEnabled() {
return new ArrayList<>(Flag.getPrivilegeFlagsEnabled());
}
@Override
public cn.lunadeer.dominion.api.dtos.@Nullable Flag getFlagByName(@NotNull String flagName) {
return Flag.getFlag(flagName);
}
}

View File

@ -44,7 +44,7 @@ public class Helper {
if (dominion == null) return groups_name;
List<GroupDTO> groups = GroupDTO.selectByDominionId(dominion.getId());
for (GroupDTO group : groups) {
groups_name.add(group.getName());
groups_name.add(group.getNamePlain());
}
return groups_name;
}

View File

@ -3,6 +3,7 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.api.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.DatabaseTables;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.utils.map.MapRender;
import cn.lunadeer.minecraftpluginutils.GiteaReleaseCheck;
@ -140,6 +141,42 @@ public class Operator {
});
}
/**
* 导出数据库
* /dominion export_db [confirm]
*
* @param sender 发送者
* @param args 参数
*/
public static void exportDatabase(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.admin")) {
return;
}
if (args.length != 2 || !args[1].equals("confirm")) {
Notification.warn(sender, Translation.Commands_Operator_ExportDBConfirm);
return;
}
DatabaseTables.Export(sender);
}
/**
* 导入数据库
* /dominion import_db [confirm]
*
* @param sender 发送者
* @param args 参数
*/
public static void importDatabase(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.admin")) {
return;
}
if (args.length != 2 || !args[1].equals("confirm")) {
Notification.warn(sender, Translation.Commands_Operator_ImportDBConfirm);
return;
}
DatabaseTables.Import(sender);
}
public static void version(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.admin")) {
return;

View File

@ -43,7 +43,7 @@ public class Title {
}
DominionDTO dominion = Cache.instance.getDominion(group.getDomID());
if (dominion == null) {
Notification.error(sender, Translation.Commands_Title_GroupDominionNotExist, group.getName());
Notification.error(sender, Translation.Commands_Title_GroupDominionNotExist, group.getNamePlain());
return;
}
if (!dominion.getOwner().equals(bukkit_player.getUniqueId())) {
@ -53,12 +53,12 @@ public class Title {
return;
}
if (!Objects.equals(member.getGroupId(), group.getId())) {
Notification.error(sender, Translation.Commands_Title_NotGroupMember, group.getName());
Notification.error(sender, Translation.Commands_Title_NotGroupMember, group.getNamePlain());
return;
}
}
player.setUsingGroupTitleID(group.getId());
Notification.info(sender, Translation.Commands_Title_UseTitleSuccess, group.getName());
Notification.info(sender, Translation.Commands_Title_UseTitleSuccess, group.getNamePlain());
}
int page = getPage(args, 2);
TitleList.show(sender, page);

View File

@ -727,20 +727,28 @@ public class DominionController {
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) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeShouldBeGreaterThan4));
if (x_length < Dominion.config.getLimitSizeMinX(operator.getPlayer())) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeXShouldBeGreaterThan, Dominion.config.getLimitSizeMinX(operator.getPlayer())));
return true;
}
if (x_length > Dominion.config.getLimitSizeX(operator.getPlayer()) && Dominion.config.getLimitSizeX(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeXShouldBeLessThan, Dominion.config.getLimitSizeX(operator.getPlayer())));
if (y_length < Dominion.config.getLimitSizeMinY(operator.getPlayer())) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeYShouldBeGreaterThan, Dominion.config.getLimitSizeMinY(operator.getPlayer())));
return true;
}
if (y_length > Dominion.config.getLimitSizeY(operator.getPlayer()) && Dominion.config.getLimitSizeY(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeYShouldBeLessThan, Dominion.config.getLimitSizeY(operator.getPlayer())));
if (z_length < Dominion.config.getLimitSizeMinZ(operator.getPlayer())) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeZShouldBeGreaterThan, Dominion.config.getLimitSizeMinZ(operator.getPlayer())));
return true;
}
if (z_length > Dominion.config.getLimitSizeZ(operator.getPlayer()) && Dominion.config.getLimitSizeZ(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeZShouldBeLessThan, Dominion.config.getLimitSizeZ(operator.getPlayer())));
if (x_length > Dominion.config.getLimitSizeMaxX(operator.getPlayer()) && Dominion.config.getLimitSizeMaxX(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeXShouldBeLessThan, Dominion.config.getLimitSizeMaxX(operator.getPlayer())));
return true;
}
if (y_length > Dominion.config.getLimitSizeMaxY(operator.getPlayer()) && Dominion.config.getLimitSizeMaxY(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeYShouldBeLessThan, Dominion.config.getLimitSizeMaxY(operator.getPlayer())));
return true;
}
if (z_length > Dominion.config.getLimitSizeMaxZ(operator.getPlayer()) && Dominion.config.getLimitSizeMaxZ(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.addMessage(Translation.Messages_SizeZShouldBeLessThan, Dominion.config.getLimitSizeMaxZ(operator.getPlayer())));
return true;
}
if (y2 > Dominion.config.getLimitMaxY(operator.getPlayer())) {

View File

@ -71,7 +71,7 @@ public class MemberController {
}
GroupDTO group = GroupDTO.select(privilege.getGroupId());
if (group != null) {
operator.setResponse(FAIL.addMessage(Translation.Messages_PlayerBelongToGroup, player_name, group.getName()));
operator.setResponse(FAIL.addMessage(Translation.Messages_PlayerBelongToGroup, player_name, group.getNamePlain()));
return;
}
if ((flag.equals("admin") || isAdmin(privilege)) && notOwner(operator, dominion)) {

View File

@ -11,6 +11,7 @@ import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -89,7 +90,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
String sql = "SELECT * FROM dominion WHERE id = ? AND id > 0;";
List<DominionDTO> dominions = query(sql, id);
if (dominions.isEmpty()) return null;
return dominions.getFirst();
return dominions.get(0);
}
public static List<DominionDTO> selectByParentId(World world, Integer parentId) {
@ -113,7 +114,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
String sql = "SELECT * FROM dominion WHERE name = ? AND id > 0;";
List<DominionDTO> dominions = query(sql, name);
if (dominions.isEmpty()) return null;
return dominions.getFirst();
return dominions.get(0);
}
public static DominionDTO insert(DominionDTO dominion) {
@ -133,7 +134,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
Cache.instance.loadDominions();
List<DominionDTO> dominions = getDTOFromRS(rs);
if (dominions.isEmpty()) return null;
return dominions.getFirst();
return dominions.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("DominionDTO.insert ", e, insert.toString());
return null;
@ -186,6 +187,8 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
this.y2.value = y2;
this.z2.value = z2;
this.parentDomId.value = parentDomId;
this.joinMessage.value = Dominion.config.getDefaultJoinMessage();
this.leaveMessage.value = Dominion.config.getDefaultLeaveMessage();
}
public DominionDTO(UUID owner, String name, @NotNull World world,
@ -208,8 +211,8 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
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", "欢迎!");
private final Field leaveMessage = new Field("leave_message", "欢迎下次光临~");
private final Field joinMessage = new Field("join_message", "");
private final Field leaveMessage = new Field("leave_message", "");
private final Map<Flag, Boolean> flags = new HashMap<>();
private final Field tp_location = new Field("tp_location", "default");
private final Field color = new Field("color", "#00BFFF");
@ -218,12 +221,12 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
// getters and setters
@Override
public Integer getId() {
public @NotNull Integer getId() {
return (Integer) id.value;
}
@Override
public UUID getOwner() {
public @NotNull UUID getOwner() {
return UUID.fromString((String) owner.value);
}
@ -235,23 +238,31 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
List<DominionDTO> dominions = getDTOFromRS(rs);
if (dominions.isEmpty()) return null;
Cache.instance.loadDominions((Integer) id.value);
return dominions.getFirst();
return dominions.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("DominionDTO.doUpdate ", e, updateRow.toString());
return null;
}
}
@Override
public DominionDTO setOwner(UUID owner) {
this.owner.value = owner.toString();
return doUpdate(new UpdateRow().field(this.owner));
}
@Override
public String getName() {
public DominionDTO setOwner(Player owner) {
this.owner.value = owner.getUniqueId().toString();
return doUpdate(new UpdateRow().field(this.owner));
}
@Override
public @NotNull String getName() {
return (String) name.value;
}
@Override
public DominionDTO setName(String name) {
this.name.value = name;
return doUpdate(new UpdateRow().field(this.name));
@ -263,12 +274,12 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public UUID getWorldUid() {
public @NotNull UUID getWorldUid() {
return UUID.fromString((String) world_uid.value);
}
@Override
public Integer getX1() {
public @NotNull Integer getX1() {
return (Integer) x1.value;
}
@ -278,7 +289,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Integer getY1() {
public @NotNull Integer getY1() {
return (Integer) y1.value;
}
@ -288,7 +299,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Integer getZ1() {
public @NotNull Integer getZ1() {
return (Integer) z1.value;
}
@ -298,7 +309,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Integer getX2() {
public @NotNull Integer getX2() {
return (Integer) x2.value;
}
@ -308,7 +319,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Integer getY2() {
public @NotNull Integer getY2() {
return (Integer) y2.value;
}
@ -318,7 +329,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Integer getZ2() {
public @NotNull Integer getZ2() {
return (Integer) z2.value;
}
@ -328,67 +339,84 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Integer getSquare() {
public @NotNull Integer getSquare() {
return getWidthX() * getWidthZ();
}
@Override
public Integer getVolume() {
public @NotNull Integer getVolume() {
return getSquare() * getHeight();
}
@Override
public Integer getWidthX() {
public @NotNull Integer getWidthX() {
return getX2() - getX1();
}
@Override
public Integer getHeight() {
public @NotNull Integer getHeight() {
return getY2() - getY1();
}
@Override
public Integer getWidthZ() {
public @NotNull Integer getWidthZ() {
return getZ2() - getZ1();
}
@Override
public Integer getParentDomId() {
public @NotNull Integer getParentDomId() {
return (Integer) parentDomId.value;
}
@Override
public String getJoinMessage() {
public @NotNull String getJoinMessage() {
return (String) joinMessage.value;
}
@Override
public DominionDTO setJoinMessage(String joinMessage) {
this.joinMessage.value = joinMessage;
return doUpdate(new UpdateRow().field(this.joinMessage));
}
@Override
public String getLeaveMessage() {
public @NotNull String getLeaveMessage() {
return (String) leaveMessage.value;
}
@Override
public DominionDTO setLeaveMessage(String leaveMessage) {
this.leaveMessage.value = leaveMessage;
return doUpdate(new UpdateRow().field(this.leaveMessage));
}
@Override
public Boolean getFlagValue(Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public DominionDTO setFlagValue(Flag flag, Boolean value) {
@Override
public @NotNull Map<Flag, Boolean> getEnvironmentFlagValue() {
return flags.entrySet().stream()
.filter(e -> e.getKey().isEnvironmentFlag())
.collect(HashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), HashMap::putAll);
}
@Override
public @NotNull Map<Flag, Boolean> getGuestPrivilegeFlagValue() {
return flags.entrySet().stream()
.filter(e -> !e.getKey().isEnvironmentFlag())
.collect(HashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), HashMap::putAll);
}
@Override
public DominionDTO setFlagValue(@NotNull Flag flag, @NotNull Boolean value) {
flags.put(flag, value);
Field flagField = new Field(flag.getFlagName(), value);
return doUpdate(new UpdateRow().field(flagField));
}
@Override
public DominionDTO setXYZ(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this.x1.value = x1;
this.y1.value = y1;
@ -396,9 +424,25 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
if (x1 > x2) {
int tmp = x1;
this.x1.value = x2;
this.x2.value = tmp;
}
if (y1 > y2) {
int tmp = y1;
this.y1.value = y2;
this.y2.value = tmp;
}
if (z1 > z2) {
int tmp = z1;
this.z1.value = z2;
this.z2.value = tmp;
}
return doUpdate(new UpdateRow().field(this.x1).field(this.y1).field(this.z1).field(this.x2).field(this.y2).field(this.z2));
}
@Override
public DominionDTO setXYZ(int[] cords) {
if (cords.length == 6) {
return setXYZ(cords[0], cords[1], cords[2], cords[3], cords[4], cords[5]);
@ -433,12 +477,12 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public Location getLocation1() {
public @NotNull Location getLocation1() {
return new Location(getWorld(), getX1(), getY1(), getZ1());
}
@Override
public Location getLocation2() {
public @NotNull Location getLocation2() {
return new Location(getWorld(), getX2(), getY2(), getZ2());
}
@ -463,7 +507,7 @@ public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
}
@Override
public String getColor() {
public @NotNull String getColor() {
return (String) color.value;
}

View File

@ -7,6 +7,7 @@ import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.i18n.Localization;
import com.alibaba.fastjson.JSONObject;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
@ -102,30 +103,35 @@ public enum Flag implements cn.lunadeer.dominion.api.dtos.Flag {
}
@Override
public String getFlagName() {
public @NotNull String getFlagName() {
return flag_name;
}
@Override
public String getDisplayName() {
public @NotNull String getDisplayName() {
return display_name;
}
@Override
public String getDescription() {
public @NotNull String getDescription() {
return description;
}
@Override
public Boolean getDefaultValue() {
public @NotNull Boolean getDefaultValue() {
return default_value;
}
@Override
public Boolean getEnable() {
public @NotNull Boolean getEnable() {
return enable;
}
@Override
public @NotNull Boolean isEnvironmentFlag() {
return dominion_only;
}
public void setDisplayName(String displayName) {
this.display_name = displayName;
}
@ -154,7 +160,24 @@ public enum Flag implements cn.lunadeer.dominion.api.dtos.Flag {
return Arrays.asList(Flag.values());
}
public static List<Flag> getDominionOnlyFlagsEnabled() {
public static List<Flag> getDominionFlagsEnabled() {
List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) {
if (!flag.enable) {
continue;
}
flags.add(flag);
}
Comparator<Object> comparator = Collator.getInstance(java.util.Locale.CHINA);
flags.sort((o1, o2) -> comparator.compare(o1.getDisplayName(), o2.getDisplayName()));
return flags;
}
public static boolean isDominionOnlyFlag(String flagName) {
return getFlag(flagName).dominion_only;
}
public static List<Flag> getEnvironmentFlagsEnabled() {
List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) {
if (!flag.dominion_only) {
@ -170,28 +193,6 @@ public enum Flag implements cn.lunadeer.dominion.api.dtos.Flag {
return flags;
}
public static boolean isDominionOnlyFlag(String flagName) {
return getFlag(flagName).dominion_only;
}
public static List<Flag> getDominionFlagsEnabled() {
List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) {
if (!flag.enable) {
continue;
}
flags.add(flag);
}
Comparator<Object> comparator = Collator.getInstance(java.util.Locale.CHINA);
flags.sort((o1, o2) -> comparator.compare(o1.getDisplayName(), o2.getDisplayName()));
return flags;
}
public static List<Flag> getAllDominionFlags() {
return new ArrayList<>(Arrays.asList(Flag.values()));
}
public static List<Flag> getPrivilegeFlagsEnabled() {
List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) {
@ -208,6 +209,10 @@ public enum Flag implements cn.lunadeer.dominion.api.dtos.Flag {
return flags;
}
public static List<Flag> getAllDominionFlags() {
return new ArrayList<>(Arrays.asList(Flag.values()));
}
public static List<Flag> getAllPrivilegeFlags() {
List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) {

View File

@ -10,6 +10,8 @@ import cn.lunadeer.minecraftpluginutils.databse.FieldType;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
import java.util.ArrayList;
@ -21,72 +23,88 @@ public class GroupDTO implements cn.lunadeer.dominion.api.dtos.GroupDTO {
Field id = new Field("id", FieldType.INT);
Field domID = new Field("dom_id", FieldType.INT);
Field name = new Field("name", FieldType.STRING);
Field name_raw = new Field("name", FieldType.STRING);
Field admin = new Field("admin", FieldType.BOOLEAN);
Field name_colored = new Field("name_colored", FieldType.STRING);
Field name_color = new Field("name_colored", FieldType.STRING);
private final Map<Flag, Boolean> flags = new HashMap<>();
@Override
public Integer getId() {
public @NotNull Integer getId() {
return (Integer) id.value;
}
@Override
public Integer getDomID() {
public @NotNull Integer getDomID() {
return (Integer) domID.value;
}
@Override
public String getName() {
return (String) name.value;
public @NotNull String getNameRaw() {
return (String) name_color.value;
}
@Override
public Component getNameColoredComponent() {
public @NotNull String getNamePlain() {
return (String) name_raw.value;
}
@Override
public @NotNull Component getNameColoredComponent() {
String with_pre_suf = "&#ffffff" +
Dominion.config.getGroupTitlePrefix() +
(String) name_colored.value +
(String) name_color.value +
"&#ffffff" +
Dominion.config.getGroupTitleSuffix();
return ColorParser.getComponentType(with_pre_suf);
}
@Override
public String getNameColoredBukkit() {
public @NotNull String getNameColoredBukkit() {
String with_pre_suf = "&#ffffff" +
Dominion.config.getGroupTitlePrefix() +
(String) name_colored.value +
(String) name_color.value +
"&#ffffff" +
Dominion.config.getGroupTitleSuffix();
return ColorParser.getBukkitType(with_pre_suf);
}
@Override
public Boolean getAdmin() {
public @NotNull Boolean getAdmin() {
return (Boolean) admin.value;
}
@Override
public Boolean getFlagValue(Flag flag) {
public @NotNull Boolean getFlagValue(@NotNull Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public GroupDTO setName(String name) {
this.name_colored.value = name;
this.name.value = ColorParser.getPlainText(name);
UpdateRow updateRow = new UpdateRow().field(this.name).field(this.name_colored);
@Override
public @NotNull Map<Flag, Boolean> getFlagsValue() {
return flags;
}
@Override
public @Nullable GroupDTO setName(@NotNull String name) {
this.name_color.value = name;
this.name_raw.value = ColorParser.getPlainText(name);
UpdateRow updateRow = new UpdateRow().field(this.name_raw).field(this.name_color);
return doUpdate(updateRow);
}
public GroupDTO setAdmin(Boolean admin) {
@Override
public @Nullable GroupDTO setAdmin(@NotNull Boolean admin) {
this.admin.value = admin;
UpdateRow updateRow = new UpdateRow().field(this.admin);
return doUpdate(updateRow);
}
public GroupDTO setFlagValue(Flag flag, Boolean value) {
@Override
public GroupDTO setFlagValue(@NotNull Flag flag, @NotNull Boolean value) {
if (flag.isEnvironmentFlag()) {
return null;
}
flags.put(flag, value);
Field f = new Field(flag.getFlagName(), value);
UpdateRow updateRow = new UpdateRow().field(f);
@ -98,17 +116,17 @@ public class GroupDTO implements cn.lunadeer.dominion.api.dtos.GroupDTO {
InsertRow insertRow = new InsertRow().returningAll().onConflictDoNothing(new Field("id", null));
insertRow.table("dominion_group")
.field(group.domID)
.field(group.name)
.field(group.name_raw)
.field(group.admin)
.field(group.name_colored);
.field(group.name_color);
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
insertRow.field(new Field(f.getFlagName(), dominionDTO.getFlagValue(f)));
}
try (ResultSet rs = insertRow.execute()) {
List<GroupDTO> groups = getDTOFromRS(rs);
if (groups.isEmpty()) return null;
Cache.instance.loadGroups(groups.getFirst().getId());
return groups.getFirst();
Cache.instance.loadGroups(groups.get(0).getId());
return groups.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("GroupDTO.create ", e, "");
return null;
@ -133,14 +151,14 @@ public class GroupDTO implements cn.lunadeer.dominion.api.dtos.GroupDTO {
String sql = "SELECT * FROM dominion_group WHERE id = ?;";
List<GroupDTO> groups = getDTOFromRS(DatabaseManager.instance.query(sql, id));
if (groups.isEmpty()) return null;
return groups.getFirst();
return groups.get(0);
}
public static GroupDTO select(Integer domID, String name) {
String sql = "SELECT * FROM dominion_group WHERE dom_id = ? AND name = ?;";
List<GroupDTO> groups = getDTOFromRS(DatabaseManager.instance.query(sql, domID, name));
if (groups.isEmpty()) return null;
return groups.getFirst();
return groups.get(0);
}
public static List<GroupDTO> selectAll() {
@ -155,8 +173,8 @@ public class GroupDTO implements cn.lunadeer.dominion.api.dtos.GroupDTO {
private GroupDTO(String name, Integer domID) {
this.domID.value = domID;
this.name.value = ColorParser.getPlainText(name);
this.name_colored.value = name;
this.name_raw.value = ColorParser.getPlainText(name);
this.name_color.value = name;
this.admin.value = false;
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, f.getDefaultValue());
@ -166,10 +184,10 @@ public class GroupDTO implements cn.lunadeer.dominion.api.dtos.GroupDTO {
private GroupDTO(Integer id, Integer domID, String name, Boolean admin, Map<Flag, Boolean> flags, String nameColored) {
this.id.value = id;
this.domID.value = domID;
this.name.value = name;
this.name_raw.value = name;
this.admin.value = admin;
this.flags.putAll(flags);
this.name_colored.value = nameColored;
this.name_color.value = nameColored;
}
private static List<GroupDTO> getDTOFromRS(ResultSet rs) {
@ -205,7 +223,7 @@ public class GroupDTO implements cn.lunadeer.dominion.api.dtos.GroupDTO {
List<GroupDTO> groups = getDTOFromRS(rs);
if (groups.isEmpty()) return null;
Cache.instance.loadGroups((Integer) id.value);
return groups.getFirst();
return groups.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("更新权限组失败: ", e, "");
return null;

View File

@ -7,6 +7,8 @@ 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.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
import java.util.*;
@ -56,7 +58,7 @@ public class MemberDTO implements cn.lunadeer.dominion.api.dtos.MemberDTO {
List<MemberDTO> players = getDTOFromRS(rs);
if (players.isEmpty()) return null;
Cache.instance.loadMembers(getPlayerUUID());
return players.getFirst();
return players.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("MemberDTO.doUpdate ", e, "");
return null;
@ -76,7 +78,7 @@ public class MemberDTO implements cn.lunadeer.dominion.api.dtos.MemberDTO {
Cache.instance.loadMembers(player.getPlayerUUID());
List<MemberDTO> players = getDTOFromRS(rs);
if (players.isEmpty()) return null;
return players.getFirst();
return players.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("MemberDTO.insert ", e, "");
return null;
@ -87,7 +89,7 @@ public class MemberDTO implements cn.lunadeer.dominion.api.dtos.MemberDTO {
String sql = "SELECT * FROM dominion_member WHERE player_uuid = ? AND dom_id = ?;";
List<MemberDTO> p = query(sql, playerUUID.toString(), dom_id);
if (p.isEmpty()) return null;
return p.getFirst();
return p.get(0);
}
public static List<MemberDTO> select(Integer dom_id) {
@ -155,19 +157,29 @@ public class MemberDTO implements cn.lunadeer.dominion.api.dtos.MemberDTO {
private final Map<Flag, Boolean> flags = new HashMap<>();
@Override
public Boolean getFlagValue(Flag flag) {
public @NotNull Boolean getFlagValue(Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public MemberDTO setFlagValue(Flag flag, Boolean value) {
@Override
public @NotNull Map<Flag, Boolean> getFlagsValue() {
return flags;
}
@Override
public MemberDTO setFlagValue(@NotNull Flag flag, @NotNull Boolean value) {
if (flag.isEnvironmentFlag()) {
return null;
}
flags.put(flag, value);
Field f = new Field(flag.getFlagName(), value);
UpdateRow updateRow = new UpdateRow().field(f);
return doUpdate(updateRow);
}
public MemberDTO setAdmin(Boolean admin) {
@Override
public @Nullable MemberDTO setAdmin(@NotNull Boolean admin) {
this.admin.value = admin;
UpdateRow updateRow = new UpdateRow().field(this.admin);
return doUpdate(updateRow);
@ -203,9 +215,7 @@ public class MemberDTO implements cn.lunadeer.dominion.api.dtos.MemberDTO {
this.playerUUID.value = playerUUID.toString();
this.admin.value = false;
this.domID.value = dom.getId();
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
this.flags.put(f, dom.getFlagValue(f));
}
this.flags.putAll(dom.getGuestPrivilegeFlagValue());
}
}

View File

@ -77,14 +77,14 @@ public class PlayerDTO {
String sql = "SELECT * FROM player_name WHERE uuid = ?;";
List<PlayerDTO> players = query(sql, uuid.toString());
if (players.isEmpty()) return null;
return players.getFirst();
return players.get(0);
}
public static PlayerDTO select(String name) {
String sql = "SELECT * FROM player_name WHERE last_known_name = ?;";
List<PlayerDTO> players = query(sql, name);
if (players.isEmpty()) return null;
return players.getFirst();
return players.get(0);
}
public static List<PlayerDTO> search(String name) {
@ -114,7 +114,7 @@ public class PlayerDTO {
try (ResultSet rs = insertRow.execute()) {
List<PlayerDTO> players = getDTOFromRS(rs);
if (players.isEmpty()) return null;
return players.getFirst();
return players.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("PlayerDTO.insert ", e, insertRow.toString());
return null;
@ -136,7 +136,7 @@ public class PlayerDTO {
try (ResultSet rs = updateRow.execute()) {
List<PlayerDTO> players = getDTOFromRS(rs);
if (players.isEmpty()) return null;
return players.getFirst();
return players.get(0);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("PlayerDTO.update ", e, updateRow.toString());
return null;

View File

@ -55,7 +55,7 @@ public class PrivilegeTemplateDTO {
try (ResultSet rs = insertRow.execute()) {
List<PrivilegeTemplateDTO> templates = getDTOFromRS(rs);
if (templates.isEmpty()) return null;
return templates.getFirst();
return templates.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("PrivilegeTemplateDTO.create ", e, null);
return null;
@ -70,7 +70,7 @@ public class PrivilegeTemplateDTO {
try (ResultSet rs = updateRow.execute()) {
List<PrivilegeTemplateDTO> templates = getDTOFromRS(rs);
if (templates.isEmpty()) return null;
return templates.getFirst();
return templates.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("PrivilegeTemplateDTO.doUpdate ", e, null);
return null;
@ -81,7 +81,7 @@ public class PrivilegeTemplateDTO {
String sql = "SELECT * FROM privilege_template WHERE creator = ? AND name = ?;";
List<PrivilegeTemplateDTO> templates = query(sql, creator.toString(), name);
if (templates.isEmpty()) return null;
return templates.getFirst();
return templates.get(0);
}
public static List<PrivilegeTemplateDTO> selectAll(UUID creator) {

View File

@ -41,6 +41,8 @@ public class ConfigManager {
_db_pass = _file.getString("Database.Pass", "postgres");
_auto_create_radius = _file.getInt("AutoCreateRadius", 10);
_default_join_message = _file.getString("DefaultJoinMessage", "&3{OWNER}: Welcome to {DOM}!");
_default_leave_message = _file.getString("DefaultLeaveMessage", "&3{OWNER}: Leaving {DOM}...");
_message_display_no_permission = _file.getString("MessageDisplay.NoPermission", "ACTION_BAR");
_message_display_join_leave = _file.getString("MessageDisplay.JoinLeave", "ACTION_BAR");
@ -55,6 +57,7 @@ public class ConfigManager {
_tp_delay = _file.getInt("Teleport.Delay", 0);
_tp_cool_down = _file.getInt("Teleport.CoolDown", 0);
_tool = _file.getString("Tool", "ARROW");
_info_tool = _file.getString("InfoTool", "STRING");
_economy_enable = _file.getBoolean("Economy.Enable", false);
if (getEconomyEnable()) {
@ -67,9 +70,21 @@ public class ConfigManager {
_group_title_suffix = _file.getString("GroupTitle.Suffix", "&#ffffff]");
GroupLimit defaultGroup = new GroupLimit();
defaultGroup.setLimitSizeX(_file.getInt("Limit.SizeX", 128), null);
defaultGroup.setLimitSizeY(_file.getInt("Limit.SizeY", 64), null);
defaultGroup.setLimitSizeZ(_file.getInt("Limit.SizeZ", 128), null);
if (_file.contains("Limit.SizeX")) { // todo: should be removed in the future
defaultGroup.setLimitSizeMaxX(_file.getInt("Limit.SizeX", 128), null);
defaultGroup.setLimitSizeMaxY(_file.getInt("Limit.SizeY", 64), null);
defaultGroup.setLimitSizeMaxZ(_file.getInt("Limit.SizeZ", 128), null);
defaultGroup.setLimitSizeMinX(4, null);
defaultGroup.setLimitSizeMinY(4, null);
defaultGroup.setLimitSizeMinZ(4, null);
} else {
defaultGroup.setLimitSizeMaxX(_file.getInt("Limit.Size.MaxX", 128), null);
defaultGroup.setLimitSizeMaxY(_file.getInt("Limit.Size.MaxY", 64), null);
defaultGroup.setLimitSizeMaxZ(_file.getInt("Limit.Size.MaxZ", 128), null);
defaultGroup.setLimitSizeMinX(_file.getInt("Limit.Size.MinX", 4), null);
defaultGroup.setLimitSizeMinY(_file.getInt("Limit.Size.MinY", 4), null);
defaultGroup.setLimitSizeMinZ(_file.getInt("Limit.Size.MinZ", 4), null);
}
defaultGroup.setLimitMinY(_file.getInt("Limit.MinY", -64), null);
defaultGroup.setLimitMaxY(_file.getInt("Limit.MaxY", 320), null);
defaultGroup.setLimitAmount(_file.getInt("Limit.Amount", 10), null);
@ -113,6 +128,10 @@ public class ConfigManager {
_file.set("AutoCreateRadius", _auto_create_radius);
_file.setComments("AutoCreateRadius", Arrays.asList(Translation.Config_Comment_AutoCreateRadius.trans(), Translation.Config_Comment_NegativeOneDisabled.trans()));
_file.set("DefaultJoinMessage", _default_join_message);
_file.setComments("DefaultJoinMessage", Collections.singletonList(Translation.Config_Comment_DefaultJoinMessage.trans()));
_file.set("DefaultLeaveMessage", _default_leave_message);
_file.setComments("DefaultLeaveMessage", Collections.singletonList(Translation.Config_Comment_DefaultLeaveMessage.trans()));
_file.setComments("MessageDisplay", Collections.singletonList(Translation.Config_Comment_MessageDisplay.trans()));
_file.set("MessageDisplay.NoPermission", _message_display_no_permission);
@ -127,12 +146,18 @@ public class ConfigManager {
_file.setInlineComments("Limit.MinY", List.of(Translation.Config_Comment_MinY.trans()));
_file.set("Limit.MaxY", groupLimits.get("default").getLimitMaxY(null));
_file.setInlineComments("Limit.MaxY", List.of(Translation.Config_Comment_MaxY.trans()));
_file.set("Limit.SizeX", groupLimits.get("default").getLimitSizeX(null));
_file.setInlineComments("Limit.SizeX", List.of(Translation.Config_Comment_SizeX.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.SizeY", groupLimits.get("default").getLimitSizeY(null));
_file.setInlineComments("Limit.SizeY", List.of(Translation.Config_Comment_SizeY.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.SizeZ", groupLimits.get("default").getLimitSizeZ(null));
_file.setInlineComments("Limit.SizeZ", List.of(Translation.Config_Comment_SizeZ.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.Size.MaxX", groupLimits.get("default").getLimitSizeMaxX(null));
_file.setInlineComments("Limit.Size.MaxX", List.of(Translation.Config_Comment_SizeMaxX.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.Size.MaxY", groupLimits.get("default").getLimitSizeMaxY(null));
_file.setInlineComments("Limit.Size.MaxY", List.of(Translation.Config_Comment_SizeMaxY.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.Size.MaxZ", groupLimits.get("default").getLimitSizeMaxZ(null));
_file.setInlineComments("Limit.Size.MaxZ", List.of(Translation.Config_Comment_SizeMaxZ.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.Size.MinX", groupLimits.get("default").getLimitSizeMinX(null));
_file.setInlineComments("Limit.Size.MinX", List.of(Translation.Config_Comment_SizeMinX.trans()));
_file.set("Limit.Size.MinY", groupLimits.get("default").getLimitSizeMinY(null));
_file.setInlineComments("Limit.Size.MinY", List.of(Translation.Config_Comment_SizeMinY.trans()));
_file.set("Limit.Size.MinZ", groupLimits.get("default").getLimitSizeMinZ(null));
_file.setInlineComments("Limit.Size.MinZ", List.of(Translation.Config_Comment_SizeMinZ.trans()));
_file.set("Limit.Amount", groupLimits.get("default").getLimitAmount(null));
_file.setInlineComments("Limit.Amount", List.of(Translation.Config_Comment_Amount.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
_file.set("Limit.Depth", groupLimits.get("default").getLimitDepth(null));
@ -155,6 +180,8 @@ public class ConfigManager {
_file.set("Tool", _tool);
_file.setComments("Tool", List.of(Translation.Config_Comment_ToolName.trans()));
_file.set("InfoTool", _info_tool);
_file.setComments("InfoTool", List.of(Translation.Config_Comment_InfoToolName.trans()));
_file.setComments("Economy", Arrays.asList(Translation.Config_Comment_Economy.trans(), Translation.Config_Comment_VaultRequired.trans()));
_file.set("Economy.Enable", _economy_enable);
@ -243,22 +270,42 @@ public class ConfigManager {
return _db_pass;
}
public Integer getLimitSizeX(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeX(player.getWorld());
public Integer getLimitSizeMaxX(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeMaxX(player.getWorld());
}
public Integer getLimitSizeY(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeY(player.getWorld());
public Integer getLimitSizeMaxY(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeMaxY(player.getWorld());
}
public Integer getLimitSizeZ(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeZ(player.getWorld());
public Integer getLimitSizeMaxZ(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeMaxZ(player.getWorld());
}
public Integer getLimitSizeMinX(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeMinX(player.getWorld());
}
public Integer getLimitSizeMinY(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeMinY(player.getWorld());
}
public Integer getLimitSizeMinZ(Player player) {
return groupLimits.get(getPlayerGroup(player)).getLimitSizeMinZ(player.getWorld());
}
public Integer getAutoCreateRadius() {
return _auto_create_radius;
}
public String getDefaultJoinMessage() {
return _default_join_message;
}
public String getDefaultLeaveMessage() {
return _default_leave_message;
}
public void setAutoCreateRadius(Integer radius) {
_auto_create_radius = radius;
_file.set("AutoCreateRadius", radius);
@ -352,6 +399,15 @@ public class ConfigManager {
_file.set("Tool", tool);
}
public Material getInfoTool() {
return Material.getMaterial(_info_tool);
}
public void setInfoTool(String info_tool) {
_info_tool = info_tool;
_file.set("InfoTool", info_tool);
}
public Boolean getEconomyEnable() {
return _economy_enable;
}
@ -406,6 +462,10 @@ public class ConfigManager {
XLogger.err(Translation.Config_Check_ToolNameError);
setTool("ARROW");
}
if (Material.getMaterial(_info_tool) == null) {
XLogger.err(Translation.Config_Check_InfoToolNameError);
setInfoTool("STRING");
}
if (getAutoCreateRadius() <= 0 && getAutoCreateRadius() != -1) {
XLogger.err(Translation.Config_Check_AutoCreateRadiusError);
setAutoCreateRadius(10);
@ -451,6 +511,8 @@ public class ConfigManager {
private String _language;
private Integer _auto_create_radius;
private String _default_join_message;
private String _default_leave_message;
private Boolean _limit_op_bypass;
@ -463,7 +525,9 @@ public class ConfigManager {
private Boolean _tp_enable;
private Integer _tp_delay;
private Integer _tp_cool_down;
private String _tool;
private String _info_tool;
private Boolean _economy_enable;

View File

@ -1,16 +1,27 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.commands.Operator;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.*;
import cn.lunadeer.minecraftpluginutils.databse.syntax.AddColumn;
import cn.lunadeer.minecraftpluginutils.databse.syntax.CreateTable;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.RemoveColumn;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DatabaseTables {
public static void migrate() {
@ -114,8 +125,8 @@ public class DatabaseTables {
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", "再见");
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)
@ -260,4 +271,79 @@ public class DatabaseTables {
new RemoveColumn("world").table("dominion").IfExists().execute();
}
}
private static final File export_path = new File(Dominion.instance.getDataFolder(), "ExportedDatabaseTables");
public static void Export(CommandSender sender) {
Scheduler.runTaskAsync(() -> {
Notification.info(sender, Translation.Commands_Operator_ExportDBBegin);
if (!export_path.exists()) {
export_path.mkdirs();
}
Common.ExportCSV("player_name", new File(export_path, "player_name.csv"));
Common.ExportCSV("privilege_template", new File(export_path, "privilege_template.csv"));
Common.ExportCSV("dominion", new File(export_path, "dominion.csv"));
Common.ExportCSV("dominion_group", new File(export_path, "dominion_group.csv"));
Common.ExportCSV("dominion_member", new File(export_path, "dominion_member.csv"));
Map<String, String> world_uid_map = Dominion.instance.getServer().getWorlds().stream().collect(HashMap::new, (m, w) -> m.put(w.getName(), w.getUID().toString()), HashMap::putAll);
YamlConfiguration world_uid = new YamlConfiguration();
for (Map.Entry<String, String> entry : world_uid_map.entrySet()) {
world_uid.set(entry.getKey(), entry.getValue());
}
try {
world_uid.save(new File(export_path, "world_uid_mapping.yml"));
} catch (Exception e) {
XLogger.err("Save world_uid_mapping.yml failed: %s", e.getMessage());
return;
}
Notification.info(sender, Translation.Commands_Operator_ExportDBSuccess);
Notification.info(sender, "Path: %s", export_path.getAbsolutePath());
});
}
public static void Import(CommandSender sender) {
Scheduler.runTaskAsync(() -> {
if (!export_path.exists()) {
Notification.error(sender, Translation.Commands_Operator_ImportDBFail);
return;
}
Notification.info(sender, Translation.Commands_Operator_ImportDBBegin);
Map<String, String> world_uid_map = Dominion.instance.getServer().getWorlds().stream().collect(HashMap::new, (m, w) -> m.put(w.getName(), w.getUID().toString()), HashMap::putAll);
File player_name_csv = new File(export_path, "player_name.csv");
File privilege_template_csv = new File(export_path, "privilege_template.csv");
File dominion_csv = new File(export_path, "dominion.csv");
File world_uid_mapping = new File(export_path, "world_uid_mapping.yml");
File dominion_group_csv = new File(export_path, "dominion_group.csv");
File dominion_member_csv = new File(export_path, "dominion_member.csv");
if (!player_name_csv.exists() || !privilege_template_csv.exists() || !dominion_csv.exists() || !world_uid_mapping.exists() || !dominion_group_csv.exists() || !dominion_member_csv.exists()) {
Notification.error(sender, Translation.Commands_Operator_ImportDBIncompleteFail);
return;
}
try {
String dominion_file_str = Files.readString(dominion_csv.toPath());
YamlConfiguration world_uid = YamlConfiguration.loadConfiguration(world_uid_mapping);
for (String key : world_uid.getKeys(false)) {
if (world_uid_map.containsKey(key)) {
String old_uid = world_uid.getString(key);
String new_uid = world_uid_map.get(key);
if (old_uid == null || new_uid == null) {
continue;
}
dominion_file_str = dominion_file_str.replace(old_uid, world_uid_map.get(key));
}
}
Files.writeString(dominion_csv.toPath(), dominion_file_str);
} catch (IOException e) {
XLogger.err("Import world_uid_mapping.yml failed: %s", e.getMessage());
return;
}
Common.ImportCSV("player_name", "id", player_name_csv);
Common.ImportCSV("privilege_template", "id", privilege_template_csv);
Common.ImportCSV("dominion", "id", dominion_csv);
Common.ImportCSV("dominion_group", "id", dominion_group_csv);
Common.ImportCSV("dominion_member", "id", dominion_member_csv);
Notification.info(sender, Translation.Commands_Operator_ImportDBSuccess);
Operator.reloadCache(sender, new String[0]);
});
}
}

View File

@ -34,9 +34,21 @@ public class GroupLimit {
WorldSetting defaultSetting = new WorldSetting(filePath.getName());
defaultSetting.min_y = config.getInt("MinY", -64);
defaultSetting.max_y = config.getInt("MaxY", 320);
defaultSetting.size_x = config.getInt("SizeX", 128);
defaultSetting.size_y = config.getInt("SizeY", 64);
defaultSetting.size_z = config.getInt("SizeZ", 128);
if (config.contains("SizeX")) { // todo: should be removed in the future
defaultSetting.size_max_x = config.getInt("SizeX", 128);
defaultSetting.size_max_y = config.getInt("SizeY", 64);
defaultSetting.size_max_z = config.getInt("SizeZ", 128);
defaultSetting.size_min_x = 4;
defaultSetting.size_min_y = 4;
defaultSetting.size_min_z = 4;
} else {
defaultSetting.size_max_x = config.getInt("Size.MaxX", 128);
defaultSetting.size_max_y = config.getInt("Size.MaxY", 64);
defaultSetting.size_max_z = config.getInt("Size.MaxZ", 128);
defaultSetting.size_min_x = config.getInt("Size.MinX", 4);
defaultSetting.size_min_y = config.getInt("Size.MinY", 4);
defaultSetting.size_min_z = config.getInt("Size.MinZ", 4);
}
defaultSetting.amount = config.getInt("Amount", 10);
defaultSetting.depth = config.getInt("Depth", 3);
defaultSetting.vert = config.getBoolean("Vert", false);
@ -68,27 +80,51 @@ public class GroupLimit {
}
}
public Integer getLimitSizeX(@Nullable World world) {
public Integer getLimitSizeMaxX(@Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
return world_limits.get("default").size_x;
return world_limits.get("default").size_max_x;
} else {
return world_limits.get(world.getName()).size_x;
return world_limits.get(world.getName()).size_max_x;
}
}
public Integer getLimitSizeY(@Nullable World world) {
public Integer getLimitSizeMaxY(@Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
return world_limits.get("default").size_y;
return world_limits.get("default").size_max_y;
} else {
return world_limits.get(world.getName()).size_y;
return world_limits.get(world.getName()).size_max_y;
}
}
public Integer getLimitSizeZ(@Nullable World world) {
public Integer getLimitSizeMaxZ(@Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
return world_limits.get("default").size_z;
return world_limits.get("default").size_max_z;
} else {
return world_limits.get(world.getName()).size_z;
return world_limits.get(world.getName()).size_max_z;
}
}
public Integer getLimitSizeMinX(@Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
return world_limits.get("default").size_min_x;
} else {
return world_limits.get(world.getName()).size_min_x;
}
}
public Integer getLimitSizeMinY(@Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
return world_limits.get("default").size_min_y;
} else {
return world_limits.get(world.getName()).size_min_y;
}
}
public Integer getLimitSizeMinZ(@Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
return world_limits.get("default").size_min_z;
} else {
return world_limits.get(world.getName()).size_min_z;
}
}
@ -145,27 +181,51 @@ public class GroupLimit {
}
}
public void setLimitSizeX(Integer size_x, @Nullable World world) {
public void setLimitSizeMaxX(Integer size_x, @Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
world_limits.get("default").size_x = size_x;
world_limits.get("default").size_max_x = size_x;
} else {
world_limits.get(world.getName()).size_x = size_x;
world_limits.get(world.getName()).size_max_x = size_x;
}
}
public void setLimitSizeY(Integer size_y, @Nullable World world) {
public void setLimitSizeMaxY(Integer size_y, @Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
world_limits.get("default").size_y = size_y;
world_limits.get("default").size_max_y = size_y;
} else {
world_limits.get(world.getName()).size_y = size_y;
world_limits.get(world.getName()).size_max_y = size_y;
}
}
public void setLimitSizeZ(Integer size_z, @Nullable World world) {
public void setLimitSizeMaxZ(Integer size_z, @Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
world_limits.get("default").size_z = size_z;
world_limits.get("default").size_max_z = size_z;
} else {
world_limits.get(world.getName()).size_z = size_z;
world_limits.get(world.getName()).size_max_z = size_z;
}
}
public void setLimitSizeMinX(Integer size_x, @Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
world_limits.get("default").size_min_x = size_x;
} else {
world_limits.get(world.getName()).size_min_x = size_x;
}
}
public void setLimitSizeMinY(Integer size_y, @Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
world_limits.get("default").size_min_y = size_y;
} else {
world_limits.get(world.getName()).size_min_y = size_y;
}
}
public void setLimitSizeMinZ(Integer size_z, @Nullable World world) {
if (world == null || !world_limits.containsKey(world.getName())) {
world_limits.get("default").size_min_z = size_z;
} else {
world_limits.get(world.getName()).size_min_z = size_z;
}
}
@ -251,12 +311,18 @@ public class GroupLimit {
this.config.setInlineComments("MinY", List.of(Translation.Config_Comment_MinY.trans()));
this.config.set("MaxY", world_limits.get("default").max_y);
this.config.setInlineComments("MaxY", List.of(Translation.Config_Comment_MaxY.trans()));
this.config.set("SizeX", world_limits.get("default").size_x);
this.config.setInlineComments("SizeX", List.of(Translation.Config_Comment_SizeX.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("SizeY", world_limits.get("default").size_y);
this.config.setInlineComments("SizeY", List.of(Translation.Config_Comment_SizeY.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("SizeZ", world_limits.get("default").size_z);
this.config.setInlineComments("SizeZ", List.of(Translation.Config_Comment_SizeZ.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("Size.MaxX", world_limits.get("default").size_max_x);
this.config.setInlineComments("Size.MaxX", List.of(Translation.Config_Comment_SizeMaxX.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("Size.MaxY", world_limits.get("default").size_max_y);
this.config.setInlineComments("Size.MaxY", List.of(Translation.Config_Comment_SizeMaxY.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("Size.MaxZ", world_limits.get("default").size_max_z);
this.config.setInlineComments("Size.MaxZ", List.of(Translation.Config_Comment_SizeMaxZ.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("Size.MinX", world_limits.get("default").size_min_x);
this.config.setInlineComments("Size.MinX", List.of(Translation.Config_Comment_SizeMinX.trans()));
this.config.set("Size.MinY", world_limits.get("default").size_min_y);
this.config.setInlineComments("Size.MinY", List.of(Translation.Config_Comment_SizeMinY.trans()));
this.config.set("Size.MinZ", world_limits.get("default").size_min_z);
this.config.setInlineComments("Size.MinZ", List.of(Translation.Config_Comment_SizeMinZ.trans()));
this.config.set("Amount", world_limits.get("default").amount);
this.config.setInlineComments("Amount", List.of(Translation.Config_Comment_Amount.trans() + Translation.Config_Comment_NegativeOneUnlimited.trans()));
this.config.set("Depth", world_limits.get("default").depth);

View File

@ -148,31 +148,22 @@ public class Translation extends Localization {
public static i18n Commands_Operator_ReloadingConfig;
@i18nField(defaultValue = "配置文件已重新加载")
public static i18n Commands_Operator_ReloadedConfig;
@i18nField(defaultValue = "最高Y坐标限制不能小于最低Y坐标限制")
public static i18n Commands_SetConfig_MinYShouldBeLessThanMaxY;
@i18nField(defaultValue = "最低Y坐标限制不能大于最高Y坐标限制")
public static i18n Commands_SetConfig_MaxYShouldBeGreaterThanMinY;
@i18nField(defaultValue = "X轴(东西)最大尺寸不能小于4")
public static i18n Commands_SetConfig_SizeXShouldBeGreaterThan4;
@i18nField(defaultValue = "Z轴(南北)最大尺寸不能小于4")
public static i18n Commands_SetConfig_SizeZShouldBeGreaterThan4;
@i18nField(defaultValue = "Y轴(垂直)最大尺寸不能小于4")
public static i18n Commands_SetConfig_SizeYShouldBeGreaterThan4;
@i18nField(defaultValue = "每个玩家领地数量限制不能小于0")
public static i18n Commands_SetConfig_AmountShouldBeGreaterThan0;
@i18nField(defaultValue = "领地深度限制不能小于0")
public static i18n Commands_SetConfig_DepthShouldBeGreaterThan0;
@i18nField(defaultValue = "传送延迟不能小于0")
public static i18n Commands_SetConfig_TpDelayShouldBeGreaterThan0;
@i18nField(defaultValue = "传送冷却时间不能小于0")
public static i18n Commands_SetConfig_TpCoolDownShouldBeGreaterThan0;
@i18nField(defaultValue = "每方块单价不能小于0")
public static i18n Commands_SetConfig_PriceShouldBeGreaterThan0;
@i18nField(defaultValue = "领地退款比例不能小于0")
public static i18n Commands_SetConfig_RefundShouldBeGreaterThan0;
@i18nField(defaultValue = "出生点保护半径不能小于或等于0")
public static i18n Commands_SetConfig_SpawnProtectRadiusShouldBeGreaterThan0;
@i18nField(defaultValue = "你正在尝试导出数据库表,此行为会踢出所有玩家并关闭服务器,如确认继续请输入 /dominion export_db confirm")
public static i18n Commands_Operator_ExportDBConfirm;
@i18nField(defaultValue = "正在导出数据库表...")
public static i18n Commands_Operator_ExportDBBegin;
@i18nField(defaultValue = "数据库表导出完成")
public static i18n Commands_Operator_ExportDBSuccess;
@i18nField(defaultValue = "你正在尝试导入数据库表,此行为会踢出所有玩家并关闭服务器,如确认继续请输入 /dominion import_db confirm")
public static i18n Commands_Operator_ImportDBConfirm;
@i18nField(defaultValue = "正在导入数据库表...")
public static i18n Commands_Operator_ImportDBBegin;
@i18nField(defaultValue = "数据库表导入完成")
public static i18n Commands_Operator_ImportDBSuccess;
@i18nField(defaultValue = "没有可导入的数据")
public static i18n Commands_Operator_ImportDBFail;
@i18nField(defaultValue = "导入失败,数据不完整,请重新导出文件")
public static i18n Commands_Operator_ImportDBIncompleteFail;
@i18nField(defaultValue = "用法: /dominion template create <模板名称>")
public static i18n Commands_Template_CreateTemplateUsage;
@ -327,14 +318,18 @@ public class Translation extends Localization {
public static i18n Messages_SetMapColorSuccess;
@i18nField(defaultValue = "尺寸不合法")
public static i18n Messages_SizeInvalid;
@i18nField(defaultValue = "领地的任意一边长度不得小于4")
public static i18n Messages_SizeShouldBeGreaterThan4;
@i18nField(defaultValue = "领地X方向(东西)长度不能超过 %d")
public static i18n Messages_SizeXShouldBeLessThan;
@i18nField(defaultValue = "领地Y方向(上下)高度不能超过 %d")
public static i18n Messages_SizeYShouldBeLessThan;
@i18nField(defaultValue = "领地Z方向(南北)长度不能超过 %d")
public static i18n Messages_SizeZShouldBeLessThan;
@i18nField(defaultValue = "领地X方向(东西)长度不能少于 %d")
public static i18n Messages_SizeXShouldBeGreaterThan;
@i18nField(defaultValue = "领地Y方向(上下)高度不能少于 %d")
public static i18n Messages_SizeYShouldBeGreaterThan;
@i18nField(defaultValue = "领地Z方向(南北)长度不能少于 %d")
public static i18n Messages_SizeZShouldBeGreaterThan;
@i18nField(defaultValue = "领地Y坐标上限不能超过 %d")
public static i18n Messages_MaxYShouldBeLessThan;
@i18nField(defaultValue = "领地Y坐标下限不能超过 %d")
@ -597,10 +592,6 @@ public class Translation extends Localization {
public static i18n TUI_Menu_AllDominionButton;
@i18nField(defaultValue = "查看所有领地")
public static i18n TUI_Menu_AllDominionDescription;
@i18nField(defaultValue = "系统配置")
public static i18n TUI_Menu_ConfigButton;
@i18nField(defaultValue = "查看/修改系统配置")
public static i18n TUI_Menu_ConfigDescription;
@i18nField(defaultValue = "重载缓存")
public static i18n TUI_Menu_ReloadCacheButton;
@i18nField(defaultValue = "手动刷新缓存可解决一些玩家操作无效问题,不建议频繁操作")
@ -835,16 +826,30 @@ public class Translation extends Localization {
public static i18n Config_Check_MessageDisplayError;
@i18nField(defaultValue = "AutoCleanAfterDays 不能等于 0已重置为 180")
public static i18n Config_Check_AutoCleanAfterDaysError;
@i18nField(defaultValue = "工具名称设置错误,已重置为 ARROW")
@i18nField(defaultValue = "Tool 名称设置错误,已重置为 ARROW")
public static i18n Config_Check_ToolNameError;
@i18nField(defaultValue = "InfoTool 名称设置错误,已重置为 STRING")
public static i18n Config_Check_InfoToolNameError;
@i18nField(defaultValue = "%s 的 MinY 不能大于等于 MaxY已重置为 -64 和 320")
public static i18n Config_Check_GroupMinYError;
@i18nField(defaultValue = "%s 的 SizeX 设置过小,已重置为 128")
public static i18n Config_Check_GroupSizeXError;
@i18nField(defaultValue = "%s 的 SizeY 设置过小,已重置为 64")
public static i18n Config_Check_GroupSizeYError;
@i18nField(defaultValue = "%s 的 SizeZ 设置过小,已重置为 128")
public static i18n Config_Check_GroupSizeZError;
@i18nField(defaultValue = "%s 的 Size.MaxX 设置过小,已重置为 128")
public static i18n Config_Check_GroupSizeMaxXError;
@i18nField(defaultValue = "%s 的 Size.MaxY 设置过小,已重置为 64")
public static i18n Config_Check_GroupSizeMaxYError;
@i18nField(defaultValue = "%s 的 Size.MaxZ 设置过小,已重置为 128")
public static i18n Config_Check_GroupSizeMaxZError;
@i18nField(defaultValue = "%s 的 Size.MinX 设置过小,已重置为 4")
public static i18n Config_Check_GroupSizeMinXError;
@i18nField(defaultValue = "%s 的 Size.MinY 设置过小,已重置为 4")
public static i18n Config_Check_GroupSizeMinYError;
@i18nField(defaultValue = "%s 的 Size.MinZ 设置过小,已重置为 4")
public static i18n Config_Check_GroupSizeMinZError;
@i18nField(defaultValue = "%s 的 Size.MaxX 不能小于 MinX已重置为 128 和 4")
public static i18n Config_Check_GroupMaxMinXError;
@i18nField(defaultValue = "%s 的 Size.MinY 不能小于 MinY已重置为 64 和 4")
public static i18n Config_Check_GroupMaxMinYError;
@i18nField(defaultValue = "%s 的 Size.MaxZ 不能小于 MinZ已重置为 128 和 4")
public static i18n Config_Check_GroupMaxMinZError;
@i18nField(defaultValue = "%s 的 Amount 设置不合法,已重置为 10")
public static i18n Config_Check_GroupAmountError;
@i18nField(defaultValue = "%s 的 Depth 设置不合法,已重置为 3")
@ -864,6 +869,10 @@ public class Translation extends Localization {
public static i18n Config_Comment_Language;
@i18nField(defaultValue = "自动创建领地的半径,单位为方块")
public static i18n Config_Comment_AutoCreateRadius;
@i18nField(defaultValue = "默认进入领地提示消息")
public static i18n Config_Comment_DefaultJoinMessage;
@i18nField(defaultValue = "默认离开领地提示消息")
public static i18n Config_Comment_DefaultLeaveMessage;
@i18nField(defaultValue = "提示消息显示位置BOSS_BAR, ACTION_BAR, TITLE, SUBTITLE, CHAT")
public static i18n Config_Comment_MessageDisplay;
@i18nField(defaultValue = "玩家没有权限时的提示消息位置")
@ -883,11 +892,17 @@ public class Translation extends Localization {
@i18nField(defaultValue = "-1表示不限制")
public static i18n Config_Comment_NegativeOneUnlimited;
@i18nField(defaultValue = "X方向最大长度")
public static i18n Config_Comment_SizeX;
public static i18n Config_Comment_SizeMaxX;
@i18nField(defaultValue = "Y方向最大长度")
public static i18n Config_Comment_SizeY;
public static i18n Config_Comment_SizeMaxY;
@i18nField(defaultValue = "Z方向最大长度")
public static i18n Config_Comment_SizeZ;
public static i18n Config_Comment_SizeMaxZ;
@i18nField(defaultValue = "X方向最小长度")
public static i18n Config_Comment_SizeMinX;
@i18nField(defaultValue = "Y方向最小长度")
public static i18n Config_Comment_SizeMinY;
@i18nField(defaultValue = "Z方向最小长度")
public static i18n Config_Comment_SizeMinZ;
@i18nField(defaultValue = "最大领地数量")
public static i18n Config_Comment_Amount;
@i18nField(defaultValue = "子领地深度")
@ -908,6 +923,8 @@ public class Translation extends Localization {
public static i18n Config_Comment_AutoCleanAfterDays;
@i18nField(defaultValue = "圈地工具名称")
public static i18n Config_Comment_ToolName;
@i18nField(defaultValue = "查询领地信息工具名称")
public static i18n Config_Comment_InfoToolName;
@i18nField(defaultValue = "经济设置")
public static i18n Config_Comment_Economy;
@i18nField(defaultValue = "需要安装 Vault 前置及插件")
@ -952,6 +969,31 @@ public class Translation extends Localization {
@i18nField(defaultValue = "管理领地内的其他成员权限")
public static i18n Flags_admin_Description;
@i18nField(defaultValue = "已选择第一个点: %d %d %d")
public static i18n Tool_SelectFirstPoint;
@i18nField(defaultValue = "已选择第二个点: %d %d %d")
public static i18n Tool_SelectSecondPoint;
@i18nField(defaultValue = "两个点不在同一个世界")
public static i18n Tool_NotSameWorld;
@i18nField(defaultValue = "已选择两个点,可以使用 /dominion create <领地名称> 创建领地")
public static i18n Tool_SelectTwoPoints;
@i18nField(defaultValue = "预计领地创建价格为 %.2f %s")
public static i18n Tool_CreateDominionPrice;
@i18nField(defaultValue = "尺寸: %d x %d x %d")
public static i18n Tool_DominionSize;
@i18nField(defaultValue = "面积: %d")
public static i18n Tool_DominionSquare;
@i18nField(defaultValue = "体积: %d")
public static i18n Tool_DominionVolume;
@i18nField(defaultValue = "高度: %d")
public static i18n Tool_DominionHeight;
@i18nField(defaultValue = "这个方块(%d, %d, %d)不在任何领地内")
public static i18n Tool_LocationNotInDominion;
@i18nField(defaultValue = "这个方块(%d, %d, %d)在领地 %s 内")
public static i18n Tool_LocationInDominion;
@i18nField(defaultValue = "领地主人: %s")
public static i18n Tool_DominionOwner;
public Translation(JavaPlugin plugin) {
super(plugin);

View File

@ -9,9 +9,12 @@ import java.util.Map;
public class WorldSetting {
public Integer min_y;
public Integer max_y;
public Integer size_x;
public Integer size_y;
public Integer size_z;
public Integer size_max_x;
public Integer size_max_y;
public Integer size_max_z;
public Integer size_min_x;
public Integer size_min_y;
public Integer size_min_z;
public Integer amount;
public Integer depth;
public Boolean vert;
@ -26,9 +29,12 @@ public class WorldSetting {
YamlConfiguration section = new YamlConfiguration();
section.set("some_world_name.MinY", -64);
section.set("some_world_name.MaxY", 320);
section.set("some_world_name.SizeX", 128);
section.set("some_world_name.SizeY", 64);
section.set("some_world_name.SizeZ", 128);
section.set("some_world_name.Size.MaxX", 128);
section.set("some_world_name.Size.MaxY", 64);
section.set("some_world_name.Size.MaxZ", 128);
section.set("some_world_name.Size.MinX", 4);
section.set("some_world_name.Size.MinY", 4);
section.set("some_world_name.Size.MinZ", 4);
section.set("some_world_name.Amount", 10);
section.set("some_world_name.Depth", 3);
section.set("some_world_name.Vert", false);
@ -45,9 +51,21 @@ public class WorldSetting {
WorldSetting setting = new WorldSetting(sourceName);
setting.min_y = worldSettings.getInt(worldName + ".MinY", -64);
setting.max_y = worldSettings.getInt(worldName + ".MaxY", 320);
setting.size_x = worldSettings.getInt(worldName + ".SizeX", 128);
setting.size_y = worldSettings.getInt(worldName + ".SizeY", 64);
setting.size_z = worldSettings.getInt(worldName + ".SizeZ", 128);
if (worldSettings.contains(worldName + ".SizeX")) { // todo: should be removed in the future
setting.size_max_x = worldSettings.getInt(worldName + ".SizeX", 128);
setting.size_max_y = worldSettings.getInt(worldName + ".SizeY", 64);
setting.size_max_z = worldSettings.getInt(worldName + ".SizeZ", 128);
setting.size_min_x = 4;
setting.size_min_y = 4;
setting.size_min_z = 4;
} else {
setting.size_max_x = worldSettings.getInt(worldName + ".Size.MaxX", 128);
setting.size_max_y = worldSettings.getInt(worldName + ".Size.MaxY", 64);
setting.size_max_z = worldSettings.getInt(worldName + ".Size.MaxZ", 128);
setting.size_min_x = worldSettings.getInt(worldName + ".Size.MinX", 4);
setting.size_min_y = worldSettings.getInt(worldName + ".Size.MinY", 4);
setting.size_min_z = worldSettings.getInt(worldName + ".Size.MinZ", 4);
}
setting.amount = worldSettings.getInt(worldName + ".Amount", 10);
setting.depth = worldSettings.getInt(worldName + ".Depth", 3);
setting.vert = worldSettings.getBoolean(worldName + ".Vert", false);
@ -63,9 +81,12 @@ public class WorldSetting {
YamlConfiguration section = new YamlConfiguration();
section.set("MinY", min_y);
section.set("MaxY", max_y);
section.set("SizeX", size_x);
section.set("SizeY", size_y);
section.set("SizeZ", size_z);
section.set("Size.MaxX", size_max_x);
section.set("Size.MaxY", size_max_y);
section.set("Size.MaxZ", size_max_z);
section.set("Size.MinX", size_min_x);
section.set("Size.MinY", size_min_y);
section.set("Size.MinZ", size_min_z);
section.set("Amount", amount);
section.set("Depth", depth);
section.set("Vert", vert);
@ -78,17 +99,44 @@ public class WorldSetting {
min_y = -64;
max_y = 320;
}
if (size_x <= 4 && size_x != -1) {
XLogger.err(Translation.Config_Check_GroupSizeXError, sourceName);
size_x = 128;
if (size_max_x <= 4 && size_max_x != -1) {
XLogger.err(Translation.Config_Check_GroupSizeMaxXError, sourceName);
size_max_x = 128;
}
if (size_y <= 4 && size_y != -1) {
XLogger.err(Translation.Config_Check_GroupSizeYError, sourceName);
size_y = 64;
if (size_max_y <= 4 && size_max_y != -1) {
XLogger.err(Translation.Config_Check_GroupSizeMaxYError, sourceName);
size_max_y = 64;
}
if (size_z <= 4 && size_z != -1) {
XLogger.err(Translation.Config_Check_GroupSizeZError, sourceName);
size_z = 128;
if (size_max_z <= 4 && size_max_z != -1) {
XLogger.err(Translation.Config_Check_GroupSizeMaxZError, sourceName);
size_max_z = 128;
}
if (size_min_x <= 0) {
XLogger.err(Translation.Config_Check_GroupSizeMinXError, sourceName);
size_min_x = 4;
}
if (size_min_y <= 0) {
XLogger.err(Translation.Config_Check_GroupSizeMinYError, sourceName);
size_min_y = 4;
}
if (size_min_z <= 0) {
XLogger.err(Translation.Config_Check_GroupSizeMinZError, sourceName);
size_min_z = 4;
}
if (size_max_x < size_min_x && size_max_x != -1) {
XLogger.err(Translation.Config_Check_GroupMaxMinXError, sourceName);
size_max_x = 128;
size_min_x = 4;
}
if (size_max_y < size_min_y && size_max_y != -1) {
XLogger.err(Translation.Config_Check_GroupMaxMinYError, sourceName);
size_max_y = 64;
size_min_y = 4;
}
if (size_max_z < size_min_z && size_max_z != -1) {
XLogger.err(Translation.Config_Check_GroupMaxMinZError, sourceName);
size_max_z = 128;
size_min_z = 4;
}
if (amount < 0 && amount != -1) {
XLogger.err(Translation.Config_Check_GroupAmountError, sourceName);

View File

@ -34,7 +34,7 @@ public class CreateDominion {
Map<Integer, Location> points = autoPoints(sender);
operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), AbstractOperator.Result.SUCCESS)) {
DominionManage.show(sender, new String[]{"list"});
DominionManage.show(sender, new String[]{"manage", input});
}
});
DominionController.create(operator, input, points.get(0), points.get(1));

View File

@ -36,7 +36,7 @@ public class EnvSetting {
.append(Button.create(Translation.TUI_Navigation_DominionList).setExecuteCommand("/dominion list").build())
.append(Button.create(Translation.TUI_Navigation_Manage).setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append(Translation.TUI_Navigation_EnvSetting));
for (Flag flag : Flag.getDominionOnlyFlagsEnabled()) {
for (Flag flag : Flag.getEnvironmentFlagsEnabled()) {
view.add(createOption(flag, dominion.getFlagValue(flag), dominion.getName(), page));
}
view.showOn(player, page);

View File

@ -63,14 +63,14 @@ public class GroupList {
for (GroupDTO group : groups) {
Line line = new Line();
Button del = Button.createRed(Translation.TUI_DeleteButton)
.setHoverText(String.format(Translation.TUI_GroupList_DeleteDescription.trans(), group.getName()))
.setExecuteCommand("/dominion group delete " + dominion.getName() + " " + group.getName());
.setHoverText(String.format(Translation.TUI_GroupList_DeleteDescription.trans(), group.getNamePlain()))
.setExecuteCommand("/dominion group delete " + dominion.getName() + " " + group.getNamePlain());
Button edit = Button.create(Translation.TUI_EditButton)
.setHoverText(String.format(Translation.TUI_GroupList_EditDescription.trans(), group.getName()))
.setExecuteCommand("/dominion group setting " + dominion.getName() + " " + group.getName());
.setHoverText(String.format(Translation.TUI_GroupList_EditDescription.trans(), group.getNamePlain()))
.setExecuteCommand("/dominion group setting " + dominion.getName() + " " + group.getNamePlain());
Button add = Button.createGreen("+")
.setHoverText(String.format(Translation.TUI_GroupList_AddMemberDescription.trans(), group.getName()))
.setExecuteCommand("/dominion group select_member " + dominion.getName() + " " + group.getName() + " " + page);
.setHoverText(String.format(Translation.TUI_GroupList_AddMemberDescription.trans(), group.getNamePlain()))
.setExecuteCommand("/dominion group select_member " + dominion.getName() + " " + group.getNamePlain() + " " + page);
line.append(del.build()).append(edit.build()).append(group.getNameColoredComponent()).append(add.build());
view.add(line);
List<MemberDTO> players = MemberDTO.selectByGroupId(group.getId());
@ -80,9 +80,9 @@ public class GroupList {
if (p == null) continue;
Button remove = Button.createRed("-")
.setHoverText(
String.format(Translation.TUI_GroupList_RemoveMemberDescription.trans(), p.getLastKnownName(), group.getName())
String.format(Translation.TUI_GroupList_RemoveMemberDescription.trans(), p.getLastKnownName(), group.getNamePlain())
)
.setExecuteCommand("/dominion group remove_member " + dominion.getName() + " " + group.getName() + " " + p.getLastKnownName() + " " + page);
.setExecuteCommand("/dominion group remove_member " + dominion.getName() + " " + group.getNamePlain() + " " + p.getLastKnownName() + " " + page);
Line playerLine = new Line().setDivider("");
playerLine.append(Component.text(" "));
playerLine.append(remove.build()).append(" | " + p.getLastKnownName());

View File

@ -45,7 +45,7 @@ public class GroupSetting {
return;
}
ListView view = ListView.create(10, "/dominion group setting " + dominion.getName() + " " + group.getName());
ListView view = ListView.create(10, "/dominion group setting " + dominion.getName() + " " + group.getNamePlain());
view.title(Component.text(Translation.TUI_GroupSetting_TitleL.trans())
.append(group.getNameColoredComponent())
.append(Component.text(Translation.TUI_GroupSetting_TitleR.trans())));
@ -58,31 +58,31 @@ public class GroupSetting {
.append(Translation.TUI_Navigation_GroupSetting)
);
Button rename_btn = Button.create(Translation.TUI_GroupSetting_RenameButton)
.setHoverText(String.format(Translation.TUI_GroupSetting_RenameDescription.trans(), group.getName()))
.setExecuteCommand("/dominion cui_rename_group " + dominion.getName() + " " + group.getName());
.setHoverText(String.format(Translation.TUI_GroupSetting_RenameDescription.trans(), group.getNamePlain()))
.setExecuteCommand("/dominion cui_rename_group " + dominion.getName() + " " + group.getNamePlain());
view.add(Line.create().append(rename_btn.build()));
if (group.getAdmin()) {
view.add(Line.create()
.append(Button.createGreen("")
.setExecuteCommand(parseCommand(dominion.getName(), group.getName(), "admin", false, page))
.setExecuteCommand(parseCommand(dominion.getName(), group.getNamePlain(), "admin", false, page))
.build())
.append(
Component.text(Translation.Flags_admin_DisplayName.trans())
.hoverEvent(Component.text(Translation.Flags_admin_Description.trans()))
));
view.add(createOption(Flag.GLOW, group.getFlagValue(Flag.GLOW), dominion.getName(), group.getName(), page));
view.add(createOption(Flag.GLOW, group.getFlagValue(Flag.GLOW), dominion.getName(), group.getNamePlain(), page));
} else {
view.add(Line.create()
.append(Button.createRed("")
.setExecuteCommand(parseCommand(dominion.getName(), group.getName(), "admin", true, page))
.setExecuteCommand(parseCommand(dominion.getName(), group.getNamePlain(), "admin", true, page))
.build())
.append(
Component.text(Translation.Flags_admin_DisplayName.trans())
.hoverEvent(Component.text(Translation.Flags_admin_Description.trans()))
));
for (Flag flag : Flag.getPrivilegeFlagsEnabled()) {
view.add(createOption(flag, group.getFlagValue(flag), dominion.getName(), group.getName(), page));
view.add(createOption(flag, group.getFlagValue(flag), dominion.getName(), group.getNamePlain(), page));
}
}
view.showOn(player, page);

View File

@ -39,9 +39,9 @@ public class SelectMember {
}
int backPage = getPage(args, 4);
int page = getPage(args, 5);
ListView view = ListView.create(10, "/dominion group select_member " + dominion.getName() + " " + group.getName() + " " + backPage);
ListView view = ListView.create(10, "/dominion group select_member " + dominion.getName() + " " + group.getNamePlain() + " " + backPage);
view.title(Translation.TUI_SelectMember_Title);
Line sub = Line.create().append(String.format(Translation.TUI_SelectMember_Description.trans(), group.getName()))
Line sub = Line.create().append(String.format(Translation.TUI_SelectMember_Description.trans(), group.getNamePlain()))
.append(Button.create(Translation.TUI_BackButton).setExecuteCommand("/dominion group list " + dominion.getName() + " " + backPage).build());
view.subtitle(sub);
List<MemberDTO> members = MemberDTO.selectByDomGroupId(dominion.getId(), -1);
@ -50,7 +50,7 @@ public class SelectMember {
if (p == null) continue;
view.add(Line.create()
.append(Button.create(p.getLastKnownName())
.setExecuteCommand("/dominion group add_member " + dominion.getName() + " " + group.getName() + " " + p.getLastKnownName() + " " + backPage)
.setExecuteCommand("/dominion group add_member " + dominion.getName() + " " + group.getNamePlain() + " " + p.getLastKnownName() + " " + backPage)
.build()));
}
view.showOn(player, page);

View File

@ -99,7 +99,7 @@ public class MemberList {
}
}
if (group != null) {
prev.setDisabled(String.format(Translation.TUI_MemberList_BelongToGroup.trans(), group.getName()));
prev.setDisabled(String.format(Translation.TUI_MemberList_BelongToGroup.trans(), group.getNamePlain()));
}
line.append(remove.build());
line.append(prev.build());

View File

@ -9,6 +9,8 @@ Database:
Language: zh-cn
AutoCreateRadius: 10
DefaultJoinMessage: '&3{OWNER}: Welcome to {DOM}!'
DefaultLeaveMessage: '&3{OWNER}: Leaving {DOM}...'
MessageDisplay:
NoPermission: ACTION_BAR
@ -18,9 +20,13 @@ Limit:
SpawnProtection: 10
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Size:
MaxX: 128
MaxY: 64
MaxZ: 128
MinX: 4
MinY: 4
MinZ: 4
Amount: 10
Depth: 3
Vert: false
@ -29,9 +35,13 @@ Limit:
some_world_name:
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Size:
MaxX: 128
MaxY: 64
MaxZ: 128
MinX: 4
MinY: 4
MinZ: 4
Amount: 10
Depth: 3
Vert: false
@ -45,6 +55,8 @@ AutoCleanAfterDays: 180
Tool: ARROW
InfoTool: STRING
Economy:
Enable: false
Price: 10.0

View File

@ -1,8 +1,12 @@
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Size:
MaxX: 128
MaxY: 64
MaxZ: 128
MinX: 4
MinY: 4
MinZ: 4
Amount: 10
Depth: 3
Vert: false
@ -13,9 +17,13 @@ WorldSettings:
some_world_name:
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Size:
MaxX: 128
MaxY: 64
MaxZ: 128
MinX: 4
MinY: 4
MinZ: 4
Amount: 10
Depth: 3
Vert: false

View File

@ -3,10 +3,12 @@ version: @version@
main: cn.lunadeer.dominion.Dominion
api-version: '1.20'
folia-supported: true
libraries: [ ]
softdepend:
- Vault
- dynmap
- PlaceholderAPI
- BlueMap
commands:
Dominion:
description: 领地插件命令

View File

@ -1,6 +1,15 @@
## Dominion Documentation
## Preface
[![GitHub Repository](https://img.shields.io/badge/SourceCode-GitHub-blue?logo=github)](https://github.com/ColdeZhang/Dominion)
[![bStats](https://img.shields.io/badge/bStats-Statistics-eacd76?logo=google-analytics)](https://bstats.org/plugin/bukkit/Dominion/21445)
[![Hangar](https://img.shields.io/badge/To-Hangar-004ee9)](https://hangar.papermc.io/zhangyuheng/Dominion)
[![Modrinth](https://img.shields.io/badge/To-Modrinth-1bd96a)](https://modrinth.com/plugin/zhangyuheng-dominion)
[![Spigot](https://img.shields.io/badge/To-Spigot-ed8106)](https://www.spigotmc.org/resources/dominion.119514/)
[![Latest Build](https://img.shields.io/github/v/release/ColdeZhang/Dominion?label=LatestBuild&logo=github&color=0aa344)](https://github.com/ColdeZhang/Dominion/releases/latest)
## Brief
First of all, thank you very much for choosing and using this plugin.

View File

@ -6,7 +6,7 @@
### 1. 引入依赖
If you are using gradle, you can add the following code to your `build.gradle` file:
如果您使用 gradle可以在您的 `build.gradle` 文件中添加如下代码:
```groovy
// build.gradle
@ -15,11 +15,11 @@ repositories {
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:1.4-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
or if you are using gradle kotlin dsl:
或者你使用的是 gradle kotlin dsl
```kotlin
// build.gradle.kts
@ -28,11 +28,11 @@ repositories {
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:1.4-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
or if you are using maven, you can add the following code to your `pom.xml` file:
再或者您使用 maven可以在您的 `pom.xml` 文件中添加如下代码:
```xml
<!-- pom.xml -->
@ -47,7 +47,7 @@ or if you are using maven, you can add the following code to your `pom.xml` file
<dependency>
<groupId>cn.lunadeer</groupId>
<artifactId>DominionAPI</artifactId>
<version>1.4-SNAPSHOT</version>
<version>2.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@ -93,3 +93,7 @@ public void onEnable() {
}
}
```
[示例项目地址](https://github.com/ColdeZhang/DominionAddonExample)。
[Javadoc地址](https://coldezhang.github.io/DominionAPI/)。

View File

@ -4,7 +4,6 @@
- 1.20.1 及以上;
- Spigot、Paper、Folia...
- Java 21 及以上;
> 虽然本插件支持 Spigot 但是我们强烈推荐您升级到 Paper 或其分支核心(如 Purpur以获得更好的性能体验。

View File

@ -1,5 +1,12 @@
# Dominion 文档
[![GitHub Repository](https://img.shields.io/badge/仓库地址-GitHub-blue?logo=github)](https://github.com/ColdeZhang/Dominion)
[![bStats](https://img.shields.io/badge/bStats-数据统计-eacd76?logo=google-analytics)](https://bstats.org/plugin/bukkit/Dominion/21445)
[![Latest Build](https://img.shields.io/github/v/release/ColdeZhang/Dominion?label=%E6%9C%80%E6%96%B0%E6%9E%84%E5%BB%BA%E4%B8%8B%E8%BD%BD&logo=github&color=0aa344)](https://github.com/ColdeZhang/Dominion/releases/latest)
[![Latest Build](https://img.shields.io/github/v/release/ColdeZhang/Dominion?label=%E5%A4%87%E7%94%A8%E4%B8%8B%E8%BD%BD%E5%9C%B0%E5%9D%80&logo=gitea&color=0aa344)](https://ssl.lunadeer.cn:14446/mirror/Dominion/releases)
## 前言
首先十分感谢您选择并使用本插件。
@ -18,3 +25,6 @@ Dominion 是一个完全开源、免费,专为高版本开发,面向未来
1. [安装、必读、常见问题](operator/README.md)
2. [配置文件参考](operator/config.md)
什么,你是新手服主?推荐通读一下[驿站](https://github.com/postyizhan)大佬的 [笨蛋文档|一群笨蛋们写的 Minecraft 开服教程](https://yizhan.wiki/NitWikit/Java/intro)。
希望能对你的开服之路有所帮助!

View File

@ -15,7 +15,7 @@ repositories {
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:1.4-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
@ -28,7 +28,7 @@ repositories {
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:1.4-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
@ -44,12 +44,12 @@ dependencies {
</repositories>
<dependencies>
<dependency>
<dependency>
<groupId>cn.lunadeer</groupId>
<artifactId>DominionAPI</artifactId>
<version>1.4-SNAPSHOT</version>
<version>2.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependency>
</dependencies>
```
@ -93,3 +93,7 @@ public void onEnable() {
}
}
```
[示例项目地址](https://github.com/ColdeZhang/DominionAddonExample)。
[Javadoc地址](https://coldezhang.github.io/DominionAPI/)。

View File

@ -16,6 +16,11 @@
/dominion set_leave_msg <提示语> [领地名称]
```
## 特殊占位符
- `{OWNER}`:会被自动替换为领地主人的名字;
- `{DOM}`:会被自动替换为领地名称;
## 提示
- 提示语支持 PlaceholderAPI 占位符,例如 `%player%`

View File

@ -15,7 +15,7 @@
## 权限
当玩家处在一个子领地内时,其行为只收到子领地的权限控制。
子领地的权限设置与领地完全相同,参考[权限管理](permission/README.md)。
子领地的权限设置与领地完全相同,参考[权限管理](permission/README.md)。
## 关于子领地嵌套

View File

@ -4,7 +4,6 @@
- 1.20.1 及以上;
- Spigot、Paper、Folia...
- Java 21 及以上;
> 虽然本插件支持 Spigot 但是我们强烈推荐您升级到 Paper 或其分支核心(如 Purpur以获得更好的性能体验。

View File

@ -16,6 +16,11 @@ Language: zh-cn
# -1表示不开启
AutoCreateRadius: 10
# 默认进入领地提示消息
DefaultJoinMessage: '&3{OWNER}: Welcome to {DOM}!'
# 默认离开领地提示消息
DefaultLeaveMessage: '&3{OWNER}: Leaving {DOM}...'
# 领地提示消息显示位置BOSS_BAR, ACTION_BAR, TITLE, SUBTITLE, CHAT
MessageDisplay:
# 玩家没有权限时的提示消息位置
@ -28,9 +33,13 @@ Limit:
SpawnProtection: 10 # 出生点保护半径 出生点此范围内不允许圈地-1表示不开启
MinY: -64 # 最小Y坐标
MaxY: 320 # 最大Y坐标
SizeX: 128 # X方向最大长度-1表示不限制
SizeY: 64 # Y方向最大长度-1表示不限制
SizeZ: 128 # Z方向最大长度-1表示不限制
Size:
MaxX: 628 # X方向最大长度-1表示不限制
MaxY: 64 # Y方向最大长度-1表示不限制
MaxZ: 628 # Z方向最大长度-1表示不限制
MinX: 4 # X方向最小长度
MinY: 4 # Y方向最小长度
MinZ: 4 # Z方向最小长度
Amount: 10 # 最大领地数量-1表示不限制
Depth: 3 # 子领地深度0表示不开启-1表示不限制
Vert: false # 是否自动延伸到 MaxY 和 MinY
@ -58,6 +67,9 @@ AutoCleanAfterDays: 180
# 圈地工具名称
Tool: ARROW
# 查询领地信息工具名称
InfoTool: STRING
# 经济设置
# 需要安装 Vault 前置及插件
Economy:
@ -114,6 +126,10 @@ Timer: false # 性能测试计时器
配置玩家在使用“自动创建”功能时会自动向XYZ三个方向延伸此距离创建领地。
### DefaultJoinMessage & DefaultLeaveMessage
默认进入领地提示消息和默认离开领地提示消息。
### MessageDisplay
配置提示消息显示位置,可选项:`BOSS_BAR`, `ACTION_BAR`, `TITLE`, `SUBTITLE`, `CHAT`
@ -127,13 +143,18 @@ Timer: false # 性能测试计时器
- SpawnProtection出生点半径保护此半径范围内普通玩家无法创建领地
- MinY领地的最小Y坐标
- MaxY领地的最大Y坐标
- SizeXX方向最大长度 1表示不限制
- SizeYY方向最大长度 1表示不限制
- SizeZZ方向最大长度 1表示不限制
- Amount每个玩家拥有的最大领地数量 1表示不限制
- Size领地的大小限制
- MaxXX方向最大长度 -1表示不限制
- MaxYY方向最大长度 -1表示不限制
- MaxZZ方向最大长度 -1表示不限制
- MinXX方向最小长度 不能小于等于0 不能大于MaxX
- MinYY方向最小长度 不能小于等于0 不能大于MaxY
- MinZZ方向最小长度 不能小于等于0 不能大于MaxZ
- Amount每个玩家拥有的最大领地数量 -1表示不限制
- Depth子领地深度、0表示不允许子领地、 -1表示不限制
- Vert当设置为 `true`玩家选择区域创建或者自动创建领地会自动将Y向下向上延伸到MinY和MaxY。**同时也会根据 MinY 和 MaxY 的设置自动调整 SizeY 的配置保证数值逻辑一致。**
- Vert当设置为 `true`玩家选择区域创建或者自动创建领地会自动将Y向下向上延伸到MinY和MaxY
- WorldSettings单独设置某个世界的圈地规则如不设置则使用上述默认规则
- OpByPass是否允许OP无视领地限制
> 您服务器世界的名称应该避免使用 `default` 这样的特殊单词,否则会导致不可预料的意外错误。
@ -149,6 +170,10 @@ Timer: false # 性能测试计时器
配置手动圈地时的选取工具。如果配置错误会被设置为默认值“ARROW”箭矢。
### InfoTool
配置查询领地信息工具。如果配置错误会被设置为默认值“STRING”字符串。使用左键配合该物品点击领地内方块时会显示领地信息。
### Economy
经济控制支持,让玩家需要花费金钱圈地。使用此特性需要安装 Vault 经济前置插件。

View File

@ -1,6 +1,6 @@
# 跨群组服传送
**功能暂未上线**
**功能暂未上线**
## 新服务器配置

View File

@ -1,5 +1,14 @@
# Dominion 文檔
[![GitHub Repository](https://img.shields.io/badge/SourceCode-GitHub-blue?logo=github)](https://github.com/ColdeZhang/Dominion)
[![bStats](https://img.shields.io/badge/bStats-Statistics-eacd76?logo=google-analytics)](https://bstats.org/plugin/bukkit/Dominion/21445)
[![Hangar](https://img.shields.io/badge/To-Hangar-004ee9)](https://hangar.papermc.io/zhangyuheng/Dominion)
[![Modrinth](https://img.shields.io/badge/To-Modrinth-1bd96a)](https://modrinth.com/plugin/zhangyuheng-dominion)
[![Spigot](https://img.shields.io/badge/To-Spigot-ed8106)](https://www.spigotmc.org/resources/dominion.119514/)
[![Latest Build](https://img.shields.io/github/v/release/ColdeZhang/Dominion?label=LatestBuild&logo=github&color=0aa344)](https://github.com/ColdeZhang/Dominion/releases/latest)
## 前言
首先十分感謝您選擇並使用本插件。

View File

@ -15,7 +15,7 @@ repositories {
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:1.4-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
@ -28,7 +28,7 @@ repositories {
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:1.4-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
@ -47,7 +47,7 @@ dependencies {
<dependency>
<groupId>cn.lunadeer</groupId>
<artifactId>DominionAPI</artifactId>
<version>1.4-SNAPSHOT</version>
<version>2.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@ -93,3 +93,7 @@ public void onEnable() {
}
}
```
[示例项目地址](https://github.com/ColdeZhang/DominionAddonExample)。
[Javadoc地址](https://coldezhang.github.io/DominionAPI/)。

View File

@ -4,7 +4,6 @@
- 1.20.1 及以上;
- Spigot、Paper、Folia...
- Java 21 及以上;
> 雖然本插件支持 Spigot 但是我們強烈推薦您升級到 Paper 或其分支核心(如 Purpur以獲得更好的性能體驗。

View File

@ -4,105 +4,92 @@
# Translated by: YOUR_NAME_HERE
Commands:
Dominion:
SetFlagUsage: 'Usage: /dominion set <flag_name> <true/false> [dominion_name]'
CreateDominionUsage: 'Usage: /dominion create <territory_name>'
CreateSelectPointsFirst: Please first use the tool to select the diagonal points of the territory, or use /dominion auto_create <territory_name> to create an automatic territory
CreateSubDominionUsage: 'Usage: /dominion create_sub <sub_territory_name> [parent_territory_name]'
CreateSubSelectPointsFirst: Please first use the tool to select the diagonal points of the sub-territory, or use /dominion auto_create_sub <sub_territory_name> [parent_territory_name] to create an automatic sub-territory
AutoCreateDominionUsage: 'Usage: /dominion auto_create <territory_name>'
AutoCreateSubDominionUsage: 'Usage: /dominion auto_create_sub <sub_territory_name> [parent_territory_name]'
AutoCreateDominionDisabled: Automatic dominion creation function has been disabled
ExpandDominionUsage: 'Usage: /dominion expand [size] [dominion_name]'
ContractDominionUsage: 'Usage: /dominion contract [size] [dominion_name]'
SizeShouldBeInteger: Size should be an integer
SizeShouldBePositive: Size should be greater than 0
DeleteDominionUsage: 'Usage: /dominion delete <territory_name>'
SetEnterMessageUsage: 'Usage: /dominion set_enter_msg <prompt> [territory_name]'
SetLeaveMessageUsage: 'Usage: /dominion set_leave_msg <prompt> [territory_name]'
SetTpLocationUsage: 'Usage: /dominion set_tp_location [dominion_name]'
RenameDominionUsage: 'Usage: /dominion rename <original_territory_name> <new_territory_name>'
GiveDominionUsage: 'Usage: /dominion give <territory_name> <player_name>'
TpDominionUsage: 'Usage: /dominion tp <territory_name>'
DominionNotExist: Dominion does not exist
SetMapColorUsage: 'Usage: /dominion set_map_color <color> [territory_name]'
SetFlagUsage: 'Usage: /dominion set <flag_name> <true/false> [dominion name]'
CreateDominionUsage: 'Usage: /dominion create <dominion name>'
CreateSelectPointsFirst: Please first use the tool to select the points, or use /dominion auto_create <dominion name> to create dominion automatically.
CreateSubDominionUsage: 'Usage: /dominion create_sub <sub name> [parent name]'
CreateSubSelectPointsFirst: Please first use the tool to select the points, or use /dominion auto_create_sub <sub name> [parent name] to create sub-dominion automatically.
AutoCreateDominionUsage: 'Usage: /dominion auto_create <dominion name>'
AutoCreateSubDominionUsage: 'Usage: /dominion auto_create_sub <sub name> [parent name]'
AutoCreateDominionDisabled: Automatic creation function has been disabled by operator.
ExpandDominionUsage: 'Usage: /dominion expand [size] [dominion name]'
ContractDominionUsage: 'Usage: /dominion contract [size] [dominion name]'
SizeShouldBeInteger: Size should be an integer.
SizeShouldBePositive: Size should be greater than 0.
DeleteDominionUsage: 'Usage: /dominion delete <dominion name>'
SetEnterMessageUsage: 'Usage: /dominion set_enter_msg <msg> [dominion name]'
SetLeaveMessageUsage: 'Usage: /dominion set_leave_msg <msg> [dominion name]'
SetTpLocationUsage: 'Usage: /dominion set_tp_location [dominion name]'
RenameDominionUsage: 'Usage: /dominion rename <old name> <new name>'
GiveDominionUsage: 'Usage: /dominion give <dominion name> <player name>'
TpDominionUsage: 'Usage: /dominion tp <dominion name>'
DominionNotExist: Dominion does not exist.
SetMapColorUsage: 'Usage: /dominion set_map_color <hex color> [dominion name]'
Group:
CreateGroupUsage: 'Usage: /dominion group create <territory_name> <permission_group_name>'
DeleteGroupUsage: 'Usage: /dominion group delete <territory_name> <permission_group_name>'
RenameGroupUsage: 'Usage: /dominion group rename <territory_name> <old_permission_group_name> <new_name>'
SetGroupFlagUsage: 'Usage: /dominion group set_flag <territory_name> <permission_group_name> <permission_name> <true|false>'
AddGroupMemberUsage: 'Usage: /dominion group add_member <territory_name> <permission_group_name> <player_name>'
RemoveGroupMemberUsage: 'Usage: /dominion group remove_member <territory_name> <permission_group_name> <player_name>'
CreateGroupUsage: 'Usage: /dominion group create <dominion name> <group name>'
DeleteGroupUsage: 'Usage: /dominion group delete <dominion name> <group name>'
RenameGroupUsage: 'Usage: /dominion group rename <dominion name> <old name> <new name>'
SetGroupFlagUsage: 'Usage: /dominion group set_flag <dominion name> <group name> <flag name> <true|false>'
AddGroupMemberUsage: 'Usage: /dominion group add_member <dominion name> <group name> <player name>'
RemoveGroupMemberUsage: 'Usage: /dominion group remove_member <dominion name> <group name> <player name>'
GroupUsage: 'Usage: /dominion group <create|delete|rename|set_flag|add_member|remove_member|select_member|setting|list>'
NewGroupName: New group name
Member:
DominionAddMemberUsage: 'Usage: /dominion member add <territory_name> <player_name>'
DominionSetFlagUsage: 'Usage: /dominion member set_flag <territory_name> <player_name> <permission_name> <true/false>'
DominionRemoveMemberUsage: 'Usage: /dominion member remove <territory_name> <player_name>'
DominionApplyTemplateUsage: 'Usage: /dominion member apply_template <territory_name> <player_name> <template_name>'
DominionAddMemberUsage: 'Usage: /dominion member add <dominion name> <player name>'
DominionSetFlagUsage: 'Usage: /dominion member set_flag <dominion name> <player name> <flag name> <true/false>'
DominionRemoveMemberUsage: 'Usage: /dominion member remove <dominion name> <player name>'
DominionApplyTemplateUsage: 'Usage: /dominion member apply_template <dominion name> <player name> <template name>'
MemberUsage: 'Usage: /dominion member <add/set_flag/remove/apply_template/list/setting/select_player/select_template>'
PageOptional: Page number (optional)
ArgumentsNotEnough: Insufficient parameters
UnknownArgument: Unknown argument
PageOptional: Page (optional)
ArgumentsNotEnough: Insufficient parameters.
UnknownArgument: Unknown argument.
SizeInteger: Size (integer)
DominionName: Dominion name
SubDominionName: Sub-dominion name
EnterMessageContent: Enter message content
LeaveMessageContent: Leave message content
InputColor: Input color (hexadecimal)
NewDominionName: New dominion name
DominionName: Dominion Name
SubDominionName: Sub-dominion Name
EnterMessageContent: Enter Message
LeaveMessageContent: Leave Message
InputColor: Color (HEX)
NewDominionName: New Dominion Name
Residence:
MigrationDisabled: Residence migration feature is not enabled
MigrateUsage: 'Usage: /dominion migrate <res_dominion_name>'
NoMigrationData: You have no data to migrate
NoResidenceDominion: Specified Residence dominion not found
ResidenceNotOwner: You are not the owner of this dominion, cannot migrate it
MigrateFailed: 'Migration failed: %s'
MigrateSuccess: Dominion %s has been migrated from Residence to Dominion
MigrationDisabled: Migration from residence has been disabled by operator.
MigrateUsage: 'Usage: /dominion migrate <res territory name>'
NoMigrationData: You have no data to migrate.
NoResidenceDominion: Specified res territory not found.
ResidenceNotOwner: You are not the owner of this res territory, cannot migrate it.
MigrateFailed: 'Migration failed: %s.'
MigrateSuccess: Territory %s has been migrated from Residence to Dominion.
Operator:
ReloadingDominionCache: Reloading dominion cache from the database...
ReloadedDominionCache: Dominion cache has been reloaded
ReloadingPrivilegeCache: Reloading player privilege cache from the database...
ReloadedPrivilegeCache: Player privilege cache has been reloaded
ReloadingDominionCache: Reloading cache from the database...
ReloadedDominionCache: Cache has been reloaded.
ReloadingPrivilegeCache: Reloading player permission cache from the database...
ReloadedPrivilegeCache: Player permission cache has been reloaded.
ReloadingGroupCache: Reloading group cache from the database...
ReloadedGroupCache: Group cache has been reloaded
ExportingMCAList: Exporting the list of MCA files for owned territories...
CreateExportFolderFailed: Failed to create export folder
ReloadedGroupCache: Group cache has been reloaded.
ExportingMCAList: Exporting the list of MCA files containing dominions...
CreateExportFolderFailed: Failed to create export folder.
ExportingMCAListForWorld: Exporting the list of MCA files for %s...
DeleteMCAListFailed: Failed to delete the MCA file list for %s
CreateMCAListFailed: Failed to create the MCA file list for %s
WriteMCAListFailed: Failed to write to %s
ExportMCAListFailed: Failed to export the MCA file list for %s
ExportedMCAList: MCA file list has been exported to %s
DeleteMCAListFailed: Failed to delete the MCA file list for %s.
CreateMCAListFailed: Failed to create the MCA file list for %s.
WriteMCAListFailed: Failed to write to %s.
ExportMCAListFailed: Failed to export the MCA file list for %s.
ExportedMCAList: MCA file list has been exported to %s.
ReloadingConfig: Reloading configuration file...
ReloadedConfig: Configuration file has been reloaded
SetConfig:
MinYShouldBeLessThanMaxY: The maximum Y coordinate limit cannot be less than the minimum Y coordinate limit
MaxYShouldBeGreaterThanMinY: The minimum Y coordinate limit cannot be greater than the maximum Y coordinate limit
SizeXShouldBeGreaterThan4: The maximum size on the X axis (East-West) cannot be less than 4
SizeZShouldBeGreaterThan4: The maximum size on the Z axis (North-South) cannot be less than 4
SizeYShouldBeGreaterThan4: The maximum size on the Y axis (Vertical) cannot be less than 4
AmountShouldBeGreaterThan0: The limit of the number of dominions per player cannot be less than 0
DepthShouldBeGreaterThan0: The depth limit of the dominion cannot be less than 0
TpDelayShouldBeGreaterThan0: Teleport delay cannot be less than 0
TpCoolDownShouldBeGreaterThan0: Teleport cooldown cannot be less than 0
PriceShouldBeGreaterThan0: The price per block cannot be less than 0
RefundShouldBeGreaterThan0: The refund ratio for the dominion cannot be less than 0
SpawnProtectRadiusShouldBeGreaterThan0: Spawn protection radius cannot be less than or equal to 0
ReloadedConfig: Configuration file has been reloaded.
Template:
CreateTemplateUsage: 'Usage: /dominion template create <template_name>'
DeleteTemplateUsage: 'Usage: /dominion template delete <template_name>'
SetTemplateFlagUsage: 'Usage: /dominion template set_flag <template_name> <permission_name> <true/false>'
CreateTemplateUsage: 'Usage: /dominion template create <template name>'
DeleteTemplateUsage: 'Usage: /dominion template delete <template name>'
SetTemplateFlagUsage: 'Usage: /dominion template set_flag <template name> <flag name> <true/false>'
TemplateUsage: 'Usage: /dominion template <list|setting|delete|create|set_flag>'
NewTemplateName: New template name
Title:
UseTitleUsage: 'Usage: /dominion use_title <permission_group_id>'
RemoveTitleSuccess: Successfully removed group title
GroupNotExist: Group does not exist
GroupDominionNotExist: Group %s does not belong to any dominion
NotDominionMember: You are not a member of dominion %s and cannot use its title
NotGroupMember: You are not a member of group %s and cannot use its title
UseTitleSuccess: Successfully used group %s title
UseTitleFailed: 'Using title failed: %s'
UseTitleUsage: 'Usage: /dominion use_title <group id>'
RemoveTitleSuccess: Successfully removed title.
GroupNotExist: Group does not exist.
GroupDominionNotExist: Group %s does not belong to any dominion.
NotDominionMember: You are not a member of dominion %s and cannot use its title.
NotGroupMember: You are not a member of group %s and cannot use its title.
UseTitleSuccess: Successfully used group title %s.
UseTitleFailed: 'Using title failed: %s.'
Messages:
OpBypassTpLimit: You are OP, you will bypass territory teleportation limits
WorldNotExist: The world where the dominion is located does not exist
@ -256,174 +243,172 @@ Messages:
AutoCleanEnd: Automatic cleanup completed
MapInfoDetail: '<div>%s</div><div>Everyone: %s</div>'
TUI:
NotDominionOwnerOrAdminForPage: You are not the owner or admin of territory %s and have no access to this page
NotDominionOwnerOrAdminForPage: You are not the owner or admin of %s and have no access to this page
CommandHelp:
Title: Territory plugin command help
SubTitle: <> indicates required parameters and [] indicates optional parameters
Title: Commands Help List
SubTitle: <> is necessary, [] is optional
Navigation:
Menu: Main Menu
DominionList: My Territories
Manage: Management Interface
EnvSetting: Environmental Settings
GuestSetting: Guest Permissions
MemberList: Member List
MemberSetting: Member Permissions
GroupList: Permission Group List
GroupSetting: Permission Group Management
AllDominion: All Territories
TemplateList: Template List
TemplateSetting: Template Management
MigrateList: Res Data List
TitleList: Permission Group Title List
ManageButton: Manage
DeleteButton: Delete
SearchButton: Search
BackButton: Return
SelectButton: Select
EditButton: Edit
Menu: MAIN
DominionList: DOMS
Manage: MANAGE
EnvSetting: ENV
GuestSetting: GUEST
MemberList: MEMBERS
MemberSetting: MEMBER
GroupList: GROUPS
GroupSetting: GROUP
AllDominion: ALL_DOMS
TemplateList: TEMPLATES
TemplateSetting: TEMPLATE
MigrateList: RES_DATA
TitleList: TITLES
ManageButton: MANAGE
DeleteButton: DELETE
SearchButton: SEARCH
BackButton: BACK
SelectButton: SELECT
EditButton: EDIT
Menu:
Title: Dominion Territory System
CreateDominionButton: Create Territory
CreateDominionDescription: Automatically create a new territory centered on you
MyDominionButton: My Territories
MyDominionDescription: View my territory list
TitleListButton: Title List
TitleListDescription: View/use permission group titles
TemplateListButton: Template List
TemplateListDescription: Member Permission Template List
CommandHelpButton: Command Help
CommandHelpDescription: View command list
DocumentButton: Usage Documentation
DocumentDescription: Open usage documentation in the browser
MigrateButton: Migrate Data
MigrateDescription: Migrate your territory from Residence to Dominion
AllDominionButton: All Territories
AllDominionDescription: View all territories
ConfigButton: System Configuration
ConfigDescription: View/modify system configuration
ReloadCacheButton: Reload Cache
ReloadCacheDescription: Manually refreshing the cache can solve some player operation issues. Frequent operation is not recommended
ReloadConfigButton: Reload Configuration
ReloadConfigDescription: Reload configuration file
OpOnlySection: '--- The following options are visible only to OP ---'
Title: Dominion Main Menu
CreateDominionButton: CREATE
CreateDominionDescription: Create a dominion automatically around you.
MyDominionButton: DOMINIONS
MyDominionDescription: List all your dominions.
TitleListButton: TITLES
TitleListDescription: List/Use group titles.
TemplateListButton: TEMPLATES
TemplateListDescription: Permission template list.
CommandHelpButton: HELP
CommandHelpDescription: View command list.
DocumentButton: DOCS
DocumentDescription: Open usage documentation in the browser.
MigrateButton: MIGRATE
MigrateDescription: Migrate your territories from Residence.
AllDominionButton: ALL_DOMS
AllDominionDescription: List all dominions of server.
ReloadCacheButton: RELOAD_CACHE
ReloadCacheDescription: Could solve some weird problem. DONT DO THIS FREQUENTLY!
ReloadConfigButton: RELOAD_CONF
ReloadConfigDescription: Reload configuration file from disk.
OpOnlySection: '--- FOLLOWING VISIBLE OP ONLY ---'
DominionList:
Title: My Territory List
AdminSection: '--- The following are the territories where you have admin privileges ---'
Title: My Dominion List
AdminSection: '--- YOU ARE ADMIN OF FOLLOWING ---'
DominionManage:
Title: Management Interface for Territory %s
InfoButton: Detailed Information
InfoDescription: View detailed information of the territory
EnvSettingButton: Environmental Settings
EnvSettingDescription: Set some environmental behaviors within the territory
GuestSettingButton: Guest Permissions
GuestSettingDescription: Configure guest permissions in this territory
MemberListButton: Member Management
MemberListDescription: Manage the permissions of members of this territory
GroupListButton: Permission Groups
GroupListDescription: Manage the permission groups of this territory
SetTpLocationButton: Set Teleport Points
SetTpLocationDescription: Set your current location as the teleport point for this territory
RenameButton: Rename
RenameDescription: Rename the territory
EditJoinMessageButton: Edit Welcome Message
EditJoinMessageDescription: Message displayed when a player enters the territory
EditLeaveMessageButton: Edit Leave Message
EditLeaveMessageDescription: Message displayed when a player leaves the territory
SetMapColorButton: Set Land Color
SetMapColorDescription: Set the land color on the satellite map
Title: '%s Management'
InfoButton: DETAILS
InfoDescription: View details of this dominion.
EnvSettingButton: ENV_SETTING
EnvSettingDescription: Set some environmental behaviors.
GuestSettingButton: GUEST_SETTING
GuestSettingDescription: Configure guest permissions.
MemberListButton: MEMBERS
MemberListDescription: Manage the permissions of members.
GroupListButton: GROUPS
GroupListDescription: Manage the permission groups.
SetTpLocationButton: SET_TP_LOC
SetTpLocationDescription: Set the teleport point.
RenameButton: RENAME
RenameDescription: Rename the dominion.
EditJoinMessageButton: EDIT_ENTER_MSG
EditJoinMessageDescription: Message displayed when enter.
EditLeaveMessageButton: EDIT_LEAVE_MSG
EditLeaveMessageDescription: Message displayed when leave.
SetMapColorButton: COLOR
SetMapColorDescription: Color will be shown on web map.
NotInDominion: You are not in any dominion, please specify the dominion name /dominion manage <dominion name>
EnvSetting:
Title: Environmental Settings for Territory %s
Usage: 'Usage: /dominion env_setting <dominion name> [page number]'
Title: '%s Environmental Settings'
Usage: 'Usage: /dominion env_setting <dominion name> [page]'
GuestSetting:
Title: Guest Permissions for Territory %s
Usage: 'Usage: /dominion guest_setting <dominion name> [page number]'
Title: '%s Guest Settings'
Usage: 'Usage: /dominion guest_setting <dominion name> [page]'
SizeInfo:
Title: Size Information for Territory %s
Owner: 'Territory Owner:'
Size: 'Territory Size:'
Title: '%s Size Information'
Owner: 'Owner:'
Size: 'Size:'
Center: 'Center Coordinates:'
Vertical: 'Vertical Height:'
VertY: 'Y-axis Coordinates:'
Square: 'Horizontal Area:'
Volume: 'Territory Volume:'
TpLocation: 'Teleport Point Coordinates:'
NoneTp: None
Square: 'Square:'
Volume: 'Volume:'
TpLocation: 'Teleport Coordinates:'
NoneTp: None Tp Info
Usage: You are not in any dominion, please specify the dominion name /dominion info <dominion name>
MemberList:
Title: Member List for Territory %s
AddButton: Add Member
FlagButton: Permissions
FlagDescription: Configure Member Permissions
RemoveButton: Remove
RemoveDescription: Remove this member (turn to guest)
NoPermissionSet: You are not the territory owner and cannot edit admin permissions
NoPermissionRemove: You are not the territory owner and cannot remove the admin
BelongToGroup: This member belongs to permission group %s and cannot edit permissions separately
Usage: 'Usage: /dominion member list <dominion name> [page number]'
AdminTag: This member is an admin
NormalTag: This is a regular member
BlacklistTag: This is a blacklist member
GroupTag: This member is in a permission group
Title: '%s Member List'
AddButton: ADD_MEMBER
FlagButton: PERMS
FlagDescription: Configure member permissions.
RemoveButton: REMOVE
RemoveDescription: Remove this member (to guest).
NoPermissionSet: Only owner can set admin permissions.
NoPermissionRemove: Only owner can remove admin permissions.
BelongToGroup: This member belongs to group %s and cannot set permissions separately.
Usage: 'Usage: /dominion member list <dominion name> [page]'
AdminTag: This member is an ADMIN.
NormalTag: This is a regular MEMBER.
BlacklistTag: This is a BLACKLIST member.
GroupTag: This member is in a GROUP.
MemberSetting:
Title: Permission Settings for Player %s in Territory %s
ApplyTemplateButton: Apply Template
ApplyTemplateDescription: Choose a permission template to apply
Usage: 'Usage: /dominion member setting <dominion name> <player name> [page number]'
Title: '%s Permission in %s'
ApplyTemplateButton: APPLY_TEMPLATE
ApplyTemplateDescription: Choose a template to apply.
Usage: 'Usage: /dominion member setting <dominion name> <player name> [page]'
SelectPlayer:
Title: Select Player to Add as Member
Description: You can only select players who have logged in
Usage: 'Usage: /dominion member select_player <dominion name> [page number]'
Description: You can only select players who have logged before.
Usage: 'Usage: /dominion member select_player <dominion name> [page]'
SelectTemplate:
Title: Select a Template
Description: Apply to member %s in territory %s
Usage: 'Usage: /dominion member select_template <dominion name> <player name> [page number]'
Description: Apply to %s in %s.
Usage: 'Usage: /dominion member select_template <dominion name> <player name> [page]'
GroupList:
Title: Permission Group List for Territory %s
CreateButton: Create Permission Group
CreateDescription: Create a new permission group
DeleteDescription: Delete permission group %s
EditDescription: Edit permission group %s
AddMemberDescription: Add member to permission group %s
RemoveMemberDescription: Remove %s from permission group %s
Usage: 'Usage: /dominion group list <dominion name> [page number]'
Title: '%s Group List'
CreateButton: CREATE_GROUP
CreateDescription: Create a new group.
DeleteDescription: Delete group %s.
EditDescription: Edit group %s.
AddMemberDescription: Add member to group %s.
RemoveMemberDescription: Remove %s from group %s.
Usage: 'Usage: /dominion group list <dominion name> [page]'
GroupSetting:
RenameButton: Rename this permission group
Usage: 'Usage: /dominion group setting <dominion name> <permission group name> [page number]'
TitleL: 'Permission Group '
RenameButton: RENAME_GROUP
Usage: 'Usage: /dominion group setting <dominion name> <group name> [page]'
TitleL: 'Group '
TitleR: ' Management'
RenameDescription: Rename permission group %s
RenameDescription: Rename group %s.
SelectMember:
Title: Select Member
Description: Select members to add to permission group %s
Usage: 'Usage: /dominion group select_member <dominion name> <permission group name> [echo page number] [page number]'
Description: Select a member to add to group %s.
Usage: 'Usage: /dominion group select_member <dominion name> <group name> [cb page] [page]'
TemplateList:
Title: Member Permission Template List
CreateButton: Create Member Permission Template
CreateDescription: Create a new member permission template
Title: Permission Template List
CreateButton: CREATE_TEMPLATE
CreateDescription: Create a new permission template.
TemplateSetting:
Title: Manage Permissions for Template %s
Title: Template %s Management
Migrate:
Title: Migrate Data from Residence
NoData: You do not have any data to migrate
Button: Migrate
SubDominion: Sub-territories cannot be migrated manually; they will migrate automatically with the parent territory
Title: Migration from Residence
NoData: You do not have any data to migrate.
Button: MIGRATE
SubDominion: Sub-territories cannot be migrated manually, they will migrate automatically with the parent territory.
TitleList:
Title: Permission Group Titles I Can Use
RemoveButton: Remove
ApplyButton: Use
FromDominion: 'From Territory:'
Title: My Group Titles
RemoveButton: UNSET
ApplyButton: USE
FromDominion: 'From Dominion:'
CUI:
Input:
CreateDominion: Enter the name of the territory to create
CreateGroup: Enter the name of the permission group to create
CreateTemplate: Enter the name of the template to create
EditEnterMessage: Edit the territory entry message content
EditLeaveMessage: Edit the territory exit message content
AddMember: Enter player name to add as a member
RenameDominion: Rename Territory
RenameGroup: Rename Permission Group
SetMapColor: Enter the hex color for the satellite map plots
CreateDominion: Type New Dominion Name
CreateGroup: Type New Group Name
CreateTemplate: Type New Template Name
EditEnterMessage: Edit Enter Message
EditLeaveMessage: Edit Leave Message
AddMember: Type Player Name to Add Member
RenameDominion: Rename Dominion
RenameGroup: Rename Group
SetMapColor: Type HEX Color
Config:
Check:
AutoCreateRadiusError: AutoCreateRadius cannot be 0, reset to 10
@ -701,41 +686,41 @@ Utils:
DownloadPage: 'Download page: %s'
CurrentVersion: 'You are currently on the latest version: %s'
GetUpdateFailed: 'Failed to get updates: %s'
NewVersionConsole: 'New version found: %s Check the console for details or click the link below'
VaultNotAvailable: Vault not available
VaultUnlockedNotAvailable: VaultUnlocked not available
NoEconomyPlugin: No available economy plugin
NewVersionConsole: 'New version found: %s . Check the console for details or click the link below'
VaultNotAvailable: Vault not available.
VaultUnlockedNotAvailable: VaultUnlocked not available.
NoEconomyPlugin: No available economy plugin.
TUI:
Navigation: Navigation
Navigation: NAV
NoContent: Uh oh, theres no content here
PageError: Page error
Add: Add
Sub: Subtract
PreviousPage: Previous page
NextPage: Next page
PageError: PAGE ERROR
Add: ADD
Sub: SUB
PreviousPage: '<'
NextPage: '>'
PageL: 'Page '
PageR: ' pages '
PageR: ' '
CUI:
Input: Please enter
InputBox: Input box
NotAvailable: CUI TextInput functionality is not available on non-Paper servers, please use commands to perform corresponding operations.
SuggestCommand: 'Suggested command: %s'
LeftRightClick: Left-click to confirm | Right-click to cancel
NoSpace: Input cannot contain spaces
Input: Please Type Below
InputBox: Text here...
NotAvailable: CUI TextInput functionality is not available on non-Paper servers, please use commands to perform operations.
SuggestCommand: 'Suggestion: %s'
LeftRightClick: 'L-Click: Confirm, R-Click: Cancel'
NoSpace: No spaces allowed.
Database:
Connecting: Connecting to %s database
Connecting: Connecting to %s database...
UnsupportedType: 'Unsupported database type: '
ConnectionFailed: 'Database connection failed: '
ConnectionSuccess: Database connection successful
Reconnecting: Trying to reconnect to the database
ReconnectionSuccess: Database reconnection successful
ReconnectionFailed: Database reconnection failed
ErrorTitle: '=== Critical error ==='
ReconnectionUnexpected: Database connection unexpectedly closed, trying to reconnect
OperationAbort: Operation aborted
ConnectionSuccess: Database connection successful!
Reconnecting: Trying to reconnect to the database...
ReconnectionSuccess: Database reconnection successful!
ReconnectionFailed: Database reconnection failed!
ErrorTitle: '=== CRITICAL DATABASE ERROR ==='
ReconnectionUnexpected: Database connection unexpectedly closed, trying to reconnect...
OperationAbort: Operation aborted!
OperationFailed: 'Database operation failed: '
Closing: Closing database connection
Closed: Database connection closed
Closing: Closing database connection...
Closed: Database connection closed.
CloseFailed: 'Failed to close database connection: '
CheckColumnFailed: Failed to check if column exists
CheckTableFailed: Failed to check if table exists
CheckColumnFailed: Failed to check if column exists.
CheckTableFailed: Failed to check if table exists.

View File

@ -75,19 +75,6 @@ Commands:
ExportedMCAList: '%s に MCA ファイルのリストがエクスポートされました'
ReloadingConfig: 設定ファイルを再読み込みしています...
ReloadedConfig: 設定ファイルが再読み込みされました
SetConfig:
MinYShouldBeLessThanMaxY: 最高Y座標制限は最低Y座標制限より小さくすることはできません
MaxYShouldBeGreaterThanMinY: 最低Y座標制限は最高Y座標制限より大きくすることはできません
SizeXShouldBeGreaterThan4: X軸東西の最大サイズは4未満にできません
SizeZShouldBeGreaterThan4: Z軸南北の最大サイズは4未満にできません
SizeYShouldBeGreaterThan4: Y軸垂直の最大サイズは4未満にできません
AmountShouldBeGreaterThan0: 各プレイヤーの領地数制限は0未満にすることはできません
DepthShouldBeGreaterThan0: 領地の深さ制限は0未満にすることはできません
TpDelayShouldBeGreaterThan0: テレポート遅延は0未満にすることはできません
TpCoolDownShouldBeGreaterThan0: テレポートクールダウンは0未満にすることはできません
PriceShouldBeGreaterThan0: 各ブロック単価は0未満にすることはできません
RefundShouldBeGreaterThan0: 領地の返金率は0未満にすることはできません
SpawnProtectRadiusShouldBeGreaterThan0: スポーンポイント保護半径は0以下にはできません
Template:
CreateTemplateUsage: '使い方: /dominion template create <テンプレート名>'
DeleteTemplateUsage: '使い方: /dominion template delete <テンプレート名>'
@ -299,8 +286,6 @@ TUI:
MigrateDescription: あなたの領地をResidenceからDominionに移行します
AllDominionButton: すべての領地
AllDominionDescription: すべての領地を表示
ConfigButton: システム設定
ConfigDescription: システム設定を表示/変更
ReloadCacheButton: キャッシュをリロード
ReloadCacheDescription: 手動でキャッシュをリロードすると、一部のプレイヤー操作が無効になる問題を解決できます。ただし頻繁に行うことは推奨されません
ReloadConfigButton: 設定をリロード

View File

@ -76,19 +76,6 @@ Commands:
ExportedMCAList: MCA文件名录已导出至 %s
ReloadingConfig: 正重新加载配置文件……
ReloadedConfig: 配置文件已重新加载
SetConfig:
MinYShouldBeLessThanMaxY: 最高Y坐标之限不得小于最低Y坐标之限
MaxYShouldBeGreaterThanMinY: 最低Y坐标之限不得大于最高Y坐标之限
SizeXShouldBeGreaterThan4: X轴东西向之最大尺寸不得小于四
SizeZShouldBeGreaterThan4: Z轴南北向之最大尺寸不得小于四
SizeYShouldBeGreaterThan4: Y轴垂直向之最大尺寸不得小于四
AmountShouldBeGreaterThan0: 每玩家领地数量之限,不得小于零
DepthShouldBeGreaterThan0: 领地深度之限,不得小于零
TpDelayShouldBeGreaterThan0: 传送延迟之时,不得小于零
TpCoolDownShouldBeGreaterThan0: 传送冷却之时,不得小于零
PriceShouldBeGreaterThan0: 每方块单价,不得小于零
RefundShouldBeGreaterThan0: 领地退款之比例,不得小于零
SpawnProtectRadiusShouldBeGreaterThan0: 出生点保护之半径,不得小于或等于零
Template:
CreateTemplateUsage: '用法: /dominion template create <模板名称>'
DeleteTemplateUsage: '用法: /dominion template delete <模板名称>'
@ -300,8 +287,6 @@ TUI:
MigrateDescription: 迁汝之领地从Residence至Dominion
AllDominionButton: 所有领地
AllDominionDescription: 览所有之领地
ConfigButton: 系统配置
ConfigDescription: 览/改系统之配置
ReloadCacheButton: 重载缓存
ReloadCacheDescription: 手刷缓存可解一些玩家操作之无效问题,不建议频操
ReloadConfigButton: 重载配置

View File

@ -73,19 +73,6 @@ Commands:
ExportedMCAList: MCA文件列表已导出到 %s
ReloadingConfig: 正在重新加载配置文件...
ReloadedConfig: 配置文件已重新加载
SetConfig:
MinYShouldBeLessThanMaxY: 最高Y坐标限制不能小于最低Y坐标限制
MaxYShouldBeGreaterThanMinY: 最低Y坐标限制不能大于最高Y坐标限制
SizeXShouldBeGreaterThan4: X轴(东西)最大尺寸不能小于4
SizeZShouldBeGreaterThan4: Z轴(南北)最大尺寸不能小于4
SizeYShouldBeGreaterThan4: Y轴(垂直)最大尺寸不能小于4
AmountShouldBeGreaterThan0: 每个玩家领地数量限制不能小于0
DepthShouldBeGreaterThan0: 领地深度限制不能小于0
TpDelayShouldBeGreaterThan0: 传送延迟不能小于0
TpCoolDownShouldBeGreaterThan0: 传送冷却时间不能小于0
PriceShouldBeGreaterThan0: 每方块单价不能小于0
RefundShouldBeGreaterThan0: 领地退款比例不能小于0
SpawnProtectRadiusShouldBeGreaterThan0: 出生点保护半径不能小于或等于0
Template:
CreateTemplateUsage: '用法: /dominion template create <模板名称>'
DeleteTemplateUsage: '用法: /dominion template delete <模板名称>'
@ -297,8 +284,6 @@ TUI:
MigrateDescription: 把你的领地从Residence迁移到Dominion
AllDominionButton: 所有领地
AllDominionDescription: 查看所有领地
ConfigButton: 系统配置
ConfigDescription: 查看/修改系统配置
ReloadCacheButton: 重载缓存
ReloadCacheDescription: 手动刷新缓存可解决一些玩家操作无效问题,不建议频繁操作
ReloadConfigButton: 重载配置

View File

@ -75,19 +75,6 @@ Commands:
ExportedMCAList: MCA文件列表已導出到 %s
ReloadingConfig: 正在重新加載配置文件...
ReloadedConfig: 配置文件已重新加載
SetConfig:
MinYShouldBeLessThanMaxY: 最高Y坐標限製不能小於最低Y坐標限製
MaxYShouldBeGreaterThanMinY: 最低Y坐標限製不能大於最高Y坐標限製
SizeXShouldBeGreaterThan4: X軸(東西)最大尺寸不能小於4
SizeZShouldBeGreaterThan4: Z軸(南北)最大尺寸不能小於4
SizeYShouldBeGreaterThan4: Y軸(垂直)最大尺寸不能小於4
AmountShouldBeGreaterThan0: 每個玩家領地數量限製不能小於0
DepthShouldBeGreaterThan0: 領地深度限製不能小於0
TpDelayShouldBeGreaterThan0: 傳送延遲不能小於0
TpCoolDownShouldBeGreaterThan0: 傳送冷卻時間不能小於0
PriceShouldBeGreaterThan0: 每方塊單價不能小於0
RefundShouldBeGreaterThan0: 領地退款比例不能小於0
SpawnProtectRadiusShouldBeGreaterThan0: 出生點保護半徑不能小於或等於0
Template:
CreateTemplateUsage: '用法: /dominion template create <模板名稱>'
DeleteTemplateUsage: '用法: /dominion template delete <模板名稱>'
@ -299,8 +286,6 @@ TUI:
MigrateDescription: 把你的領地從Residence遷移到Dominion
AllDominionButton: 所有領地
AllDominionDescription: 查看所有領地
ConfigButton: 系統配置
ConfigDescription: 查看/修改系統配置
ReloadCacheButton: 重載緩存
ReloadCacheDescription: 手動刷新緩存可解決一些玩家操作無效問題,不建議頻繁操作
ReloadConfigButton: 重載配置

View File

@ -3,7 +3,7 @@ plugins {
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
// utf-8

View File

@ -1,7 +1,9 @@
package cn.lunadeer.dominion.events_v1_20_1;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.utils.Particle;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.VaultConnect.VaultConnect;
@ -41,7 +43,7 @@ public class SelectPointEvents implements Listener {
if (action == Action.LEFT_CLICK_BLOCK) {
event.setCancelled(true);
Notification.info(player, "已选择第一个点: %d %d %d", block.getX(), block.getY(), block.getZ());
Notification.info(player, Translation.Tool_SelectFirstPoint, block.getX(), block.getY(), block.getZ());
Location loc = block.getLocation();
if (Dominion.config.getLimitVert(player)) {
loc.setY(Dominion.config.getLimitMinY(player));
@ -49,7 +51,7 @@ public class SelectPointEvents implements Listener {
points.put(0, loc);
} else if (action == Action.RIGHT_CLICK_BLOCK) {
event.setCancelled(true);
Notification.info(player, "已选择第二个点: %d %d %d", block.getX(), block.getY(), block.getZ());
Notification.info(player, Translation.Tool_SelectSecondPoint, block.getX(), block.getY(), block.getZ());
Location loc = block.getLocation();
if (Dominion.config.getLimitVert(player)) {
loc.setY(Dominion.config.getLimitMaxY(player) - 1);
@ -66,10 +68,10 @@ public class SelectPointEvents implements Listener {
return;
}
if (!points.get(0).getWorld().equals(points.get(1).getWorld())) {
Notification.warn(player, "两个点不在同一个世界");
Notification.warn(player, Translation.Tool_NotSameWorld);
return;
}
Notification.info(player, "已选择两个点,可以使用 /dominion create <领地名称> 创建领地");
Notification.info(player, Translation.Tool_SelectTwoPoints);
Location loc1 = points.get(0);
Location loc2 = points.get(1);
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
@ -82,7 +84,7 @@ public class SelectPointEvents implements Listener {
minX, minY, minZ, maxX, maxY, maxZ);
if (Dominion.config.getEconomyEnable()) {
if (!VaultConnect.instance.economyAvailable()) {
Notification.error(player, "计算价格失败,没有可用的经济插件系统,请联系服主。");
Notification.error(player, Translation.Messages_NoEconomyPlugin);
return;
}
int count;
@ -92,13 +94,38 @@ public class SelectPointEvents implements Listener {
count = dominion.getVolume();
}
float price = count * Dominion.config.getEconomyPrice(player);
Notification.info(player, "预计领地创建价格为 %.2f %s", price, VaultConnect.instance.currencyNamePlural());
Notification.info(player, Translation.Tool_CreateDominionPrice, price, VaultConnect.instance.currencyNamePlural());
}
Particle.showBorder(player, dominion);
Notification.info(player, "尺寸: %d x %d x %d", dominion.getWidthX(), dominion.getHeight(), dominion.getWidthZ());
Notification.info(player, "面积: %d", dominion.getSquare());
Notification.info(player, "高度: %d", dominion.getHeight());
Notification.info(player, "体积: %d", dominion.getVolume());
Notification.info(player, Translation.Tool_DominionSize, dominion.getWidthX(), dominion.getHeight(), dominion.getWidthZ());
Notification.info(player, Translation.Tool_DominionSquare, dominion.getSquare());
Notification.info(player, Translation.Tool_DominionHeight, dominion.getHeight());
Notification.info(player, Translation.Tool_DominionVolume, dominion.getVolume());
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void selectBlockToShowInfo(PlayerInteractEvent event) {
Player player = event.getPlayer();
ItemStack item = player.getInventory().getItemInMainHand();
if (item.getType() != Dominion.config.getInfoTool()) {
return;
}
if (event.getAction() != Action.LEFT_CLICK_BLOCK) {
return;
}
event.setCancelled(true);
Block block = event.getClickedBlock();
if (block == null) {
return;
}
DominionDTO dominion = Cache.instance.getDominionByLoc(block.getLocation());
if (dominion == null) {
Notification.info(player, Translation.Tool_LocationNotInDominion, block.getX(), block.getY(), block.getZ());
} else {
Notification.info(player, Translation.Tool_LocationInDominion, block.getX(), block.getY(), block.getZ(), dominion.getName());
Notification.info(player, Translation.Tool_DominionOwner, Cache.instance.getPlayerName(dominion.getOwner()));
}
}
}

View File

@ -12,16 +12,15 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.event.Listener;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static cn.lunadeer.dominion.utils.EventUtils.checkFlag;
public class Spigot implements Listener {
static {
Map<UUID, Location> entityMap = new HashMap<>();
ConcurrentHashMap<UUID, Location> entityMap = new ConcurrentHashMap<>();
Scheduler.runTaskRepeat(() -> {
Dominion.instance.getServer().getWorlds().forEach(world -> {
world.getEntities().forEach(entity -> {

View File

@ -1,7 +1,9 @@
package cn.lunadeer.dominion.events_v1_21;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.utils.Particle;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.VaultConnect.VaultConnect;
@ -41,7 +43,7 @@ public class SelectPointEvents implements Listener {
if (action == Action.LEFT_CLICK_BLOCK) {
event.setCancelled(true);
Notification.info(player, "已选择第一个点: %d %d %d", block.getX(), block.getY(), block.getZ());
Notification.info(player, Translation.Tool_SelectFirstPoint, block.getX(), block.getY(), block.getZ());
Location loc = block.getLocation();
if (Dominion.config.getLimitVert(player)) {
loc.setY(Dominion.config.getLimitMinY(player));
@ -49,7 +51,7 @@ public class SelectPointEvents implements Listener {
points.put(0, loc);
} else if (action == Action.RIGHT_CLICK_BLOCK) {
event.setCancelled(true);
Notification.info(player, "已选择第二个点: %d %d %d", block.getX(), block.getY(), block.getZ());
Notification.info(player, Translation.Tool_SelectSecondPoint, block.getX(), block.getY(), block.getZ());
Location loc = block.getLocation();
if (Dominion.config.getLimitVert(player)) {
loc.setY(Dominion.config.getLimitMaxY(player) - 1);
@ -66,10 +68,10 @@ public class SelectPointEvents implements Listener {
return;
}
if (!points.get(0).getWorld().equals(points.get(1).getWorld())) {
Notification.warn(player, "两个点不在同一个世界");
Notification.warn(player, Translation.Tool_NotSameWorld);
return;
}
Notification.info(player, "已选择两个点,可以使用 /dominion create <领地名称> 创建领地");
Notification.info(player, Translation.Tool_SelectTwoPoints);
Location loc1 = points.get(0);
Location loc2 = points.get(1);
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
@ -82,7 +84,7 @@ public class SelectPointEvents implements Listener {
minX, minY, minZ, maxX, maxY, maxZ);
if (Dominion.config.getEconomyEnable()) {
if (!VaultConnect.instance.economyAvailable()) {
Notification.error(player, "计算价格失败,没有可用的经济插件系统,请联系服主。");
Notification.error(player, Translation.Messages_NoEconomyPlugin);
return;
}
int count;
@ -92,13 +94,38 @@ public class SelectPointEvents implements Listener {
count = dominion.getVolume();
}
float price = count * Dominion.config.getEconomyPrice(player);
Notification.info(player, "预计领地创建价格为 %.2f %s", price, VaultConnect.instance.currencyNamePlural());
Notification.info(player, Translation.Tool_CreateDominionPrice, price, VaultConnect.instance.currencyNamePlural());
}
Particle.showBorder(player, dominion);
Notification.info(player, "尺寸: %d x %d x %d", dominion.getWidthX(), dominion.getHeight(), dominion.getWidthZ());
Notification.info(player, "面积: %d", dominion.getSquare());
Notification.info(player, "高度: %d", dominion.getHeight());
Notification.info(player, "体积: %d", dominion.getVolume());
Notification.info(player, Translation.Tool_DominionSize, dominion.getWidthX(), dominion.getHeight(), dominion.getWidthZ());
Notification.info(player, Translation.Tool_DominionSquare, dominion.getSquare());
Notification.info(player, Translation.Tool_DominionHeight, dominion.getHeight());
Notification.info(player, Translation.Tool_DominionVolume, dominion.getVolume());
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void selectBlockToShowInfo(PlayerInteractEvent event) {
Player player = event.getPlayer();
ItemStack item = player.getInventory().getItemInMainHand();
if (item.getType() != Dominion.config.getInfoTool()) {
return;
}
if (event.getAction() != Action.LEFT_CLICK_BLOCK) {
return;
}
event.setCancelled(true);
Block block = event.getClickedBlock();
if (block == null) {
return;
}
DominionDTO dominion = Cache.instance.getDominionByLoc(block.getLocation());
if (dominion == null) {
Notification.info(player, Translation.Tool_LocationNotInDominion, block.getX(), block.getY(), block.getZ());
} else {
Notification.info(player, Translation.Tool_LocationInDominion, block.getX(), block.getY(), block.getZ(), dominion.getName());
Notification.info(player, Translation.Tool_DominionOwner, Cache.instance.getPlayerName(dominion.getOwner()));
}
}
}

View File

@ -12,16 +12,15 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.event.Listener;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static cn.lunadeer.dominion.utils.EventUtils.checkFlag;
public class Spigot implements Listener {
static {
Map<UUID, Location> entityMap = new HashMap<>();
ConcurrentHashMap<UUID, Location> entityMap = new ConcurrentHashMap<>();
Scheduler.runTaskRepeat(() -> {
Dominion.instance.getServer().getWorlds().forEach(world -> {
world.getEntities().forEach(entity -> {