#39: Copy files and load worlds asynchronously

This commit is contained in:
Daniel Saukel 2016-07-08 20:41:04 +02:00
parent 3778009785
commit 27afe9b1fd
26 changed files with 624 additions and 137 deletions

View File

@ -32,6 +32,7 @@ DungeonsXL also provides custom game mechanics to make these worlds interesting.
* A powerful API: [Read more...](../../wiki/api-tutorial) * A powerful API: [Read more...](../../wiki/api-tutorial)
* Different game types allow you to use your maps dynamically for different purposes. [Read more...](../../wiki/game-types) * Different game types allow you to use your maps dynamically for different purposes. [Read more...](../../wiki/game-types)
* Announcements sothat users can join the next match easily. [Read more...](../../wiki/announcements) * Announcements sothat users can join the next match easily. [Read more...](../../wiki/announcements)
* Great performance due to a custom, asynchronous world loading and creation method and several other performance tweaks
* ...and many more! * ...and many more!
@ -49,7 +50,7 @@ If you want to learn how to use DungeonsXL step by step, please have a look at t
DungeonsXL works with 1.7.8 and higher. However, support for 1.10.x / 1.9.x has a higher priority than support for 1.8.x and lower. Some cosmetic features require the Spigot API and will therefore not work with CraftBukkit. DungeonsXL works with 1.7.8 and higher. However, support for 1.10.x / 1.9.x has a higher priority than support for 1.8.x and lower. Some cosmetic features require the Spigot API and will therefore not work with CraftBukkit.
Older versions of DungeonsXL support versions since Minecraft 1.3.x, but of course, they are completely unsupported. Older versions of DungeonsXL support versions since Minecraft 1.3.x, but of course, they are completely unsupported.
* [1.7.8-1.10](../../tree/master) * [1.7.8-1.10.2](../../tree/master)
* [1.7.5](../../tree/50f772d14281bfe278dba2559d1758cc459c1a30) * [1.7.5](../../tree/50f772d14281bfe278dba2559d1758cc459c1a30)
* [1.7.2](../../tree/eccf82b7335dfb0723e3cd37a57df1a968ea7842) * [1.7.2](../../tree/eccf82b7335dfb0723e3cd37a57df1a968ea7842)
* [1.6.4](../../tree/780145cf783ea76fe1bfee04cf89216bd4f92e1d) * [1.6.4](../../tree/780145cf783ea76fe1bfee04cf89216bd4f92e1d)

View File

@ -70,7 +70,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version> <version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -121,11 +121,6 @@
<artifactId>BetonQuest</artifactId> <artifactId>BetonQuest</artifactId>
<version>1.8.5</version> <version>1.8.5</version>
</dependency> </dependency>
<dependency>
<groupId>com.boydti</groupId>
<artifactId>fawe-api</artifactId>
<version>3.5.0-dev</version>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
<repository> <repository>

View File

@ -188,6 +188,7 @@ public class DungeonsXL extends BRPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
mainConfig.setTweaksEnabled(false);
// Save // Save
saveData(); saveData();
messageConfig.save(); messageConfig.save();

View File

@ -97,7 +97,7 @@ public class CreateCommand extends BRCommand {
MessageUtil.log(plugin, DMessages.LOG_WORLD_GENERATION_FINISHED.getMessage()); MessageUtil.log(plugin, DMessages.LOG_WORLD_GENERATION_FINISHED.getMessage());
// Tp Player // Tp Player
new DEditPlayer(player, editWorld.getWorld()); DEditPlayer.create(player, editWorld);
} }
} }

View File

@ -77,7 +77,7 @@ public class EditCommand extends BRCommand {
return; return;
} }
new DEditPlayer(player, editWorld.getWorld()); DEditPlayer.create(player, editWorld);
} }
} }

View File

@ -81,7 +81,7 @@ public class EnterCommand extends BRCommand {
joining.sendMessage(DMessages.CMD_ENTER_SUCCESS.getMessage(joining.getName(), targetName)); joining.sendMessage(DMessages.CMD_ENTER_SUCCESS.getMessage(joining.getName(), targetName));
for (Player player : joining.getPlayers()) { for (Player player : joining.getPlayers()) {
new DGamePlayer(player, game.getWorld()).ready(); DGamePlayer.create(player, game.getWorld(), true);
} }
} }

View File

