diff --git a/src/main/java/io/github/dre2n/dungeonsxl/DungeonsXL.java b/src/main/java/io/github/dre2n/dungeonsxl/DungeonsXL.java index b4a71a66..81614108 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/DungeonsXL.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/DungeonsXL.java @@ -55,6 +55,7 @@ import io.github.dre2n.dungeonsxl.task.WorldUnloadTask; import io.github.dre2n.dungeonsxl.trigger.TriggerTypes; import io.github.dre2n.dungeonsxl.world.EditWorld; import io.github.dre2n.dungeonsxl.world.GameWorld; +import io.github.dre2n.dungeonsxl.world.Worlds; import io.github.dre2n.itemsxl.ItemsXL; import java.io.File; import java.util.List; @@ -100,6 +101,7 @@ public class DungeonsXL extends BRPlugin { private DClasses dClasses; private DMobTypes dMobTypes; private SignScripts signScripts; + private Worlds worlds; private BukkitTask announcerTask; private BukkitTask worldUnloadTask; @@ -108,8 +110,6 @@ public class DungeonsXL extends BRPlugin { private BukkitTask secureModeTask; private CopyOnWriteArrayList dLootInventories = new CopyOnWriteArrayList<>(); - private CopyOnWriteArrayList editWorlds = new CopyOnWriteArrayList<>(); - private CopyOnWriteArrayList gameWorlds = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList games = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList dGroups = new CopyOnWriteArrayList<>(); @@ -602,10 +602,24 @@ public class DungeonsXL extends BRPlugin { } /** - * @return the worldUnloadTask + * @return the loaded instance of Worlds */ - public BukkitTask getWorldUnloadTask() { - return worldUnloadTask; + public Worlds getWorlds() { + return worlds; + } + + /** + * load / reload a new instance of Worlds + */ + public void loadWorlds(File folder) { + worlds = new Worlds(MAPS); + } + + /** + * @return the AnnouncerTask + */ + public BukkitTask getAnnouncerTask() { + return announcerTask; } /** @@ -618,10 +632,10 @@ public class DungeonsXL extends BRPlugin { } /** - * @return the AnnouncerTask + * @return the worldUnloadTask */ - public BukkitTask getAnnouncerTask() { - return announcerTask; + public BukkitTask getWorldUnloadTask() { + return worldUnloadTask; } /** @@ -680,20 +694,6 @@ public class DungeonsXL extends BRPlugin { return dLootInventories; } - /** - * @return the editWorlds - */ - public List getEditWorlds() { - return editWorlds; - } - - /** - * @return the gameWorlds - */ - public List getGameWorlds() { - return gameWorlds; - } - /** * @return the games */ diff --git a/src/main/java/io/github/dre2n/dungeonsxl/config/SignData.java b/src/main/java/io/github/dre2n/dungeonsxl/config/SignData.java new file mode 100644 index 00000000..c674054c --- /dev/null +++ b/src/main/java/io/github/dre2n/dungeonsxl/config/SignData.java @@ -0,0 +1,141 @@ +/* + * 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 . + */ +package io.github.dre2n.dungeonsxl.config; + +import io.github.dre2n.dungeonsxl.sign.DSign; +import io.github.dre2n.dungeonsxl.world.EditWorld; +import io.github.dre2n.dungeonsxl.world.GameWorld; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.List; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; + +/** + * @author Daniel Saukel + */ +public class SignData { + + private File file; + + public SignData(File file) { + this.file = file; + } + + /* Getters and setters */ + /** + * @return the file + */ + public File getFile() { + return file; + } + + /* Actions */ + /** + * Applies all signs from the file to the EditWorld. + * Also sets the lobby location of the EditWorld to the location of the lobby sign if one exists. + * + * @param editWorld + * the EditWorld where the signs are + * @throws IOException + */ + public void deserializeSigns(EditWorld editWorld) throws IOException { + ObjectInputStream os = new ObjectInputStream(new FileInputStream(file)); + int length = os.readInt(); + + for (int i = 0; i < length; i++) { + int x = os.readInt(); + int y = os.readInt(); + int z = os.readInt(); + + Block block = editWorld.getWorld().getBlockAt(x, y, z); + editWorld.getSigns().add(block); + + if (block.getState() instanceof Sign) { + Sign sign = (Sign) block.getState(); + String[] lines = sign.getLines(); + + if (lines[0].equalsIgnoreCase("[lobby]")) { + editWorld.setLobbyLocation(block.getLocation()); + } + } + } + } + + /** + * Applies all signs from the file to the GameWorld. + * + * @param gameWorld + * the GameWorld where the signs are + * @return a Set of all DSign blocks + * @throws IOException + */ + public void deserializeSigns(GameWorld gameWorld) throws IOException { + ObjectInputStream os = new ObjectInputStream(new FileInputStream(file)); + + int length = os.readInt(); + for (int i = 0; i < length; i++) { + int x = os.readInt(); + int y = os.readInt(); + int z = os.readInt(); + + Block block = gameWorld.getWorld().getBlockAt(x, y, z); + if (block.getState() instanceof Sign) { + DSign dSign = DSign.create((Sign) block.getState(), gameWorld); + gameWorld.getDSigns().add(dSign); + } + } + + os.close(); + } + + /** + * Applies all signs from the EditWorld to the file. + * + * @param editWorld + * the EditWorld that contains the signs to serialize + * @throws IOException + */ + public void serializeSigns(EditWorld editWorld) throws IOException { + serializeSigns(editWorld.getSigns()); + } + + /** + * Applies all signs from the sign list to the file. + * + * @param signs + * the signs to serialize + * @throws IOException + */ + public void serializeSigns(List signs) throws IOException { + ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); + out.writeInt(signs.size()); + + for (Block sign : signs) { + out.writeInt(sign.getX()); + out.writeInt(sign.getY()); + out.writeInt(sign.getZ()); + } + + out.close(); + } + +} diff --git a/src/main/java/io/github/dre2n/dungeonsxl/world/InstanceWorld.java b/src/main/java/io/github/dre2n/dungeonsxl/world/InstanceWorld.java new file mode 100644 index 00000000..c1d7f5ae --- /dev/null +++ b/src/main/java/io/github/dre2n/dungeonsxl/world/InstanceWorld.java @@ -0,0 +1,95 @@ +/* + * 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 . + */ +package io.github.dre2n.dungeonsxl.world; + +import io.github.dre2n.dungeonsxl.DungeonsXL; +import io.github.dre2n.dungeonsxl.config.WorldConfig; +import org.bukkit.Location; +import org.bukkit.World; + +/** + * @author Daniel Saukel + */ +public class InstanceWorld { + + DungeonsXL plugin = DungeonsXL.getInstance(); + + public static String ID_FILE_PREFIX = ".id_"; + + private ResourceWorld resourceWorld; + private World world; + private int id; + private Location lobby; + + InstanceWorld(ResourceWorld resourceWorld, World world, int id) { + this.resourceWorld = resourceWorld; + this.world = world; + this.id = id; + } + + /* Getters and setters */ + /** + * @return the name of the ResourceWorld + */ + public String getName() { + return resourceWorld.getName(); + } + + /** + * @return the WorldConfig + */ + public WorldConfig getConfig() { + return resourceWorld.getConfig(); + } + + /** + * @return the instance + */ + public World getWorld() { + return world; + } + + /** + * @return the unique ID + */ + public int getId() { + return id; + } + + /** + * @return the location where the player spawns + */ + public Location getLobbyLocation() { + return lobby; + } + + /** + * @param lobby + * the spawn location to set + */ + public void setLobbyLocation(Location lobby) { + this.lobby = lobby; + } + + /** + * @return the ResourceWorld of that this world is an instance + */ + public ResourceWorld getResource() { + return resourceWorld; + } + +} diff --git a/src/main/java/io/github/dre2n/dungeonsxl/world/ResourceWorld.java b/src/main/java/io/github/dre2n/dungeonsxl/world/ResourceWorld.java new file mode 100644 index 00000000..c92742fa --- /dev/null +++ b/src/main/java/io/github/dre2n/dungeonsxl/world/ResourceWorld.java @@ -0,0 +1,148 @@ +/* + * 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 . + */ +package io.github.dre2n.dungeonsxl.world; + +import io.github.dre2n.commons.util.FileUtil; +import io.github.dre2n.dungeonsxl.DungeonsXL; +import io.github.dre2n.dungeonsxl.config.SignData; +import io.github.dre2n.dungeonsxl.config.WorldConfig; +import java.io.File; +import java.io.IOException; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; + +/** + * This class represents unloaded worlds. + * + * @author Daniel Saukel + */ +public class ResourceWorld { + + DungeonsXL plugin = DungeonsXL.getInstance(); + + private File folder; + private WorldConfig config; + private SignData signData; + + public ResourceWorld(File folder) { + this.folder = folder; + + File configFile = new File(folder, "config.yml"); + if (configFile.exists()) { + config = new WorldConfig(configFile); + } + + File signData = new File(folder, "DXLData.data"); + if (signData.exists()) { + this.signData = new SignData(signData); + } + } + + /* Getters and setters */ + /** + * @return the folder that stores the world + */ + public File getFolder() { + return folder; + } + + /** + * @return the name of the world + */ + public String getName() { + return folder.getName(); + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + folder.renameTo(new File(folder.getParentFile(), name)); + } + + /** + * @return the WorldConfig + */ + public WorldConfig getConfig() { + return config; + } + + /** + * @return the DXLData.data file + */ + public SignData getSignData() { + return signData; + } + + /* Actions */ + /** + * @param game + * whether the instance is a GameWorld + * @return an instance of this world + */ + public InstanceWorld instantiate(boolean game) { + int id = plugin.getWorlds().getInstances().size(); + String name = "DXL_" + (game ? "Game" : "Edit") + "_" + id; + File instanceFolder = new File(Bukkit.getWorldContainer(), name); + FileUtil.copyDirectory(folder, instanceFolder, DungeonsXL.EXCLUDED_FILES); + + if (Bukkit.getWorld(name) != null) { + return null; + } + + World world = plugin.getServer().createWorld(WorldCreator.name(name)); + + File idFile = new File(name, InstanceWorld.ID_FILE_PREFIX + getName()); + try { + idFile.createNewFile(); + } catch (IOException exception) { + exception.printStackTrace(); + } + + InstanceWorld instance = new InstanceWorld(this, world, id); + + try { + if (game) { + signData.deserializeSigns((GameWorld) instance); + } else { + signData.deserializeSigns((EditWorld) instance); + } + + } catch (IOException exception) { + exception.printStackTrace(); + } + + return instance; + } + + /** + * @return an instance of this world + */ + public EditWorld instantiateAsEditWorld() { + return (EditWorld) instantiate(false); + } + + /** + * @return an instance of this world + */ + public GameWorld instantiateAsGameWorld() { + return (GameWorld) instantiate(true); + } + +} diff --git a/src/main/java/io/github/dre2n/dungeonsxl/world/Worlds.java b/src/main/java/io/github/dre2n/dungeonsxl/world/Worlds.java index e9d822f0..a4379b8f 100644 --- a/src/main/java/io/github/dre2n/dungeonsxl/world/Worlds.java +++ b/src/main/java/io/github/dre2n/dungeonsxl/world/Worlds.java @@ -16,6 +16,7 @@ */ package io.github.dre2n.dungeonsxl.world; +import io.github.dre2n.commons.util.NumberUtil; import java.io.File; import java.util.Set; @@ -24,23 +25,68 @@ import java.util.Set; */ public class Worlds { - /*private Set resourceWorlds; + private Set resources; + private Set instances; public Worlds(File folder) { for (File file : folder.listFiles()) { - resourceWorlds.add(new ResourceWorld()); + if (file.isDirectory()) { + resources.add(new ResourceWorld(file)); + } } - }*/ + } - @Deprecated - public static boolean exists(String name) { - for (File world : io.github.dre2n.dungeonsxl.DungeonsXL.MAPS.listFiles()) { - if (world.isDirectory() && world.getName().equalsIgnoreCase(name)) { - return true; + /* Getters and setters */ + /** + * @return the ResourceWorld that has this name + */ + public ResourceWorld getResourceByName(String name) { + for (ResourceWorld world : resources) { + if (world.getName().equals(name)) { + return world; } } - return false; + return null; + } + + /** + * @return the InstanceWorld that has this name + */ + public InstanceWorld getInstanceByName(String name) { + String[] splitted = name.split("_"); + if (splitted.length != 3) { + return null; + } + + return getInstanceById(NumberUtil.parseInt(splitted[2], -1)); + } + + /** + * @return the InstanceWorld that has this ID + */ + public InstanceWorld getInstanceById(int id) { + for (InstanceWorld world : instances) { + if (world.getId() == id) { + return world; + } + } + + return null; + } + + /** + * @return the ResourceWorlds in the maps folder + */ + public Set getResources() { + return resources; + } + + /** + * @return the loaded InstanceWorlds in the world container + */ + public Set getInstances() { + return instances; } }