Compare commits

...

178 Commits

Author SHA1 Message Date
a4c61f183c 将项目迁移到GitHub https://github.com/DeerGiteaMirror/Dominion
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m55s
2024-08-25 11:13:02 +08:00
eeb0f1adc7 实现了采用world uid存储世界而不是name(如果使用此版本出现问题请不要回退版本!请立即和作者取得联系!)
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m4s
2024-08-24 20:53:07 +08:00
87fc89407d 完成了DTO的修改 2024-08-24 19:50:12 +08:00
85b9becfab 更新版本
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m14s
2024-08-24 19:22:41 +08:00
2e589287b5 Merge remote-tracking branch 'origin/master' 2024-08-24 19:20:12 +08:00
ba495d9bd7 修复了部分领地tp点报错未捕获异常问题 2024-08-24 19:15:07 +08:00
bbb97b0859 修复了漏斗可以偷领地内箱子的漏洞
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 5m33s
修复了活塞可以跨领地推东西导致潜在破坏的漏洞
2024-08-23 19:42:19 +08:00
150939dc45 修复了领地管理员权限组可能无法管理领地玩家的问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 5m11s
2024-08-22 10:44:49 +08:00
0cb2ac81d4 修复领地系统权限组配置被覆写问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 4m11s
完成了领地系统权限组功能开发
(此功能详见 > https://ssl.lunadeer.cn:14448/doc/82/)
2024-08-21 10:29:31 +08:00
a39030e258 更新 README.md 2024-08-20 14:06:47 +08:00
fd853661e3 实现了领地系统多权限组(多种圈地限制)功能 2024-08-19 22:17:10 +08:00
230e26037f 新增领地系统权限组 2024-08-19 18:47:35 +08:00
9660968125 完善配置文件 2024-08-19 14:24:30 +08:00
765fef5c66 优化代码结构,修复了某些指令输入错误时缺少提示的问题
Some checks failed
Java CI-CD with Gradle / build (push) Failing after 7m50s
2024-08-19 14:14:08 +08:00
6978e4f05b 更新README 2024-08-19 10:32:25 +08:00
3ec3c63724 更新README 2024-08-19 10:31:23 +08:00
170dd8cbe7 修复了展示框可被小白破坏的问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 31m40s
2024-08-14 17:08:30 +08:00
a321e39fe5 数据库新增自动重连机制,允许修改配置文件后直接重连不必再重启服务器
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 31m17s
2024-08-14 10:04:20 +08:00
0e638e00b2 引入计时器统计性能 2024-08-13 14:49:56 +08:00
3fe0ebfe3c 从菜单中暂时移除帮助菜单 2024-08-12 21:22:28 +08:00
16d2ae73d8 修复领地所有者可以被添加为领地成员的漏洞
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 15m10s
2024-08-12 19:38:39 +08:00
7f04300fc3 gradle更换国内源
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 15m53s
2024-08-12 17:54:43 +08:00
5f3051aaf9 gradle更换国内源
Some checks failed
Java CI-CD with Gradle / build (push) Failing after 7m59s
2024-08-12 17:45:49 +08:00
761d51c653 修复op无法绕过出生点保护问题
Some checks failed
Java CI-CD with Gradle / build (push) Has been cancelled
2024-08-12 17:31:39 +08:00
a66014227c 修复op无法绕过出生点保护问题
Some checks failed
Java CI-CD with Gradle / build (push) Has been cancelled
2024-08-12 16:32:34 +08:00
0471764641 新增领地住主可以使用自己领地的任意的权限组
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 1h5m12s
2024-08-12 11:00:29 +08:00
53ec758ad4 修复领地列表丢失问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 40m29s
2024-08-11 15:32:42 +08:00
4ebcb4e7fd 优化称号列表显示
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 30m14s
2024-08-11 12:43:53 +08:00
a37f194d1b 修复了不能卸下权限组称号的问题
Some checks failed
Java CI-CD with Gradle / build (push) Failing after 1m31s
2024-08-11 12:23:15 +08:00
c0fcc2aaa0 初步实现了权限组称号功能
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 13m11s
2024-08-11 11:56:40 +08:00
bb32f085ac 新增权限组称号前后缀 2024-08-11 08:30:24 +08:00
e6cea57dfe 优化TNT爆炸保护 2024-08-11 08:12:23 +08:00
ee470c6cad Merge remote-tracking branch 'origin/master'
# Conflicts:
#	build.gradle.kts
2024-08-11 02:00:10 +08:00
8da3c1e871 初步实现了权限组称号功能(还缺少前后缀) 2024-08-11 01:59:34 +08:00
c9ea2384a0 修复设置tui中出生点保护范围显示不正确的问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 31m5s
2024-08-09 00:20:34 +08:00
99125fa924 修复了删除领地时不能退款的问题
All checks were successful
Java CI-CD with Gradle / build (push) Successful in 25m57s
2024-08-07 12:49:19 +08:00
15793e24b4 add gradle-wrapper.jar
All checks were successful
Java CI-CD with Maven / build (push) Successful in 15m48s
2024-08-05 20:45:00 +08:00
4deb2ac5fa 多版本支持
Some checks failed
Java CI-CD with Maven / build (push) Failing after 1m16s
2024-08-05 20:37:27 +08:00
3923973778 Merge branch 'refs/heads/nms-for-multi-version' 2024-08-05 20:36:35 +08:00
e0bd285e74 实现了多模块、多版本打包 2024-08-05 15:46:35 +08:00
cabd3149ff 尝试通过多模块引入多版本支持(编译脚本有问题) 2024-08-05 00:52:12 +08:00
96c07e3067 修复有些情况下玩家无法从res迁移领地的问题 2024-08-04 22:50:12 +08:00
0ad56e3c0b 提高1.20.x兼容性 2024-08-03 08:37:15 +08:00
4a8ae8b568 提高1.20.x兼容性 2024-08-02 22:26:45 +08:00
c74b332e65 尝试对1.20.x兼容 2024-08-02 17:48:25 +08:00
010e9386da 优化部分代码 2024-08-02 16:08:01 +08:00
8bee085eda 新增gradle以辅助cicd运行 2024-08-02 10:23:32 +08:00
533063ee7c 更新CI-CD以适配gradle 2024-08-02 10:22:44 +08:00
86fe23421f 新增权限:投掷物触发压力板
新增权限:生物触发压力板
新增权限:掉落物触发压力板
新增权限:投掷物是否可以破坏展示框/画
2024-08-02 10:19:24 +08:00
36a32c1d7b 还原部分api提高兼容性 2024-08-01 23:10:51 +08:00
9180a2a4e0 新增支持1.21的合成台权限控制 2024-08-01 23:06:01 +08:00
49772fadc9 初步完成到gradle的迁移 2024-08-01 18:03:21 +08:00
6007773710 迁移项目至gradle 2024-08-01 17:11:07 +08:00
316abaef33 添加开源许可证 2024-08-01 17:07:44 +08:00
2c013e0eb4 尝试添加1.21更新 2024-08-01 16:06:56 +08:00
86d40fedb2 修复潜影贝打掉地图的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 11m7s
2024-07-31 15:16:23 +08:00
9e1ad7640a 修复玩家可以用弓箭打掉地图的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m6s
2024-07-30 17:26:12 +08:00
79d7f13a94 修复了领地管理员默认可能无法传送到领地的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m7s
2024-07-29 15:11:30 +08:00
5e5d45e1d7 修复了领地外边缘的爆炸会波及领地内的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m55s
2024-07-26 15:45:58 +08:00
bdfb368716 优化转移领地所有权的逻辑校验
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m25s
2024-07-26 14:10:09 +08:00
46d15d01eb 补充悬挂物放置
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m16s
2024-07-26 12:00:18 +08:00
26fa5f60a5 修复权限组默认不生效问题 2024-07-25 21:20:51 +08:00
f22b97a7f7 优化完善展示框行为 2024-07-25 16:54:32 +08:00
8b9e984917 修复即使没有权限也能破坏展示框的问题 2024-07-25 15:48:41 +08:00
bdec39272c 修正错别字 2024-07-25 13:20:39 +08:00
ee2cc157d0 新增权限节点功能 2024-07-25 00:08:49 +08:00
d348ee76f9 新增出生点半径保护
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m19s
2024-07-24 16:25:46 +08:00
c2caf96c03 新增音符盒权限控制
All checks were successful
Java CI-CD with Maven / build (push) Successful in 15m19s
2024-07-23 21:57:38 +08:00
e3cd0a04a8 新增op上线会自动发送更新提示消息
All checks were successful
Java CI-CD with Maven / build (push) Successful in 22m1s
2024-07-22 21:48:54 +08:00
4706e1325a 修复了小范围扩建、缩小领地时经济计算尺寸不正确问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 14m17s
2024-07-22 21:06:36 +08:00
066d7a389b 修复经济无法正常连接问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m25s
2024-07-21 11:53:39 +08:00
9a11f4b1f9 新增op可绕过经济检查
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m5s
2024-07-21 01:47:07 +08:00
00193c5cb9 更新了readme 2024-07-20 17:30:30 +08:00
ff0a65a3d5 更新了readme 2024-07-20 17:29:45 +08:00
fc09831546 修复了第一次连接经济插件时必失败的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m32s
2024-07-20 12:12:34 +08:00
aeb8264645 新增对VaultUnlock的支持
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m7s
2024-07-19 23:05:07 +08:00
390333e782 优化管理员设置页面小数过长问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m11s
2024-07-19 09:58:15 +08:00
fe75a3cfda 修复了在某些情况下没有经济插件也能创建领地的可能
All checks were successful
Java CI-CD with Maven / build (push) Successful in 13m14s
2024-07-18 20:26:26 +08:00
1297f0cb34 修复在没有dynmap下无法加载的问题。
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m7s
2024-07-18 14:40:35 +08:00
4d1325a126 合并 Dynmap,现已支持 Dynmap 卫星地图渲染。
All checks were successful
Java CI-CD with Maven / build (push) Successful in 35m43s
2024-07-18 11:40:26 +08:00
81e7cdd217 Merge branch 'dynmap-impl'
# Conflicts:
#	pom.xml
#	src/main/java/cn/lunadeer/dominion/Cache.java
2024-07-18 11:33:17 +08:00
4beeea5040 优化边界显示 2024-07-18 11:32:05 +08:00
6f1ae1a904 修复dynmap渲染报错问题 2024-07-18 10:44:02 +08:00
aa31a45cec Merge branch 'master' into dynmap-impl
# Conflicts:
#	pom.xml
2024-07-18 09:51:24 +08:00
9c2d18cc3e 更新说明 2024-07-17 23:44:37 +08:00
b3934b9fe2 优化缓存领地搜索算法,提速300%
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m3s
2024-07-17 18:06:58 +08:00
de2d8758d1 Merge branch 'master' into dynmap-impl
# Conflicts:
#	pom.xml
2024-07-15 15:57:15 +08:00
0fe7f28c64 修复了领地显示尺寸与实际尺寸不一致问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m25s
2024-07-15 15:20:13 +08:00
4c8066f7cb Merge remote-tracking branch 'origin/master'
# Conflicts:
#	pom.xml
2024-07-13 16:34:46 +08:00
cc2423dd1b 新增“末影龙破坏方块”领地设置
All checks were successful
Java CI-CD with Maven / build (push) Successful in 13m46s
2024-07-13 16:33:41 +08:00
ba81403d6f 修复了自动垂直选取不生效问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 15m2s
2024-07-12 21:11:51 +08:00
f3c52fe8e5 修复了扩展领地时经济行为错误问题(如果你是1.35.9-beta版本请务必更新) 2024-07-10 12:13:12 +08:00
95d6d809b0 Merge branch 'master' into dynmap-impl
# Conflicts:
#	pom.xml
2024-07-10 12:11:47 +08:00
c859718f8b 修复了扩展领地时经济行为错误问题(如果你是1.35.9-beta版本请务必更新)
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m31s
2024-07-10 12:00:49 +08:00
23eb35c8b3 新增dynmap支持 2024-07-10 11:56:22 +08:00
fb1736e0f2 新增数据统计项
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m29s
2024-07-08 16:51:16 +08:00
c858332fbd 补充DominionDTO中缺失的方法 2024-07-08 01:28:05 +08:00
9997fc12a9 优化DominionController结构 2024-07-08 01:23:09 +08:00
eb9fd31277 修复了使用菜单创建领地时不会自动选点或选点错误的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m17s
2024-07-07 11:01:04 +08:00
zhangyuheng
e7a5e2b37f 修复了模板配置无法翻页的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 34m22s
2024-07-07 00:45:34 +08:00
32c730e28c 修复领地传送点异常bug
All checks were successful
Java CI-CD with Maven / build (push) Successful in 7m55s
2024-07-06 20:11:07 +08:00
0e1eb53465 将“领地没有传送点”警告从控制台警告修改为玩家消息提示警告
Some checks failed
Java CI-CD with Maven / build (push) Has been cancelled
2024-07-06 20:08:40 +08:00
f08e0f51e2 修复了由于调用了paper特殊api导致在spigot下有概率报错问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 28m59s
2024-07-05 11:53:04 +08:00
6a3f9fbd20 修复了创建领地时领地列表结构不自动分级问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 28m32s
2024-07-04 14:55:17 +08:00
26f87ab835 将经济系统初始化移动到配置文件加载中,现在即便重载配置也能hook经济系统
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m23s
2024-07-04 13:40:25 +08:00
a119cf747f 新增数据库类型bstats统计(匿名)
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m33s
2024-07-04 10:22:14 +08:00
4498267c50 修复提示错误 2024-07-04 10:13:18 +08:00
0d714a402b 修复权限组设置tp权限无法生效的问题 2024-07-03 15:37:14 +08:00
21a5b10a97 更新表名、内部变量名,规范项目内部分命名 2024-07-03 14:51:40 +08:00
e690b3f66a 新增龙蛋保护权限
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m42s
2024-07-03 11:19:16 +08:00
9b94a2c5a6 优化了权限设置拦截
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m10s
2024-07-01 21:08:46 +08:00
9a36ddbc06 修复了选择权限组成员时出现多个重复权限的问题 2024-07-01 21:05:36 +08:00
2f7ae111a9 修复了选择权限组成员时无法翻页的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 7m25s
2024-07-01 01:41:08 +08:00
bf9aa8414c 重构了tui相关的页面逻辑代码
All checks were successful
Java CI-CD with Maven / build (push) Successful in 29m8s
2024-06-30 21:25:25 +08:00
73fe76c3c7 修复权限组飞行发光设置不生效问题 2024-06-30 09:48:28 +08:00
2f8a0f2e23 新增输入内容合法性检查 2024-06-30 00:40:45 +08:00
68c6ccd5d0 优化权限组列表展示 2024-06-30 00:01:39 +08:00
f4b234928a 重构部分CUI结构 2024-06-29 12:41:55 +08:00
aa30f178de 优化选择成员界面副标题内容 2024-06-29 11:19:29 +08:00
e2508904f4 修复了权限组相关bug,初步测试可用 2024-06-29 00:46:54 +08:00
146fa32480 实现了权限组功能(未测试) 2024-06-28 17:41:12 +08:00
27a7dea809 实现了权限组功能(未测试) 2024-06-28 17:40:51 +08:00
13c6d59b04 更新 readme
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m41s
2024-06-26 16:21:02 +08:00
b7b7311d5f Merge branch 'res-migration'
# Conflicts:
#	pom.xml
2024-06-26 16:20:01 +08:00
266db4850e 新增传送倒计时提示 2024-06-26 14:49:26 +08:00
3156bda387 Merge branch 'master' into res-migration
# Conflicts:
#	pom.xml
#	src/main/java/cn/lunadeer/dominion/Commands.java
#	src/main/java/cn/lunadeer/dominion/dtos/DominionDTO.java
#	src/main/java/cn/lunadeer/dominion/dtos/PlayerDTO.java
2024-06-26 10:12:24 +08:00
8196d6d225 修复了无法从residence迁移tp点的问题 2024-06-26 10:03:51 +08:00
2dfbae52cf 新增配置项,控制是否可以从residence迁移数据 2024-06-25 19:49:02 +08:00
98093f2532 初步实现了从residence迁移数据的功能 2024-06-25 17:38:28 +08:00
90245ce5b6 新增:动物生成(繁殖)、对村民造成伤害、村民繁殖,三种权限(行为)控制
All checks were successful
Java CI-CD with Maven / build (push) Successful in 7m50s
2024-06-25 10:37:38 +08:00
570ea0c75c 修复没有权限仍然能打开告示牌编辑界面的问题(修复前:可以打开,但是不能编辑;修复后直接无法打开) 2024-06-25 10:15:54 +08:00
26bc618b93 修复没有权限仍然能通过床设置重生点的权限漏洞 2024-06-25 09:43:20 +08:00
e33be83b07 修复在领地外仍然能触发按钮的权限漏洞 2024-06-25 09:31:48 +08:00
a090ea7bf1 修复了无法修改管理员发光效果的bug
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m38s
2024-06-24 13:49:46 +08:00
f608041e9a 移除部分旧代码,优化import 2024-06-24 10:50:22 +08:00
9089d7ae34 Merge branch 'mysql-impl'
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m38s
# Conflicts:
#	pom.xml
#	src/main/java/cn/lunadeer/dominion/Cache.java
2024-06-23 10:10:08 +08:00
a568d87ff6 修复玩家修改名字时领地丢失的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 14m4s
2024-06-21 23:54:07 +08:00
17870432fe 优化领地缓存更新加载策略,提高效率 2024-06-21 15:49:40 +08:00
723ac794fe 优化成员权限缓存更新加载策略,提高效率 2024-06-21 14:57:21 +08:00
278ce8a686 优化成员权限缓存更新加载策略,提高效率 2024-06-21 14:33:21 +08:00
2f9c4cd73a 修复bukkit核心无法使用expand/contract问题 2024-06-21 10:00:07 +08:00
d23c368d10 修复数据类型错误 2024-06-21 00:58:34 +08:00
ea9be48c68 新增缓存计时器 2024-06-21 00:46:31 +08:00
abab7967b0 优化dominion dto内容结构,将原始变量合并到Field中 2024-06-20 17:58:33 +08:00
6f0b97f458 初步实现mysql支持,初步测试了三种数据库(暂无问题) 2024-06-20 00:53:46 +08:00
cac0b91734 初步实现mysql适配 2024-06-19 21:01:20 +08:00
7a6798bed1 修改dto代码适配新数据库工具库 2024-06-19 18:00:51 +08:00
268648e492 修复某些情况下无法正确hook到经济插件问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m14s
2024-06-18 16:30:31 +08:00
03cb1af603 初步实现mysql适配,但暂时存在returning语法缺失问题 2024-06-17 17:51:43 +08:00
2299630e15 将tnt爆炸、火焰蔓延等领地独有的(非玩家行为)控制从“访客权限”移动到“环境设置”,避免歧义
All checks were successful
Java CI-CD with Maven / build (push) Successful in 7m34s
2024-06-17 15:12:51 +08:00
4bd817bd84 实现了卫星地图自定义色块功能
All checks were successful
Java CI-CD with Maven / build (push) Successful in 7m44s
2024-06-17 10:31:25 +08:00
7328e9aff1 优化了数据库连接方式 2024-06-14 14:17:30 +08:00
78095df43a 修复了当关闭领地传送时拥有者也无法传送的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 9m52s
2024-06-12 23:43:40 +08:00
d492663e8d 修复了修改发光、飞行权限时无法立即生效只有重新进出领地才会生效的问题 2024-06-12 23:42:37 +08:00
dc50603a91 新增告示牌编辑权限
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m12s
2024-06-12 16:07:35 +08:00
7d28622904 修改部分菜单命名
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m11s
2024-06-12 15:36:06 +08:00
d28d20757b 初步实现了迁移 2024-06-12 15:08:22 +08:00
8613feda90 完善readme 2024-06-10 19:08:51 +08:00
75ba23f593 新增cui提示消息,合并bukkit适配
All checks were successful
Java CI-CD with Maven / build (push) Successful in 14m31s
2024-06-09 23:48:23 +08:00
e731a9023d Merge branch 'bukkit-impl'
# Conflicts:
#	pom.xml
#	src/main/java/cn/lunadeer/dominion/controllers/PrivilegeController.java
2024-06-09 21:35:55 +08:00
4c80ad292e 实现了权限模板套用功能
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m1s
2024-06-08 09:35:30 +08:00
ae1444c469 实现了成员权限模板界面 2024-06-07 13:11:51 +08:00
dcf52b0954 修复了bukkit下消息提示报错问题 2024-06-06 13:24:06 +08:00
fbd47a49af 完成了对bukkit的适配,优化了经济系统的实现方式 2024-06-06 10:49:27 +08:00
9271860511 实现了基本功能 2024-06-05 22:51:54 +08:00
e7900d72cd 优化传送失败时的消息提示
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m40s
2024-06-05 14:46:58 +08:00
c3f4c6f502 优化尺寸输出代码 2024-06-02 23:38:23 +08:00
9b7917aa14 修复了选区价格和创建价格不符问题、修复了玩家重新上线时飞行权限不生效问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 13m14s
2024-06-02 23:18:13 +08:00
7b4d26970b 修复了创建领地失败,提示数据库错误的问题。
All checks were successful
Java CI-CD with Maven / build (push) Successful in 13m3s
2024-06-02 17:01:54 +08:00
08d6e93e7e 优化了错误处理框架 2024-06-01 12:39:00 +08:00
c30e5d9d66 领地提示语新增支持占位符
All checks were successful
Java CI-CD with Maven / build (push) Successful in 6m41s
2024-06-01 09:59:55 +08:00
a8e36f4759 新增玩家名字排序
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m56s
2024-05-31 21:29:11 +08:00
5d614d4760 修复了操作领地时自动选择领地失败问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 12m11s
2024-05-31 21:03:00 +08:00
a34cc43cbf 实现了对权限列表的排序
All checks were successful
Java CI-CD with Maven / build (push) Successful in 10m0s
2024-05-31 20:47:50 +08:00
6666fb6131 优化了数据表的生成方式
All checks were successful
Java CI-CD with Maven / build (push) Successful in 1h11m11s
2024-05-31 17:30:08 +08:00
31ba268f2f 新增flags json序列化 2024-05-30 18:20:40 +08:00
5c3e0d847b 新增所有领地界面、成员新增tag便于标识身份
All checks were successful
Java CI-CD with Maven / build (push) Successful in 8m37s
2024-05-30 10:07:22 +08:00
033b103d35 修复在没有领地的时候报错null的问题
All checks were successful
Java CI-CD with Maven / build (push) Successful in 17m31s
2024-05-29 23:59:25 +08:00
117 changed files with 9906 additions and 3752 deletions

View File

@ -1,4 +1,4 @@
name: Java CI-CD with Maven name: Java CI-CD with Gradle
on: on:
push: push:
@ -13,18 +13,17 @@ jobs:
uses: https://ssl.lunadeer.cn:14446/actions/checkout@v3 uses: https://ssl.lunadeer.cn:14446/actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: "Set up Maven" - name: "Set up JDK 21"
uses: https://ssl.lunadeer.cn:14446/actions/setup-maven@v4
- name: "Set up JDK 17"
uses: https://ssl.lunadeer.cn:14446/actions/setup-java@v3 uses: https://ssl.lunadeer.cn:14446/actions/setup-java@v3
with: with:
java-version: '17' java-version: '21'
distribution: 'zulu' distribution: 'zulu'
cache: maven cache: gradle
- name: "Build with Maven" - name: "Build with Gradle"
run: mvn -B package --file pom.xml run: |
./gradlew buildPlugin
- name: "Copy jar to staging" - name: "Copy jar to staging"
run: mkdir staging && cp target/*.jar staging run: mkdir staging && cp build/libs/*.jar staging/
- name: "Build & test" - name: "Build & test"
run: | run: |
echo "done!" echo "done!"

View File

@ -1,4 +1,4 @@
name: Java CI-CD with Maven name: Java CI-CD with Gradle
on: on:
push: push:
@ -11,33 +11,24 @@ jobs:
permissions: write-all permissions: write-all
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# 下载代码
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up JDK 17 - name: Set up JDK 21
# 安装 JDK
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: '17' java-version: '21'
distribution: 'temurin' distribution: 'zulu'
cache: maven cache: gradle
# Maven 打包 - name: "Build with Gradle"
- name: Build with Maven run: ./gradlew buildPlugin
run: mvn -B package --file pom.xml - name: "Copy jar to staging"
# 将打包好的 Jar 包 放到 staging 文件夹 run: mkdir staging && cp build/libs/*.jar staging/
- run: mkdir staging && cp target/*.jar staging
# 设置 jobs Maven pom 版本环境变量
- name: Set Release version env variable
run: |
echo "RELEASE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV
- name: "Build & test" - name: "Build & test"
run: | run: |
echo "done!" echo "done!"
# 上传文件并发布 Release
- uses: "marvinpinto/action-automatic-releases@latest" - uses: "marvinpinto/action-automatic-releases@latest"
with: with:
repo_token: "${{ secrets.GITHUB_TOKEN }}" repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest" automatic_release_tag: "latest"
prerelease: false prerelease: false
title: "Release ${{ env.RELEASE_VERSION }}"
files: | files: |
staging/*.jar staging/*.jar

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 ZhangYuheng
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,8 +1,8 @@
<div style="text-align: center;"> <div align="center">
<img src="https://ssl.lunadeer.cn:14437/i/2024/03/28/6604f0cec0f0e.png" alt="" width="70%"> <img src="https://ssl.lunadeer.cn:14437/i/2024/03/28/6604f0cec0f0e.png" alt="" width="70%">
### [开源地址](https://ssl.lunadeer.cn:14446/zhangyuheng/Dominion) | [文档地址](https://ssl.lunadeer.cn:14448/doc/23/) ### [开源地址](https://github.com/DeerGiteaMirror/Dominion) | [文档地址](https://ssl.lunadeer.cn:14448/doc/23/)
### [下载页面](https://ssl.lunadeer.cn:14446/zhangyuheng/Dominion/releases) ### [下载页面](https://ssl.lunadeer.cn:14446/zhangyuheng/Dominion/releases)
@ -12,9 +12,9 @@
## 简介 ## 简介
鉴于 Residence 插件的作者项目较多维护压力大无法及时跟进新版本以及适配Folia核心。故开发此插件旨在平替纯净版生存服Residence的使用。 鉴于 Residence 插件的作者项目较多维护压力大无法及时跟进新版本以及适配Folia核心。故开发此插件旨在平替纯净版生存服Residence的使用(支持从 Res 迁移数据)
请注意本插件仍然处于测试阶段因此可能存在一定的行为控制漏洞。如果遇到此类遗漏的行为控制欢迎即使发送邮件或添加QQ告知感激不尽。 **请注意本插件目前处于中期测试稳定阶段绝大多数bug或漏洞已被修复目前已具备完全可用性。但不排除仍然存在某些问题如果遇到任何 BUG 欢迎及时发送邮件或添加QQ群告知感激不尽。**
## 说明 ## 说明
@ -28,36 +28,43 @@
## 功能介绍 ## 功能介绍
- 支持 Postgresql 或 sqlite 存储数据; - 支持 Postgresql、Mysql、Sqlite3 存储数据;
- 支持BlueMap卫星地图渲染 - 支持 BlueMap、Dynmap 卫星地图渲染;
- 支持为玩家单独设置特权; - 支持为玩家单独设置特权;
- 支持设置领地管理员; - 支持设置领地管理员;
- 支持子领地; - 支持子领地;
- 采用 TUI 方式进行权限配置交互,简单快捷; - 采用 TUI 方式进行权限配置交互,简单快捷;
- 支持基础价格系统 - 支持经济系统(需要 Vault 前置)
- 领地区域可视化; - 领地区域可视化;
- 管理员可在游戏内使用TUI配置领地系统 - 管理员可在游戏内使用TUI配置领地系统
- 支持[从 Residence 迁移](https://ssl.lunadeer.cn:14448/doc/73/)领地数据1.33.7+
- 超高性能一个坐标在10127个领地内的搜索平均耗时不超过0.2ms仅占用1tick的不到0.4%时间)
<div style="text-align: center;"> <div align="center">
创建领地 ### 创建领地
<img src="https://ssl.lunadeer.cn:14437/i/2024/05/10/663debf78eca4.gif" alt="" width="60%"> <img src="https://ssl.lunadeer.cn:14437/i/2024/05/10/663debf78eca4.gif" alt="" width="60%">
权限管理 ### 权限管理
<img src="https://ssl.lunadeer.cn:14437/i/2024/05/10/663debe052786.gif" alt="" width="60%"> <img src="https://ssl.lunadeer.cn:14437/i/2024/05/10/663debe052786.gif" alt="" width="60%">
配置 ### 配置
<img src="https://ssl.lunadeer.cn:14437/i/2024/05/10/663debec11dad.gif" alt="" width="60%"> <img src="https://ssl.lunadeer.cn:14437/i/2024/05/10/663debec11dad.gif" alt="" width="60%">
### 高性能
<img src="https://ssl.lunadeer.cn:14437/i/2024/08/13/66bad56cc9fac.png" alt="" width="60%">
</div> </div>
## 支持版本 ## 支持版本
- 1.20.1+ (Paper、Folia) - 1.20.1+ (Bukkit、Spigot、Paper、Folia)
> 需要使用 Java21 运行你的服务端,如果你还在使用 Java17 可以放心替换为 Java21理论上 1.20.1+ 版本的服务端核心可以直接升级到 Java21 启动。
## TODO ## TODO

73
build.gradle.kts Normal file
View File

@ -0,0 +1,73 @@
plugins {
id("java")
id("com.github.johnrengelman.shadow") version "8.1.1"
}
group = "cn.lunadeer"
version = "2.3.0-beta"
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}
// utf-8
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
allprojects {
apply(plugin = "java")
apply(plugin = "com.github.johnrengelman.shadow")
repositories {
mavenLocal()
mavenCentral()
maven("https://oss.sonatype.org/content/groups/public")
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/")
}
dependencies {
compileOnly("com.github.BlueMap-Minecraft:BlueMapAPI:v2.6.2")
compileOnly("us.dynmap:DynmapCoreAPI:3.4")
compileOnly("me.clip:placeholderapi:2.11.6")
implementation("cn.lunadeer:MinecraftPluginUtils:1.3.7-SNAPSHOT")
implementation("org.yaml:snakeyaml:2.0")
}
tasks.processResources {
outputs.upToDateWhen { false }
// replace @version@ in plugin.yml with project version
filesMatching("**/plugin.yml") {
filter {
it.replace("@version@", rootProject.version.toString())
}
}
}
tasks.shadowJar {
archiveClassifier.set("")
archiveVersion.set(project.version.toString())
dependsOn(tasks.withType<ProcessResources>())
}
}
dependencies {
implementation(project(":core"))
implementation(project(":v1_20_1"))
implementation(project(":v1_21"))
}
tasks.shadowJar {
archiveClassifier.set("")
archiveVersion.set(project.version.toString())
}
tasks.register("buildPlugin") { // <<<< RUN THIS TASK TO BUILD PLUGIN
dependsOn(tasks.clean)
dependsOn(tasks.shadowJar)
}

16
core/build.gradle.kts Normal file
View File

@ -0,0 +1,16 @@
plugins {
id("java")
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}
// utf-8
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
dependencies {
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
}

View File

@ -0,0 +1,591 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.*;
import cn.lunadeer.dominion.utils.MapRender;
import cn.lunadeer.dominion.utils.Particle;
import cn.lunadeer.dominion.utils.ResMigration;
import cn.lunadeer.minecraftpluginutils.AutoTimer;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import static cn.lunadeer.dominion.DominionNode.getLocInDominionNode;
import static cn.lunadeer.dominion.DominionNode.isInDominion;
public class Cache {
public Cache() {
player_current_dominion_id = new HashMap<>();
loadDominions();
loadMembers();
loadGroups();
}
/**
* 从数据库加载所有领地
* 如果idToLoad为null则加载所有领地
*
* @param idToLoad 领地ID
*/
public void loadDominions(Integer idToLoad) {
if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadDominionsExecution directly");
loadDominionsExecution(idToLoad);
} else {
if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution");
_update_dominion_is_scheduled.set(true);
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution(idToLoad);
_update_dominion_is_scheduled.set(false);
},
delay_tick);
}
}
public void loadDominions() {
loadDominions(null);
}
private void loadDominionsExecution(Integer idToLoad) {
Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis();
int count = 0;
if (idToLoad == null) {
id_dominions = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
CompletableFuture<Void> res = dominion_trees.initAsync(dominions);
count = dominions.size();
for (DominionDTO d : dominions) {
id_dominions.put(d.getId(), d);
if (!dominion_children.containsKey(d.getParentDomId())) {
dominion_children.put(d.getParentDomId(), new ArrayList<>());
}
dominion_children.get(d.getParentDomId()).add(d.getId());
}
res.join(); // 等待树的构建完成
} else {
DominionDTO dominion = DominionDTO.select(idToLoad);
if (dominion == null && id_dominions.containsKey(idToLoad)) {
id_dominions.remove(idToLoad);
} else if (dominion != null) {
id_dominions.put(idToLoad, dominion);
count = 1;
}
}
MapRender.render();
recheckPlayerState = true;
_last_update_dominion.set(System.currentTimeMillis());
XLogger.debug("loadDominionsExecution cost: %d ms for %d dominions"
, System.currentTimeMillis() - start, count);
});
}
/**
* 从数据库加载所有玩家特权
* 如果player_uuid为null则加载所有玩家的特权
*
* @param player_uuid 玩家UUID
*/
public void loadMembers(UUID player_uuid) {
if (_last_update_member.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadMembersExecution directly");
loadMembersExecution(player_uuid);
} else {
if (_update_member_is_scheduled.get()) return;
XLogger.debug("schedule loadMembersExecution");
_update_member_is_scheduled.set(true);
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_member.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadMembersExecution scheduled");
loadMembersExecution(player_uuid);
_update_member_is_scheduled.set(false);
},
delay_tick);
}
}
public void loadMembers() {
loadMembers(null);
}
private void loadMembersExecution(UUID player_to_update) {
Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis();
List<MemberDTO> all_privileges;
if (player_to_update == null) {
all_privileges = MemberDTO.selectAll();
player_uuid_to_member = new ConcurrentHashMap<>();
} else {
all_privileges = MemberDTO.selectAll(player_to_update);
if (!player_uuid_to_member.containsKey(player_to_update)) {
player_uuid_to_member.put(player_to_update, new ConcurrentHashMap<>());
}
player_uuid_to_member.get(player_to_update).clear();
}
for (MemberDTO privilege : all_privileges) {
UUID player_uuid = privilege.getPlayerUUID();
if (!player_uuid_to_member.containsKey(player_uuid)) {
player_uuid_to_member.put(player_uuid, new ConcurrentHashMap<>());
}
player_uuid_to_member.get(player_uuid).put(privilege.getDomID(), privilege);
}
recheckPlayerState = true;
_last_update_member.set(System.currentTimeMillis());
XLogger.debug("loadMembersExecution cost: %d ms for %d privileges"
, System.currentTimeMillis() - start, all_privileges.size());
});
}
public void loadGroups() {
loadGroups(null);
}
public void loadGroups(Integer groupId) {
if (_last_update_group.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadGroupsExecution directly");
loadGroupExecution(groupId);
} else {
if (_update_group_is_scheduled.get()) return;
XLogger.debug("schedule loadGroupsExecution");
_update_group_is_scheduled.set(true);
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_group.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadGroupsExecution scheduled");
loadGroupExecution(groupId);
_update_group_is_scheduled.set(false);
},
delay_tick);
}
}
private void loadGroupExecution(Integer groupId) {
Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis();
if (groupId == null) {
id_groups = new ConcurrentHashMap<>();
List<GroupDTO> groups = GroupDTO.selectAll();
List<PlayerDTO> players = PlayerDTO.all();
for (GroupDTO group : groups) {
id_groups.put(group.getId(), group);
}
for (PlayerDTO player : players) {
map_player_using_group_title_id.put(player.getUuid(), player.getUsingGroupTitleID());
}
} else {
GroupDTO group = GroupDTO.select(groupId);
if (group == null && id_groups.containsKey(groupId)) {
id_groups.remove(groupId);
} else if (group != null) {
id_groups.put(groupId, group);
}
}
recheckPlayerState = true;
_last_update_group.set(System.currentTimeMillis());
XLogger.debug("loadGroupsExecution cost: %d ms", System.currentTimeMillis() - start);
});
}
/**
* 获取玩家当前所在领地
* 此方法会先判断缓存中是否有玩家当前所在领地如果没有则遍历所有领地判断玩家所在位置
* 如果玩家不在任何领地内则返回null
* 如果玩家在领地内则返回领地信息
*
* @param player 玩家
* @return 玩家当前所在领地
*/
public DominionDTO getPlayerCurrentDominion(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;
if (last_in_dom_id != null) {
last_dominion = id_dominions.get(last_in_dom_id);
}
if (isInDominion(last_dominion, player.getLocation())) {
if (dominion_children.get(last_in_dom_id) == null || dominion_children.get(last_in_dom_id).isEmpty()) {
// 如果玩家仍在领地内且领地没有子领地则直接返回
if (recheckPlayerState) {
lightOrNot(player, last_dominion);
flyOrNot(player, last_dominion);
recheckPlayerState = false;
}
return last_dominion;
}
}
DominionDTO current_dominion = dominion_trees.getLocInDominionDTO(player.getLocation());
int last_dom_id = last_dominion == null ? -1 : last_dominion.getId();
int current_dom_id = current_dominion == null ? -1 : current_dominion.getId();
if (last_dom_id == current_dom_id) {
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);
}
if (current_dom_id != -1) {
String msg = current_dominion.getJoinMessage();
msg = msg.replace("${DOM_NAME}", current_dominion.getName());
Notification.actionBar(player, msg);
}
lightOrNot(player, current_dominion); // 发光检查
flyOrNot(player, current_dominion); // 飞行检查
if (current_dominion == null) {
player_current_dominion_id.put(player.getUniqueId(), null);
return null;
}
player_current_dominion_id.put(player.getUniqueId(), current_dominion.getId());
// show border
if (current_dominion.getFlagValue(Flag.SHOW_BORDER)) {
Particle.showBorder(player, current_dominion);
}
return current_dominion;
}
}
/**
* 玩家退出时调用 用于清除玩家当前所在领地
* 会将玩家当前所在领地设置为null
* 这样当玩家下次进入领地时会重新检查玩家所在位置
*
* @param player 玩家
*/
public void onPlayerQuit(Player player) {
player_current_dominion_id.put(player.getUniqueId(), null);
}
/**
* 检查玩家是否需要设置为发光
*
* @param player 玩家
* @param dominion 领地
*/
private void lightOrNot(Player player, DominionDTO dominion) {
if (!Flag.GLOW.getEnable()) {
return;
}
if (dominion == null) {
player.setGlowing(false);
return;
}
MemberDTO privilege = getMember(player, dominion);
if (privilege != null) {
if (privilege.getGroupId() == -1) {
player.setGlowing(privilege.getFlagValue(Flag.GLOW));
} else {
GroupDTO group = getGroup(privilege.getGroupId());
if (group != null) {
player.setGlowing(group.getFlagValue(Flag.GLOW));
} else {
player.setGlowing(dominion.getFlagValue(Flag.GLOW));
}
}
} else {
player.setGlowing(dominion.getFlagValue(Flag.GLOW));
}
}
private void flyOrNot(Player player, DominionDTO dominion) {
for (String flyPN : Dominion.config.getFlyPermissionNodes()) {
if (player.hasPermission(flyPN)) {
return;
}
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
if (player.isOp() && Dominion.config.getLimitOpBypass()) {
return;
}
if (!Flag.FLY.getEnable()) {
player.setAllowFlight(false);
return;
}
if (dominion == null) {
player.setAllowFlight(false);
return;
}
MemberDTO privilege = getMember(player, dominion);
if (privilege != null) {
if (privilege.getGroupId() == -1) {
player.setAllowFlight(privilege.getFlagValue(Flag.FLY));
} else {
GroupDTO group = getGroup(privilege.getGroupId());
if (group != null) {
player.setAllowFlight(group.getFlagValue(Flag.FLY));
} else {
player.setAllowFlight(dominion.getFlagValue(Flag.FLY));
}
}
} else {
player.setAllowFlight(dominion.getFlagValue(Flag.FLY));
}
}
public DominionDTO getDominionByLoc(Location loc) {
return dominion_trees.getLocInDominionDTO(loc);
}
public GroupDTO getGroup(Integer id) {
return id_groups.get(id);
}
/**
* 获取玩家在指定领地的特权
* 如果玩家不存在特权则返回null
*
* @param player 玩家
* @param dominion 领地
* @return 特权表
*/
public MemberDTO getMember(Player player, 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) {
if (!player_uuid_to_member.containsKey(player_uuid)) return null;
return player_uuid_to_member.get(player_uuid).get(dominion.getId());
}
public List<GroupDTO> getBelongGroupsOf(UUID plauer_uuid) {
List<GroupDTO> groups = new ArrayList<>();
if (!player_uuid_to_member.containsKey(plauer_uuid)) return groups;
for (MemberDTO member : player_uuid_to_member.get(plauer_uuid).values()) {
if (member.getGroupId() != -1) {
GroupDTO group = getGroup(member.getGroupId());
if (group != null) {
groups.add(group);
}
}
}
return groups;
}
public DominionDTO getDominion(Integer id) {
return id_dominions.get(id);
}
public int getPlayerDominionCount(UUID player_uuid) {
int count = 0;
for (DominionDTO dominion : id_dominions.values()) {
if (dominion.getOwner().equals(player_uuid)) {
count++;
}
}
return count;
}
public List<ResMigration.ResidenceNode> getResidenceData(UUID player_uuid) {
if (residence_data == null) {
residence_data = new HashMap<>();
List<ResMigration.ResidenceNode> residences = ResMigration.extractFromResidence(Dominion.instance);
for (ResMigration.ResidenceNode node : residences) {
if (node == null) {
continue;
}
if (!residence_data.containsKey(node.owner)) {
XLogger.debug("residence_data put %s", node.owner);
residence_data.put(node.owner, new ArrayList<>());
}
residence_data.get(node.owner).add(node);
}
XLogger.debug("residence_data: %d", residence_data.size());
}
return residence_data.get(player_uuid);
}
public List<DominionDTO> getDominions() {
return new ArrayList<>(id_dominions.values());
}
public int getDominionCounts() {
return id_dominions.size();
}
public int getMemberCounts() {
int count = 0;
for (Map<Integer, MemberDTO> member : player_uuid_to_member.values()) {
count += member.size();
}
return count;
}
public int getGroupCounts() {
return id_groups.size();
}
public static Cache instance;
private ConcurrentHashMap<Integer, DominionDTO> id_dominions;
private ConcurrentHashMap<Integer, GroupDTO> id_groups;
private final WorldDominionTreeSectored dominion_trees = new WorldDominionTreeSectored();
private ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, MemberDTO>> player_uuid_to_member; // 玩家所有的特权
private final Map<UUID, Integer> player_current_dominion_id; // 玩家当前所在领地
private ConcurrentHashMap<Integer, List<Integer>> dominion_children;
private final AtomicLong _last_update_dominion = new AtomicLong(0);
private final AtomicBoolean _update_dominion_is_scheduled = new AtomicBoolean(false);
private final AtomicLong _last_update_member = new AtomicLong(0);
private final AtomicBoolean _update_member_is_scheduled = new AtomicBoolean(false);
private final AtomicLong _last_update_group = new AtomicLong(0);
private final AtomicBoolean _update_group_is_scheduled = new AtomicBoolean(false);
private static final long UPDATE_INTERVAL = 1000 * 4;
private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态发光飞行
public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>();
private Map<UUID, List<ResMigration.ResidenceNode>> residence_data = null;
private final Map<UUID, Integer> map_player_using_group_title_id = new HashMap<>();
private static class WorldDominionTreeSectored {
/*
D | C
--+--
B | A
*/
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_a; // x >= 0, z >= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_b; // x <= 0, z >= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_c; // x >= 0, z <= 0
private ConcurrentHashMap<UUID, List<DominionNode>> world_dominion_tree_sector_d; // x <= 0, z <= 0
public DominionDTO getLocInDominionDTO(@NotNull Location loc) {
try (AutoTimer ignored = new AutoTimer(Dominion.config.TimerEnabled())) {
List<DominionNode> nodes = getNodes(loc);
if (nodes == null) return null;
if (nodes.isEmpty()) return null;
DominionNode dominionNode = getLocInDominionNode(nodes, loc);
return dominionNode == null ? null : dominionNode.getDominion();
}
}
public List<DominionNode> getNodes(@NotNull Location loc) {
return getNodes(loc.getWorld().getUID(), loc.getBlockX(), loc.getBlockZ());
}
public List<DominionNode> getNodes(World world, int x, int z) {
return getNodes(world.getUID(), x, z);
}
public List<DominionNode> getNodes(UUID world, int x, int z) {
if (x >= 0 && z >= 0) {
return world_dominion_tree_sector_a.get(world);
}
if (x <= 0 && z >= 0) {
return world_dominion_tree_sector_b.get(world);
}
if (x >= 0) {
return world_dominion_tree_sector_c.get(world);
}
return world_dominion_tree_sector_d.get(world);
}
public CompletableFuture<Void> initAsync(List<DominionDTO> dominions) {
return CompletableFuture.runAsync(() -> init(dominions));
}
private void init(List<DominionDTO> dominions) {
world_dominion_tree_sector_a = new ConcurrentHashMap<>();
world_dominion_tree_sector_b = new ConcurrentHashMap<>();
world_dominion_tree_sector_c = new ConcurrentHashMap<>();
world_dominion_tree_sector_d = new ConcurrentHashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_a = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_b = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_c = new HashMap<>();
Map<UUID, List<DominionDTO>> world_dominions_sector_d = new HashMap<>();
for (DominionDTO d : dominions) {
// 对每个世界的领地进行四个象限的划分
if (!world_dominions_sector_a.containsKey(d.getWorldUid()) ||
!world_dominions_sector_b.containsKey(d.getWorldUid()) ||
!world_dominions_sector_c.containsKey(d.getWorldUid()) ||
!world_dominions_sector_d.containsKey(d.getWorldUid())) {
world_dominions_sector_a.put(d.getWorldUid(), new ArrayList<>());
world_dominions_sector_b.put(d.getWorldUid(), new ArrayList<>());
world_dominions_sector_c.put(d.getWorldUid(), new ArrayList<>());
world_dominions_sector_d.put(d.getWorldUid(), new ArrayList<>());
}
if (d.getX1() >= 0 && d.getZ1() >= 0) {
world_dominions_sector_a.get(d.getWorldUid()).add(d);
} else if (d.getX1() <= 0 && d.getZ1() >= 0) {
if (d.getX2() >= 0) {
world_dominions_sector_a.get(d.getWorldUid()).add(d);
world_dominions_sector_b.get(d.getWorldUid()).add(d);
} else {
world_dominions_sector_b.get(d.getWorldUid()).add(d);
}
} else if (d.getX1() >= 0 && d.getZ1() <= 0) {
if (d.getZ2() >= 0) {
world_dominions_sector_a.get(d.getWorldUid()).add(d);
world_dominions_sector_c.get(d.getWorldUid()).add(d);
} else {
world_dominions_sector_c.get(d.getWorldUid()).add(d);
}
} else {
if (d.getX2() >= 0 && d.getZ2() >= 0) {
world_dominions_sector_a.get(d.getWorldUid()).add(d);
world_dominions_sector_b.get(d.getWorldUid()).add(d);
world_dominions_sector_c.get(d.getWorldUid()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
} else if (d.getX2() >= 0 && d.getZ2() <= 0) {
world_dominions_sector_c.get(d.getWorldUid()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
} else if (d.getZ2() >= 0 && d.getX2() <= 0) {
world_dominions_sector_b.get(d.getWorldUid()).add(d);
world_dominions_sector_d.get(d.getWorldUid()).add(d);
} else {
world_dominions_sector_d.get(d.getWorldUid()).add(d);
}
}
}
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_a.entrySet()) {
world_dominion_tree_sector_a.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_b.entrySet()) {
world_dominion_tree_sector_b.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_c.entrySet()) {
world_dominion_tree_sector_c.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
for (Map.Entry<UUID, List<DominionDTO>> entry : world_dominions_sector_d.entrySet()) {
world_dominion_tree_sector_d.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
}
}
public @Nullable GroupDTO getPlayerUsingGroupTitle(UUID uuid) {
if (!Dominion.config.getGroupTitleEnable()) {
return null;
}
if (map_player_using_group_title_id.containsKey(uuid)) {
return getGroup(map_player_using_group_title_id.get(uuid));
}
return null;
}
public void updatePlayerUsingGroupTitle(UUID uuid, Integer groupId) {
map_player_using_group_title_id.put(uuid, groupId);
}
}

View File

@ -2,8 +2,15 @@ package cn.lunadeer.dominion;
import cn.lunadeer.dominion.commands.*; import cn.lunadeer.dominion.commands.*;
import cn.lunadeer.dominion.controllers.PlayerController; import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.cuis.*;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.tuis.*; 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.utils.TuiUtils;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
@ -18,24 +25,6 @@ import java.util.List;
import static cn.lunadeer.dominion.commands.Helper.*; import static cn.lunadeer.dominion.commands.Helper.*;
public class Commands implements TabExecutor { public class Commands implements TabExecutor {
/*
创建领地 /dominion create <领地名称>
自动创建领地 /dominion auto_create <领地名称>
创建子领地 /dominion create_sub <子领地名称> [父领地名称]
自动创建子领地 /dominion auto_create_sub <子领地名称> [父领地名称]
扩张领地 /dominion expand [大小] [领地名称]
缩小领地 /dominion contract [大小] [领地名称]
删除领地 /dominion delete <领地名称> [force]
设置领地权限 /dominion set <权限名称> <true/false> [领地名称]
设置玩家权限 /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]
重置玩家权限 /dominion clear_privilege <玩家名称> [领地名称]
创建权限组 /dominion create_group <权限组名称>
删除权限组 /dominion delete_group <权限组名称>
设置权限组权限 /dominion set_group <权限组名称> <权限名称> <true/false>
设置玩家在某个领地归属的权限组 /dominion add_player <玩家名称> <权限组名称> [领地名称]
删除玩家在某个领地归属的权限组 /dominion remove_player <玩家名称> <权限组名称> [领地名称]
*/
/** /**
* Executes the given command, returning its success. * Executes the given command, returning its success.
@ -60,19 +49,19 @@ public class Commands implements TabExecutor {
Menu.show(sender, args); Menu.show(sender, args);
break; break;
case "list": case "list":
ListDominion.show(sender, args); DominionList.show(sender, args);
break; break;
case "help": case "help":
cn.lunadeer.dominion.tuis.Apis.printHelp(sender, args); TuiUtils.printHelp(sender, args);
break; break;
case "info": case "info":
DominionSizeInfo.show(sender, args); SizeInfo.show(sender, args);
break; break;
case "manage": case "manage":
DominionManage.show(sender, args); DominionManage.show(sender, args);
break; break;
case "flag_info": case "guest_setting":
DominionFlagInfo.show(sender, args); GuestSetting.show(sender, args);
break; break;
case "create": case "create":
DominionOperate.createDominion(sender, args); DominionOperate.createDominion(sender, args);
@ -98,24 +87,6 @@ public class Commands implements TabExecutor {
case "set": case "set":
DominionFlag.setDominionFlag(sender, args); DominionFlag.setDominionFlag(sender, args);
break; break;
case "create_privilege":
PlayerPrivilege.createPlayerPrivilege(sender, args);
break;
case "set_privilege":
PlayerPrivilege.setPlayerPrivilege(sender, args);
break;
case "clear_privilege":
PlayerPrivilege.clearPlayerPrivilege(sender, args);
break;
case "privilege_list":
DominionPrivilegeList.show(sender, args);
break;
case "privilege_info":
PrivilegeInfo.show(sender, args);
break;
case "select_player_create_privilege":
SelectPlayer.show(sender, args);
break;
case "set_enter_msg": case "set_enter_msg":
DominionOperate.setEnterMessage(sender, args); DominionOperate.setEnterMessage(sender, args);
break; break;
@ -143,27 +114,70 @@ public class Commands implements TabExecutor {
case "export_mca": case "export_mca":
Operator.exportMca(sender, args); Operator.exportMca(sender, args);
break; break;
case "config": case "sys_config":
DominionConfig.show(sender, args); SysConfig.show(sender, args);
break; break;
case "set_config": case "set_config":
SetConfig.handler(sender, args); SetConfig.handler(sender, args);
break; break;
case "all_dominion":
AllDominion.show(sender, args);
break;
case "migrate_list":
MigrateList.show(sender, args);
break;
case "migrate":
Migration.migrate(sender, args);
break;
case "set_map_color":
DominionOperate.setMapColor(sender, args);
break;
case "env_setting":
EnvSetting.show(sender, args);
break;
case "use_title":
Title.use_title(sender, args);
break;
case "title_list":
TitleList.show(sender, args);
break;
// ---=== Sub Command ===---
case "member":
Member.handle(sender, args);
break;
case "group":
Group.handle(sender, args);
break;
case "template":
Template.handle(sender, args);
break;
// ---=== CUI ===--- // ---=== CUI ===---
case "cui_rename": case "cui_rename":
OpenCUI.RenameDominion(sender, args); RenameDominion.open(sender, args);
break; break;
case "cui_edit_join_message": case "cui_edit_join_message":
OpenCUI.EditJoinMessage(sender, args); EditJoinMessage.open(sender, args);
break; break;
case "cui_edit_leave_message": case "cui_edit_leave_message":
OpenCUI.EditLeaveMessage(sender, args); EditLeaveMessage.open(sender, args);
break; break;
case "cui_create": case "cui_create":
OpenCUI.CreateDominion(sender, args); CreateDominion.open(sender, args);
break; break;
case "cui_create_privilege": case "cui_member_add":
OpenCUI.CreatePrivilege(sender, args); MemberAdd.open(sender, args);
break;
case "cui_template_create":
CreateTemplate.open(sender, args);
break;
case "cui_set_map_color":
SetMapColor.open(sender, args);
break;
case "cui_create_group":
CreateGroup.open(sender, args);
break;
case "cui_rename_group":
RenameGroup.open(sender, args);
break; break;
default: default:
return false; return false;
@ -187,9 +201,8 @@ public class Commands implements TabExecutor {
@Override @Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (args.length == 1) { if (args.length == 1) {
return Arrays.asList("menu", "help", "info", "manage", "flag_info", "privilege_list", return Arrays.asList("menu", "help", "info", "manage", "guest_setting",
"create", "auto_create", "create_sub", "auto_create_sub", "expand", "contract", "delete", "set", "create", "auto_create", "create_sub", "auto_create_sub", "expand", "contract", "delete", "set",
"create_privilege", "set_privilege", "clear_privilege", "list", "privilege_info",
"set_enter_msg", "set_enter_msg",
"set_leave_msg", "set_leave_msg",
"set_tp_location", "set_tp_location",
@ -199,23 +212,35 @@ public class Commands implements TabExecutor {
"reload_cache", "reload_cache",
"reload_config", "reload_config",
"export_mca", "export_mca",
"config" "sys_config",
"all_dominion",
"set_map_color",
"member",
"group",
"template"
); );
} }
if (args.length > 1 && args[0].equals("member")) {
return Member.handleTab(sender, args);
}
if (args.length > 1 && args[0].equals("group")) {
return Group.handleTab(sender, args);
}
if (args.length > 1 && args[0].equals("template")) {
return Template.handleTab(sender, args);
}
if (args.length == 2) { if (args.length == 2) {
switch (args[0]) { switch (args[0]) {
case "help": case "help":
case "list": case "list":
case "config": case "sys_config":
return Collections.singletonList("页码(可选)");
case "create": case "create":
case "auto_create": case "auto_create":
return Collections.singletonList("输入领地名称"); return Collections.singletonList("输入领地名称");
case "delete": case "delete":
case "info": case "info":
case "manage": case "manage":
case "flag_info": case "guest_setting":
case "privilege_list":
case "rename": case "rename":
case "give": case "give":
case "set_tp_location": case "set_tp_location":
@ -224,11 +249,6 @@ public class Commands implements TabExecutor {
return allDominions(); return allDominions();
case "set": case "set":
return dominionFlags(); return dominionFlags();
case "create_privilege":
case "set_privilege":
case "clear_privilege":
case "privilege_info":
return playerNames();
case "expand": case "expand":
case "contract": case "contract":
return Collections.singletonList("大小(整数)"); return Collections.singletonList("大小(整数)");
@ -239,23 +259,21 @@ public class Commands implements TabExecutor {
return Collections.singletonList("进入提示语内容"); return Collections.singletonList("进入提示语内容");
case "set_leave_msg": case "set_leave_msg":
return Collections.singletonList("离开提示语内容"); return Collections.singletonList("离开提示语内容");
case "set_map_color":
return Collections.singletonList("输入颜色(16进制)");
} }
} }
if (args.length == 3) { if (args.length == 3) {
switch (args[0]) { switch (args[0]) {
case "set": case "set":
return boolOptions(); return boolOptions();
case "set_privilege":
return playerPrivileges();
case "expand": case "expand":
case "contract": case "contract":
case "clear_privilege":
case "create_privilege":
case "privilege_info":
case "auto_create_sub": case "auto_create_sub":
case "create_sub": case "create_sub":
case "set_enter_msg": case "set_enter_msg":
case "set_leave_msg": case "set_leave_msg":
case "set_map_color":
return playerDominions(sender); return playerDominions(sender);
case "rename": case "rename":
return Collections.singletonList("输入新领地名称"); return Collections.singletonList("输入新领地名称");
@ -267,18 +285,16 @@ public class Commands implements TabExecutor {
switch (args[0]) { switch (args[0]) {
case "set": case "set":
return playerDominions(sender); return playerDominions(sender);
case "set_privilege":
return boolOptions();
} }
} }
return null; return null;
} }
private static List<String> boolOptions() { public static List<String> boolOptions() {
return Arrays.asList("true", "false"); return Arrays.asList("true", "false");
} }
private static List<String> playerNames() { public static List<String> playerNames() {
List<PlayerDTO> players = PlayerController.allPlayers(); List<PlayerDTO> players = PlayerController.allPlayers();
List<String> names = new ArrayList<>(); List<String> names = new ArrayList<>();
for (PlayerDTO player : players) { for (PlayerDTO player : players) {

View File

@ -1,11 +1,13 @@
package cn.lunadeer.dominion; package cn.lunadeer.dominion;
import cn.lunadeer.dominion.events.EnvironmentEvents;
import cn.lunadeer.dominion.events.PlayerEvents;
import cn.lunadeer.dominion.events.SelectPointEvents;
import cn.lunadeer.dominion.managers.ConfigManager; import cn.lunadeer.dominion.managers.ConfigManager;
import cn.lunadeer.dominion.managers.DatabaseTables; import cn.lunadeer.dominion.managers.DatabaseTables;
import cn.lunadeer.dominion.managers.PlaceHolderApi;
import cn.lunadeer.dominion.utils.DynmapConnect;
import cn.lunadeer.dominion.utils.MapRender;
import cn.lunadeer.minecraftpluginutils.*; import cn.lunadeer.minecraftpluginutils.*;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseType;
import cn.lunadeer.minecraftpluginutils.scui.CuiManager; import cn.lunadeer.minecraftpluginutils.scui.CuiManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -25,9 +27,8 @@ public final class Dominion extends JavaPlugin {
new Notification(this); new Notification(this);
new XLogger(this); new XLogger(this);
config = new ConfigManager(this); config = new ConfigManager(this);
XLogger.setDebug(config.isDebug()); new DatabaseManager(this,
database = new DatabaseManager(this, DatabaseType.valueOf(config.getDbType().toUpperCase()),
config.getDbType().equals("pgsql") ? DatabaseManager.TYPE.POSTGRESQL : DatabaseManager.TYPE.SQLITE,
config.getDbHost(), config.getDbHost(),
config.getDbPort(), config.getDbPort(),
config.getDbName(), config.getDbName(),
@ -38,20 +39,24 @@ public final class Dominion extends JavaPlugin {
AutoClean.run(); AutoClean.run();
Cache.instance = new Cache(); Cache.instance = new Cache();
if (config.getEconomyEnable()) { if (config.getGroupTitleEnable()) {
vault = new VaultConnect(this); if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
if (vault.getEconomy() == null) { new PlaceHolderApi(this);
XLogger.err("你没有安装 Vault 前置插件,无法使用经济功能。"); } else {
config.setEconomyEnable(false); XLogger.warn("未找到 PlaceholderAPI 插件,无法使用权限组组称号功能,已自动关闭");
config.setGroupTitleEnable(false);
} }
} }
Bukkit.getPluginManager().registerEvents(new PlayerEvents(), this); new EventsRegister(this);
Bukkit.getPluginManager().registerEvents(new EnvironmentEvents(), this);
Bukkit.getPluginManager().registerEvents(new SelectPointEvents(), this);
Objects.requireNonNull(Bukkit.getPluginCommand("dominion")).setExecutor(new Commands()); Objects.requireNonNull(Bukkit.getPluginCommand("dominion")).setExecutor(new Commands());
bStatsMetrics metrics = new bStatsMetrics(this, 21445); bStatsMetrics metrics = new bStatsMetrics(this, 21445);
metrics.addCustomChart(new bStatsMetrics.SimplePie("database", () -> config.getDbType()));
metrics.addCustomChart(new bStatsMetrics.SingleLineChart("dominion_count", () -> Cache.instance.getDominionCounts()));
metrics.addCustomChart(new bStatsMetrics.SingleLineChart("group_count", () -> Cache.instance.getGroupCounts()));
metrics.addCustomChart(new bStatsMetrics.SingleLineChart("member_count", () -> Cache.instance.getMemberCounts()));
if (config.getCheckUpdate()) { if (config.getCheckUpdate()) {
giteaReleaseCheck = new GiteaReleaseCheck(this, giteaReleaseCheck = new GiteaReleaseCheck(this,
"https://ssl.lunadeer.cn:14446", "https://ssl.lunadeer.cn:14446",
@ -63,7 +68,7 @@ public final class Dominion extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new CuiManager(this), this); Bukkit.getPluginManager().registerEvents(new CuiManager(this), this);
XLogger.info("领地插件已启动"); XLogger.info("领地插件已启动");
XLogger.info("版本:" + this.getPluginMeta().getVersion()); XLogger.info("版本:" + this.getDescription().getVersion());
// http://patorjk.com/software/taag/#p=display&f=Big&t=Dominion // http://patorjk.com/software/taag/#p=display&f=Big&t=Dominion
XLogger.info(" _____ _ _"); XLogger.info(" _____ _ _");
XLogger.info(" | __ \\ (_) (_)"); XLogger.info(" | __ \\ (_) (_)");
@ -73,18 +78,18 @@ public final class Dominion extends JavaPlugin {
XLogger.info(" |_____/ \\___/|_| |_| |_|_|_| |_|_|\\___/|_| |_|"); XLogger.info(" |_____/ \\___/|_| |_| |_|_|_| |_|_|\\___/|_| |_|");
XLogger.info(" "); XLogger.info(" ");
Scheduler.runTaskLaterAsync(BlueMapConnect::render, 40 * 20); if (config.getDynmap()) new DynmapConnect(); // 注册 Dynmap API
Scheduler.runTaskLaterAsync(MapRender::render, 40 * 20);
} }
@Override @Override
public void onDisable() { public void onDisable() {
// Plugin shutdown logic // Plugin shutdown logic
DatabaseManager.instance.close();
} }
public static Dominion instance; public static Dominion instance;
public static ConfigManager config; public static ConfigManager config;
public static DatabaseManager database;
public static Map<UUID, Map<Integer, Location>> pointsSelect = new HashMap<>(); public static Map<UUID, Map<Integer, Location>> pointsSelect = new HashMap<>();
private GiteaReleaseCheck giteaReleaseCheck; private GiteaReleaseCheck giteaReleaseCheck;
public static VaultConnect vault;
} }

View File

@ -0,0 +1,75 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.*;
public class DominionNode {
private Integer dominion_id;
private List<DominionNode> children = new ArrayList<>();
public DominionDTO getDominion() {
return Cache.instance.getDominion(dominion_id);
}
public List<DominionNode> getChildren() {
return children;
}
public static List<DominionNode> BuildNodeTree(Integer rootId, List<DominionDTO> dominions) {
// 映射父节点ID到其子节点列表
Map<Integer, List<DominionDTO>> parentToChildrenMap = new HashMap<>();
for (DominionDTO dominion : dominions) {
parentToChildrenMap
.computeIfAbsent(dominion.getParentDomId(), k -> new ArrayList<>())
.add(dominion);
}
// 递归构建节点树
return buildTree(rootId, parentToChildrenMap);
}
private static List<DominionNode> buildTree(Integer rootId, Map<Integer, List<DominionDTO>> parentToChildrenMap) {
List<DominionNode> dominionTree = new ArrayList<>();
List<DominionDTO> children = parentToChildrenMap.get(rootId);
if (children != null) {
for (DominionDTO dominion : children) {
DominionNode node = new DominionNode();
node.dominion_id = dominion.getId();
node.children = buildTree(dominion.getId(), parentToChildrenMap);
dominionTree.add(node);
}
}
return dominionTree;
}
public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) {
for (DominionNode node : nodes) {
if (isInDominion(node.getDominion(), loc)) {
if (node.children.isEmpty()) {
return node;
} else {
DominionNode childDominion = getLocInDominionNode(node.children, loc);
return Objects.requireNonNullElse(childDominion, node);
}
}
}
return null;
}
public static boolean isInDominion(@Nullable DominionDTO dominion, @NotNull Location location) {
if (dominion == null) return false;
if (!Objects.equals(dominion.getWorldUid(), location.getWorld().getUID())) return false;
double x = location.getX();
double y = location.getY();
double z = location.getZ();
return x >= dominion.getX1() && x < dominion.getX2() &&
y >= dominion.getY1() && y < dominion.getY2() &&
z >= dominion.getZ1() && z < dominion.getZ2();
}
}

View File

@ -0,0 +1,64 @@
package cn.lunadeer.dominion;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Bukkit;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
public class EventsRegister {
private JavaPlugin plugin;
public EventsRegister(JavaPlugin plugin) {
APIVersion version = GetAPIVersion(plugin);
this.plugin = plugin;
if (version == null) {
return;
}
try {
switch (version) {
case v1_21:
XLogger.debug("Load API version: 1.21");
registerEvents("cn.lunadeer.dominion.events_v1_21.PlayerEvents");
registerEvents("cn.lunadeer.dominion.events_v1_21.EnvironmentEvents");
registerEvents("cn.lunadeer.dominion.events_v1_21.SelectPointEvents");
break;
case v1_20_1:
XLogger.debug("Load API version: 1.20.1");
registerEvents("cn.lunadeer.dominion.events_v1_20_1.PlayerEvents");
registerEvents("cn.lunadeer.dominion.events_v1_20_1.EnvironmentEvents");
registerEvents("cn.lunadeer.dominion.events_v1_20_1.SelectPointEvents");
break;
}
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
XLogger.err("Failed to register events: %s", e.getMessage());
plugin.getServer().getPluginManager().disablePlugin(plugin);
}
}
enum APIVersion {
v1_21,
v1_20_1
}
private static APIVersion GetAPIVersion(JavaPlugin plugin) {
String version = plugin.getServer().getBukkitVersion();
if (version.contains("1.21")) {
return APIVersion.v1_21;
} else if (version.contains("1.20.1")
|| version.contains("1.20.4")
|| version.contains("1.20.6")) {
return APIVersion.v1_20_1;
}
XLogger.err("Unsupported API version: %s", version);
plugin.getServer().getPluginManager().disablePlugin(plugin);
return null;
}
private void registerEvents(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> clazz = Class.forName(className);
Listener listener = (Listener) clazz.newInstance();
Bukkit.getPluginManager().registerEvents(listener, plugin);
}
}

View File

@ -2,12 +2,13 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator; import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.FlagsController; import cn.lunadeer.dominion.controllers.FlagsController;
import cn.lunadeer.dominion.tuis.DominionFlagInfo; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.tuis.dominion.manage.EnvSetting;
import cn.lunadeer.dominion.tuis.dominion.manage.GuestSetting;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
public class DominionFlag { public class DominionFlag {
@ -19,9 +20,10 @@ public class DominionFlag {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void setDominionFlag(CommandSender sender, String[] args) { public static void setDominionFlag(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (!hasPermission(sender, "dominion.default")) {
if (player == null) return; return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); }
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length == 3) { if (args.length == 3) {
FlagsController.setFlag(operator, args[1], Boolean.parseBoolean(args[2])); FlagsController.setFlag(operator, args[1], Boolean.parseBoolean(args[2]));
} else if (args.length == 4) { } else if (args.length == 4) {
@ -29,10 +31,15 @@ public class DominionFlag {
} else if (args.length == 5) { } else if (args.length == 5) {
FlagsController.setFlag(operator, args[1], Boolean.parseBoolean(args[2]), args[3]); FlagsController.setFlag(operator, args[1], Boolean.parseBoolean(args[2]), args[3]);
String[] newArgs = new String[3]; String[] newArgs = new String[3];
newArgs[0] = "flag_info"; newArgs[0] = Flag.isDominionOnlyFlag(args[1]) ? "env_info" : "flag_info";
newArgs[1] = args[3]; newArgs[1] = args[3];
newArgs[2] = args[4]; newArgs[2] = args[4];
DominionFlagInfo.show(sender, newArgs); if (Flag.isDominionOnlyFlag(args[1])) {
EnvSetting.show(sender, newArgs);
} else {
GuestSetting.show(sender, newArgs);
}
} else { } else {
Notification.error(sender, "用法: /dominion set <权限名称> <true/false> [领地名称]"); Notification.error(sender, "用法: /dominion set <权限名称> <true/false> [领地名称]");
} }

View File

@ -2,12 +2,12 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator; import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController; import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Scheduler; import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.Teleport; import cn.lunadeer.minecraftpluginutils.Teleport;
@ -19,9 +19,10 @@ import org.bukkit.entity.Player;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import static cn.lunadeer.dominion.commands.Apis.*; import static cn.lunadeer.dominion.DominionNode.isInDominion;
import static cn.lunadeer.dominion.utils.CommandUtils.*;
import static cn.lunadeer.dominion.utils.EventUtils.canByPass;
public class DominionOperate { public class DominionOperate {
/** /**
@ -32,6 +33,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void createDominion(CommandSender sender, String[] args) { public static void createDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2) { if (args.length != 2) {
@ -56,6 +60,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void createSubDominion(CommandSender sender, String[] args) { public static void createSubDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2 && args.length != 3) { if (args.length != 2 && args.length != 3) {
@ -84,6 +91,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void autoCreateDominion(CommandSender sender, String[] args) { public static void autoCreateDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2) { if (args.length != 2) {
@ -107,6 +117,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void autoCreateSubDominion(CommandSender sender, String[] args) { public static void autoCreateSubDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2 && args.length != 3) { if (args.length != 2 && args.length != 3) {
@ -129,6 +142,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void expandDominion(CommandSender sender, String[] args) { public static void expandDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2 && args.length != 3) { if (args.length != 2 && args.length != 3) {
@ -166,6 +182,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void contractDominion(CommandSender sender, String[] args) { public static void contractDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2 && args.length != 3) { if (args.length != 2 && args.length != 3) {
@ -203,9 +222,10 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void deleteDominion(CommandSender sender, String[] args) { public static void deleteDominion(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (!hasPermission(sender, "dominion.default")) {
if (player == null) return; return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); }
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length == 2) { if (args.length == 2) {
String name = args[1]; String name = args[1];
DominionController.delete(operator, name, false); DominionController.delete(operator, name, false);
@ -229,9 +249,10 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void setEnterMessage(CommandSender sender, String[] args) { public static void setEnterMessage(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (!hasPermission(sender, "dominion.default")) {
if (player == null) return; return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); }
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length == 2) { if (args.length == 2) {
DominionController.setJoinMessage(operator, args[1]); DominionController.setJoinMessage(operator, args[1]);
return; return;
@ -251,9 +272,10 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void setLeaveMessage(CommandSender sender, String[] args) { public static void setLeaveMessage(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (!hasPermission(sender, "dominion.default")) {
if (player == null) return; return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); }
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length == 2) { if (args.length == 2) {
DominionController.setLeaveMessage(operator, args[1]); DominionController.setLeaveMessage(operator, args[1]);
return; return;
@ -273,6 +295,9 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void setTpLocation(CommandSender sender, String[] args) { public static void setTpLocation(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
@ -298,9 +323,10 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void renameDominion(CommandSender sender, String[] args) { public static void renameDominion(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (!hasPermission(sender, "dominion.default")) {
if (player == null) return; return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); }
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length != 3) { if (args.length != 3) {
Notification.error(sender, "用法: /dominion rename <原领地名称> <新领地名称>"); Notification.error(sender, "用法: /dominion rename <原领地名称> <新领地名称>");
return; return;
@ -316,9 +342,10 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void giveDominion(CommandSender sender, String[] args) { public static void giveDominion(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (!hasPermission(sender, "dominion.default")) {
if (player == null) return; return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player); }
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length == 3) { if (args.length == 3) {
String dom_name = args[1]; String dom_name = args[1];
String player_name = args[2]; String player_name = args[2];
@ -344,33 +371,65 @@ public class DominionOperate {
* @param args 命令参数 * @param args 命令参数
*/ */
public static void teleportToDominion(CommandSender sender, String[] args) { public static void teleportToDominion(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
if (args.length != 2) { if (args.length != 2) {
Notification.error(sender, "用法: /dominion tp <领地名称>"); Notification.error(sender, "用法: /dominion tp <领地名称>");
return; return;
} }
if (!Dominion.config.getTpEnable()) {
Notification.error(sender, "管理员没有开启领地传送功能");
return;
}
DominionDTO dominionDTO = DominionDTO.select(args[1]); DominionDTO dominionDTO = DominionDTO.select(args[1]);
if (dominionDTO == null) { if (dominionDTO == null) {
Notification.error(sender, "领地不存在"); Notification.error(sender, "领地不存在");
return; return;
} }
PlayerPrivilegeDTO privilegeDTO = PlayerPrivilegeDTO.select(player.getUniqueId(), dominionDTO.getId()); if (player.isOp() && Dominion.config.getLimitOpBypass()) {
Notification.warn(sender, "你是OP将忽略领地传送限制");
Location location = dominionDTO.getTpLocation();
if (location == null) {
int x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = dominionDTO.getWorld();
if (world == null) {
Notification.error(sender, "领地所在世界不存在");
return;
}
location = new Location(world, x, player.getLocation().getY(), z);
XLogger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
}
Teleport.doTeleportSafely(player, location);
Notification.info(player, "已将你传送到 " + dominionDTO.getName());
return;
}
if (!Dominion.config.getTpEnable()) {
Notification.error(sender, "管理员没有开启领地传送功能");
return;
}
MemberDTO privilegeDTO = MemberDTO.select(player.getUniqueId(), dominionDTO.getId());
if (!canByPass(player, dominionDTO, privilegeDTO)) {
if (privilegeDTO == null) { if (privilegeDTO == null) {
if (!dominionDTO.getFlagValue(Flag.TELEPORT)) { if (!dominionDTO.getFlagValue(Flag.TELEPORT)) {
Notification.error(sender, "此领地禁止传送"); Notification.error(sender, "此领地禁止传送");
return; return;
} }
} else {
GroupDTO groupDTO = Cache.instance.getGroup(privilegeDTO.getGroupId());
if (privilegeDTO.getGroupId() != -1 && groupDTO != null) {
if (!groupDTO.getFlagValue(Flag.TELEPORT)) {
Notification.error(sender, "你所在的权限组组不被允许传送到这个领地");
return;
}
} else { } else {
if (!privilegeDTO.getFlagValue(Flag.TELEPORT)) { if (!privilegeDTO.getFlagValue(Flag.TELEPORT)) {
Notification.error(sender, "你不被允许传送到这个领地"); Notification.error(sender, "你不被允许传送到这个领地");
return; return;
} }
} }
}
}
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
LocalDateTime next_time = Cache.instance.NextTimeAllowTeleport.get(player.getUniqueId()); LocalDateTime next_time = Cache.instance.NextTimeAllowTeleport.get(player.getUniqueId());
@ -383,21 +442,70 @@ public class DominionOperate {
} }
if (Dominion.config.getTpDelay() > 0) { if (Dominion.config.getTpDelay() > 0) {
Notification.info(player, "传送将在 %d 秒后执行", Dominion.config.getTpDelay()); Notification.info(player, "传送将在 %d 秒后执行", Dominion.config.getTpDelay());
Scheduler.runTaskAsync(() -> {
int i = Dominion.config.getTpDelay();
while (i > 0) {
if (!player.isOnline()) {
return;
}
Notification.actionBar(player, "传送倒计时 %d 秒", i);
i--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
XLogger.err(e.getMessage());
}
}
});
} }
Cache.instance.NextTimeAllowTeleport.put(player.getUniqueId(), now.plusSeconds(Dominion.config.getTpCoolDown())); Cache.instance.NextTimeAllowTeleport.put(player.getUniqueId(), now.plusSeconds(Dominion.config.getTpCoolDown()));
Scheduler.runTaskLater(() -> { Scheduler.runTaskLater(() -> {
Location location = dominionDTO.getTpLocation(); Location location = dominionDTO.getTpLocation();
int center_x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int center_z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = dominionDTO.getWorld();
if (world == null) {
Notification.error(player, "领地所在世界不存在");
return;
}
if (location == null) { if (location == null) {
int x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2; location = new Location(world, center_x, player.getLocation().getY(), center_z);
int z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2; Notification.warn(player, "领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld()); } else if (!isInDominion(dominionDTO, location)) {
location = new Location(world, x, player.getLocation().getY(), z); location = new Location(world, center_x, player.getLocation().getY(), center_z);
XLogger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName()); Notification.warn(player, "领地 %s 传送点不在领地内,将尝试传送到中心点", dominionDTO.getName());
} }
if (player.isOnline()) { if (player.isOnline()) {
Teleport.doTeleportSafely(player, location); Teleport.doTeleportSafely(player, location).thenAccept(b -> {
if (b) {
Notification.info(player, "已将你传送到 " + dominionDTO.getName()); Notification.info(player, "已将你传送到 " + dominionDTO.getName());
} else {
Notification.error(player, "传送失败,请重试");
}
});
} }
}, 20L * Dominion.config.getTpDelay()); }, 20L * Dominion.config.getTpDelay());
} }
/**
* 设置领地卫星地图地块颜色
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void setMapColor(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 2) {
Notification.error(sender, "用法: /dominion set_map_color <颜色> [领地名称]");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
if (args.length == 2) {
DominionController.setMapColor(operator, args[1]);
} else {
DominionController.setMapColor(operator, args[1], args[2]);
}
}
} }

View File

@ -0,0 +1,271 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.GroupController;
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.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static cn.lunadeer.dominion.Commands.boolOptions;
import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
import static cn.lunadeer.dominion.commands.Helper.*;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class Group {
/**
* /dominion group create <领地名称> <权限组名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void createGroup(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 4) {
Notification.error(sender, "用法: /dominion group create <领地名称> <权限组名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String groupName = args[3];
GroupController.createGroup(operator, dominionName, ColorParser.getPlainText(groupName), groupName);
GroupList.show(sender, dominionName);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* /dominion group delete <领地名称> <权限组名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void deleteGroup(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 4) {
Notification.error(sender, "用法: /dominion group delete <领地名称> <权限组名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String groupName = args[3];
GroupController.deleteGroup(operator, dominionName, groupName);
GroupList.show(sender, dominionName);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* /dominion group rename <领地名称> <权限组旧名称> <新名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void renameGroup(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 5) {
Notification.error(sender, "用法: /dominion group rename <领地名称> <权限组旧名称> <新名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String oldGroupName = args[3];
String newGroupName = args[4];
GroupController.renameGroup(operator, dominionName, oldGroupName, ColorParser.getPlainText(newGroupName), newGroupName);
GroupSetting.show(sender, dominionName, newGroupName);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* /dominion group set_flag <领地名称> <权限组名称> <权限名称> <true|false>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void setGroupFlag(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 6) {
Notification.error(sender, "用法: /dominion group set_flag <领地名称> <权限组名称> <权限名称> <true|false>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String groupName = args[3];
String flag = args[4];
boolean value = Boolean.parseBoolean(args[5]);
int page = getPage(args, 6);
GroupController.setGroupFlag(operator, dominionName, groupName, flag, value);
GroupSetting.show(sender, dominionName, groupName, page);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* /dominion group add_member <领地名称> <权限组名称> <玩家名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void addMember(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 5) {
Notification.error(sender, "用法: /dominion group add_member <领地名称> <权限组名称> <玩家名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String groupName = args[3];
String playerName = args[4];
int page = getPage(args, 5);
GroupController.addMember(operator, dominionName, groupName, playerName);
GroupList.show(sender, dominionName, page);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* /dominion group remove_member <领地名称> <权限组名称> <玩家名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void removeMember(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 5) {
Notification.error(sender, "用法: /dominion group remove_member <领地名称> <权限组名称> <玩家名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String groupName = args[3];
String playerName = args[4];
int page = getPage(args, 5);
GroupController.removeMember(operator, dominionName, groupName, playerName);
GroupList.show(sender, dominionName, page);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
public static void handle(@NotNull CommandSender sender, @NotNull String[] args) {
if (args.length < 2) {
Notification.error(sender, "用法: /dominion group <create|delete|rename|set_flag|add_member|remove_member|select_member|setting|list>");
return;
}
switch (args[1]) {
case "create":
createGroup(sender, args);
break;
case "delete":
deleteGroup(sender, args);
break;
case "rename":
renameGroup(sender, args);
break;
case "set_flag":
setGroupFlag(sender, args);
break;
case "add_member":
addMember(sender, args);
break;
case "remove_member":
removeMember(sender, args);
break;
case "select_member":
SelectMember.show(sender, args);
break;
case "setting":
GroupSetting.show(sender, args);
break;
case "list":
GroupList.show(sender, args);
break;
}
}
public static @Nullable List<String> handleTab(@NotNull CommandSender sender, @NotNull String[] args) {
if (args.length == 2) {
return Arrays.asList("create", "delete", "rename", "set_flag", "add_member", "remove_member",
"select_member", "list");
}
if (args.length == 3) {
switch (args[1]) {
case "create":
case "delete":
case "rename":
case "set_flag":
case "add_member":
case "remove_member":
case "select_member":
case "setting":
case "list":
return playerDominions(sender);
}
}
if (args.length == 4) {
switch (args[1]) {
case "create":
return Collections.singletonList("新权限组名称");
case "delete":
case "rename":
case "set_flag":
case "add_member":
case "remove_member":
case "select_member":
case "setting":
return dominionGroups(args[2]);
}
}
if (args.length == 5) {
switch (args[1]) {
case "rename":
return Collections.singletonList("权限组新名称");
case "set_flag":
return playerPrivileges();
case "remove_member":
return groupPlayers(args[2], args[3]);
}
}
if (args.length == 6) {
switch (args[1]) {
case "set_flag":
return boolOptions();
}
}
return null;
}
}

View File

@ -1,9 +1,7 @@
package cn.lunadeer.dominion.commands; package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.DominionController; import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.*;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -11,7 +9,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class Helper { public class Helper {
@ -40,6 +38,32 @@ public class Helper {
return dominions_name; return dominions_name;
} }
public static List<String> dominionGroups(String dominionName) {
List<String> groups_name = new ArrayList<>();
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) return groups_name;
List<GroupDTO> groups = GroupDTO.selectByDominionId(dominion.getId());
for (GroupDTO group : groups) {
groups_name.add(group.getName());
}
return groups_name;
}
public static List<String> groupPlayers(String domName, String groupName) {
List<String> players_name = new ArrayList<>();
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) return players_name;
GroupDTO group = GroupDTO.select(dominion.getId(), groupName);
if (group == null) return players_name;
List<MemberDTO> privileges = MemberDTO.selectByDomGroupId(dominion.getId(), group.getId());
for (MemberDTO privilege : privileges) {
PlayerDTO player = PlayerDTO.select(privilege.getPlayerUUID());
if (player == null) continue;
players_name.add(player.getLastKnownName());
}
return players_name;
}
public static List<String> playerOwnDominions(CommandSender sender) { public static List<String> playerOwnDominions(CommandSender sender) {
List<String> dominions_name = new ArrayList<>(); List<String> dominions_name = new ArrayList<>();
Player player = playerOnly(sender); Player player = playerOnly(sender);
@ -55,8 +79,8 @@ public class Helper {
List<String> dominions_name = new ArrayList<>(); List<String> dominions_name = new ArrayList<>();
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return dominions_name; if (player == null) return dominions_name;
List<PlayerPrivilegeDTO> dominions_admin = PlayerPrivilegeDTO.selectAll(player.getUniqueId()); List<MemberDTO> dominions_admin = MemberDTO.selectAll(player.getUniqueId());
for (PlayerPrivilegeDTO privilege : dominions_admin) { for (MemberDTO privilege : dominions_admin) {
if (privilege.getAdmin()) { if (privilege.getAdmin()) {
DominionDTO dom = DominionDTO.select(privilege.getDomID()); DominionDTO dom = DominionDTO.select(privilege.getDomID());
if (dom == null) continue; if (dom == null) continue;
@ -75,4 +99,15 @@ public class Helper {
return dominions_name; return dominions_name;
} }
public static List<String> allTemplates(CommandSender sender) {
List<String> templates_name = new ArrayList<>();
Player player = playerOnly(sender);
if (player == null) return templates_name;
List<PrivilegeTemplateDTO> templates = PrivilegeTemplateDTO.selectAll(player.getUniqueId());
for (PrivilegeTemplateDTO template : templates) {
templates_name.add(template.getName());
}
return templates_name;
}
} }

View File

@ -0,0 +1,217 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.MemberController;
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.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static cn.lunadeer.dominion.Commands.boolOptions;
import static cn.lunadeer.dominion.Commands.playerNames;
import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
import static cn.lunadeer.dominion.commands.Helper.*;
public class Member {
/**
* 创建玩家特权
* /dominion member add <领地名称> <玩家名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void member_add(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 4) {
Notification.error(sender, "用法: /dominion member add <领地名称> <玩家名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String playerName = args[3];
MemberController.memberAdd(operator, dominionName, playerName);
MemberList.show(sender, dominionName);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* 设置玩家权限
* /dominion member set_flag <领地名称> <玩家名称> <权限名称> <true/false>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void member_set_flag(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 6) {
Notification.error(sender, "用法: /dominion member set_flag <领地名称> <玩家名称> <权限名称> <true/false>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String playerName = args[3];
String flagName = args[4];
boolean flagValue = Boolean.parseBoolean(args[5]);
Integer page = args.length == 7 ? Integer.parseInt(args[6]) : 1;
MemberController.setMemberFlag(operator, dominionName, playerName, flagName, flagValue);
MemberSetting.show(sender, dominionName, playerName, page);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* 重置玩家权限
* /dominion member remove <领地名称> <玩家名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void member_remove(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 4) {
Notification.error(sender, "用法: /dominion member remove <领地名称> <玩家名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String playerName = args[3];
MemberController.memberRemove(operator, dominionName, playerName);
MemberList.show(sender, dominionName);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* 应用权限模板
* /dominion member apply_template <领地名称> <玩家名称> <模板名称>
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void member_apply_template(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 5) {
Notification.error(sender, "用法: /dominion member apply_template <领地名称> <玩家名称> <模板名称>");
return;
}
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
String dominionName = args[2];
String playerName = args[3];
String templateName = args[4];
MemberController.applyTemplate(operator, dominionName, playerName, templateName);
MemberSetting.show(sender, dominionName, playerName);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
public static void handle(@NotNull CommandSender sender, @NotNull String[] args) {
if (args.length < 2) {
Notification.error(sender, "用法: /dominion member <add/set_flag/remove/apply_template/list/setting/select_player/select_template>");
return;
}
switch (args[1]) {
case "add":
Member.member_add(sender, args);
break;
case "set_flag":
Member.member_set_flag(sender, args);
break;
case "remove":
Member.member_remove(sender, args);
break;
case "apply_template":
Member.member_apply_template(sender, args);
break;
case "list":
MemberList.show(sender, args);
break;
case "setting":
MemberSetting.show(sender, args);
break;
case "select_player":
SelectPlayer.show(sender, args);
break;
case "select_template":
SelectTemplate.show(sender, args);
break;
}
}
public static @Nullable List<String> handleTab(@NotNull CommandSender sender, @NotNull String[] args) {
if (args.length == 2) {
return Arrays.asList("add", "set_flag", "remove", "apply_template", "list", "setting", "select_player", "select_template");
}
if (args.length == 3) {
switch (args[1]) {
case "add":
case "remove":
case "list":
case "setting":
case "set_flag":
case "apply_template":
case "select_player":
case "select_template":
return playerDominions(sender);
}
}
if (args.length == 4) {
switch (args[1]) {
case "add":
case "remove":
case "set_flag":
case "apply_template":
case "setting":
case "select_template":
case "select_player":
return playerNames();
case "list":
return Collections.singletonList("页码(可选)");
}
}
if (args.length == 5) {
switch (args[1]) {
case "set_flag":
return playerPrivileges();
case "apply_template":
return allTemplates(sender);
case "setting":
case "select_template":
return Collections.singletonList("页码(可选)");
}
}
if (args.length == 6) {
switch (args[1]) {
case "set_flag":
return boolOptions();
}
}
return null;
}
}

View File

@ -0,0 +1,99 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.MigrateList;
import cn.lunadeer.dominion.utils.ResMigration;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.Objects;
import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class Migration {
public static void migrate(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player player = playerOnly(sender);
if (player == null) return;
if (!Dominion.config.getResidenceMigration()) {
Notification.error(sender, "Residence 迁移功能没有开启");
return;
}
if (args.length < 2) {
Notification.error(sender, "用法: /dominion migrate <res领地名称>");
return;
}
String resName = args[1];
List<ResMigration.ResidenceNode> res_data = Cache.instance.getResidenceData(player.getUniqueId());
if (res_data == null) {
Notification.error(sender, "你没有可迁移的数据");
return;
}
ResMigration.ResidenceNode resNode = res_data.stream().filter(node -> node.name.equals(resName)).findFirst().orElse(null);
if (resNode == null) {
Notification.error(sender, "未找到指定的 Residence 领地");
return;
}
if (!resNode.owner.equals(player.getUniqueId())) {
Notification.error(sender, "你不是该领地的所有者,无法迁移此领地");
return;
}
create(player, resNode, "");
if (args.length == 3 ) {
int parentId = Integer.parseInt(args[2]);
String[] newArgs = new String[2];
newArgs[0] = "migrate_list";
newArgs[1] = String.valueOf(parentId);
MigrateList.show(sender, newArgs);
}
} catch (Exception e) {
Notification.error(sender, "迁移失败: " + e.getMessage());
}
}
private static void create(Player player, ResMigration.ResidenceNode node, String parentName) {
BukkitPlayerOperator operator = new BukkitPlayerOperator(player);
operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), BukkitPlayerOperator.Result.SUCCESS)) {
DominionDTO dominion = DominionDTO.select(node.name);
if (dominion == null) {
return;
}
dominion.setTpLocation(node.tpLoc)
.setJoinMessage(node.joinMessage)
.setLeaveMessage(node.leaveMessage);
for (String msg : result.getMessages()) {
Notification.info(player, msg);
}
Notification.info(player, "领地 " + node.name + " 已从 Residence 迁移至 Dominion");
if (node.children != null) {
for (ResMigration.ResidenceNode child : node.children) {
create(player, child, node.name);
}
}
} else if (Objects.equals(result.getStatus(), BukkitPlayerOperator.Result.WARNING)) {
for (String msg : result.getMessages()) {
Notification.warn(player, msg);
}
} else {
for (String msg : result.getMessages()) {
Notification.error(player, msg);
}
}
});
DominionController.create(operator, node.name, node.loc1, node.loc2, parentName, true);
}
}

View File

@ -1,12 +1,14 @@
package cn.lunadeer.dominion.commands; package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.BlueMapConnect;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.MapRender;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Scheduler; import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger; import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseType;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.io.File; import java.io.File;
@ -15,12 +17,15 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static cn.lunadeer.dominion.commands.Apis.notOpOrConsole; import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
public class Operator { public class Operator {
public static void reloadCache(CommandSender sender, String[] args) { public static void reloadCache(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return; if (!hasPermission(sender, "dominion.admin")) {
return;
}
Scheduler.runTaskAsync(() -> { Scheduler.runTaskAsync(() -> {
Notification.info(sender, "正在从数据库重新加载领地缓存..."); Notification.info(sender, "正在从数据库重新加载领地缓存...");
Cache.instance.loadDominions(); Cache.instance.loadDominions();
@ -28,20 +33,30 @@ public class Operator {
}); });
Scheduler.runTaskAsync(() -> { Scheduler.runTaskAsync(() -> {
Notification.info(sender, "正在从数据库重新加载玩家权限缓存..."); Notification.info(sender, "正在从数据库重新加载玩家权限缓存...");
Cache.instance.loadPlayerPrivileges(); Cache.instance.loadMembers();
Notification.info(sender, "玩家权限缓存已重新加载"); Notification.info(sender, "玩家权限缓存已重新加载");
}); });
Scheduler.runTaskAsync(() -> {
Notification.info(sender, "正在从数据库重新加载权限组缓存...");
Cache.instance.loadGroups();
Notification.info(sender, "权限组缓存已重新加载");
});
} }
public static void exportMca(CommandSender sender, String[] args) { public static void exportMca(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return; if (!hasPermission(sender, "dominion.admin")) {
return;
}
Scheduler.runTaskAsync(() -> { Scheduler.runTaskAsync(() -> {
Notification.info(sender, "正在导出拥有领地的MCA文件列表..."); Notification.info(sender, "正在导出拥有领地的MCA文件列表...");
Map<String, List<String>> mca_cords = new HashMap<>(); Map<String, List<String>> mca_cords = new HashMap<>();
List<DominionDTO> doms = Cache.instance.getDominions(); List<DominionDTO> doms = Cache.instance.getDominions();
for (DominionDTO dom : doms) { for (DominionDTO dom : doms) {
if (!mca_cords.containsKey(dom.getWorld())) { if (dom.getWorld() == null) {
mca_cords.put(dom.getWorld(), new ArrayList<>()); continue;
}
if (!mca_cords.containsKey(dom.getWorld().getName())) {
mca_cords.put(dom.getWorld().getName(), new ArrayList<>());
} }
Integer world_x1 = dom.getX1(); Integer world_x1 = dom.getX1();
Integer world_x2 = dom.getX2(); Integer world_x2 = dom.getX2();
@ -54,10 +69,10 @@ public class Operator {
for (int x = mca_x1; x <= mca_x2; x++) { for (int x = mca_x1; x <= mca_x2; x++) {
for (int z = mca_z1; z <= mca_z2; z++) { for (int z = mca_z1; z <= mca_z2; z++) {
String file_name = "r." + x + "." + z + ".mca"; String file_name = "r." + x + "." + z + ".mca";
if (mca_cords.get(dom.getWorld()).contains(file_name)) { if (mca_cords.get(dom.getWorld().getName()).contains(file_name)) {
continue; continue;
} }
mca_cords.get(dom.getWorld()).add(file_name); mca_cords.get(dom.getWorld().getName()).add(file_name);
} }
} }
} }
@ -99,16 +114,26 @@ public class Operator {
Notification.error(sender, e.getMessage()); Notification.error(sender, e.getMessage());
} }
} }
BlueMapConnect.renderMCA(mca_cords); MapRender.renderMCA(mca_cords);
Notification.info(sender, "MCA文件列表已导出到 %s", folder.getAbsolutePath()); Notification.info(sender, "MCA文件列表已导出到 %s", folder.getAbsolutePath());
}); });
} }
public static void reloadConfig(CommandSender sender, String[] args) { public static void reloadConfig(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return; if (!hasPermission(sender, "dominion.admin")) {
return;
}
Scheduler.runTaskAsync(() -> { Scheduler.runTaskAsync(() -> {
Notification.info(sender, "正在重新加载配置文件..."); Notification.info(sender, "正在重新加载配置文件...");
Dominion.config.reload(); Dominion.config.reload();
DatabaseManager.instance.reConnection(
DatabaseType.valueOf(Dominion.config.getDbType().toUpperCase()),
Dominion.config.getDbHost(),
Dominion.config.getDbPort(),
Dominion.config.getDbName(),
Dominion.config.getDbUser(),
Dominion.config.getDbPass()
);
Notification.info(sender, "配置文件已重新加载"); Notification.info(sender, "配置文件已重新加载");
}); });
} }

View File

@ -1,16 +1,18 @@
package cn.lunadeer.dominion.commands; package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.tuis.DominionConfig; import cn.lunadeer.dominion.tuis.SysConfig;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import static cn.lunadeer.dominion.commands.Apis.notOpOrConsole; import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
public class SetConfig { public class SetConfig {
public static void handler(CommandSender sender, String[] args) { public static void handler(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return; if (!hasPermission(sender, "dominion.admin")) {
return;
}
if (args.length < 2) { if (args.length < 2) {
Notification.error(sender, "参数错误"); Notification.error(sender, "参数错误");
return; return;
@ -67,6 +69,12 @@ public class SetConfig {
case "economy_refund": case "economy_refund":
setEconomyRefund(sender, args); setEconomyRefund(sender, args);
break; break;
case "residence_migration":
setResidenceMigration(sender, args);
break;
case "spawn_protection":
setSpawnProtection(sender, args);
break;
default: default:
Notification.error(sender, "未知参数"); Notification.error(sender, "未知参数");
} }
@ -78,7 +86,7 @@ public class SetConfig {
String[] newArgs = new String[2]; String[] newArgs = new String[2];
newArgs[0] = "config"; newArgs[0] = "config";
newArgs[1] = String.valueOf(page); newArgs[1] = String.valueOf(page);
DominionConfig.show(sender, newArgs); SysConfig.show(sender, newArgs);
} }
} }
@ -94,14 +102,14 @@ public class SetConfig {
} }
private static void adjustSizeY() { private static void adjustSizeY() {
if (Dominion.config.getLimitVert()) { if (Dominion.config.getLimitVert(null)) {
Dominion.config.setLimitSizeY(Dominion.config.getLimitMaxY() - Dominion.config.getLimitMinY() + 1); Dominion.config.setLimitSizeY(Dominion.config.getLimitMaxY(null) - Dominion.config.getLimitMinY(null) + 1);
} }
} }
private static void setLimitMaxY(CommandSender sender, String[] args) { private static void setLimitMaxY(CommandSender sender, String[] args) {
int maxY = Integer.parseInt(args[2]); int maxY = Integer.parseInt(args[2]);
if (maxY <= Dominion.config.getLimitMinY()) { if (maxY <= Dominion.config.getLimitMinY(null)) {
Notification.error(sender, "最高Y坐标限制不能小于最低Y坐标限制"); Notification.error(sender, "最高Y坐标限制不能小于最低Y坐标限制");
return; return;
} }
@ -112,7 +120,7 @@ public class SetConfig {
private static void setLimitMinY(CommandSender sender, String[] args) { private static void setLimitMinY(CommandSender sender, String[] args) {
int minY = Integer.parseInt(args[2]); int minY = Integer.parseInt(args[2]);
if (minY >= Dominion.config.getLimitMaxY()) { if (minY >= Dominion.config.getLimitMaxY(null)) {
Notification.error(sender, "最低Y坐标限制不能大于最高Y坐标限制"); Notification.error(sender, "最低Y坐标限制不能大于最高Y坐标限制");
return; return;
} }
@ -249,5 +257,23 @@ public class SetConfig {
} else { } else {
Dominion.config.setEconomyRefund(economyRefund); Dominion.config.setEconomyRefund(economyRefund);
} }
refreshPageOrNot(sender, args);
}
private static void setResidenceMigration(CommandSender sender, String[] args) {
boolean residenceMigration = Boolean.parseBoolean(args[2]);
Dominion.config.setResidenceMigration(residenceMigration);
refreshPageOrNot(sender, args);
}
private static void setSpawnProtection(CommandSender sender, String[] args) {
int spawnProtection = Integer.parseInt(args[2]);
if (spawnProtection != -1 && spawnProtection <= 0) {
Dominion.config.setSpawnProtection(1);
Notification.error(sender, "出生点保护半径不能小于或等于0");
} else {
Dominion.config.setSpawnProtection(spawnProtection);
}
refreshPageOrNot(sender, args);
} }
} }

View File

@ -0,0 +1,165 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.TemplateController;
import cn.lunadeer.dominion.tuis.template.TemplateList;
import cn.lunadeer.dominion.tuis.template.TemplateSetting;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static cn.lunadeer.dominion.Commands.boolOptions;
import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.commands.Helper.allTemplates;
import static cn.lunadeer.dominion.commands.Helper.playerPrivileges;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class Template {
/**
* 创建权限模板
* /dominion template create <模板名称> [页码]
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void createTemplate(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 3) {
Notification.error(sender, "用法: /dominion template create <模板名称>");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
TemplateController.createTemplate(operator, args[2]);
TemplateList.show(sender);
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* 删除权限模板
* /dominion template delete <模板名称> [页码]
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void deleteTemplate(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 3) {
Notification.error(sender, "用法: /dominion template delete <模板名称>");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
TemplateController.deleteTemplate(operator, args[2]);
TemplateList.show(sender, getPage(args, 3));
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
/**
* 编辑模板
* /dominion template set_flag <模板名称> <权限名称> <true/false> [页码]
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void setTemplateFlag(CommandSender sender, String[] args) {
try {
if (!hasPermission(sender, "dominion.default")) {
return;
}
if (args.length < 5) {
Notification.error(sender, "用法: /dominion template set_flag <模板名称> <权限名称> <true/false>");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
String templateName = args[2];
String flagName = args[3];
boolean value = Boolean.parseBoolean(args[4]);
TemplateController.setTemplateFlag(operator, templateName, flagName, value);
TemplateSetting.show(sender, templateName, getPage(args, 5));
} catch (Exception e) {
Notification.error(sender, e.getMessage());
}
}
public static void handle(@NotNull CommandSender sender, @NotNull String[] args) {
if (args.length < 2) {
Notification.error(sender, "用法: /dominion template <list|setting|delete|create|set_flag>");
return;
}
switch (args[1]) {
case "list":
TemplateList.show(sender, args);
break;
case "setting":
TemplateSetting.show(sender, args);
break;
case "delete":
Template.deleteTemplate(sender, args);
break;
case "create":
Template.createTemplate(sender, args);
break;
case "set_flag":
Template.setTemplateFlag(sender, args);
break;
}
}
public static @Nullable List<String> handleTab(@NotNull CommandSender sender, @NotNull String[] args) {
if (args.length == 2) {
return Arrays.asList("list", "setting", "delete", "create", "set_flag");
}
if (args.length == 3) {
switch (args[1]) {
case "create":
return Collections.singletonList("输入模板名称");
case "delete":
case "set_flag":
case "setting":
return allTemplates(sender);
case "list":
return Collections.singletonList("页码(可选)");
}
}
if (args.length == 4) {
switch (args[1]) {
case "set_flag":
return playerPrivileges();
case "setting":
return Collections.singletonList("页码(可选)");
}
}
if (args.length == 5) {
switch (args[1]) {
case "set_flag":
return boolOptions();
}
}
return null;
}
}

View File

@ -0,0 +1,69 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.tuis.TitleList;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Objects;
import static cn.lunadeer.dominion.utils.CommandUtils.hasPermission;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class Title {
public static void use_title(CommandSender sender, String[] args) {
if (!hasPermission(sender, "dominion.default")) {
return;
}
Player bukkit_player = playerOnly(sender);
if (bukkit_player == null) return;
if (args.length < 2) {
Notification.error(sender, "用法: /dominion use_title <权限组ID>");
return;
}
try {
int id = Integer.parseInt(args[1]);
PlayerDTO player = PlayerDTO.get(bukkit_player);
if (id == -1) {
player.setUsingGroupTitleID(id);
Notification.info(sender, "成功卸下权限组称号");
} else {
GroupDTO group = Cache.instance.getGroup(id);
if (group == null) {
Notification.error(sender, "权限组不存在");
return;
}
DominionDTO dominion = Cache.instance.getDominion(group.getDomID());
if (dominion == null) {
Notification.error(sender, "权限组 %s 所属领地不存在", group.getName());
return;
}
if (!dominion.getOwner().equals(bukkit_player.getUniqueId())) {
MemberDTO member = Cache.instance.getMember(bukkit_player, dominion);
if (member == null) {
Notification.error(sender, "你不是 %s 的成员,无法使用其称号", dominion.getName());
return;
}
if (!Objects.equals(member.getGroupId(), group.getId())) {
Notification.error(sender, "你不属于权限组 %s无法使用其称号", group.getName());
return;
}
}
player.setUsingGroupTitleID(group.getId());
Notification.info(sender, "成功使用权限组 %s 称号", group.getName());
}
int page = getPage(args, 2);
TitleList.show(sender, page);
} catch (Exception e) {
Notification.error(sender, "使用称号失败: " + e.getMessage());
}
}
}

View File

@ -5,6 +5,8 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -16,21 +18,16 @@ public interface AbstractOperator {
public static final Integer FAILURE = 2; public static final Integer FAILURE = 2;
private Integer success; private Integer success;
private String message; private List<String> messages;
public Result(Integer success, String message, Object... args) { public Result(Integer success, String message, Object... args) {
this.success = success; this.success = success;
this.message = String.format(message, args); this.messages = new ArrayList<>();
this.messages.add(String.format(message, args));
} }
public Result setMessage(String message, Object... args) { public Result addMessage(String message, Object... args) {
this.message = String.format(message, args); this.messages.add(String.format(message, args));
return this;
}
public Result appendMessage(String message, Object... args) {
this.message += " ";
this.message += String.format(message, args);
return this; return this;
} }
@ -38,8 +35,8 @@ public interface AbstractOperator {
return success; return success;
} }
public String getMessage() { public List<String> getMessages() {
return message; return messages;
} }
} }
@ -51,9 +48,9 @@ public interface AbstractOperator {
public @Nullable Location getLocation(); public @Nullable Location getLocation();
public Player getPlayer(); public @Nullable Player getPlayer();
public BlockFace getDirection(); public @Nullable BlockFace getDirection();
public CompletableFuture<Result> getResponse(); public CompletableFuture<Result> getResponse();
} }

View File

@ -3,29 +3,43 @@ package cn.lunadeer.dominion.controllers;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class BukkitPlayerOperator implements AbstractOperator { public class BukkitPlayerOperator implements AbstractOperator {
private final org.bukkit.entity.Player player; private final CommandSender player;
private final CompletableFuture<Result> response = new CompletableFuture<>(); private final CompletableFuture<Result> response = new CompletableFuture<>();
public BukkitPlayerOperator(org.bukkit.entity.Player player) { public BukkitPlayerOperator(CommandSender player) {
this.player = player; this.player = player;
} }
public boolean isConsole() {
return !(player instanceof Player);
}
@Override @Override
public UUID getUniqueId() { public UUID getUniqueId() {
return player.getUniqueId(); if (isConsole()) {
return UUID.randomUUID();
} else {
return ((Player) player).getUniqueId();
}
} }
@Override @Override
public boolean isOp() { public boolean isOp() {
return player.isOp(); if (isConsole()) {
return true;
} else {
return ((Player) player).isOp() || player.hasPermission("dominion.admin");
}
} }
@Override @Override
@ -34,19 +48,30 @@ public class BukkitPlayerOperator implements AbstractOperator {
} }
@Override @Override
public Location getLocation() { public @Nullable Location getLocation() {
return player.getLocation(); if (isConsole()) {
return null;
} else {
return ((Player) player).getLocation();
}
} }
@Override @Override
public Player getPlayer() { public @Nullable Player getPlayer() {
return player; if (isConsole()) {
return null;
} else {
return (Player) player;
}
} }
@Override @Override
public BlockFace getDirection() { public @Nullable BlockFace getDirection() {
float yaw = player.getYaw(); if (isConsole() || getLocation() == null) {
float pitch = player.getPitch(); return null;
}
float yaw = getLocation().getYaw();
float pitch = getLocation().getPitch();
if (pitch > -45 && pitch < 45) { if (pitch > -45 && pitch < 45) {
if (yaw > -45 && yaw < 45) { if (yaw > -45 && yaw < 45) {
return BlockFace.SOUTH; return BlockFace.SOUTH;
@ -69,15 +94,21 @@ public class BukkitPlayerOperator implements AbstractOperator {
return response; return response;
} }
public static BukkitPlayerOperator create(org.bukkit.entity.Player player) { public static BukkitPlayerOperator create(CommandSender player) {
BukkitPlayerOperator operator = new BukkitPlayerOperator(player); BukkitPlayerOperator operator = new BukkitPlayerOperator(player);
operator.getResponse().thenAccept(result -> { operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), BukkitPlayerOperator.Result.SUCCESS)) { if (Objects.equals(result.getStatus(), BukkitPlayerOperator.Result.SUCCESS)) {
Notification.info(player, result.getMessage()); for (String msg : result.getMessages()) {
Notification.info(player, msg);
}
} else if (Objects.equals(result.getStatus(), BukkitPlayerOperator.Result.WARNING)) { } else if (Objects.equals(result.getStatus(), BukkitPlayerOperator.Result.WARNING)) {
Notification.warn(player, result.getMessage()); for (String msg : result.getMessages()) {
Notification.warn(player, msg);
}
} else { } else {
Notification.error(player, result.getMessage()); for (String msg : result.getMessages()) {
Notification.error(player, msg);
}
} }
}); });
return operator; return operator;

View File

@ -2,29 +2,31 @@ package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.DominionNode;
import cn.lunadeer.dominion.commands.OpenCUI;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.Particle;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.ParticleRender; import cn.lunadeer.minecraftpluginutils.VaultConnect.VaultConnect;
import cn.lunadeer.minecraftpluginutils.XLogger; import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static cn.lunadeer.dominion.DominionNode.isInDominion; import static cn.lunadeer.dominion.DominionNode.isInDominion;
import static cn.lunadeer.dominion.controllers.Apis.*; import static cn.lunadeer.dominion.utils.ControllerUtils.getPlayerCurrentDominion;
import static cn.lunadeer.dominion.utils.ControllerUtils.notOwner;
public class DominionController { public class DominionController {
public static List<DominionDTO> all(Player owner) { public static List<DominionDTO> all(Player owner) {
return DominionDTO.selectAll(owner.getUniqueId()); return DominionDTO.selectByOwner(owner.getUniqueId());
} }
public static List<DominionDTO> all() { public static List<DominionDTO> all() {
@ -38,7 +40,6 @@ public class DominionController {
* @param name 领地名称 * @param name 领地名称
* @param loc1 位置1 * @param loc1 位置1
* @param loc2 位置2 * @param loc2 位置2
* @return 创建的领地
*/ */
public static void create(AbstractOperator operator, String name, Location loc1, Location loc2) { public static void create(AbstractOperator operator, String name, Location loc1, Location loc2) {
DominionDTO parent = getPlayerCurrentDominion(operator); DominionDTO parent = getPlayerCurrentDominion(operator);
@ -57,56 +58,72 @@ public class DominionController {
* @param loc1 位置1 * @param loc1 位置1
* @param loc2 位置2 * @param loc2 位置2
* @param parent_dominion_name 父领地名称 * @param parent_dominion_name 父领地名称
* @return 创建的领地
*/ */
public static void create(AbstractOperator operator, String name, public static void create(AbstractOperator operator, String name,
Location loc1, Location loc2, Location loc1, Location loc2,
String parent_dominion_name) { String parent_dominion_name) {
create(operator, name, loc1, loc2, parent_dominion_name, false);
}
/**
* 创建子领地
*
* @param operator 拥有者
* @param name 领地名称
* @param loc1 位置1
* @param loc2 位置2
* @param parent_dominion_name 父领地名称(留空表示为根领地)
* @param skipEco 是否跳过经济检查
*/
public static void create(AbstractOperator operator, String name,
Location loc1, Location loc2,
@NotNull String parent_dominion_name, boolean skipEco) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建领地失败"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建领地失败");
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功创建领地 %s", name);
if (name.isEmpty()) { if (name.isEmpty()) {
operator.setResponse(FAIL.appendMessage("领地名称不能为空")); operator.setResponse(FAIL.addMessage("领地名称不能为空"));
return; return;
} }
if (name.contains(" ")) { if (name.contains(" ") || name.contains(".")) {
operator.setResponse(FAIL.appendMessage("领地名称不能包含空格")); operator.setResponse(FAIL.addMessage("领地名称不能包含空格或点"));
return; return;
} }
if (DominionDTO.select(name) != null) { if (DominionDTO.select(name) != null) {
operator.setResponse(FAIL.appendMessage("已经存在名称为 %s 的领地", name)); operator.setResponse(FAIL.addMessage("已经存在名称为 %s 的领地", name));
return; return;
} }
if (!loc1.getWorld().equals(loc2.getWorld())) { if (!loc1.getWorld().getUID().equals(loc2.getWorld().getUID())) {
operator.setResponse(FAIL.appendMessage("选点世界不一致")); operator.setResponse(FAIL.addMessage("选点世界不一致"));
return; return;
} }
// 检查世界是否可以创建 // 检查世界是否可以创建
if (worldNotValid(operator, loc1.getWorld().getName())) { if (worldNotValid(operator, loc1.getWorld().getName())) {
operator.setResponse(FAIL.appendMessage("禁止在世界 %s 创建领地", loc1.getWorld().getName())); operator.setResponse(FAIL.addMessage("禁止在世界 %s 创建领地", loc1.getWorld().getName()));
return; return;
} }
// 检查领地数量是否达到上限 // 检查领地数量是否达到上限
if (amountNotValid(operator)) { if (amountNotValid(operator)) {
operator.setResponse(FAIL.appendMessage("你的领地数量已达上限(%d个)", Dominion.config.getLimitAmount())); operator.setResponse(FAIL.addMessage("你的领地数量已达上限(%d个)", Dominion.config.getLimitAmount(operator.getPlayer())));
return; return;
} }
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
int minY = Math.min(loc1.getBlockY(), loc2.getBlockY());
int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ());
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()) + 1;
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()) + 1;
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()) + 1;
// 检查领地大小是否合法 // 检查领地大小是否合法
if (sizeNotValid(operator, if (sizeNotValid(operator, minX, minY, minZ, maxX, maxY, maxZ)) {
loc1.getBlockX(), loc1.getBlockY(), loc1.getBlockZ(),
loc2.getBlockX(), loc2.getBlockY(), loc2.getBlockZ())) {
return; return;
} }
DominionDTO dominion = new DominionDTO(operator.getUniqueId(), name, loc1.getWorld().getName(),
(int) Math.min(loc1.getX(), loc2.getX()), (int) Math.min(loc1.getY(), loc2.getY()),
(int) Math.min(loc1.getZ(), loc2.getZ()), (int) Math.max(loc1.getX(), loc2.getX()),
(int) Math.max(loc1.getY(), loc2.getY()), (int) Math.max(loc1.getZ(), loc2.getZ()));
DominionDTO parent_dominion; DominionDTO parent_dominion;
if (parent_dominion_name.isEmpty()) { if (parent_dominion_name.isEmpty() || parent_dominion_name.equals("root")) {
parent_dominion = DominionDTO.select(-1); parent_dominion = DominionDTO.select(-1);
} else { } else {
parent_dominion = DominionDTO.select(parent_dominion_name); parent_dominion = DominionDTO.select(parent_dominion_name);
} }
if (parent_dominion == null) { if (parent_dominion == null) {
operator.setResponse(FAIL.appendMessage("父领地 %s 不存在", parent_dominion_name)); operator.setResponse(FAIL.addMessage("父领地 %s 不存在", parent_dominion_name));
if (parent_dominion_name.isEmpty()) { if (parent_dominion_name.isEmpty()) {
XLogger.err("根领地丢失!"); XLogger.err("根领地丢失!");
} }
@ -115,13 +132,16 @@ public class DominionController {
// 是否是父领地的拥有者 // 是否是父领地的拥有者
if (parent_dominion.getId() != -1) { if (parent_dominion.getId() != -1) {
if (notOwner(operator, parent_dominion)) { if (notOwner(operator, parent_dominion)) {
operator.setResponse(FAIL.appendMessage("你不是父领地 %s 的拥有者,无法创建子领地", parent_dominion_name)); operator.setResponse(FAIL.addMessage("你不是父领地 %s 的拥有者,无法创建子领地", parent_dominion_name));
return; return;
} }
} }
// 创建 dominion (此步骤不会写入数据)
DominionDTO dominion = DominionDTO.create(parent_dominion.getId() == -1 ? operator.getUniqueId() : parent_dominion.getOwner(), name, loc1.getWorld(),
minX, minY, minZ, maxX, maxY, maxZ, parent_dominion);
// 如果parent_dominion不为-1 检查是否在同一世界 // 如果parent_dominion不为-1 检查是否在同一世界
if (parent_dominion.getId() != -1 && !parent_dominion.getWorld().equals(dominion.getWorld())) { if (parent_dominion.getId() != -1 && !parent_dominion.getWorldUid().equals(dominion.getWorldUid())) {
operator.setResponse(FAIL.appendMessage("父领地与子领地不在同一世界。")); operator.setResponse(FAIL.addMessage("父领地与子领地不在同一世界。"));
return; return;
} }
// 检查深度是否达到上限 // 检查深度是否达到上限
@ -130,44 +150,67 @@ public class DominionController {
} }
// 检查是否超出父领地范围 // 检查是否超出父领地范围
if (!isContained(dominion, parent_dominion)) { if (!isContained(dominion, parent_dominion)) {
operator.setResponse(FAIL.appendMessage("超出父领地 %s 范围", parent_dominion.getName())); operator.setResponse(FAIL.addMessage("超出父领地 %s 范围", parent_dominion.getName()));
return; return;
} }
// 获取此领地的所有同级领地 // 获取此领地的所有同级领地
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), parent_dominion.getId()); List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), parent_dominion.getId());
// 检查是否与出生点保护冲突
if (isIntersectSpawn(operator, dominion)) {
operator.setResponse(FAIL.addMessage("与出生点保护冲突"));
return;
}
// 检查是否与其他子领地冲突 // 检查是否与其他子领地冲突
for (DominionDTO sub_dominion : sub_dominions) { for (DominionDTO sub_dominion : sub_dominions) {
if (isIntersect(sub_dominion, dominion)) { if (isIntersect(sub_dominion, dominion)) {
operator.setResponse(FAIL.appendMessage("与领地 %s 冲突", sub_dominion.getName())); operator.setResponse(FAIL.addMessage("与领地 %s 冲突", sub_dominion.getName()));
return; return;
} }
} }
// 检查经济 // 检查经济
if (Dominion.config.getEconomyEnable()) { if (!skipEco) {
int count; if (handleEconomyFailed(operator, Dominion.config.getEconomyOnlyXZ(operator.getPlayer()) ? dominion.getSquare() : dominion.getVolume(), true, FAIL, SUCCESS)) {
if (Dominion.config.getEconomyOnlyXZ()) {
count = (loc2.getBlockX() - loc1.getBlockX() + 1) * (loc2.getBlockZ() - loc1.getBlockZ() + 1);
} else {
count = (loc2.getBlockX() - loc1.getBlockX() + 1) * (loc2.getBlockY() - loc1.getBlockY() + 1) * (loc2.getBlockZ() - loc1.getBlockZ() + 1);
}
float price = count * Dominion.config.getEconomyPrice();
if (Dominion.vault.getEconomy().getBalance(operator.getPlayer()) < price) {
operator.setResponse(FAIL.appendMessage("你的余额不足,创建此领地需要 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural()));
return; return;
} }
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "已扣除 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural()));
Dominion.vault.getEconomy().withdrawPlayer(operator.getPlayer(), price);
} }
dominion = DominionDTO.insert(dominion); dominion = DominionDTO.insert(dominion);
if (dominion == null) { if (dominion == null) {
operator.setResponse(FAIL.appendMessage("创建领地失败,数据库错误,请联系管理员")); operator.setResponse(FAIL.addMessage("创建领地失败,数据库错误,请联系管理员"));
return; return;
} }
if (operator instanceof BukkitPlayerOperator) { // 显示粒子效果
ParticleRender.showBoxFace(Dominion.instance, operator.getPlayer(), loc1, loc2); handleParticle(operator, dominion);
operator.setResponse(SUCCESS);
} }
dominion.setParentDomId(parent_dominion.getId());
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功创建领地 %s", name)); private static boolean isIntersectSpawn(AbstractOperator operator, DominionDTO dominion) {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false;
}
int radius = Dominion.config.getSpawnProtection();
if (radius == -1) {
return false;
}
World world = dominion.getWorld();
if (world == null) {
return false;
}
Location spawn = world.getSpawnLocation();
return isIntersect(dominion, spawn.getBlockX() - radius, spawn.getBlockY() - radius, spawn.getBlockZ() - radius
, spawn.getBlockX() + radius, spawn.getBlockY() + radius, spawn.getBlockZ() + radius);
}
private static boolean isIntersectSpawn(AbstractOperator operator, @NotNull World world, int[] cords) {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false;
}
int radius = Dominion.config.getSpawnProtection();
if (radius == -1) {
return false;
}
Location spawn = world.getSpawnLocation();
return isIntersect(cords, spawn.getBlockX() - radius, spawn.getBlockY() - radius, spawn.getBlockZ() - radius
, spawn.getBlockX() + radius, spawn.getBlockY() + radius, spawn.getBlockZ() + radius);
} }
/** /**
@ -177,7 +220,6 @@ public class DominionController {
* *
* @param operator 操作者 * @param operator 操作者
* @param size 扩展的大小 * @param size 扩展的大小
* @return 扩展后的领地
*/ */
public static void expand(AbstractOperator operator, Integer size) { public static void expand(AbstractOperator operator, Integer size) {
DominionDTO dominion = getPlayerCurrentDominion(operator); DominionDTO dominion = getPlayerCurrentDominion(operator);
@ -194,98 +236,49 @@ public class DominionController {
* @param operator 操作者 * @param operator 操作者
* @param size 扩展的大小 * @param size 扩展的大小
* @param dominion_name 领地名称 * @param dominion_name 领地名称
* @return 扩展后的领地
*/ */
public static void expand(AbstractOperator operator, Integer size, String dominion_name) { public static void expand(AbstractOperator operator, Integer size, String dominion_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "扩展领地失败"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "扩展领地失败");
Location location = operator.getLocation(); DominionDTO dominion = expandContractPreCheck(operator, getExistDomAndIsOwner(operator, dominion_name), FAIL);
BlockFace face = operator.getDirection();
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) { if (dominion == null) {
return; return;
} }
if (location != null) { int[] newCords = expandContractSizeChange(operator, dominion, true, size, FAIL);
if (!location.getWorld().getName().equals(dominion.getWorld())) { if (newCords == null) {
operator.setResponse(FAIL.appendMessage("禁止跨世界操作"));
return; return;
} }
} // 检查是否与出生点保护冲突
Integer x1 = dominion.getX1(); if (isIntersectSpawn(operator, dominion.getWorld(), newCords)) {
Integer y1 = dominion.getY1(); operator.setResponse(FAIL.addMessage("与出生点保护冲突"));
Integer z1 = dominion.getZ1();
Integer x2 = dominion.getX2();
Integer y2 = dominion.getY2();
Integer z2 = dominion.getZ2();
switch (face) {
case NORTH:
z1 -= size;
break;
case SOUTH:
z2 += size;
break;
case WEST:
x1 -= size;
break;
case EAST:
x2 += size;
break;
case UP:
y2 += size;
break;
case DOWN:
y1 -= size;
break;
default:
operator.setResponse(FAIL.appendMessage("无效的方向"));
return;
}
if (sizeNotValid(operator, x1, y1, z1, x2, y2, z2)) {
return; return;
} }
// 校验是否超出父领地范围 // 校验是否超出父领地范围
DominionDTO parent_dominion = DominionDTO.select(dominion.getParentDomId()); DominionDTO parent_dominion = DominionDTO.select(dominion.getParentDomId());
if (parent_dominion == null) { if (parent_dominion == null) {
operator.setResponse(FAIL.appendMessage("父领地丢失")); operator.setResponse(FAIL.addMessage("父领地丢失"));
return; return;
} }
if (!isContained(x1, y1, z1, x2, y2, z2, parent_dominion)) { if (!isContained(newCords, parent_dominion)) {
operator.setResponse(FAIL.appendMessage("超出父领地 %s 范围", parent_dominion.getName())); operator.setResponse(FAIL.addMessage("超出父领地 %s 范围", parent_dominion.getName()));
return; return;
} }
// 获取同世界下的所有同级领地 // 获取同世界下的所有同级领地
List<DominionDTO> exist_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getParentDomId()); List<DominionDTO> exist_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), dominion.getParentDomId());
for (DominionDTO exist_dominion : exist_dominions) { for (DominionDTO exist_dominion : exist_dominions) {
if (isIntersect(exist_dominion, x1, y1, z1, x2, y2, z2)) { if (isIntersect(exist_dominion, newCords)) {
// 如果是自己跳过 // 如果是自己跳过
if (exist_dominion.getId().equals(dominion.getId())) continue; if (exist_dominion.getId().equals(dominion.getId())) continue;
operator.setResponse(FAIL.appendMessage("与领地 %s 冲突", exist_dominion.getName())); operator.setResponse(FAIL.addMessage("与领地 %s 冲突", exist_dominion.getName()));
return; return;
} }
} }
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功扩展领地 %s %d格", dominion_name, size); AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功扩展领地 %s %d格", dominion_name, size);
// 检查经济 // 检查经济
if (Dominion.config.getEconomyEnable()) { if (handleEconomyFailed(operator, Dominion.config.getEconomyOnlyXZ(operator.getPlayer()) ? sqr(newCords) - dominion.getSquare() : vol(newCords) - dominion.getVolume()
int count; , true, FAIL, SUCCESS)) return;
if (Dominion.config.getEconomyOnlyXZ()) { // 显示粒子效果
count = (x2 - x1 + 1) * (z2 - z1 + 1) - dominion.getSquare(); dominion = dominion.setXYZ(newCords);
} else { handleParticle(operator, dominion);
count = (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1) - dominion.getVolume();
}
float price = count * Dominion.config.getEconomyPrice();
if (Dominion.vault.getEconomy().getBalance(operator.getPlayer()) < price) {
operator.setResponse(FAIL.appendMessage("你的余额不足,扩展此领地需要 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural()));
return;
}
SUCCESS.appendMessage("已扣除 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural());
Dominion.vault.getEconomy().withdrawPlayer(operator.getPlayer(), price);
}
if (operator instanceof BukkitPlayerOperator) {
World world = Dominion.instance.getServer().getWorld(dominion.getWorld());
ParticleRender.showBoxFace(Dominion.instance, operator.getPlayer(),
new Location(world, x1, y1, z1),
new Location(world, x2, y2, z2));
}
dominion.setXYZ(x1, y1, z1, x2, y2, z2);
operator.setResponse(SUCCESS); operator.setResponse(SUCCESS);
} }
@ -296,7 +289,6 @@ public class DominionController {
* *
* @param operator 操作者 * @param operator 操作者
* @param size 缩小的大小 * @param size 缩小的大小
* @return 缩小后的领地
*/ */
public static void contract(AbstractOperator operator, Integer size) { public static void contract(AbstractOperator operator, Integer size) {
DominionDTO dominion = getPlayerCurrentDominion(operator); DominionDTO dominion = getPlayerCurrentDominion(operator);
@ -313,90 +305,51 @@ public class DominionController {
* @param operator 操作者 * @param operator 操作者
* @param size 缩小的大小 * @param size 缩小的大小
* @param dominion_name 领地名称 * @param dominion_name 领地名称
* @return 缩小后的领地
*/ */
public static void contract(AbstractOperator operator, Integer size, String dominion_name) { public static void contract(AbstractOperator operator, Integer size, String dominion_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "缩小领地失败"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "缩小领地失败");
Location location = operator.getLocation(); DominionDTO dominion = expandContractPreCheck(operator, getExistDomAndIsOwner(operator, dominion_name), FAIL);
BlockFace face = operator.getDirection();
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) { if (dominion == null) {
return; return;
} }
if (location != null) { int[] newCords = expandContractSizeChange(operator, dominion, false, size, FAIL);
if (!location.getWorld().getName().equals(dominion.getWorld())) { if (newCords == null) {
operator.setResponse(FAIL.appendMessage("禁止跨世界操作"));
return;
}
}
Integer x1 = dominion.getX1();
Integer y1 = dominion.getY1();
Integer z1 = dominion.getZ1();
Integer x2 = dominion.getX2();
Integer y2 = dominion.getY2();
Integer z2 = dominion.getZ2();
switch (face) {
case SOUTH:
z2 -= size;
break;
case NORTH:
z1 += size;
break;
case EAST:
x2 -= size;
break;
case WEST:
x1 += size;
break;
case UP:
y2 -= size;
break;
case DOWN:
y1 += size;
break;
default:
operator.setResponse(FAIL.appendMessage("无效的方向"));
return;
}
// 校验第二组坐标是否小于第一组坐标
if (x1 >= x2 || y1 >= y2 || z1 >= z2) {
operator.setResponse(FAIL.appendMessage("缩小后的领地大小无效"));
return;
}
if (sizeNotValid(operator, x1, y1, z1, x2, y2, z2)) {
return; return;
} }
// 获取所有的子领地 // 获取所有的子领地
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId()); List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), dominion.getId());
for (DominionDTO sub_dominion : sub_dominions) { for (DominionDTO sub_dominion : sub_dominions) {
if (!isContained(sub_dominion, x1, y1, z1, x2, y2, z2)) { if (!isContained(sub_dominion, newCords)) {
operator.setResponse(FAIL.appendMessage("缩小后的领地无法包含子领地 %s", sub_dominion.getName())); operator.setResponse(FAIL.addMessage("缩小后的领地无法包含子领地 %s", sub_dominion.getName()));
return; return;
} }
} }
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功缩小领地 %s %d格", dominion_name, size); AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功缩小领地 %s %d格", dominion_name, size);
// 退还经济 // 退还经济
if (Dominion.config.getEconomyEnable()) { if (handleEconomyFailed(operator, Dominion.config.getEconomyOnlyXZ(operator.getPlayer()) ? dominion.getSquare() - sqr(newCords) : dominion.getVolume() - vol(newCords)
int count; , false, FAIL, SUCCESS)) return;
if (Dominion.config.getEconomyOnlyXZ()) { // 显示粒子效果
count = dominion.getSquare() - (x2 - x1 + 1) * (z2 - z1 + 1); dominion = dominion.setXYZ(newCords);
} else { handleParticle(operator, dominion);
count = dominion.getVolume() - (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1);
}
float refund = count * Dominion.config.getEconomyPrice() * Dominion.config.getEconomyRefund();
Dominion.vault.getEconomy().depositPlayer(operator.getPlayer(), refund);
SUCCESS.appendMessage("已退还 %.2f %s", refund, Dominion.vault.getEconomy().currencyNamePlural());
}
if (operator instanceof BukkitPlayerOperator) {
World world = Dominion.instance.getServer().getWorld(dominion.getWorld());
ParticleRender.showBoxFace(Dominion.instance, operator.getPlayer(),
new Location(world, x1, y1, z1),
new Location(world, x2, y2, z2));
}
dominion.setXYZ(x1, y1, z1, x2, y2, z2);
operator.setResponse(SUCCESS); operator.setResponse(SUCCESS);
} }
private static int vol(int x1, int y1, int z1, int x2, int y2, int z2) {
return (x2 - x1) * (y2 - y1) * (z2 - z1);
}
private static int vol(int[] cords) {
return vol(cords[0], cords[1], cords[2], cords[3], cords[4], cords[5]);
}
private static int sqr(int x1, int z1, int x2, int z2) {
return (x2 - x1) * (z2 - z1);
}
private static int sqr(int[] cords) {
return sqr(cords[0], cords[2], cords[3], cords[5]);
}
/** /**
* 删除领地 会同时删除其所有子领地 * 删除领地 会同时删除其所有子领地
* *
@ -405,6 +358,8 @@ public class DominionController {
* @param force 是否强制删除 * @param force 是否强制删除
*/ */
public static void delete(AbstractOperator operator, String dominion_name, boolean force) { public static void delete(AbstractOperator operator, String dominion_name, boolean force) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "删除领地失败");
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "领地 %s 及其所有子领地已删除", dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name); DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) { if (dominion == null) {
return; return;
@ -412,14 +367,7 @@ public class DominionController {
List<DominionDTO> sub_dominions = getSubDominionsRecursive(dominion); List<DominionDTO> sub_dominions = getSubDominionsRecursive(dominion);
if (!force) { if (!force) {
AbstractOperator.Result WARNING = new AbstractOperator.Result(AbstractOperator.Result.WARNING, "删除领地 %s 会同时删除其所有子领地,是否继续?", dominion_name); AbstractOperator.Result WARNING = new AbstractOperator.Result(AbstractOperator.Result.WARNING, "删除领地 %s 会同时删除其所有子领地,是否继续?", dominion_name);
String sub_names = ""; showSubNamesWarning(sub_dominions, WARNING);
for (DominionDTO sub_dominion : sub_dominions) {
sub_names = sub_dominion.getName() + ", ";
}
if (sub_dominions.size() > 0) {
sub_names = sub_names.substring(0, sub_names.length() - 2);
WARNING.appendMessage("(子领地:%s)", sub_names);
}
if (operator instanceof BukkitPlayerOperator) { if (operator instanceof BukkitPlayerOperator) {
Notification.warn(operator.getPlayer(), "输入 /dominion delete %s force 确认删除", dominion_name); Notification.warn(operator.getPlayer(), "输入 /dominion delete %s force 确认删除", dominion_name);
} }
@ -427,23 +375,20 @@ public class DominionController {
return; return;
} }
DominionDTO.delete(dominion); DominionDTO.delete(dominion);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "领地 %s 及其所有子领地已删除", dominion_name);
// 退还经济 // 退还经济
if (Dominion.config.getEconomyEnable()) { int count;
int count = 0; if (Dominion.config.getEconomyOnlyXZ(operator.getPlayer())) {
if (Dominion.config.getEconomyOnlyXZ()) { count = dominion.getSquare();
for (DominionDTO sub_dominion : sub_dominions) { for (DominionDTO sub_dominion : sub_dominions) {
count += sub_dominion.getSquare(); count += sub_dominion.getSquare();
} }
} else { } else {
count = dominion.getVolume();
for (DominionDTO sub_dominion : sub_dominions) { for (DominionDTO sub_dominion : sub_dominions) {
count += sub_dominion.getVolume(); count += sub_dominion.getVolume();
} }
} }
float refund = count * Dominion.config.getEconomyPrice() * Dominion.config.getEconomyRefund(); if (handleEconomyFailed(operator, count, false, FAIL, SUCCESS)) return;
Dominion.vault.getEconomy().depositPlayer(operator.getPlayer(), refund);
SUCCESS.appendMessage("已退还 %.2f %s", refund, Dominion.vault.getEconomy().currencyNamePlural());
}
operator.setResponse(SUCCESS); operator.setResponse(SUCCESS);
} }
@ -527,14 +472,15 @@ public class DominionController {
* @param dominion_name 领地名称 * @param dominion_name 领地名称
*/ */
public static void setTpLocation(AbstractOperator operator, int x, int y, int z, String dominion_name) { public static void setTpLocation(AbstractOperator operator, int x, int y, int z, String dominion_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置领地传送点失败");
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name); DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) { if (dominion == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "领地 %s 不存在", dominion_name)); operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "领地 %s 不存在", dominion_name));
return; return;
} }
World world = Dominion.instance.getServer().getWorld(dominion.getWorld()); World world = dominion.getWorld();
if (world == null) { if (world == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "世界 %s 不存在", dominion.getWorld())); operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "领地所在世界不存在"));
return; return;
} }
Location loc = new Location(world, x, y, z); Location loc = new Location(world, x, y, z);
@ -546,7 +492,7 @@ public class DominionController {
"成功设置领地 %s 的传送点 %d %d %d", dominion_name "成功设置领地 %s 的传送点 %d %d %d", dominion_name
, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); , loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
} else { } else {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "传送点不在领地 %s 内", dominion_name)); operator.setResponse(FAIL.addMessage("传送点不在领地 %s 内", dominion_name));
} }
} }
@ -560,15 +506,15 @@ public class DominionController {
public static void rename(AbstractOperator operator, String old_name, String new_name) { public static void rename(AbstractOperator operator, String old_name, String new_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "重命名领地失败"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "重命名领地失败");
if (new_name.isEmpty()) { if (new_name.isEmpty()) {
operator.setResponse(FAIL.appendMessage("新名称不能为空")); operator.setResponse(FAIL.addMessage("新名称不能为空"));
return; return;
} }
if (new_name.contains(" ")) { if (new_name.contains(" ") || new_name.contains(".")) {
operator.setResponse(FAIL.appendMessage("领地名称不能包含空格")); operator.setResponse(FAIL.addMessage("领地名称不能包含空格或点"));
return; return;
} }
if (Objects.equals(old_name, new_name)) { if (Objects.equals(old_name, new_name)) {
operator.setResponse(FAIL.appendMessage("新名称与旧名称相同")); operator.setResponse(FAIL.addMessage("新名称与旧名称相同"));
return; return;
} }
DominionDTO dominion = getExistDomAndIsOwner(operator, old_name); DominionDTO dominion = getExistDomAndIsOwner(operator, old_name);
@ -576,7 +522,7 @@ public class DominionController {
return; return;
} }
if (DominionDTO.select(new_name) != null) { if (DominionDTO.select(new_name) != null) {
operator.setResponse(FAIL.appendMessage("已经存在名称为 %s 的领地", new_name)); operator.setResponse(FAIL.addMessage("已经存在名称为 %s 的领地", new_name));
return; return;
} }
dominion.setName(new_name); dominion.setName(new_name);
@ -595,11 +541,7 @@ public class DominionController {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "转让领地失败"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "转让领地失败");
PlayerDTO operatorDTO = PlayerDTO.select(operator.getUniqueId()); PlayerDTO operatorDTO = PlayerDTO.select(operator.getUniqueId());
if (operatorDTO == null) { if (operatorDTO == null) {
operator.setResponse(FAIL.appendMessage("操作者信息丢失,请联系管理员")); operator.setResponse(FAIL.addMessage("操作者信息丢失,请联系管理员"));
return;
}
if (Objects.equals(player_name, operatorDTO.getLastKnownName())) {
operator.setResponse(FAIL.appendMessage("不能将领地转让给自己"));
return; return;
} }
DominionDTO dominion = getExistDomAndIsOwner(operator, dom_name); DominionDTO dominion = getExistDomAndIsOwner(operator, dom_name);
@ -608,24 +550,21 @@ public class DominionController {
} }
PlayerDTO player = PlayerController.getPlayerDTO(player_name); PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) { if (player == null) {
operator.setResponse(FAIL.appendMessage("玩家 %s 不存在", player_name)); operator.setResponse(FAIL.addMessage("玩家 %s 不存在", player_name));
return;
}
if (Objects.equals(dominion.getOwner(), player.getUuid())) {
operator.setResponse(FAIL.addMessage("领地 %s 已经属于 %s无需转移", dom_name, player_name));
return; return;
} }
if (dominion.getParentDomId() != -1) { if (dominion.getParentDomId() != -1) {
operator.setResponse(FAIL.appendMessage("子领地无法转让,你可以通过将 %s 设置为管理员来让其管理领地 %s ", player_name, dom_name)); operator.setResponse(FAIL.addMessage("子领地无法转让,你可以通过将 %s 设置为管理员来让其管理领地 %s ", player_name, dom_name));
return; return;
} }
List<DominionDTO> sub_dominions = getSubDominionsRecursive(dominion); List<DominionDTO> sub_dominions = getSubDominionsRecursive(dominion);
if (!force) { if (!force) {
AbstractOperator.Result WARNING = new AbstractOperator.Result(AbstractOperator.Result.WARNING, "转让领地 %s 给 %s 会同时转让其所有子领地,是否继续?", dom_name, player_name); AbstractOperator.Result WARNING = new AbstractOperator.Result(AbstractOperator.Result.WARNING, "转让领地 %s 给 %s 会同时转让其所有子领地,是否继续?", dom_name, player_name);
String sub_names = ""; showSubNamesWarning(sub_dominions, WARNING);
for (DominionDTO sub_dominion : sub_dominions) {
sub_names = sub_dominion.getName() + ", ";
}
if (sub_dominions.size() > 0) {
sub_names = sub_names.substring(0, sub_names.length() - 2);
WARNING.appendMessage("(子领地:%s)", sub_names);
}
if (operator instanceof BukkitPlayerOperator) { if (operator instanceof BukkitPlayerOperator) {
Notification.warn(operator.getPlayer(), "输入 /dominion give %s %s force 确认转让", dom_name, player_name); Notification.warn(operator.getPlayer(), "输入 /dominion give %s %s force 确认转让", dom_name, player_name);
} }
@ -639,13 +578,53 @@ public class DominionController {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功将领地 %s 及其所有子领地转让给 %s", dom_name, player_name)); operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功将领地 %s 及其所有子领地转让给 %s", dom_name, player_name));
} }
/**
* 设置领地的卫星地图地块颜色
*
* @param operator 操作者
* @param color 16进制颜色 例如 #ff0000
* @param dom_name 领地名称
*/
public static void setMapColor(AbstractOperator operator, String color, String dom_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置领地地图颜色失败");
DominionDTO dominion = getExistDomAndIsOwner(operator, dom_name);
if (dominion == null) {
return;
}
if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者", dom_name));
return;
}
color = color.toUpperCase(); // 转换为大写
if (!color.matches("^#[0-9a-fA-F]{6}$")) {
operator.setResponse(FAIL.addMessage("颜色格式不正确"));
return;
}
dominion.setColor(color);
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "成功设置领地 %s 的卫星地图颜色为 %s", dom_name, color));
}
/**
* 设置领地的卫星地图地块颜色
*
* @param operator 操作者
* @param color 16进制颜色 例如 #ff0000
*/
public static void setMapColor(AbstractOperator operator, String color) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置领地地图颜色失败");
DominionDTO dominion = getPlayerCurrentDominion(operator);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("无法获取你所处的领地,请指定名称"));
return;
}
setMapColor(operator, color, dominion.getName());
}
/** /**
* 判断两个领地是否相交 * 判断两个领地是否相交
*/ */
private static boolean isIntersect(DominionDTO a, DominionDTO b) { private static boolean isIntersect(DominionDTO a, DominionDTO b) {
return a.getX1() < b.getX2() && a.getX2() > b.getX1() && return isIntersect(a, b.getX1(), b.getY1(), b.getZ1(), b.getX2(), b.getY2(), b.getZ2());
a.getY1() < b.getY2() && a.getY2() > b.getY1() &&
a.getZ1() < b.getZ2() && a.getZ2() > b.getZ1();
} }
private static boolean isIntersect(DominionDTO a, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { private static boolean isIntersect(DominionDTO a, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
@ -654,6 +633,16 @@ public class DominionController {
a.getZ1() < z2 && a.getZ2() > z1; a.getZ1() < z2 && a.getZ2() > z1;
} }
private static boolean isIntersect(DominionDTO a, int[] cord) {
return isIntersect(a, cord[0], cord[1], cord[2], cord[3], cord[4], cord[5]);
}
private static boolean isIntersect(int[] cord, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
return cord[0] < x2 && cord[3] > x1 &&
cord[1] < y2 && cord[4] > y1 &&
cord[2] < z2 && cord[5] > z1;
}
/** /**
* 判断 sub 是否完全被 parent 包裹 * 判断 sub 是否完全被 parent 包裹
*/ */
@ -661,28 +650,36 @@ public class DominionController {
if (parent.getId() == -1) { if (parent.getId() == -1) {
return true; return true;
} }
return sub.getX1() >= parent.getX1() && sub.getX2() <= parent.getX2() && return isContained(sub.getX1(), sub.getY1(), sub.getZ1(), sub.getX2(), sub.getY2(), sub.getZ2(), parent.getX1(), parent.getY1(), parent.getZ1(), parent.getX2(), parent.getY2(), parent.getZ2());
sub.getY1() >= parent.getY1() && sub.getY2() <= parent.getY2() && }
sub.getZ1() >= parent.getZ1() && sub.getZ2() <= parent.getZ2();
private static boolean isContained(int[] cords, DominionDTO parent) {
return isContained(cords[0], cords[1], cords[2], cords[3], cords[4], cords[5], parent);
}
private static boolean isContained(DominionDTO sub, int[] cords) {
return isContained(sub, cords[0], cords[1], cords[2], cords[3], cords[4], cords[5]);
} }
private static boolean isContained(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, DominionDTO parent) { private static boolean isContained(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, DominionDTO parent) {
if (parent.getId() == -1) { if (parent.getId() == -1) {
return true; return true;
} }
return x1 >= parent.getX1() && x2 <= parent.getX2() && return isContained(x1, y1, z1, x2, y2, z2, parent.getX1(), parent.getY1(), parent.getZ1(), parent.getX2(), parent.getY2(), parent.getZ2());
y1 >= parent.getY1() && y2 <= parent.getY2() &&
z1 >= parent.getZ1() && z2 <= parent.getZ2();
} }
private static boolean isContained(DominionDTO sub, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) { private static boolean isContained(DominionDTO sub, Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
return sub.getX1() >= x1 && sub.getX2() <= x2 && return isContained(sub.getX1(), sub.getY1(), sub.getZ1(), sub.getX2(), sub.getY2(), sub.getZ2(), x1, y1, z1, x2, y2, z2);
sub.getY1() >= y1 && sub.getY2() <= y2 && }
sub.getZ1() >= z1 && sub.getZ2() <= z2;
private static boolean isContained(int sub_x1, int sub_y1, int sub_z1, int sub_x2, int sub_y2, int sub_z2, int parent_x1, int parent_y1, int parent_z1, int parent_x2, int parent_y2, int parent_z2) {
return sub_x1 >= parent_x1 && sub_x2 <= parent_x2 &&
sub_y1 >= parent_y1 && sub_y2 <= parent_y2 &&
sub_z1 >= parent_z1 && sub_z2 <= parent_z2;
} }
private static List<DominionDTO> getSubDominionsRecursive(DominionDTO dominion) { private static List<DominionDTO> getSubDominionsRecursive(DominionDTO dominion) {
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId()); List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorldUid(), dominion.getId());
List<DominionDTO> sub_sub_dominions = new ArrayList<>(); List<DominionDTO> sub_sub_dominions = new ArrayList<>();
for (DominionDTO sub_dominion : sub_dominions) { for (DominionDTO sub_dominion : sub_dominions) {
sub_sub_dominions.addAll(getSubDominionsRecursive(sub_dominion)); sub_sub_dominions.addAll(getSubDominionsRecursive(sub_dominion));
@ -691,6 +688,10 @@ public class DominionController {
return sub_dominions; return sub_dominions;
} }
private static boolean sizeNotValid(AbstractOperator operator, int[] cords) {
return sizeNotValid(operator, cords[0], cords[1], cords[2], cords[3], cords[4], cords[5]);
}
private static boolean sizeNotValid(AbstractOperator operator, int x1, int y1, int z1, int x2, int y2, int z2) { private static boolean sizeNotValid(AbstractOperator operator, int x1, int y1, int z1, int x2, int y2, int z2) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "尺寸不合法"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "尺寸不合法");
if (operator.isOp() && Dominion.config.getLimitOpBypass()) { if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
@ -716,27 +717,27 @@ public class DominionController {
int y_length = y2 - y1; int y_length = y2 - y1;
int z_length = z2 - z1; int z_length = z2 - z1;
if (x_length < 4 || y_length < 4 || z_length < 4) { if (x_length < 4 || y_length < 4 || z_length < 4) {
operator.setResponse(FAIL.appendMessage("领地的任意一边长度不得小于4")); operator.setResponse(FAIL.addMessage("领地的任意一边长度不得小于4"));
return true; return true;
} }
if (x_length > Dominion.config.getLimitSizeX() && Dominion.config.getLimitSizeX() > 0) { if (x_length > Dominion.config.getLimitSizeX(operator.getPlayer()) && Dominion.config.getLimitSizeX(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.appendMessage("领地X方向长度不能超过 %s", Dominion.config.getLimitSizeX())); operator.setResponse(FAIL.addMessage("领地X方向长度不能超过 %d", Dominion.config.getLimitSizeX(operator.getPlayer())));
return true; return true;
} }
if (y_length > Dominion.config.getLimitSizeY() && Dominion.config.getLimitSizeY() > 0) { if (y_length > Dominion.config.getLimitSizeY(operator.getPlayer()) && Dominion.config.getLimitSizeY(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.appendMessage("领地Y方向高度不能超过 %s", Dominion.config.getLimitSizeY())); operator.setResponse(FAIL.addMessage("领地Y方向高度不能超过 %d", Dominion.config.getLimitSizeY(operator.getPlayer())));
return true; return true;
} }
if (z_length > Dominion.config.getLimitSizeZ() && Dominion.config.getLimitSizeZ() > 0) { if (z_length > Dominion.config.getLimitSizeZ(operator.getPlayer()) && Dominion.config.getLimitSizeZ(operator.getPlayer()) > 0) {
operator.setResponse(FAIL.appendMessage("领地Z方向长度不能超过 %s", Dominion.config.getLimitSizeZ())); operator.setResponse(FAIL.addMessage("领地Z方向长度不能超过 %d", Dominion.config.getLimitSizeZ(operator.getPlayer())));
return true; return true;
} }
if (y2 > Dominion.config.getLimitMaxY()) { if (y2 > Dominion.config.getLimitMaxY(operator.getPlayer())) {
operator.setResponse(FAIL.appendMessage("领地Y坐标不能超过 %s", Dominion.config.getLimitMaxY())); operator.setResponse(FAIL.addMessage("领地Y坐标不能超过 %d", Dominion.config.getLimitMaxY(operator.getPlayer())));
return true; return true;
} }
if (y1 < Dominion.config.getLimitMinY()) { if (y1 < Dominion.config.getLimitMinY(operator.getPlayer())) {
operator.setResponse(FAIL.appendMessage("领地Y坐标不能低于 %s", Dominion.config.getLimitMinY())); operator.setResponse(FAIL.addMessage("领地Y坐标不能低于 %d", Dominion.config.getLimitMinY(operator.getPlayer())));
return true; return true;
} }
return false; return false;
@ -747,11 +748,11 @@ public class DominionController {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) { if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false; return false;
} }
if (Dominion.config.getLimitDepth() == -1) { if (Dominion.config.getLimitDepth(operator.getPlayer()) == -1) {
return false; return false;
} }
if (parent_dom.getId() != -1 && Dominion.config.getLimitDepth() == 0) { if (parent_dom.getId() != -1 && Dominion.config.getLimitDepth(operator.getPlayer()) == 0) {
operator.setResponse(FAIL.appendMessage("不允许创建子领地")); operator.setResponse(FAIL.addMessage("不允许创建子领地"));
return true; return true;
} }
if (parent_dom.getId() == -1) { if (parent_dom.getId() == -1) {
@ -762,8 +763,8 @@ public class DominionController {
parent_dom = Cache.instance.getDominion(parent_dom.getParentDomId()); parent_dom = Cache.instance.getDominion(parent_dom.getParentDomId());
level++; level++;
} }
if (level >= Dominion.config.getLimitDepth()) { if (level >= Dominion.config.getLimitDepth(operator.getPlayer())) {
operator.setResponse(FAIL.appendMessage("子领地嵌套深度不能超过 %s", Dominion.config.getLimitDepth())); operator.setResponse(FAIL.addMessage("子领地嵌套深度不能超过 %d", Dominion.config.getLimitDepth(operator.getPlayer())));
return true; return true;
} }
return false; return false;
@ -773,28 +774,165 @@ public class DominionController {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) { if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false; return false;
} }
return Cache.instance.getPlayerDominionCount(operator.getUniqueId()) >= Dominion.config.getLimitAmount() && Dominion.config.getLimitAmount() != -1; return Cache.instance.getPlayerDominionCount(operator.getUniqueId()) >= Dominion.config.getLimitAmount(operator.getPlayer()) && Dominion.config.getLimitAmount(operator.getPlayer()) != -1;
} }
private static boolean worldNotValid(AbstractOperator operator, String world) { private static boolean worldNotValid(AbstractOperator operator, String worldName) {
if (operator.isOp() && Dominion.config.getLimitOpBypass()) { if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
return false; return false;
} }
return Dominion.config.getWorldBlackList().contains(world); return Dominion.config.getWorldBlackList(operator.getPlayer()).contains(worldName);
} }
private static DominionDTO getExistDomAndIsOwner(AbstractOperator operator, String dominion_name) { private static DominionDTO getExistDomAndIsOwner(AbstractOperator operator, String dominion_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, ""); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "");
DominionDTO dominion = DominionDTO.select(dominion_name); DominionDTO dominion = DominionDTO.select(dominion_name);
if (dominion == null) { if (dominion == null) {
operator.setResponse(FAIL.setMessage("领地 %s 不存在", dominion_name)); operator.setResponse(FAIL.addMessage("领地 %s 不存在", dominion_name));
return null; return null;
} }
if (notOwner(operator, dominion)) { if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.setMessage("你不是领地 %s 的拥有者", dominion_name)); operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者", dominion_name));
return null; return null;
} }
return dominion; return dominion;
} }
/**
* 处理经济系统
*
* @param operator 操作者
* @param count 数量
* @param paid 操作类型 true 为扣费 false 为退费
* @param FAIL 失败消息
* @param SUCCESS 成功消息
*/
private static boolean handleEconomyFailed(AbstractOperator operator, Integer count, boolean paid, AbstractOperator.Result FAIL, AbstractOperator.Result SUCCESS) {
if (Dominion.config.getEconomyEnable()) {
if (!VaultConnect.instance.economyAvailable()) {
operator.setResponse(FAIL.addMessage("没有可用的经济插件系统,请联系服主。"));
return true;
}
if (operator.isOp() && Dominion.config.getLimitOpBypass()) {
SUCCESS.addMessage("你是OP已跳过经济检查。");
return false;
}
float priceOrRefund = count * Dominion.config.getEconomyPrice(operator.getPlayer());
if (paid) {
if (VaultConnect.instance.getBalance(operator.getPlayer()) < priceOrRefund) {
operator.setResponse(FAIL.addMessage("你的余额不足,需要 %.2f %s", priceOrRefund, VaultConnect.instance.currencyNamePlural()));
return true;
}
SUCCESS.addMessage("已扣除 %.2f %s", priceOrRefund, VaultConnect.instance.currencyNamePlural());
VaultConnect.instance.withdrawPlayer(operator.getPlayer(), priceOrRefund);
} else {
float refund = priceOrRefund * Dominion.config.getEconomyRefund(operator.getPlayer());
VaultConnect.instance.depositPlayer(operator.getPlayer(), refund);
SUCCESS.addMessage("已退还 %.2f %s", refund, VaultConnect.instance.currencyNamePlural());
}
}
return false;
}
/**
* 显示粒子效果
*
* @param operator 操作者
* @param dominion 领地
*/
private static void handleParticle(AbstractOperator operator, DominionDTO dominion) {
if (operator instanceof BukkitPlayerOperator) {
Particle.showBorder(operator.getPlayer(), dominion);
}
}
private static @Nullable DominionDTO expandContractPreCheck(AbstractOperator operator, @Nullable DominionDTO dominion, AbstractOperator.Result FAIL) {
if (dominion == null) {
return null;
}
if (operator.getLocation() == null) {
operator.setResponse(FAIL.addMessage("无法获取你的位置"));
return null;
}
if (!operator.getLocation().getWorld().getUID().equals(dominion.getWorldUid())) {
operator.setResponse(FAIL.addMessage("禁止跨世界操作"));
return null;
}
if (!isInDominion(dominion, operator.getLocation())) {
operator.setResponse(FAIL.addMessage("你不在领地 %s 内,无法执行此操作", dominion.getName()));
return null;
}
return dominion;
}
private static int[] expandContractSizeChange(AbstractOperator operator, @NotNull DominionDTO dominion, boolean expand, int size, AbstractOperator.Result FAIL) {
BlockFace face = operator.getDirection();
if (face == null) {
operator.setResponse(FAIL.addMessage("无法获取你的方向"));
return null;
}
int[] result = new int[6];
result[0] = dominion.getX1();
result[1] = dominion.getY1();
result[2] = dominion.getZ1();
result[3] = dominion.getX2();
result[4] = dominion.getY2();
result[5] = dominion.getZ2();
if (!expand) {
size = size * -1;
}
switch (face) {
case NORTH:
result[2] -= size;
break;
case SOUTH:
result[5] += size;
break;
case WEST:
result[0] -= size;
break;
case EAST:
result[3] += size;
break;
case UP:
result[4] += size;
break;
case DOWN:
result[1] -= size;
break;
default:
operator.setResponse(FAIL.addMessage("无效的方向"));
return null;
}
if (!expand) {
// 校验第二组坐标是否小于第一组坐标
if (result[0] > result[3] || result[1] > result[4] || result[2] > result[5]) {
operator.setResponse(FAIL.addMessage("缩小后的领地大小无效"));
return null;
}
}
if (sizeNotValid(operator, result)) {
return null;
}
return result;
}
/**
* 以警告形式打印所有子领地名称
*
* @param sub_dominions 子领地列表
* @param WARNING 警告消息
*/
public static void showSubNamesWarning(List<DominionDTO> sub_dominions, AbstractOperator.Result WARNING) {
String sub_names = "";
for (DominionDTO sub_dominion : sub_dominions) {
sub_names = sub_dominion.getName() + ", ";
}
if (!sub_dominions.isEmpty()) {
sub_names = sub_names.substring(0, sub_names.length() - 2);
WARNING.addMessage("(子领地:%s)", sub_names);
}
}
} }

View File

@ -2,10 +2,9 @@ package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.dominion.utils.ControllerUtils;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.controllers.Apis.noAuthToChangeFlags; import static cn.lunadeer.dominion.utils.ControllerUtils.noAuthToChangeFlags;
public class FlagsController { public class FlagsController {
@ -15,10 +14,9 @@ public class FlagsController {
* @param operator 操作者 * @param operator 操作者
* @param flag 权限名称 * @param flag 权限名称
* @param value 权限值 * @param value 权限值
* @return 设置后的领地信息
*/ */
public static void setFlag(AbstractOperator operator, String flag, boolean value) { public static void setFlag(AbstractOperator operator, String flag, boolean value) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator); DominionDTO dominion = ControllerUtils.getPlayerCurrentDominion(operator);
if (dominion == null) return; if (dominion == null) return;
setFlag(operator, flag, value, dominion.getName()); setFlag(operator, flag, value, dominion.getName());
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "设置领地权限 %s 为 %s", flag, value)); operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "设置领地权限 %s 为 %s", flag, value));
@ -31,7 +29,6 @@ public class FlagsController {
* @param flag 权限名称 * @param flag 权限名称
* @param value 权限值 * @param value 权限值
* @param dominionName 领地名称 * @param dominionName 领地名称
* @return 设置后的领地信息
*/ */
public static void setFlag(AbstractOperator operator, String flag, boolean value, String dominionName) { public static void setFlag(AbstractOperator operator, String flag, boolean value, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName); DominionDTO dominion = DominionDTO.select(dominionName);

View File

@ -0,0 +1,218 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.dtos.*;
import java.util.Objects;
import static cn.lunadeer.dominion.utils.ControllerUtils.noAuthToChangeFlags;
import static cn.lunadeer.dominion.utils.ControllerUtils.notOwner;
public class GroupController {
public static void createGroup(AbstractOperator operator, String domName, String groupName, String nameColored) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建权限组 %s 失败", groupName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "创建权限组 %s 成功", groupName);
if (groupName.contains(" ")) {
operator.setResponse(FAIL.addMessage("权限组名称不能包含空格"));
return;
}
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", domName));
return;
}
if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法创建权限组", domName));
return;
}
GroupDTO group = GroupDTO.select(dominion.getId(), groupName);
if (group != null) {
operator.setResponse(FAIL.addMessage("领地 %s 已存在名为 %s 的权限组", domName, groupName));
return;
}
group = GroupDTO.create(nameColored, dominion);
if (group == null) {
operator.setResponse(FAIL.addMessage("请联系服务器管理员"));
return;
}
operator.setResponse(SUCCESS);
}
public static void deleteGroup(AbstractOperator operator, String domName, String groupName) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "删除权限组 %s 失败", groupName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "删除权限组 %s 成功", groupName);
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", domName));
return;
}
if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法删除权限组", domName));
return;
}
GroupDTO group = GroupDTO.select(dominion.getId(), groupName);
if (group == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在名为 %s 的权限组", domName, groupName));
return;
}
group.delete();
operator.setResponse(SUCCESS);
}
public static void setGroupFlag(AbstractOperator operator, String domName, String groupName, String flag, boolean value) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置权限组 %s 的权限 %s 为 %s 失败", groupName, flag, value);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "设置权限组 %s 的权限 %s 为 %s 成功", groupName, flag, value);
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", domName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) {
return;
}
GroupDTO group = GroupDTO.select(dominion.getId(), groupName);
if (group == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在名为 %s 的权限组", domName, groupName));
return;
}
if ((flag.equals("admin") || group.getAdmin()) && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改管理员权限组权限", domName));
return;
}
if (flag.equals("admin")) {
group = group.setAdmin(value);
} else {
Flag f = Flag.getFlag(flag);
if (f == null) {
operator.setResponse(FAIL.addMessage("未知的权限 %s", flag));
return;
}
group = group.setFlagValue(f, value);
}
if (group == null) {
operator.setResponse(FAIL.addMessage("请联系服务器管理员"));
return;
}
operator.setResponse(SUCCESS);
}
public static void renameGroup(AbstractOperator operator, String domName, String oldName, String newName, String nameColored) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "重命名权限组 %s 为 %s 失败", oldName, newName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "重命名权限组 %s 为 %s 成功", oldName, newName);
if (newName.contains(" ")) {
operator.setResponse(FAIL.addMessage("权限组名称不能包含空格"));
return;
}
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", domName));
return;
}
if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法重命名权限组", domName));
return;
}
GroupDTO group = GroupDTO.select(dominion.getId(), oldName);
if (group == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在名为 %s 的权限组", domName, oldName));
return;
}
group = group.setName(nameColored);
if (group == null) {
operator.setResponse(FAIL.addMessage("请联系服务器管理员"));
return;
}
operator.setResponse(SUCCESS);
}
public static void addMember(AbstractOperator operator, String domName, String groupName, String playerName) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "添加成员 %s 到权限组 %s 失败", playerName, groupName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "添加成员 %s 到权限组 %s 成功", playerName, groupName);
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", domName));
return;
}
GroupDTO group = GroupDTO.select(dominion.getId(), groupName);
if (group == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在名为 %s 的权限组", domName, groupName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你没有权限修改领地 %s 的权限组 %s 成员", domName, groupName));
return;
}
if (group.getAdmin() && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法添加成员到管理员权限组", domName));
return;
}
PlayerDTO player = PlayerDTO.select(playerName);
if (player == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不存在", playerName));
return;
}
MemberDTO privilege = MemberDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员,无法直接加入权限组", playerName, domName));
return;
}
if (Objects.equals(privilege.getGroupId(), group.getId())) {
operator.setResponse(FAIL.addMessage("玩家 %s 已在权限组 %s 中", playerName, groupName));
return;
}
if (notOwner(operator, dominion) && privilege.getAdmin()) {
operator.setResponse(FAIL.addMessage("%s 是管理员,你不是领地 %s 的拥有者,无法添加管理员到权限组", playerName, domName));
return;
}
privilege = privilege.setGroupId(group.getId());
if (privilege == null) {
operator.setResponse(FAIL.addMessage("请联系服务器管理员"));
return;
}
operator.setResponse(SUCCESS);
}
public static void removeMember(AbstractOperator operator, String domName, String groupName, String playerName) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "从权限组 %s 移除成员 %s 失败", groupName, playerName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "从权限组 %s 移除成员 %s 成功", groupName, playerName);
DominionDTO dominion = DominionDTO.select(domName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", domName));
return;
}
GroupDTO group = GroupDTO.select(dominion.getId(), groupName);
if (group == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在名为 %s 的权限组", domName, groupName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你没有权限移除领地 %s 的权限组 %s 成员", domName, groupName));
return;
}
if (group.getAdmin() && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法从管理员权限组移除成员", domName));
return;
}
PlayerDTO player = PlayerDTO.select(playerName);
if (player == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不存在", playerName));
return;
}
MemberDTO privilege = MemberDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员", playerName, domName));
return;
}
if (!Objects.equals(privilege.getGroupId(), group.getId())) {
operator.setResponse(FAIL.addMessage("玩家 %s 不在权限组 %s 中", playerName, groupName));
return;
}
privilege = privilege.setGroupId(-1);
if (privilege == null) {
operator.setResponse(FAIL.addMessage("请联系服务器管理员"));
return;
}
operator.setResponse(SUCCESS);
}
}

View File

@ -0,0 +1,160 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.dtos.*;
import static cn.lunadeer.dominion.utils.ControllerUtils.*;
public class MemberController {
/**
* 清空玩家成员权限
*
* @param operator 操作者
* @param player_name 玩家
* @param dominionName 领地名称
*/
public static void memberRemove(AbstractOperator operator, String dominionName, String player_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "将玩家 %s 从领地 %s 移除失败", player_name, dominionName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "将玩家 %s 从领地 %s 移除成功", player_name, dominionName);
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不存在或没有登录过", player_name));
return;
}
MemberDTO privilege = MemberDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员", player_name, dominionName));
return;
}
if (isAdmin(privilege) && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法移除一个领地管理员", dominionName));
return;
}
MemberDTO.delete(player.getUuid(), dominion.getId());
operator.setResponse(SUCCESS);
}
/**
* 设置玩家成员权限
*
* @param operator 操作者
* @param player_name 玩家
* @param flag 权限名称
* @param value 权限值
* @param dominionName 领地名称
*/
public static void setMemberFlag(AbstractOperator operator, String dominionName, String player_name, String flag, boolean value) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置玩家 %s 在领地 %s 的权限 %s 为 %s 失败", player_name, dominionName, flag, value);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "设置玩家 %s 在领地 %s 的权限 %s 为 %s 成功", player_name, dominionName, flag, value);
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不存在或没有登录过", player_name));
return;
}
MemberDTO privilege = MemberDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员", player_name, dominionName));
return;
}
GroupDTO group = GroupDTO.select(privilege.getGroupId());
if (group != null) {
operator.setResponse(FAIL.addMessage("玩家 %s 属于 %s 权限组,无法单独设置权限", player_name, group.getName()));
return;
}
if ((flag.equals("admin") || isAdmin(privilege)) && notOwner(operator, dominion)) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他玩家管理员的权限", dominionName));
return;
}
if (flag.equals("admin")) {
privilege.setAdmin(value);
} else {
Flag f = Flag.getFlag(flag);
if (f == null) {
operator.setResponse(FAIL.addMessage("未知的领地权限 %s", flag));
return;
}
privilege.setFlagValue(f, value);
}
operator.setResponse(SUCCESS);
}
public static void memberAdd(AbstractOperator operator, String dominionName, String player_name) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "将玩家 %s 添加到领地成员 %s 失败", player_name, dominionName);
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "将玩家 %s 添加到领地成员 %s 成功", player_name, dominionName);
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不存在或没有登录过", player_name));
return;
}
if (dominion.getOwner().equals(player.getUuid())) {
operator.setResponse(FAIL.addMessage("玩家 %s 是领地 %s 的拥有者,不可以被添加为成员", player_name, dominionName));
return;
}
MemberDTO privilege = MemberDTO.select(player.getUuid(), dominion.getId());
if (privilege != null) {
operator.setResponse(FAIL.addMessage("玩家 %s 已经是领地 %s 的成员", player_name, dominionName));
return;
}
privilege = MemberDTO.insert(new MemberDTO(player.getUuid(), dominion));
if (privilege == null) {
operator.setResponse(FAIL);
} else {
operator.setResponse(SUCCESS);
}
}
public static void applyTemplate(AbstractOperator operator, String dominionName, String playerName, String templateName) {
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "应用模板 %s 到玩家 %s 在领地 %s 的权限成功", templateName, playerName, dominionName);
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "应用模板 %s 到玩家 %s 在领地 %s 的权限失败", templateName, playerName, dominionName);
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(FAIL.addMessage("领地 %s 不存在", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerDTO.select(playerName);
if (player == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不存在或没有登录过", playerName));
return;
}
MemberDTO privilege = MemberDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
operator.setResponse(FAIL.addMessage("玩家 %s 不是领地 %s 的成员", playerName, dominionName));
return;
}
PrivilegeTemplateDTO template = PrivilegeTemplateDTO.select(operator.getUniqueId(), templateName);
if (template == null) {
operator.setResponse(FAIL.addMessage("模板 %s 不存在", templateName));
return;
}
if (notOwner(operator, dominion) && (isAdmin(privilege) || template.getAdmin())) {
operator.setResponse(FAIL.addMessage("你不是领地 %s 的拥有者,无法修改其他管理员的权限", dominionName));
return;
}
privilege = privilege.applyTemplate(template);
if (privilege == null) {
operator.setResponse(FAIL);
} else {
operator.setResponse(SUCCESS);
}
}
}

View File

@ -2,6 +2,7 @@ package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -20,6 +21,9 @@ public class PlayerController {
} }
public static List<PlayerDTO> allPlayers() { public static List<PlayerDTO> allPlayers() {
return PlayerDTO.all(); List<PlayerDTO> players = PlayerDTO.all();
// 按照名字排序
players.sort(Comparator.comparing(PlayerDTO::getLastKnownName));
return players;
} }
} }

View File

@ -0,0 +1,69 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;
import java.util.List;
public class TemplateController {
public static void createTemplate(AbstractOperator operator, String templateName) {
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "创建成功");
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建失败");
if (templateName.contains(" ")) {
operator.setResponse(FAIL.addMessage("模板名称不能包含空格"));
return;
}
List<PrivilegeTemplateDTO> templates = PrivilegeTemplateDTO.selectAll(operator.getUniqueId());
for (PrivilegeTemplateDTO template : templates) {
if (template.getName().equals(templateName)) {
operator.setResponse(FAIL.addMessage("已经存在名为 %s 的权限模板", templateName));
return;
}
}
PrivilegeTemplateDTO template = PrivilegeTemplateDTO.create(operator.getUniqueId(), templateName);
if (template == null) {
operator.setResponse(FAIL.addMessage("可能是数据库错误,请联系管理员"));
return;
}
operator.setResponse(SUCCESS.addMessage("成功创建名为 %s 的权限模板", templateName));
}
public static void deleteTemplate(AbstractOperator operator, String templateName) {
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "删除成功");
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "删除失败");
PrivilegeTemplateDTO template = PrivilegeTemplateDTO.select(operator.getUniqueId(), templateName);
if (template == null) {
operator.setResponse(FAIL.addMessage("模板不存在"));
return;
}
if (!template.getCreator().equals(operator.getUniqueId())) {
operator.setResponse(FAIL.addMessage("这不是你的模板"));
return;
}
PrivilegeTemplateDTO.delete(operator.getUniqueId(), templateName);
operator.setResponse(SUCCESS);
}
public static void setTemplateFlag(AbstractOperator operator, String templateName, String flag_name, boolean value) {
AbstractOperator.Result SUCCESS = new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "设置成功");
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置失败");
PrivilegeTemplateDTO template = PrivilegeTemplateDTO.select(operator.getUniqueId(), templateName);
if (template == null) {
operator.setResponse(FAIL.addMessage("模板不存在"));
return;
}
if (flag_name.equals("admin")) {
template.setAdmin(value);
} else {
Flag f = Flag.getFlag(flag_name);
if (f == null) {
operator.setResponse(FAIL.addMessage("未知的权限 %s", flag_name));
return;
}
template.setFlagValue(f, value);
}
operator.setResponse(SUCCESS.addMessage("成功设置模板 " + template.getName() + " 的权限 " + flag_name + "" + value));
}
}

View File

@ -0,0 +1,51 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.Objects;
import static cn.lunadeer.dominion.utils.CommandUtils.autoPoints;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class CreateDominion {
private static class createDominionCB implements CuiTextInput.InputCallback {
private final Player sender;
public createDominionCB(Player sender) {
this.sender = sender;
}
@Override
public void handleData(String input) {
XLogger.debug("createDominionCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
Map<Integer, Location> points = autoPoints(sender);
operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), AbstractOperator.Result.SUCCESS)) {
DominionManage.show(sender, new String[]{"list"});
}
});
DominionController.create(operator, input, points.get(0), points.get(1));
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
CuiTextInput.InputCallback createDominionCB = new createDominionCB(player);
CuiTextInput view = CuiTextInput.create(createDominionCB).setText("未命名领地").title("输入要创建的领地名称");
view.setSuggestCommand("/dominion auto_create <领地名称>");
view.open(player);
}
}

View File

@ -0,0 +1,51 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.GroupController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.dominion.manage.group.GroupList;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class CreateGroup {
private static class createGroupCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public createGroupCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("createGroupCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
GroupController.createGroup(operator, dominionName, ColorParser.getPlainText(input), input);
GroupList.show(sender, dominionName);
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback createGroupCB = new createGroupCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(createGroupCB).setText("未命名权限组").title("输入要创建的权限组名称");
view.setSuggestCommand("/dominion group create <领地名称> <权限组名称>");
view.open(player);
}
}

View File

@ -0,0 +1,40 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.TemplateController;
import cn.lunadeer.dominion.tuis.template.TemplateList;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class CreateTemplate {
private static class createTemplateCB implements CuiTextInput.InputCallback {
private final Player sender;
public createTemplateCB(Player sender) {
this.sender = sender;
}
@Override
public void handleData(String input) {
XLogger.debug("createTemplateCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
TemplateController.createTemplate(operator, input);
TemplateList.show(sender);
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
CuiTextInput.InputCallback createTemplateCB = new createTemplateCB(player);
CuiTextInput view = CuiTextInput.create(createTemplateCB).setText("未命名模板").title("输入模板名称");
view.setSuggestCommand("/dominion template create <模板名称>");
view.open(player);
}
}

View File

@ -0,0 +1,48 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class EditJoinMessage {
private static class editJoinMessageCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public editJoinMessageCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("editJoinMessageCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.setJoinMessage(operator, input, dominionName);
DominionManage.show(sender, new String[]{"manage", dominionName});
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback editJoinMessageCB = new editJoinMessageCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(editJoinMessageCB).setText(dominion.getJoinMessage()).title("编辑欢迎提示语");
view.setSuggestCommand("/dominion set_enter_msg <提示语> [领地名称]");
view.open(player);
}
}

View File

@ -0,0 +1,48 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class EditLeaveMessage {
private static class editLeaveMessageCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public editLeaveMessageCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("editLeaveMessageCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.setLeaveMessage(operator, input, dominionName);
DominionManage.show(sender, new String[]{"manage", dominionName});
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback editLeaveMessageCB = new editLeaveMessageCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(editLeaveMessageCB).setText(dominion.getLeaveMessage()).title("编辑离开提示语");
view.setSuggestCommand("/dominion set_leave_msg <提示语> [领地名称]");
view.open(player);
}
}

View File

@ -0,0 +1,59 @@
package cn.lunadeer.dominion.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.tuis.dominion.manage.member.MemberList;
import cn.lunadeer.dominion.tuis.dominion.manage.member.SelectPlayer;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Objects;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class MemberAdd {
private static class memberAddCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public memberAddCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("createPrivilegeCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), AbstractOperator.Result.SUCCESS)) {
MemberList.show(sender, dominionName);
} else {
SelectPlayer.show(sender, dominionName, 1);
}
});
MemberController.memberAdd(operator, dominionName, input);
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback createPrivilegeCB = new memberAddCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(createPrivilegeCB).setText("Steve").title("输入玩家名称以添加为成员");
view.setSuggestCommand("/dominion member add <领地名称> <玩家名称>");
view.open(player);
}
}

View File

@ -0,0 +1,41 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class RenameDominion {
private static class renameDominionCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String oldName;
public renameDominionCB(Player sender, String oldName) {
this.sender = sender;
this.oldName = oldName;
}
@Override
public void handleData(String input) {
XLogger.debug("renameDominionCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.rename(operator, oldName, input);
DominionManage.show(sender, new String[]{"manage", input});
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
CuiTextInput.InputCallback renameDominionCB = new renameDominionCB(player, args[1]);
CuiTextInput view = CuiTextInput.create(renameDominionCB).setText(args[1]).title("领地重命名");
view.setSuggestCommand("/dominion rename <原领地名称> <新领地名称>");
view.open(player);
}
}

View File

@ -0,0 +1,53 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.GroupController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.dominion.manage.group.GroupSetting;
import cn.lunadeer.minecraftpluginutils.ColorParser;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class RenameGroup {
private static class renameGroupCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
private final String oldName;
public renameGroupCB(Player sender, String dominionName, String oldName) {
this.sender = sender;
this.dominionName = dominionName;
this.oldName = oldName;
}
@Override
public void handleData(String input) {
XLogger.debug("renameGroupCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
GroupController.renameGroup(operator, dominionName, oldName, ColorParser.getPlainText(input), input);
GroupSetting.show(sender, dominionName, ColorParser.getPlainText(input));
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback renameGroupCB = new renameGroupCB(player, dominion.getName(), args[2]);
CuiTextInput view = CuiTextInput.create(renameGroupCB).setText(args[2]).title("输入新的权限组名称");
view.setSuggestCommand("/dominion group rename <领地名称> <权限组旧名称> <新名称>");
view.open(player);
}
}

View File

@ -0,0 +1,49 @@
package cn.lunadeer.dominion.cuis;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.dominion.DominionManage;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class SetMapColor {
private static class setMapColorCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public setMapColorCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("editLeaveMessageCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.setMapColor(operator, input, dominionName);
DominionManage.show(sender, new String[]{"manage", dominionName});
}
}
public static void open(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback setMapColorCB = new SetMapColor.setMapColorCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(setMapColorCB).setText(dominion.getColor()).title("输入卫星地图地块颜色16进制");
view.setSuggestCommand("/dominion set_map_color <颜色> [领地名称]");
view.open(player);
}
}

View File

@ -0,0 +1,445 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.FieldType;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class DominionDTO {
private static List<DominionDTO> query(String sql, Object... args) {
List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, args)) {
return getDTOFromRS(rs);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("数据库操作失败: ", e, sql);
}
return dominions;
}
private static List<DominionDTO> getDTOFromRS(ResultSet rs) throws SQLException {
List<DominionDTO> dominions = new ArrayList<>();
if (rs == null) return dominions;
while (rs.next()) {
Integer id = rs.getInt("id");
UUID owner = UUID.fromString(rs.getString("owner"));
String name = rs.getString("name");
UUID world_uid = UUID.fromString(rs.getString("world_uid"));
Integer x1 = rs.getInt("x1");
Integer y1 = rs.getInt("y1");
Integer z1 = rs.getInt("z1");
Integer x2 = rs.getInt("x2");
Integer y2 = rs.getInt("y2");
Integer z2 = rs.getInt("z2");
Integer parentDomId = rs.getInt("parent_dom_id");
String tp_location = rs.getString("tp_location");
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getDominionFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
String color = rs.getString("color");
DominionDTO dominion = new DominionDTO(id, owner, name, world_uid, x1, y1, z1, x2, y2, z2, parentDomId,
rs.getString("join_message"),
rs.getString("leave_message"),
flags,
tp_location,
color
);
dominions.add(dominion);
}
return dominions;
}
public static List<DominionDTO> selectAll() {
String sql = "SELECT * FROM dominion WHERE id > 0;";
return query(sql);
}
public static List<DominionDTO> search(String name) {
String sql = "SELECT * FROM dominion WHERE name LIKE ? AND id > 0;";
return query(sql, "%" + name + "%");
}
public static List<DominionDTO> selectByOwner(UUID owner) {
String sql = "SELECT * FROM dominion WHERE owner = ? AND id > 0 ORDER BY id DESC;";
return query(sql, owner.toString());
}
public static DominionDTO select(Integer id) {
if (id == -1) {
return new DominionDTO(-1,
UUID.fromString("00000000-0000-0000-0000-000000000000"),
"根领地", UUID.fromString("00000000-0000-0000-0000-000000000000"),
-2147483648, -2147483648, -2147483648,
2147483647, 2147483647, 2147483647, -1);
}
String sql = "SELECT * FROM dominion WHERE id = ? AND id > 0;";
List<DominionDTO> dominions = query(sql, id);
if (dominions.isEmpty()) return null;
return dominions.getFirst();
}
public static List<DominionDTO> selectByParentId(World world, Integer parentId){
return selectByParentId(world.getUID(), parentId);
}
public static List<DominionDTO> selectByParentId(UUID world_uid, Integer parentId) {
String sql = "SELECT * FROM dominion WHERE world_uid = ? AND parent_dom_id = ? AND id > 0;";
return query(sql, world_uid.toString(), parentId);
}
public static List<DominionDTO> selectByLocation(UUID world_uid, Integer x, Integer y, Integer z) {
String sql = "SELECT * FROM dominion WHERE world_uid = ? AND " +
"x1 <= ? AND x2 >= ? AND " +
"y1 <= ? AND y2 >= ? AND " +
"z1 <= ? AND z2 >= ? AND " + "id > 0;";
return query(sql, world_uid.toString(), x, x, y, y, z, z);
}
public static DominionDTO select(String name) {
String sql = "SELECT * FROM dominion WHERE name = ? AND id > 0;";
List<DominionDTO> dominions = query(sql, name);
if (dominions.isEmpty()) return null;
return dominions.getFirst();
}
public static DominionDTO insert(DominionDTO dominion) {
InsertRow insert = new InsertRow().returningAll().table("dominion").onConflictDoNothing(new Field("id", null));
insert.field(dominion.owner)
.field(dominion.name)
.field(dominion.world_uid)
.field(dominion.x1).field(dominion.y1).field(dominion.z1)
.field(dominion.x2).field(dominion.y2).field(dominion.z2)
.field(dominion.parentDomId)
.field(dominion.joinMessage).field(dominion.leaveMessage)
.field(dominion.tp_location);
for (Flag f : Flag.getDominionFlagsEnabled()) {
insert.field(new Field(f.getFlagName(), f.getDefaultValue()));
}
try (ResultSet rs = insert.execute()) {
Cache.instance.loadDominions();
List<DominionDTO> dominions = getDTOFromRS(rs);
if (dominions.isEmpty()) return null;
return dominions.getFirst();
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("数据库操作失败: ", e, insert.toString());
return null;
}
}
public static void delete(DominionDTO dominion) {
String sql = "DELETE FROM dominion WHERE id = ?;";
query(sql, dominion.getId());
Cache.instance.loadDominions();
}
private DominionDTO(Integer id, UUID owner, String name, UUID world_uid,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId,
String joinMessage, String leaveMessage,
Map<Flag, Boolean> flags,
String tp_location,
String color) {
this.id.value = id;
this.owner.value = owner.toString();
this.name.value = name;
this.world_uid.value = world_uid.toString();
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
this.parentDomId.value = parentDomId;
this.joinMessage.value = joinMessage;
this.leaveMessage.value = leaveMessage;
this.flags.putAll(flags);
this.tp_location.value = tp_location;
this.color.value = color;
}
private DominionDTO(Integer id, UUID owner, String name, UUID world_uid,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId) {
this.id.value = id;
this.owner.value = owner.toString();
this.name.value = name;
this.world_uid.value = world_uid.toString();
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
this.parentDomId.value = parentDomId;
}
public DominionDTO(UUID owner, String name, @NotNull World world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this(null, owner, name, world.getUID(), x1, y1, z1, x2, y2, z2, -1);
}
public static DominionDTO create(UUID owner, String name, @NotNull World world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2, DominionDTO parent) {
return new DominionDTO(null, owner, name, world.getUID(), x1, y1, z1, x2, y2, z2, parent == null ? -1 : parent.getId());
}
private final Field id = new Field("id", FieldType.INT);
private final Field owner = new Field("owner", FieldType.STRING);
private final Field name = new Field("name", FieldType.STRING);
private final Field x1 = new Field("x1", FieldType.INT);
private final Field y1 = new Field("y1", FieldType.INT);
private final Field z1 = new Field("z1", FieldType.INT);
private final Field x2 = new Field("x2", FieldType.INT);
private final Field y2 = new Field("y2", FieldType.INT);
private final Field z2 = new Field("z2", FieldType.INT);
private final Field parentDomId = new Field("parent_dom_id", -1);
private final Field joinMessage = new Field("join_message", "欢迎来到 ${DOM_NAME}");
private final Field leaveMessage = new Field("leave_message", "你正在离开 ${DOM_NAME},欢迎下次光临~");
private final Map<Flag, Boolean> flags = new HashMap<>();
private final Field tp_location = new Field("tp_location", "default");
private final Field color = new Field("color", "#00BFFF");
private final Field world_uid = new Field("world_uid", FieldType.STRING);
// getters and setters
public Integer getId() {
return (Integer) id.value;
}
public UUID getOwner() {
return UUID.fromString((String) owner.value);
}
private DominionDTO doUpdate(UpdateRow updateRow) {
updateRow.returningAll(id)
.table("dominion")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<DominionDTO> dominions = getDTOFromRS(rs);
if (dominions.isEmpty()) return null;
Cache.instance.loadDominions((Integer) id.value);
return dominions.getFirst();
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("更新领地信息失败: ", e, updateRow.toString());
return null;
}
}
public DominionDTO setOwner(UUID owner) {
this.owner.value = owner.toString();
return doUpdate(new UpdateRow().field(this.owner));
}
public String getName() {
return (String) name.value;
}
public DominionDTO setName(String name) {
this.name.value = name;
return doUpdate(new UpdateRow().field(this.name));
}
public @Nullable World getWorld() {
return Dominion.instance.getServer().getWorld(getWorldUid());
}
public UUID getWorldUid() {
return UUID.fromString((String) world_uid.value);
}
public Integer getX1() {
return (Integer) x1.value;
}
public DominionDTO setX1(Integer x1) {
this.x1.value = x1;
return doUpdate(new UpdateRow().field(this.x1));
}
public Integer getY1() {
return (Integer) y1.value;
}
public DominionDTO setY1(Integer y1) {
this.y1.value = y1;
return doUpdate(new UpdateRow().field(this.y1));
}
public Integer getZ1() {
return (Integer) z1.value;
}
public DominionDTO setZ1(Integer z1) {
this.z1.value = z1;
return doUpdate(new UpdateRow().field(this.z1));
}
public Integer getX2() {
return (Integer) x2.value;
}
public DominionDTO setX2(Integer x2) {
this.x2.value = x2;
return doUpdate(new UpdateRow().field(this.x2));
}
public Integer getY2() {
return (Integer) y2.value;
}
public DominionDTO setY2(Integer y2) {
this.y2.value = y2;
return doUpdate(new UpdateRow().field(this.y2));
}
public Integer getZ2() {
return (Integer) z2.value;
}
public DominionDTO setZ2(Integer z2) {
this.z2.value = z2;
return doUpdate(new UpdateRow().field(this.z2));
}
public Integer getSquare() {
return getWidthX() * getWidthZ();
}
public Integer getVolume() {
return getSquare() * getHeight();
}
public Integer getWidthX() {
return getX2() - getX1();
}
public Integer getHeight() {
return getY2() - getY1();
}
public Integer getWidthZ() {
return getZ2() - getZ1();
}
public Integer getParentDomId() {
return (Integer) parentDomId.value;
}
public String getJoinMessage() {
return (String) joinMessage.value;
}
public DominionDTO setJoinMessage(String joinMessage) {
this.joinMessage.value = joinMessage;
return doUpdate(new UpdateRow().field(this.joinMessage));
}
public String getLeaveMessage() {
return (String) leaveMessage.value;
}
public DominionDTO setLeaveMessage(String leaveMessage) {
this.leaveMessage.value = leaveMessage;
return doUpdate(new UpdateRow().field(this.leaveMessage));
}
public Boolean getFlagValue(Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public DominionDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value);
Field flagField = new Field(flag.getFlagName(), value);
return doUpdate(new UpdateRow().field(flagField));
}
public DominionDTO setXYZ(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this.x1.value = x1;
this.y1.value = y1;
this.z1.value = z1;
this.x2.value = x2;
this.y2.value = y2;
this.z2.value = z2;
return doUpdate(new UpdateRow().field(this.x1).field(this.y1).field(this.z1).field(this.x2).field(this.y2).field(this.z2));
}
public DominionDTO setXYZ(int[] cords) {
if (cords.length == 6) {
return setXYZ(cords[0], cords[1], cords[2], cords[3], cords[4], cords[5]);
} else {
XLogger.warn("领地坐标数据异常: %s", (Object) cords);
return null;
}
}
public Location getTpLocation() {
if (Objects.equals(tp_location.value, "default")) {
return null;
} else {
// 0:0:0
String[] loc = ((String) tp_location.value).split(":");
World w = getWorld();
if (loc.length == 3 && w != null) {
return new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
} else {
XLogger.warn("领地传送点数据异常: %s", tp_location);
XLogger.debug("world: %s, loc.length: %d", getWorld(), loc.length);
return null;
}
}
}
public DominionDTO setTpLocation(Location loc) {
this.tp_location.value = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
return doUpdate(new UpdateRow().field(tp_location));
}
public Location getLocation1() {
return new Location(getWorld(), getX1(), getY1(), getZ1());
}
public Location getLocation2() {
return new Location(getWorld(), getX2(), getY2(), getZ2());
}
public DominionDTO setColor(String color) {
this.color.value = color;
return doUpdate(new UpdateRow().field(this.color));
}
public int getColorR() {
return Integer.valueOf(getColor().substring(1, 3), 16);
}
public int getColorG() {
return Integer.valueOf(getColor().substring(3, 5), 16);
}
public int getColorB() {
return Integer.valueOf(getColor().substring(5, 7), 16);
}
public String getColor() {
return (String) color.value;
}
public int getColorHex() {
return (getColorR() << 16) + (getColorG() << 8) + getColorB();
}
}

View File

@ -6,32 +6,38 @@ import cn.lunadeer.minecraftpluginutils.XLogger;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import java.io.File; import java.io.File;
import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
public enum Flag { public enum Flag {
ANCHOR("anchor", "重生锚", "是否允许设置重生锚", false, false, true), ANCHOR("anchor", "重生锚", "是否允许设置重生锚", false, false, true),
ANIMAL_KILLING("animal_killing", "对动物造成伤害", "是否允许对动物造成伤害", false, false, true), ANIMAL_KILLING("animal_killing", "对动物造成伤害", "是否允许对动物造成伤害", false, false, true),
ANIMAL_SPAWN("animal_spawn", "动物生成", "是否允许动物生成", true, true, false), ANIMAL_SPAWN("animal_spawn", "动物生成(繁殖)", "是否允许动物生成(包括繁殖)", true, true, false),
ANVIL("anvil", "使用铁砧", "是否允许使用铁砧", false, false, true), ANVIL("anvil", "使用铁砧", "是否允许使用铁砧", false, false, true),
BEACON("beacon", "信标交互", "是否允许与信标交互", false, false, true), BEACON("beacon", "信标交互", "是否允许与信标交互", false, false, true),
BED("bed", "床交互", "是否允许使用床睡觉或设置重生点", false, false, true), BED("bed", "床交互", "是否允许使用床睡觉或设置重生点", false, false, true),
BREW("brew", "使用酿造台", "是否可以使用酿造台", false, false, true), BREW("brew", "使用酿造台", "是否可以使用酿造台", false, false, true),
BREAK_BLOCK("break", "破坏方块", "是否可以破坏方块(包括:一般方块、展示框", false, false, true), BREAK_BLOCK("break", "破坏方块", "是否可以破坏方块(包括:一般方块、展示框、盔甲架", false, false, true),
BUTTON("button", "使用按钮", "是否可以使用各种材质的按钮", false, false, true), BUTTON("button", "使用按钮", "是否可以使用各种材质的按钮", false, false, true),
CAKE("cake", "吃蛋糕", "是否可以吃蛋糕", false, false, true), CAKE("cake", "吃蛋糕", "是否可以吃蛋糕", false, false, true),
CONTAINER("container", "一般容器", "包含:箱子/木桶/潜影盒/盔甲架/展示框", false, false, true), CONTAINER("container", "一般容器", "包含:箱子/木桶/潜影盒/盔甲架/展示框", false, false, true),
CRAFT("craft", "使用工作台", "是否可以使用工作台", false, false, true), CRAFT("craft", "使用工作台", "是否可以使用工作台", false, false, true),
CREEPER_EXPLODE("creeper_explode", "实体爆炸", "包含:苦力怕/凋零头颅/水晶爆炸", false, true, true), CRAFTER("crafter", "合成器", "是否可以修改自动合成器", false, false, true),
COMPARER("comparer", "比较器交互", "是否可以与比较器交互", false, false, true), CREEPER_EXPLODE("creeper_explode", "生物破坏", "包含:苦力怕/凋零头颅/末影水晶/火球爆炸等", false, true, true),
DOOR("door", "门交互", "是否可以使用各种材质的门", false, false, true), COMPARER("comparer", "比较器交互", "是否可以修改比较器状态", false, false, true),
DYE("dye", "染色", "是否可以使用染料染色", false, false, true), DOOR("door", "门交互", "是否可以使用各种材质的门(包括活板门)", false, false, true),
DRAGON_BREAK_BLOCK("dragon_break_block", "末影龙破坏方块", "末影龙冲撞是否可以破坏方块", false, true, true),
DRAGON_EGG("dragon_egg", "触碰龙蛋", "是否可以触碰龙蛋", false, false, true),
DYE("dye", "染色", "是否可以使用染料(对羊、狗项圈、猫项圈)染色", false, false, true),
EDIT_SIGN("edit_sign", "编辑告示牌", "是否可以编辑告示牌", false, false, true),
EGG("egg", "扔鸡蛋", "是否可以扔鸡蛋", false, false, true), EGG("egg", "扔鸡蛋", "是否可以扔鸡蛋", false, false, true),
ENCHANT("enchant", "使用附魔台", "是否可以使用附魔台", false, false, true), ENCHANT("enchant", "使用附魔台", "是否可以使用附魔台", false, false, true),
ENDER_MAN("ender_man", "末影人行为", "包含:末影人是否可以生成、瞬移", false, true, true), ENDER_MAN("ender_man", "末影人行为", "包含:末影人是否可以生成、瞬移", false, true, true),
ENDER_PEARL("ender_pearl", "投掷末影珍珠", "是否可以使用末影珍珠", false, false, true), ENDER_PEARL("ender_pearl", "投掷末影珍珠", "是否可以使用末影珍珠", false, false, true),
FEED("feed", "喂养", "是否可以喂养动物", false, false, true), FEED("feed", "喂养动物", "是否可以喂养动物", false, false, true),
FIRE_SPREAD("fire_spread", "火焰蔓延", "是否可以火焰蔓延", false, true, true), FIRE_SPREAD("fire_spread", "火焰蔓延", "是否可以火焰蔓延", false, true, true),
FLOW_IN_PROTECTION("flow_in_protection", "外部流体是否可以进入", "包含:岩浆、水(不会阻止领地内部的流体蔓延)", false, true, true), FLOW_IN_PROTECTION("flow_in_protection", "外部流体是否可以进入", "包含:岩浆、水(不会阻止领地内部的流体蔓延)", false, true, true),
FLY("fly", "飞行", "不是翅鞘飞行,是类似于创造模式的飞行", false, false, false), FLY("fly", "飞行", "不是翅鞘飞行,是类似于创造模式的飞行", false, false, false),
@ -39,26 +45,36 @@ public enum Flag {
HARVEST("harvest", "收获", "收获庄稼、作物", false, false, true), HARVEST("harvest", "收获", "收获庄稼、作物", false, false, true),
HONEY("honey", "蜂巢交互", "是否可以采蜂蜜", false, false, true), HONEY("honey", "蜂巢交互", "是否可以采蜂蜜", false, false, true),
HOOK("hook", "使用钓钩", "是否可以使用钓钩", false, false, true), HOOK("hook", "使用钓钩", "是否可以使用钓钩", false, false, true),
HOPPER("hopper", "特殊容器", "包含:漏斗/熔炉/发射器等", false, false, true), HOPPER("hopper", "特殊容器", "包含:漏斗/熔炉/发射器/投掷器/高炉/烟熏炉", false, false, true),
HOPPER_OUTSIDE("hopper_outside", "领地外漏斗对领地内箱子是否生效", "领地外的漏斗是否可以对领地内的箱子生效", false, true, true),
IGNITE("ignite", "点燃", "是否可以使用打火石点火", false, false, true), IGNITE("ignite", "点燃", "是否可以使用打火石点火", false, false, true),
ITEM_FRAME_INTERACTIVE("item_frame_interactive", "展示框交互", "是否可以与物品展示框交互(旋转展示框的东西)", false, false, true),
ITEM_FRAME_PROJ_DAMAGE("item_frame_proj_damage", "投掷物是否可以破坏展示框/画", "非玩家发出的投掷物是否可以破坏展示框/画等悬挂物", false, true, true),
LEVER("lever", "使用拉杆", "是否可以使用拉杆", false, false, true), LEVER("lever", "使用拉杆", "是否可以使用拉杆", false, false, true),
MOB_DROP_ITEM("mob_drop_item", "生物战利品掉落", "生物死亡时是否产生凋落物", true, true, true), MOB_DROP_ITEM("mob_drop_item", "生物战利品掉落", "生物死亡时是否产生落物", true, true, true),
MONSTER_KILLING("monster_killing", "对怪物造成伤害", "玩家是否可以对怪物造成伤害", false, false, true), MONSTER_KILLING("monster_killing", "对怪物造成伤害", "玩家是否可以对怪物造成伤害", false, false, true),
MONSTER_SPAWN("monster_spawn", "怪物生成", "是否可以生成怪物", false, true, false), MONSTER_SPAWN("monster_spawn", "怪物生成", "是否可以生成怪物", false, true, false),
MOVE("move", "移动", "是否可以移动", true, false, true), MOVE("move", "移动", "是否可以移动", true, false, true),
NOTE_BLOCK("note_block", "点击音符盒", "红石音乐或者某些红石机器会用到...", false, false, true),
PLACE("place", "放置方块", "是否可以放置方块(包括:一般方块、展示框、岩浆、水)", false, false, true), PLACE("place", "放置方块", "是否可以放置方块(包括:一般方块、展示框、岩浆、水)", false, false, true),
PISTON_OUTSIDE("piston_outside", "活塞是否可以跨领地推动方块", "活塞是否可以往领地内推东西或推东西到领地外", false, true, true),
PRESSURE("pressure", "压力板交互", "是否可以触发各种材质的压力板", false, false, true), PRESSURE("pressure", "压力板交互", "是否可以触发各种材质的压力板", false, false, true),
RIDING("riding", "骑乘载具", "是否可以骑乘各种载具", false, false, true), RIDING("riding", "骑乘载具", "是否可以骑乘各种载具", false, false, true),
REPEATER("repeater", "中继器交互", "是否可以与中继器交互", false, false, true), REPEATER("repeater", "中继器交互", "是否可以与中继器交互", false, false, true),
SHEAR("shear", "剪羊毛", "是否可以剪羊毛", false, false, true), SHEAR("shear", "剪羊毛", "是否可以剪羊毛", false, false, true),
SHOOT("shoot", "发射类型武器", "包括:射箭/雪球/三叉戟", false, false, true), SHOOT("shoot", "投掷型武器", "包括:射箭/雪球/三叉戟/风弹", false, false, true),
SHOW_BORDER("show_border", "显示领地边界", "是否显示领地边界", false, true, true), SHOW_BORDER("show_border", "显示领地边界", "是否显示领地边界", true, true, true),
TELEPORT("teleport", "领地传送", "是否开启领地传送", false, false, true), TELEPORT("teleport", "领地传送", "是否开启领地传送", false, false, true),
TNT_EXPLODE("tnt_explode", "TNT爆炸", "TNT是否可以爆炸", false, true, true), TNT_EXPLODE("tnt_explode", "TNT爆炸", "TNT是否可以爆炸", false, true, true),
TRADE("trade", "村民交易", "是否可以与村民交易", false, false, true), TRADE("trade", "村民交易", "是否可以与村民交易", false, false, true),
TRAMPLE("trample", "作物践踏", "是否可以践踏作物(关闭意味着保护耕地)", false, true, true), TRAMPLE("trample", "作物践踏", "是否可以践踏作物(关闭意味着保护耕地)", false, true, true),
TRIG_PRESSURE_PROJ("trig_pressure_proj", "投掷物触发压力板", "投掷物(箭/风弹/雪球)是否可以触发压力板", false, true, true),
TRIG_PRESSURE_MOB("trig_pressure_mob", "生物触发压力板", "生物(不包含玩家)是否可以触发压力板", false, true, true),
TRIG_PRESSURE_DROP("trig_pressure_drop", "掉落物触发压力板", "掉落物是否可以触发压力板", false, true, true),
VEHICLE_DESTROY("vehicle_destroy", "破坏载具", "是否可以破坏载具(主要是矿车)", false, false, true), VEHICLE_DESTROY("vehicle_destroy", "破坏载具", "是否可以破坏载具(主要是矿车)", false, false, true),
VEHICLE_SPAWN("vehicle_spawn", "生成载具", "是否可以生成载具(主要是矿车)", false, false, true), VEHICLE_SPAWN("vehicle_spawn", "生成载具", "是否可以生成载具(主要是矿车)", false, false, true),
VILLAGER_KILLING("villager_killing", "对村民造成伤害", "是否可以对村民造成伤害", false, false, true),
VILLAGER_SPAWN("villager_spawn", "村民繁殖", "是否允许村民繁殖(包括村民蛋)", true, true, true),
WITHER_SPAWN("wither_spawn", "凋零生成", "凋零生成", false, true, true), WITHER_SPAWN("wither_spawn", "凋零生成", "凋零生成", false, true, true),
; ;
private final String flag_name; private final String flag_name;
@ -117,6 +133,26 @@ public enum Flag {
return Arrays.asList(Flag.values()); return Arrays.asList(Flag.values());
} }
public static List<Flag> getDominionOnlyFlagsEnabled() {
List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) {
if (!flag.dominion_only) {
continue;
}
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> getDominionFlagsEnabled() { public static List<Flag> getDominionFlagsEnabled() {
List<Flag> flags = new ArrayList<>(); List<Flag> flags = new ArrayList<>();
for (Flag flag : Flag.values()) { for (Flag flag : Flag.values()) {
@ -125,6 +161,8 @@ public enum Flag {
} }
flags.add(flag); flags.add(flag);
} }
Comparator<Object> comparator = Collator.getInstance(java.util.Locale.CHINA);
flags.sort((o1, o2) -> comparator.compare(o1.getDisplayName(), o2.getDisplayName()));
return flags; return flags;
} }
@ -144,6 +182,8 @@ public enum Flag {
} }
flags.add(flag); flags.add(flag);
} }
Comparator<Object> comparator = Collator.getInstance(java.util.Locale.CHINA);
flags.sort((o1, o2) -> comparator.compare(o1.getDisplayName(), o2.getDisplayName()));
return flags; return flags;
} }
@ -173,17 +213,25 @@ public enum Flag {
} }
*/ */
public static void loadFromJson() { public static JSONObject serializeToJson(Flag flag) {
try { JSONObject json = new JSONObject();
File flagFile = new File(Dominion.instance.getDataFolder(), "flags.json"); json.put("display_name", flag.getDisplayName());
if (!flagFile.exists()) { json.put("description", flag.getDescription());
saveToJson(); json.put("default_value", flag.getDefaultValue());
json.put("enable", flag.getEnable());
return json;
} }
JSONObject jsonObject = JsonFile.loadFromFile(flagFile);
if (jsonObject == null) { public static JSONObject serializeToJson() {
XLogger.warn("读取权限配置失败,已重置"); JSONObject json = new JSONObject();
saveToJson(); for (Flag flag : getAllFlags()) {
JSONObject flagJson = serializeToJson(flag);
json.put(flag.getFlagName(), flagJson);
} }
return json;
}
public static void deserializeFromJson(JSONObject jsonObject) {
for (Flag flag : getAllFlags()) { for (Flag flag : getAllFlags()) {
try { try {
JSONObject flagJson = (JSONObject) jsonObject.get(flag.getFlagName()); JSONObject flagJson = (JSONObject) jsonObject.get(flag.getFlagName());
@ -197,6 +245,20 @@ public enum Flag {
XLogger.warn("读取权限 %s 配置失败:%s已跳过", flag.getFlagName(), e.getMessage()); XLogger.warn("读取权限 %s 配置失败:%s已跳过", flag.getFlagName(), e.getMessage());
} }
} }
}
public static void loadFromJson() {
try {
File flagFile = new File(Dominion.instance.getDataFolder(), "flags.json");
if (!flagFile.exists()) {
saveToJson();
}
JSONObject jsonObject = JsonFile.loadFromFile(flagFile);
if (jsonObject == null) {
XLogger.warn("读取权限配置失败,已重置");
saveToJson();
}
deserializeFromJson(jsonObject);
saveToJson(); // 复写一遍确保文件中包含所有权限 saveToJson(); // 复写一遍确保文件中包含所有权限
} catch (Exception e) { } catch (Exception e) {
XLogger.err("读取权限配置失败:%s", e.getMessage()); XLogger.err("读取权限配置失败:%s", e.getMessage());
@ -205,15 +267,7 @@ public enum Flag {
public static void saveToJson() { public static void saveToJson() {
try { try {
JSONObject json = new JSONObject(); JSONObject json = serializeToJson();
for (Flag f : getAllFlags()) {
JSONObject flagJson = new JSONObject();
flagJson.put("display_name", f.getDisplayName());
flagJson.put("description", f.getDescription());
flagJson.put("default_value", f.getDefaultValue());
flagJson.put("enable", f.enable);
json.put(f.getFlagName(), flagJson);
}
XLogger.debug("保存权限配置:%s", json.toJSONString()); XLogger.debug("保存权限配置:%s", json.toJSONString());
File flagFile = new File(Dominion.instance.getDataFolder(), "flags.json"); File flagFile = new File(Dominion.instance.getDataFolder(), "flags.json");
JsonFile.saveToFile(json, flagFile); JsonFile.saveToFile(json, flagFile);

View File

@ -0,0 +1,208 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.ColorParser;
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 net.kyori.adventure.text.Component;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GroupDTO {
Field id = new Field("id", FieldType.INT);
Field domID = new Field("dom_id", FieldType.INT);
Field name = new Field("name", FieldType.STRING);
Field admin = new Field("admin", FieldType.BOOLEAN);
Field name_colored = new Field("name_colored", FieldType.STRING);
private final Map<Flag, Boolean> flags = new HashMap<>();
public Integer getId() {
return (Integer) id.value;
}
public Integer getDomID() {
return (Integer) domID.value;
}
public String getName() {
return (String) name.value;
}
public Component getNameColoredComponent() {
String with_pre_suf = "&#ffffff" +
Dominion.config.getGroupTitlePrefix() +
(String) name_colored.value +
"&#ffffff" +
Dominion.config.getGroupTitleSuffix();
return ColorParser.getComponentType(with_pre_suf);
}
public String getNameColoredBukkit() {
String with_pre_suf = "&#ffffff" +
Dominion.config.getGroupTitlePrefix() +
(String) name_colored.value +
"&#ffffff" +
Dominion.config.getGroupTitleSuffix();
return ColorParser.getBukkitType(with_pre_suf);
}
public Boolean getAdmin() {
return (Boolean) admin.value;
}
public Boolean getFlagValue(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);
return doUpdate(updateRow);
}
public GroupDTO setAdmin(Boolean admin) {
this.admin.value = admin;
UpdateRow updateRow = new UpdateRow().field(this.admin);
return doUpdate(updateRow);
}
public GroupDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value);
Field f = new Field(flag.getFlagName(), value);
UpdateRow updateRow = new UpdateRow().field(f);
return doUpdate(updateRow);
}
public static GroupDTO create(String name, DominionDTO dominionDTO) {
GroupDTO group = new GroupDTO(name, dominionDTO.getId());
InsertRow insertRow = new InsertRow().returningAll().onConflictDoNothing(new Field("id", null));
insertRow.table("dominion_group")
.field(group.domID)
.field(group.name)
.field(group.admin)
.field(group.name_colored);
for (Flag f : 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();
} catch (Exception e) {
DatabaseManager.handleDatabaseError("创建权限组失败: ", e, "");
return null;
}
}
public void delete() {
delete(getId());
}
public static void delete(Integer id) {
String sql = "DELETE FROM dominion_group WHERE id = ?;";
DatabaseManager.instance.query(sql, id);
Cache.instance.loadGroups(id);
List<MemberDTO> players = MemberDTO.selectByGroupId(id);
for (MemberDTO player : players) {
player.setGroupId(-1);
}
}
public static GroupDTO select(Integer id) {
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();
}
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();
}
public static List<GroupDTO> selectAll() {
String sql = "SELECT * FROM dominion_group;";
return getDTOFromRS(DatabaseManager.instance.query(sql));
}
public static List<GroupDTO> selectByDominionId(Integer domID) {
String sql = "SELECT * FROM dominion_group WHERE dom_id = ?;";
return getDTOFromRS(DatabaseManager.instance.query(sql, domID));
}
private GroupDTO(String name, Integer domID) {
this.domID.value = domID;
this.name.value = ColorParser.getPlainText(name);
this.name_colored.value = name;
this.admin.value = false;
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, f.getDefaultValue());
}
}
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.admin.value = admin;
this.flags.putAll(flags);
this.name_colored.value = nameColored;
}
private static List<GroupDTO> getDTOFromRS(ResultSet rs) {
List<GroupDTO> list = new ArrayList<>();
if (rs == null) return list;
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
GroupDTO group = new GroupDTO(
rs.getInt("id"),
rs.getInt("dom_id"),
rs.getString("name"),
rs.getBoolean("admin"),
flags,
rs.getString("name_colored")
);
list.add(group);
}
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询权限组失败: ", e, "");
}
return list;
}
private GroupDTO doUpdate(UpdateRow updateRow) {
updateRow.returningAll(id)
.table("dominion_group")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<GroupDTO> groups = getDTOFromRS(rs);
if (groups.isEmpty()) return null;
Cache.instance.loadGroups((Integer) id.value);
return groups.getFirst();
} catch (Exception e) {
DatabaseManager.handleDatabaseError("更新权限组失败: ", e, "");
return null;
}
}
}

View File

@ -0,0 +1,204 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
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 java.sql.ResultSet;
import java.util.*;
public class MemberDTO {
private static List<MemberDTO> query(String sql, Object... params) {
List<MemberDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
return getDTOFromRS(rs);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询玩家权限失败: ", e, sql);
}
return players;
}
private static List<MemberDTO> getDTOFromRS(ResultSet rs) {
List<MemberDTO> players = new ArrayList<>();
if (rs == null) return players;
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
MemberDTO player = new MemberDTO(
rs.getInt("id"),
UUID.fromString(rs.getString("player_uuid")),
rs.getBoolean("admin"),
rs.getInt("dom_id"),
flags,
rs.getInt("group_id")
);
players.add(player);
}
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询玩家权限失败: ", e, "");
}
return players;
}
private MemberDTO doUpdate(UpdateRow updateRow) {
updateRow.returningAll(id)
.table("dominion_member")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<MemberDTO> players = getDTOFromRS(rs);
if (players.size() == 0) return null;
Cache.instance.loadMembers(getPlayerUUID());
return players.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("更新玩家权限失败: ", e, "");
return null;
}
}
public static MemberDTO insert(MemberDTO player) {
InsertRow insertRow = new InsertRow().returningAll().onConflictDoNothing(new Field("id", null))
.table("dominion_member")
.field(player.playerUUID)
.field(player.admin)
.field(player.domID);
for (Flag f : 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.size() == 0) return null;
return players.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("插入玩家权限失败: ", e, "");
return null;
}
}
public static MemberDTO select(UUID playerUUID, Integer dom_id) {
String sql = "SELECT * FROM dominion_member WHERE player_uuid = ? AND dom_id = ?;";
List<MemberDTO> p = query(sql, playerUUID.toString(), dom_id);
if (p.size() == 0) return null;
return p.get(0);
}
public static List<MemberDTO> select(Integer dom_id) {
String sql = "SELECT * FROM dominion_member WHERE dom_id = ?;";
return query(sql, dom_id);
}
public static void delete(UUID player, Integer domID) {
String sql = "DELETE FROM dominion_member WHERE player_uuid = ? AND dom_id = ?;";
query(sql, player.toString(), domID);
Cache.instance.loadMembers(player);
}
public static List<MemberDTO> selectAll() {
String sql = "SELECT * FROM dominion_member;";
return query(sql);
}
public static List<MemberDTO> selectAll(UUID player) {
String sql = "SELECT * FROM dominion_member WHERE player_uuid = ?;";
return query(sql, player.toString());
}
public static List<MemberDTO> selectByGroupId(Integer groupId) {
String sql = "SELECT * FROM dominion_member WHERE group_id = ?;";
return query(sql, groupId);
}
public static List<MemberDTO> selectByDomGroupId(Integer domId, Integer groupId) {
String sql = "SELECT * FROM dominion_member WHERE group_id = ? AND dom_id = ?;";
return query(sql, groupId, domId);
}
Field id = new Field("id", FieldType.INT);
Field playerUUID = new Field("player_uuid", FieldType.STRING);
Field admin = new Field("admin", FieldType.BOOLEAN);
Field domID = new Field("dom_id", FieldType.INT);
Field groupId = new Field("group_id", FieldType.INT);
public Integer getId() {
return (Integer) id.value;
}
public UUID getPlayerUUID() {
return UUID.fromString((String) playerUUID.value);
}
public Boolean getAdmin() {
return (Boolean) admin.value;
}
public Integer getDomID() {
return (Integer) domID.value;
}
public Integer getGroupId() {
return (Integer) groupId.value;
}
private final Map<Flag, Boolean> flags = new HashMap<>();
public Boolean getFlagValue(Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public MemberDTO setFlagValue(Flag flag, Boolean value) {
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) {
this.admin.value = admin;
UpdateRow updateRow = new UpdateRow().field(this.admin);
return doUpdate(updateRow);
}
public MemberDTO setGroupId(Integer groupId) {
this.groupId.value = groupId;
UpdateRow updateRow = new UpdateRow().field(this.groupId);
return doUpdate(updateRow);
}
public MemberDTO applyTemplate(PrivilegeTemplateDTO template) {
this.admin.value = template.getAdmin();
UpdateRow updateRow = new UpdateRow().field(admin);
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
this.flags.put(f, template.getFlagValue(f));
updateRow.field(new Field(f.getFlagName(), template.getFlagValue(f)));
}
return doUpdate(updateRow);
}
private MemberDTO(Integer id, UUID playerUUID, Boolean admin, Integer domID, Map<Flag, Boolean> flags, Integer groupId) {
this.id.value = id;
this.playerUUID.value = playerUUID.toString();
this.admin.value = admin;
this.domID.value = domID;
this.groupId.value = groupId;
this.flags.putAll(flags);
}
public MemberDTO(UUID playerUUID, DominionDTO dom) {
this.id.value = null;
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));
}
}
}

View File

@ -0,0 +1,205 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class PlayerDTO {
public static PlayerDTO get(Player player) {
PlayerDTO re = select(player.getUniqueId());
if (re == null) {
re = insert(new PlayerDTO(player.getUniqueId(), player.getName(), System.currentTimeMillis()));
}
return re;
}
public static @Nullable PlayerDTO get(OfflinePlayer player) {
if (player.getName() == null) {
return null;
}
PlayerDTO re = select(player.getUniqueId());
if (re == null) {
re = insert(new PlayerDTO(player.getUniqueId(), player.getName(), System.currentTimeMillis()));
}
return re;
}
public static List<PlayerDTO> all() {
String sql = "SELECT * FROM player_name WHERE id > 0;";
return query(sql);
}
public PlayerDTO onJoin(String name) {
this.setLastKnownName(name);
return update(this);
}
private static List<PlayerDTO> query(String sql, Object... params) {
List<PlayerDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
return getDTOFromRS(rs);
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("查询玩家信息失败: ", e, sql);
}
return players;
}
private static List<PlayerDTO> getDTOFromRS(ResultSet rs) throws SQLException {
List<PlayerDTO> players = new ArrayList<>();
if (rs == null) return players;
while (rs.next()) {
Integer id = rs.getInt("id");
UUID uuid = UUID.fromString(rs.getString("uuid"));
String lastKnownName = rs.getString("last_known_name");
Long lastJoinAt = rs.getTimestamp("last_join_at").getTime();
Integer usingGroupTitleID = rs.getInt("using_group_title_id");
PlayerDTO player = new PlayerDTO(id, uuid, lastKnownName, lastJoinAt, usingGroupTitleID);
players.add(player);
}
return players;
}
public static PlayerDTO select(UUID uuid) {
String sql = "SELECT * FROM player_name WHERE uuid = ?;";
List<PlayerDTO> players = query(sql, uuid.toString());
if (players.isEmpty()) return null;
return players.getFirst();
}
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();
}
public static List<PlayerDTO> search(String name) {
// 模糊搜索
String sql = "SELECT * FROM player_name WHERE last_known_name LIKE ?;";
return query(sql, "%" + name + "%");
}
public static void delete(PlayerDTO player) {
String sql = "DELETE FROM player_name WHERE uuid = ?;";
query(sql, player.getUuid());
}
private static PlayerDTO insert(PlayerDTO player) {
Field uuid = new Field("uuid", player.getUuid().toString());
Field lastKnownName = new Field("last_known_name", player.getLastKnownName());
Field lastJoinAt = new Field("last_join_at", Timestamp.valueOf(LocalDateTime.now()));
Field usingGroupTitleID = new Field("using_group_title_id", player.getUsingGroupTitleID());
InsertRow insertRow = new InsertRow()
.table("player_name")
.field(uuid)
.field(lastKnownName)
.field(lastJoinAt)
.field(usingGroupTitleID)
.returningAll()
.onConflictOverwrite(new Field("id", null));
try (ResultSet rs = insertRow.execute()) {
List<PlayerDTO> players = getDTOFromRS(rs);
if (players.isEmpty()) return null;
return players.getFirst();
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("插入玩家信息失败: ", e, insertRow.toString());
return null;
}
}
private static PlayerDTO update(PlayerDTO player) {
Field lastKnownName = new Field("last_known_name", player.getLastKnownName());
Field uuid = new Field("uuid", player.getUuid().toString());
Field lastJoinAt = new Field("last_join_at", Timestamp.valueOf(LocalDateTime.now()));
Field usingGroupTitleID = new Field("using_group_title_id", player.getUsingGroupTitleID());
UpdateRow updateRow = new UpdateRow()
.table("player_name")
.field(lastKnownName)
.field(lastJoinAt)
.field(usingGroupTitleID)
.where("uuid = ?", uuid.value)
.returningAll(uuid);
try (ResultSet rs = updateRow.execute()) {
List<PlayerDTO> players = getDTOFromRS(rs);
if (players.isEmpty()) return null;
return players.getFirst();
} catch (SQLException e) {
DatabaseManager.handleDatabaseError("更新玩家信息失败: ", e, updateRow.toString());
return null;
}
}
private PlayerDTO(Integer id, UUID uuid, String lastKnownName, Long lastJoinAt, Integer using_group_title_id) {
this.id = id;
this.uuid = uuid;
this.lastKnownName = lastKnownName;
this.lastJoinAt = lastJoinAt;
this.using_group_title_id = using_group_title_id;
}
private PlayerDTO(UUID uuid, String lastKnownName, Long lastJoinAt) {
this(null, uuid, lastKnownName, lastJoinAt, -1);
}
public Integer getId() {
return id;
}
public UUID getUuid() {
return uuid;
}
public String getLastKnownName() {
return lastKnownName;
}
public Long getLastJoinAt() {
return lastJoinAt;
}
public void setId(Integer id) {
this.id = id;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
public void setLastKnownName(String lastKnownName) {
this.lastKnownName = lastKnownName;
}
public void setLastJoinAt(Long lastJoinAt) {
this.lastJoinAt = lastJoinAt;
}
public Integer getUsingGroupTitleID() {
return using_group_title_id;
}
public void setUsingGroupTitleID(Integer usingGroupTitleID) {
this.using_group_title_id = usingGroupTitleID;
update(this);
Cache.instance.updatePlayerUsingGroupTitle(uuid, usingGroupTitleID);
}
private Integer id;
private UUID uuid;
private String lastKnownName;
private Long lastJoinAt;
private Integer using_group_title_id;
}

View File

@ -0,0 +1,142 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import java.sql.ResultSet;
import java.util.*;
public class PrivilegeTemplateDTO {
private static List<PrivilegeTemplateDTO> query(String sql, Object... params) {
List<PrivilegeTemplateDTO> templates = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
return getDTOFromRS(rs);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询权限模版失败: ", e, sql);
}
return templates;
}
private static List<PrivilegeTemplateDTO> getDTOFromRS(ResultSet rs) {
List<PrivilegeTemplateDTO> templates = new ArrayList<>();
if (rs == null) return templates;
try {
while (rs.next()) {
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getPrivilegeFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
PrivilegeTemplateDTO template = new PrivilegeTemplateDTO(
rs.getInt("id"),
UUID.fromString(rs.getString("creator")),
rs.getString("name"),
rs.getBoolean("admin"),
flags
);
templates.add(template);
}
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询权限模版失败: ", e, null);
}
return templates;
}
public static PrivilegeTemplateDTO create(UUID creator, String name) {
Field creatorField = new Field("creator", creator.toString());
Field nameField = new Field("name", name);
InsertRow insertRow = new InsertRow().table("privilege_template").onConflictDoNothing(new Field("id", null))
.field(creatorField)
.field(nameField)
.returningAll();
try (ResultSet rs = insertRow.execute()) {
List<PrivilegeTemplateDTO> templates = getDTOFromRS(rs);
if (templates.size() == 0) return null;
return templates.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("创建权限模版失败: ", e, null);
return null;
}
}
private PrivilegeTemplateDTO doUpdate(UpdateRow updateRow) {
Field id = new Field("id", this.id);
updateRow.returningAll(id)
.table("privilege_template")
.where("id = ?", id.value);
try (ResultSet rs = updateRow.execute()) {
List<PrivilegeTemplateDTO> templates = getDTOFromRS(rs);
if (templates.size() == 0) return null;
return templates.get(0);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("更新权限模版失败: ", e, null);
return null;
}
}
public static PrivilegeTemplateDTO select(UUID creator, String name) {
String sql = "SELECT * FROM privilege_template WHERE creator = ? AND name = ?;";
List<PrivilegeTemplateDTO> templates = query(sql, creator.toString(), name);
if (templates.size() == 0) return null;
return templates.get(0);
}
public static List<PrivilegeTemplateDTO> selectAll(UUID creator) {
String sql = "SELECT * FROM privilege_template WHERE creator = ?;";
return query(sql, creator.toString());
}
public static void delete(UUID creator, String name) {
String sql = "DELETE FROM privilege_template WHERE creator = ? AND name = ?;";
query(sql, creator.toString(), name);
}
private PrivilegeTemplateDTO(Integer id, UUID creator, String name, Boolean admin, Map<Flag, Boolean> flags) {
this.id = id;
this.creator = creator;
this.name = name;
this.admin = admin;
this.flags.putAll(flags);
}
private Integer id;
private UUID creator;
private String name;
private Boolean admin;
private final Map<Flag, Boolean> flags = new HashMap<>();
public Integer getId() {
return id;
}
public UUID getCreator() {
return creator;
}
public String getName() {
return name;
}
public Boolean getAdmin() {
return admin;
}
public Boolean getFlagValue(Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public PrivilegeTemplateDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value);
return doUpdate(new UpdateRow().field(new Field(flag.getFlagName(), value)));
}
public PrivilegeTemplateDTO setAdmin(Boolean admin) {
this.admin = admin;
return doUpdate(new UpdateRow().field(new Field("admin", admin)));
}
}

View File

@ -0,0 +1,570 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.VaultConnect.VaultConnect;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConfigManager {
public ConfigManager(Dominion plugin) {
_plugin = plugin;
_plugin.saveDefaultConfig();
reload();
_plugin.saveConfig();
}
public void reload() {
_plugin.reloadConfig();
_file = _plugin.getConfig();
_debug = _file.getBoolean("Debug", false);
_timer = _file.getBoolean("Timer", false);
XLogger.setDebug(_debug);
_db_type = _file.getString("Database.Type", "sqlite");
_db_host = _file.getString("Database.Host", "localhost");
_db_port = _file.getString("Database.Port", "5432");
_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);
if (_auto_create_radius == 0) {
XLogger.err("AutoCreateRadius 不能等于 0已重置为 10");
setAutoCreateRadius(10);
}
_spawn_protection = _file.getInt("Limit.SpawnProtection", 10);
_blue_map = _file.getBoolean("BlueMap", false);
_dynmap = _file.getBoolean("Dynmap", false);
_auto_clean_after_days = _file.getInt("AutoCleanAfterDays", 180);
if (_auto_clean_after_days == 0) {
XLogger.err("AutoCleanAfterDays 不能等于 0已重置为 180");
setAutoCleanAfterDays(180);
}
_limit_op_bypass = _file.getBoolean("Limit.OpByPass", true);
_check_update = _file.getBoolean("CheckUpdate", true);
_tp_enable = _file.getBoolean("Teleport.Enable", false);
_tp_delay = _file.getInt("Teleport.Delay", 0);
_tp_cool_down = _file.getInt("Teleport.CoolDown", 0);
_tool = _file.getString("Tool", "ARROW");
if (Material.getMaterial(_tool) == null) {
XLogger.err("工具名称设置错误,已重置为 ARROW");
setTool("ARROW");
}
_economy_enable = _file.getBoolean("Economy.Enable", false);
if (getEconomyEnable()) {
new VaultConnect(this._plugin);
}
_fly_permission_nodes = _file.getStringList("FlyPermissionNodes");
_residence_migration = _file.getBoolean("ResidenceMigration", false);
_group_title_enable = _file.getBoolean("GroupTitle.Enable", false);
_group_title_prefix = _file.getString("GroupTitle.Prefix", "&#ffffff[");
_group_title_suffix = _file.getString("GroupTitle.Suffix", "&#ffffff]");
GroupLimit defaultGroup = new GroupLimit();
defaultGroup.setLimitSizeX(_file.getInt("Limit.SizeX", 128));
defaultGroup.setLimitSizeY(_file.getInt("Limit.SizeY", 64));
defaultGroup.setLimitSizeZ(_file.getInt("Limit.SizeZ", 128));
defaultGroup.setLimitMinY(_file.getInt("Limit.MinY", -64));
defaultGroup.setLimitMaxY(_file.getInt("Limit.MaxY", 320));
defaultGroup.setLimitAmount(_file.getInt("Limit.Amount", 10));
defaultGroup.setLimitDepth(_file.getInt("Limit.Depth", 3));
defaultGroup.setLimitVert(_file.getBoolean("Limit.Vert", false));
defaultGroup.setWorldBlackList(_file.getStringList("Limit.WorldBlackList"));
defaultGroup.setPrice(_file.getDouble("Economy.Price", 10.0));
defaultGroup.setPriceOnlyXZ(_file.getBoolean("Economy.OnlyXZ", false));
defaultGroup.setRefundRatio(_file.getDouble("Economy.Refund", 0.85));
limits.put("default", defaultGroup);
if (defaultGroup.getLimitSizeX() <= 4 && defaultGroup.getLimitSizeX() != -1) {
XLogger.err("Limit.SizeX 尺寸不能小于 4已重置为 128");
setLimitSizeX(128);
}
if (defaultGroup.getLimitSizeY() <= 4 && defaultGroup.getLimitSizeY() != -1) {
XLogger.err("Limit.SizeY 尺寸不能小于 4已重置为 64");
setLimitSizeY(64);
}
if (defaultGroup.getLimitSizeZ() <= 4 && defaultGroup.getLimitSizeZ() != -1) {
XLogger.err("Limit.SizeZ 尺寸不能小于 4已重置为 128");
setLimitSizeZ(128);
}
if (defaultGroup.getLimitMinY() >= defaultGroup.getLimitMaxY()) {
XLogger.err("Limit.MinY 不能大于或等于 Limit.MaxY已重置为 -64 320");
setLimitMinY(-64);
setLimitMaxY(320);
}
if (defaultGroup.getRefundRatio() < 0.0 || defaultGroup.getRefundRatio() > 1.0) {
XLogger.err("Economy.Refund 设置不合法,已重置为 0.85");
setEconomyRefund(0.85f);
}
if (defaultGroup.getPrice() < 0.0) {
XLogger.err("Economy.Price 设置不合法,已重置为 10.0");
setEconomyPrice(10.0f);
}
if (defaultGroup.getLimitVert() && defaultGroup.getLimitSizeY() <= defaultGroup.getLimitMaxY() - defaultGroup.getLimitMinY()) {
XLogger.warn("启用 Limit.Vert 时 Limit.SizeY 不能小于 Limit.MaxY - Limit.MinY已自动调整为 " + (defaultGroup.getLimitMaxY() - defaultGroup.getLimitMinY() + 1));
setLimitSizeY(defaultGroup.getLimitMaxY() - defaultGroup.getLimitMinY() + 1);
}
if (defaultGroup.getLimitAmount() < 0 && defaultGroup.getLimitAmount() != -1) {
XLogger.err("Limit.Amount 设置不合法,已重置为 10");
setLimitAmount(10);
}
if (defaultGroup.getLimitDepth() < 0 && defaultGroup.getLimitDepth() != -1) {
XLogger.err("Limit.Depth 设置不合法,已重置为 3");
setLimitDepth(3);
}
limits.putAll(GroupLimit.loadGroups(_plugin));
saveAll(); // 回写文件 防止文件中的数据不完整
Flag.loadFromJson(); // 加载 Flag 配置
}
public void saveAll() {
// 删除旧文件
new File(_plugin.getDataFolder(), "config.yml").delete();
// 保存新文件
_plugin.saveDefaultConfig();
// 重新加载
_plugin.reloadConfig();
_file = _plugin.getConfig();
// 保存配置
_file.set("Database.Type", _db_type);
_file.set("Database.Host", _db_host);
_file.set("Database.Port", _db_port);
_file.set("Database.Name", _db_name);
_file.set("Database.User", _db_user);
_file.set("Database.Pass", _db_pass);
_file.set("AutoCreateRadius", _auto_create_radius);
_file.set("Limit.SpawnProtection", _spawn_protection);
_file.set("Limit.MinY", limits.get("default").getLimitMinY());
_file.set("Limit.MaxY", limits.get("default").getLimitMaxY());
_file.set("Limit.SizeX", limits.get("default").getLimitSizeX());
_file.set("Limit.SizeY", limits.get("default").getLimitSizeY());
_file.set("Limit.SizeZ", limits.get("default").getLimitSizeZ());
_file.set("Limit.Amount", limits.get("default").getLimitAmount());
_file.set("Limit.Depth", limits.get("default").getLimitDepth());
_file.set("Limit.Vert", limits.get("default").getLimitVert());
_file.set("Limit.WorldBlackList", limits.get("default").getWorldBlackList());
_file.set("Limit.OpByPass", _limit_op_bypass);
_file.set("Teleport.Enable", _tp_enable);
_file.set("Teleport.Delay", _tp_delay);
_file.set("Teleport.CoolDown", _tp_cool_down);
_file.set("AutoCleanAfterDays", _auto_clean_after_days);
_file.set("Tool", _tool);
_file.set("Economy.Enable", _economy_enable);
_file.set("Economy.Price", limits.get("default").getPrice());
_file.set("Economy.OnlyXZ", limits.get("default").getPriceOnlyXZ());
_file.set("Economy.Refund", limits.get("default").getRefundRatio());
_file.set("FlyPermissionNodes", _fly_permission_nodes);
_file.set("ResidenceMigration", _residence_migration);
_file.set("GroupTitle.Enable", _group_title_enable);
_file.set("GroupTitle.Prefix", _group_title_prefix);
_file.set("GroupTitle.Suffix", _group_title_suffix);
_file.set("BlueMap", _blue_map);
_file.set("Dynmap", _dynmap);
_file.set("CheckUpdate", _check_update);
_file.set("Debug", _debug);
_file.set("Timer", _timer);
_plugin.saveConfig();
}
public Boolean isDebug() {
return _debug;
}
public void setDebug(Boolean debug) {
_debug = debug;
_file.set("Debug", debug);
_plugin.saveConfig();
XLogger.setDebug(debug);
}
public Boolean TimerEnabled() {
return _timer;
}
public String getDbType() {
return _db_type;
}
public void setDbType(String db_type) {
_db_type = db_type;
_file.set("Database.Type", db_type);
_plugin.saveConfig();
}
public String getDbHost() {
return _db_host;
}
public String getDbPort() {
return _db_port;
}
public String getDbName() {
return _db_name;
}
public void setDbUser(String db_user) {
_db_user = db_user;
_file.set("Database.User", db_user);
_plugin.saveConfig();
}
public String getDbUser() {
if (_db_user.contains("@")) {
setDbUser("'" + _db_user + "'");
}
return _db_user;
}
public void setDbPass(String db_pass) {
_db_pass = db_pass;
_file.set("Database.Pass", db_pass);
_plugin.saveConfig();
}
public String getDbPass() {
return _db_pass;
}
public Integer getLimitSizeX(Player player) {
return limits.get(getPlayerGroup(player)).getLimitSizeX();
}
public void setLimitSizeX(Integer max_x) {
limits.get("default").setLimitSizeX(max_x);
_file.set("Limit.SizeX", max_x);
_plugin.saveConfig();
}
public Integer getLimitSizeY(Player player) {
return limits.get(getPlayerGroup(player)).getLimitSizeY();
}
public void setLimitSizeY(Integer max_y) {
limits.get("default").setLimitSizeY(max_y);
_file.set("Limit.SizeY", max_y);
_plugin.saveConfig();
}
public Integer getLimitSizeZ(Player player) {
return limits.get(getPlayerGroup(player)).getLimitSizeZ();
}
public void setLimitSizeZ(Integer max_z) {
limits.get("default").setLimitSizeZ(max_z);
_file.set("Limit.SizeZ", max_z);
_plugin.saveConfig();
}
public Integer getAutoCreateRadius() {
return _auto_create_radius;
}
public void setAutoCreateRadius(Integer radius) {
_auto_create_radius = radius;
_file.set("AutoCreateRadius", radius);
_plugin.saveConfig();
}
public Boolean getBlueMap() {
return _blue_map;
}
public Boolean getDynmap() {
return _dynmap;
}
public Integer getAutoCleanAfterDays() {
return _auto_clean_after_days;
}
public void setAutoCleanAfterDays(Integer auto_clean_after_days) {
_auto_clean_after_days = auto_clean_after_days;
_file.set("AutoCleanAfterDays", auto_clean_after_days);
_plugin.saveConfig();
}
public Integer getLimitMinY(Player player) {
return limits.get(getPlayerGroup(player)).getLimitMinY();
}
public void setLimitMinY(Integer limit_bottom) {
limits.get("default").setLimitMinY(limit_bottom);
_file.set("Limit.MinY", limit_bottom);
_plugin.saveConfig();
}
public Integer getLimitMaxY(Player player) {
return limits.get(getPlayerGroup(player)).getLimitMaxY();
}
public void setLimitMaxY(Integer limit_top) {
limits.get("default").setLimitMaxY(limit_top);
_file.set("Limit.MaxY", limit_top);
_plugin.saveConfig();
}
public Integer getLimitAmount(Player player) {
return limits.get(getPlayerGroup(player)).getLimitAmount();
}
public void setLimitAmount(Integer limit_amount) {
limits.get("default").setLimitAmount(limit_amount);
_file.set("Limit.Amount", limit_amount);
_plugin.saveConfig();
}
public Integer getLimitDepth(Player player) {
return limits.get(getPlayerGroup(player)).getLimitDepth();
}
public void setLimitDepth(Integer limit_depth) {
limits.get("default").setLimitDepth(limit_depth);
_file.set("Limit.Depth", limit_depth);
_plugin.saveConfig();
}
public Boolean getLimitVert(Player player) {
return limits.get(getPlayerGroup(player)).getLimitVert();
}
public void setLimitVert(Boolean limit_vert) {
limits.get("default").setLimitVert(limit_vert);
_file.set("Limit.Vert", limit_vert);
_plugin.saveConfig();
}
public List<String> getWorldBlackList(Player player) {
return limits.get(getPlayerGroup(player)).getWorldBlackList();
}
public Boolean getLimitOpBypass() {
return _limit_op_bypass;
}
public void setLimitOpBypass(Boolean limit_op_bypass) {
_limit_op_bypass = limit_op_bypass;
_file.set("Limit.OpByPass", limit_op_bypass);
_plugin.saveConfig();
}
public Boolean getCheckUpdate() {
return _check_update;
}
public Boolean getTpEnable() {
return _tp_enable;
}
public void setTpEnable(Boolean tp_enable) {
_tp_enable = tp_enable;
_file.set("Teleport.Enable", tp_enable);
_plugin.saveConfig();
}
public Integer getTpDelay() {
return _tp_delay;
}
public void setTpDelay(Integer tp_delay) {
_tp_delay = tp_delay;
_file.set("Teleport.Delay", tp_delay);
_plugin.saveConfig();
}
public Integer getTpCoolDown() {
return _tp_cool_down;
}
public void setTpCoolDown(Integer tp_cool_down) {
_tp_cool_down = tp_cool_down;
_file.set("Teleport.CoolDown", tp_cool_down);
_plugin.saveConfig();
}
public Material getTool() {
return Material.getMaterial(_tool);
}
public void setTool(String tool) {
_tool = tool;
_file.set("Tool", tool);
_plugin.saveConfig();
}
public Boolean getEconomyEnable() {
return _economy_enable;
}
public void setEconomyEnable(Boolean economy_enable) {
_economy_enable = economy_enable;
_file.set("Economy.Enable", economy_enable);
_plugin.saveConfig();
}
public Float getEconomyPrice(Player player) {
return limits.get(getPlayerGroup(player)).getPrice().floatValue();
}
public void setEconomyPrice(Float economy_price) {
limits.get("default").setPrice((double) economy_price);
_file.set("Economy.Price", economy_price);
_plugin.saveConfig();
}
public Boolean getEconomyOnlyXZ(Player player) {
return limits.get(getPlayerGroup(player)).getPriceOnlyXZ();
}
public void setEconomyOnlyXZ(Boolean economy_only_xz) {
limits.get("default").setPriceOnlyXZ(economy_only_xz);
_file.set("Economy.OnlyXZ", economy_only_xz);
_plugin.saveConfig();
}
public Float getEconomyRefund(Player player) {
return limits.get(getPlayerGroup(player)).getRefundRatio().floatValue();
}
public void setEconomyRefund(Float economy_refund) {
limits.get("default").setRefundRatio((double) economy_refund);
_file.set("Economy.Refund", economy_refund);
_plugin.saveConfig();
}
public List<String> getFlyPermissionNodes() {
return _fly_permission_nodes;
}
public void setFlyPermissionNodes(List<String> fly_permission_nodes) {
_fly_permission_nodes = fly_permission_nodes;
_file.set("FlyPermissionNodes", fly_permission_nodes);
_plugin.saveConfig();
}
public Boolean getResidenceMigration() {
return _residence_migration;
}
public void setResidenceMigration(Boolean residence_migration) {
_residence_migration = residence_migration;
_file.set("ResidenceMigration", residence_migration);
_plugin.saveConfig();
}
public Integer getSpawnProtection() {
return _spawn_protection;
}
public void setSpawnProtection(Integer spawn_protection) {
_spawn_protection = spawn_protection;
_file.set("Limit.SpawnProtection", spawn_protection);
_plugin.saveConfig();
}
public Boolean getGroupTitleEnable() {
return _group_title_enable;
}
public void setGroupTitleEnable(Boolean group_title_enable) {
_group_title_enable = group_title_enable;
_file.set("GroupTitle.Enable", group_title_enable);
_plugin.saveConfig();
}
public String getGroupTitlePrefix() {
return _group_title_prefix;
}
public void setGroupTitlePrefix(String group_title_prefix) {
_group_title_prefix = group_title_prefix;
_file.set("GroupTitle.Prefix", group_title_prefix);
_plugin.saveConfig();
}
public String getGroupTitleSuffix() {
return _group_title_suffix;
}
public void setGroupTitleSuffix(String group_title_suffix) {
_group_title_suffix = group_title_suffix;
_file.set("GroupTitle.Suffix", group_title_suffix);
_plugin.saveConfig();
}
private final Dominion _plugin;
private FileConfiguration _file;
private Boolean _debug;
private Boolean _timer;
private String _db_type;
private String _db_host;
private String _db_port;
private String _db_user;
private String _db_pass;
private String _db_name;
private Integer _auto_create_radius;
private Boolean _limit_op_bypass;
private Boolean _blue_map;
private Boolean _dynmap;
private Integer _auto_clean_after_days;
private Boolean _check_update;
private Boolean _tp_enable;
private Integer _tp_delay;
private Integer _tp_cool_down;
private String _tool;
private Boolean _economy_enable;
private List<String> _fly_permission_nodes;
private Boolean _residence_migration;
private Integer _spawn_protection;
private Boolean _group_title_enable;
private String _group_title_prefix;
private String _group_title_suffix;
private final Map<String, GroupLimit> limits = new HashMap<>();
private String getPlayerGroup(@Nullable Player player) {
if (player == null) {
return "default";
}
for (String group : limits.keySet()) {
if (group.equals("default")) {
continue;
}
if (player.hasPermission("group." + group)) {
return group;
}
}
return "default";
}
}

View File

@ -0,0 +1,263 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.Flag;
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 java.sql.ResultSet;
import java.util.List;
public class DatabaseTables {
public static void migrate() {
// player name
TableColumn player_name_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn player_name_uuid = new TableColumn("uuid", FieldType.STRING, false, false, true, true, "''");
TableColumn player_name_last_known_name = new TableColumn("last_known_name", FieldType.STRING, false, false, true, false, "'unknown'");
TableColumn player_name_last_join_at = new TableColumn("last_join_at", FieldType.DATETIME, false, false, true, false, "CURRENT_TIMESTAMP");
CreateTable player_name = new CreateTable().ifNotExists();
player_name.table("player_name")
.field(player_name_id)
.field(player_name_uuid)
.field(player_name_last_known_name)
.field(player_name_last_join_at);
player_name.execute();
// dominion table
TableColumn dominion_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn dominion_owner = new TableColumn("owner", FieldType.STRING, false, false, true, false, "''");
TableColumn dominion_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
TableColumn dominion_world = new TableColumn("world", FieldType.STRING, false, false, true, false, "'world'");
TableColumn dominion_x1 = new TableColumn("x1", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_y1 = new TableColumn("y1", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_z1 = new TableColumn("z1", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_x2 = new TableColumn("x2", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_y2 = new TableColumn("y2", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_z2 = new TableColumn("z2", FieldType.INT, false, false, true, false, 0);
TableColumn dominion_parent_dom_id = new TableColumn("parent_dom_id", FieldType.INT, false, false, true, false, -1);
TableColumn dominion_join_message = new TableColumn("join_message", FieldType.STRING, false, false, true, false, "'欢迎'");
TableColumn dominion_leave_message = new TableColumn("leave_message", FieldType.STRING, false, false, true, false, "'再见'");
CreateTable.ForeignKey dominion_owner_fk = new CreateTable.ForeignKey(dominion_owner, "player_name", player_name_uuid, true);
CreateTable.ForeignKey dominion_parent_dom_id_fk = new CreateTable.ForeignKey(dominion_parent_dom_id, "dominion", dominion_id, true);
CreateTable dominion = new CreateTable().ifNotExists();
dominion.table("dominion")
.field(dominion_id)
.field(dominion_owner)
.field(dominion_name)
.field(dominion_world)
.field(dominion_x1)
.field(dominion_y1)
.field(dominion_z1)
.field(dominion_x2)
.field(dominion_y2)
.field(dominion_z2)
.field(dominion_parent_dom_id)
.field(dominion_join_message)
.field(dominion_leave_message)
.foreignKey(dominion_owner_fk)
.foreignKey(dominion_parent_dom_id_fk);
dominion.execute();
for (Flag flag : Flag.getAllDominionFlags()) {
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("dominion").ifNotExists().execute();
}
// player privilege
if (!Common.IsTableExist("dominion_member")) {
TableColumn player_privilege_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn player_privilege_player_uuid = new TableColumn("player_uuid", FieldType.STRING, false, false, true, false, "''");
TableColumn player_privilege_dom_id = new TableColumn("dom_id", FieldType.INT, false, false, true, false, -1);
TableColumn player_privilege_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, false);
CreateTable.ForeignKey player_privilege_player_uuid_fk = new CreateTable.ForeignKey(player_privilege_player_uuid, "player_name", player_name_uuid, true);
CreateTable.ForeignKey player_privilege_dom_id_fk = new CreateTable.ForeignKey(player_privilege_dom_id, "dominion", dominion_id, true);
CreateTable player_privilege = new CreateTable().ifNotExists();
player_privilege.table("player_privilege")
.field(player_privilege_id)
.field(player_privilege_player_uuid)
.field(player_privilege_dom_id)
.field(player_privilege_admin)
.foreignKey(player_privilege_player_uuid_fk)
.foreignKey(player_privilege_dom_id_fk)
.unique(player_privilege_player_uuid, player_privilege_dom_id);
player_privilege.execute();
for (Flag flag : Flag.getAllPrivilegeFlags()) {
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("player_privilege").ifNotExists().execute();
}
}
// server root player name
Field server_player_name_id_field = new Field("id", -1);
Field server_player_name_uuid_field = new Field("uuid", "00000000-0000-0000-0000-000000000000");
Field server_player_name_last_known_name_field = new Field("last_known_name", "server");
InsertRow insert_server_player_name = new InsertRow().table("player_name").onConflictDoNothing(server_player_name_id_field)
.field(server_player_name_id_field)
.field(server_player_name_uuid_field)
.field(server_player_name_last_known_name_field);
insert_server_player_name.execute();
// server root dominion
Field server_dom_id_field = new Field("id", -1);
Field server_dom_owner_field = new Field("owner", "00000000-0000-0000-0000-000000000000");
Field server_dom_name_field = new Field("name", "根领地");
Field server_dom_world_field = new Field("world", "all");
Field server_dom_x1_field = new Field("x1", -2147483648);
Field server_dom_y1_field = new Field("y1", -2147483648);
Field server_dom_z1_field = new Field("z1", -2147483648);
Field server_dom_x2_field = new Field("x2", 2147483647);
Field server_dom_y2_field = new Field("y2", 2147483647);
Field server_dom_z2_field = new Field("z2", 2147483647);
Field server_dom_parent_dom_id_field = new Field("parent_dom_id", -1);
Field server_dom_join_message_field = new Field("join_message", "欢迎");
Field server_dom_leave_message_field = new Field("leave_message", "再见");
InsertRow insert_server_dom = new InsertRow().table("dominion").onConflictDoNothing(server_dom_id_field)
.field(server_dom_id_field)
.field(server_dom_owner_field)
.field(server_dom_name_field)
.field(server_dom_world_field)
.field(server_dom_x1_field)
.field(server_dom_y1_field)
.field(server_dom_z1_field)
.field(server_dom_x2_field)
.field(server_dom_y2_field)
.field(server_dom_z2_field)
.field(server_dom_parent_dom_id_field)
.field(server_dom_join_message_field)
.field(server_dom_leave_message_field);
insert_server_dom.execute();
// 1.18.0 dominion add tp_location
TableColumn dominion_tp_location = new TableColumn("tp_location", FieldType.STRING, false, false, true, false, "'default'");
new AddColumn(dominion_tp_location).table("dominion").ifNotExists().execute();
// 1.31.0 add privilege_template
TableColumn privilege_template_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn privilege_template_creator = new TableColumn("creator", FieldType.STRING, false, false, true, false, "''");
TableColumn privilege_template_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
TableColumn privilege_template_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, false);
CreateTable.ForeignKey privilege_template_creator_fk = new CreateTable.ForeignKey(privilege_template_creator, "player_name", player_name_uuid, true);
CreateTable privilege_template = new CreateTable().ifNotExists();
privilege_template.table("privilege_template")
.field(privilege_template_id)
.field(privilege_template_creator)
.field(privilege_template_name)
.field(privilege_template_admin)
.foreignKey(privilege_template_creator_fk)
.unique(privilege_template_creator, privilege_template_name);
privilege_template.execute();
for (Flag flag : Flag.getAllPrivilegeFlags()) {
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("privilege_template").ifNotExists().execute();
}
// 1.31.6 dominion add blue-map tile color
TableColumn dominion_color = new TableColumn("color", FieldType.STRING, false, false, true, false, "'#00BFFF'");
new AddColumn(dominion_color).table("dominion").ifNotExists().execute();
// 1.34.0 add dominion_group
if (!Common.IsTableExist("dominion_member")) {
TableColumn player_privilege_group_id = new TableColumn("group_id", FieldType.INT, false, false, true, false, -1);
new AddColumn(player_privilege_group_id).table("player_privilege").ifNotExists().execute();
}
TableColumn dominion_group_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn dominion_group_dom_id = new TableColumn("dom_id", FieldType.INT, false, false, true, false, -1);
TableColumn dominion_group_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "'未命名'");
TableColumn dominion_group_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, false);
CreateTable.ForeignKey group_dom_id_fk = new CreateTable.ForeignKey(dominion_group_dom_id, "dominion", dominion_id, true);
CreateTable group = new CreateTable().ifNotExists();
group.table("dominion_group")
.field(dominion_group_id)
.field(dominion_group_dom_id)
.field(dominion_group_name)
.field(dominion_group_admin)
.foreignKey(group_dom_id_fk)
.unique(dominion_group_dom_id, dominion_group_name);
group.execute();
for (Flag flag : Flag.getAllPrivilegeFlags()) {
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("dominion_group").ifNotExists().execute();
}
// 1.35.0 migrate player_privilege -> dominion_member
TableColumn dominion_member_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn dominion_member_player_uuid = new TableColumn("player_uuid", FieldType.STRING, false, false, true, false, "''");
TableColumn dominion_member_dom_id = new TableColumn("dom_id", FieldType.INT, false, false, true, false, -1);
TableColumn dominion_member_admin = new TableColumn("admin", FieldType.BOOLEAN, false, false, true, false, false);
TableColumn dominion_member_group_id = new TableColumn("group_id", FieldType.INT, false, false, true, false, -1);
CreateTable.ForeignKey dominion_member_player_uuid_fk = new CreateTable.ForeignKey(dominion_member_player_uuid, "player_name", player_name_uuid, true);
CreateTable.ForeignKey dominion_member_dom_id_fk = new CreateTable.ForeignKey(dominion_member_dom_id, "dominion", dominion_id, true);
CreateTable dominion_member = new CreateTable().ifNotExists();
dominion_member.table("dominion_member")
.field(dominion_member_id)
.field(dominion_member_player_uuid)
.field(dominion_member_dom_id)
.field(dominion_member_admin)
.field(dominion_member_group_id)
.foreignKey(dominion_member_player_uuid_fk)
.foreignKey(dominion_member_dom_id_fk)
.unique(dominion_member_player_uuid, dominion_member_dom_id);
dominion_member.execute();
for (Flag flag : Flag.getAllPrivilegeFlags()) {
TableColumn column = new TableColumn(flag.getFlagName(), FieldType.BOOLEAN, false, false, true, false, flag.getDefaultValue());
new AddColumn(column).table("dominion_member").ifNotExists().execute();
}
if (Common.IsTableExist("player_privilege")) {
// migrate from player_privilege to dominion_member
String sql = "SELECT * FROM player_privilege;";
try (ResultSet rs = DatabaseManager.instance.query(sql)) {
while (rs.next()) {
String player_uuid = rs.getString("player_uuid");
int dom_id = rs.getInt("dom_id");
boolean admin = rs.getBoolean("admin");
int group_id = rs.getInt("group_id");
InsertRow insert = new InsertRow().table("dominion_member")
.field(new Field("player_uuid", player_uuid))
.field(new Field("dom_id", dom_id))
.field(new Field("group_id", group_id))
.field(new Field("admin", admin));
for (Flag flag : Flag.getAllPrivilegeFlags()) {
insert.field(new Field(flag.getFlagName(), rs.getBoolean(flag.getFlagName())));
}
insert.execute();
}
sql = "DROP TABLE player_privilege;";
DatabaseManager.instance.query(sql);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("迁移 player_privilege 到 dominion_member 失败", e, sql);
}
}
// 2.1.0-beta add group name colored
if (!Common.IsFieldExist("dominion_group", "name_colored")) {
TableColumn dominion_group_name_colored = new TableColumn("name_colored", FieldType.STRING, false, false, true, false, "'未命名'");
new AddColumn(dominion_group_name_colored).table("dominion_group").ifNotExists().execute();
String copy_sql = "UPDATE dominion_group SET name_colored = name;";
DatabaseManager.instance.query(copy_sql);
TableColumn player_name_using_group_title_id = new TableColumn("using_group_title_id", FieldType.INT, false, false, true, false, -1);
new AddColumn(player_name_using_group_title_id).table("player_name").ifNotExists().execute();
}
// 2.3.0 change world name to world uid
if (!Common.IsFieldExist("dominion", "world_uid")) {
TableColumn dominion_world_uid = new TableColumn("world_uid", FieldType.STRING, false, false, true, false, "'00000000-0000-0000-0000-000000000000'");
new AddColumn(dominion_world_uid).table("dominion").ifNotExists().execute();
List<World> worlds = Dominion.instance.getServer().getWorlds();
for (World world : worlds) {
String sql = String.format("UPDATE dominion SET world_uid = '%s' WHERE world = '%s';", world.getUID().toString(), world.getName());
DatabaseManager.instance.query(sql);
}
DatabaseManager.instance.query("UPDATE dominion SET world_uid = '00000000-0000-0000-0000-000000000000' WHERE world = 'all';");
new RemoveColumn("world").table("dominion").IfExists().execute();
}
}
}

View File

@ -0,0 +1,241 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GroupLimit {
private final YamlConfiguration config;
private final File file_path;
private Integer min_y;
private Integer max_y;
private Integer size_x;
private Integer size_y;
private Integer size_z;
private Integer amount;
private Integer depth;
private Boolean vert;
private List<String> world_black_list;
private Double price;
private Boolean only_xz;
private Double refund;
public GroupLimit() {
this.file_path = null;
this.config = new YamlConfiguration();
}
public GroupLimit(File filePath) {
this.file_path = filePath;
config = YamlConfiguration.loadConfiguration(this.file_path);
setLimitMinY(config.getInt("MinY", -64));
setLimitMaxY(config.getInt("MaxY", 320));
if (getLimitMinY() >= getLimitMaxY()) {
XLogger.err("权限组 %s 的 MinY 不能大于等于 MaxY已重置为 -64 和 320", this.file_path.getName());
setLimitMinY(-64);
setLimitMaxY(320);
}
setLimitSizeX(config.getInt("SizeX", 128));
if (getLimitSizeX() <= 4 && getLimitSizeX() != -1) {
XLogger.err("权限组 %s 的 SizeX 设置过小,已重置为 128", this.file_path.getName());
setLimitSizeX(128);
}
setLimitSizeY(config.getInt("SizeY", 64));
if (getLimitSizeY() <= 4 && getLimitSizeY() != -1) {
XLogger.err("权限组 %s 的 SizeY 设置过小,已重置为 64", this.file_path.getName());
setLimitSizeY(64);
}
setLimitSizeZ(config.getInt("SizeZ", 128));
if (getLimitSizeZ() <= 4 && getLimitSizeZ() != -1) {
XLogger.err("权限组 %s 的 SizeZ 设置过小,已重置为 128", this.file_path.getName());
setLimitSizeZ(128);
}
setLimitAmount(config.getInt("Amount", 10));
if (getLimitAmount() <= 0 && getLimitAmount() != -1) {
XLogger.err("权限组 %s 的 Amount 设置不合法,已重置为 10", this.file_path.getName());
setLimitAmount(10);
}
setLimitDepth(config.getInt("Depth", 3));
if (getLimitDepth() <= 0 && getLimitDepth() != -1) {
XLogger.err("权限组 %s 的 Depth 设置不合法,已重置为 3", this.file_path.getName());
setLimitDepth(3);
}
setLimitVert(config.getBoolean("Vert", false));
setWorldBlackList(config.getStringList("WorldBlackList"));
setPrice(config.getDouble("Price", 10.0));
if (getPrice() < 0.0) {
XLogger.err("权限组 %s 的 Price 设置不合法,已重置为 10.0", this.file_path.getName());
setPrice(10.0);
}
setPriceOnlyXZ(config.getBoolean("OnlyXZ", false));
setRefundRatio(config.getDouble("Refund", 0.85));
if (getRefundRatio() < 0.0 || getRefundRatio() > 1.0) {
XLogger.err("权限组 %s 的 Refund 设置不合法,已重置为 0.85", this.file_path.getName());
setRefundRatio(0.85);
}
save(); // 保存一次确保文件中的数据是合法的
}
public Integer getLimitMinY() {
return min_y;
}
public Integer getLimitMaxY() {
return max_y;
}
public Integer getLimitSizeX() {
return size_x;
}
public Integer getLimitSizeY() {
return size_y;
}
public Integer getLimitSizeZ() {
return size_z;
}
public Integer getLimitAmount() {
return amount;
}
public Integer getLimitDepth() {
return depth;
}
public Boolean getLimitVert() {
return vert;
}
public List<String> getWorldBlackList() {
return world_black_list;
}
public Double getPrice() {
return price;
}
public Boolean getPriceOnlyXZ() {
return only_xz;
}
public Double getRefundRatio() {
return refund;
}
public void setLimitMinY(Integer min_y) {
this.min_y = min_y;
this.config.set("MinY", min_y);
this.save();
}
public void setLimitMaxY(Integer max_y) {
this.max_y = max_y;
this.config.set("MaxY", max_y);
this.save();
}
public void setLimitSizeX(Integer size_x) {
this.size_x = size_x;
this.config.set("SizeX", size_x);
this.save();
}
public void setLimitSizeY(Integer size_y) {
this.size_y = size_y;
this.config.set("SizeY", size_y);
this.save();
}
public void setLimitSizeZ(Integer size_z) {
this.size_z = size_z;
this.config.set("SizeZ", size_z);
this.save();
}
public void setLimitAmount(Integer amount) {
this.amount = amount;
this.config.set("Amount", amount);
this.save();
}
public void setLimitDepth(Integer depth) {
this.depth = depth;
this.config.set("Depth", depth);
this.save();
}
public void setLimitVert(Boolean vert) {
this.vert = vert;
this.config.set("Vert", vert);
this.save();
}
public void setWorldBlackList(List<String> world_black_list) {
this.world_black_list = world_black_list;
this.config.set("WorldBlackList", world_black_list);
this.save();
}
public void setPrice(Double price) {
this.price = price;
this.config.set("Price", price);
this.save();
}
public void setPriceOnlyXZ(Boolean only_xz) {
this.only_xz = only_xz;
this.config.set("OnlyXZ", only_xz);
this.save();
}
public void setRefundRatio(Double refund) {
this.refund = refund;
this.config.set("Refund", refund);
this.save();
}
private void save() {
if (file_path == null) {
return;
}
try {
config.save(file_path);
} catch (Exception e) {
XLogger.err("Failed to save group limit file: " + file_path.getName());
}
}
public static Map<String, GroupLimit> loadGroups(JavaPlugin plugin) {
Map<String, GroupLimit> groups = new HashMap<>();
File root = plugin.getDataFolder();
File groupsDir = new File(root, "groups");
if (!groupsDir.exists()) {
// 创建文件夹 并且从jar中复制文件
plugin.saveResource("groups/sponsor.yml", true);
}
File[] files = groupsDir.listFiles();
if (files == null) {
return groups;
}
for (File file : files) {
String name = file.getName();
if (!name.endsWith(".yml")) {
continue;
}
String groupName = name.substring(0, name.length() - 4);
GroupLimit group = new GroupLimit(file);
groups.put(groupName, group);
}
XLogger.info("共加载了 %d 个领地组。", groups.size());
return groups;
}
}

View File

@ -0,0 +1,51 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.minecraftpluginutils.XLogger;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
public class PlaceHolderApi extends PlaceholderExpansion {
private final JavaPlugin plugin;
public static PlaceHolderApi instance;
public PlaceHolderApi(JavaPlugin plugin) {
this.plugin = plugin;
this.register();
instance = this;
XLogger.info("成功注册 PlaceholderAPI 扩展");
}
@Override
public String onPlaceholderRequest(Player bukkitPlayer, @NotNull String params) {
if (params.equalsIgnoreCase("group_title")) {
GroupDTO group = Cache.instance.getPlayerUsingGroupTitle(bukkitPlayer.getUniqueId());
if (group == null) {
return "";
}
return group.getNameColoredBukkit();
}
return null; //
}
@Override
public @NotNull String getIdentifier() {
return "dominion";
}
@Override
public @NotNull String getAuthor() {
return "zhangyuheng";
}
@Override
public @NotNull String getVersion() {
return plugin.getPluginMeta().getVersion();
}
}

View File

@ -0,0 +1,35 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.DominionNode;
import cn.lunadeer.dominion.dtos.DominionDTO;
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;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
import static cn.lunadeer.dominion.utils.TuiUtils.notOp;
import static cn.lunadeer.dominion.tuis.dominion.DominionList.BuildTreeLines;
public class AllDominion {
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
if (notOp(player)) return;
int page = getPage(args, 1);
List<DominionNode> allDominions = DominionNode.BuildNodeTree(-1, DominionDTO.selectAll());
ListView view = ListView.create(10, "/dominion all_dominion");
view.title("所有领地");
view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("所有领地"));
view.addLines(BuildTreeLines(allDominions, 0));
view.showOn(player, page);
}
}

View File

@ -0,0 +1,82 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.ViewStyles;
import cn.lunadeer.minecraftpluginutils.stui.components.Button;
import cn.lunadeer.minecraftpluginutils.stui.components.Line;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class Menu {
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
int page = 1;
if (args.length == 2) {
try {
page = Integer.parseInt(args[1]);
} catch (Exception ignored) {
}
}
Line create = Line.create()
.append(Button.create("创建领地").setExecuteCommand("/dominion cui_create").build())
.append("以你为中心自动创建一个新的领地");
Line list = Line.create()
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append("查看我的领地");
Line title = Line.create()
.append(Button.create("称号列表").setExecuteCommand("/dominion title_list").build())
.append("查看/使用权限组称号");
Line template = Line.create()
.append(Button.create("模板列表").setExecuteCommand("/dominion template list").build())
.append("成员权限模板列表");
// Line help = Line.create()
// .append(Button.create("指令帮助").setExecuteCommand("/dominion help").build())
// .append("查看指令帮助");
Line link = Line.create()
.append(Button.create("使用文档").setOpenURL("https://ssl.lunadeer.cn:14448/doc/23/").build())
.append("在浏览器中打开使用文档");
Line migrate = Line.create()
.append(Button.create("迁移数据").setExecuteCommand("/dominion migrate_list").build())
.append("把你的领地从Residence迁移到Dominion");
Line all = Line.create()
.append(Button.create("所有领地").setExecuteCommand("/dominion all_dominion").build())
.append("查看所有领地");
Line config = Line.create()
.append(Button.create("系统配置").setExecuteCommand("/dominion sys_config").build())
.append("查看/修改系统配置");
Line reload_cache = Line.create()
.append(Button.create("重载缓存").setExecuteCommand("/dominion reload_cache").build())
.append("手动刷新缓存可解决一些玩家操作无效问题,不建议频繁操作");
Line reload_config = Line.create()
.append(Button.create("重载配置").setExecuteCommand("/dominion reload_config").build())
.append("重载配置文件");
ListView view = ListView.create(10, "/dominion menu");
view.title("Dominion 领地系统");
view.navigator(Line.create().append("主菜单"));
view.add(create);
view.add(list);
if (Dominion.config.getGroupTitleEnable()) view.add(title);
view.add(template);
// view.add(help);
view.add(link);
if (Dominion.config.getResidenceMigration()) {
view.add(migrate);
}
if (player.isOp()) {
view.add(Line.create().append(""));
view.add(Line.create().append(Component.text("--- 以下选项仅OP可见 ---", ViewStyles.main_color)));
view.add(all);
view.add(config);
view.add(reload_cache);
view.add(reload_config);
}
view.showOn(player, page);
}
}

View File

@ -0,0 +1,76 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.ResMigration;
import cn.lunadeer.dominion.utils.TuiUtils;
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;
import java.util.ArrayList;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
public class MigrateList {
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
if (!Dominion.config.getResidenceMigration()) {
Notification.error(sender, "Residence 迁移功能没有开启");
return;
}
int page = TuiUtils.getPage(args, 1);
ListView view = ListView.create(10, "/dominion migrate_list");
view.title("从 Residence 迁移数据");
view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("Res数据"));
List<ResMigration.ResidenceNode> res_data = Cache.instance.getResidenceData(player.getUniqueId());
if (res_data == null) {
view.add(Line.create().append("你没有可迁移的数据"));
} else {
view.addLines(BuildTreeLines(res_data, 0, page));
}
view.showOn(player, page);
}
public static List<Line> BuildTreeLines(List<ResMigration.ResidenceNode> dominionTree, Integer depth, int page) {
List<Line> lines = new ArrayList<>();
StringBuilder prefix = new StringBuilder();
for (int i = 0; i < depth; i++) {
prefix.append(" | ");
}
for (ResMigration.ResidenceNode node : dominionTree) {
TextComponent migrate = Button.create("迁移").setExecuteCommand("/dominion migrate " + node.name + " " + page).build();
Line line = Line.create();
if (depth == 0) {
line.append(migrate);
} else {
line.append(Component.text("[迁移]",
Style.style(TextColor.color(190, 190, 190),
TextDecoration.STRIKETHROUGH))
.hoverEvent(Component.text("子领地无法手动迁移,会随父领地自动迁移")));
}
line.append(prefix + node.name);
lines.add(line);
lines.addAll(BuildTreeLines(node.children, depth + 1, page));
}
return lines;
}
}

View File

@ -11,55 +11,68 @@ import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.tuis.Apis.getPage; import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
import static cn.lunadeer.dominion.utils.TuiUtils.notOp;
public class DominionConfig { public class SysConfig {
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
int page = getPage(args); if (notOp(player)) return;
ListView view = ListView.create(10, "/dominion config"); int page = getPage(args, 1);
ListView view = ListView.create(10, "/dominion sys_config");
view.title("系统配置"); view.title("系统配置");
view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("系统配置")); view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("系统配置"));
Line limitSize = Line.create() Line limitSize = Line.create()
.append(Component.text("领地尺寸限制")); .append(Component.text("领地尺寸限制"));
view.add(limitSize); view.add(limitSize);
Line spawnProtect = Line.create()
.append(Component.text(" 出生点保护范围"));
if (Dominion.config.getSpawnProtection() == -1) {
spawnProtect.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config spawn_protection 10 " + page).build());
} else {
spawnProtect.append(NumChanger.create(Dominion.config.getSpawnProtection(), "/dominion set_config spawn_protection").setPageNumber(page).build());
spawnProtect.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config spawn_protection -1 " + page).build());
}
view.add(spawnProtect);
Line limitSizeX = Line.create() Line limitSizeX = Line.create()
.append(Component.text(" X轴(东西)")); .append(Component.text(" X轴(东西)"));
if (Dominion.config.getLimitSizeX() == -1) { if (Dominion.config.getLimitSizeX(null) == -1) {
limitSizeX.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_size_x 64 " + page).build()); limitSizeX.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_size_x 64 " + page).build());
} else { } else {
limitSizeX.append(NumChanger.create(Dominion.config.getLimitSizeX(), "/dominion set_config limit_size_x").setPageNumber(page).build()); limitSizeX.append(NumChanger.create(Dominion.config.getLimitSizeX(null), "/dominion set_config limit_size_x").setPageNumber(page).build());
limitSizeX.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_size_x -1 " + page).build()); limitSizeX.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_size_x -1 " + page).build());
} }
view.add(limitSizeX); view.add(limitSizeX);
Line limitSizeZ = Line.create() Line limitSizeZ = Line.create()
.append(Component.text(" Z轴(南北)")); .append(Component.text(" Z轴(南北)"));
if (Dominion.config.getLimitSizeZ() == -1) { if (Dominion.config.getLimitSizeZ(null) == -1) {
limitSizeZ.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_size_z 64 " + page).build()); limitSizeZ.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_size_z 64 " + page).build());
} else { } else {
limitSizeZ.append(NumChanger.create(Dominion.config.getLimitSizeZ(), "/dominion set_config limit_size_z").setPageNumber(page).build()); limitSizeZ.append(NumChanger.create(Dominion.config.getLimitSizeZ(null), "/dominion set_config limit_size_z").setPageNumber(page).build());
limitSizeZ.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_size_z -1 " + page).build()); limitSizeZ.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_size_z -1 " + page).build());
} }
view.add(limitSizeZ); view.add(limitSizeZ);
Line limitSizeY = Line.create() Line limitSizeY = Line.create()
.append(Component.text(" Y轴(垂直)")); .append(Component.text(" Y轴(垂直)"));
if (!Dominion.config.getLimitVert()) { if (!Dominion.config.getLimitVert(null)) {
if (Dominion.config.getLimitSizeY() == -1) { if (Dominion.config.getLimitSizeY(null) == -1) {
limitSizeY.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_size_y 64 " + page).build()); limitSizeY.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_size_y 64 " + page).build());
} else { } else {
limitSizeY.append(NumChanger.create(Dominion.config.getLimitSizeY(), "/dominion set_config limit_size_y").setPageNumber(page).build()); limitSizeY.append(NumChanger.create(Dominion.config.getLimitSizeY(null), "/dominion set_config limit_size_y").setPageNumber(page).build());
limitSizeY.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_size_y -1 " + page).build()); limitSizeY.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_size_y -1 " + page).build());
} }
} else { } else {
limitSizeY.append(Component.text(Dominion.config.getLimitSizeY()) limitSizeY.append(Component.text(Dominion.config.getLimitSizeY(null))
.style(Style.style(TextDecoration.STRIKETHROUGH)) .style(Style.style(TextDecoration.STRIKETHROUGH))
.hoverEvent(Component.text("因为垂直自动延伸已开启,此设置不可手动修改"))); .hoverEvent(Component.text("因为垂直自动延伸已开启,此设置不可手动修改")));
} }
view.add(limitSizeY); view.add(limitSizeY);
if (Dominion.config.getLimitVert()) { if (Dominion.config.getLimitVert(null)) {
view.add(Line.create() view.add(Line.create()
.append("垂直自动延伸") .append("垂直自动延伸")
.append(Button.createGreen("").setExecuteCommand("/dominion set_config limit_vert false " + page).build())); .append(Button.createGreen("").setExecuteCommand("/dominion set_config limit_vert false " + page).build()));
@ -70,27 +83,27 @@ public class DominionConfig {
} }
Line limitMaxY = Line.create() Line limitMaxY = Line.create()
.append(Component.text("最高Y坐标限制")); .append(Component.text("最高Y坐标限制"));
limitMaxY.append(NumChanger.create(Dominion.config.getLimitMaxY(), "/dominion set_config limit_max_y").setPageNumber(page).build()); limitMaxY.append(NumChanger.create(Dominion.config.getLimitMaxY(null), "/dominion set_config limit_max_y").setPageNumber(page).build());
view.add(limitMaxY); view.add(limitMaxY);
Line limitMinY = Line.create() Line limitMinY = Line.create()
.append(Component.text("最低Y坐标限制")); .append(Component.text("最低Y坐标限制"));
limitMinY.append(NumChanger.create(Dominion.config.getLimitMinY(), "/dominion set_config limit_min_y").setPageNumber(page).build()); limitMinY.append(NumChanger.create(Dominion.config.getLimitMinY(null), "/dominion set_config limit_min_y").setPageNumber(page).build());
view.add(limitMinY); view.add(limitMinY);
Line limitAmount = Line.create() Line limitAmount = Line.create()
.append(Component.text("每个玩家领地数量限制")); .append(Component.text("每个玩家领地数量限制"));
if (Dominion.config.getLimitAmount() == -1) { if (Dominion.config.getLimitAmount(null) == -1) {
limitAmount.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_amount 3 " + page).build()); limitAmount.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_amount 3 " + page).build());
} else { } else {
limitAmount.append(NumChanger.create(Dominion.config.getLimitAmount(), "/dominion set_config limit_amount").setPageNumber(page).build()); limitAmount.append(NumChanger.create(Dominion.config.getLimitAmount(null), "/dominion set_config limit_amount").setPageNumber(page).build());
limitAmount.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_amount -1 " + page).build()); limitAmount.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_amount -1 " + page).build());
} }
view.add(limitAmount); view.add(limitAmount);
Line limitDepth = Line.create() Line limitDepth = Line.create()
.append(Component.text("领地深度限制")); .append(Component.text("领地深度限制"));
if (Dominion.config.getLimitDepth() == -1) { if (Dominion.config.getLimitDepth(null) == -1) {
limitDepth.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_depth 64 " + page).build()); limitDepth.append(Component.text("无限制")).append(Button.create("设置数值").setExecuteCommand("/dominion set_config limit_depth 64 " + page).build());
} else { } else {
limitDepth.append(NumChanger.create(Dominion.config.getLimitDepth(), "/dominion set_config limit_depth").setPageNumber(page).build()); limitDepth.append(NumChanger.create(Dominion.config.getLimitDepth(null), "/dominion set_config limit_depth").setPageNumber(page).build());
limitDepth.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_depth -1 " + page).build()); limitDepth.append(Button.create("设置无限制").setExecuteCommand("/dominion set_config limit_depth -1 " + page).build());
} }
view.add(limitDepth); view.add(limitDepth);
@ -133,9 +146,9 @@ public class DominionConfig {
view.add(economy); view.add(economy);
Line price = Line.create() Line price = Line.create()
.append(Component.text(" 每方块单价")) .append(Component.text(" 每方块单价"))
.append(NumChanger.create(Dominion.config.getEconomyPrice(), "/dominion set_config economy_price", 0.1).setPageNumber(page).build()); .append(NumChanger.create(Dominion.config.getEconomyPrice(null), "/dominion set_config economy_price", 0.1).setPageNumber(page).build());
view.add(price); view.add(price);
if (Dominion.config.getEconomyOnlyXZ()) { if (Dominion.config.getEconomyOnlyXZ(null)) {
view.add(Line.create() view.add(Line.create()
.append(" 仅计价平面积") .append(" 仅计价平面积")
.append(Button.createGreen("").setExecuteCommand("/dominion set_config economy_only_xz false " + page).build())); .append(Button.createGreen("").setExecuteCommand("/dominion set_config economy_only_xz false " + page).build()));
@ -146,9 +159,18 @@ public class DominionConfig {
} }
Line refund = Line.create() Line refund = Line.create()
.append(Component.text(" 删除/缩小领地退还比例")) .append(Component.text(" 删除/缩小领地退还比例"))
.append(NumChanger.create(Dominion.config.getEconomyRefund(), "/dominion set_config economy_refund", 0.01).setPageNumber(page).build()); .append(NumChanger.create(Dominion.config.getEconomyRefund(null), "/dominion set_config economy_refund", 0.01).setPageNumber(page).build());
view.add(refund); view.add(refund);
} }
if (Dominion.config.getResidenceMigration()) {
view.add(Line.create()
.append("是否允许从Residence迁移数据")
.append(Button.createGreen("").setExecuteCommand("/dominion set_config residence_migration false " + page).build()));
} else {
view.add(Line.create()
.append("是否允许从Residence迁移数据")
.append(Button.createRed("").setExecuteCommand("/dominion set_config residence_migration true " + page).build()));
}
view.showOn(player, page); view.showOn(player, page);
} }
} }

View File

@ -0,0 +1,57 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
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;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class TitleList {
public static void show(CommandSender sender, int page) {
show(sender, new String[]{String.valueOf(page)});
}
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
int page = getPage(args, 1);
ListView view = ListView.create(10, "/dominion title_list");
view.title("我可使用的权限组称号");
view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("权限组称号列表"));
List<GroupDTO> groups = Cache.instance.getBelongGroupsOf(player.getUniqueId());
GroupDTO using = Cache.instance.getPlayerUsingGroupTitle(player.getUniqueId());
// 将其拥有的所有领地的权限组称号都加入列表 - 领地所有者可以使用其领地的任意权限组称号
List<DominionDTO> dominions = DominionDTO.selectByOwner(player.getUniqueId());
for (DominionDTO dominion : dominions) {
List<GroupDTO> groupsOfDom = GroupDTO.selectByDominionId(dominion.getId());
groups.addAll(groupsOfDom);
}
for (GroupDTO group : groups) {
DominionDTO dominion = Cache.instance.getDominion(group.getDomID());
Line line = Line.create();
if (using != null && using.getId().equals(group.getId())) {
line.append(Button.createRed("卸下").setExecuteCommand("/dominion use_title -1").build());
} else {
line.append(Button.createGreen("使用").setExecuteCommand("/dominion use_title " + group.getId()).build());
}
line.append(group.getNameColoredComponent()).append("来自领地:" + dominion.getName());
view.add(line);
}
view.showOn(player, page);
}
}

View File

@ -1,7 +1,7 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis.dominion;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.DominionNode; import cn.lunadeer.dominion.DominionNode;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.stui.ListView; import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.ViewStyles; import cn.lunadeer.minecraftpluginutils.stui.ViewStyles;
import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Button;
@ -14,23 +14,25 @@ import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.commands.Helper.playerAdminDominions; import static cn.lunadeer.dominion.commands.Helper.playerAdminDominions;
import static cn.lunadeer.dominion.tuis.Apis.getPage; import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class ListDominion { public class DominionList {
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
int page = getPage(args); int page = getPage(args, 1);
ListView view = ListView.create(10, "/dominion list"); ListView view = ListView.create(10, "/dominion list");
// 根据id从小到大排序
List<String> admin_dominions = playerAdminDominions(sender);
view.title("我的领地列表"); view.title("我的领地列表");
view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("我的领地")); view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("我的领地"));
view.addLines(BuildTreeLines(Cache.instance.getDominionTreeByPlayer(player.getName()), 0)); view.addLines(BuildTreeLines(DominionNode.BuildNodeTree(-1, DominionDTO.selectByOwner(player.getUniqueId())), 0));
view.add(Line.create().append(Component.text("-= 以下为你拥有管理员权限的领地 =-", ViewStyles.main_color))); List<String> admin_dominions = playerAdminDominions(sender);
if (!admin_dominions.isEmpty()) {
view.add(Line.create().append(""));
view.add(Line.create().append(Component.text("--- 以下为你拥有管理员权限的领地 ---", ViewStyles.main_color)));
}
for (String dominion : admin_dominions) { for (String dominion : admin_dominions) {
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + dominion).build(); TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + dominion).build();
view.add(Line.create().append(manage).append(dominion)); view.add(Line.create().append(manage).append(dominion));
@ -38,18 +40,16 @@ public class ListDominion {
view.showOn(player, page); view.showOn(player, page);
} }
private static List<Line> BuildTreeLines(List<DominionNode> dominionTree, Integer depth) { public static List<Line> BuildTreeLines(List<DominionNode> dominionTree, Integer depth) {
List<Line> lines = new ArrayList<>(); List<Line> lines = new ArrayList<>();
StringBuilder prefix = new StringBuilder(); StringBuilder prefix = new StringBuilder();
for (int i = 0; i < depth; i++) { prefix.append(" | ".repeat(Math.max(0, depth)));
prefix.append(" | ");
}
for (DominionNode node : dominionTree) { for (DominionNode node : dominionTree) {
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.dominion.getName()).build(); TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.getDominion().getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.dominion.getName()).build(); TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.getDominion().getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.dominion.getName()); Line line = Line.create().append(delete).append(manage).append(prefix + node.getDominion().getName());
lines.add(line); lines.add(line);
lines.addAll(BuildTreeLines(node.children, depth + 1)); lines.addAll(BuildTreeLines(node.getChildren(), depth + 1));
} }
return lines; return lines;
} }

View File

@ -1,16 +1,18 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis.dominion;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.stui.ListView; import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Button;
import cn.lunadeer.minecraftpluginutils.stui.components.Line; import cn.lunadeer.minecraftpluginutils.stui.components.Line;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.tuis.Apis.getDominionNameArg_1; import static cn.lunadeer.dominion.utils.TuiUtils.*;
import static cn.lunadeer.dominion.tuis.Apis.noAuthToManage;
public class DominionManage { public class DominionManage {
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
@ -22,15 +24,22 @@ public class DominionManage {
return; return;
} }
if (noAuthToManage(player, dominion)) return; if (noAuthToManage(player, dominion)) return;
int page = getPage(args, 2);
Line size_info = Line.create() Line size_info = Line.create()
.append(Button.create("详细信息").setExecuteCommand("/dominion info " + dominion.getName()).build()) .append(Button.create("详细信息").setExecuteCommand("/dominion info " + dominion.getName()).build())
.append("查看领地详细信息"); .append("查看领地详细信息");
Line env_info = Line.create()
.append(Button.create("环境设置").setExecuteCommand("/dominion env_setting " + dominion.getName()).build())
.append("设置领地内的一些非玩家相关效果");
Line flag_info = Line.create() Line flag_info = Line.create()
.append(Button.create("访客权限").setExecuteCommand("/dominion flag_info " + dominion.getName()).build()) .append(Button.create("访客权限").setExecuteCommand("/dominion guest_setting " + dominion.getName()).build())
.append("访客在此领地的权限"); .append("访客在此领地的权限");
Line privilege_list = Line.create() Line privilege_list = Line.create()
.append(Button.create("成员权限").setExecuteCommand("/dominion privilege_list " + dominion.getName()).build()) .append(Button.create("成员管理").setExecuteCommand("/dominion member list " + dominion.getName()).build())
.append("管理此领地成员的权限"); .append("管理此领地成员的权限");
Line group_list = Line.create()
.append(Button.create("权限组").setExecuteCommand("/dominion group list " + dominion.getName()).build())
.append("管理此领地的权限组");
Line set_tp = Line.create() Line set_tp = Line.create()
.append(Button.create("设置传送点").setExecuteCommand("/dominion set_tp_location " + dominion.getName()).build()) .append(Button.create("设置传送点").setExecuteCommand("/dominion set_tp_location " + dominion.getName()).build())
.append("设置当前位置为此领地传送点"); .append("设置当前位置为此领地传送点");
@ -43,6 +52,11 @@ public class DominionManage {
Line leave_msg = Line.create() Line leave_msg = Line.create()
.append(Button.create("编辑离开提示语").setExecuteCommand("/dominion cui_edit_leave_message " + dominion.getName()).build()) .append(Button.create("编辑离开提示语").setExecuteCommand("/dominion cui_edit_leave_message " + dominion.getName()).build())
.append("当玩家离开领地时显示的消息"); .append("当玩家离开领地时显示的消息");
Line map_color = Line.create()
.append(Button.create("设置颜色").setExecuteCommand("/dominion cui_set_map_color " + dominion.getName()).build())
.append(Component.text("设置卫星地图上的地块颜色")
.append(Component.text(dominion.getColor(),
TextColor.color(dominion.getColorR(), dominion.getColorG(), dominion.getColorB()))));
ListView view = ListView.create(10, "/dominion manage " + dominion.getName()); ListView view = ListView.create(10, "/dominion manage " + dominion.getName());
view.title("领地 " + dominion.getName() + " 管理界面") view.title("领地 " + dominion.getName() + " 管理界面")
.navigator(Line.create() .navigator(Line.create()
@ -50,12 +64,17 @@ public class DominionManage {
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build()) .append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(dominion.getName())) .append(dominion.getName()))
.add(size_info) .add(size_info)
.add(env_info)
.add(flag_info) .add(flag_info)
.add(privilege_list) .add(privilege_list)
.add(group_list)
.add(set_tp) .add(set_tp)
.add(rename) .add(rename)
.add(join_msg) .add(join_msg)
.add(leave_msg) .add(leave_msg);
.showOn(player, 1); if (Dominion.config.getBlueMap()) {
view.add(map_color);
}
view.showOn(player, page);
} }
} }

View File

@ -0,0 +1,56 @@
package cn.lunadeer.dominion.tuis.dominion.manage;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
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 org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class EnvSetting {
public static void show(CommandSender sender, String[] args) {
if (args.length < 2) {
Notification.error(sender, "用法: /dominion env_setting <领地名称> [页码]");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地 %s 不存在", args[1]);
return;
}
int page = getPage(args, 2);
ListView view = ListView.create(10, "/dominion env_setting " + dominion.getName());
view.title("领地 " + dominion.getName() + " 环境设置")
.navigator(Line.create()
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append("环境设置"));
for (Flag flag : Flag.getDominionOnlyFlagsEnabled()) {
view.add(createOption(flag, dominion.getFlagValue(flag), dominion.getName(), page));
}
view.showOn(player, page);
}
private static Line createOption(Flag flag, boolean value, String dominion_name, int page) {
if (value) {
return Line.create()
.append(Button.createGreen("").setExecuteCommand("/dominion set " + flag.getFlagName() + " false " + dominion_name + " " + page).build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
} else {
return Line.create()
.append(Button.createRed("").setExecuteCommand("/dominion set " + flag.getFlagName() + " true " + dominion_name + " " + page).build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
}
}
}

View File

@ -1,4 +1,4 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis.dominion.manage;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
@ -10,37 +10,32 @@ import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class DominionFlagInfo { public class GuestSetting {
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length < 2) { if (args.length < 2) {
Notification.error(sender, "用法: /dominion flag_info <领地名称> [页码]"); Notification.error(sender, "用法: /dominion guest_setting <领地名称> [页码]");
return; return;
} }
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]); DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) { if (dominion == null) {
Notification.error(sender, "领地 %s 不存在", args[1]); Notification.error(sender, "领地 %s 不存在", args[1]);
return; return;
} }
int page = 1; int page = getPage(args, 2);
if (args.length == 3) { ListView view = ListView.create(10, "/dominion guest_setting " + dominion.getName());
try {
page = Integer.parseInt(args[2]);
} catch (Exception ignored) {
}
}
ListView view = ListView.create(10, "/dominion flag_info " + dominion.getName());
view.title("领地 " + dominion.getName() + " 访客权限") view.title("领地 " + dominion.getName() + " 访客权限")
.navigator(Line.create() .navigator(Line.create()
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()) .append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build()) .append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build()) .append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append("访客权限")); .append("访客权限"));
for (Flag flag : Flag.getDominionFlagsEnabled()) { for (Flag flag : Flag.getPrivilegeFlagsEnabled()) {
view.add(createOption(flag, dominion.getFlagValue(flag), dominion.getName(), page)); view.add(createOption(flag, dominion.getFlagValue(flag), dominion.getName(), page));
} }
view.showOn(player, page); view.showOn(player, page);

View File

@ -1,21 +1,20 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis.dominion.manage;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.PlayerController; import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.Particle;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import cn.lunadeer.minecraftpluginutils.stui.View; import cn.lunadeer.minecraftpluginutils.stui.View;
import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Button;
import cn.lunadeer.minecraftpluginutils.stui.components.Line; import cn.lunadeer.minecraftpluginutils.stui.components.Line;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.tuis.Apis.getDominionNameArg_1; import static cn.lunadeer.dominion.utils.TuiUtils.getDominionNameArg_1;
public class DominionSizeInfo { public class SizeInfo {
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
@ -33,13 +32,13 @@ public class DominionSizeInfo {
Integer z2 = dominion.getZ2(); Integer z2 = dominion.getZ2();
View view = View.create(); View view = View.create();
view.title("领地 " + dominion.getName() + " 的尺寸信息") view.title("领地 " + dominion.getName() + " 的尺寸信息")
.subtitle("领地归属" + owner.getLastKnownName()) .subtitle("领地所有者" + owner.getLastKnownName())
.addLine(Line.create().append("领地大小:").append((x2 - x1) + " x" + (y2 - y1) + " x" + (z2 - z1))) .addLine(Line.create().append("领地大小:").append(dominion.getWidthX() + " x " + dominion.getHeight() + " x " + dominion.getWidthZ()))
.addLine(Line.create().append("中心坐标:").append((x1 + (x2 - x1) / 2) + " " + (y1 + (y2 - y1) / 2) + " " + (z1 + (z2 - z1) / 2))) .addLine(Line.create().append("中心坐标:").append((x1 + (x2 - x1) / 2) + " " + (y1 + (y2 - y1) / 2) + " " + (z1 + (z2 - z1) / 2)))
.addLine(Line.create().append("垂直高度:").append(String.valueOf(y2 - y1))) .addLine(Line.create().append("垂直高度:").append(String.valueOf(dominion.getHeight())))
.addLine(Line.create().append("Y轴坐标").append(y1 + " ~ " + y2)) .addLine(Line.create().append("Y轴坐标").append(y1 + " ~ " + y2))
.addLine(Line.create().append("水平面积:").append(String.valueOf((x2 - x1) * (z2 - z1)))) .addLine(Line.create().append("水平面积:").append(String.valueOf(dominion.getSquare())))
.addLine(Line.create().append("领地体积:").append(String.valueOf((x2 - x1) * (y2 - y1) * (z2 - z1)))) .addLine(Line.create().append("领地体积:").append(String.valueOf(dominion.getVolume())))
.addLine(Line.create().append("传送点坐标:").append( .addLine(Line.create().append("传送点坐标:").append(
dominion.getTpLocation() == null ? dominion.getTpLocation() == null ?
"" : "" :
@ -47,10 +46,8 @@ public class DominionSizeInfo {
)) ))
.actionBar(Line.create() .actionBar(Line.create()
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build()) .append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append(Button.create("权限列表").setExecuteCommand("/dominion flag_info " + dominion.getName()).build())) .append(Button.create("访客权限").setExecuteCommand("/dominion guest_setting " + dominion.getName()).build()))
.showOn(player); .showOn(player);
ParticleRender.showBoxFace(Dominion.instance, player, Particle.showBorder(player, dominion);
dominion.getLocation1(),
dominion.getLocation2());
} }
} }

View File

@ -0,0 +1,93 @@
package cn.lunadeer.dominion.tuis.dominion.manage.group;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.TuiUtils;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
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 org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.noAuthToManage;
public class GroupList {
public static void show(CommandSender sender, String dominionName) {
show(sender, new String[]{"", "", dominionName});
}
public static void show(CommandSender sender, String dominionName, int page) {
show(sender, new String[]{"", "", dominionName, String.valueOf(page)});
}
public static void show(CommandSender sender, String[] args) {
if (args.length < 3) {
Notification.error(sender, "用法: /dominion group list <领地名称> [页码]");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[2]);
if (dominion == null) {
Notification.error(sender, "领地 %s 不存在", args[2]);
return;
}
if (noAuthToManage(player, dominion)) return;
int page = TuiUtils.getPage(args, 3);
List<GroupDTO> groups = GroupDTO.selectByDominionId(dominion.getId());
ListView view = ListView.create(10, "/dominion group list " + dominion.getName());
view.title("权限组列表");
view.navigator(
Line.create()
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append("权限组列表")
);
Button create_btn = Button.createGreen("创建权限组")
.setHoverText("创建一个新的权限组")
.setExecuteCommand("/dominion cui_create_group " + dominion.getName());
view.add(new Line().append(create_btn.build()));
for (GroupDTO group : groups) {
Line line = new Line();
Button del = Button.createRed("删除")
.setHoverText("删除权限组 " + group.getName())
.setExecuteCommand("/dominion group delete " + dominion.getName() + " " + group.getName());
Button edit = Button.create("编辑")
.setHoverText("编辑权限组 " + group.getName())
.setExecuteCommand("/dominion group setting " + dominion.getName() + " " + group.getName());
Button add = Button.createGreen("+")
.setHoverText("添加成员到权限组 " + group.getName())
.setExecuteCommand("/dominion group select_member " + dominion.getName() + " " + group.getName() + " " + page);
line.append(del.build()).append(edit.build()).append(group.getNameColoredComponent()).append(add.build());
view.add(line);
List<MemberDTO> players = MemberDTO.selectByGroupId(group.getId());
XLogger.debug("players: " + players.size());
for (MemberDTO playerPrivilege : players) {
PlayerDTO p = PlayerDTO.select(playerPrivilege.getPlayerUUID());
if (p == null) continue;
Button remove = Button.createRed("-")
.setHoverText("" + p.getLastKnownName() + " 移出权限组 " + group.getName())
.setExecuteCommand("/dominion group remove_member " + dominion.getName() + " " + group.getName() + " " + p.getLastKnownName() + " " + page);
Line playerLine = new Line().setDivider("");
playerLine.append(Component.text(" "));
playerLine.append(remove.build()).append(" | " + p.getLastKnownName());
view.add(playerLine);
}
view.add(new Line().append(""));
}
view.showOn(player, page);
}
}

View File

@ -0,0 +1,101 @@
package cn.lunadeer.dominion.tuis.dominion.manage.group;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.utils.TuiUtils;
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 org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.noAuthToManage;
public class GroupSetting {
public static void show(CommandSender sender, String dominionName, String groupName) {
show(sender, new String[]{"", "", dominionName, groupName});
}
public static void show(CommandSender sender, String dominionName, String groupName, Integer page) {
show(sender, new String[]{"", "", dominionName, groupName, page.toString()});
}
public static void show(CommandSender sender, String[] args) {
if (args.length < 4) {
Notification.error(sender, "用法: /dominion group setting <领地名称> <权限组名称> [页码]");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[2]);
if (dominion == null) {
Notification.error(sender, "领地 %s 不存在", args[2]);
return;
}
if (noAuthToManage(player, dominion)) return;
int page = TuiUtils.getPage(args, 4);
GroupDTO group = GroupDTO.select(dominion.getId(), args[3]);
if (group == null) {
Notification.error(sender, "权限组 %s 不存在", args[3]);
return;
}
ListView view = ListView.create(10, "/dominion group setting " + dominion.getName() + " " + group.getName());
view.title(Component.text("权限组 ").append(group.getNameColoredComponent()).append(Component.text(" 管理")));
view.navigator(
Line.create()
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append(Button.create("权限组列表").setExecuteCommand("/dominion group list " + dominion.getName()).build())
.append("权限组管理")
);
Button rename_btn = Button.create("重命名此权限组")
.setHoverText("重命名权限组 " + group.getName())
.setExecuteCommand("/dominion cui_rename_group " + dominion.getName() + " " + group.getName());
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))
.build())
.append("管理员"));
view.add(createOption(Flag.GLOW, group.getFlagValue(Flag.GLOW), dominion.getName(), group.getName(), page));
} else {
view.add(Line.create()
.append(Button.createRed("")
.setExecuteCommand(parseCommand(dominion.getName(), group.getName(), "admin", true, page))
.build())
.append("管理员"));
for (Flag flag : Flag.getPrivilegeFlagsEnabled()) {
view.add(createOption(flag, group.getFlagValue(flag), dominion.getName(), group.getName(), page));
}
}
view.showOn(player, page);
}
private static Line createOption(Flag flag, boolean value, String DominionName, String groupName, int page) {
if (value) {
return Line.create()
.append(Button.createGreen("")
.setExecuteCommand(parseCommand(DominionName, groupName, flag.getFlagName(), false, page))
.build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
} else {
return Line.create()
.append(Button.createRed("")
.setExecuteCommand(parseCommand(DominionName, groupName, flag.getFlagName(), true, page))
.build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
}
}
private static String parseCommand(String dominionName, String groupName, String flagName, boolean value, int page) {
return String.format("/dominion group set_flag %s %s %s %s %d", dominionName, groupName, flagName, value, page);
}
}

View File

@ -0,0 +1,57 @@
package cn.lunadeer.dominion.tuis.dominion.manage.group;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
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;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
import static cn.lunadeer.dominion.utils.TuiUtils.noAuthToManage;
public class SelectMember {
public static void show(CommandSender sender, String[] args) {
if (args.length < 4) {
Notification.error(sender, "用法: /dominion group select_member <领地名称> <权限组名称> [回显页码] [页码]");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[2]);
if (dominion == null) {
Notification.error(sender, "领地 %s 不存在", args[2]);
return;
}
if (noAuthToManage(player, dominion)) return;
GroupDTO group = GroupDTO.select(dominion.getId(), args[3]);
if (group == null) {
Notification.error(sender, "权限组不存在");
return;
}
int backPage = getPage(args, 4);
int page = getPage(args, 5);
ListView view = ListView.create(10, "/dominion group select_member " + dominion.getName() + " " + group.getName() + " " + backPage);
view.title("选择成员");
Line sub = Line.create().append("选择成员添加到权限组 " + group.getName())
.append(Button.create("返回").setExecuteCommand("/dominion group list " + dominion.getName() + " " + backPage).build());
view.subtitle(sub);
List<MemberDTO> members = MemberDTO.selectByDomGroupId(dominion.getId(), -1);
for (MemberDTO member : members) {
PlayerDTO p = PlayerDTO.select(member.getPlayerUUID());
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)
.build()));
}
view.showOn(player, page);
}
}

View File

@ -0,0 +1,119 @@
package cn.lunadeer.dominion.tuis.dominion.manage.member;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.*;
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 org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.CommandParser;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
import static cn.lunadeer.dominion.utils.TuiUtils.noAuthToManage;
public class MemberList {
public static void show(CommandSender sender, String dominionName, Integer page) {
show(sender, new String[]{"", "", dominionName, page.toString()});
}
public static void show(CommandSender sender, String dominionName) {
show(sender, new String[]{"", "", dominionName});
}
public static void show(CommandSender sender, String[] args) {
if (args.length < 3) {
Notification.error(sender, "用法: /dominion member list <领地名称> [页码]");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[2]);
if (dominion == null) {
Notification.error(sender, "领地 %s 不存在", args[2]);
return;
}
int page = getPage(args, 3);
ListView view = ListView.create(10, "/dominion member list " + dominion.getName());
if (noAuthToManage(player, dominion)) return;
List<MemberDTO> privileges = MemberDTO.select(dominion.getId());
view.title("领地 " + dominion.getName() + " 成员列表");
view.navigator(
Line.create()
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append("成员列表")
);
view.add(Line.create().append(Button.create("添加成员")
.setExecuteCommand(CommandParser("/dominion member select_player %s", dominion.getName())).build()));
for (MemberDTO privilege : privileges) {
PlayerDTO p_player = PlayerDTO.select(privilege.getPlayerUUID());
if (p_player == null) continue;
GroupDTO group = Cache.instance.getGroup(privilege.getGroupId());
Line line = Line.create();
if (group != null) {
line.append(groupTag);
} else if (privilege.getAdmin()) {
line.append(adminTag);
} else {
if (!privilege.getFlagValue(Flag.MOVE)) {
line.append(banTag);
} else {
line.append(normalTag);
}
}
Button prev = Button.createGreen("权限")
.setHoverText("配置成员权限")
.setExecuteCommand(CommandParser("/dominion member setting %s %s", dominion.getName(), p_player.getLastKnownName()));
Button remove = Button.createRed("移除")
.setHoverText("将此成员移出(变为访客)")
.setExecuteCommand(CommandParser("/dominion member remove %s %s", dominion.getName(), p_player.getLastKnownName()));
if (!player.getUniqueId().equals(dominion.getOwner())) {
boolean disable = false;
if (group == null) {
if (privilege.getAdmin()) {
disable = true;
}
} else {
if (group.getAdmin()) {
disable = true;
}
}
if (disable) {
prev.setDisabled("你不是领地主人,无法编辑管理员权限");
remove.setDisabled("你不是领地主人,无法移除管理员");
}
}
if (group != null) {
prev.setDisabled(String.format("此成员属于权限组 %s 无法单独编辑权限", group.getName()));
}
line.append(remove.build());
line.append(prev.build());
line.append(p_player.getLastKnownName());
view.add(line);
}
view.showOn(player, page);
}
private static final TextComponent adminTag = Component.text("[A]", Style.style(TextColor.color(97, 97, 210)))
.hoverEvent(Component.text("这是一个管理员"));
private static final TextComponent normalTag = Component.text("[N]", Style.style(TextColor.color(255, 255, 255)))
.hoverEvent(Component.text("这是一个普通成员"));
private static final TextComponent banTag = Component.text("[B]", Style.style(TextColor.color(255, 67, 0)))
.hoverEvent(Component.text("这是一个黑名单成员"));
private static final TextComponent groupTag = Component.text("[G]", Style.style(TextColor.color(0, 185, 153)))
.hoverEvent(Component.text("这个成员在一个权限组里"));
}

View File

@ -1,9 +1,9 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis.dominion.manage.member;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.stui.ListView; import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Button;
@ -12,36 +12,41 @@ import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.tuis.Apis.getDominionNameArg_2; import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
import static cn.lunadeer.dominion.tuis.Apis.noAuthToManage; import static cn.lunadeer.dominion.utils.TuiUtils.noAuthToManage;
public class MemberSetting {
public static void show(CommandSender sender, String dominionName, String playerName, Integer page) {
show(sender, new String[]{"", "", dominionName, playerName, page.toString()});
}
public static void show(CommandSender sender, String dominionName, String playerName) {
show(sender, new String[]{"", "", dominionName, playerName});
}
public class PrivilegeInfo {
// /dominion privilege_info <玩家名称> [领地名称] [页码]
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender); if (args.length < 3) {
if (player == null) return; Notification.error(sender, "用法: /dominion member setting <领地名称> <玩家名称> [页码]");
DominionDTO dominion = getDominionNameArg_2(player, args); return;
int page = 1; }
if (args.length == 4) { Player player = playerOnly(sender);
try { if (player == null) return;
page = Integer.parseInt(args[3]); DominionDTO dominion = DominionDTO.select(args[2]);
} catch (Exception ignored) { if (dominion == null) {
} Notification.error(sender, "领地 %s 不存在", args[2]);
}
String playerName = args[1];
if (dominion == null) {
Notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion privilege_info <玩家名称> [领地名称]");
return; return;
} }
ListView view = ListView.create(10, "/dominion privilege_info " + playerName + " " + dominion.getName());
if (noAuthToManage(player, dominion)) return; if (noAuthToManage(player, dominion)) return;
int page = getPage(args, 4);
String playerName = args[3];
ListView view = ListView.create(10, "/dominion member setting " + dominion.getName() + " " + playerName);
PlayerDTO playerDTO = PlayerDTO.select(playerName); PlayerDTO playerDTO = PlayerDTO.select(playerName);
if (playerDTO == null) { if (playerDTO == null) {
Notification.error(sender, "玩家 %s 不存在", playerName); Notification.error(sender, "玩家 %s 不存在", playerName);
return; return;
} }
PlayerPrivilegeDTO privilege = PlayerPrivilegeDTO.select(playerDTO.getUuid(), dominion.getId()); MemberDTO privilege = MemberDTO.select(playerDTO.getUuid(), dominion.getId());
if (privilege == null) { if (privilege == null) {
Notification.warn(sender, "玩家 %s 不是领地 %s 的成员", playerName, dominion.getName()); Notification.warn(sender, "玩家 %s 不是领地 %s 的成员", playerName, dominion.getName());
return; return;
@ -52,33 +57,49 @@ public class PrivilegeInfo {
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()) .append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("我的领地").setExecuteCommand("/dominion list").build()) .append(Button.create("我的领地").setExecuteCommand("/dominion list").build())
.append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build()) .append(Button.create("管理界面").setExecuteCommand("/dominion manage " + dominion.getName()).build())
.append(Button.create("成员列表").setExecuteCommand("/dominion privilege_list " + dominion.getName()).build()) .append(Button.create("成员列表").setExecuteCommand("/dominion member list " + dominion.getName()).build())
.append("成员权限") .append("成员权限")
); );
view.add(Line.create().append(Button.createGreen("套用模板")
.setHoverText("选择一个权限模板套用")
.setExecuteCommand("/dominion member select_template " + dominion.getName() + " " + playerName).build()));
if (privilege.getAdmin()) { if (privilege.getAdmin()) {
view.add(Line.create() view.add(Line.create()
.append(Button.createGreen("").setExecuteCommand("/dominion set_privilege " + playerName + " admin false " + dominion.getName() + " " + page).build()) .append(Button.createGreen("").setExecuteCommand(
parseCommand(dominion.getName(), playerName, "admin", false, page)
).build())
.append("管理员")); .append("管理员"));
view.add(createOption(Flag.GLOW, privilege.getFlagValue(Flag.GLOW), playerName, dominion.getName(), page));
} else { } else {
view.add(Line.create() view.add(Line.create()
.append(Button.createRed("").setExecuteCommand("/dominion set_privilege " + playerName + " admin true " + dominion.getName() + " " + page).build()) .append(Button.createRed("").setExecuteCommand(
parseCommand(dominion.getName(), playerName, "admin", true, page)
).build())
.append("管理员")); .append("管理员"));
}
for (Flag flag : Flag.getPrivilegeFlagsEnabled()) { for (Flag flag : Flag.getPrivilegeFlagsEnabled()) {
view.add(createOption(flag, privilege.getFlagValue(flag), playerName, dominion.getName(), page)); view.add(createOption(flag, privilege.getFlagValue(flag), playerName, dominion.getName(), page));
} }
}
view.showOn(player, page); view.showOn(player, page);
} }
private static Line createOption(Flag flag, boolean value, String player_name, String dominion_name, int page) { private static Line createOption(Flag flag, boolean value, String player_name, String dominion_name, int page) {
if (value) { if (value) {
return Line.create() return Line.create()
.append(Button.createGreen("").setExecuteCommand("/dominion set_privilege " + player_name + " " + flag.getFlagName() + " false " + dominion_name + " " + page).build()) .append(Button.createGreen("").setExecuteCommand(
parseCommand(dominion_name, player_name, flag.getFlagName(), false, page)
).build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription()))); .append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
} else { } else {
return Line.create() return Line.create()
.append(Button.createRed("").setExecuteCommand("/dominion set_privilege " + player_name + " " + flag.getFlagName() + " true " + dominion_name + " " + page).build()) .append(Button.createRed("").setExecuteCommand(
parseCommand(dominion_name, player_name, flag.getFlagName(), true, page)
).build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription()))); .append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
} }
} }
private static String parseCommand(String dominionName, String playerName, String flagName, boolean value, int page) {
return String.format("/dominion member set_flag %s %s %s %s %d", dominionName, playerName, flagName, value, page);
}
} }

View File

@ -1,7 +1,8 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis.dominion.manage.member;
import cn.lunadeer.dominion.controllers.PlayerController; import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.stui.ListView; import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Button;
import cn.lunadeer.minecraftpluginutils.stui.components.Line; import cn.lunadeer.minecraftpluginutils.stui.components.Line;
@ -10,26 +11,29 @@ import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.CommandParser;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class SelectPlayer { public class SelectPlayer {
// /dominion select_player_create_privilege <领地名称> [页码] public static void show(CommandSender sender, String dominionName, Integer page) {
show(sender, new String[]{"", "", dominionName, page.toString()});
}
public static void show(CommandSender sender, String[] args) { public static void show(CommandSender sender, String[] args) {
if (args.length < 3) {
Notification.error(sender, "用法: /dominion member select_player <领地名称> [页码]");
return;
}
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
int page = 1; int page = getPage(args, 3);
if (args.length == 3) { String dominion_name = args[2];
try { ListView view = ListView.create(10, "/dominion member select_player " + dominion_name);
page = Integer.parseInt(args[2]);
} catch (Exception ignored) {
}
}
String dominion_name = args[1];
ListView view = ListView.create(10, "/dominion select_player_create_privilege " + dominion_name);
Line sub = Line.create() Line sub = Line.create()
.append("只能选择已经登录过的玩家") .append("只能选择已经登录过的玩家")
.append(Button.create("搜索").setExecuteCommand("/dominion cui_create_privilege " + dominion_name).build()) .append(Button.create("搜索").setExecuteCommand("/dominion cui_member_add " + dominion_name).build())
.append(Button.create("返回").setExecuteCommand("/dominion privilege_list " + dominion_name).build()); .append(Button.create("返回").setExecuteCommand("/dominion member list " + dominion_name).build());
view.title("选择玩家添加为成员").subtitle(sub); view.title("选择玩家添加为成员").subtitle(sub);
List<PlayerDTO> players = PlayerController.allPlayers(); List<PlayerDTO> players = PlayerController.allPlayers();
for (PlayerDTO p : players) { for (PlayerDTO p : players) {
@ -38,7 +42,7 @@ public class SelectPlayer {
} }
view.add(Line.create(). view.add(Line.create().
append(Button.create(p.getLastKnownName()) append(Button.create(p.getLastKnownName())
.setExecuteCommand("/dominion create_privilege " + p.getLastKnownName() + " " + dominion_name + " b") .setExecuteCommand(CommandParser("/dominion member add %s %s", dominion_name, p.getLastKnownName()))
.build())); .build()));
} }
view.showOn(player, page); view.showOn(player, page);

View File

@ -0,0 +1,56 @@
package cn.lunadeer.dominion.tuis.dominion.manage.member;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;
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 org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.CommandParser;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class SelectTemplate {
public static void show(CommandSender sender, String[] args) {
if (args.length < 4) {
// /dominion member select_template <领地名称> <玩家名称> [页码]
Notification.error(sender, "用法: /dominion member select_template <领地名称> <玩家名称> [页码]");
return;
}
Player player = playerOnly(sender);
if (player == null) return;
String dominionName = args[2];
String playerName = args[3];
int page = getPage(args, 4);
List<PrivilegeTemplateDTO> templates = PrivilegeTemplateDTO.selectAll(player.getUniqueId());
ListView view = ListView.create(10, "/dominion member select_template " + dominionName + " " + playerName);
view.title("选择一个模板");
Line sub = Line.create()
.append("套用在领地 " + dominionName + " 的成员 " + playerName + " 身上")
.append(Button.create("返回").setExecuteCommand("/dominion member setting " + dominionName + " " + playerName).build());
view.subtitle(sub);
for (PrivilegeTemplateDTO template : templates) {
// /dominion member apply_template <领地名称> <成员名称> <模板名称>
view.add(Line.create()
.append(Button.create("选择")
.setExecuteCommand(CommandParser("/dominion member apply_template %s %s %s", dominionName, playerName, template.getName()))
.build())
.append(Component.text(template.getName())));
}
view.showOn(player, page);
}
}

View File

@ -0,0 +1,53 @@
package cn.lunadeer.dominion.tuis.template;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;
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;
import java.util.List;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class TemplateList {
public static void show(CommandSender sender) {
show(sender, 1);
}
public static void show(CommandSender sender, int page) {
show(sender, new String[]{"", "", String.valueOf(page)});
}
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
int page = getPage(args, 2);
ListView view = ListView.create(10, "/dominion template list");
List<PrivilegeTemplateDTO> templates = PrivilegeTemplateDTO.selectAll(player.getUniqueId());
view.title("成员权限模板列表");
view.navigator(Line.create().append(Button.create("主菜单").setExecuteCommand("/dominion menu").build()).append("模板列表"));
Button create = Button.create("创建成员权限模板").setExecuteCommand("/dominion cui_template_create")
.setHoverText("创建一个新的成员权限模板");
view.add(Line.create().append(create.build()));
for (PrivilegeTemplateDTO template : templates) {
Button manage = Button.createGreen("配置").setExecuteCommand("/dominion template setting " + template.getName());
Button delete = Button.createRed("删除").setExecuteCommand("/dominion template delete " + template.getName());
Line line = Line.create()
.append(delete.build())
.append(manage.build())
.append(template.getName());
view.add(line);
}
view.showOn(player, page);
}
}

View File

@ -0,0 +1,73 @@
package cn.lunadeer.dominion.tuis.template;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PrivilegeTemplateDTO;
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 org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.utils.TuiUtils.getPage;
public class TemplateSetting {
// /dominion template setting <模板名称> [页码]
public static void show(CommandSender sender, String templateName, int page) {
show(sender, new String[]{"", "", templateName, String.valueOf(page)});
}
public static void show(CommandSender sender, String templateName) {
show(sender, new String[]{"", "", templateName});
}
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
int page = getPage(args, 3);
PrivilegeTemplateDTO template = PrivilegeTemplateDTO.select(player.getUniqueId(), args[2]);
if (template == null) {
Notification.error(sender, "模板 %s 不存在", args[2]);
return;
}
ListView view = ListView.create(10, "/dominion template setting " + template.getName());
view.title("模板 " + args[1] + " 权限管理");
view.navigator(Line.create()
.append(Button.create("主菜单").setExecuteCommand("/dominion menu").build())
.append(Button.create("模板列表").setExecuteCommand("/dominion template list").build())
.append("模板管理")
);
// /dominion template_set_flag <模板名称> <权限名称> <true/false> [页码]
if (template.getAdmin()) {
view.add(Line.create()
.append(Button.createGreen("").setExecuteCommand("/dominion template set_flag " + template.getName() + " admin false " + page).build())
.append("管理员"));
} else {
view.add(Line.create()
.append(Button.createRed("").setExecuteCommand("/dominion template set_flag " + template.getName() + " admin true " + page).build())
.append("管理员"));
}
for (Flag flag : Flag.getPrivilegeFlagsEnabled()) {
view.add(createOption(flag, template.getFlagValue(flag), template.getName(), page));
}
view.showOn(player, page);
}
private static Line createOption(Flag flag, boolean value, String templateName, int page) {
if (value) {
return Line.create()
.append(Button.createGreen("").setExecuteCommand("/dominion template set_flag " + templateName + " " + flag.getFlagName() + " false " + page).build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
} else {
return Line.create()
.append(Button.createRed("").setExecuteCommand("/dominion template set_flag " + templateName + " " + flag.getFlagName() + " true " + page).build())
.append(Component.text(flag.getDisplayName()).hoverEvent(Component.text(flag.getDescription())));
}
}
}

View File

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

View File

@ -0,0 +1,49 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
public class CommandUtils {
public static Player playerOnly(CommandSender sender) {
if (!(sender instanceof Player)) {
Notification.error(sender, "该命令只能由玩家执行");
return null;
}
return (Player) sender;
}
public static boolean hasPermission(CommandSender sender, String permission) {
if (!sender.hasPermission(permission)) {
Notification.error(sender, "你没有 %s 权限执行此命令", permission);
return false;
}
return true;
}
public static Map<Integer, Location> autoPoints(Player player) {
Integer size = Dominion.config.getAutoCreateRadius();
Location location = player.getLocation();
Location location1 = new Location(location.getWorld(), location.getX() - size, location.getY() - size, location.getZ() - size);
Location location2 = new Location(location.getWorld(), location.getX() + size, location.getY() + size, location.getZ() + size);
if (Dominion.config.getLimitVert(player)) {
location1.setY(Dominion.config.getLimitMinY(player));
location2.setY(Dominion.config.getLimitMaxY(player) - 1);
}
Map<Integer, Location> points = new HashMap<>();
points.put(0, location1);
points.put(1, location2);
Dominion.pointsSelect.put(player.getUniqueId(), points);
return points;
}
public static String CommandParser(String command, Object... args) {
return String.format(command, args);
}
}

View File

@ -1,26 +1,25 @@
package cn.lunadeer.dominion.controllers; package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.dominion.dtos.MemberDTO;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.BlockFace; import org.jetbrains.annotations.NotNull;
import org.bukkit.entity.Player;
import java.util.List; public class ControllerUtils {
public class Apis {
public static boolean notOwner(AbstractOperator player, DominionDTO dominion) { public static boolean notOwner(AbstractOperator player, DominionDTO dominion) {
if (player.isOp()) return false; if (player.isOp() && Dominion.config.getLimitOpBypass()) return false;
return !dominion.getOwner().equals(player.getUniqueId()); return !dominion.getOwner().equals(player.getUniqueId());
} }
public static boolean noAuthToChangeFlags(AbstractOperator player, DominionDTO dominion) { public static boolean noAuthToChangeFlags(AbstractOperator player, DominionDTO dominion) {
if (player.isOp()) return false; if (player.isOp() && Dominion.config.getLimitOpBypass()) return false;
if (!dominion.getOwner().equals(player.getUniqueId())) { if (!dominion.getOwner().equals(player.getUniqueId())) {
PlayerPrivilegeDTO privileges = PlayerPrivilegeDTO.select(player.getUniqueId(), dominion.getId()); MemberDTO privileges = MemberDTO.select(player.getUniqueId(), dominion.getId());
if (privileges == null || !privileges.getAdmin()) { if (privileges == null || !privileges.getAdmin()) {
player.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你不是领地 %s 的拥有者或管理员,无权修改权限", dominion.getName())); player.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你不是领地 %s 的拥有者或管理员,无权修改权限", dominion.getName()));
return true; return true;
@ -42,8 +41,11 @@ public class Apis {
player.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "无法获取你的位置信息")); player.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "无法获取你的位置信息"));
return null; return null;
} }
DominionDTO dominion = Cache.instance.getDominion(location); DominionDTO dominion = Cache.instance.getDominionByLoc(location);
if (dominion == null || dominion.getParentDomId() != -1) { if (dominion == null) {
return null;
}
if (dominion.getParentDomId() == -1) {
return dominion; return dominion;
} else { } else {
player.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你当前在子领地内,请指定要操作的领地名称")); player.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你当前在子领地内,请指定要操作的领地名称"));
@ -51,4 +53,20 @@ public class Apis {
} }
} }
/**
* 检查一个成员是否是管理员
* 此方法会同时尝试搜索玩家所在的权限组是否是管理员
*
* @param member 成员权限
* @return 是否是管理员
*/
public static boolean isAdmin(@NotNull MemberDTO member) {
GroupDTO group = GroupDTO.select(member.getGroupId());
if (group == null) {
return member.getAdmin();
} else {
return group.getAdmin();
}
}
} }

View File

@ -0,0 +1,108 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.dynmap.DynmapCommonAPI;
import org.dynmap.DynmapCommonAPIListener;
import org.dynmap.markers.AreaMarker;
import org.dynmap.markers.MarkerAPI;
import org.dynmap.markers.MarkerSet;
import java.util.List;
import java.util.Map;
public class DynmapConnect extends DynmapCommonAPIListener {
public static DynmapConnect instance;
private MarkerSet markerSet_dominion = null;
private MarkerSet markerSet_mca = null;
public DynmapConnect() {
DynmapCommonAPIListener.register(this);
instance = this;
}
@Override
public void apiEnabled(DynmapCommonAPI dynmapCommonAPI) {
MarkerAPI markerAPI = dynmapCommonAPI.getMarkerAPI();
this.markerSet_dominion = markerAPI.getMarkerSet("dominion");
if (this.markerSet_dominion == null) {
this.markerSet_dominion = markerAPI.createMarkerSet("dominion", "Dominion领地", null, false);
}
this.markerSet_mca = markerAPI.getMarkerSet("mca");
if (this.markerSet_mca == null) {
this.markerSet_mca = markerAPI.createMarkerSet("mca", "MCA文件", null, false);
}
XLogger.info("Dynmap 成功注册");
}
private void setDominionMarker(DominionDTO dominion) {
String nameLabel = "<div>" + dominion.getName() + "</div>";
double[] xx = {dominion.getX1(), dominion.getX2()};
double[] zz = {dominion.getZ1(), dominion.getZ2()};
if (dominion.getWorld() == null) {
return;
}
AreaMarker marker = this.markerSet_dominion.createAreaMarker(
dominion.getId().toString(),
nameLabel,
true,
dominion.getWorld().getName(),
xx,
zz,
false
);
marker.setFillStyle(0.2, dominion.getColorHex());
marker.setLineStyle(1, 0.8, dominion.getColorHex());
XLogger.debug("Add dominion marker: " + dominion.getName());
}
public void setDominionMarkers(List<DominionDTO> dominions) {
Scheduler.runTaskAsync(() -> {
if (this.markerSet_dominion == null) {
XLogger.warn("无法连接到 Dynmap如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能。");
return;
}
this.markerSet_dominion.getAreaMarkers().forEach(AreaMarker::deleteMarker);
for (DominionDTO dominion : dominions) {
this.setDominionMarker(dominion);
}
});
}
public void setMCAMarkers(Map<String, List<String>> mca_files) {
Scheduler.runTaskAsync(() -> {
if (this.markerSet_mca == null) {
XLogger.warn("无法连接到 Dynmap如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能。");
return;
}
this.markerSet_mca.getAreaMarkers().forEach(AreaMarker::deleteMarker);
for (Map.Entry<String, List<String>> entry : mca_files.entrySet()) {
for (String file : entry.getValue()) {
String[] cords = file.split("\\.");
int world_x1 = Integer.parseInt(cords[1]) * 512;
int world_x2 = (Integer.parseInt(cords[1]) + 1) * 512;
int world_z1 = Integer.parseInt(cords[2]) * 512;
int world_z2 = (Integer.parseInt(cords[2]) + 1) * 512;
String nameLabel = "<div>" + file + "</div>";
double[] xx = {world_x1, world_x2};
double[] zz = {world_z1, world_z2};
AreaMarker marker = this.markerSet_mca.createAreaMarker(
file,
nameLabel,
true,
entry.getKey(),
xx,
zz,
false
);
marker.setFillStyle(0.2, 0x00CC00);
marker.setLineStyle(1, 0.8, 0x00CC00);
}
}
});
}
}

View File

@ -1,24 +1,26 @@
package cn.lunadeer.dominion.events; package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.GroupDTO;
import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.title.Title;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class Apis { import javax.annotation.Nullable;
public static boolean canByPass(Player player, DominionDTO dom, PlayerPrivilegeDTO prev) {
public class EventUtils {
public static boolean canByPass(Player player, DominionDTO dom, MemberDTO prev) {
if (player.isOp() && Dominion.config.getLimitOpBypass()) { if (player.isOp() && Dominion.config.getLimitOpBypass()) {
return true; return true;
} }
@ -29,7 +31,12 @@ public class Apis {
return true; return true;
} }
if (prev != null) { if (prev != null) {
if (prev.getGroupId() == -1) {
return prev.getAdmin(); return prev.getAdmin();
} else {
GroupDTO group = Cache.instance.getGroup(prev.getGroupId());
return group != null && group.getAdmin();
}
} }
return false; return false;
} }
@ -38,7 +45,7 @@ public class Apis {
if (inv.getLocation() == null) { if (inv.getLocation() == null) {
return null; return null;
} else { } else {
return Cache.instance.getDominion(inv.getLocation()); return Cache.instance.getDominionByLoc(inv.getLocation());
} }
} }
@ -49,14 +56,21 @@ public class Apis {
if (dom == null) { if (dom == null) {
return true; return true;
} }
PlayerPrivilegeDTO prev = Cache.instance.getPlayerPrivilege(player, dom); MemberDTO prev = Cache.instance.getMember(player, dom);
if (canByPass(player, dom, prev)) { if (canByPass(player, dom, prev)) {
return true; return true;
} }
if (prev != null) { if (prev != null) {
GroupDTO group = Cache.instance.getGroup(prev.getGroupId());
if (prev.getGroupId() != -1 && group != null) {
if (group.getFlagValue(flag)) {
return true;
}
} else {
if (prev.getFlagValue(flag)) { if (prev.getFlagValue(flag)) {
return true; return true;
} }
}
} else { } else {
if (dom.getFlagValue(flag)) { if (dom.getFlagValue(flag)) {
return true; return true;
@ -66,15 +80,14 @@ public class Apis {
String.format("你没有 %s (%s) 权限", flag.getDisplayName(), flag.getDescription()), String.format("你没有 %s (%s) 权限", flag.getDisplayName(), flag.getDescription()),
Style.style(TextColor.color(0xFF0000), TextDecoration.BOLD)) Style.style(TextColor.color(0xFF0000), TextDecoration.BOLD))
.hoverEvent(Component.text(flag.getDescription())); .hoverEvent(Component.text(flag.getDescription()));
// Notification.error(player, msg); Notification.actionBar(player, msg);
player.sendActionBar(msg);
if (event != null) { if (event != null) {
event.setCancelled(true); event.setCancelled(true);
} }
return false; return false;
} }
public static boolean checkFlag(DominionDTO dom, Flag flag, Cancellable event) { public static boolean checkFlag(@Nullable DominionDTO dom, @NotNull Flag flag, @Nullable Cancellable event) {
if (!flag.getEnable()) { if (!flag.getEnable()) {
return true; return true;
} }
@ -84,7 +97,9 @@ public class Apis {
if (dom.getFlagValue(flag)) { if (dom.getFlagValue(flag)) {
return true; return true;
} }
if (event != null) {
event.setCancelled(true); event.setCancelled(true);
}
return false; return false;
} }
} }

View File

@ -0,0 +1,31 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import java.util.List;
import java.util.Map;
public class MapRender {
public static void render() {
if (Dominion.config.getBlueMap()) {
BlueMapConnect.render();
}
if (Dominion.config.getDynmap()) {
DynmapConnect.instance.setDominionMarkers(Cache.instance.getDominions());
}
}
public static void renderMCA(Map<String, List<String>> mca_files) {
if (Dominion.config.getBlueMap()) {
BlueMapConnect.renderMCA(mca_files);
}
if (Dominion.config.getDynmap()) {
DynmapConnect.instance.setMCAMarkers(mca_files);
}
}
}

View File

@ -0,0 +1,21 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import org.bukkit.entity.Player;
public class Particle {
public static void showBorder(Player player, DominionDTO dominion) {
ParticleRender.showBoxFace(player,
dominion.getLocation1().getWorld(),
dominion.getLocation1().getBlockX(),
dominion.getLocation1().getBlockY(),
dominion.getLocation1().getBlockZ(),
dominion.getLocation2().getBlockX(),
dominion.getLocation2().getBlockY(),
dominion.getLocation2().getBlockZ()
);
}
}

View File

@ -0,0 +1,147 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.Residence.Message;
import cn.lunadeer.dominion.utils.Residence.Permission;
import cn.lunadeer.dominion.utils.Residence.Residence;
import cn.lunadeer.dominion.utils.Residence.SaveFile;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.plugin.java.JavaPlugin;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.*;
public class ResMigration {
public static class ResidenceNode {
public UUID owner;
public World world;
public String name;
public Location loc1;
public Location loc2;
public Location tpLoc;
public String joinMessage;
public String leaveMessage;
public List<ResidenceNode> children = new ArrayList<>();
}
public static List<ResidenceNode> extractFromResidence(JavaPlugin plugin) {
List<ResidenceNode> dominions = new ArrayList<>();
File resSave = new File(plugin.getDataFolder().getParent(), "Residence");
resSave = new File(resSave, "Save");
resSave = new File(resSave, "Worlds");
if (!resSave.exists()) {
XLogger.info("Residence Save not found, skipping migration");
return dominions;
}
// list .yml files
File[] files = resSave.listFiles((dir, name) -> name.endsWith(".yml"));
if (files == null || files.length == 0) {
XLogger.info("No save files found");
return dominions;
}
for (File file : files) {
try {
dominions.addAll(processWorld(file));
} catch (Exception e) {
XLogger.err("Failed to process file: %s, %s", file.getName(), e.getMessage());
}
}
XLogger.info("Extract %d residences", dominions.size());
return dominions;
}
private static ResidenceNode parseDominion(String name, World world, Residence res, SaveFile save) {
String[] loc = res.Areas.values().toArray()[0].toString().split(":");
if (loc.length != 6) {
XLogger.warn("Invalid location: " + res.Areas.get("main"));
return null;
}
ResidenceNode dominionNode = new ResidenceNode();
dominionNode.owner = UUID.fromString(res.Permissions.OwnerUUID);
dominionNode.world = world;
dominionNode.name = name;
dominionNode.joinMessage = save.Messages.get(res.Messages).EnterMessage;
dominionNode.leaveMessage = save.Messages.get(res.Messages).LeaveMessage;
dominionNode.loc1 = new Location(world, Double.parseDouble(loc[0]), Double.parseDouble(loc[1]), Double.parseDouble(loc[2]));
dominionNode.loc2 = new Location(world, Double.parseDouble(loc[3]), Double.parseDouble(loc[4]), Double.parseDouble(loc[5]));
if (res.TPLoc != null) {
String[] tpLocStr = res.TPLoc.split(":");
if (tpLocStr.length >= 3) {
dominionNode.tpLoc = new Location(world, Double.parseDouble(tpLocStr[0]), Double.parseDouble(tpLocStr[1]), Double.parseDouble(tpLocStr[2]));
}
}
if (res.Subzones != null) {
for (Map.Entry<String, Residence> entry : res.Subzones.entrySet()) {
ResidenceNode sub = parseDominion(entry.getKey(), world, entry.getValue(), save);
if (sub != null) {
dominionNode.children.add(sub);
}
}
}
return dominionNode;
}
private static Map<String, Residence> parseResYml(Map<String, Object> zones) {
Map<String, Residence> res = new HashMap<>();
for (Map.Entry<String, Object> entry : zones.entrySet()) {
Map<String, Object> zone = (Map<String, Object>) entry.getValue();
Residence residence = new Residence();
if (zone.containsKey("TPLoc")) {
residence.setTPLoc((String) zone.get("TPLoc"));
}
residence.setMessages((int) zone.get("Messages"));
Permission permission = new Permission();
permission.OwnerUUID = ((Map<String, Object>) zone.get("Permissions")).get("OwnerUUID").toString();
permission.OwnerLastKnownName = ((Map<String, Object>) zone.get("Permissions")).get("OwnerLastKnownName").toString();
residence.setPermissions(permission);
residence.setAreas((Map<String, String>) zone.get("Areas"));
if (zone.containsKey("Subzones")) {
residence.setSubzones(parseResYml((Map<String, Object>) zone.get("Subzones")));
}
res.put(entry.getKey(), residence);
}
return res;
}
private static List<ResidenceNode> processWorld(File saveFile) throws Exception {
XLogger.debug("=====================================");
XLogger.debug("Processing file: %s", saveFile.getName());
String worldName = saveFile.getName().replace("res_", "").replace(".yml", "");
World world = Dominion.instance.getServer().getWorld(worldName);
InputStream inputStream = Files.newInputStream(saveFile.toPath());
Map<String, Object> yaml = new Yaml().load(inputStream);
SaveFile save = new SaveFile();
Map<Integer, Object> Messages = (Map<Integer, Object>) yaml.get("Messages");
Map<Integer, Message> messages = new HashMap<>();
for (Map.Entry<Integer, Object> entry : Messages.entrySet()) {
Map<String, String> message = (Map<String, String>) entry.getValue();
Message msg = new Message();
msg.EnterMessage = (String) message.get("EnterMessage");
msg.LeaveMessage = (String) message.get("LeaveMessage");
messages.put(entry.getKey(), msg);
}
save.setMessages(messages);
Map<String, Object> Residences = (Map<String, Object>) yaml.get("Residences");
save.Residences = parseResYml(Residences);
inputStream.close();
List<ResidenceNode> dominions = new ArrayList<>();
for (Map.Entry<String, Residence> entry : save.Residences.entrySet()) {
String name = entry.getKey();
Residence residence = entry.getValue();
ResidenceNode dominion = parseDominion(name, world, residence, save);
dominions.add(dominion);
}
return dominions;
}
}

View File

@ -0,0 +1,24 @@
package cn.lunadeer.dominion.utils.Residence;
public class Message {
public String LeaveMessage;
public String EnterMessage;
// getters and setters
public String getLeaveMessage() {
return LeaveMessage;
}
public void setLeaveMessage(String leaveMessage) {
LeaveMessage = leaveMessage;
}
public String getEnterMessage() {
return EnterMessage;
}
public void setEnterMessage(String enterMessage) {
EnterMessage = enterMessage;
}
}

View File

@ -0,0 +1,24 @@
package cn.lunadeer.dominion.utils.Residence;
public class Permission {
public String OwnerUUID;
public String OwnerLastKnownName;
// getters and setters
public String getOwnerUUID() {
return OwnerUUID;
}
public void setOwnerUUID(String ownerUUID) {
OwnerUUID = ownerUUID;
}
public String getOwnerLastKnownName() {
return OwnerLastKnownName;
}
public void setOwnerLastKnownName(String ownerLastKnownName) {
OwnerLastKnownName = ownerLastKnownName;
}
}

View File

@ -0,0 +1,53 @@
package cn.lunadeer.dominion.utils.Residence;
import java.util.Map;
public class Residence {
public String TPLoc;
public Map<String, Residence> Subzones;
public int Messages;
public Permission Permissions;
public Map<String, String> Areas;
// getters and setters
public String getTPLoc() {
return TPLoc;
}
public void setTPLoc(String TPLoc) {
this.TPLoc = TPLoc;
}
public Map<String, Residence> getSubzones() {
return Subzones;
}
public void setSubzones(Map<String, Residence> subzones) {
Subzones = subzones;
}
public int getMessages() {
return Messages;
}
public void setMessages(int messages) {
Messages = messages;
}
public Permission getPermissions() {
return Permissions;
}
public void setPermissions(Permission permissions) {
Permissions = permissions;
}
public Map<String, String> getAreas() {
return Areas;
}
public void setAreas(Map<String, String> areas) {
Areas = areas;
}
}

View File

@ -0,0 +1,25 @@
package cn.lunadeer.dominion.utils.Residence;
import java.util.Map;
public class SaveFile {
public Map<String, Residence> Residences;
public Map<Integer, Message> Messages;
// getters and setters
public Map<String, Residence> getResidences() {
return Residences;
}
public void setResidences(Map<String, Residence> residences) {
Residences = residences;
}
public Map<Integer, Message> getMessages() {
return Messages;
}
public void setMessages(Map<Integer, Message> messages) {
Messages = messages;
}
}

View File

@ -1,8 +1,8 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.MemberDTO;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.stui.ListView; import cn.lunadeer.minecraftpluginutils.stui.ListView;
import cn.lunadeer.minecraftpluginutils.stui.components.Button; import cn.lunadeer.minecraftpluginutils.stui.components.Button;
@ -10,16 +10,15 @@ import cn.lunadeer.minecraftpluginutils.stui.components.Line;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.utils.CommandUtils.playerOnly;
import static cn.lunadeer.dominion.controllers.Apis.getPlayerCurrentDominion;
public class Apis { public class TuiUtils {
public static int getPage(String[] args) { public static int getPage(String[] args, int pos) {
int page = 1; int page = 1;
if (args.length == 2) { if (args.length > pos) {
try { try {
page = Integer.parseInt(args[1]); page = Integer.parseInt(args[pos]);
} catch (Exception e) { } catch (Exception e) {
return 1; return 1;
} }
@ -43,26 +42,10 @@ public class Apis {
} }
} }
/**
* 尝试从 arg[2] 获取领地名称
* 如果没有此参数则会尝试获取玩家当前所在位置
*
* @param player 玩家
* @param args 参数
* @return 领地信息
*/
public static DominionDTO getDominionNameArg_2(Player player, String[] args) {
if (args.length >= 3) {
return DominionDTO.select(args[2]);
} else {
return Cache.instance.getPlayerCurrentDominion(player);
}
}
public static boolean noAuthToManage(Player player, DominionDTO dominion) { public static boolean noAuthToManage(Player player, DominionDTO dominion) {
if (player.isOp()) return false; if (player.isOp()) return false;
if (!dominion.getOwner().equals(player.getUniqueId())) { if (!dominion.getOwner().equals(player.getUniqueId())) {
PlayerPrivilegeDTO privileges = PlayerPrivilegeDTO.select(player.getUniqueId(), dominion.getId()); MemberDTO privileges = MemberDTO.select(player.getUniqueId(), dominion.getId());
if (privileges == null || !privileges.getAdmin()) { if (privileges == null || !privileges.getAdmin()) {
Notification.error(player, "你不是领地 %s 的拥有者或管理员,无权访问此页面", dominion.getName()); Notification.error(player, "你不是领地 %s 的拥有者或管理员,无权访问此页面", dominion.getName());
return true; return true;
@ -71,14 +54,22 @@ public class Apis {
return false; return false;
} }
public static boolean notOp(CommandSender sender) {
if (!sender.isOp()) {
Notification.error(sender, "你没有权限访问此页面");
return true;
}
return false;
}
public static void printHelp(CommandSender sender, String[] args) { public static void printHelp(CommandSender sender, String[] args) {
Player player = playerOnly(sender); Player player = playerOnly(sender);
if (player == null) return; if (player == null) return;
int page = getPage(args); int page = getPage(args, 1);
ListView view = ListView.create(10, "/dominion help"); ListView view = ListView.create(10, "/dominion help");
view.title("领地插件命令帮助 <>表示必填参数 []表示可选参数") view.title("领地插件命令帮助 <>表示必填参数 []表示可选参数")
.add(Line.create().append("打开交互菜单").append(Button.create("/dominion menu").setExecuteCommand("/dominion menu").build())) .add(Line.create().append("打开交互菜单").append("/dominion menu"))
.add(Line.create().append("查看帮助").append(Button.create("/dominion help [页码]").setExecuteCommand("/dominion help 1").build())) .add(Line.create().append("查看帮助").append("/dominion help [页码]"))
.add(Line.create().append("创建领地").append("/dominion create <领地名称>")) .add(Line.create().append("创建领地").append("/dominion create <领地名称>"))
.add(Line.create().append("自动创建领地").append("/dominion auto_create <领地名称>")) .add(Line.create().append("自动创建领地").append("/dominion auto_create <领地名称>"))
.add(Line.create().append("创建子领地").append("/dominion create_sub <子领地名称> [父领地名称]")) .add(Line.create().append("创建子领地").append("/dominion create_sub <子领地名称> [父领地名称]"))
@ -97,18 +88,6 @@ public class Apis {
.add(Line.create().append("---[管理员指令]---")) .add(Line.create().append("---[管理员指令]---"))
.add(Line.create().append("刷新缓存").append(Button.create("/dominion reload_cache").setExecuteCommand("/dominion reload_cache").build())) .add(Line.create().append("刷新缓存").append(Button.create("/dominion reload_cache").setExecuteCommand("/dominion reload_cache").build()))
.add(Line.create().append("重载配置").append(Button.create("/dominion reload_config").setExecuteCommand("/dominion reload_config").build())) .add(Line.create().append("重载配置").append(Button.create("/dominion reload_config").setExecuteCommand("/dominion reload_config").build()))
// 以下指令主要被用于 ui 触发
.add(Line.create().append("---[以下主要用于UI触发]---"))
.add(Line.create().append("列出所有领地").append(Button.create("/dominion list [页码]").setExecuteCommand("/dominion list").build()))
.add(Line.create().append("查看领地信息").append(Button.create("/dominion info [领地名称]").setExecuteCommand("/dominion info").build()))
.add(Line.create().append("查看领地权限信息").append(Button.create("/dominion flag_info <领地名称> [页码]").setExecuteCommand("/dominion flag_info").build()))
.add(Line.create().append("设置领地权限").append("/dominion set <权限名称> <true/false> [领地名称]"))
.add(Line.create().append("创建玩家特权").append("/dominion create_privilege <玩家名称> [领地名称]"))
.add(Line.create().append("设置玩家特权").append("/dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]"))
.add(Line.create().append("重置玩家特权").append("/dominion clear_privilege <玩家名称> [领地名称]"))
.add(Line.create().append("查看领地玩家特权列表").append("/dominion privilege_list [领地名称] [页码]"))
.add(Line.create().append("查看玩家特权信息").append("/dominion privilege_info <玩家名称> [领地名称] [页码]"))
.add(Line.create().append("系统配置").append(Button.create("/dominion config [页码]").setExecuteCommand("/dominion config").build()))
.showOn(player, page); .showOn(player, page);
} }

View File

@ -1,5 +1,5 @@
Database: Database:
Type: sqlite # pgsql, sqlite Type: sqlite # pgsql, sqlite, mysql
Host: localhost Host: localhost
Port: 5432 Port: 5432
Name: dominion Name: dominion
@ -10,6 +10,7 @@ Database:
AutoCreateRadius: 10 #-1 表示不开启 AutoCreateRadius: 10 #-1 表示不开启
Limit: Limit:
SpawnProtection: 10 # 出生点保护半径 出生点此范围内不允许圈地 -1 表示不开启
MinY: -64 # 最小Y坐标 MinY: -64 # 最小Y坐标
MaxY: 320 # 最大Y坐标 MaxY: 320 # 最大Y坐标
SizeX: 128 # X方向最大长度 -1表示不限制 SizeX: 128 # X方向最大长度 -1表示不限制
@ -49,8 +50,22 @@ FlyPermissionNodes:
- essentials.fly - essentials.fly
- cmi.command.fly - cmi.command.fly
BlueMap: true # 是否允许玩家从 Residence 迁移领地数据
ResidenceMigration: false
# 权限组称号 - 使用权限组当作称号(需要PlaceholderAPI插件)
# Papi: %dominion_group_title%
# 前后缀如需要加颜色请使用这种格式 &#ffffff
GroupTitle:
Enable: false
Prefix: "["
Suffix: "]"
BlueMap: false
Dynmap: false
CheckUpdate: true CheckUpdate: true
Debug: false Debug: false
Timer: false # 性能测试计时器

View File

@ -0,0 +1,20 @@
# >---------------------------------<
# | 圈地限制特殊权限组配置 |
# >---------------------------------<
# 此文件可以作为模板,你可以将此文件复制后重命名为你想要的权限组名,然后修改里面的配置
# 如果你想给赞助玩家或者VIP一些特殊优惠例如更少的圈地价格、更大的领地等你可以在这里配置
# 详细说明参阅 > https://ssl.lunadeer.cn:14448/doc/82/
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
WorldBlackList: [ ] # 不允许领地的世界
Price: 10.0 # 方块单价
OnlyXZ: false # 是否只计算xz平面积
Refund: 0.85 # 删除领地退还比例

View File

@ -0,0 +1,21 @@
name: Dominion
version: @version@
main: cn.lunadeer.dominion.Dominion
api-version: '1.20'
folia-supported: true
softdepend:
- Vault
- dynmap
- PlaceholderAPI
commands:
Dominion:
description: 领地插件命令
usage: /dominion <cmd>
aliases: [ dominion, dom ]
permissions:
dominion.admin:
description: 领地插件管理员权限
default: op
dominion.default:
description: 领地插件用户权限
default: true

0
gradle.properties Normal file
View File

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-8.8-bin.zip

234
gradlew vendored Executable file
View File

@ -0,0 +1,234 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

100
pom.xml
View File

@ -1,100 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.lunadeer</groupId>
<artifactId>Dominion</artifactId>
<version>1.30.4-beta</version>
<packaging>jar</packaging>
<name>Dominion</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>lunadeer-repo</id>
<url>https://ssl.lunadeer.cn:14454/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.20.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.lunadeer</groupId>
<artifactId>MinecraftPluginUtils</artifactId>
<version>1.3.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.BlueMap-Minecraft</groupId>
<artifactId>BlueMapAPI</artifactId>
<version>v2.6.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

7
settings.gradle.kts Normal file
View File

@ -0,0 +1,7 @@
rootProject.name = "Dominion"
include(
"core",
"v1_20_1",
"v1_21"
)

View File

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

View File

@ -1,300 +0,0 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.XLogger;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import static cn.lunadeer.dominion.DominionNode.getLocInDominionDTO;
public class Cache {
public Cache() {
player_current_dominion_id = new HashMap<>();
loadDominions();
loadPlayerPrivileges();
}
/**
* 从数据库加载所有领地
*/
public void loadDominions() {
if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadDominionsExecution directly");
loadDominionsExecution();
} else {
if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution");
_update_dominion_is_scheduled.set(true);
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution();
_update_dominion_is_scheduled.set(false);
},
delay_tick);
}
}
private void loadDominionsExecution() {
id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO d : dominions) {
if (!world_dominions.containsKey(d.getWorld())) {
world_dominions.put(d.getWorld(), new ArrayList<>());
}
world_dominions.get(d.getWorld()).add(d);
id_dominions.put(d.getId(), d);
if (!dominion_children.containsKey(d.getParentDomId())) {
dominion_children.put(d.getParentDomId(), new ArrayList<>());
}
dominion_children.get(d.getParentDomId()).add(d.getId());
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions.entrySet()) {
world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
BlueMapConnect.render();
_last_update_dominion.set(System.currentTimeMillis());
}
/**
* 从数据库加载所有玩家特权
*/
public void loadPlayerPrivileges() {
if (_last_update_privilege.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
loadPlayerPrivilegesExecution();
} else {
if (_update_privilege_is_scheduled.get()) return;
_update_privilege_is_scheduled.set(true);
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
loadPlayerPrivilegesExecution();
_update_privilege_is_scheduled.set(false);
},
delay_tick);
}
}
private void loadPlayerPrivilegesExecution() {
List<PlayerPrivilegeDTO> all_privileges = PlayerPrivilegeDTO.selectAll();
if (all_privileges == null) {
XLogger.err("加载玩家特权失败");
return;
}
player_uuid_to_privilege = new ConcurrentHashMap<>();
for (PlayerPrivilegeDTO privilege : all_privileges) {
UUID player_uuid = privilege.getPlayerUUID();
if (!player_uuid_to_privilege.containsKey(player_uuid)) {
player_uuid_to_privilege.put(player_uuid, new ConcurrentHashMap<>());
}
player_uuid_to_privilege.get(player_uuid).put(privilege.getDomID(), privilege);
}
_last_update_privilege.set(System.currentTimeMillis());
}
/**
* 获取玩家当前所在领地
* 此方法会先判断缓存中是否有玩家当前所在领地如果没有则遍历所有领地判断玩家所在位置
* 如果玩家不在任何领地内则返回null
* 如果玩家在领地内则返回领地信息
*
* @param player 玩家
* @return 玩家当前所在领地
*/
public DominionDTO getPlayerCurrentDominion(Player player) {
Integer last_in_dom_id = player_current_dominion_id.get(player.getUniqueId());
DominionDTO last_dominion = null;
if (last_in_dom_id != null) {
last_dominion = id_dominions.get(last_in_dom_id);
}
if (isInDominion(last_dominion, player)) {
if (dominion_children.get(last_in_dom_id) == null) {
// 如果玩家仍在领地内且领地没有子领地则直接返回
return last_dominion;
}
}
DominionDTO current_dominion = getLocInDominionDTO(world_dominion_tree.get(player.getWorld().getName()), player.getLocation());
int last_dom_id = last_dominion == null ? -1 : last_dominion.getId();
int current_dom_id = current_dominion == null ? -1 : current_dominion.getId();
if (last_dom_id == current_dom_id) {
return last_dominion;
}
if (last_dom_id != -1) {
// if (last_dominion.getParentDomId() == -1)
// Notification.info(player, "您已离开领地:%s", last_dominion.getName());
// else
// Notification.info(player, "您已离开子领地:%s", last_dominion.getName());
player.sendActionBar(Component.text(last_dominion.getLeaveMessage()));
}
if (current_dom_id != -1) {
// if (current_dominion.getParentDomId() == -1)
// Notification.info(player, "您正在进入领地:%s", current_dominion.getName());
// else
// Notification.info(player, "您正在进入子领地:%s", current_dominion.getName());
player.sendActionBar(Component.text(current_dominion.getJoinMessage()));
}
lightOrNot(player, current_dominion); // 发光检查
flyOrNot(player, current_dominion); // 飞行检查
if (current_dominion == null) {
player_current_dominion_id.put(player.getUniqueId(), null);
return null;
}
player_current_dominion_id.put(player.getUniqueId(), current_dominion.getId());
// show border
if (current_dominion.getFlagValue(Flag.SHOW_BORDER)) {
ParticleRender.showBoxFace(Dominion.instance, player,
current_dominion.getLocation1(),
current_dominion.getLocation2());
}
return current_dominion;
}
/**
* 检查玩家是否需要设置为发光
*
* @param player 玩家
* @param dominion 领地
*/
private void lightOrNot(Player player, DominionDTO dominion) {
if (!Flag.GLOW.getEnable()) {
return;
}
if (dominion == null) {
player.setGlowing(false);
return;
}
PlayerPrivilegeDTO privilege = getPlayerPrivilege(player, dominion);
if (privilege != null) {
player.setGlowing(privilege.getFlagValue(Flag.GLOW));
} else {
player.setGlowing(dominion.getFlagValue(Flag.GLOW));
}
}
private void flyOrNot(Player player, DominionDTO dominion) {
for (String flyPN : Dominion.config.getFlyPermissionNodes()) {
if (player.hasPermission(flyPN)) {
return;
}
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
if (player.isOp() && Dominion.config.getLimitOpBypass()) {
return;
}
if (!Flag.FLY.getEnable()) {
player.setAllowFlight(false);
return;
}
if (dominion == null) {
player.setAllowFlight(false);
return;
}
PlayerPrivilegeDTO privilege = getPlayerPrivilege(player, dominion);
if (privilege != null) {
player.setAllowFlight(privilege.getFlagValue(Flag.FLY));
} else {
player.setAllowFlight(dominion.getFlagValue(Flag.FLY));
}
}
public DominionDTO getDominion(Location loc) {
List<DominionNode> tree = world_dominion_tree.get(loc.getWorld().getName());
if (tree == null) return null;
return getLocInDominionDTO(tree, loc);
}
public List<DominionNode> getDominionTreeByPlayer(String player_name) {
List<DominionNode> dominionTree = new ArrayList<>();
PlayerDTO player = PlayerDTO.select(player_name);
if (player == null) return dominionTree;
for (List<DominionNode> tree : world_dominion_tree.values()) {
for (DominionNode node : tree) {
if (node.dominion.getOwner().equals(player.getUuid())) {
dominionTree.add(node);
}
}
}
return dominionTree;
}
/**
* 获取玩家在指定领地的特权
* 如果玩家不存在特权则返回null
*
* @param player 玩家
* @param dominion 领地
* @return 特权表
*/
public PlayerPrivilegeDTO getPlayerPrivilege(Player player, DominionDTO dominion) {
if (!player_uuid_to_privilege.containsKey(player.getUniqueId())) return null;
return player_uuid_to_privilege.get(player.getUniqueId()).get(dominion.getId());
}
public PlayerPrivilegeDTO getPlayerPrivilege(UUID player_uuid, DominionDTO dominion) {
if (!player_uuid_to_privilege.containsKey(player_uuid)) return null;
return player_uuid_to_privilege.get(player_uuid).get(dominion.getId());
}
private static boolean isInDominion(@Nullable DominionDTO dominion, Player player) {
if (dominion == null) return false;
if (!Objects.equals(dominion.getWorld(), player.getWorld().getName())) return false;
double x = player.getLocation().getX();
double y = player.getLocation().getY();
double z = player.getLocation().getZ();
return x >= dominion.getX1() && x <= dominion.getX2() &&
y >= dominion.getY1() && y <= dominion.getY2() &&
z >= dominion.getZ1() && z <= dominion.getZ2();
}
public DominionDTO getDominion(Integer id) {
return id_dominions.get(id);
}
public int getPlayerDominionCount(UUID player_uuid) {
int count = 0;
for (DominionDTO dominion : id_dominions.values()) {
if (dominion.getOwner().equals(player_uuid)) {
count++;
}
}
return count;
}
public List<DominionDTO> getDominions() {
return new ArrayList<>(id_dominions.values());
}
public static Cache instance;
private ConcurrentHashMap<Integer, DominionDTO> id_dominions;
private ConcurrentHashMap<String, List<DominionNode>> world_dominion_tree;
private ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, PlayerPrivilegeDTO>> player_uuid_to_privilege; // 玩家所有的特权
private final Map<UUID, Integer> player_current_dominion_id; // 玩家当前所在领地
private ConcurrentHashMap<Integer, List<Integer>> dominion_children;
private final AtomicLong _last_update_dominion = new AtomicLong(0);
private final AtomicBoolean _update_dominion_is_scheduled = new AtomicBoolean(false);
private final AtomicLong _last_update_privilege = new AtomicLong(0);
private final AtomicBoolean _update_privilege_is_scheduled = new AtomicBoolean(false);
private static final long UPDATE_INTERVAL = 1000 * 4;
public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>();
}

View File

@ -1,62 +0,0 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class DominionNode {
public DominionDTO dominion;
public List<DominionNode> children = new ArrayList<>();
public static List<DominionNode> BuildNodeTree(Integer rootId, List<DominionDTO> dominions) {
List<DominionNode> dominionTree = new ArrayList<>();
for (DominionDTO dominion : dominions) {
if (Objects.equals(dominion.getParentDomId(), rootId)) {
DominionNode node = new DominionNode();
node.dominion = dominion;
node.children = BuildNodeTree(dominion.getId(), dominions);
dominionTree.add(node);
}
}
return dominionTree;
}
public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) {
for (DominionNode node : nodes) {
if (isInDominion(node.dominion, loc)) {
if (node.children.isEmpty()) {
return node;
} else {
DominionNode childDominion = getLocInDominionNode(node.children, loc);
if (childDominion == null) {
return node;
} else {
return childDominion;
}
}
}
}
return null;
}
public static DominionDTO getLocInDominionDTO(@NotNull List<DominionNode> nodes, @NotNull Location loc) {
DominionNode dominionNode = getLocInDominionNode(nodes, loc);
return dominionNode == null ? null : dominionNode.dominion;
}
public static boolean isInDominion(@Nullable DominionDTO dominion, Location location) {
if (dominion == null) return false;
if (!Objects.equals(dominion.getWorld(), location.getWorld().getName())) return false;
double x = location.getX();
double y = location.getY();
double z = location.getZ();
return x >= dominion.getX1() && x <= dominion.getX2() &&
y >= dominion.getY1() && y <= dominion.getY2() &&
z >= dominion.getZ1() && z <= dominion.getZ2();
}
}

View File

@ -1,62 +0,0 @@
package cn.lunadeer.dominion;
import cn.lunadeer.minecraftpluginutils.XLogger;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
public class VaultConnect {
private Economy econ = null;
private Permission perms = null;
private Chat chat = null;
private JavaPlugin plugin;
public VaultConnect(JavaPlugin plugin) {
this.plugin = plugin;
if (!setupEconomy()) {
XLogger.err("你没有安装 Vault 前置插件,无法使用经济功能,如果不需要使用经济功能请前往配置文件关闭。");
return;
}
setupPermissions();
setupChat();
}
private boolean setupEconomy() {
if (plugin.getServer().getPluginManager().getPlugin("Vault") == null) {
return false;
}
RegisteredServiceProvider<Economy> rsp = plugin.getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
econ = rsp.getProvider();
return econ != null;
}
private boolean setupChat() {
RegisteredServiceProvider<Chat> rsp = plugin.getServer().getServicesManager().getRegistration(Chat.class);
chat = rsp.getProvider();
return chat != null;
}
private boolean setupPermissions() {
RegisteredServiceProvider<Permission> rsp = plugin.getServer().getServicesManager().getRegistration(Permission.class);
perms = rsp.getProvider();
return perms != null;
}
public Economy getEconomy() {
return econ;
}
public Permission getPermissions() {
return perms;
}
public Chat getChat() {
return chat;
}
}

View File

@ -1,65 +0,0 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
public class Apis {
public static Player playerOnly(CommandSender sender) {
if (!(sender instanceof Player)) {
Notification.error(sender, "该命令只能由玩家执行");
return null;
}
return (Player) sender;
}
public static void sizeInfo(CommandSender sender, DominionDTO dominionDTO) {
Integer x1 = dominionDTO.getX1();
Integer y1 = dominionDTO.getY1();
Integer z1 = dominionDTO.getZ1();
Integer x2 = dominionDTO.getX2();
Integer y2 = dominionDTO.getY2();
Integer z2 = dominionDTO.getZ2();
Notification.info(sender, "领地 %s 的尺寸信息:", dominionDTO.getName());
Notification.info(sender, " 大小: %d x %d x %d", x2 - x1, y2 - y1, z2 - z1);
Notification.info(sender, " 中心坐标: %d %d %d", x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2, z1 + (z2 - z1) / 2);
Notification.info(sender, " 高度: %d", y2 - y1);
Notification.info(sender, " Y坐标范围 %d ~ %d", y1, y2);
Notification.info(sender, " 体积: %d", (x2 - x1) * (y2 - y1) * (z2 - z1));
Notification.info(sender, " 领地所在世界: %s", dominionDTO.getWorld());
Notification.info(sender, " 领地的对角点坐标: x1=%d y1=%d z1=%d, x2=%d y2=%d z2=%d", x1, y1, z1, x2, y2, z2);
}
public static void autoPoints(Player player) {
Integer size = Dominion.config.getAutoCreateRadius();
Location location = player.getLocation();
Location location1 = new Location(location.getWorld(), location.getX() - size, location.getY() - size, location.getZ() - size);
Location location2 = new Location(location.getWorld(), location.getX() + size, location.getY() + size, location.getZ() + size);
if (Dominion.config.getLimitVert()) {
location1.setY(Dominion.config.getLimitMinY());
location2.setY(Dominion.config.getLimitMaxY());
}
Map<Integer, Location> points = new HashMap<>();
points.put(0, location1);
points.put(1, location2);
Dominion.pointsSelect.put(player.getUniqueId(), points);
}
public static boolean notOpOrConsole(CommandSender sender) {
if (sender instanceof Player) {
Player player = (Player) sender;
if (!player.isOp()) {
Notification.warn(player, "你没有权限使用此命令");
return true;
}
}
return false;
}
}

View File

@ -1,184 +0,0 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.AbstractOperator;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.controllers.PrivilegeController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.tuis.DominionManage;
import cn.lunadeer.dominion.tuis.DominionPrivilegeList;
import cn.lunadeer.dominion.tuis.SelectPlayer;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.scui.CuiTextInput;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.Objects;
import static cn.lunadeer.dominion.commands.Apis.autoPoints;
import static cn.lunadeer.dominion.commands.Apis.playerOnly;
public class OpenCUI {
private static class renameDominionCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String oldName;
public renameDominionCB(Player sender, String oldName) {
this.sender = sender;
this.oldName = oldName;
}
@Override
public void handleData(String input) {
XLogger.debug("renameDominionCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.rename(operator, oldName, input);
DominionManage.show(sender, new String[]{"manage", input});
}
}
private static class editJoinMessageCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public editJoinMessageCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("editJoinMessageCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.setJoinMessage(operator, input, dominionName);
DominionManage.show(sender, new String[]{"manage", dominionName});
}
}
private static class editLeaveMessageCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public editLeaveMessageCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("editLeaveMessageCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
DominionController.setLeaveMessage(operator, input, dominionName);
DominionManage.show(sender, new String[]{"manage", dominionName});
}
}
private static class createDominionCB implements CuiTextInput.InputCallback {
private final Player sender;
public createDominionCB(Player sender) {
this.sender = sender;
}
@Override
public void handleData(String input) {
XLogger.debug("createDominionCB.run: %s", input);
autoPoints(sender);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
Map<Integer, Location> points = Dominion.pointsSelect.get(sender.getUniqueId());
if (points == null || points.get(0) == null || points.get(1) == null) {
Notification.error(sender, "自动选点失败");
return;
}
operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), AbstractOperator.Result.SUCCESS)){
DominionManage.show(sender, new String[]{"list"});
}
});
DominionController.create(operator, input, points.get(0), points.get(1));
}
}
private static class createPrivilegeCB implements CuiTextInput.InputCallback {
private final Player sender;
private final String dominionName;
public createPrivilegeCB(Player sender, String dominionName) {
this.sender = sender;
this.dominionName = dominionName;
}
@Override
public void handleData(String input) {
XLogger.debug("createPrivilegeCB.run: %s", input);
BukkitPlayerOperator operator = BukkitPlayerOperator.create(sender);
PrivilegeController.createPrivilege(operator, input, dominionName);
operator.getResponse().thenAccept(result -> {
if (Objects.equals(result.getStatus(), AbstractOperator.Result.SUCCESS)){
DominionPrivilegeList.show(sender, new String[]{"privilege_list", dominionName});
} else {
SelectPlayer.show(sender, new String[]{"select_player_create_privilege", dominionName});
}
});
}
}
public static void RenameDominion(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
CuiTextInput.InputCallback renameDominionCB = new renameDominionCB(player, args[1]);
CuiTextInput view = CuiTextInput.create(renameDominionCB).setText(args[1]).title("领地重命名");
view.open(player);
}
public static void EditJoinMessage(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback editJoinMessageCB = new editJoinMessageCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(editJoinMessageCB).setText(dominion.getJoinMessage()).title("编辑欢迎提示语");
view.open(player);
}
public static void EditLeaveMessage(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback editLeaveMessageCB = new editLeaveMessageCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(editLeaveMessageCB).setText(dominion.getLeaveMessage()).title("编辑离开提示语");
view.open(player);
}
public static void CreateDominion(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
CuiTextInput.InputCallback createDominionCB = new createDominionCB(player);
CuiTextInput view = CuiTextInput.create(createDominionCB).setText("未命名领地").title("输入要创建的领地名称");
view.open(player);
}
public static void CreatePrivilege(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地不存在");
return;
}
CuiTextInput.InputCallback createPrivilegeCB = new createPrivilegeCB(player, dominion.getName());
CuiTextInput view = CuiTextInput.create(createPrivilegeCB).setText("Steve").title("输入玩家名称以添加为成员");
view.open(player);
}
}

View File

@ -1,99 +0,0 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.controllers.BukkitPlayerOperator;
import cn.lunadeer.dominion.tuis.DominionPrivilegeList;
import cn.lunadeer.dominion.tuis.PrivilegeInfo;
import cn.lunadeer.minecraftpluginutils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly;
import static cn.lunadeer.dominion.controllers.PrivilegeController.*;
public class PlayerPrivilege {
/**
* 创建玩家特权
* /dominion create_privilege <玩家名称> [领地名称]
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void createPlayerPrivilege(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
if (args.length != 2 && args.length != 3 && args.length != 4) {
Notification.error(sender, "用法: /dominion create_privilege <玩家名称> [领地名称]");
return;
}
if (args.length == 2) {
createPrivilege(operator, args[1]);
} else {
createPrivilege(operator, args[1], args[2]);
}
if (args.length == 4) {
String[] newArgs = new String[2];
newArgs[0] = "privilege_list";
newArgs[1] = args[2];
DominionPrivilegeList.show(sender, newArgs);
}
}
/**
* 设置玩家权限
* /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void setPlayerPrivilege(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
if (args.length == 4) {
setPrivilege(operator, args[1], args[2], Boolean.parseBoolean(args[3]));
} else if (args.length == 5) {
setPrivilege(operator, args[1], args[2], Boolean.parseBoolean(args[3]), args[4]);
} else if (args.length == 6) {
setPrivilege(operator, args[1], args[2], Boolean.parseBoolean(args[3]), args[4]);
String[] newArgs = new String[4];
newArgs[0] = "privilege_info";
newArgs[1] = args[1];
newArgs[2] = args[4];
newArgs[3] = args[5];
PrivilegeInfo.show(sender, newArgs);
} else {
Notification.error(sender, "用法: /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]");
}
}
/**
* 重置玩家权限
* /dominion clear_privilege <玩家名称> [领地名称]
*
* @param sender 命令发送者
* @param args 命令参数
*/
public static void clearPlayerPrivilege(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
BukkitPlayerOperator operator = BukkitPlayerOperator.create(player);
if (args.length != 2 && args.length != 3 && args.length != 4) {
Notification.error(sender, "用法: /dominion clear_privilege <玩家名称> [领地名称]");
return;
}
if (args.length == 2) {
clearPrivilege(operator, args[1]);
} else {
clearPrivilege(operator, args[1], args[2]);
}
if (args.length == 4) {
String[] newArgs = new String[3];
newArgs[0] = "privilege_list";
newArgs[1] = args[2];
DominionPrivilegeList.show(sender, newArgs);
}
}
}

View File

@ -1,178 +0,0 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.entity.Player;
import java.util.UUID;
import static cn.lunadeer.dominion.controllers.Apis.noAuthToChangeFlags;
import static cn.lunadeer.dominion.controllers.Apis.notOwner;
public class PrivilegeController {
/**
* 清空玩家成员权限
*
* @param operator 操作者
* @param player_name 玩家
* @return 是否清空成功
*/
public static void clearPrivilege(AbstractOperator operator, String player_name) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你不在任何领地内,请指定领地名称 /dominion clear_privilege <玩家名称> <领地名称>"));
return;
}
clearPrivilege(operator, player_name, dominion.getName());
}
/**
* 清空玩家成员权限
*
* @param operator 操作者
* @param player_name 玩家
* @param dominionName 领地名称
* @return 是否清空成功
*/
public static void clearPrivilege(AbstractOperator operator, String player_name, String dominionName) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "清空玩家 %s 在领地 %s 的权限失败", player_name, dominionName);
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(FAIL.appendMessage("领地 %s 不存在", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
operator.setResponse(FAIL.appendMessage("玩家 %s 不存在或没有登录过", player_name));
return;
}
PlayerPrivilegeDTO privilege = PlayerPrivilegeDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
operator.setResponse(FAIL.appendMessage("玩家 %s 不是领地 %s 的成员", player_name, dominionName));
return;
}
if (privilege.getAdmin() && notOwner(operator, dominion)) {
operator.setResponse(FAIL.appendMessage("你不是领地 %s 的拥有者,无法移除一个领地管理员", dominionName));
return;
}
PlayerPrivilegeDTO.delete(player.getUuid(), dominion.getId());
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "清空玩家 %s 在领地 %s 的权限成功", player_name, dominionName));
}
/**
* 设置玩家成员权限
*
* @param operator 操作者
* @param player_name 玩家
* @param flag 权限名称
* @param value 权限值
* @return 是否设置成功
*/
public static void setPrivilege(AbstractOperator operator, String player_name, String flag, boolean value) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你不在任何领地内,请指定领地名称 /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]"));
return;
}
setPrivilege(operator, player_name, flag, value, dominion.getName());
}
/**
* 设置玩家成员权限
*
* @param operator 操作者
* @param player_name 玩家
* @param flag 权限名称
* @param value 权限值
* @param dominionName 领地名称
* @return 是否设置成功
*/
public static void setPrivilege(AbstractOperator operator, String player_name, String flag, boolean value, String dominionName) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "设置玩家 %s 在领地 %s 的权限 %s 为 %s 失败", player_name, dominionName, flag, value);
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(FAIL.appendMessage("领地 %s 不存在", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
operator.setResponse(FAIL.appendMessage("玩家 %s 不存在或没有登录过", player_name));
return;
}
PlayerPrivilegeDTO privilege = PlayerPrivilegeDTO.select(player.getUuid(), dominion.getId());
if (privilege == null) {
privilege = createPlayerPrivilege(operator, player.getUuid(), dominion);
if (privilege == null) return;
}
if (flag.equals("admin")) {
if (notOwner(operator, dominion)) {
operator.setResponse(FAIL.appendMessage("你不是领地 %s 的拥有者,无法设置/取消其他玩家为管理员", dominionName));
return;
}
privilege.setAdmin(value);
} else {
Flag f = Flag.getFlag(flag);
if (f == null) {
operator.setResponse(FAIL.appendMessage("未知的领地权限 %s", flag));
return;
}
privilege.setFlagValue(f, value);
}
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "设置玩家 %s 在领地 %s 的权限 %s 为 %s 成功", player_name, dominionName, flag, value));
}
public static void createPrivilege(AbstractOperator operator, String player_name) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你不在任何领地内,请指定领地名称 /dominion create_privilege <玩家名称> <领地名称>"));
return;
}
createPrivilege(operator, player_name, dominion.getName());
}
public static void createPrivilege(AbstractOperator operator, String player_name, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "领地 %s 不存在,无法创建成员权限", dominionName));
return;
}
if (noAuthToChangeFlags(operator, dominion)) return;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "玩家 %s 不存在或没有登录过", player_name));
return;
}
if (createPlayerPrivilege(operator, player.getUuid(), dominion) != null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.SUCCESS, "创建玩家 %s 在领地 %s 的成员权限成功", player_name, dominionName));
}
}
private static PlayerPrivilegeDTO createPlayerPrivilege(AbstractOperator operator, UUID player, DominionDTO dom) {
XLogger.debug("operator: " + operator.getUniqueId() + " player: " + player);
if (operator.getUniqueId().equals(player)) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "你不能给自己设置成员权限"));
return null;
}
PlayerDTO playerDTO = PlayerDTO.select(player);
PlayerPrivilegeDTO privilege = Cache.instance.getPlayerPrivilege(player, dom);
if (privilege != null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建玩家成员权限失败,玩家 %s 已经是领地 %s 的成员", playerDTO.getLastKnownName(), dom.getName()));
return null;
}
privilege = PlayerPrivilegeDTO.insert(new PlayerPrivilegeDTO(player, dom));
if (privilege == null) {
operator.setResponse(new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建玩家成员权限失败,请联系管理员"));
return null;
}
return privilege;
}
}

View File

@ -1,409 +0,0 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.minecraftpluginutils.XLogger;
import org.bukkit.Location;
import org.bukkit.World;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class DominionDTO {
private static List<DominionDTO> query(String sql, Object... args) {
List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = Dominion.database.query(sql, args)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadDominions();
}
if (rs == null) return dominions;
while (rs.next()) {
Integer id = rs.getInt("id");
UUID owner = UUID.fromString(rs.getString("owner"));
String name = rs.getString("name");
String world = rs.getString("world");
Integer x1 = rs.getInt("x1");
Integer y1 = rs.getInt("y1");
Integer z1 = rs.getInt("z1");
Integer x2 = rs.getInt("x2");
Integer y2 = rs.getInt("y2");
Integer z2 = rs.getInt("z2");
Integer parentDomId = rs.getInt("parent_dom_id");
String tp_location = rs.getString("tp_location");
Map<Flag, Boolean> flags = new HashMap<>();
for (Flag f : Flag.getDominionFlagsEnabled()) {
flags.put(f, rs.getBoolean(f.getFlagName()));
}
DominionDTO dominion = new DominionDTO(id, owner, name, world, x1, y1, z1, x2, y2, z2, parentDomId,
rs.getString("join_message"),
rs.getString("leave_message"),
flags,
tp_location
);
dominions.add(dominion);
}
} catch (SQLException e) {
Dominion.database.handleDatabaseError("数据库操作失败: ", e, sql);
}
return dominions;
}
public static List<DominionDTO> selectAll() {
String sql = "SELECT * FROM dominion WHERE id > 0;";
return query(sql);
}
public static List<DominionDTO> selectAll(String world) {
String sql = "SELECT * FROM dominion WHERE world = ? AND id > 0;";
return query(sql, world);
}
public static List<DominionDTO> search(String name) {
String sql = "SELECT * FROM dominion WHERE name LIKE ? AND id > 0;";
return query(sql, "%" + name + "%");
}
public static List<DominionDTO> selectAll(UUID owner) {
String sql = "SELECT * FROM dominion WHERE owner = ? AND id > 0;";
return query(sql, owner.toString());
}
public static DominionDTO select(Integer id) {
if (id == -1) {
return new DominionDTO(-1,
UUID.fromString("00000000-0000-0000-0000-000000000000"),
"根领地", "all",
-2147483648, -2147483648, -2147483648,
2147483647, 2147483647, 2147483647, -1);
}
String sql = "SELECT * FROM dominion WHERE id = ? AND id > 0;";
List<DominionDTO> dominions = query(sql, id);
if (dominions.size() == 0) return null;
return dominions.get(0);
}
public static List<DominionDTO> selectByParentId(String world, Integer parentId) {
String sql = "SELECT * FROM dominion WHERE world = ? AND parent_dom_id = ? AND id > 0;";
return query(sql, world, parentId);
}
public static List<DominionDTO> selectByLocation(String world, Integer x, Integer y, Integer z) {
String sql = "SELECT * FROM dominion WHERE world = ? AND " +
"x1 <= ? AND x2 >= ? AND " +
"y1 <= ? AND y2 >= ? AND " +
"z1 <= ? AND z2 >= ? AND " + "id > 0;";
return query(sql, world, x, x, y, y, z, z);
}
public static DominionDTO select(String name) {
String sql = "SELECT * FROM dominion WHERE name = ? AND id > 0;";
List<DominionDTO> dominions = query(sql, name);
if (dominions.size() == 0) return null;
return dominions.get(0);
}
public static DominionDTO insert(DominionDTO dominion) {
String sql = "INSERT INTO dominion (" +
"owner, name, world, x1, y1, z1, x2, y2, z2, ";
for (Flag f : Flag.getAllDominionFlags()) {
sql += f.getFlagName() + ", ";
}
sql += "tp_location";
sql += ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ";
for (Flag f : Flag.getAllDominionFlags()) {
sql += f.getDefaultValue() + ", ";
}
sql += "'default'";
sql += ") RETURNING *;";
List<DominionDTO> dominions = query(sql,
dominion.getOwner(),
dominion.getName(),
dominion.getWorld(),
dominion.getX1(),
dominion.getY1(),
dominion.getZ1(),
dominion.getX2(),
dominion.getY2(),
dominion.getZ2());
if (dominions.size() == 0) return null;
return dominions.get(0);
}
public static void delete(DominionDTO dominion) {
String sql = "DELETE FROM dominion WHERE id = ?;";
query(sql, dominion.getId());
}
private static DominionDTO update(DominionDTO dominion) {
String tp_location;
if (dominion.getTpLocation() == null) {
tp_location = "default";
} else {
Location loc = dominion.getTpLocation();
tp_location = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
}
String sql = "UPDATE dominion SET " +
"owner = ?," +
"name = ?," +
"world = ?," +
"x1 = " + dominion.getX1() + ", " +
"y1 = " + dominion.getY1() + ", " +
"z1 = " + dominion.getZ1() + ", " +
"x2 = " + dominion.getX2() + ", " +
"y2 = " + dominion.getY2() + ", " +
"z2 = " + dominion.getZ2() + ", " +
"parent_dom_id = " + dominion.getParentDomId() + ", " +
"join_message = ?," +
"leave_message = ?,";
for (Flag f : Flag.getDominionFlagsEnabled()) {
sql += f.getFlagName() + " = " + dominion.getFlagValue(f) + ",";
}
sql += "tp_location = ?" +
" WHERE id = " + dominion.getId() +
" RETURNING *;";
List<DominionDTO> dominions = query(sql,
dominion.getOwner().toString(),
dominion.getName(),
dominion.getWorld(),
dominion.getJoinMessage(),
dominion.getLeaveMessage(),
tp_location);
if (dominions.size() == 0) return null;
return dominions.get(0);
}
private DominionDTO(Integer id, UUID owner, String name, String world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId,
String joinMessage, String leaveMessage,
Map<Flag, Boolean> flags,
String tp_location) {
this.id = id;
this.owner = owner;
this.name = name;
this.world = world;
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
this.parentDomId = parentDomId;
this.joinMessage = joinMessage;
this.leaveMessage = leaveMessage;
this.flags.putAll(flags);
this.tp_location = tp_location;
}
private DominionDTO(Integer id, UUID owner, String name, String world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2,
Integer parentDomId) {
this.id = id;
this.owner = owner;
this.name = name;
this.world = world;
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
this.parentDomId = parentDomId;
}
public DominionDTO(UUID owner, String name, String world,
Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this(null, owner, name, world, x1, y1, z1, x2, y2, z2, -1);
}
private Integer id;
private UUID owner;
private String name;
private final String world;
private Integer x1;
private Integer y1;
private Integer z1;
private Integer x2;
private Integer y2;
private Integer z2;
private Integer parentDomId = -1;
private String joinMessage = "欢迎";
private String leaveMessage = "再见";
private final Map<Flag, Boolean> flags = new HashMap<>();
private String tp_location;
// getters and setters
public Integer getId() {
return id;
}
public DominionDTO setId(Integer id) {
this.id = id;
return update(this);
}
public UUID getOwner() {
return owner;
}
public DominionDTO setOwner(UUID owner) {
this.owner = owner;
return update(this);
}
public String getName() {
return name;
}
public DominionDTO setName(String name) {
this.name = name;
return update(this);
}
public String getWorld() {
return world;
}
public Integer getX1() {
return x1;
}
public DominionDTO setX1(Integer x1) {
this.x1 = x1;
return update(this);
}
public Integer getY1() {
return y1;
}
public DominionDTO setY1(Integer y1) {
this.y1 = y1;
return update(this);
}
public Integer getZ1() {
return z1;
}
public DominionDTO setZ1(Integer z1) {
this.z1 = z1;
return update(this);
}
public Integer getX2() {
return x2;
}
public DominionDTO setX2(Integer x2) {
this.x2 = x2;
return update(this);
}
public Integer getY2() {
return y2;
}
public DominionDTO setY2(Integer y2) {
this.y2 = y2;
return update(this);
}
public Integer getZ2() {
return z2;
}
public DominionDTO setZ2(Integer z2) {
this.z2 = z2;
return update(this);
}
public Integer getSquare() {
return (x2 - x1) * (z2 - z1);
}
public Integer getVolume() {
return getSquare() * (y2 - y1);
}
public Integer getParentDomId() {
return parentDomId;
}
public DominionDTO setParentDomId(Integer parentDomId) {
this.parentDomId = parentDomId;
return update(this);
}
public String getJoinMessage() {
return joinMessage;
}
public DominionDTO setJoinMessage(String joinMessage) {
this.joinMessage = joinMessage;
return update(this);
}
public String getLeaveMessage() {
return leaveMessage;
}
public DominionDTO setLeaveMessage(String leaveMessage) {
this.leaveMessage = leaveMessage;
return update(this);
}
public Boolean getFlagValue(Flag flag) {
if (!flags.containsKey(flag)) return flag.getDefaultValue();
return flags.get(flag);
}
public DominionDTO setFlagValue(Flag flag, Boolean value) {
flags.put(flag, value);
return update(this);
}
public DominionDTO setXYZ(Integer x1, Integer y1, Integer z1, Integer x2, Integer y2, Integer z2) {
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
return update(this);
}
public Location getTpLocation() {
if (Objects.equals(tp_location, "default")) {
return null;
} else {
// 0:0:0
String[] loc = tp_location.split(":");
World w = Dominion.instance.getServer().getWorld(world);
if (loc.length == 3 && w != null) {
return new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
} else {
XLogger.warn("领地传送点数据异常: %s", tp_location);
XLogger.debug("world: %s, loc.length: %d", world, loc.length);
return null;
}
}
}
public DominionDTO setTpLocation(Location loc) {
this.tp_location = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
return update(this);
}
public Location getLocation1() {
return new Location(Dominion.instance.getServer().getWorld(world), x1, y1, z1);
}
public Location getLocation2() {
return new Location(Dominion.instance.getServer().getWorld(world), x2, y2, z2);
}
}

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