banner
libxcnya.so

libxcnya.so

Nothing...
telegram
twitter
github
email

一种基于 File IO 的 Bukkit 地图备份还原技术?

前景需要#

最近在研究 Minecraft 服务端插件开发,有一个场景需要用到服务器重启时重置地图
搜了一圈好像并没有什么现有的尽人意的插件,于是决定自己写一个

探索#

最开始想直接用 Slime World Manager 的,但是一看仓库

This repository was archived by the owner on Apr 21, 2025. It is now read-only.

呃呃,不过恰好又看到它的一个衍生 fork
https://github.com/InfernalSuite/AdvancedSlimePaper

看起来很有用,不过它的插件版好像不太喜欢我的服务器(Paper 1.20.4 + Java 24)
反正就报缺类

但是呢他们好像又起了个分支去魔改 Paper 了,我不是很喜欢
没办法了,直接用土方法

实现#

我们都知道 Bukkit API 提供了 onEnableonDisable
原本想的是直接在 onEnable 的时候备份还原一气呵成,但是 Bukkit 的插件加载是比 world 后的
而且我们不能通过 Bukkit API 直接卸载默认世界(也就是 worldworld_netherworld_end

用正常的 Bukkit.unloadWorld(Bukkit.getWorld("world"), false); 是没法卸载的,即使没报错(实际上被忽略了)
所以我们不能在 onEnable 的时候还原

那有没有更好的位置呢,相信聪明的你一定想到了,那就是 onDisable
所以我们就可以在 onEnable 的时候备份地图,在每次 onDisable 的时候给复制回去

大致如下

    private void copyWorld(Path source, Path target) throws IOException {
        Files.walkFileTree(source, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                Path targetDir = target.resolve(source.relativize(dir));
                Files.createDirectories(targetDir);
                return FileVisitResult.CONTINUE;
            }
        });
    }

然后在 onDisable 处调用就行了
欸你问我 world 被加载后那个 session.lock 被挂锁了没法复制?那我们跳过不就好了吗!

     @Override
     public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
         if (!file.getFileName().toString().endsWith(".lock")) {
             Files.copy(file, target.resolve(source.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
         }
         return FileVisitResult.CONTINUE;
     }

然后你已经会写这个逻辑了,快去写个插件!

注意事项#

这个方法对于那些不好好关服务器的人不友好(指不用 Ctrl+C 或者 /stop 的)
因为那样无法触发 onDisable 所以无法触发还原事件(不过不用担心,你下次正常关就能还原)

调用 copyWorld 个人认为应该保持同步(Bukkit 不就是同步卸载插件的吗,所以应该不用担心 race condition)
对于存档过于大的服务器可能需要数十秒才能完全 备份 / 还原 完成(所以要考验你的硬盘 IO 啦!)

当然,以上只是最坏的解决方案,但是也最有效

END#

轮子我已经造好了,在遵循君子协议的情况下随便 skid
https://github.com/NyaStudio/MapBackup

此文由 Mix Space 同步更新至 xLog
原始链接为 https://blog.xcnya.cn/posts/technology/128.html


読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。