@ -27,6 +27,7 @@ import java.io.File;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
/** /**
* @author Frank Baumann, Daniel Saukel * @author Frank Baumann, Daniel Saukel
@ -47,8 +48,8 @@ public class ImportCommand extends BRCommand {
@Override @Override
public void onExecute(String[] args, CommandSender sender) { public void onExecute(String[] args, CommandSender sender) {
File target = new File(DungeonsXL.MAPS, args[1]); final File target = new File(DungeonsXL.MAPS, args[1]);
File source = new File(Bukkit.getWorldContainer(), args[1]); final File source = new File(Bukkit.getWorldContainer(), args[1]);
if (!source.exists()) { if (!source.exists()) {
MessageUtil.sendMessage(sender, DMessages.ERROR_NO_SUCH_MAP.getMessage(args[1])); MessageUtil.sendMessage(sender, DMessages.ERROR_NO_SUCH_MAP.getMessage(args[1]));
@ -68,10 +69,19 @@ public class ImportCommand extends BRCommand {
MessageUtil.log(plugin, DMessages.LOG_NEW_MAP.getMessage()); MessageUtil.log(plugin, DMessages.LOG_NEW_MAP.getMessage());
MessageUtil.log(plugin, DMessages.LOG_IMPORT_WORLD.getMessage()); MessageUtil.log(plugin, DMessages.LOG_IMPORT_WORLD.getMessage());
if (!plugin.getMainConfig().areTweaksEnabled()) {
FileUtil.copyDirectory(source, target, new String[]{"playerdata", "stats"}); FileUtil.copyDirectory(source, target, new String[]{"playerdata", "stats"});
plugin.getDWorlds().addResource(new DResourceWorld(plugin.getDWorlds(), args[1])); } else {
new BukkitRunnable() {
@Override
public void run() {
FileUtil.copyDirectory(source, target, new String[]{"playerdata", "stats"});
}
}.runTaskAsynchronously(plugin);
}
plugin.getDWorlds().addResource(new DResourceWorld(plugin.getDWorlds(), args[1]));
MessageUtil.sendMessage(sender, DMessages.CMD_IMPORT_SUCCESS.getMessage(args[1])); MessageUtil.sendMessage(sender, DMessages.CMD_IMPORT_SUCCESS.getMessage(args[1]));
} }

View File

@ -58,8 +58,10 @@ public class ListCommand extends BRCommand {
} }
ArrayList<String> mapList = new ArrayList<>(); ArrayList<String> mapList = new ArrayList<>();
for (File file : DungeonsXL.MAPS.listFiles()) { for (File file : DungeonsXL.MAPS.listFiles()) {
if (!file.equals(DWorlds.RAW)) {
mapList.add(file.getName()); mapList.add(file.getName());
} }
}
ArrayList<String> loadedList = new ArrayList<>(); ArrayList<String> loadedList = new ArrayList<>();
for (DEditWorld editWorld : worlds.getEditWorlds()) { for (DEditWorld editWorld : worlds.getEditWorlds()) {
loadedList.add(editWorld.getWorld().getWorldFolder().getName()); loadedList.add(editWorld.getWorld().getWorldFolder().getName());

View File

@ -145,12 +145,12 @@ public class PlayCommand extends BRCommand {
if (dGroup.getGameWorld().getLobbyLocation() == null) { if (dGroup.getGameWorld().getLobbyLocation() == null) {
for (Player groupPlayer : dGroup.getPlayers()) { for (Player groupPlayer : dGroup.getPlayers()) {
new DGamePlayer(groupPlayer, dGroup.getGameWorld()); DGamePlayer.create(groupPlayer, dGroup.getGameWorld());
} }
} else { } else {
for (Player groupPlayer : dGroup.getPlayers()) { for (Player groupPlayer : dGroup.getPlayers()) {
new DGamePlayer(groupPlayer, dGroup.getGameWorld()); DGamePlayer.create(groupPlayer, dGroup.getGameWorld());
} }
} }
} }

View File

@ -20,6 +20,7 @@ import io.github.dre2n.commons.command.BRCommand;
import io.github.dre2n.commons.util.messageutil.MessageUtil; import io.github.dre2n.commons.util.messageutil.MessageUtil;
import io.github.dre2n.dungeonsxl.DungeonsXL; import io.github.dre2n.dungeonsxl.DungeonsXL;
import io.github.dre2n.dungeonsxl.config.DMessages; import io.github.dre2n.dungeonsxl.config.DMessages;
import io.github.dre2n.dungeonsxl.config.MainConfig;
import io.github.dre2n.dungeonsxl.config.MainConfig.BackupMode; import io.github.dre2n.dungeonsxl.config.MainConfig.BackupMode;
import io.github.dre2n.dungeonsxl.player.DPermissions; import io.github.dre2n.dungeonsxl.player.DPermissions;
import io.github.dre2n.dungeonsxl.world.DEditWorld; import io.github.dre2n.dungeonsxl.world.DEditWorld;
@ -32,6 +33,7 @@ import org.bukkit.entity.Player;
public class SaveCommand extends BRCommand { public class SaveCommand extends BRCommand {
DungeonsXL plugin = DungeonsXL.getInstance(); DungeonsXL plugin = DungeonsXL.getInstance();
MainConfig mainConfig = plugin.getMainConfig();
public SaveCommand() { public SaveCommand() {
setCommand("save"); setCommand("save");
@ -47,9 +49,9 @@ public class SaveCommand extends BRCommand {
Player player = (Player) sender; Player player = (Player) sender;
DEditWorld editWorld = DEditWorld.getByWorld(player.getWorld()); DEditWorld editWorld = DEditWorld.getByWorld(player.getWorld());
if (editWorld != null) { if (editWorld != null) {
BackupMode backupMode = plugin.getMainConfig().getBackupMode(); BackupMode backupMode = mainConfig.getBackupMode();
if (backupMode == BackupMode.ON_SAVE || backupMode == BackupMode.ON_DISABLE_AND_SAVE) { if (backupMode == BackupMode.ON_SAVE || backupMode == BackupMode.ON_DISABLE_AND_SAVE) {
editWorld.getResource().backup(false); editWorld.getResource().backup(mainConfig.areTweaksEnabled());
} }
editWorld.save(); editWorld.save();

View File

@ -38,7 +38,7 @@ public class MainConfig extends BRConfig {
NEVER NEVER
} }
public static final int CONFIG_VERSION = 10; public static final int CONFIG_VERSION = 11;
private String language = "english"; private String language = "english";
private boolean enableEconomy = false; private boolean enableEconomy = false;
@ -65,7 +65,10 @@ public class MainConfig extends BRConfig {
/* Misc */ /* Misc */
private boolean sendFloorTitle = true; private boolean sendFloorTitle = true;
private Map<String, Object> externalMobProviders = new HashMap<>(); private Map<String, Object> externalMobProviders = new HashMap<>();
/* Performance */
private int maxInstances = 10; private int maxInstances = 10;
private boolean tweaksEnabled = false;
/* Secure Mode */ /* Secure Mode */
private boolean secureModeEnabled = false; private boolean secureModeEnabled = false;
@ -247,6 +250,21 @@ public class MainConfig extends BRConfig {
this.maxInstances = maxInstances; this.maxInstances = maxInstances;
} }
/**
* @return if the performance tweaks are enabled
*/
public boolean areTweaksEnabled() {
return tweaksEnabled;
}
/**
* @param enabled
* if the performance tweaks are enabled
*/
public void setTweaksEnabled(boolean enabled) {
tweaksEnabled = enabled;
}
/** /**
* @return if the secure mode is enabled * @return if the secure mode is enabled
*/ */
@ -390,6 +408,10 @@ public class MainConfig extends BRConfig {
config.set("maxInstances", maxInstances); config.set("maxInstances", maxInstances);
} }
if (!config.contains("tweaksEnabled")) {
config.set("tweaksEnabled", tweaksEnabled);
}
if (!config.contains("secureMode.enabled")) { if (!config.contains("secureMode.enabled")) {
config.set("secureMode.enabled", secureModeEnabled); config.set("secureMode.enabled", secureModeEnabled);
} }
@ -473,6 +495,10 @@ public class MainConfig extends BRConfig {
maxInstances = config.getInt("maxInstances"); maxInstances = config.getInt("maxInstances");
} }
if (config.contains("tweaksEnabled")) {
tweaksEnabled = config.getBoolean("tweaksEnabled");
}
if (config.contains("secureMode.enabled")) { if (config.contains("secureMode.enabled")) {
secureModeEnabled = config.getBoolean("secureMode.enabled"); secureModeEnabled = config.getBoolean("secureMode.enabled");
} }

