Compare commits

...

98 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
a350e01e4b 实现了 api 支持 2024-09-23 15:04:56 +08:00
5bdd15f442 初步完成API定义 2024-09-23 00:54:16 +08:00
bc2c66bdd9 尝试添加api 2024-09-22 23:45:10 +08:00
e8271927ea 移除 WorldSettings 中的 Allow 配置
该功能本质上为 Limits.Amount,通过配置一个世界的数量为 0 可达到同样的效果。
2024-09-22 17:49:59 +08:00
ab0f2a95dd 修复文档无法查看访客权限文档的问题 2024-09-20 17:02:29 +08:00
6789828dec 介绍文档新增五张笑脸(中文特供) 2024-09-20 16:56:32 +08:00
0611600a72
Merge pull request #21 from cygbs/master
增文言以供古人用之。
2024-09-20 09:36:13 +08:00
cygbs
38c780302d
Fix some issues. 2024-09-20 04:26:33 +08:00
8dc6190f57 新增 PR action 自动检查 2024-09-19 21:27:11 +08:00
cygbs
6ed1f2eaf5
增文言以供古人用之。
为增插件之通用性,特此撰一文言翻译并交以「PR」。望君笑纳!
2024-09-19 18:39:26 +08:00
ff23753c62 补充了文档关于多语言更新说明 2024-09-19 17:26:00 +08:00
72a5a84a65 修复了在1.21中风弹的击退效果无法被拦截的漏洞 #17 2024-09-19 14:44:08 +08:00
99405c3828 领地环境设置新增“允许外部重力方块落入”权限 #18
如果禁止则领地外的重力方块进入领地触地时会变为掉落物,该权限默认为禁止
2024-09-19 14:22:13 +08:00
3a08f41906 新增 MessageDisplay 配置,允许服务器管理员配置消息提示位置 #20 2024-09-18 17:18:04 +08:00
b818fc2153 领地进入/离开提示语新增彩色支持,同时新增部分 Papi 变量 #20 2024-09-18 14:56:28 +08:00
bac6f90196 modify issue template 2024-09-17 20:34:08 +08:00
b6f0d8f8ef add translate note 2024-09-13 09:55:49 +08:00
9f788ae26d 整个烂活儿 2024-09-13 00:34:33 +08:00
e12dd87173 fix translate error 2024-09-12 13:38:20 +08:00
618b5c1810 modify language file load logic 2024-09-12 13:15:52 +08:00
66af44e789 add language support: en-us, ja-jp 2024-09-12 11:41:59 +08:00
dbbcf45266 更新了文档以及关联下载地址页面 2024-09-11 23:39:55 +08:00
b82e6d2364 测试 hangar 发布脚本 2024-09-11 16:09:26 +08:00
278de184ae 测试 hangar 发布脚本 2024-09-11 15:18:06 +08:00
268d17bd4f 测试 hangar 发布脚本 2024-09-11 15:03:47 +08:00
e126a2629e 测试 hangar 发布脚本 2024-09-11 14:26:30 +08:00
1ba7de75cb 测试 hangar 发布脚本 2024-09-11 14:12:29 +08:00
9113d3a043 测试modrinth发布脚本 2024-09-11 11:27:58 +08:00
a12775e0ff 测试modrinth发布脚本 2024-09-11 11:17:23 +08:00
f9a5535c3f 测试modrinth发布脚本 2024-09-11 11:14:19 +08:00
ea8c171858 测试modrinth发布脚本 2024-09-11 11:01:30 +08:00
5d890bc957 测试modrinth发布脚本 2024-09-11 10:53:26 +08:00
864bb65376 测试modrinth发布脚本 2024-09-11 10:40:54 +08:00
4effb8a829 测试modrinth发布脚本 2024-09-11 10:37:09 +08:00
555bb68af3 flags.yml 新增自动注释 便于查看权限功能 2024-09-10 22:20:44 +08:00
0a8e1935be 增加 en-us 文档 2024-09-10 17:37:27 +08:00
bb5d95a6f8 更新readme 2024-09-10 17:02:14 +08:00
d39d1981f2 更新readme 2024-09-10 17:00:09 +08:00
59668604c1 更新readme 2024-09-10 16:58:27 +08:00
c3a2b5db13 更新readme 2024-09-10 16:55:25 +08:00
35ed249fbb 更新readme 2024-09-10 16:45:12 +08:00
cb24f91208 更新readme 2024-09-10 14:22:31 +08:00
456859b645 更新readme 2024-09-10 14:02:52 +08:00
57bc5ada44 更新readme 2024-09-10 12:00:47 +08:00
a0f7ba8a45 更新readme 2024-09-10 11:57:24 +08:00
4a1aecf31a 新增 bedrock ui 分支 2024-09-10 10:19:16 +08:00
d6bb84d777 引入部分文档的多语言 2024-09-08 19:22:38 +08:00
ac995b5c62 引入部分文档的多语言 2024-09-08 19:19:45 +08:00
1f824bc0b9 引入部分文档的多语言 2024-09-08 19:06:48 +08:00
a41e245f5e 引入部分文档的多语言 2024-09-08 18:55:11 +08:00
e995af24fd 引入部分文档的多语言 2024-09-08 18:48:21 +08:00
c541a63ee0 引入部分文档的多语言 2024-09-08 18:36:46 +08:00
48d8742bec 引入部分文档的多语言 2024-09-08 18:26:58 +08:00
e52b4426e7 引入部分文档的多语言 2024-09-08 18:26:45 +08:00
3a9fcc89ad 引入部分文档的多语言 2024-09-08 18:20:46 +08:00
9a402199d1 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	build.gradle.kts
2024-09-08 18:12:30 +08:00
e90f7f674c 引入部分文档的多语言 2024-09-08 18:08:49 +08:00
e158066d88 补充了关于 Residence 领地迁移的文档 2024-09-06 17:31:04 +08:00
18632f9094 卫星地图展示新增所有人名称 #12 2024-09-06 17:25:49 +08:00
04c3036f2c 补充 zh-cn 相关翻译字段 #10 2024-09-06 17:12:12 +08:00
173 changed files with 6403 additions and 559 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

@ -15,10 +15,9 @@ assignees: ''
Bug复现步骤
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
1. 打开冰箱;
2. 将大象放入冰箱;
3. 关上冰箱。
**正常情况的表现**
@ -33,6 +32,7 @@ Bug复现步骤
- 服务器系统win, linux
- 服务端核心Paper、Spigot
- 服务端版本:
- 客户端版本:
- 插件版本:
**补充信息**

21
.github/workflows/check.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: Merge/PR Build Check
on: [ pull_request ]
jobs:
build:
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: "Set up JDK 21"
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'zulu'
cache: gradle
- name: "Build with Gradle"
run: ./gradlew buildPlugin
- name: "Done!"
run: |
echo "done!"

View File

