From 95c7220f4ad661b7f26d3fbadb264e3bb63799f1 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Sun, 19 Apr 2020 00:21:43 +0200 Subject: [PATCH 01/11] Add a delay between unloading and saving edit worlds (WIP) --- .../de/erethon/dungeonsxl/DungeonsXL.java | 3 +- .../erethon/dungeonsxl/config/MainConfig.java | 22 ++++++++- .../dungeonsxl/player/DEditPlayer.java | 2 +- .../erethon/dungeonsxl/world/DEditWorld.java | 47 ++++++++++++++++++- .../dungeonsxl/world/DResourceWorld.java | 18 ++++++- .../de/erethon/dungeonsxl/world/SignData.java | 4 +- 6 files changed, 88 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java index 0b1ce3ab..35e17315 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java +++ b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java @@ -80,6 +80,7 @@ import de.erethon.dungeonsxl.trigger.TriggerListener; import de.erethon.dungeonsxl.trigger.TriggerTypeCache; import de.erethon.dungeonsxl.util.LWCUtil; import de.erethon.dungeonsxl.util.PlaceholderUtil; +import de.erethon.dungeonsxl.world.DEditWorld; import de.erethon.dungeonsxl.world.DResourceWorld; import de.erethon.dungeonsxl.world.DWorldListener; import de.erethon.dungeonsxl.world.LWCIntegration; @@ -436,7 +437,7 @@ public class DungeonsXL extends DREPlugin implements DungeonsAPI { public void saveData() { protections.saveAll(); - instanceCache.getAllIf(i -> i instanceof EditWorld).forEach(i -> ((EditWorld) i).save()); + instanceCache.getAllIf(i -> i instanceof EditWorld).forEach(i -> ((DEditWorld) i).forceSave()); } public void loadData() { diff --git a/core/src/main/java/de/erethon/dungeonsxl/config/MainConfig.java b/core/src/main/java/de/erethon/dungeonsxl/config/MainConfig.java index 980b10ab..ca19d4d5 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/config/MainConfig.java +++ b/core/src/main/java/de/erethon/dungeonsxl/config/MainConfig.java @@ -48,7 +48,7 @@ public class MainConfig extends DREConfig { NEVER } - public static final int CONFIG_VERSION = 17; + public static final int CONFIG_VERSION = 18; private String language = "english"; private boolean enableEconomy = false; @@ -96,6 +96,7 @@ public class MainConfig extends DREConfig { /* Performance */ private int maxInstances = 10; + private int editInstanceRemovalDelay = 5; /* Secure Mode */ private boolean secureModeEnabled = false; @@ -385,6 +386,20 @@ public class MainConfig extends DREConfig { this.maxInstances = maxInstances; } + /** + * @return the delay in seconds until an edit world without players is saved and removed + */ + public int getEditInstanceRemovalDelay() { + return editInstanceRemovalDelay; + } + + /** + * @param delay the delay in seconds until an edit world without players is saved and removed + */ + public void setEditInstanceRemovalDelay(int delay) { + editInstanceRemovalDelay = delay; + } + /** * @return if the secure mode is enabled */ @@ -559,6 +574,10 @@ public class MainConfig extends DREConfig { config.set("maxInstances", maxInstances); } + if (!config.contains("editInstanceRemovalDelay")) { + config.set("editInstanceRemovalDelay", editInstanceRemovalDelay); + } + if (!config.contains("secureMode.enabled")) { config.set("secureMode.enabled", secureModeEnabled); } @@ -647,6 +666,7 @@ public class MainConfig extends DREConfig { } maxInstances = config.getInt("maxInstances", maxInstances); + editInstanceRemovalDelay = config.getInt("editInstanceRemovalDelay", editInstanceRemovalDelay); secureModeEnabled = config.getBoolean("secureMode.enabled", secureModeEnabled); openInventories = config.getBoolean("secureMode.openInventories", openInventories); dropItems = config.getBoolean("secureMode.dropItems", dropItems); diff --git a/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java b/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java index acbda58d..0a1e73cb 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java +++ b/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java @@ -143,7 +143,7 @@ public class DEditPlayer extends DInstancePlayer implements EditPlayer { reset(false); - if (editWorld != null) { + if (editWorld != null && editWorld.getPlayers().isEmpty()) { editWorld.save(); } } diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java index bb94f07d..7df6e6e4 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java @@ -18,16 +18,20 @@ package de.erethon.dungeonsxl.world; import de.erethon.commons.compatibility.Version; import de.erethon.commons.misc.FileUtil; +import de.erethon.commons.misc.ProgressBar; import de.erethon.dungeonsxl.DungeonsXL; import de.erethon.dungeonsxl.api.event.world.EditWorldSaveEvent; import de.erethon.dungeonsxl.api.event.world.EditWorldUnloadEvent; import de.erethon.dungeonsxl.api.world.EditWorld; +import de.erethon.dungeonsxl.player.DEditPlayer; import java.io.File; import java.io.IOException; +import java.util.List; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; /** @@ -87,7 +91,40 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { public void save() { EditWorldSaveEvent event = new EditWorldSaveEvent(this); Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + plugin.setLoadingWorld(true); + List players = getWorld().getPlayers(); + kickAllPlayers(); + + getResource().editWorld = null; + plugin.getInstanceCache().remove(this); + getResource().getSignData().serializeSigns(signs.values()); + Bukkit.unloadWorld(getWorld(), true); + new ProgressBar(players, plugin.getMainConfig().getEditInstanceRemovalDelay()) { + @Override + public void onFinish() { + getResource().clearFolder(); + FileUtil.copyDir(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES); + DResourceWorld.deleteUnusedFiles(getResource().getFolder()); + FileUtil.removeDir(getFolder()); + + EditWorld newEditWorld = getResource().getOrInstantiateEditWorld(true); + players.forEach(p -> { + if (p.isOnline()) { + new DEditPlayer(plugin, p, newEditWorld); + } + }); + plugin.setLoadingWorld(false); + } + }.send(plugin); + } + + public void forceSave() { + EditWorldSaveEvent event = new EditWorldSaveEvent(this); + Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { return; } @@ -116,10 +153,12 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { kickAllPlayers(); if (save) { + getResource().getSignData().serializeSigns(signs.values()); Bukkit.unloadWorld(getWorld(), true); new BukkitRunnable() { @Override public void run() { + getResource().clearFolder(); FileUtil.copyDir(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES); DResourceWorld.deleteUnusedFiles(getResource().getFolder()); FileUtil.removeDir(getFolder()); @@ -128,8 +167,12 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { } if (!save) { Bukkit.unloadWorld(getWorld(), /* SPIGOT-5225 */ !Version.isAtLeast(Version.MC1_14_4)); - DResourceWorld.deleteUnusedFiles(getResource().getFolder()); - FileUtil.removeDir(getFolder()); + new BukkitRunnable() { + @Override + public void run() { + FileUtil.removeDir(getFolder()); + } + }.runTaskLaterAsynchronously(plugin, 200L); } getResource().editWorld = null; diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java index 3f3d44a4..a156ba61 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java @@ -65,7 +65,7 @@ public class DResourceWorld implements ResourceWorld { config = new WorldConfig(plugin, configFile); } - signData = new SignData(new File(folder, "DXLData.data")); + signData = new SignData(new File(folder, SignData.FILE_NAME)); } public DResourceWorld(DungeonsXL plugin, File folder) { @@ -78,7 +78,7 @@ public class DResourceWorld implements ResourceWorld { config = new WorldConfig(plugin, configFile); } - signData = new SignData(new File(folder, "DXLData.data")); + signData = new SignData(new File(folder, SignData.FILE_NAME)); } /* Getters and setters */ @@ -211,6 +211,7 @@ public class DResourceWorld implements ResourceWorld { if (game) { signData.deserializeSigns((DGameWorld) instance); + instance.getWorld().setAutoSave(false); } else { signData.deserializeSigns((DEditWorld) instance); } @@ -297,6 +298,19 @@ public class DResourceWorld implements ResourceWorld { return editWorld; } + void clearFolder() { + for (File file : FileUtil.getFilesForFolder(getFolder())) { + if (file.getName().equals(SignData.FILE_NAME)) { + continue; + } + if (file.isDirectory()) { + FileUtil.removeDir(file); + } else { + file.delete(); + } + } + } + /** * Removes files that are not needed from a world * diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/SignData.java b/core/src/main/java/de/erethon/dungeonsxl/world/SignData.java index c847470d..93993e94 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/SignData.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/SignData.java @@ -36,6 +36,8 @@ import org.bukkit.block.Sign; */ public class SignData { + public static final String FILE_NAME = "DXLData.data"; + private File file; public SignData(File file) { @@ -55,7 +57,7 @@ public class SignData { } public void updateFile(DResourceWorld resource) { - file = new File(resource.getFolder(), "DXLData.data"); + file = new File(resource.getFolder(), FILE_NAME); } /** From 452b3b47002ef004d656299e98063d059c570560 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Sun, 19 Apr 2020 00:21:57 +0200 Subject: [PATCH 02/11] Removing WorldUnloadTask --- .../de/erethon/dungeonsxl/DungeonsXL.java | 2 - .../dungeonsxl/world/WorldUnloadTask.java | 39 ------------------- 2 files changed, 41 deletions(-) delete mode 100644 core/src/main/java/de/erethon/dungeonsxl/world/WorldUnloadTask.java diff --git a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java index 35e17315..4ce6575f 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java +++ b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java @@ -85,7 +85,6 @@ import de.erethon.dungeonsxl.world.DResourceWorld; import de.erethon.dungeonsxl.world.DWorldListener; import de.erethon.dungeonsxl.world.LWCIntegration; import de.erethon.dungeonsxl.world.WorldConfig; -import de.erethon.dungeonsxl.world.WorldUnloadTask; import de.erethon.vignette.api.VignetteAPI; import java.io.File; import java.io.IOException; @@ -352,7 +351,6 @@ public class DungeonsXL extends DREPlugin implements DungeonsAPI { if (!DResourceWorld.RAW.exists()) { DResourceWorld.createRaw(); } - new WorldUnloadTask(this).runTaskTimer(this, 20L, 20L);//1200L Bukkit.getPluginManager().registerEvents(new DWorldListener(this), this); if (LWCUtil.isLWCLoaded()) { new LWCIntegration(this); diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/WorldUnloadTask.java b/core/src/main/java/de/erethon/dungeonsxl/world/WorldUnloadTask.java deleted file mode 100644 index 577e85a5..00000000 --- a/core/src/main/java/de/erethon/dungeonsxl/world/WorldUnloadTask.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2012-2020 Frank Baumann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.erethon.dungeonsxl.world; - -import de.erethon.dungeonsxl.DungeonsXL; -import de.erethon.dungeonsxl.api.world.InstanceWorld; -import org.bukkit.scheduler.BukkitRunnable; - -/** - * @author Frank Baumann, Daniel Saukel - */ -public class WorldUnloadTask extends BukkitRunnable { - - private DungeonsXL plugin; - - public WorldUnloadTask(DungeonsXL plugin) { - this.plugin = plugin; - } - - @Override - public void run() { - plugin.getInstanceCache().getAllIf(i -> ((DInstanceWorld) i).exists() && i.getPlayers().isEmpty()).forEach(InstanceWorld::delete); - } - -} From d62460bbe01b55d31d04a3ef396cd7589322971a Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Sun, 19 Apr 2020 13:51:39 +0200 Subject: [PATCH 03/11] Delete game worlds when no players are left --- .../main/java/de/erethon/dungeonsxl/player/DGamePlayer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/de/erethon/dungeonsxl/player/DGamePlayer.java b/core/src/main/java/de/erethon/dungeonsxl/player/DGamePlayer.java index ce7d34e7..96f0f5ea 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/player/DGamePlayer.java +++ b/core/src/main/java/de/erethon/dungeonsxl/player/DGamePlayer.java @@ -457,6 +457,10 @@ public class DGamePlayer extends DInstancePlayer implements GamePlayer { // ...*flies away* } } + + if (gameWorld.getPlayers().isEmpty()) { + gameWorld.delete(); + } } @Override From f491c53e33db18e2ae07a5ce9d82da0fab953b6c Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Mon, 20 Apr 2020 21:21:46 +0200 Subject: [PATCH 04/11] Use config editInstanceRemovalDelay values --- .../src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java index 7df6e6e4..968db10e 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java @@ -163,7 +163,7 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { DResourceWorld.deleteUnusedFiles(getResource().getFolder()); FileUtil.removeDir(getFolder()); } - }.runTaskLaterAsynchronously(plugin, 200L); + }.runTaskLaterAsynchronously(plugin, plugin.getMainConfig().getEditInstanceRemovalDelay() * 20L); } if (!save) { Bukkit.unloadWorld(getWorld(), /* SPIGOT-5225 */ !Version.isAtLeast(Version.MC1_14_4)); @@ -172,7 +172,7 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { public void run() { FileUtil.removeDir(getFolder()); } - }.runTaskLaterAsynchronously(plugin, 200L); + }.runTaskLaterAsynchronously(plugin, plugin.getMainConfig().getEditInstanceRemovalDelay() * 20L); } getResource().editWorld = null; From 1920f7385999347632a768c644f3492c5ca11d11 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 00:20:44 +0200 Subject: [PATCH 05/11] Use world name instead of WeakReference --- .../erethon/dungeonsxl/global/GlobalProtection.java | 8 ++++---- .../java/de/erethon/dungeonsxl/world/DGameWorld.java | 7 +------ .../de/erethon/dungeonsxl/world/DInstanceWorld.java | 11 ++++++----- .../de/erethon/dungeonsxl/world/DResourceWorld.java | 5 ++--- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/global/GlobalProtection.java b/core/src/main/java/de/erethon/dungeonsxl/global/GlobalProtection.java index 8f7e544f..9ace7c4e 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/global/GlobalProtection.java +++ b/core/src/main/java/de/erethon/dungeonsxl/global/GlobalProtection.java @@ -21,8 +21,8 @@ import de.erethon.dungeonsxl.DungeonsXL; import de.erethon.dungeonsxl.config.DMessage; import de.erethon.dungeonsxl.player.DGlobalPlayer; import java.io.File; -import java.lang.ref.WeakReference; import java.util.Collection; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; @@ -39,7 +39,7 @@ public abstract class GlobalProtection { public static final String SIGN_TAG = "[DXL]"; - private WeakReference world; + private String world; private int id; protected GlobalProtection(DungeonsXL plugin, World world, int id) { @@ -47,7 +47,7 @@ public abstract class GlobalProtection { protections = plugin.getGlobalProtectionCache(); config = plugin.getGlobalData().getConfig(); - this.world = new WeakReference<>(world); + this.world = world.getName(); this.id = id; protections.addProtection(this); @@ -57,7 +57,7 @@ public abstract class GlobalProtection { * @return the world */ public World getWorld() { - return world.get(); + return Bukkit.getWorld(world); } /** diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DGameWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DGameWorld.java index 470262f7..fcf5bab9 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DGameWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DGameWorld.java @@ -96,13 +96,8 @@ public class DGameWorld extends DInstanceWorld implements GameWorld { private boolean readySign; - DGameWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, World world, int id) { - super(plugin, resourceWorld, folder, world, id); - caliburn = plugin.getCaliburn(); - } - DGameWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, int id) { - this(plugin, resourceWorld, folder, null, id); + super(plugin, resourceWorld, folder, id); caliburn = plugin.getCaliburn(); } diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DInstanceWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DInstanceWorld.java index 29067ad9..35dfaf53 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DInstanceWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DInstanceWorld.java @@ -28,7 +28,6 @@ import de.erethon.dungeonsxl.api.player.PlayerCache; import de.erethon.dungeonsxl.api.sign.DungeonSign; import de.erethon.dungeonsxl.api.world.InstanceWorld; import java.io.File; -import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Collection; @@ -51,17 +50,16 @@ public abstract class DInstanceWorld implements InstanceWorld { protected Map signs = new HashMap<>(); private DResourceWorld resourceWorld; private File folder; - WeakReference world; + String world; private int id; private Location lobby; - DInstanceWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, World world, int id) { + DInstanceWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, int id) { this.plugin = plugin; dPlayers = plugin.getPlayerCache(); this.resourceWorld = resourceWorld; this.folder = folder; - this.world = new WeakReference<>(world); this.id = id; plugin.getInstanceCache().add(id, this); @@ -85,7 +83,10 @@ public abstract class DInstanceWorld implements InstanceWorld { @Override public World getWorld() { - return world.get(); + if (world == null) { + return null; + } + return Bukkit.getWorld(world); } /** diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java index a156ba61..80cf4342 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java @@ -29,7 +29,6 @@ import de.erethon.dungeonsxl.api.world.GameWorld; import de.erethon.dungeonsxl.api.world.ResourceWorld; import java.io.File; import java.io.IOException; -import java.lang.ref.WeakReference; import org.bukkit.Bukkit; import org.bukkit.GameRule; import org.bukkit.OfflinePlayer; @@ -201,7 +200,7 @@ public class DResourceWorld implements ResourceWorld { DInstanceWorld instance = game ? new DGameWorld(plugin, this, instanceFolder, id) : new DEditWorld(plugin, this, instanceFolder, id); FileUtil.copyDir(folder, instanceFolder, DungeonsXL.EXCLUDED_FILES); - instance.world = new WeakReference<>(Bukkit.createWorld(WorldCreator.name(name).environment(getWorldEnvironment()))); + instance.world = Bukkit.createWorld(WorldCreator.name(name).environment(getWorldEnvironment())).getName(); instance.getWorld().setGameRule(GameRule.DO_FIRE_TICK, false); if (Bukkit.getPluginManager().isPluginEnabled("dynmap")) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "dynmap pause all"); @@ -292,7 +291,7 @@ public class DResourceWorld implements ResourceWorld { } FileUtil.copyDir(RAW, folder, DungeonsXL.EXCLUDED_FILES); editWorld.generateIdFile(); - editWorld.world = new WeakReference<>(creator.createWorld()); + editWorld.world = creator.createWorld().getName(); editWorld.generateIdFile(); return editWorld; From bcc2dabdf958dde13ca2f9a1104acc6d7c25670c Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 00:22:46 +0200 Subject: [PATCH 06/11] Use world name instead of WeakReference --- .../main/java/de/erethon/dungeonsxl/world/DEditWorld.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java index 968db10e..af9399db 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java @@ -28,7 +28,6 @@ import java.io.File; import java.io.IOException; import java.util.List; import org.bukkit.Bukkit; -import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.entity.Player; @@ -43,12 +42,8 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { private File idFile; - DEditWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, World world, int id) { - super(plugin, resourceWorld, folder, world, id); - } - DEditWorld(DungeonsXL plugin, DResourceWorld resourceWorld, File folder, int id) { - this(plugin, resourceWorld, folder, null, id); + super(plugin, resourceWorld, folder, id); } /* Getters and setters */ From 41715f37b0da42ccaf3ddec2185a2eae2bea86af Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 00:36:18 +0200 Subject: [PATCH 07/11] Don't save world that is already being saved --- .../src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java b/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java index 0a1e73cb..356072a2 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java +++ b/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java @@ -143,7 +143,7 @@ public class DEditPlayer extends DInstancePlayer implements EditPlayer { reset(false); - if (editWorld != null && editWorld.getPlayers().isEmpty()) { + if (!plugin.isLoadingWorld() && editWorld != null && editWorld.getPlayers().isEmpty()) { editWorld.save(); } } From ed838d01dae056a7bbc1ff2703ff97fdf2e70f08 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 13:12:42 +0200 Subject: [PATCH 08/11] Fix world loading state in DEditWorld#save() --- core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java index af9399db..4a63ae98 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java @@ -106,13 +106,13 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { DResourceWorld.deleteUnusedFiles(getResource().getFolder()); FileUtil.removeDir(getFolder()); + plugin.setLoadingWorld(false); EditWorld newEditWorld = getResource().getOrInstantiateEditWorld(true); players.forEach(p -> { if (p.isOnline()) { new DEditPlayer(plugin, p, newEditWorld); } }); - plugin.setLoadingWorld(false); } }.send(plugin); } From 4c159c79a48288ebcd70c21621fa3354520dc7f7 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 13:13:01 +0200 Subject: [PATCH 09/11] Teleport players to the positions where they were --- .../erethon/dungeonsxl/world/DEditWorld.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java index 4a63ae98..ac44d81b 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java @@ -26,8 +26,10 @@ import de.erethon.dungeonsxl.api.world.EditWorld; import de.erethon.dungeonsxl.player.DEditPlayer; import java.io.File; import java.io.IOException; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.entity.Player; @@ -91,14 +93,23 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { } plugin.setLoadingWorld(true); - List players = getWorld().getPlayers(); + Map players = new HashMap<>(); + getWorld().getPlayers().forEach(p -> players.put(p, + new Double[]{ + p.getLocation().getX(), + p.getLocation().getY(), + p.getLocation().getZ(), + new Double(p.getLocation().getYaw()), + new Double(p.getLocation().getPitch()) + } + )); kickAllPlayers(); getResource().editWorld = null; plugin.getInstanceCache().remove(this); getResource().getSignData().serializeSigns(signs.values()); Bukkit.unloadWorld(getWorld(), true); - new ProgressBar(players, plugin.getMainConfig().getEditInstanceRemovalDelay()) { + new ProgressBar(players.keySet(), plugin.getMainConfig().getEditInstanceRemovalDelay()) { @Override public void onFinish() { getResource().clearFolder(); @@ -108,9 +119,11 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { plugin.setLoadingWorld(false); EditWorld newEditWorld = getResource().getOrInstantiateEditWorld(true); - players.forEach(p -> { + players.keySet().forEach(p -> { if (p.isOnline()) { new DEditPlayer(plugin, p, newEditWorld); + Double[] coords = players.get(p); + p.teleport(new Location(newEditWorld.getWorld(), coords[0], coords[1], coords[2], coords[3].floatValue(), coords[4].floatValue())); } }); } From dec5aa62827cb144bb3ad000e72a946f0eaa21c4 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 13:54:09 +0200 Subject: [PATCH 10/11] Delete edit worlds when no editors are left --- .../src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java b/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java index 356072a2..3bd56cb5 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java +++ b/core/src/main/java/de/erethon/dungeonsxl/player/DEditPlayer.java @@ -144,7 +144,7 @@ public class DEditPlayer extends DInstancePlayer implements EditPlayer { reset(false); if (!plugin.isLoadingWorld() && editWorld != null && editWorld.getPlayers().isEmpty()) { - editWorld.save(); + editWorld.delete(); } } From db67bae75ee03c61dddf969a18cd277760b14de1 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 1 May 2020 14:04:37 +0200 Subject: [PATCH 11/11] Remove Paper check --- .../de/erethon/dungeonsxl/DungeonsXL.java | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java index 4ce6575f..2467aa06 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java +++ b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java @@ -87,7 +87,6 @@ import de.erethon.dungeonsxl.world.LWCIntegration; import de.erethon.dungeonsxl.world.WorldConfig; import de.erethon.vignette.api.VignetteAPI; import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -97,8 +96,6 @@ import java.util.Map.Entry; import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; @@ -207,23 +204,8 @@ public class DungeonsXL extends DREPlugin implements DungeonsAPI { @Override public void onEnable() { super.onEnable(); - if (compat.isPaper() && Internals.andHigher(Internals.v1_14_R1).contains(compat.getInternals()) && System.getProperty("XLDevMode") == null) { - File paperFile = new File("paper.yml"); - FileConfiguration paperConfig = YamlConfiguration.loadConfiguration(paperFile); - if (paperConfig.getBoolean("settings.async-chunks.enable")) { - MessageUtil.log(this, "&4It seems that the server runs Paper 1.14 or higher and that asynchronous world / chunk (un-) loading is enabled."); - MessageUtil.log(this, "&4This feature seems to be too error-prone for massive usage at runtime, which DungeonsXL requires."); - MessageUtil.log(this, "&4See &6https://github.com/PaperMC/Paper/issues/3063 &4for further information."); - MessageUtil.log(this, "&4The server will be restarted with asynchronous chunk loading turned off."); - paperConfig.set("settings.async-chunks.enable", false); - try { - paperConfig.save(paperFile); - } catch (IOException exception) { - exception.printStackTrace(); - } - getServer().spigot().restart(); - return; - } + if (Internals.andHigher(Internals.v1_14_R1).contains(compat.getInternals())) { + getLogger().warning("Support for Minecraft 1.14 and higher is experimental. Do not use this in a production environment."); } instance = this;