View File

@ -57,7 +57,8 @@ public class SignData {
* the DEditWorld where the signs are * the DEditWorld where the signs are
* @throws IOException * @throws IOException
*/ */
public void deserializeSigns(DEditWorld editWorld) throws IOException { public void deserializeSigns(DEditWorld editWorld) {
try {
ObjectInputStream os = new ObjectInputStream(new FileInputStream(file)); ObjectInputStream os = new ObjectInputStream(new FileInputStream(file));
int length = os.readInt(); int length = os.readInt();
@ -78,6 +79,10 @@ public class SignData {
} }
} }
} }
} catch (IOException exception) {
exception.printStackTrace();
}
} }
/** /**
@ -88,7 +93,8 @@ public class SignData {
* @return a Set of all DSign blocks * @return a Set of all DSign blocks
* @throws IOException * @throws IOException
*/ */
public void deserializeSigns(DGameWorld gameWorld) throws IOException { public void deserializeSigns(DGameWorld gameWorld) {
try {
ObjectInputStream os = new ObjectInputStream(new FileInputStream(file)); ObjectInputStream os = new ObjectInputStream(new FileInputStream(file));
int length = os.readInt(); int length = os.readInt();
@ -105,6 +111,10 @@ public class SignData {
} }
os.close(); os.close();
} catch (IOException exception) {
exception.printStackTrace();
}
} }
/** /**
@ -114,7 +124,7 @@ public class SignData {
* the DEditWorld that contains the signs to serialize * the DEditWorld that contains the signs to serialize
* @throws IOException * @throws IOException
*/ */
public void serializeSigns(DEditWorld editWorld) throws IOException { public void serializeSigns(DEditWorld editWorld) {
serializeSigns(editWorld.getSigns()); serializeSigns(editWorld.getSigns());
} }
@ -125,7 +135,8 @@ public class SignData {
* the signs to serialize * the signs to serialize
* @throws IOException * @throws IOException
*/ */
public void serializeSigns(List<Block> signs) throws IOException { public void serializeSigns(List<Block> signs) {
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
out.writeInt(signs.size()); out.writeInt(signs.size());
@ -136,6 +147,10 @@ public class SignData {
} }
out.close(); out.close();
} catch (IOException exception) {
exception.printStackTrace();
}
} }
} }

View File

@ -202,7 +202,7 @@ public class DPortal extends GlobalProtection {
dGroup.setGameWorld(target); dGroup.setGameWorld(target);
} }
new DGamePlayer(player, target); DGamePlayer.create(player, target);
} }
@Override @Override

View File

@ -554,7 +554,7 @@ public class PlayerListener implements Listener {
continue; continue;
} }
new DGamePlayer(player, dGroup.getGameWorld()); DGamePlayer.create(player, dGroup.getGameWorld());
plugin.debug.end("PlayerListener#onJoin", true); plugin.debug.end("PlayerListener#onJoin", true);
return; return;
} }

View File

