前景需要#
最近 Minecraft サーバープラグインの開発を研究していて、サーバー再起動時にマップをリセットする必要があるシーンがありました。
調べたところ、満足のいく既存のプラグインは見当たらなかったので、自分で作成することにしました。
探索#
最初は直接Slime World Manager
を使おうと思ったのですが、リポジトリを見たら、
このリポジトリは 2025 年 4 月 21 日にオーナーによってアーカイブされました。現在は読み取り専用です。
うーん、でもちょうどその派生フォークを見つけました。
https://github.com/InfernalSuite/AdvancedSlimePaper
とても役に立ちそうですが、そのプラグイン版は私のサーバー(Paper 1.20.4 + Java 24)をあまり好まないようです。
とにかくクラスが見つからないとエラーが出ます。
しかし、彼らは Paper を魔改造するためのブランチを立ち上げたようで、私はあまり好きではありません。
仕方がないので、直接土方法を使うことにしました。
実現#
私たちは Bukkit API がonEnable
とonDisable
を提供していることを知っています。
最初はonEnable
の時にバックアップを一気に復元しようと思っていましたが、Bukkit のプラグインの読み込みはワールドの後に行われます。
また、Bukkit API を通じてデフォルトのワールド(つまりworld
、world_nether
、world_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
のところで呼び出せばいいのです。
え?ワールドがロードされた後にその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 は同期的にプラグインをアンロードするのですから、レースコンディションを心配する必要はありません)。
アーカイブが非常に大きいサーバーでは、完全にバックアップ / 復元が完了するまでに数十秒かかる場合があります(だからあなたのハードディスクの IO が試されるのです!)。
もちろん、以上は最悪の解決策ですが、最も効果的でもあります。
END#
ホイールはすでに作りましたので、君子協定に従って自由にスキッドしてください。
https://github.com/NyaStudio/MapBackup
この記事は Mix Space によって xLog に同期更新されました。
元のリンクは https://blog.xcnya.cn/posts/technology/128.html