Merge branch 'res-migration'

# Conflicts:
#	pom.xml
This commit is contained in:
zhangyuheng 2024-06-26 16:20:01 +08:00
commit b7b7311d5f
18 changed files with 564 additions and 7 deletions

View File

@ -39,6 +39,7 @@
- 支持经济系统(需要 Vault 前置); - 支持经济系统(需要 Vault 前置);
- 领地区域可视化; - 领地区域可视化;
- 管理员可在游戏内使用TUI配置领地系统 - 管理员可在游戏内使用TUI配置领地系统
- 支持[从 Residence 迁移](https://ssl.lunadeer.cn:14448/doc/73/)领地数据;
<div style="text-align: center;"> <div style="text-align: center;">

View File

@ -90,5 +90,10 @@
<version>v2.6.2</version> <version>v2.6.2</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -4,6 +4,7 @@ import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.ResMigration;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.ParticleRender; import cn.lunadeer.minecraftpluginutils.ParticleRender;
import cn.lunadeer.minecraftpluginutils.Scheduler; import cn.lunadeer.minecraftpluginutils.Scheduler;
@ -344,6 +345,25 @@ public class Cache {
return 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() { public List<DominionDTO> getDominions() {
return new ArrayList<>(id_dominions.values()); return new ArrayList<>(id_dominions.values());
} }
@ -361,4 +381,6 @@ public class Cache {
private static final long UPDATE_INTERVAL = 1000 * 4; private static final long UPDATE_INTERVAL = 1000 * 4;
private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态发光飞行 private boolean recheckPlayerState = false; // 是否需要重新检查玩家状态发光飞行
public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>(); public final Map<UUID, LocalDateTime> NextTimeAllowTeleport = new java.util.HashMap<>();
private Map<UUID, List<ResMigration.ResidenceNode>> residence_data = null;
} }

View File

@ -5,6 +5,7 @@ import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.cuis.*; 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.MigrateList;
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;
@ -174,6 +175,12 @@ public class Commands implements TabExecutor {
case "select_template": case "select_template":
SelectTemplate.show(sender, args); SelectTemplate.show(sender, args);
break; break;
case "migrate_list":
MigrateList.show(sender, args);
break;
case "migrate":
Migration.migrate(sender, args);
break;
case "set_map_color": case "set_map_color":
DominionOperate.setMapColor(sender, args); DominionOperate.setMapColor(sender, args);
break; break;

View File

@ -0,0 +1,95 @@
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.commands.Apis.playerOnly;
public class Migration {
public static void migrate(CommandSender sender, String[] args) {
try {
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

@ -67,6 +67,9 @@ public class SetConfig {
case "economy_refund": case "economy_refund":
setEconomyRefund(sender, args); setEconomyRefund(sender, args);
break; break;
case "residence_migration":
setResidenceMigration(sender, args);
break;
default: default:
Notification.error(sender, "未知参数"); Notification.error(sender, "未知参数");
} }
@ -250,4 +253,10 @@ public class SetConfig {
Dominion.config.setEconomyRefund(economyRefund); Dominion.config.setEconomyRefund(economyRefund);
} }
} }
private static void setResidenceMigration(CommandSender sender, String[] args) {
boolean residenceMigration = Boolean.parseBoolean(args[2]);
Dominion.config.setResidenceMigration(residenceMigration);
refreshPageOrNot(sender, args);
}
} }

View File

@ -38,7 +38,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,11 +56,26 @@ 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,
String parent_dominion_name, boolean skipEco) {
AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建领地失败"); AbstractOperator.Result FAIL = new AbstractOperator.Result(AbstractOperator.Result.FAILURE, "创建领地失败");
if (name.isEmpty()) { if (name.isEmpty()) {
operator.setResponse(FAIL.addMessage("领地名称不能为空")); operator.setResponse(FAIL.addMessage("领地名称不能为空"));
@ -143,7 +157,7 @@ public class DominionController {
} }
} }
// 检查经济 // 检查经济
if (Dominion.config.getEconomyEnable()) { if (Dominion.config.getEconomyEnable() && !skipEco) {
if (!VaultConnect.instance.economyAvailable()) { if (!VaultConnect.instance.economyAvailable()) {
operator.setResponse(FAIL.addMessage("没有可用的经济插件系统,请联系服主。")); operator.setResponse(FAIL.addMessage("没有可用的经济插件系统,请联系服主。"));
return; return;
@ -181,7 +195,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);
@ -198,7 +211,6 @@ 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, "扩展领地失败");
@ -304,7 +316,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);
@ -321,7 +332,6 @@ 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, "缩小领地失败");

View File