@ -20,6 +20,7 @@ import io.github.dre2n.commons.util.messageutil.MessageUtil;
import io.github.dre2n.commons.util.playerutil.PlayerUtil; import io.github.dre2n.commons.util.playerutil.PlayerUtil;
import io.github.dre2n.dungeonsxl.config.DMessages; import io.github.dre2n.dungeonsxl.config.DMessages;
import io.github.dre2n.dungeonsxl.event.dplayer.DPlayerUpdateEvent; import io.github.dre2n.dungeonsxl.event.dplayer.DPlayerUpdateEvent;
import io.github.dre2n.dungeonsxl.task.CreateDInstancePlayerTask;
import io.github.dre2n.dungeonsxl.world.DEditWorld; import io.github.dre2n.dungeonsxl.world.DEditWorld;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -40,19 +41,15 @@ public class DEditPlayer extends DInstancePlayer {
private String[] linesCopy; private String[] linesCopy;
public DEditPlayer(DGlobalPlayer player, DEditWorld world) { public DEditPlayer(Player player, DEditWorld world) {
this(player.getPlayer(), world.getWorld()); super(player, world.getWorld());
}
public DEditPlayer(Player player, World world) {
super(player, world);
player.setGameMode(GameMode.CREATIVE); player.setGameMode(GameMode.CREATIVE);
clearPlayerData(); clearPlayerData();
Location teleport = DEditWorld.getByWorld(world).getLobbyLocation(); Location teleport = world.getLobbyLocation();
if (teleport == null) { if (teleport == null) {
PlayerUtil.secureTeleport(player, world.getSpawnLocation()); PlayerUtil.secureTeleport(player, world.getWorld().getSpawnLocation());
} else { } else {
PlayerUtil.secureTeleport(player, teleport); PlayerUtil.secureTeleport(player, teleport);
} }
@ -65,6 +62,16 @@ public class DEditPlayer extends DInstancePlayer {
} }
} }
/**
* @param player
* the represented Player
* @param editWorld
* the player's EditWorld
*/
public static void create(Player player, DEditWorld editWorld) {
new CreateDInstancePlayerTask(player, editWorld).runTaskTimer(plugin, 0L, 5L);
}
/* Getters and setters */ /* Getters and setters */
/** /**
* @return the linesCopy * @return the linesCopy

View File

@ -33,9 +33,11 @@ import io.github.dre2n.dungeonsxl.game.GameRules;
import io.github.dre2n.dungeonsxl.game.GameType; import io.github.dre2n.dungeonsxl.game.GameType;
import io.github.dre2n.dungeonsxl.game.GameTypeDefault; import io.github.dre2n.dungeonsxl.game.GameTypeDefault;
import io.github.dre2n.dungeonsxl.mob.DMob; import io.github.dre2n.dungeonsxl.mob.DMob;
import static io.github.dre2n.dungeonsxl.player.DGlobalPlayer.plugin;
import io.github.dre2n.dungeonsxl.requirement.Requirement; import io.github.dre2n.dungeonsxl.requirement.Requirement;
import io.github.dre2n.dungeonsxl.reward.DLootInventory; import io.github.dre2n.dungeonsxl.reward.DLootInventory;
import io.github.dre2n.dungeonsxl.reward.Reward; import io.github.dre2n.dungeonsxl.reward.Reward;
import io.github.dre2n.dungeonsxl.task.CreateDInstancePlayerTask;
import io.github.dre2n.dungeonsxl.trigger.DistanceTrigger; import io.github.dre2n.dungeonsxl.trigger.DistanceTrigger;
import io.github.dre2n.dungeonsxl.world.DGameWorld; import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.DResourceWorld; import io.github.dre2n.dungeonsxl.world.DResourceWorld;
@ -54,6 +56,7 @@ import org.bukkit.entity.Wolf;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.scheduler.BukkitRunnable;
/** /**
* Represents a player in a DGameWorld. * Represents a player in a DGameWorld.
@ -77,15 +80,11 @@ public class DGamePlayer extends DInstancePlayer {
private int initialLives = -1; private int initialLives = -1;
private int lives; private int lives;
public DGamePlayer(Player player, DGameWorld gameWorld) { public DGamePlayer(Player player, DGameWorld world) {
this(player, gameWorld.getWorld()); super(player, world.getWorld());
}
public DGamePlayer(Player player, World world) {
super(player, world);
plugin.debug.start("DGamePlayer#init"); plugin.debug.start("DGamePlayer#init");
Game game = Game.getByWorld(world); Game game = Game.getByGameWorld(world);
if (game == null) { if (game == null) {
game = new Game(DGroup.getByPlayer(player)); game = new Game(DGroup.getByPlayer(player));
} }
@ -104,15 +103,37 @@ public class DGamePlayer extends DInstancePlayer {
initialLives = rules.getInitialLives(); initialLives = rules.getInitialLives();
lives = initialLives; lives = initialLives;
Location teleport = DGameWorld.getByWorld(world).getLobbyLocation(); Location teleport = world.getLobbyLocation();
if (teleport == null) { if (teleport == null) {
PlayerUtil.secureTeleport(player, world.getSpawnLocation()); PlayerUtil.secureTeleport(player, world.getWorld().getSpawnLocation());
} else { } else {
PlayerUtil.secureTeleport(player, teleport); PlayerUtil.secureTeleport(player, teleport);
} }
plugin.debug.end("DGamePlayer#init", true); plugin.debug.end("DGamePlayer#init", true);
} }
/**
* @param player
* the represented Player
* @param gameWorld
* the player's GameWorld
*/
public static void create(Player player, DGameWorld gameWorld) {
create(player, gameWorld, false);
}
/**
* @param player
* the represented Player
* @param gameWorld
* the player's GameWorld
* @param ready
* if the player will be ready from the beginning
*/
public static void create(Player player, DGameWorld gameWorld, boolean ready) {
new CreateDInstancePlayerTask(player, gameWorld, ready).runTaskTimer(plugin, 0L, 5L);
}
/* Getters and setters */ /* Getters and setters */
/** /**
* @param player * @param player

View File

@ -31,7 +31,7 @@ public abstract class DInstancePlayer extends DGlobalPlayer {
private World world; private World world;
private boolean inDungeonChat = false; private boolean inDungeonChat = false;
public DInstancePlayer(Player player, World world) { DInstancePlayer(Player player, World world) {
super(player); super(player);
double health = player.getHealth(); double health = player.getHealth();

View File

@ -87,7 +87,7 @@ public class AnnouncerStartGameTask extends BukkitRunnable {
} }
for (Player player : game.getPlayers()) { for (Player player : game.getPlayers()) {
new DGamePlayer(player, game.getWorld()); DGamePlayer.create(player, game.getWorld());
} }
announcer.endStartTask(); announcer.endStartTask();

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2012-2016 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 <http://www.gnu.org/licenses/>.
*/
package io.github.dre2n.dungeonsxl.task;
import io.github.dre2n.commons.util.messageutil.MessageUtil;
import io.github.dre2n.dungeonsxl.player.DEditPlayer;
import io.github.dre2n.dungeonsxl.player.DGamePlayer;
import io.github.dre2n.dungeonsxl.world.DEditWorld;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.DInstanceWorld;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
/**
* @author Daniel Saukel
*/
public class CreateDInstancePlayerTask extends BukkitRunnable {
public static final String BAR = "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588";
private UUID player;
private DInstanceWorld instance;
private boolean ready;
private int i = 12;
public CreateDInstancePlayerTask(Player player, DInstanceWorld instance) {
this.player = player.getUniqueId();
this.instance = instance;
}
public CreateDInstancePlayerTask(Player player, DInstanceWorld instance, boolean ready) {
this.player = player.getUniqueId();
this.instance = instance;
this.ready = ready;
}
@Override
public void run() {
Player player = Bukkit.getPlayer(this.player);
if (player == null || !player.isOnline()) {
cancel();
return;
}
if (instance.exists()) {
if (instance instanceof DGameWorld) {
DGamePlayer gamePlayer = new DGamePlayer(player, (DGameWorld) instance);
if (ready) {
gamePlayer.ready();
}
} else if (instance instanceof DEditWorld) {
new DEditPlayer(player, (DEditWorld) instance);
}
cancel();
return;
}
StringBuilder bar = new StringBuilder(BAR);
int pos = i;
if (bar.length() - pos < 0) {
pos = bar.length();
}
bar.insert(bar.length() - pos, ChatColor.GREEN.toString());
pos = i - 2;
if (pos > 0) {
bar.insert(bar.length() - pos, ChatColor.DARK_RED.toString());
}
MessageUtil.sendActionBarMessage(player, ChatColor.DARK_RED + bar.toString());
i--;
if (i == 0) {
i = 12;
}
}
}

