添加了通过ui选择创建玩家特权的途径

This commit is contained in:
zhangyuheng 2024-02-16 20:40:42 +08:00
parent f6c9cb53ee
commit 9a4d2a462c
11 changed files with 228 additions and 24 deletions

54
README.md Normal file
View File

@ -0,0 +1,54 @@
# Dominion
## 简介
鉴于 Residence 插件的作者项目较多维护压力大无法及时跟进新版本以及适配Folia核心。故开发此插件旨在平替纯净版生存服Residence的使用。
## 说明
本插件基本还原了Residence的核心功能主要适用于原版纯净生存服务器的防破坏目的因此暂不考虑引入价格系统、商店等非原版Minecraft玩法。
![](https://ssl.lunadeer.cn:14437/i/2024/02/16/65cf3b08c986b.png)
为了提高存储效率,本插件使用了数据库+缓存的方式存储领地数据,玩家配置领地权限直接修改数据库内容,随后触发缓存更新。权限控制则以异步的方式访问缓存,减少事件阻塞。
权限系统主要由领地权限、玩家特权组成,玩家特权优先级高于领地权限。没有特权的玩家在领地内收到领地权限的控制,有特权配置则按照特权设置受控。
## 功能介绍
- 使用 Postgresql 存储数据;
- 支持BlueMap卫星地图渲染
- 可视化领地权限配置;
- 支持为玩家单独设置特权;
- 支持设置领地管理员;
- 支持子领地;
## 支持版本
- 1.20.1+ (Paper、Folia)
## 安装方法
1. 将插件放入服务器的 `plugins` 目录下
2. 重启服务器
3. 在 `plugins/XXXXXXX/config.yml` 中配置
4. 重启服务器
## 玩家使用方法
## 管理员指南
## 指令
### 玩家指令
### 管理员指令
## 配置文件参考
```yaml
```
## TODO
- WebUI

View File

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

1
resource/frame.drawio Normal file
View File

@ -0,0 +1 @@
<mxfile host="Electron" modified="2024-02-06T02:51:17.167Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.8.16 Chrome/106.0.5249.199 Electron/21.4.0 Safari/537.36" etag="EzG-lQXLogbq_xywu-ye" version="20.8.16" type="device"><diagram name="第 1 页" id="TAprC_qEjeDnN3pvnCCR">7ZvbcuI4EIafhstQtmUbc5lAmJmtbG1qM1uzuRS2bDQRFiOL0z79tmwZbGQSpjiEpHxDUEvW8dOvVpt00GC6+iLwbPInjwjrOFa06qBhx3ECx4ZPZVgXBg+5hSERNCpM1tbwRP8jhdEurXMakUzbCpPknEk6qxtDnqYklDUbFoIv68VizqKaYYYTYhieQsxM6w8ayUlhdf2gkvGV0GSim0bI0j2f4rK0NmQTHPFlxYTuO2ggOJfFt+lqQJiavPrEjPbkbjogSCoPeeD5ORn80ROPv5bu37b1kL746/im7NwCs7kesu6tXJdzQCKYEp3kQk54wlPM7rfWO8HnaURUOxakshciQzV2GxITHE7mgnzBMzC4YPhJkySvCibgLpyLBRlRKWma6Ae2LTxwPtPGn0TKtaYDzyVXFcsp07kxT+UITylTkN2KcEIlsJDBKKAwLA0RutATn4tQ1TGREgACGm/hA2ZMfagCWTfhHLqHZzTrhnyaZ4RZXnQUF03A11ojnnO320zRUdtXkyGxkLeKRLCEDGcZDUvziLJyCMWkq5neu7ralJVj2Lekgd4mWCREvlLORhsIYfcSPiVSwOgsQRiWdFHvCNb7KNmU04/C0PC6UmDGaapmZVPzozJAAa0IvuUVNWpBQP4Otbvl/VfLw5eiB2WqMpStKd8Jv7ErAmNTfP/nm7EvttSrFVwqIJ5mOF+bpVC8Vxk9blNcKeGO2u4xUDzgjIt8VlAcx05YIC74C6nkRP7Y9/wN7AsiJFm9jrtJp37A86w6FqXsLrcqbZeHyKQi0K61H+gKVL/PTDmGVkk/jZKW/FyplPacDyCltulg/CDjVk2vSk393rWpKbINQK5ePGGyxfpf3XqeeFaJrlcmh6tq5nCtU1eKoym6KU/JjuJaJ1bc8o73puI6RyruUXTa5lk/xBKPcUZaXTtI14gdeaTXpGt9v4fwmbxEt2fqGoidqWv+uXTNdgxyBrDMLTYnw0YBQ0PMbhlNUsiTSr1PAVPQexsmFFwSpr6pQt//ylqUDkIJQAoitwmlwBkj/0QKFPTr0HgNnhVyG6BxzuZZtRG/T3dPRYd6TXtgvYzX5PZa0C7tm5M0MlEE4zlBPDYOYgQuAsfu1kMXbj8oLWU1Bfz6yR1STxDHcM2YsBTAG6yM4zOYp7uxqLHt/5qrNzv5qt1k+bIBEZbtzVb5pJf58C1Rf+ezCEvTD1Tr8oDHhNW5xNq7CWGNcjh23Z4pjaJiAxFoHI/z+hQROqoElXt3HW+4w5V3KPN7z0b9Jk632NkcZFWeXpGHvSfpjdW1dwJeN7rJI/FyapU6O1zxOM7IWZAqZbt6F4CpF5wxRVXrxR0SHwtC0hwfGwee61mvkXrE24bg3e+RnsHO/YLocHHLzdvePyZB3MiNHwZkHJ/nytgUV228Mp4vrtr/eD5YG1c92jFDzoE3BHSsB3fcDQF9ZDq7th1UCbXf4DNPPRJBYfIUJB8L2v0328qdQ5O9vXC8F9fFefleXJfdrJzWI5pG1ZtDcQkY8ilNKU/bU/yKvD/jFPfNU7zfcIj3z3WIu20I73OdzofG74ofz76bipn31W+ZqWG3EWhYK2BXJGD94G0B611UwNrfyn0uAXMPFbD3dcNcA7uvuEHBHgVdUEZgYowsroK8KZetvl2RvtnWAR5aU5jlbAKHzPDc1rXfZWrEcNLG7a4KKPtyQEFy+z9AxauF7X9Sofv/AQ==</diagram></mxfile>

View File

@ -99,6 +99,9 @@ public class Commands implements TabExecutor {
case "set":
DominionFlag.setDominionFlag(sender, args);
break;
case "create_privilege":
PlayerPrivilege.createPlayerPrivilege(sender, args);
break;
case "set_privilege":
PlayerPrivilege.setPlayerPrivilege(sender, args);
break;
@ -111,6 +114,9 @@ public class Commands implements TabExecutor {
case "privilege_info":
PrivilegeInfo.show(sender, args);
break;
case "select_player_create_privilege":
SelectPlayer.show(sender, args);
break;
default:
return false;
}
@ -135,7 +141,7 @@ public class Commands implements TabExecutor {
if (args.length == 1) {
return Arrays.asList("menu", "help", "info", "manage", "flag_info", "group_list", "privilege_list", "group",
"create", "auto_create", "create_sub", "auto_create_sub", "expand", "contract", "delete", "set",
"set_privilege", "clear_privilege", "list", "privilege_info"
"create_privilege", "set_privilege", "clear_privilege", "list", "privilege_info"
);
}
if (args.length == 2) {
@ -154,6 +160,7 @@ public class Commands implements TabExecutor {
return playerDominions(sender);
case "set":
return dominionFlags();
case "create_privilege":
case "set_privilege":
case "clear_privilege":
case "privilege_info":
@ -175,6 +182,7 @@ public class Commands implements TabExecutor {
case "expand":
case "contract":
case "clear_privilege":
case "create_privilege":
case "privilege_info":
case "auto_create_sub":
case "create_sub":

View File

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.tuis.DominionPrivilegeList;
import cn.lunadeer.dominion.tuis.PrivilegeInfo;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.command.CommandSender;
@ -8,9 +9,44 @@ import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly;
import static cn.lunadeer.dominion.controllers.PrivilegeController.clearPrivilege;
import static cn.lunadeer.dominion.controllers.PrivilegeController.setPrivilege;
import static cn.lunadeer.dominion.controllers.PrivilegeController.createPrivilege;
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;
if (args.length != 2 && args.length != 3 && args.length != 4) {
Notification.error(sender, "用法: /dominion create_privilege <玩家名称> [领地名称]");
return;
}
if (args.length == 2) {
if (!createPrivilege(player, args[1])) {
Notification.error(sender, "创建玩家特权失败");
return;
}
} else {
if (!createPrivilege(player, args[1], args[2])) {
Notification.error(sender, "创建玩家特权失败");
return;
}
}
Notification.info(sender, "成功创建玩家特权 " + args[1]);
if (args.length == 4) {
String[] newArgs = new String[3];
newArgs[0] = "privilege_list";
newArgs[1] = args[2];
DominionPrivilegeList.show(sender, newArgs);
}
}
/**
* 设置玩家权限
* /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]
@ -61,20 +97,28 @@ public class PlayerPrivilege {
public static void clearPlayerPrivilege(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3) {
if (args.length != 2 && args.length != 3 && args.length != 4) {
Notification.error(sender, "用法: /dominion clear_privilege <玩家名称> [领地名称]");
return;
}
if (args.length == 2) {
if (clearPrivilege(player, args[1])) {
if (!clearPrivilege(player, args[1])) {
Notification.error(sender, "重置玩家权限失败");
return;
}
} else {
if (clearPrivilege(player, args[1], args[2])) {
if (!clearPrivilege(player, args[1], args[2])) {
Notification.error(sender, "重置玩家权限失败");
return;
}
}
Notification.error(sender, "重置玩家权限失败");
Notification.info(sender, "成功清除玩家权限 " + args[1]);
if (args.length == 4) {
String[] newArgs = new String[3];
newArgs[0] = "privilege_list";
newArgs[1] = args[2];
DominionPrivilegeList.show(sender, newArgs);
}
}
}

View File

@ -9,6 +9,7 @@ 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 {
@ -21,7 +22,10 @@ public class PrivilegeController {
*/
public static boolean clearPrivilege(Player operator, String player_name) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) return false;
if (dominion == null) {
Notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion clear_privilege <玩家名称> <领地名称>");
return false;
}
return clearPrivilege(operator, player_name, dominion.getName());
}
@ -60,7 +64,10 @@ public class PrivilegeController {
*/
public static boolean setPrivilege(Player operator, String player_name, String flag, boolean value) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) return false;
if (dominion == null) {
Notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]");
return false;
}
return setPrivilege(operator, player_name, flag, value, dominion.getName());
}
@ -199,6 +206,30 @@ public class PrivilegeController {
return true;
}
public static boolean createPrivilege(Player operator, String player_name) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
Notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion create_privilege <玩家名称> <领地名称>");
return false;
}
return createPrivilege(operator, player_name, dominion.getName());
}
public static boolean createPrivilege(Player operator, String player_name, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
Notification.error(operator, "领地 " + dominionName + " 不存在,无法设置特权");
return false;
}
if (notOwner(operator, dominion)) return false;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
Notification.error(operator, "玩家 " + player_name + " 不存在或没有登录过");
return false;
}
return createPlayerPrivilege(operator, player.getUuid(), dominion) != null;
}
private static PlayerPrivilegeDTO createPlayerPrivilege(Player operator, UUID player, DominionDTO dom) {
PlayerPrivilegeDTO privilege = new PlayerPrivilegeDTO(player, dom.getId(),
dom.getAnchor(), dom.getAnimalKilling(), dom.getAnvil(),
@ -208,7 +239,7 @@ public class PrivilegeController {
dom.getEgg(), dom.getEnchant(), dom.getEnderPearl(),
dom.getFeed(),
dom.getGlow(),
dom.getHoney(), dom.getHook(),
dom.getHarvest(), dom.getHoney(), dom.getHook(),
dom.getIgnite(),
dom.getLever(),
dom.getMonsterKilling(), dom.getMove(),
@ -216,10 +247,10 @@ public class PrivilegeController {
dom.getRiding(), dom.getRepeater(),
dom.getShear(), dom.getShoot(),
dom.getTrade(),
dom.getVehicleDestroy(), dom.getHarvest());
dom.getVehicleDestroy());
privilege = PlayerPrivilegeDTO.insert(privilege);
if (privilege == null) {
Notification.error(operator, "创建玩家特权关联玩家时失败");
Notification.error(operator, "创建玩家特权失败,可能是此玩家已存在特权");
return null;
}
return privilege;

View File

@ -21,7 +21,7 @@ public class PlayerDTO {
}
public static List<PlayerDTO> all() {
String sql = "SELECT * FROM player_name;";
String sql = "SELECT * FROM player_name WHERE id > 0;";
return query(sql);
}

View File

@ -12,10 +12,41 @@ import java.util.UUID;
public class PlayerPrivilegeDTO {
public static PlayerPrivilegeDTO insert(PlayerPrivilegeDTO player) {
String sql = "INSERT INTO player_privilege (player_uuid, admin, dom_id) VALUES (" +
"'" + player.getPlayerUUID() + "', " +
player.getAdmin() + ", " +
player.getDomID() +
String sql = "INSERT INTO player_privilege (player_uuid, admin, dom_id, " +
"anchor, animal_killing, anvil, " +
"beacon, bed, brew, break, button, " +
"cake, container, craft, comparer, " +
"door, dye, " +
"egg, enchant, ender_pearl, " +
"feed, " +
"glow, " +
"harvest, honey, hook, " +
"ignite, " +
"lever, " +
"monster_killing, move, " +
"place, pressure, " +
"riding, repeater, " +
"shear, shoot, " +
"trade, " +
"vehicle_destroy" +
") VALUES (" +
"'" + player.getPlayerUUID() + "', " + player.getAdmin() + ", " + player.getDomID() + ", " +
player.getAnchor() + ", " + player.getAnimalKilling() + ", " + player.getAnvil() + ", " +
player.getBeacon() + ", " + player.getBed() + ", " + player.getBrew() + ", " + player.getBreak() + ", " + player.getButton() + ", " +
player.getCake() + ", " + player.getContainer() + ", " + player.getCraft() + ", " + player.getComparer() + ", " +
player.getDoor() + ", " + player.getDye() + ", " +
player.getEgg() + ", " + player.getEnchant() + ", " + player.getEnderPearl() + ", " +
player.getFeed() + ", " +
player.getGlow() + ", " +
player.getHarvest() + ", " + player.getHoney() + ", " + player.getHook() + ", " +
player.getIgnite() + ", " +
player.getLever() + ", " +
player.getMonsterKilling() + ", " + player.getMove() + ", " +
player.getPlace() + ", " + player.getPressure() + ", " +
player.getRiding() + ", " + player.getRepeater() + ", " +
player.getShear() + ", " + player.getShoot() + ", " +
player.getTrade() + ", " +
player.getVehicleDestroy() +
") RETURNING *;";
List<PlayerPrivilegeDTO> players = query(sql);
if (players.size() == 0) return null;

View File

@ -66,10 +66,11 @@ public class Apis {
.add(Line.create().append("缩小领地").append("/dominion contract [大小] [领地名称]"))
.add(Line.create().append("删除领地").append("/dominion delete <领地名称> [force]"))
.add(Line.create().append("设置领地权限").append("/dominion set <权限名称> <true/false> [领地名称]"))
.add(Line.create().append("设置玩家权限").append("/dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]"))
.add(Line.create().append("重置玩家权限").append("/dominion clear_privilege <玩家名称> [领地名称]"))
.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("/dominion privilege_info <玩家名称> [领地名称] [页码]"))
.showOn(player, page);
}

View File

@ -36,10 +36,6 @@ public class DominionPrivilegeList {
ListView view = ListView.create(10, "/dominion privilege_list " + dominion.getName());
if (noAuthToManage(player, dominion)) return;
List<PlayerPrivilegeDTO> privileges = PlayerPrivilegeDTO.select(dominion.getId());
if (privileges.isEmpty()) {
Notification.warn(sender, "领地 " + dominion.getName() + " 没有任何玩家拥有特权");
return;
}
view.title("领地 " + dominion.getName() + " 玩家特权列表");
view.navigator(
Line.create()
@ -48,13 +44,14 @@ public class DominionPrivilegeList {
.append(Button.create("管理界面", "/dominion manage " + dominion.getName()))
.append("特权列表")
);
view.add(Line.create().append(Button.create("选择玩家创建特权", "/dominion select_player_create_privilege " + dominion.getName())));
for (PlayerPrivilegeDTO privilege : privileges) {
PlayerDTO p_player = PlayerDTO.select(privilege.getPlayerUUID());
if (p_player == null) continue;
view.add(Line.create()
.append(p_player.getLastKnownName())
.append(Button.createGreen("管理", "/dominion privilege_info " + p_player.getLastKnownName() + " " + dominion.getName()))
.append(Button.createRed("", "/dominion clear_privilege " + p_player.getLastKnownName() + " " + dominion.getName()))
.append(Button.createRed("", "/dominion clear_privilege " + p_player.getLastKnownName() + " " + dominion.getName() + " b"))
);
}
view.showOn(player, page);

View File

@ -0,0 +1,37 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import static cn.lunadeer.dominion.commands.Apis.playerOnly;
public class SelectPlayer {
// /dominion select_player_create_privilege <领地名称> [页码]
public static void show(CommandSender sender, String[] args) {
Player player = playerOnly(sender);
int page = 1;
if (args.length == 3) {
try {
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);
view.title("选择玩家以创建特权").subtitle("只能选择已经登录过的玩家");
List<PlayerDTO> players = PlayerController.allPlayers();
for (PlayerDTO p : players) {
view.add(Line.create().
append(Button.create(p.getLastKnownName(),
"/dominion create_privilege " + p.getLastKnownName() + " " + dominion_name + " b")));
}
view.showOn(player, page);
}
}