Помогите Ошибки при удалении мира

l_Slime_l

Активный участник
Пользователь
Баллы
76
Для моей мини-игры нужно удалить мир, который был скопирован. Он удаляется, но остаётся папка region и вся консоль захламляется ошибками ( 100+ штук 👎 ). Каждая ошибка однотипная и выглядит примерно так:
[18:48:53 ERROR]: Couldn't save chunk; already in use by another instance of Minecraft?
net.minecraft.server.v1_12_R1.ExceptionWorldConflict: Failed to check session lock for world located at .\Beach11, aborting. Stop the server and delete the session.lock in this world to prevent further issues.
at net.minecraft.server.v1_12_R1.WorldNBTStorage.checkSession(WorldNBTStorage.java:85) ~[spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.World.checkSession(World.java:2814) ~[spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.ChunkRegionLoader.saveChunk(ChunkRegionLoader.java:127) ~[spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.ChunkProviderServer.saveChunk(ChunkProviderServer.java:209) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.ChunkProviderServer.unloadChunk(ChunkProviderServer.java:316) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.ChunkProviderServer.unloadChunks(ChunkProviderServer.java:268) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.WorldServer.doTick(WorldServer.java:294) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:801) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:406) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679) [spigot.jar:git-Spigot-3d850ec-809c399]
at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577) [spigot.jar:git-Spigot-3d850ec-809c399]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_161]
По идее, виноват файл session.lock..
Вот как я удаляю мир. (Пробовал оба метода)
Код:
public static boolean deleteWorld(String worldName, boolean loaded) {
         if (loaded) {
             unloadWorld(worldName);
         }
         File path = new File (worldName);
         if (path.exists()) {
             for (File file : path.listFiles()) {
                 if (file.isDirectory()) {
                     deleteWorld(worldName + "\\" + file.getName(), false);
                 } else {
                     file.delete();
                 }
             }
         }
         return (path.delete());
     }
Код:
public static boolean deleteWorld(File path) {
        if (path.exists()) {
            File files[] = path.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    deleteWorld(files[i]);
                } else {
                    files[i].delete();
                }
            }
        }
        return (path.delete());
    }
 
Java:
public static void removeWorld(String worldName) {
    World world = Bukkit.getWorld(worldName);
    if (world != null) {
        if (!world.getPlayers().isEmpty()) {
            throw new IllegalStateException("The world \"" + worldName + "\" still contains a players. You need " +
                    "to teleport them to the another world before unloading that world.");
        }
        if (!Bukkit.unloadWorld(world, false)) {
            throw new InternalError("Failed to unload world \"" + worldName + "\"");
        }
    }

    final File worldDir = Paths.get(".", worldName).toAbsolutePath().normalize().toFile();

    if (!org.apache.commons.io.FileUtils.deleteQuietly(worldDir)) {
        //worldDir is not fully deleted.
    }
}
 
Последнее редактирование:
Java:
public static void removeWorld(String worldName) {
    World world = Bukkit.getWorld(worldName);
    if (world != null) {
        if (!world.getPlayers().isEmpty()) {
            throw new IllegalStateException("The world \"" + worldName + "\" still contains a players. You need " +
                    "to teleport them to the another world before unloading that world.");
        }
        if (!Bukkit.unloadWorld(world, false)) {
            throw new InternalError("Failed to unload world \"" + worldName + "\"");
        }
    }

    final File worldDir = Paths.get(".", worldName.toLowerCase(Locale.ENGLISH))
            .toAbsolutePath().normalize().toFile();

    if (!org.apache.commons.io.FileUtils.deleteQuietly(worldDir)) {
        //worldDir is not fully deleted.
    }
}
Как сделать чтобы этот код выполнялся через определенное время? BukkitRunnable не работает.. Мне просто игроков с арены нужно телепортировать.
 
Так телепортируй и после этого запускай. Сервер однопоточный, все телепортируются.
Я понял почему не срабатывает. Пока игрок не нажмет Respawn, он как бы всё ещё в этом мире. Как его быстро отреспавнить без нажатия кнопки?
UPD. Уже разобрался.
 
С этим разобрался, но у меня папка region всё равно не удаляется.
А она, увы, не удалится. Надо будет копать nms, освобождать File, и принудительно снимать лок с папки.
А ещё проверять плагины, которые хранят экземпляр World в себе.
 
NMS кэширует доступ к файлам мира, потому даже после выгрузки мира зачастую удалить нельзя. Иногда людям везёт и либо файлов в кэшэ уже нет, либо сервер успел всё сохранить и выгрузить из кэша к моменту начала удаления. Так что в общем и целом безопасно выгруженный мир никак не удалить. Потому люди и используют одноразовые сервера за bungeecord для этого.
 
Назад
Верх