@ -12,24 +12,51 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 21
- name: "Set up JDK 21"
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'zulu'
cache: gradle
- name: "Build with Gradle"
run: ./gradlew buildPlugin
- name: "Copy jar to staging"
run: mkdir staging && cp build/libs/*.jar staging/
run: |
./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\///')
echo "done!"
- uses: "marvinpinto/action-automatic-releases@latest"
- name: "GitHub Release"
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "${{ steps.build.outputs.TAG }}"
prerelease: false
files: |
staging/*.jar
- name: "Modrinth Release"
uses: dsx137/modrinth-release-action@main
env:
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
with:
name: ${{ env.AUTOMATIC_RELEASES_TAG }}
project_id: vVZc7jAV
loaders: bukkit,folia,paper,purpur,spigot
game_versions: 1.20.1:1.20.6,1.21,1.21.1
version_number: ${{ env.AUTOMATIC_RELEASES_TAG }}
files: |
staging/*-lite.jar
changelog: "See https://github.com/ColdeZhang/Dominion/releases/tag/${{ env.AUTOMATIC_RELEASES_TAG }}"
version_type: beta
featured: false
updatable: false
delete_old_files: false
- name: "Hangar Release"
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_API_TOKEN }}
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

65
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,65 @@
# Contributing to Dominion
Thank you for considering contributing to Dominion! We welcome contributions from everyone. By participating in this
project, you agree to abide by our code of conduct.
## How to Contribute
### 🪲Reporting Bugs
If you find a bug, please report it by opening an issue on our GitHub repository. Include as much detail as possible,
including steps to reproduce the issue, the expected result, and the actual result.
### 💡Suggesting Enhancements
We welcome suggestions for new features or improvements. Please open an issue on our GitHub repository and describe the
enhancement you would like to see, why you think it would be useful, and any other relevant information.
### 🌐Translating
#### **Translate Plugin Messages**
Since the plugin messages are translated by AI, there must be some mistakes in the translation. If you find any mistakes
(or inappropriate translations), there are two ways to help us improve the translation:
1. Fork the repository & clone the repository to your local.
2. Create a new branch for your translation.
3. Translate the plugin messages.
4. Commit & Push your changes to your fork.
5. Open a pull request, wait for your pull request to be reviewed and merged.
Plugin messages are located in the `languages` directory. Translate the files in the language you want to
- If the language you want to translate to does not exist, create a new file with the language code (e.g., `zh-cn.yml`
for Simplified Chinese).
- If the translation is not up-to-date, please update it from the `zh-cn.yml` file.
- Don't forget to leave your name in the header-comment of the file.
> Plugin messages was uploaded to Crowdin too, you can directly modify the translation on
> the [Crowdin project](https://crowdin.com/project/dominion).
>
> But we **NOT RECOMMEND** this way, because the translation on Crowdin may not be the latest.
>
> ![Crowdin](https://badges.crowdin.net/dominion/localized.svg)
#### **Translate Documentation**
1. Fork the repository & clone the repository to your local.
2. Create a new branch for your translation.
3. Translate the documentation or plugin messages.
4. Commit & Push your changes to your fork.
5. Open a pull request, wait for your pull request to be reviewed and merged.
Documentations are located in the `docs` directory. Translate the files in the language you want to contribute to.
- If the language you want to translate to does not exist, create a new directory with the language code (e.g., `zh-cn`
for Simplified Chinese).
- If the documentation is not up-to-date, please update it from the `zh-cn` directory.
- Don't forget to leave your name and contact information in `docs/YOUR_LANGUAGE_CODE/README.md` below.
## 🫴Getting Help
If you need help, feel free to ask questions by opening an issue on our GitHub repository.
Thank you for contributing ❤!

View File

@ -1,52 +1,55 @@
<div align="center">
<img src="https://ssl.lunadeer.cn:14437/i/2024/03/28/6604f0cec0f0e.png" alt="" width="70%">
<img src="logos/logo3.png" alt="" width="30%">
[![GitHub Repository](https://img.shields.io/badge/GitHub-开源地址-blue?logo=github)](https://github.com/ColdeZhang/Dominion)
[![Documentation](https://img.shields.io/badge/Document-Online-70f3ff?logo=readthedocs)](https://dominion.lunadeer.cn/)
[![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/Hangar-Project-bacac6?logo=paper)](https://hangar.papermc.io/zhangyuheng/Dominion)
[![Documentation](https://img.shields.io/badge/在线文档-点击跳转-70f3ff?logo=readthedocs)](https://dominion.lunadeer.cn/)
[![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)
[![Latest Build](https://img.shields.io/github/v/release/ColdeZhang/Dominion?label=LatestBuild&logo=github&color=0aa344)](https://github.com/ColdeZhang/Dominion/releases/latest)
[![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/)
</div>
---
## 简介
[中文(简体)](README_zh.md) | English
鉴于 Residence 插件的作者项目较多维护压力大无法及时跟进新版本以及适配Folia核心。故开发此插件旨在平替纯净版生存服Residence的使用支持从
Res 迁移数据)。
## What's this?
**请注意本插件目前处于中期测试稳定阶段绝大多数bug或漏洞已被修复目前已具备完全可用性。但不排除仍然存在某些问题如果遇到任何BUG 欢迎及时在仓库提交 ISSUE 或添加QQ群告知感激不尽。**
Dominion is a completely open-source, free, future-proof, territory anti-grief plugin developed specifically for
high-versions minecraft server. The plugin is currently undergoing rapid development and iteration, and we will do our
best to ensure the stability and functionality of the plugin.
## 功能介绍
<div align="center">
<img src="resource/img/tui.png" alt="" width="100%"/>
<img src="resource/img/manage.png" alt="" width="100%"/>
<img src="resource/img/migration.png" alt="" width="100%"/>
<img src="resource/img/db.png" alt="" width="100%"/>
<img src="resource/img/performance.png" alt="" width="100%"/>
</div>
For detail functions and features of Dominion, you can view [Introduction](intro/intro_en-us.md)
## 支持版本
## Version Support
- 1.20.1+ (Bukkit、Spigot、Paper、Folia)
> 需要使用 Java21 运行你的服务端,如果你还在使用 Java17 可以放心替换为 Java21理论上 1.20.1+ 版本的服务端核心可以直接升级到
> 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.
> 虽然本插件支持 Spigot但是我们强烈建议您将您的核心升级到 Paper 或其分支核心(如 Purpur以获得更好的性能体验。
## For developer
## 建议与反馈
Dominion provides some simple (for now) APIs for developers to build something amazing depends on Dominion. You can
take a look at [Developer](docs/en-us/developer.md) for more details.
请优先在 [GitHub ISSUE](https://github.com/ColdeZhang/Dominion/issues) 提交您的问题
## Help us improve
QQ群309428300
If you encounter any problems during use or have any suggestions, please feel free to open
a [GitHub ISSUE](https://github.com/ColdeZhang/Dominion/issues) about your questions or ideas.
## 统计
For detailed contribution guidelines (such as **translation** etc.), please see [CONTRIBUTING](CONTRIBUTING.md)。
> **This project was developed under chinese-simplified originally. It's Multi-Language was translated by AI currently.**
> **So, there must be some mistakes in the translation. If you find any mistakes (or inappropriate translations), please**
> **feel free to modify it and submit a pull request. See [Translating](CONTRIBUTING.md#translating) for more details.**
## bStats Statics
<div align="center">
<img src="https://bstats.org/signatures/bukkit/Dominion.svg" alt="" width="100%">

61
README_zh.md Normal file
View File

@ -0,0 +1,61 @@
<div align="center">
<img src="logos/logo3.png" alt="" width="30%">
[![Documentation](https://img.shields.io/badge/在线文档-点击跳转-70f3ff?logo=readthedocs)](https://dominion.lunadeer.cn/)
[![GitHub Repository](https://img.shields.io/badge/开源地址-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)
[![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)
[![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/)
</div>
---
中文(简体) | [English](README.md)
## 简介
Dominion 是一个完全开源、免费,专为高版本开发,面向未来的全新领地保护插件。插件目前处于快速的开发、迭代阶段,我们会尽力保证插件的稳定性和功能性。
关于本插件的功能特性,您可以查看 [功能介绍](intro/intro_zh-cn.md)。
## 支持版本
- 1.20.1+ (Bukkit、Spigot、Paper、Folia)
> 虽然本插件支持 Spigot但是我们强烈建议您将您的核心升级到 Paper 或其分支核心(如 Purpur以获得更好的性能体验。
## 帮助我们不断改进
如果您在使用过程中遇到任何问题,或者有任何建议,欢迎在 [GitHub ISSUE](https://github.com/ColdeZhang/Dominion/issues) 提交您的问题或想法。
详细的参与贡献指南请查看 [CONTRIBUTING](CONTRIBUTING.md)。
交流QQ群309428300
## 开发者指南
Dominion 提供了一些简单只是暂时后续会逐步增强api的 API 供开发者基于 Dominion
构建一些更有趣的东西。您可以查看 [开发者指南](docs/zh-cn/developer.md) 了解更多细节。
## 整个烂活儿
| | Dominion | R插件 | G插件 |
|---------|----------|-----|-----|
| 纳秒级索引 | 😊 | 😑 | 😭 |
| 权限组快捷配置 | 😊 | 😭 | 😑 |
| 开源可信 | 😊 | 😑 | 😑 |
| 高版本快速跟进 | 😊 | 😭 | 😑 |
| 完全免费 | 😊 | 😑 | 😑 |
## 统计
<div align="center">
<img src="https://bstats.org/signatures/bukkit/Dominion.svg" alt="" width="100%">
</div>

1
api Submodule

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

View File

@ -1,13 +1,20 @@
import io.papermc.hangarpublishplugin.model.Platforms
plugins {
id("java")
id("com.github.johnrengelman.shadow") version "8.1.1"
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.6.0-beta"
version = "2.14.1-beta"
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
// utf-8
@ -26,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/")
}
@ -35,17 +41,37 @@ allprojects {
compileOnly("us.dynmap:DynmapCoreAPI:3.4")
compileOnly("me.clip:placeholderapi:2.11.6")
implementation("cn.lunadeer:MinecraftPluginUtils:1.3.8-SNAPSHOT")
implementation("org.yaml:snakeyaml:2.0")
if (!BuildFull) {
libraries.forEach {
compileOnly(it)
}
} else {
libraries.forEach {
implementation(it)
}
}
}
tasks.processResources {
outputs.upToDateWhen { false }
// copy languages folder from PROJECT_DIR/languages to core/src/main/resources
from(file("${projectDir}/languages")) {
into("languages")
}
// replace @version@ in plugin.yml with project version
filesMatching("**/plugin.yml") {
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) + "]")
}
}
}
}
@ -53,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")
}
}
@ -67,7 +95,29 @@ 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)
}
hangarPublish {
publications.register("plugin") {
version.set(project.version as String) // use project version as publication version
id.set("Dominion")
channel.set("Beta")
changelog.set("See https://github.com/ColdeZhang/Dominion/releases/tag/v${project.version}")
apiKey.set(System.getenv("HANGAR_TOKEN"))
// register platforms
platforms {
register(Platforms.PAPER) {
jar.set(tasks.shadowJar.flatMap { it.archiveFile })
println("ShadowJar: ${tasks.shadowJar.flatMap { it.archiveFile }}")
platformVersions.set(listOf("1.20.1-1.20.6","1.21.x"))
}
}
}
}
tasks.named("publishPluginPublicationToHangar") {
dependsOn(tasks.named("jar"))
}

View File