View File

@ -32,18 +32,22 @@ public class WorldUnloadTask extends BukkitRunnable {
@Override @Override
public void run() { public void run() {
for (DGameWorld gameWorld : plugin.getDWorlds().getGameWorlds()) { for (DGameWorld gameWorld : plugin.getDWorlds().getGameWorlds()) {
if (gameWorld.exists()) {
if (gameWorld.getWorld().getPlayers().isEmpty()) { if (gameWorld.getWorld().getPlayers().isEmpty()) {
if (DGamePlayer.getByWorld(gameWorld.getWorld()).isEmpty()) { if (DGamePlayer.getByWorld(gameWorld.getWorld()).isEmpty()) {
gameWorld.delete(); gameWorld.delete();
} }
} }
} }
}
for (DEditWorld editWorld : plugin.getDWorlds().getEditWorlds()) { for (DEditWorld editWorld : plugin.getDWorlds().getEditWorlds()) {
if (editWorld.exists()) {
if (editWorld.getWorld().getPlayers().isEmpty()) { if (editWorld.getWorld().getPlayers().isEmpty()) {
editWorld.delete(true); editWorld.delete(true);
} }
} }
} }
}
} }

View File

@ -0,0 +1,206 @@
/*
* Copyright (C) 2012-2016 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 <http://www.gnu.org/licenses/>.
*/
package io.github.dre2n.dungeonsxl.util;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.logging.Logger;
import net.minecraft.server.v1_10_R1.BlockPosition;
import net.minecraft.server.v1_10_R1.Convertable;
import net.minecraft.server.v1_10_R1.EntityTracker;
import net.minecraft.server.v1_10_R1.EnumDifficulty;
import net.minecraft.server.v1_10_R1.EnumGamemode;
import net.minecraft.server.v1_10_R1.IDataManager;
import net.minecraft.server.v1_10_R1.IProgressUpdate;
import net.minecraft.server.v1_10_R1.MinecraftServer;
import net.minecraft.server.v1_10_R1.ServerNBTManager;
import net.minecraft.server.v1_10_R1.WorldData;
import net.minecraft.server.v1_10_R1.WorldLoaderServer;
import net.minecraft.server.v1_10_R1.WorldManager;
import net.minecraft.server.v1_10_R1.WorldServer;
import net.minecraft.server.v1_10_R1.WorldSettings;
import net.minecraft.server.v1_10_R1.WorldType;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.PluginManager;
/**
* A custom thread safe world loader.
*
* @author Daniel Saukel
*/
public class WorldLoader {
static MinecraftServer console;
static CraftServer server = ((CraftServer) Bukkit.getServer());
static Map<String, World> worlds;
static PluginManager pluginManager = Bukkit.getPluginManager();
static File worldContainer = Bukkit.getWorldContainer();
static Logger logger = Bukkit.getLogger();
static {
try {
Field fConsole = CraftServer.class.getDeclaredField("console");
fConsole.setAccessible(true);
console = (MinecraftServer) fConsole.get(server);
Field fWorlds = CraftServer.class.getDeclaredField("worlds");
fWorlds.setAccessible(true);
worlds = (Map<String, World>) fWorlds.get(server);
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) {
exception.printStackTrace();
}
}
/**
* @param creator
* the WorldCreator which stores the information to create the new world
* @return
* the new World
*/
@SuppressWarnings("deprecation")
public static World createWorld(WorldCreator creator) {
String name = creator.name();
ChunkGenerator generator = creator.generator();
File folder = new File(worldContainer, name);
World world = Bukkit.getWorld(name);
WorldType type = WorldType.getType(creator.type().getName());
boolean generateStructures = creator.generateStructures();
if (world != null) {
return world;
}
if ((folder.exists()) && (!folder.isDirectory())) {
throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder");
}
if (generator == null) {
generator = server.getGenerator(name);
}
Convertable converter = new WorldLoaderServer(worldContainer, server.getHandle().getServer().getDataConverterManager());
if (converter.isConvertable(name)) {
logger.info("Converting world '" + name + "'");
converter.convert(name, new IProgressUpdate() {
private long b = System.currentTimeMillis();
@Override
public void a(String s) {
}
@Override
public void a(int i) {
if (System.currentTimeMillis() - this.b >= 1000L) {
this.b = System.currentTimeMillis();
MinecraftServer.LOGGER.info("Converting... " + i + "%");
}
}
@Override
public void c(String s) {
}
});
}
int dimension = CraftWorld.CUSTOM_DIMENSION_OFFSET + console.worlds.size();
boolean used = false;
do {
for (WorldServer server : console.worlds) {
used = server.dimension == dimension;
if (used) {
dimension++;
break;
}
}
} while (used);
boolean hardcore = false;
IDataManager sdm = new ServerNBTManager(worldContainer, name, true, server.getHandle().getServer().getDataConverterManager());
WorldData worlddata = sdm.getWorldData();
WorldSettings worldSettings = null;
if (worlddata == null) {
worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(server.getDefaultGameMode().getValue()), generateStructures, hardcore, type);
worldSettings.setGeneratorSettings(creator.generatorSettings());
worlddata = new WorldData(worldSettings, name);
}
worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
WorldServer internal = (WorldServer) new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b();
if (!(worlds.containsKey(name.toLowerCase(java.util.Locale.ENGLISH)))) {
return null;
}
if (worldSettings != null) {
internal.a(worldSettings);
}
internal.scoreboard = server.getScoreboardManager().getMainScoreboard().getHandle();
internal.tracker = new EntityTracker(internal);
internal.addIWorldAccess(new WorldManager(console, internal));
internal.worldData.setDifficulty(EnumDifficulty.EASY);
internal.setSpawnFlags(true, true);
console.worlds.add(internal);
if (generator != null) {
internal.getWorld().getPopulators().addAll(generator.getDefaultPopulators(internal.getWorld()));
}
pluginManager.callEvent(new WorldInitEvent(internal.getWorld()));
logger.info("Preparing start region for level " + (console.worlds.size() - 1) + " (Seed: " + internal.getSeed() + ")");
if (internal.getWorld().getKeepSpawnInMemory()) {
short short1 = 196;
long i = System.currentTimeMillis();
for (int j = -short1; j <= short1; j += 16) {
for (int k = -short1; k <= short1; k += 16) {
long l = System.currentTimeMillis();
if (l < i) {
i = l;
}
if (l > i + 1000L) {
int i1 = (short1 * 2 + 1) * (short1 * 2 + 1);
int j1 = (j + short1) * (short1 * 2 + 1) + k + 1;
logger.info("Preparing spawn area for " + name + ", " + (j1 * 100 / i1) + "%");
i = l;
}
BlockPosition chunkcoordinates = internal.getSpawn();
try {
internal.getChunkProviderServer().getChunkAt(chunkcoordinates.getX() + j >> 4, chunkcoordinates.getZ() + k >> 4);
} catch (Exception exception) {
}
}
}
}
pluginManager.callEvent(new WorldLoadEvent(internal.getWorld()));
return internal.getWorld();
}
}

