Wrap all World fields in WeakReferences

This commit is contained in:
Daniel Saukel 2020-04-17 23:16:58 +02:00
parent 85bfacc9ec
commit 964337815b
6 changed files with 34 additions and 37 deletions

View File

@ -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> 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();
}
/**

View File

@ -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);
}
}

View File

@ -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());

View File

@ -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;
}

View File

@ -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<Block, DungeonSign> signs = new HashMap<>();
private DResourceWorld resourceWorld;
private File folder;
World world;
WeakReference<World> 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));
}
}

View File

@ -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;