@ -3,7 +3,7 @@ plugins {
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
// utf-8
@ -12,5 +12,6 @@ tasks.withType<JavaCompile> {
}
dependencies {
implementation(project(":api"))
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
}

View File

@ -1,11 +1,12 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.api.DominionAPI;
import cn.lunadeer.dominion.dtos.*;
import cn.lunadeer.dominion.utils.map.MapRender;
import cn.lunadeer.dominion.utils.MessageDisplay;
import cn.lunadeer.dominion.utils.Particle;
import cn.lunadeer.dominion.utils.ResMigration;
import cn.lunadeer.dominion.utils.map.MapRender;
import cn.lunadeer.minecraftpluginutils.AutoTimer;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.GameMode;
@ -205,16 +206,7 @@ public class Cache {
});
}
/**
* 获取玩家当前所在领地
* 此方法会先判断缓存中是否有玩家当前所在领地如果没有则遍历所有领地判断玩家所在位置
* 如果玩家不在任何领地内则返回null
* 如果玩家在领地内则返回领地信息
*
* @param player 玩家
* @return 玩家当前所在领地
*/
public DominionDTO getPlayerCurrentDominion(Player player) {
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());
DominionDTO last_dominion = null;
@ -239,14 +231,18 @@ public class Cache {
return last_dominion;
}
if (last_dom_id != -1) {
String msg = last_dominion.getLeaveMessage();
msg = msg.replace("${DOM_NAME}", last_dominion.getName());
Notification.actionBar(player, msg);
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) {
String msg = current_dominion.getJoinMessage();
msg = msg.replace("${DOM_NAME}", current_dominion.getName());
Notification.actionBar(player, msg);
MessageDisplay.show(player, Dominion.config.getMessageDisplayJoinLeave(),
current_dominion.getJoinMessage()
.replace("{DOM}", current_dominion.getName())
.replace("{OWNER}", getPlayerName(current_dominion.getOwner()))
);
}
lightOrNot(player, current_dominion); // 发光检查
@ -264,6 +260,10 @@ public class Cache {
}
}
public DominionDTO getDominionByLoc(@NotNull Location loc) {
return dominion_trees.getLocInDominionDTO(loc);
}
/**
* 玩家退出时调用 用于清除玩家当前所在领地
* 会将玩家当前所在领地设置为null
@ -343,28 +343,16 @@ public class Cache {
}
}
public DominionDTO getDominionByLoc(Location loc) {
return dominion_trees.getLocInDominionDTO(loc);
}
public GroupDTO getGroup(Integer id) {
public GroupDTO getGroup(@NotNull Integer id) {
return id_groups.get(id);
}
/**
* 获取玩家在指定领地的特权
* 如果玩家不存在特权则返回null
*
* @param player 玩家
* @param dominion 领地
* @return 特权表
*/
public MemberDTO getMember(Player player, DominionDTO dominion) {
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());
}
public MemberDTO getMember(UUID player_uuid, DominionDTO dominion) {
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());
}
@ -383,10 +371,20 @@ public class Cache {
return groups;
}
public DominionDTO getDominion(Integer id) {
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()) {
@ -416,7 +414,7 @@ public class Cache {
return residence_data.get(player_uuid);
}
public List<DominionDTO> getDominions() {
public @NotNull List<cn.lunadeer.dominion.api.dtos.DominionDTO> getAllDominions() {
return new ArrayList<>(id_dominions.values());
}
@ -452,6 +450,7 @@ public class Cache {
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;
@ -595,7 +594,7 @@ public class Cache {
}
}
public @Nullable GroupDTO getPlayerUsingGroupTitle(UUID uuid) {
public @Nullable GroupDTO getPlayerUsingGroupTitle(@NotNull UUID uuid) {
if (!Dominion.config.getGroupTitleEnable()) {
return null;
}

View File

@ -2,15 +2,18 @@ package cn.lunadeer.dominion;
import cn.lunadeer.dominion.commands.*;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.cuis.*;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.*;
import cn.lunadeer.dominion.tuis.dominion.DominionList;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.tuis.dominion.manage.EnvSetting;
import cn.lunadeer.dominion.tuis.dominion.manage.GuestSetting;
import cn.lunadeer.dominion.tuis.dominion.manage.SizeInfo;
import cn.lunadeer.dominion.uis.cuis.*;
import cn.lunadeer.dominion.uis.tuis.AllDominion;
import cn.lunadeer.dominion.uis.tuis.Menu;
import cn.lunadeer.dominion.uis.tuis.MigrateList;
import cn.lunadeer.dominion.uis.tuis.TitleList;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionList;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.EnvSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.GuestSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.SizeInfo;
import cn.lunadeer.dominion.utils.TuiUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -115,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;
@ -213,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,14 +39,14 @@ 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 {
XLogger.warn(Translation.Messages_PlaceholderAPINotFound);
config.setGroupTitleEnable(false);
}
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
new PlaceHolderApi(this);
}
if (config.getGroupTitleEnable() && !Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
XLogger.warn(Translation.Messages_PlaceholderAPINotFound);
config.setGroupTitleEnable(false);
}
new EventsRegister(this);

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

@ -4,8 +4,8 @@ import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.FlagsController;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.manage.EnvSetting;
import cn.lunadeer.dominion.tuis.dominion.manage.GuestSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.EnvSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.GuestSetting;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;

View File

@ -3,9 +3,9 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.GroupController;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.manage.group.GroupList;
import cn.lunadeer.dominion.tuis.dominion.manage.group.GroupSetting;
import cn.lunadeer.dominion.tuis.dominion.manage.group.SelectMember;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.group.GroupList;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.group.GroupSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.group.SelectMember;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;

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,10 +3,10 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.MemberController;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.manage.member.MemberList;
import cn.lunadeer.dominion.tuis.dominion.manage.member.MemberSetting;
import cn.lunadeer.dominion.tuis.dominion.manage.member.SelectPlayer;
import cn.lunadeer.dominion.tuis.dominion.manage.member.SelectTemplate;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.member.MemberList;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.member.MemberSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.member.SelectPlayer;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.member.SelectTemplate;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;

View File

@ -6,7 +6,7 @@ import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.MigrateList;
import cn.lunadeer.dominion.uis.tuis.MigrateList;
import cn.lunadeer.dominion.utils.ResMigration;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;

View File

@ -2,7 +2,8 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
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;
@ -52,7 +53,7 @@ public class Operator {
Scheduler.runTaskAsync(() -> {
Notification.info(sender, Translation.Commands_Operator_ExportingMCAList);
Map<String, List<String>> mca_cords = new HashMap<>();
List<DominionDTO> doms = Cache.instance.getDominions();
List<DominionDTO> doms = Cache.instance.getAllDominions();
for (DominionDTO dom : doms) {
if (dom.getWorld() == null) {
continue;
@ -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

@ -3,8 +3,8 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.TemplateController;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.template.TemplateList;
import cn.lunadeer.dominion.tuis.template.TemplateSetting;
import cn.lunadeer.dominion.uis.tuis.template.TemplateList;
import cn.lunadeer.dominion.uis.tuis.template.TemplateSetting;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

View File

@ -6,7 +6,7 @@ import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.TitleList;
import cn.lunadeer.dominion.uis.tuis.TitleList;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -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

@ -2,6 +2,7 @@ package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.api.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
@ -10,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;
@ -17,7 +19,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class DominionDTO {
public class DominionDTO implements cn.lunadeer.dominion.api.dtos.DominionDTO {
private static List<DominionDTO> query(String sql, Object... args) {
List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, args)) {
@ -45,7 +47,7 @@ public class DominionDTO {
Integer parentDomId = rs.getInt("parent_dom_id");
String tp_location = rs.getString("tp_location");
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getDominionFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getDominionFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
String color = rs.getString("color");
@ -88,7 +90,7 @@ public class 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) {
@ -112,7 +114,7 @@ public class 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) {
@ -125,14 +127,14 @@ public class DominionDTO {
.field(dominion.parentDomId)
.field(dominion.joinMessage).field(dominion.leaveMessage)
.field(dominion.tp_location);
for (Flag f : Flag.getDominionFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getDominionFlagsEnabled()) {
insert.field(new Field(f.getFlagName(), f.getDefaultValue()));
}
try (ResultSet rs = insert.execute()) {
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;
@ -185,6 +187,8 @@ public class 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,
@ -207,8 +211,8 @@ public class 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", "欢迎来到 ${DOM_NAME}");
private final Field leaveMessage = new Field("leave_message", "你正在离开 ${DOM_NAME},欢迎下次光临~");
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");
@ -216,11 +220,13 @@ public class DominionDTO {
// getters and setters
public Integer getId() {
@Override
public @NotNull Integer getId() {
return (Integer) id.value;
}
public UUID getOwner() {
@Override
public @NotNull UUID getOwner() {
return UUID.fromString((String) owner.value);
}
@ -232,36 +238,48 @@ public class 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));
}
public String getName() {
@Override
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));
}
@Override
public @Nullable World getWorld() {
return Dominion.instance.getServer().getWorld(getWorldUid());
}
public UUID getWorldUid() {
@Override
public @NotNull UUID getWorldUid() {
return UUID.fromString((String) world_uid.value);
}
public Integer getX1() {
@Override
public @NotNull Integer getX1() {
return (Integer) x1.value;
}
@ -270,7 +288,8 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.x1));
}
public Integer getY1() {
@Override
public @NotNull Integer getY1() {
return (Integer) y1.value;
}
@ -279,7 +298,8 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.y1));
}
public Integer getZ1() {
@Override
public @NotNull Integer getZ1() {
return (Integer) z1.value;
}
@ -288,7 +308,8 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.z1));
}
public Integer getX2() {
@Override
public @NotNull Integer getX2() {
return (Integer) x2.value;
}
@ -297,7 +318,8 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.x2));
}
public Integer getY2() {
@Override
public @NotNull Integer getY2() {
return (Integer) y2.value;
}
@ -306,7 +328,8 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.y2));
}
public Integer getZ2() {
@Override
public @NotNull Integer getZ2() {
return (Integer) z2.value;
}
@ -315,43 +338,53 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.z2));
}
public Integer getSquare() {
@Override
public @NotNull Integer getSquare() {
return getWidthX() * getWidthZ();
}
public Integer getVolume() {
@Override
public @NotNull Integer getVolume() {
return getSquare() * getHeight();
}
public Integer getWidthX() {
@Override
public @NotNull Integer getWidthX() {
return getX2() - getX1();
}
public Integer getHeight() {
@Override
public @NotNull Integer getHeight() {
return getY2() - getY1();
}
public Integer getWidthZ() {
@Override
public @NotNull Integer getWidthZ() {
return getZ2() - getZ1();
}
public Integer getParentDomId() {
@Override
public @NotNull Integer getParentDomId() {
return (Integer) parentDomId.value;
}
public String getJoinMessage() {
@Override
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));
}
public String getLeaveMessage() {
@Override
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));
@ -362,12 +395,28 @@ public class DominionDTO {
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;
@ -375,9 +424,25 @@ public class 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]);
@ -388,6 +453,7 @@ public class DominionDTO {
}
@Override
public Location getTpLocation() {
if (Objects.equals(tp_location.value, "default")) {
return null;
@ -410,11 +476,13 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(tp_location));
}
public Location getLocation1() {
@Override
public @NotNull Location getLocation1() {
return new Location(getWorld(), getX1(), getY1(), getZ1());
}
public Location getLocation2() {
@Override
public @NotNull Location getLocation2() {
return new Location(getWorld(), getX2(), getY2(), getZ2());
}
@ -423,22 +491,27 @@ public class DominionDTO {
return doUpdate(new UpdateRow().field(this.color));
}
@Override
public int getColorR() {
return Integer.valueOf(getColor().substring(1, 3), 16);
}
@Override
public int getColorG() {
return Integer.valueOf(getColor().substring(3, 5), 16);
}
@Override
public int getColorB() {
return Integer.valueOf(getColor().substring(5, 7), 16);
}
public String getColor() {
@Override
public @NotNull String getColor() {
return (String) color.value;
}
@Override
public int getColorHex() {
return (getColorR() << 16) + (getColorG() << 8) + getColorB();
}

View File

@ -7,16 +7,14 @@ 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;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.*;
public enum Flag {
public enum Flag implements cn.lunadeer.dominion.api.dtos.Flag {
ANCHOR("anchor", "重生锚", "是否允许设置/使用重生锚", false, false, true),
ANIMAL_KILLING("animal_killing", "对动物造成伤害", "是否允许对动物造成伤害", false, false, true),
ANIMAL_SPAWN("animal_spawn", "动物生成(繁殖)", "是否允许动物生成(包括繁殖)", true, true, false),
@ -47,6 +45,7 @@ public enum Flag {
FLOW_IN_PROTECTION("flow_in_protection", "外部流体是否可以进入", "包含:岩浆、水(不会阻止领地内部的流体蔓延)", false, true, true),
FLY("fly", "飞行", "不是翅鞘飞行,是类似于创造模式的飞行", false, false, false),
GLOW("glow", "玩家发光", "类似光灵箭的高亮效果", false, false, true),
GRAVITY_BLOCK("gravity_block", "允许外部重力方块落入", "如果禁止则领地外重力方块进入领地会变为掉落物", false, true, true),
HARVEST("harvest", "收获", "收获庄稼、作物", false, false, true),
HONEY("honey", "蜂巢交互", "是否可以采蜂蜜", false, false, true),
HOOK("hook", "使用钓钩", "是否可以使用钓钩", false, false, true),
@ -103,26 +102,36 @@ public enum Flag {
this.enable = enable;
}
public String getFlagName() {
@Override
public @NotNull String getFlagName() {
return flag_name;
}
public String getDisplayName() {
@Override
public @NotNull String getDisplayName() {
return display_name;
}
public String getDescription() {
@Override
public @NotNull String getDescription() {
return description;
}
public Boolean getDefaultValue() {
@Override
public @NotNull Boolean getDefaultValue() {
return default_value;
}
public Boolean getEnable() {
@Override
public @NotNull Boolean getEnable() {
return enable;
}
@Override
public @NotNull Boolean isEnvironmentFlag() {
return dominion_only;
}
public void setDisplayName(String displayName) {
this.display_name = displayName;
}
@ -151,7 +160,24 @@ public enum 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) {
@ -167,28 +193,6 @@ public enum 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()) {
@ -205,6 +209,10 @@ public enum 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()) {
@ -255,10 +263,13 @@ public enum Flag {
// load flags default value & enable
String defaultValueKey;
String enableKey;
String descriptionKey;
if (flag.dominion_only) {
descriptionKey = "environment." + flag.getFlagName();
defaultValueKey = "environment." + flag.getFlagName() + ".default";
enableKey = "environment." + flag.getFlagName() + ".enable";
} else {
descriptionKey = "privilege." + flag.getFlagName();
defaultValueKey = "privilege." + flag.getFlagName() + ".default";
enableKey = "privilege." + flag.getFlagName() + ".enable";
}
@ -272,6 +283,7 @@ public enum Flag {
} else {
yaml.set(enableKey, flag.getEnable());
}
yaml.setInlineComments(descriptionKey, Collections.singletonList(flag.getDisplayName() + "-" + flag.getDescription()));
}
yaml.save(yamlFile);
}

View File

@ -2,6 +2,7 @@ package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.api.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
@ -9,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;
@ -16,69 +19,92 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GroupDTO {
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<>();
public Integer getId() {
@Override
public @NotNull Integer getId() {
return (Integer) id.value;
}
public Integer getDomID() {
@Override
public @NotNull Integer getDomID() {
return (Integer) domID.value;
}
public String getName() {
return (String) name.value;
@Override
public @NotNull String getNameRaw() {
return (String) name_color.value;
}
public Component getNameColoredComponent() {
@Override
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);
}
public String getNameColoredBukkit() {
@Override
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);
}
public Boolean getAdmin() {
@Override
public @NotNull Boolean getAdmin() {
return (Boolean) admin.value;
}
public Boolean getFlagValue(Flag flag) {
@Override
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);
@ -90,17 +116,17 @@ public class 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);
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
.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;
@ -125,14 +151,14 @@ public class 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() {
@ -147,10 +173,10 @@ public class 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 : Flag.getPrivilegeFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, f.getDefaultValue());
}
}
@ -158,10 +184,10 @@ public class 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) {
@ -170,7 +196,7 @@ public class GroupDTO {
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
GroupDTO group = new GroupDTO(
@ -197,7 +223,7 @@ public class 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

@ -1,16 +1,19 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.api.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.FieldType;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
import java.util.*;
public class MemberDTO {
public class MemberDTO implements cn.lunadeer.dominion.api.dtos.MemberDTO {
private static List<MemberDTO> query(String sql, Object... params) {
List<MemberDTO> players = new ArrayList<>();
@ -28,7 +31,7 @@ public class MemberDTO {
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
MemberDTO player = new MemberDTO(
@ -55,7 +58,7 @@ public class 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;
@ -68,14 +71,14 @@ public class MemberDTO {
.field(player.playerUUID)
.field(player.admin)
.field(player.domID);
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
insertRow.field(new Field(f.getFlagName(), player.getFlagValue(f)));
}
try (ResultSet rs = insertRow.execute()) {
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;
@ -86,7 +89,7 @@ public class 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) {
@ -126,41 +129,57 @@ public class MemberDTO {
Field domID = new Field("dom_id", FieldType.INT);
Field groupId = new Field("group_id", FieldType.INT);
@Override
public Integer getId() {
return (Integer) id.value;
}
@Override
public UUID getPlayerUUID() {
return UUID.fromString((String) playerUUID.value);
}
@Override
public Boolean getAdmin() {
return (Boolean) admin.value;
}
@Override
public Integer getDomID() {
return (Integer) domID.value;
}
@Override
public Integer getGroupId() {
return (Integer) groupId.value;
}
private final Map<Flag, Boolean> flags = new HashMap<>();
public Boolean getFlagValue(Flag flag) {
@Override
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);
@ -175,7 +194,7 @@ public class MemberDTO {
public MemberDTO applyTemplate(PrivilegeTemplateDTO template) {
this.admin.value = template.getAdmin();
UpdateRow updateRow = new UpdateRow().field(admin);
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
this.flags.put(f, template.getFlagValue(f));
updateRow.field(new Field(f.getFlagName(), template.getFlagValue(f)));
}
@ -196,9 +215,7 @@ public class MemberDTO {
this.playerUUID.value = playerUUID.toString();
this.admin.value = false;
this.domID.value = dom.getId();
for (Flag f : 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

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.api.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
@ -26,7 +27,7 @@ public class PrivilegeTemplateDTO {
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
for (Flag f : cn.lunadeer.dominion.dtos.Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
PrivilegeTemplateDTO template = new PrivilegeTemplateDTO(
@ -54,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;
@ -69,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;
@ -80,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

@ -2,6 +2,7 @@ package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.utils.MessageDisplay;
import cn.lunadeer.minecraftpluginutils.VaultConnect.VaultConnect;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Material;
@ -11,10 +12,7 @@ import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class ConfigManager {
public static ConfigManager instance;
@ -41,7 +39,14 @@ public class ConfigManager {
_db_name = _file.getString("Database.Name", "dominion");
_db_user = _file.getString("Database.User", "postgres");
_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");
_spawn_protection = _file.getInt("Limit.SpawnProtection", 10);
_blue_map = _file.getBoolean("BlueMap", false);
_dynmap = _file.getBoolean("Dynmap", false);
@ -52,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()) {
@ -64,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);
@ -110,6 +128,16 @@ 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);
_file.setComments("MessageDisplay.NoPermission", Collections.singletonList(Translation.Config_Comment_MessageDisplayNoPermission.trans()));
_file.set("MessageDisplay.JoinLeave", _message_display_join_leave);
_file.setComments("MessageDisplay.JoinLeave", Collections.singletonList(Translation.Config_Comment_MessageDisplayJoinLeave.trans()));
_file.setComments("Limit", List.of(Translation.Config_Comment_DefaultLimit.trans()));
_file.set("Limit.SpawnProtection", _spawn_protection);
@ -118,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));
@ -146,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);
@ -234,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);
@ -267,6 +323,14 @@ public class ConfigManager {
return _auto_clean_after_days;
}
public MessageDisplay.Place getMessageDisplayNoPermission() {
return MessageDisplay.Place.valueOf(_message_display_no_permission);
}
public MessageDisplay.Place getMessageDisplayJoinLeave() {
return MessageDisplay.Place.valueOf(_message_display_join_leave);
}
public void setAutoCleanAfterDays(Integer auto_clean_after_days) {
_auto_clean_after_days = auto_clean_after_days;
_file.set("AutoCleanAfterDays", auto_clean_after_days);
@ -335,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;
}
@ -389,14 +462,26 @@ public class ConfigManager {
XLogger.err(Translation.Config_Check_ToolNameError);
setTool("ARROW");
}
if (getAutoCreateRadius() == 0) {
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);
}
if (getAutoCleanAfterDays() == 0) {
if (getAutoCleanAfterDays() <= 0 && getAutoCleanAfterDays() != -1) {
XLogger.err(Translation.Config_Check_AutoCleanAfterDaysError);
setAutoCleanAfterDays(180);
}
if (Arrays.stream(MessageDisplay.Place.values()).noneMatch(place -> place.name().equals(getMessageDisplayNoPermission().name()))) {
XLogger.err(Translation.Config_Check_MessageDisplayError, getMessageDisplayNoPermission());
_message_display_no_permission = "ACTION_BAR";
}
if (Arrays.stream(MessageDisplay.Place.values()).noneMatch(place -> place.name().equals(getMessageDisplayJoinLeave().name()))) {
XLogger.err(Translation.Config_Check_MessageDisplayError, getMessageDisplayJoinLeave());
_message_display_join_leave = "ACTION_BAR";
}
if (getTpDelay() < 0) {
XLogger.err(Translation.Config_Check_TpDelayError);
setTpDelay(0);
@ -426,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;
@ -438,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;
@ -450,6 +539,9 @@ public class ConfigManager {
private String _group_title_prefix;
private String _group_title_suffix;
private String _message_display_no_permission;
private String _message_display_join_leave;
private final Map<String, GroupLimit> groupLimits = new HashMap<>();
private String getPlayerGroup(@Nullable Player player) {

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

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
@ -33,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);
@ -67,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;
}
}
@ -144,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;
}
}
@ -250,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);
@ -309,9 +376,17 @@ public class GroupLimit {
public List<String> getWorldBlackList() {
List<String> list = new ArrayList<>();
if (world_limits.getOrDefault("default", new WorldSetting("default")).amount == 0) {
list.addAll(Dominion.instance.getServer().getWorlds().stream().map(World::getName).toList());
}
for (Map.Entry<String, WorldSetting> entry : world_limits.entrySet()) {
if (!entry.getValue().allow) {
if (entry.getKey().equals("default")) {
continue;
}
if (entry.getValue().amount == 0) {
list.add(entry.getKey());
} else {
list.remove(entry.getKey());
}
}
return list;

View File

@ -1,6 +1,7 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.minecraftpluginutils.XLogger;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@ -30,6 +31,13 @@ public class PlaceHolderApi extends PlaceholderExpansion {
}
return group.getNameColoredBukkit();
}
if (params.equalsIgnoreCase("current_dominion")) {
DominionDTO dominion = Cache.instance.getDominionByLoc(bukkitPlayer.getLocation());
if (dominion == null) {
return "";
}
return dominion.getName();
}
return null; //
}

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")
@ -504,6 +499,8 @@ public class Translation extends Localization {
public static i18n Messages_PlaceholderAPIRegisterSuccess;
@i18nField(defaultValue = "共加载了 %d 个领地组")
public static i18n Messages_LoadedGroupAmount;
@i18nField(defaultValue = "<div>%s</div><div>所有人:%s</div>")
public static i18n Messages_MapInfoDetail;
@i18nField(defaultValue = "开始自动清理长时间未登录玩家领地数据")
public static i18n Messages_AutoCleanStart;
@ -595,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 = "手动刷新缓存可解决一些玩家操作无效问题,不建议频繁操作")
@ -829,18 +822,34 @@ public class Translation extends Localization {
@i18nField(defaultValue = "AutoCreateRadius 不能等于 0已重置为 10")
public static i18n Config_Check_AutoCreateRadiusError;
@i18nField(defaultValue = "MessageDisplay 不能设置为 %s已重置为 ACTION_BAR")
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")
@ -860,6 +869,16 @@ 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 = "玩家没有权限时的提示消息位置")
public static i18n Config_Comment_MessageDisplayNoPermission;
@i18nField(defaultValue = "进入/离开领地时的提示消息位置")
public static i18n Config_Comment_MessageDisplayJoinLeave;
@i18nField(defaultValue = "-1表示不开启")
public static i18n Config_Comment_NegativeOneDisabled;
@i18nField(defaultValue = "默认玩家圈地限制")
@ -873,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 = "子领地深度")
@ -898,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 前置及插件")
@ -942,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,13 +9,15 @@ 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;
public Boolean allow = true;
private final String sourceName;
/**
@ -27,13 +29,15 @@ 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);
section.set("some_world_name.Allow", false);
return section;
}
@ -47,13 +51,27 @@ 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);
setting.allow = worldSettings.getBoolean(worldName + ".Allow", false);
if (worldSettings.contains(worldName + ".Allow") && !worldSettings.getBoolean(worldName + ".Allow")) {
setting.amount = 0;
}
world_limits.put(worldName, setting);
}
return world_limits;
@ -63,13 +81,15 @@ 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);
section.set("Allow", allow);
return section;
}
@ -79,19 +99,46 @@ 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 (amount <= 0 && amount != -1) {
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);
amount = 10;
}

View File

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.Location;
@ -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

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.GroupController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.manage.group.GroupList;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.group.GroupList;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;

View File

@ -1,9 +1,9 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.TemplateController;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.template.TemplateList;
import cn.lunadeer.dominion.uis.tuis.template.TemplateList;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;

View File

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;

View File

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;

View File

@ -1,12 +1,12 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.MemberController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.manage.member.MemberList;
import cn.lunadeer.dominion.tuis.dominion.manage.member.SelectPlayer;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.member.MemberList;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.member.SelectPlayer;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;

View File

@ -1,9 +1,9 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;

View File

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.GroupController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.manage.group.GroupSetting;
import cn.lunadeer.dominion.uis.tuis.dominion.manage.group.GroupSetting;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;

View File

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.cuis;
package cn.lunadeer.dominion.uis.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.dominion.uis.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis;
package cn.lunadeer.dominion.uis.tuis;
import cn.lunadeer.dominion.DominionNode;
import cn.lunadeer.dominion.dtos.DominionDTO;
@ -11,7 +11,7 @@ import org.bukkit.entity.Player;
import java.util.List;
import static cn.lunadeer.dominion.tuis.dominion.DominionList.BuildTreeLines;
import static cn.lunadeer.dominion.uis.tuis.dominion.DominionList.BuildTreeLines;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
import static cn.lunadeer.dominion.utils.TuiUtils.notOp;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis;
package cn.lunadeer.dominion.uis.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.managers.Translation;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis;
package cn.lunadeer.dominion.uis.tuis;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
@ -9,11 +9,6 @@ import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.components.Button;
import cn.lunadeer.minecraftpluginutils.stui.components.Line;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis;
package cn.lunadeer.dominion.uis.tuis;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion;
package cn.lunadeer.dominion.uis.tuis.dominion;
import cn.lunadeer.dominion.DominionNode;
import cn.lunadeer.dominion.dtos.DominionDTO;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion;
package cn.lunadeer.dominion.uis.tuis.dominion;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage;
package cn.lunadeer.dominion.uis.tuis.dominion.manage;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
@ -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

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage;
package cn.lunadeer.dominion.uis.tuis.dominion.manage;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage;
package cn.lunadeer.dominion.uis.tuis.dominion.manage;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.DominionDTO;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.group;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.group;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
@ -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

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.group;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.group;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
@ -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

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.group;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.group;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
@ -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

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.member;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.member;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.*;
@ -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

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.member;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.member;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.member;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.member;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.PlayerDTO;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.dominion.manage.member;
package cn.lunadeer.dominion.uis.tuis.dominion.manage.member;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;
import cn.lunadeer.dominion.managers.Translation;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.template;
package cn.lunadeer.dominion.uis.tuis.template;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;
import cn.lunadeer.dominion.managers.Translation;

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis.template;
package cn.lunadeer.dominion.uis.tuis.template;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;

View File

@ -7,12 +7,6 @@ import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.minecraftpluginutils.Notification;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.inventory.Inventory;
@ -77,11 +71,9 @@ public class EventUtils {
return true;
}
}
TextComponent msg = Component.text(
String.format(Translation.Messages_NoPermissionForFlag.trans(), flag.getDisplayName(), flag.getDescription()),
Style.style(TextColor.color(0xFF0000), TextDecoration.BOLD))
.hoverEvent(Component.text(flag.getDescription()));
Notification.actionBar(player, msg);
String msg = String.format(Translation.Messages_NoPermissionForFlag.trans(), flag.getDisplayName(), flag.getDescription());
msg = "&#FF0000" + "&l" + msg;
MessageDisplay.show(player, Dominion.config.getMessageDisplayNoPermission(), msg);
if (event != null) {
event.setCancelled(true);
}

View File

@ -0,0 +1,37 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class MessageDisplay {
public enum Place {
BOSS_BAR,
ACTION_BAR,
TITLE,
SUBTITLE,
CHAT
}
public static void show(Player player, Place place, String message) {
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
message = PlaceholderAPI.setPlaceholders(player, message);
}
message = ColorParser.getBukkitType(message);
// BOSS_BAR, ACTION_BAR, TITLE, SUBTITLE, CHAT
if (place == Place.BOSS_BAR) {
Notification.bossBar(player, message);
} else if (place == Place.CHAT) {
player.sendMessage(message);
} else if (place == Place.TITLE) {
Notification.title(player, message);
} else if (place == Place.SUBTITLE) {
Notification.subTitle(player, message);
} else {
Notification.actionBar(player, message);
}
}
}

View File

@ -6,7 +6,6 @@ import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.components.Button;
import cn.lunadeer.minecraftpluginutils.stui.components.Line;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

View File

@ -1,7 +1,8 @@
package cn.lunadeer.dominion.utils.map;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.api.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
@ -21,7 +22,7 @@ public class BlueMapConnect {
try {
BlueMapAPI.getInstance().ifPresent(api -> {
Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO dominion : Cache.instance.getDominions()) {
for (DominionDTO dominion : Cache.instance.getAllDominions()) {
if (dominion.getWorld() == null) {
continue;
}
@ -37,6 +38,11 @@ public class BlueMapConnect {
.build();
for (DominionDTO dominion : d.getValue()) {
PlayerDTO p = PlayerDTO.select(dominion.getOwner());
if (p == null) {
continue;
}
Collection<Vector2d> vectors = new ArrayList<>();
vectors.add(new Vector2d(dominion.getX1() + 0.001, dominion.getZ1() + 0.001));
vectors.add(new Vector2d(dominion.getX2() - 0.001, dominion.getZ1() + 0.001));
@ -55,6 +61,7 @@ public class BlueMapConnect {
Color fill = new Color(r, g, b, 0.2F);
ExtrudeMarker marker = ExtrudeMarker.builder()
.label(dominion.getName())
.detail(String.format(Translation.Messages_MapInfoDetail.trans(), dominion.getName(), p.getLastKnownName()))
.position(x, y, z)
.shape(shape, dominion.getY1() + 0.001f, dominion.getY2() - 0.001f)
.lineColor(line)

View File

@ -1,6 +1,7 @@
package cn.lunadeer.dominion.utils.map;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.api.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.managers.Translation;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
@ -40,7 +41,11 @@ public class DynmapConnect extends DynmapCommonAPIListener {
}
private void setDominionMarker(DominionDTO dominion) {
String nameLabel = "<div>" + dominion.getName() + "</div>";
PlayerDTO p = PlayerDTO.select(dominion.getOwner());
if (p == null) {
return;
}
String nameLabel = String.format(Translation.Messages_MapInfoDetail.trans(), dominion.getName(), p.getLastKnownName());
double[] xx = {dominion.getX1(), dominion.getX2()};
double[] zz = {dominion.getZ1(), dominion.getZ2()};
if (dominion.getWorld() == null) {

View File

@ -14,7 +14,7 @@ public class MapRender {
}
if (Dominion.config.getDynmap()) {
DynmapConnect.instance.setDominionMarkers(Cache.instance.getDominions());
DynmapConnect.instance.setDominionMarkers(Cache.instance.getAllDominions());
}
}

View File

@ -9,14 +9,24 @@ Database:
Language: zh-cn
AutoCreateRadius: 10
DefaultJoinMessage: '&3{OWNER}: Welcome to {DOM}!'
DefaultLeaveMessage: '&3{OWNER}: Leaving {DOM}...'
MessageDisplay:
NoPermission: ACTION_BAR
JoinLeave: ACTION_BAR
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
@ -25,13 +35,16 @@ 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
Allow: false
Teleport:
Enable: true
@ -42,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,10 +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
Allow: 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: 领地插件命令
@ -18,4 +20,4 @@ permissions:
default: op
dominion.default:
description: 领地插件用户权限
default: true
default: true

View File

@ -1,5 +1,5 @@
# Languages
* [中文(简体)](zh-cn/)
* [中文(繁體)](zh-tw/)
* [English](en/)
* [中文(繁體)](zh-hk/)
* [English](en-us/)

39
docs/en-us/README.md Normal file
View File

@ -0,0 +1,39 @@
## Dominion Documentation
[![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.
Dominion is a completely open-source, free, future-proof, territory anti-grief plugin developed specifically for
high-versions minecraft server. The plugin is currently undergoing rapid development and iteration, and we will do our
best to ensure the stability and functionality of the plugin.
If you encounter any problems during use, or have any suggestions, please feel free to submit your questions or ideas
at [GitHub ISSUE](https://github.com/ColdeZhang/Dominion/issues).
## Quick start (for players)
1. [How to create a dominion](create-dominion.md)
2. [Managing your dominion](manage-dominion/README.md)
## Quick start (for server administrators)
1. [Installation, Required Readings, FAQ](operator/README.md)
2. [Configuration File Reference](operator/config.md)
## Help translate this documentation
If you want to help us translate the documentation, please refer
to [CONTRIBUTING.md](https://github.com/ColdeZhang/Dominion/blob/master/CONTRIBUTING.md#translate-documentation).
❤ Thank you for your support and contribution! ❤

24
docs/en-us/SUMMARY.md Normal file
View File

@ -0,0 +1,24 @@
# Summary
* [Preface](README.md)
* [Creating a Dominion](README.md)
* [Territory Management](manage-dominion/README.md)
* [Environment Settings](manage-dominion/environment.md)
* [Permission Management](manage-dominion/permission/README.md)
* [Guest Permissions](manage-dominion/permission/guest.md)
* [Territory members](manage-dominion/permission/member.md)
* [Permission Groups](manage-dominion/permission/permission-group.md)
* [Permission Templates](manage-dominion/permission/template.md)
* [Territory Teleport](manage-dominion/teleport.md)
* [Resize](manage-dominion/resize.md)
* [Setting the territory reminder message](manage-dominion/message.md)
* [Permission group title](manage-dominion/group-title.md)
* [Subdominion](manage-dominion/sub-dominion.md)
* [Migration from residence](migration-residence.md)
* [Command list](command-list.md)
* [Administrator's Guide](operator/README.md)
* [Configuration file reference](operator/config.md)
* [flags.yml](operator/flags.md)
* [Privileged Player Configuration](operator/privilege.md)
* [Cross-group teleportation (global-tp in testing)](operator/global-tp.md)
* [Developer](developer.md)

View File

@ -0,0 +1 @@
# 指令列表

View File

@ -0,0 +1,23 @@
# 创建领地
## 名称规则
- 领地名称不可与其他领地重复;
- 领地名称不可包含空格;
- 领地名称不可包含特殊字符;
## 手动创建
需要使用圈地工具(默认为箭矢),依次使用左键点选领地长方体区域的第一个点、右键点击长方体区域的第二个点。然后使用:
`/dominion create <领地名称>`创建领地,领地名称不可与其他领地重复。
## 自动创建
不需要选择对角线点,会以玩家为中心自动创建一定区域的领地。
1. 使用 `/dominion` 打开主菜单,点击`【创建领地】`;
2. 在弹出的 UI 中输入你要创建的领地名称;
3. 输入完成后左键点击下方中间的绿色混凝土,即可自动创建一块领地;
> 自动创建半径是由服务器管理员在配置文件中设置的;

99
docs/en-us/developer.md Normal file
View File

@ -0,0 +1,99 @@
# 开发者文档
> DominionAPI 自 Dominion-2.9.0-beta 开始支持。
## 一、接入 DominionAPI
### 1. 引入依赖
如果您使用 gradle可以在您的 `build.gradle` 文件中添加如下代码:
```groovy
// build.gradle
repositories {
maven { url = "https://ssl.lunadeer.cn:14454/repository/maven-snapshots/" }
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
或者你使用的是 gradle kotlin dsl
```kotlin
// build.gradle.kts
repositories {
maven("https://ssl.lunadeer.cn:14454/repository/maven-snapshots/")
}
dependencies {
compileOnly("cn.lunadeer:DominionAPI:2.1-SNAPSHOT")
}
```
再或者您使用 maven可以在您的 `pom.xml` 文件中添加如下代码:
```xml
<!-- pom.xml -->
<repositories>
<repository>
<id>lunadeer</id>
<url>https://ssl.lunadeer.cn:14454/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>cn.lunadeer</groupId>
<artifactId>DominionAPI</artifactId>
<version>2.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
### 2. plugin.yml 配置
在您的插件的 `plugin.yml` 文件中添加如下配置,以确保在 Dominion 准备完成后再加载您的插件:
```yaml
# plugin.yml
depend: [ Dominion ]
```
## 二、使用 DominionAPI
可以通过如下方法直接获取 DominionAPI 实例:
```java
import cn.lunadeer.dominion.api.Dominion;
import cn.lunadeer.dominion.api.DominionAPI;
DominionAPI dominionAPI = Dominion.getInstance();
```
例如,获取某个位置的领地信息:
```java
@Override
public void onEnable() {
// Plugin startup logic
try {
DominionAPI dominionAPI = Dominion.getInstance();
DominionDTO d = dominionAPI.getDominionByLoc(some_location);
if (d == null) {
this.getLogger().info("no dominion found");
return;
}
this.getLogger().info("name:" + d.getName());
} catch (Exception e) {
this.getLogger().info(e.getMessage());
}
}
```
[示例项目地址](https://github.com/ColdeZhang/DominionAddonExample)。
[Javadoc地址](https://coldezhang.github.io/DominionAPI/)。

View File

@ -0,0 +1,14 @@
# 领地管理
领地的管理可以通过领地菜单完成,通常来说您不需要任何指令就可以完成领地的管理。
## 主菜单界面 `/dominion`
使用 `/dominion` 可以打开领地系统的可视化操作菜单界面TUI。单击`【我的领地】`可以查看自己创建的所有领地。
## 领地管理界面 `/dominion manage [领地名称]`
单击对应领地的【管理】即可进入对应领地的管理界面,通过管理界面可以管理此领地的权限等信息。 也可以直接输入
`/dominion manage [领地名称]` 来快速打开当前所在领地的管理界面。
> 领地名称是可选的,不填写则自动打开你当前所在的领地管理界面。

View File

@ -0,0 +1,16 @@
# 环境设置
## 简介
领地环境设置主要包含了领地内的一些非玩家行为的设置例如TNT爆炸、火焰蔓延等等。
## 设置方法
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【环境设置】`
4. 点击对应设置项的权限前的 ☑/☐ 来允许或者禁止对应的领地环境行为。
## 注意事项
- 鼠标移动到权限名称上可以显示此权限的详细(描述)信息;

View File

@ -0,0 +1,26 @@
# 权限组称号
## 简介
权限组称号可以用来对外展示玩家在领地的角色/地位/身份,有利于提高领地内的社交性、增强玩家的归属感。
## 领地主要做的事
参照文档完成领地[权限组的配置](permission/permission-group.md),并且添加对应成员;
> 领地主玩家可以使用自己领地的所有权限组称号,所以如果领地主想给自己一个称号可以建一个空权限组专门用来给自己作称号用。
## 成员玩家要做的事
1. 打开领地菜单 `/dominion`
2. 在主菜单点击`【称号列表】`,此处会列出所有你拥有的领地权限组称号,以及该称号来源于哪个领地:
3. 点击对应称号前的【使用】,即可;
## 管理员要做的事
1. 在配置文件中启用 `GroupTitle.Enable`
2. 安装 PlaceholderAPI 插件;
3. 在你想要显示称号的地方如聊天前缀、TAB列表添加占位符`%dominion_group_title%`
> 通常来说你还需要安装一个聊天插件来显示占位符,例如 InteractiveChat、TAB 之类的。

View File

@ -0,0 +1,17 @@
# 领地提示消息
## 进入消息
可以为领地设置玩家进入时的欢迎语句,提示语将在玩家进入领地时弹出。
```
/dominion set_enter_msg <提示语> [领地名称]
```
## 离开消息
可以为领地设置玩家离开时的欢送语句,提示语将在玩家离开领地时弹出。
```
/dominion set_leave_msg <提示语> [领地名称]
```

View File

@ -0,0 +1,53 @@
# 权限管理
## 简介
Dominion 采用了 `访客-成员-权限组` 的权限管理模型。通过此方案既可以满足对于权限的细粒度控制,又可以保证权限的可维护性,减轻玩家的操作负担。
- [访客](guest):领地的访客权限,不属于领地成员的玩家将收到此权限的限制;
- [成员](member.md):领地的成员权限,属于领地成员的玩家将收到此权限的限制;
- [权限组](permission-group.md):领地的权限组,将玩家添加到权限组中,可以为多个玩家配置相同的权限;
## 权限模型透视
```
┌───────────┐
│ Player │
└─────┬─────┘
┌───────────┐ ┌───────────┐
│ IsMember? │───►│ HasGroup? │
└─────┬─────┘ Y └──┬────┬───┘
│N │ │
▼ │ │
┌───────────┐ N│ Y│
│ Visitor │ │ │
└───────────┘ │ │
┌───────────┐ │ │
│ Member │◄──────┘ │
└───────────┘ │
┌───────────┐ │
│ Group │◄───────────┘
└───────────┘
```
- 当一个玩家不属于领地成员时将收到访客权限的限制;
- 如果是领地成员那么会判断玩家是否属于权限组;
- 如果玩家属于权限组那么将收到对应权限组的行为控制;
- 如果玩家不属于权限组那么将采用该玩家在此领地中的成员权限;
## 领地管理员
管理员是领地成员权限中的一个特殊权限:
- ✅管理员可以做的事:
- 该领地的其他所有权限
- 修改领地权限
- 修改领地的玩家权限(添加、删除、修改)
- ❌管理员不可以做的事:
- 删除领地
- 修改领地尺寸
- 将其他玩家设置为管理员
通过将一些玩家设置为管理员,可以让他们帮助你管理领地的其他玩家,减轻领地所有人的操作负担。同时不必担心管理员会对领地进行破坏性操作(例如删除、缩小领地)。

View File

@ -0,0 +1,19 @@
# 访客权限
## 简介
访客是相对于领地成员而言的,通过设置访客权限,你可以控制非领地成员的玩家在领地内的行为。
例如:如果你是个大好人希望提供公共物资给服务器内的其他玩家使用,那么你可以将该领地访客权限中的【容器】权限打开。
这样其他玩家就可以在你的领地内使用你的箱子了,无需给他们领地成员的权限。
## 设置方法
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【访客权限】`
4. 点击对应设置项的权限前的 ☑/☐ 来允许或者禁止对应的领地环境行为。
## 封禁一个玩家?
Dominion自身并没有直接提供封禁玩家的功能但是你可以通过将玩家添加为领地成员然后关闭他的【移动】权限来实现类似的效果。具体操作请参考[领地成员](member.md)。

View File

@ -0,0 +1,32 @@
# 领地成员
## 简介
顾名思义。
## 添加成员
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【成员管理】`
4. 点击 `【添加成员】`,选择或输入玩家名称添加为领地成员。
## 管理成员
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【成员管理】`,此处列出了领地的所有成员;
- 点击 `【配置权限】` 可以配置此成员在领地内的权限;
- 点击 `【移除成员】` 可以将此成员移出领地;
- 如果一个玩家属于某[权限组](permission-group.md),那么你不能单独编辑他的权限,对应`【配置权限】`为灰色不可点击;
玩家名称最前方标记含义:
- 【A】该领地管理员
- 【N】普通成员
- 【B】黑名单成员没有移动权限
- 【G】属于某个权限组
## 注意事项
- 选择成员页面只会显示在安装了Dominion后登录过服务器的玩家名称因此暂时不支持对从没有在服务器登录过的玩家进行操作。
- 通过搜索框添加成员不支持模糊搜索,需要输入准确的玩家名称(大小写敏感)。

View File

@ -0,0 +1,51 @@
# 权限组
## 简介
权限组可以对一批玩家的权限进行统一的管理、设置,减少大量重复的操作,提高效率。
## 创建权限组
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【权限组】`
4. 点击 `【创建权限组】`,输入权限组名称,左键点击绿色混凝土完成创建;
## 权限组成员管理
权限组成员只能是领地成员,因此需要**先将玩家添加为领地成员**,才能将其编入权限组。
- 添加成员:点击权限组后面的`【+】`,选择领地成员;
- 移除成员:点击玩家名字前面的`【-】`
## 管理权限组
- 编辑权限组:点击权限组前的`【编辑】`,配置此权限组的权限或修改权限组的名称;
- 删除权限组:点击权限组前的`【删除】`,删除此权限组;
- 配置权限:在编辑页面,点击对应权限前的 ☑/☐ 来允许或者禁止该权限组内的玩家的行为;
> 注意:删除权限组后,权限组内的成员会被自动移出权限组,成为领地普通成员。
## 其他
- 权限组名称同时也可以作为称号,用来对外展示玩家在领地的角色/地位/身份,详见[权限组称号](../group-title.md)
- 权限组名称支持 RGB 彩色效果,详情参见 [彩色字符](https://ssl.lunadeer.cn:14448/doc/81/)
## Q&A 常见问题
Q我将玩家 A 编入了权限组 G还可以手动设置 A 的成员权限吗?
A不可以编入权限组 G 后此玩家的行为只能由此权限组控制。
---
Q我将玩家 A 编入了权限组 G1还能再编入权限组 G2 吗?
A不可以在一个领地内一个玩家只能属于一个权限组不支持混合。
---
Q我将玩家 A 编入了权限组 G然后一不小心删除了权限组 G 会发生生么?
A玩家会被自动移出权限组成为领地一般成员。

View File

@ -0,0 +1,37 @@
# 权限模板
权限模板功能允许你预先配置好一组权限,然后直接将模板套用到成员身上,即可快速将此成员的权限设置为理想的状态。相比于权限组,模板主要适用于某些特殊的、非通用的权限组和。
例如:你并不喜欢权限组的统一性,你希望每个成员都有自己的权限设置,但是又不想每次都手动设置,这时候权限模板就派上用场了。
## 创建一个模板
1. 打开领地菜单 `/dominion`
2. 在主菜单点击`【权限模板】`
3. 点击`【创建成员权限模板】`,输入模板名称,点击绿色混凝土完成创建;
4. 点击模板前的`【管理】`,配置此模板的权限;
## 使用模板
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【成员管理】`,此处列出了领地的所有成员;
4. 点击 `【配置权限】` 后,点击 `【套用模板】`
5. 在列表中点击你想要使用的模板,完成权限模板的套用;
## Q&A 常见问题
Q我将模板 T 套用在了玩家 A 身上,还可以手动设置 A 的成员权限吗?
A可以。
---
Q我将模板 T 套用在了玩家 A 身上,修改玩家 A 的权限会同步修改模板 T 的权限吗?
A不会模板应用是单向的。
---
Q我将模板 T 套用在了玩家 A 身上,修改模板 T 的权限会同步修改玩家 A 的权限吗?
A不会模板应用是一次性的类似于批量处理不会产生连锁影响。

View File

@ -0,0 +1,23 @@
# 修改领地尺寸
## 扩大
面向想要扩大的方向,使用命令:
```
/dominion expand [大小] [领地名称]
```
- 大小可选默认为10
- 领地名称:可选,默认为当前所在领地,如果在子领地内则需要指定领地名称;
## 缩小
面向想要缩小的方向,使用命令:
```
/dominion contract [大小] [领地名称]
```
- 大小可选默认为10
- 领地名称:可选,默认为当前所在领地,如果在子领地内则需要指定领地名称;

View File

@ -0,0 +1,22 @@
# 创建子领地
## 创建方法
创建方法与普通领地相同,可以使用自动创建,也可以手动创建。
命令分别为:
`/dominion create_sub <子领地名称> [父领地名称]`
`/dominion auto_create_sub <子领地名称> [父领地名称]`
当不填写父领地名称时会尝试以当前所在领地为父领地进行创建。
## 权限
当玩家处在一个子领地内时,其行为只收到子领地的权限控制。
子领地的权限设置与傅领地完全相同,参考[权限管理](permission/README.md)。
## 关于子领地嵌套
子领地内部可以再创建子领地,但是子领地的嵌套深度是有限制的,具体嵌套深度由服务器管理员在[配置文件](../operator/config.md)中设置。

View File

@ -0,0 +1,17 @@
# 领地传送
## 设置传送点
1. 打开领地菜单 `/dominion`
2. 在 `【我的领地】` 中点击对应领地的 `【管理】`
3. 在领地管理界面中选择 `【设置传送点】`,此时你的位置会被设置为领地的传送点。
## 配置权限
- 默认情况下,领地传送的权限是关闭的;
- 如果你希望允许**所有人**都能够传送到你的领地,你可以直接在【访客权限】中将【领地传送】打开;
- 如果你**只希望部分玩家**能够传送过来,那么你可以单独为这部分玩家添加【成员权限】,然后打开他们的【领地传送】权限。
## 传送
使用指令传到目标领地:`/dominion tp <领地名称>`

View File

@ -0,0 +1,20 @@
# 将领地从 Residence 迁移到 Dominion
## 注意事项
1. 迁移采取的“玩家自助”方案,即由玩家自行决定要迁移自己的哪些领地;
2. 目前支持迁移领地、tp点、欢迎/离开提示消息、子领地;
3. 由于对权限的存储、索引方式不同,目前**不支持**对权限进行迁移;
4. 迁移领地**不会产生二次消费**
## 服主要做的事
1. 删除 Residence 插件,保留其数据文件 `plugins/Residence`;
2. 在 Dominion 配置中将 `ResidenceMigration` 打开设置为true
## 玩家要做的事
1. 上线,打开 Dominion 菜单 `/dom`,点击`【迁移数据】`
2. 选择要迁移的 Residence 领地,点击前面的`【迁移】`
3. 完成后即可前往领地列表进一步配置领地的权限等信息:

View File

@ -0,0 +1,55 @@
# 管理员基础入门
## 环境要求
- 1.20.1 及以上;
- Spigot、Paper、Folia...
> 虽然本插件支持 Spigot 但是我们强烈推荐您升级到 Paper 或其分支核心(如 Purpur以获得更好的性能体验。
## 安装方法
1. 将插件放入服务器的 `plugins` 目录下
2. 重启服务器
3. 在 `plugins/Dominion/config.yml` 中配置
## 权限节点
| 功能 | 权限节点 | 默认 |
|--------|------------------|------|
| 普通玩家指令 | dominion.default | true |
| 管理员指令 | dominion.admin | op |
## 玩家“滥发消息”导致被踢
由于本插件使用TUI作为交互方式因此会与玩家客户端之间产生大量消息。而 spigot 增加了滥发消息保护,因此默认情况下当玩家快速操作界面时大概率会被踢出服务器。
![](https://ssl.lunadeer.cn:14437/i/2024/05/17/664723d8a3477.png)
解决办法为在 `spigot.yml` 配置文件中将本插件命令的消息设置为白名单:
```
...
commands:
...
spam-exclusions:
- /dom
- /dominion
```
## 安装本插件后原来可以飞行现在飞不了
如果你安装了一些飞行相关的插件,在打开 flags 中的领地飞行后可能会遇到其他飞行插件不生效的问题。
这些问题包括但不限于:无法起飞、进入领地后“坠机”、离开领地时“坠机”等。
解决办法为在配置文件中添加对应插件的权限节点:
```
# 飞行权限节点 - 拥有以下任意一个权限节点的玩家不会被本插件拦截飞行
FlyPermissionNodes:
- essentials.fly
- cmi.command.fly
```
拥有此列表中任意一个权限节点的玩家不会被本插件拦截飞行行为。

View File

@ -0,0 +1,182 @@
# 配置文件参考
```yaml
Database:
Type: sqlite # pgsql, sqlite, mysql
Host: localhost
Port: '5432'
Name: dominion
User: dominion
Pass: dominion
# 语言设置,参考 languages 文件夹下的文件名
Language: zh-cn
# 自动创建领地的半径,单位为方块
# -1表示不开启
AutoCreateRadius: 10
# 默认玩家圈地限制
Limit:
SpawnProtection: 10 # 出生点保护半径 出生点此范围内不允许圈地-1表示不开启
MinY: -64 # 最小Y坐标
MaxY: 320 # 最大Y坐标
SizeX: 128 # X方向最大长度-1表示不限制
SizeY: 64 # Y方向最大长度-1表示不限制
SizeZ: 128 # Z方向最大长度-1表示不限制
Amount: 10 # 最大领地数量-1表示不限制
Depth: 3 # 子领地深度0表示不开启-1表示不限制
Vert: false # 是否自动延伸到 MaxY 和 MinY
OpByPass: true # 是否允许OP无视领地限制
WorldSettings:
some_world_name:
MinY: -64
MaxY: 320
SizeX: 128
SizeY: 64
SizeZ: 128
Amount: 10
Depth: 3
Vert: false
Allow: false
Teleport:
Enable: true
Delay: 0 # 传送延迟 秒
CoolDown: 0 # 传送冷却 秒
# 自动清理长时间未上线玩家的领地(天)
# -1表示不开启
AutoCleanAfterDays: 180
# 圈地工具名称
Tool: ARROW
# 经济设置
# 需要安装 Vault 前置及插件
Economy:
Enable: false
Price: 10.0 # 圈地价格 单位每方块
OnlyXZ: false # 是否只计算xz平面积
Refund: 0.85 # 删除或缩小领地时的退款比例
# 飞行权限节点 - 拥有以下任意一个权限节点的玩家不会被本插件拦截飞行
FlyPermissionNodes:
- essentials.fly
- cmi.command.fly
# 是否允许玩家从 Residence 迁移领地数据
ResidenceMigration: false
# 权限组称号 - 使用权限组当作称号(需要PlaceholderAPI插件)
# 变量: %dominion_group_title%
# 前后缀如需要加颜色请使用这种格式 &#ffffff
GroupTitle:
Enable: false
Prefix: '['
Suffix: ']'
BlueMap: false
Dynmap: false
CheckUpdate: true
Debug: false
Timer: false # 性能测试计时器
```
## 配置说明
### Database
可选数据库Postgresql、Sqlite3`1.33.4-beta` 开始支持Mysql。
- 如果使用 Postgresql 数据库,需要手动创建数据库。
- 如果使用 sqlite 数据库,插件会自动在插件目录下创建数据库文件。配置文件内的 Host、Port、User、Pass 字段不会被使用。
### Language
语言设置,参考 languages 文件夹下的文件名。
如果需要更新语言文件,请删除 `plugins/Dominion/languages` 文件夹下对应的文件,然后重启服务器。
插件会自动生成最新的对应语言文件。
### AutoCreateRadius
配置玩家在使用“自动创建”功能时会自动向XYZ三个方向延伸此距离创建领地。
### Limit
玩家使用此插件的一些限制:
- SpawnProtection出生点半径保护此半径范围内普通玩家无法创建领地
- MinY领地的最小Y坐标
- MaxY领地的最大Y坐标
- SizeXX方向最大长度 1表示不限制
- SizeYY方向最大长度 1表示不限制
- SizeZZ方向最大长度 1表示不限制
- Amount每个玩家拥有的最大领地数量 1表示不限制
- Depth子领地深度、0表示不允许子领地、 -1表示不限制
- Vert当设置为 `true`玩家选择区域创建或者自动创建领地会自动将Y向下向上延伸到MinY和MaxY。**同时也会根据 MinY 和 MaxY 的设置自动调整 SizeY 的配置保证数值逻辑一致。**
- WorldSettings单独设置某个世界的圈地规则如不设置则使用上述默认规则
- Allow是否允许在此世界圈地
> 您服务器世界的名称应该避免使用 `default` 这样的特殊单词,否则会导致不可预料的意外错误。
### Teleport
领地传送功能,可以配置是否允许使用传送、传送延迟、两次传送之间的冷却时间。
### AutoCleanAfterDays
配置数据自动清理,-1表示不开启。180表示如果一个玩家超过180天没有上线那么会自动删除此玩家在本插件内的所有数据包括他的领地、他在其他玩家领地内的权限等
### Tool
配置手动圈地时的选取工具。如果配置错误会被设置为默认值“ARROW”箭矢。
### Economy
经济控制支持,让玩家需要花费金钱圈地。使用此特性需要安装 Vault 经济前置插件。
- Enable控制是否启用此功能如果不需要请关闭。修改是否启用需要完整重启服务器不要使用管理插件热重载
- Price每个单位方块价值。
- OnlyXZ是否只计算平面面积价值忽略Y轴
- Refund删除、缩小领地时的退还金钱比例。
### FlyPermissionNodes
飞行权限节点,拥有此列表任意一个权限节点的玩家不会被本插件拦截飞行。
EssentialX飞行权限essentials.fly
CMI飞行权限cmi.command.fly
### ResidenceMigration
是否允许玩家从 Residence 迁移领地数据,打开后玩家可以自行决定要从 Residence 中迁移哪些数据到 Dominion。
### GroupTitle
- Enable是否启用权限组称号
- Prefix称号前缀 (如需要加颜色请使用这种格式 &#ffffff
- Suffix称号后缀 (如需要加颜色请使用这种格式 &#ffffff
关于如何配置详见[权限组称号](../manage-dominion/group-title.md)。
### BlueMap
配置是否在 BlueMap 渲染玩家领地。
### Dynmap
配置是否在 Dynmap 渲染玩家领地。
### CheckUpdate
自动检查更新。
### Debug
调试模式如果遇到bug可以尝试打开此开关后复现问题然后将日志发送给我。

View File

@ -0,0 +1,37 @@
# 权限可见性配置
## 简介
Dominion 开发的初衷是仅用于防熊与保护领地,随着使用人数的增加,有些服务器管理员希望可以增加例如“禁止怪物生成”这样的权限。
在作者看来这样的权限属于利用插件功能改变游戏内容,因此这类权限默认情况是不可见、不生效且玩家无法配置的。
通过 flags.yml 服务器管理员可以打开一些默认关闭的权限,让玩家可以在游戏内配置这些权限。
## 配置文件
```yaml
privilege:
anchor:
default: false
enable: true
animal_killing:
default: false
enable: true
...
environment:
animal_spawn:
default: true
enable: false
animal_move:
default: true
enable: false
...
```
- enable是否启用此权限
- default_value权限的默认值
## 注意事项
- 如果关闭了某个权限,那么此权限将不会出现在游戏内 TUI 权限列表中,并且无论默认值如何, Dominion 都不会再对此权限的对应行为作处理;
- 修改默认值不会对已有的权限造成影响,只会对修改之后的新建领地生效;
- 此文件支持热修改,无需重启服务器或者重载插件,只需要使用 `/dom reload_config` 指令重新加载配置文件即可;

View File

@ -0,0 +1,19 @@
# 跨群组服传送
**改功能暂未上线**
## 新服务器配置
1. 配置好 Mysql 或 Pgsql 数据库不可使用sqlite需要将所有子服连接到同一个数据库配置文件的数据库部分一致
2. 将所有子服启动一次后关闭;
3. 修改各子服 `plugins/Dominion/server_info.json` 中的 `name` 字段,需要将其修改为你在群组代理中设置的对应子服的名称;
4. 启动所有子服,大功告成;
## 迁移
目前暂不支持将多个已经在使用此插件的子服合并为群租,你只能选择其一保留领地数据。
需要在你要保留数据的子服中先运行本插件,再安装至其他子服运行一次,随后可参照以上的 2-4 步骤。

View File

@ -0,0 +1,36 @@
# 特权玩家配置
如果你想给赞助玩家或者VIP一些特殊优惠例如更少的圈地价格、可以圈更大的领地等那请继续阅读下面的内容。
## 前置条件
1. Dominion 插件版本 >= 2.2.0;
2. 安装有权限插件,例如 LuckPerms
## 配置圈地限制
假设你现在想为赞助玩家提供优惠,打开 `plugins/Dominion/groups/sponsor.yml` 文件。修改里面的设置为你期望的数值,保存文件。
假如你想再为 VIP 玩家提供更丰厚的优惠,你可以复制一份 `sponsor.yml` 重命名为 `vip.yml`
,然后编辑里面的数值。(这个文件的名称你可以自定义,但是请不要使用中文、特殊字符、空格等)
## 加载配置
使用指令 `/dom reload_config`,加载配置的权限组。
## 将相应玩家添加到权限组
以 LuckPerms 为例,打开权限组查看是否有对应的权限,按照第一步的内容这里需要用 `sponsor``vip` 两个权限组:
<img src="https://ssl.lunadeer.cn:14437/i/2024/08/20/66c46029af3ed.png" alt="" width="20%">
如果没有则需要创建,创建完成后根据你的需要给对应玩家添加 `group.sponsor` 或者 `group.vip` 即可。
最后保存 LuckPerms 配置,即可生效。
## 注意事项
`groups` 中的 `WorldSettings``config.yml` 中的是独立的。
例如:你不希望任何玩家在下届顶层圈地(包括 `sponsor`),你已经在 `config.yml` 中设置了下届的 `MinY``MaxY`
如果你不在 `sponsor.yml` 中进行同样的设置的话,那么 `sponsor` 玩家就不会收到这个限制。

View File

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

@ -5,7 +5,7 @@
* [领地管理](manage-dominion/README.md)
* [环境设置](manage-dominion/environment.md)
* [权限管理](manage-dominion/permission/README.md)
* [访客权限](manage-dominion/permission/guest)
* [访客权限](manage-dominion/permission/guest.md)
* [领地成员](manage-dominion/permission/member.md)
* [权限组](manage-dominion/permission/permission-group.md)
* [权限模板](manage-dominion/permission/template.md)
@ -20,5 +20,7 @@
* [配置文件参考](operator/config.md)
* [flags.yml](operator/flags.md)
* [特权玩家配置](operator/privilege.md)
* [Papi一览](operator/papi.md)
* [跨群组服传送global-tp 测试中)](operator/global-tp.md)
* [开发者文档](developer.md)

Some files were not shown because too many files have changed in this diff Show More