View File

@ -28,6 +28,7 @@ import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
/** /**
* @author Frank Baumann, Daniel Saukel * @author Frank Baumann, Daniel Saukel
@ -43,7 +44,10 @@ public class DEditWorld extends DInstanceWorld {
DEditWorld(DResourceWorld resourceWorld, File folder, World world, int id) { DEditWorld(DResourceWorld resourceWorld, File folder, World world, int id) {
super(resourceWorld, folder, world, id); super(resourceWorld, folder, world, id);
generateIdFile(); }
DEditWorld(DResourceWorld resourceWorld, File folder, int id) {
this(resourceWorld, folder, null, id);
} }
/* Getters and setters */ /* Getters and setters */
@ -113,14 +117,21 @@ public class DEditWorld extends DInstanceWorld {
getWorld().save(); getWorld().save();
if (!plugin.getMainConfig().areTweaksEnabled()) {
FileUtil.copyDirectory(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES); FileUtil.copyDirectory(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES);
FileUtil.deleteUnusedFiles(getResource().getFolder()); FileUtil.deleteUnusedFiles(getResource().getFolder());
try { } else {
getResource().getSignData().serializeSigns(signs); new BukkitRunnable() {
} catch (IOException exception) { @Override
exception.printStackTrace(); public void run() {
FileUtil.copyDirectory(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES);
FileUtil.deleteUnusedFiles(getResource().getFolder());
} }
}.runTaskAsynchronously(plugin);
}
getResource().getSignData().serializeSigns(signs);
} }
@Override @Override
@ -134,7 +145,8 @@ public class DEditWorld extends DInstanceWorld {
* @param save * @param save
* whether this world should be saved * whether this world should be saved
*/ */
public void delete(boolean save) { public void delete(final boolean save) {
plugin.debug.start("DEditWorld#delete");
EditWorldUnloadEvent event = new EditWorldUnloadEvent(this, true); EditWorldUnloadEvent event = new EditWorldUnloadEvent(this, true);
plugin.getServer().getPluginManager().callEvent(event); plugin.getServer().getPluginManager().callEvent(event);
@ -142,26 +154,42 @@ public class DEditWorld extends DInstanceWorld {
return; return;
} }
worlds.getInstances().remove(this);
for (Player player : getWorld().getPlayers()) { for (Player player : getWorld().getPlayers()) {
DEditPlayer dPlayer = DEditPlayer.getByPlayer(player); DEditPlayer dPlayer = DEditPlayer.getByPlayer(player);
dPlayer.leave(); dPlayer.leave();
} }
if (!plugin.getMainConfig().areTweaksEnabled()) {
if (save) { if (save) {
plugin.getServer().unloadWorld(getWorld(), true); plugin.getServer().unloadWorld(getWorld(), true);
} }
FileUtil.copyDirectory(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES); FileUtil.copyDirectory(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES);
FileUtil.deleteUnusedFiles(getResource().getFolder()); FileUtil.deleteUnusedFiles(getResource().getFolder());
if (!save) { if (!save) {
plugin.getServer().unloadWorld(getWorld(), true); plugin.getServer().unloadWorld(getWorld(), true);
} }
FileUtil.removeDirectory(getFolder()); FileUtil.removeDirectory(getFolder());
worlds.removeInstance(this); worlds.removeInstance(this);
} else {
final DEditWorld editWorld = this;
new BukkitRunnable() {
@Override
public void run() {
if (save) {
plugin.getServer().unloadWorld(getWorld(), true);
}
FileUtil.copyDirectory(getFolder(), getResource().getFolder(), DungeonsXL.EXCLUDED_FILES);
FileUtil.deleteUnusedFiles(getResource().getFolder());
if (!save) {
plugin.getServer().unloadWorld(getWorld(), true);
}
FileUtil.removeDirectory(getFolder());
worlds.removeInstance(editWorld);
}
}.runTaskAsynchronously(plugin);
}
plugin.debug.end("DEditWorld#delete", true);
} }
/* Statics */ /* Statics */

