From 964337815bdbc89cf6d839d47fb94417b9f03734 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 17 Apr 2020 23:16:58 +0200 Subject: [PATCH] Wrap all World fields in WeakReferences --- .../dungeonsxl/global/GlobalProtection.java | 14 ++++------- .../dungeonsxl/player/DInstancePlayer.java | 10 ++------ .../erethon/dungeonsxl/world/DEditWorld.java | 11 +++++++-- .../erethon/dungeonsxl/world/DGameWorld.java | 6 ++--- .../dungeonsxl/world/DInstanceWorld.java | 23 ++++++++++--------- .../dungeonsxl/world/DResourceWorld.java | 7 +++--- 6 files changed, 34 insertions(+), 37 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 babed504..8f7e544f 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/global/GlobalProtection.java +++ b/core/src/main/java/de/erethon/dungeonsxl/global/GlobalProtection.java @@ -21,6 +21,7 @@ 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.World; import org.bukkit.block.Block; @@ -38,7 +39,7 @@ public abstract class GlobalProtection { public static final String SIGN_TAG = "[DXL]"; - private World world; + private WeakReference world; private int id; protected GlobalProtection(DungeonsXL plugin, World world, int id) { @@ -46,7 +47,7 @@ public abstract class GlobalProtection { protections = plugin.getGlobalProtectionCache(); config = plugin.getGlobalData().getConfig(); - this.world = world; + this.world = new WeakReference<>(world); this.id = id; protections.addProtection(this); @@ -56,14 +57,7 @@ public abstract class GlobalProtection { * @return the world */ public World getWorld() { - return world; - } - - /** - * @param world the world to set - */ - public void setWorld(World world) { - this.world = world; + return world.get(); } /** diff --git a/core/src/main/java/de/erethon/dungeonsxl/player/DInstancePlayer.java b/core/src/main/java/de/erethon/dungeonsxl/player/DInstancePlayer.java index f993549f..2a27e18f 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/player/DInstancePlayer.java +++ b/core/src/main/java/de/erethon/dungeonsxl/player/DInstancePlayer.java @@ -35,7 +35,6 @@ public abstract class DInstancePlayer extends DGlobalPlayer implements InstanceP protected MainConfig config; private InstanceWorld instanceWorld; - private World world; DInstancePlayer(DungeonsXL plugin, Player player, InstanceWorld world) { super(plugin, player, false); @@ -43,7 +42,6 @@ public abstract class DInstancePlayer extends DGlobalPlayer implements InstanceP config = plugin.getMainConfig(); instanceWorld = world; - this.world = world.getWorld(); getData().savePlayerState(player); } @@ -55,11 +53,7 @@ public abstract class DInstancePlayer extends DGlobalPlayer implements InstanceP @Override public World getWorld() { - return world; - } - - public void setWorld(World instance) { - world = instance; + return instanceWorld.getWorld(); } // Players in dungeons never get announcer messages @@ -115,7 +109,7 @@ public abstract class DInstancePlayer extends DGlobalPlayer implements InstanceP for (GlobalPlayer player : plugin.getPlayerCache()) { if (player.isInChatSpyMode()) { - if (!world.getPlayers().contains(player.getPlayer())) { + if (!getWorld().getPlayers().contains(player.getPlayer())) { player.sendMessage(ParsingUtil.replaceChatPlaceholders(config.getChatFormatSpy(), this) + message); } } 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 5e535fdc..196a1c97 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DEditWorld.java @@ -28,6 +28,7 @@ import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; +import org.bukkit.scheduler.BukkitRunnable; /** * @author Frank Baumann, Daniel Saukel @@ -116,11 +117,17 @@ public class DEditWorld extends DInstanceWorld implements EditWorld { if (save) { Bukkit.unloadWorld(getWorld(), true); + new BukkitRunnable() { + @Override + public void run() { + FileUtil.copyDir(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES); + DResourceWorld.deleteUnusedFiles(getResource().getFolder()); + } + }.runTaskLater(plugin, 200L); } - FileUtil.copyDir(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES); - DResourceWorld.deleteUnusedFiles(getResource().getFolder()); if (!save) { Bukkit.unloadWorld(getWorld(), /* SPIGOT-5225 */ !Version.isAtLeast(Version.MC1_14_4)); + DResourceWorld.deleteUnusedFiles(getResource().getFolder()); } FileUtil.removeDir(getFolder()); 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 81041f38..949ddf97 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DGameWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DGameWorld.java @@ -410,8 +410,8 @@ public class DGameWorld extends DInstanceWorld implements GameWorld { return; } - world.setDifficulty(getRules().getState(GameRule.DIFFICULTY)); - world.setGameRule(org.bukkit.GameRule.DO_FIRE_TICK, getRules().getState(GameRule.FIRE_TICK)); + getWorld().setDifficulty(getRules().getState(GameRule.DIFFICULTY)); + getWorld().setGameRule(org.bukkit.GameRule.DO_FIRE_TICK, getRules().getState(GameRule.FIRE_TICK)); isPlaying = true; @@ -512,7 +512,7 @@ public class DGameWorld extends DInstanceWorld implements GameWorld { } // Cancel if a protected entity is attached - for (Entity entity : world.getNearbyEntities(block.getLocation(), 2, 2, 2)) { + for (Entity entity : getWorld().getNearbyEntities(block.getLocation(), 2, 2, 2)) { if (!(entity instanceof Hanging)) { continue; } 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 8caf993f..29067ad9 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DInstanceWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DInstanceWorld.java @@ -28,6 +28,7 @@ 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; @@ -50,7 +51,7 @@ public abstract class DInstanceWorld implements InstanceWorld { protected Map signs = new HashMap<>(); private DResourceWorld resourceWorld; private File folder; - World world; + WeakReference world; private int id; private Location lobby; @@ -60,7 +61,7 @@ public abstract class DInstanceWorld implements InstanceWorld { this.resourceWorld = resourceWorld; this.folder = folder; - this.world = world; + this.world = new WeakReference<>(world); this.id = id; plugin.getInstanceCache().add(id, this); @@ -84,7 +85,7 @@ public abstract class DInstanceWorld implements InstanceWorld { @Override public World getWorld() { - return world; + return world.get(); } /** @@ -167,30 +168,30 @@ public abstract class DInstanceWorld implements InstanceWorld { public void kickAllPlayers() { getPlayers().forEach(p -> p.leave()); // Players who shouldn't be in the dungeon but still are for some reason - world.getPlayers().forEach(p -> PlayerUtil.secureTeleport(p, Bukkit.getWorlds().get(0).getSpawnLocation())); + getWorld().getPlayers().forEach(p -> PlayerUtil.secureTeleport(p, Bukkit.getWorlds().get(0).getSpawnLocation())); } /** * @param rules sets up the time and weather to match the rules */ public void setWeather(GameRuleContainer rules) { - if (world == null) { + if (world == null || getWorld() == null) { return; } if (rules.getState(GameRule.THUNDER) != null) { if (rules.getState(GameRule.THUNDER)) { - world.setThundering(true); - world.setStorm(true); - world.setThunderDuration(Integer.MAX_VALUE); + getWorld().setThundering(true); + getWorld().setStorm(true); + getWorld().setThunderDuration(Integer.MAX_VALUE); } else { - world.setThundering(false); - world.setStorm(false); + getWorld().setThundering(false); + getWorld().setStorm(false); } } if (rules.getState(GameRule.TIME) != null) { - world.setTime(rules.getState(GameRule.TIME)); + getWorld().setTime(rules.getState(GameRule.TIME)); } } 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 c2ed35c6..095aa8dc 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java +++ b/core/src/main/java/de/erethon/dungeonsxl/world/DResourceWorld.java @@ -29,6 +29,7 @@ import de.erethon.dungeonsxl.api.world.ResourceWorld; import de.erethon.dungeonsxl.event.editworld.EditWorldGenerateEvent; 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; @@ -200,8 +201,8 @@ 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 = Bukkit.createWorld(WorldCreator.name(name).environment(getWorldEnvironment())); - instance.world.setGameRule(GameRule.DO_FIRE_TICK, false); + instance.world = new WeakReference<>(Bukkit.createWorld(WorldCreator.name(name).environment(getWorldEnvironment()))); + instance.getWorld().setGameRule(GameRule.DO_FIRE_TICK, false); if (Bukkit.getPluginManager().isPluginEnabled("dynmap")) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "dynmap pause all"); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "dmap worldset " + name + " enabled:false"); @@ -290,7 +291,7 @@ public class DResourceWorld implements ResourceWorld { } FileUtil.copyDir(RAW, folder, DungeonsXL.EXCLUDED_FILES); editWorld.generateIdFile(); - editWorld.world = creator.createWorld(); + editWorld.world = new WeakReference<>(creator.createWorld()); editWorld.generateIdFile(); return editWorld;