@ -4,8 +4,11 @@ import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field; import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow; import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow; import cn.lunadeer.minecraftpluginutils.databse.syntax.UpdateRow;
import cn.lunadeer.dominion.Dominion;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
@ -24,6 +27,17 @@ public class PlayerDTO {
return re; 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() { public static List<PlayerDTO> all() {
String sql = "SELECT * FROM player_name WHERE id > 0;"; String sql = "SELECT * FROM player_name WHERE id > 0;";
return query(sql); return query(sql);

View File

@ -83,6 +83,7 @@ public class ConfigManager {
_economy_only_xz = _file.getBoolean("Economy.OnlyXZ", false); _economy_only_xz = _file.getBoolean("Economy.OnlyXZ", false);
_economy_refund = (float) _file.getDouble("Economy.Refund", 0.85); _economy_refund = (float) _file.getDouble("Economy.Refund", 0.85);
_fly_permission_nodes = _file.getStringList("FlyPermissionNodes"); _fly_permission_nodes = _file.getStringList("FlyPermissionNodes");
_residence_migration = _file.getBoolean("ResidenceMigration", false);
saveAll(); // 回写文件 防止文件中的数据不完整 saveAll(); // 回写文件 防止文件中的数据不完整
Flag.loadFromJson(); Flag.loadFromJson();
} }
@ -111,6 +112,7 @@ public class ConfigManager {
_file.set("Economy.OnlyXZ", _economy_only_xz); _file.set("Economy.OnlyXZ", _economy_only_xz);
_file.set("Economy.Refund", _economy_refund); _file.set("Economy.Refund", _economy_refund);
_file.set("FlyPermissionNodes", _fly_permission_nodes); _file.set("FlyPermissionNodes", _fly_permission_nodes);
_file.set("ResidenceMigration", _residence_migration);
_plugin.saveConfig(); _plugin.saveConfig();
} }
@ -388,6 +390,16 @@ public class ConfigManager {
_plugin.saveConfig(); _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();
}
private final Dominion _plugin; private final Dominion _plugin;
private FileConfiguration _file; private FileConfiguration _file;
private Boolean _debug; private Boolean _debug;
@ -426,4 +438,5 @@ public class ConfigManager {
private Boolean _economy_only_xz; private Boolean _economy_only_xz;
private Float _economy_refund; private Float _economy_refund;
private List<String> _fly_permission_nodes; private List<String> _fly_permission_nodes;
private Boolean _residence_migration;
} }

View File

@ -151,6 +151,15 @@ public class DominionConfig {
.append(NumChanger.create(Dominion.config.getEconomyRefund(), "/dominion set_config economy_refund", 0.01).setPageNumber(page).build()); .append(NumChanger.create(Dominion.config.getEconomyRefund(), "/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

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.tuis; package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
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;
@ -38,6 +39,9 @@ public class Menu {
Line link = Line.create() Line link = Line.create()
.append(Button.create("使用文档").setOpenURL("https://ssl.lunadeer.cn:14448/doc/23/").build()) .append(Button.create("使用文档").setOpenURL("https://ssl.lunadeer.cn:14448/doc/23/").build())
.append("在浏览器中打开使用文档"); .append("在浏览器中打开使用文档");
Line migrate = Line.create()
.append(Button.create("迁移数据").setExecuteCommand("/dominion migrate_list").build())
.append("把你的领地从Residence迁移到Dominion");
Line all = Line.create() Line all = Line.create()
.append(Button.create("所有领地").setExecuteCommand("/dominion all_dominion").build()) .append(Button.create("所有领地").setExecuteCommand("/dominion all_dominion").build())
.append("查看所有领地"); .append("查看所有领地");
@ -58,6 +62,9 @@ public class Menu {
.add(template) .add(template)
.add(help) .add(help)
.add(link); .add(link);
if (Dominion.config.getResidenceMigration()) {
view.add(migrate);
}
if (player.isOp()) { if (player.isOp()) {
view.add(Line.create().append("")); view.add(Line.create().append(""));
view.add(Line.create().append(Component.text("--- 以下选项仅OP可见 ---", ViewStyles.main_color))); view.add(Line.create().append(Component.text("--- 以下选项仅OP可见 ---", ViewStyles.main_color)));

View File

@ -0,0 +1,81 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.ResMigration;
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.commands.Apis.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 = 1;
if (args.length == 2) {
try {
page = Integer.parseInt(args[1]);
} catch (Exception ignored) {
}
}
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

@ -0,0 +1,155 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.PlayerDTO;
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.OfflinePlayer;
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) {
OfflinePlayer bukkitOwner = Dominion.instance.getServer().getOfflinePlayer(UUID.fromString(res.Permissions.OwnerUUID));
PlayerDTO owner = PlayerDTO.get(bukkitOwner);
if (owner == null) {
XLogger.warn("Owner not found: " + res.Permissions.OwnerUUID);
return null;
}
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 = owner.getUuid();
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

@ -49,6 +49,9 @@ FlyPermissionNodes:
- essentials.fly - essentials.fly
- cmi.command.fly - cmi.command.fly
# 是否允许玩家从 Residence 迁移领地数据
ResidenceMigration: false
BlueMap: true BlueMap: true
CheckUpdate: true CheckUpdate: true