数据写入
文档/dominion-api/数据写入

数据写入

使用 Provider 修改 Dominion 数据,并正确处理权限、失败结果和异步回调。

修改领地名称

api.getDominionProvider()
        .renameDominion(Bukkit.getConsoleSender(), dominion, newName)
        .thenAccept(updated -> {
            if (updated == null) {
                getLogger().warning("Rename rejected: " + newName);
                return;
            }
            getLogger().info("Dominion renamed to " + updated.getName());
        });

不需要模拟玩家权限的后台任务可以使用控制台作为 operator。如果操作应该受领地主人或成员权限约束,传入真实的 Player,不要使用控制台替代权限判断。

添加成员并设置权限

PlayerDTO target = api.getPlayer(targetUuid);
if (target == null) {
    return;
}

api.getMemberProvider()
        .addMember(operator, dominion, target)
        .thenAccept(member -> {
            if (member == null) return;

            api.getMemberProvider()
                    .setMemberFlag(operator, dominion, member, Flags.CONTAINER, true)
                    .thenAccept(updated -> {
                        if (updated == null) {
                            getLogger().warning("Member flag update failed.");
                        }
                    });
        });

如果想为一组玩家设置相同权限,创建 GroupDTO 后使用 GroupProvider.setGroupFlag,再用 GroupProvider.addMember 把成员加入组。不要在多个 DTO 上直接复制 flag Map。

创建领地

CuboidDTO cuboid = new CuboidDTO(
        minX, minY, minZ,
        maxX, maxY, maxZ
);

api.getDominionProvider()
        .createDominion(
                Bukkit.getConsoleSender(),
                "addon-created",
                ownerUuid,
                world,
                cuboid,
                null,       // null 表示顶级领地
                true        // 示例中跳过经济检查;生产功能应由管理员配置
        )
        .thenAccept(created -> {
            if (created == null) {
                getLogger().warning("Dominion creation failed.");
                return;
            }
            getLogger().info("Created dominion " + created.getName());
        });

skipEconomy 不应被当成“跳过所有限制”。Dominion 仍会检查名称、数量、边界、重叠、父子关系和其他合法性。

调整边界

使用 DominionReSizeEvent.TYPE.EXPAND/CONTRACTDIRECTION 指定方向:

api.getDominionProvider().resizeDominion(
        operator,
        dominion,
        DominionReSizeEvent.TYPE.EXPAND,
        DominionReSizeEvent.DIRECTION.EAST,
        8
).thenAccept(updated -> {
    if (updated == null) {
        getLogger().warning("Resize rejected.");
    }
});

在生产服开放边界修改前,先检查目标领地的父领地、子领地、相邻领地和管理员权限;Provider 会执行这些检查,但附属仍应给用户清晰的失败提示。

异步调用的注意事项

  • 不要连续调用 future.get()join() 等待结果;
  • 链式操作使用 thenCompose,避免嵌套回调;
  • 回调中不要假设仍处于 Bukkit 主线程或同一个 Folia region;
  • 需要访问在线实体、打开菜单或发送依赖线程模型的操作时,使用对应服务端调度器;
  • 领地已被删除、玩家已离线或操作员权限已变化时,仍可能得到 null/false