View File

@ -49,6 +49,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Spider; import org.bukkit.entity.Spider;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
/** /**
* @author Frank Baumann, Milan Albrecht, Daniel Saukel * @author Frank Baumann, Milan Albrecht, Daniel Saukel
@ -73,6 +74,10 @@ public class DGameWorld extends DInstanceWorld {
super(resourceWorld, folder, world, id); super(resourceWorld, folder, world, id);
} }
DGameWorld(DResourceWorld resourceWorld, File folder, int id) {
this(resourceWorld, folder, null, id);
}
/** /**
* @return * @return
* the Game connected to the DGameWorld * the Game connected to the DGameWorld
@ -354,7 +359,6 @@ public class DGameWorld extends DInstanceWorld {
* Set up the instance for the game * Set up the instance for the game
*/ */
public void startGame() { public void startGame() {
plugin.debug.start("DGameWorld#startGame");
GameWorldStartGameEvent event = new GameWorldStartGameEvent(this, getGame()); GameWorldStartGameEvent event = new GameWorldStartGameEvent(this, getGame());
plugin.getServer().getPluginManager().callEvent(event); plugin.getServer().getPluginManager().callEvent(event);
@ -387,7 +391,6 @@ public class DGameWorld extends DInstanceWorld {
} }
} }
} }
plugin.debug.end("DGameWorld#startGame", true);
} }
/** /**
@ -403,11 +406,22 @@ public class DGameWorld extends DInstanceWorld {
return; return;
} }
plugin.getDWorlds().getInstances().remove(this); if (!plugin.getMainConfig().areTweaksEnabled()) {
plugin.getServer().unloadWorld(getWorld(), true); plugin.getServer().unloadWorld(getWorld(), false);
FileUtil.removeDirectory(getFolder()); FileUtil.removeDirectory(getFolder());
worlds.removeInstance(this); worlds.removeInstance(this);
} else {
final DGameWorld gameWorld = this;
new BukkitRunnable() {
@Override
public void run() {
plugin.getServer().unloadWorld(getWorld(), false);
FileUtil.removeDirectory(getFolder());
worlds.removeInstance(gameWorld);
}
}.runTaskAsynchronously(plugin);
}
plugin.debug.end("DGameWorld#delete", true); plugin.debug.end("DGameWorld#delete", true);
} }

View File

@ -34,7 +34,7 @@ public abstract class DInstanceWorld {
private DResourceWorld resourceWorld; private DResourceWorld resourceWorld;
private File folder; private File folder;
private World world; World world;
private int id; private int id;
private Location lobby; private Location lobby;
@ -83,6 +83,13 @@ public abstract class DInstanceWorld {
return world; return world;
} }
/**
* @return false if this instance does not have a world, yet
*/
public boolean exists() {
return world != null;
}
/** /**
* @return the unique ID * @return the unique ID
*/ */

View File

@ -20,13 +20,14 @@ import io.github.dre2n.commons.util.FileUtil;
import io.github.dre2n.dungeonsxl.DungeonsXL; import io.github.dre2n.dungeonsxl.DungeonsXL;
import io.github.dre2n.dungeonsxl.config.SignData; import io.github.dre2n.dungeonsxl.config.SignData;
import io.github.dre2n.dungeonsxl.config.WorldConfig; import io.github.dre2n.dungeonsxl.config.WorldConfig;
import io.github.dre2n.dungeonsxl.event.editworld.EditWorldGenerateEvent;
import io.github.dre2n.dungeonsxl.player.DEditPlayer; import io.github.dre2n.dungeonsxl.player.DEditPlayer;
import io.github.dre2n.dungeonsxl.task.BackupResourceTask; import io.github.dre2n.dungeonsxl.task.BackupResourceTask;
import io.github.dre2n.dungeonsxl.util.WorldLoader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import org.bukkit.WorldType; import org.bukkit.WorldType;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@ -187,32 +188,47 @@ public class DResourceWorld {
* whether the instance is a DGameWorld * whether the instance is a DGameWorld
* @return an instance of this world * @return an instance of this world
*/ */
public DInstanceWorld instantiate(boolean game) { public DInstanceWorld instantiate(final boolean game) {
plugin.debug.start("DResourceWorld#instantiate"); plugin.debug.start("DResourceWorld#instantiate");
int id = worlds.generateId(); int id = worlds.generateId();
String name = worlds.generateName(game); String name = worlds.generateName(game);
File instanceFolder = new File(Bukkit.getWorldContainer(), name); final File instanceFolder = new File(Bukkit.getWorldContainer(), name);
FileUtil.copyDirectory(folder, instanceFolder, DungeonsXL.EXCLUDED_FILES);
if (Bukkit.getWorld(name) != null) { if (Bukkit.getWorld(name) != null) {
return null; return null;
} }
World world = plugin.getServer().createWorld(WorldCreator.name(name)); final DInstanceWorld instance = game ? new DGameWorld(this, instanceFolder, id) : new DEditWorld(this, instanceFolder, id);
if (!plugin.getMainConfig().areTweaksEnabled()) {
FileUtil.copyDirectory(folder, instanceFolder, DungeonsXL.EXCLUDED_FILES);
instance.world = plugin.getServer().createWorld(WorldCreator.name(name));
DInstanceWorld instance = null;
try {
if (game) { if (game) {
instance = new DGameWorld(this, instanceFolder, world, id);
signData.deserializeSigns((DGameWorld) instance); signData.deserializeSigns((DGameWorld) instance);
} else { } else {
instance = new DEditWorld(this, instanceFolder, world, id);
signData.deserializeSigns((DEditWorld) instance); signData.deserializeSigns((DEditWorld) instance);
} }
} catch (IOException exception) { } else {
exception.printStackTrace(); new BukkitRunnable() {
@Override
public void run() {
FileUtil.copyDirectory(folder, instanceFolder, DungeonsXL.EXCLUDED_FILES);
instance.world = WorldLoader.createWorld(WorldCreator.name(instanceFolder.getName()));
new BukkitRunnable() {
@Override
public void run() {
if (game) {
signData.deserializeSigns((DGameWorld) instance);
} else {
signData.deserializeSigns((DEditWorld) instance);
}
}
}.runTask(plugin);
}
}.runTaskAsynchronously(plugin);
} }
plugin.debug.end("DResourceWorld#instantiate", true); plugin.debug.end("DResourceWorld#instantiate", true);
@ -240,23 +256,34 @@ public class DResourceWorld {
*/ */
public DEditWorld generate() { public DEditWorld generate() {
plugin.debug.start("DResourceWorld#generate"); plugin.debug.start("DResourceWorld#generate");
String name = worlds.generateName(false); final String name = worlds.generateName(false);
WorldCreator creator = WorldCreator.name(name); int id = worlds.generateId();
final File folder = new File(Bukkit.getWorldContainer(), name);
final WorldCreator creator = new WorldCreator(name);
creator.type(WorldType.FLAT); creator.type(WorldType.FLAT);
creator.generateStructures(false); creator.generateStructures(false);
/*EditWorldGenerateEvent event = new EditWorldGenerateEvent(this); final DEditWorld editWorld = new DEditWorld(this, folder, id);
EditWorldGenerateEvent event = new EditWorldGenerateEvent(editWorld);
plugin.getServer().getPluginManager().callEvent(event); plugin.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return null;
} }
*/
int id = worlds.generateId();
File folder = new File(Bukkit.getWorldContainer(), name);
World world = plugin.getServer().createWorld(creator);
DEditWorld editWorld = new DEditWorld(this, folder, world, id); if (!plugin.getMainConfig().areTweaksEnabled()) {
editWorld.world = creator.createWorld();
} else {
new BukkitRunnable() {
@Override
public void run() {
FileUtil.copyDirectory(DWorlds.RAW, folder, DungeonsXL.EXCLUDED_FILES);
editWorld.generateIdFile();
editWorld.world = WorldLoader.createWorld(creator);
}
}.runTaskAsynchronously(plugin);
}
plugin.debug.end("DResourceWorld#generate", true); plugin.debug.end("DResourceWorld#generate", true);
return editWorld; return editWorld;

View File

@ -19,11 +19,15 @@ package io.github.dre2n.dungeonsxl.world;
import io.github.dre2n.commons.util.FileUtil; import io.github.dre2n.commons.util.FileUtil;
import io.github.dre2n.commons.util.NumberUtil; import io.github.dre2n.commons.util.NumberUtil;
import io.github.dre2n.dungeonsxl.DungeonsXL; import io.github.dre2n.dungeonsxl.DungeonsXL;
import io.github.dre2n.dungeonsxl.config.MainConfig;
import io.github.dre2n.dungeonsxl.config.MainConfig.BackupMode; import io.github.dre2n.dungeonsxl.config.MainConfig.BackupMode;
import java.io.File; import java.io.File;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.WorldType;
/** /**
* @author Daniel Saukel * @author Daniel Saukel
@ -31,16 +35,21 @@ import org.bukkit.Bukkit;
public class DWorlds { public class DWorlds {
DungeonsXL plugin = DungeonsXL.getInstance(); DungeonsXL plugin = DungeonsXL.getInstance();
MainConfig mainConfig = plugin.getMainConfig();
public static final File RAW = new File(DungeonsXL.MAPS, ".raw");
private Set<DResourceWorld> resources = new HashSet<>(); private Set<DResourceWorld> resources = new HashSet<>();
private Set<DInstanceWorld> instances = new HashSet<>(); private Set<DInstanceWorld> instances = new HashSet<>();
public DWorlds(File folder) { public DWorlds(File folder) {
for (File file : folder.listFiles()) { for (File file : folder.listFiles()) {
if (file.isDirectory()) { if (file.isDirectory() && !file.getName().equals(".raw")) {
resources.add(new DResourceWorld(this, file)); resources.add(new DResourceWorld(this, file));
} }
} }
createRaw();
} }
/* Getters and setters */ /* Getters and setters */
@ -203,11 +212,11 @@ public class DWorlds {
* Clean up all instances. * Clean up all instances.
*/ */
public void deleteAllInstances() { public void deleteAllInstances() {
BackupMode backupMode = plugin.getMainConfig().getBackupMode(); BackupMode backupMode = mainConfig.getBackupMode();
HashSet<DInstanceWorld> instances = new HashSet<>(this.instances); HashSet<DInstanceWorld> instances = new HashSet<>(this.instances);
for (DInstanceWorld instance : instances) { for (DInstanceWorld instance : instances) {
if (backupMode == BackupMode.ON_DISABLE | backupMode == BackupMode.ON_DISABLE_AND_SAVE && instance instanceof DEditWorld) { if (backupMode == BackupMode.ON_DISABLE | backupMode == BackupMode.ON_DISABLE_AND_SAVE && instance instanceof DEditWorld) {
instance.getResource().backup(false); instance.getResource().backup(mainConfig.areTweaksEnabled());
} }
instance.delete(); instance.delete();
@ -246,4 +255,18 @@ public class DWorlds {
return "DXL_" + (game ? "Game" : "Edit") + "_" + generateId(); return "DXL_" + (game ? "Game" : "Edit") + "_" + generateId();
} }
/**
* Creates a raw, new flat world sothat it can be copied if needed instead of getting generated from scratch.
*/
public void createRaw() {
WorldCreator creator = WorldCreator.name(".raw");
creator.type(WorldType.FLAT);
creator.generateStructures(false);
World world = creator.createWorld();
File worldFolder = new File(Bukkit.getWorldContainer(), ".raw");
FileUtil.copyDirectory(worldFolder, RAW, DungeonsXL.EXCLUDED_FILES);
Bukkit.unloadWorld(world, false);
FileUtil.removeDirectory(worldFolder);
}
} }