#94: New world system (WIP)

- Added world handler class (Worlds)
- Added representation class for unloaded worlds (ResourceWorld)
- Added abstract representation class for all loaded worlds
(InstanceWorld)
- Added class to represent sign data file (SignData)
This commit is contained in:
Daniel Saukel 2016-06-22 21:40:43 +02:00
parent 19fef13ffb
commit 8bb9fe0eac
5 changed files with 461 additions and 31 deletions

View File

@ -55,6 +55,7 @@ import io.github.dre2n.dungeonsxl.task.WorldUnloadTask;
import io.github.dre2n.dungeonsxl.trigger.TriggerTypes; import io.github.dre2n.dungeonsxl.trigger.TriggerTypes;
import io.github.dre2n.dungeonsxl.world.EditWorld; import io.github.dre2n.dungeonsxl.world.EditWorld;
import io.github.dre2n.dungeonsxl.world.GameWorld; import io.github.dre2n.dungeonsxl.world.GameWorld;
import io.github.dre2n.dungeonsxl.world.Worlds;
import io.github.dre2n.itemsxl.ItemsXL; import io.github.dre2n.itemsxl.ItemsXL;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@ -100,6 +101,7 @@ public class DungeonsXL extends BRPlugin {
private DClasses dClasses; private DClasses dClasses;
private DMobTypes dMobTypes; private DMobTypes dMobTypes;
private SignScripts signScripts; private SignScripts signScripts;
private Worlds worlds;
private BukkitTask announcerTask; private BukkitTask announcerTask;
private BukkitTask worldUnloadTask; private BukkitTask worldUnloadTask;
@ -108,8 +110,6 @@ public class DungeonsXL extends BRPlugin {
private BukkitTask secureModeTask; private BukkitTask secureModeTask;
private CopyOnWriteArrayList<DLootInventory> dLootInventories = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList<DLootInventory> dLootInventories = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<EditWorld> editWorlds = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<GameWorld> gameWorlds = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<Game> games = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList<Game> games = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<DGroup> dGroups = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList<DGroup> dGroups = new CopyOnWriteArrayList<>();
@ -602,10 +602,24 @@ public class DungeonsXL extends BRPlugin {
} }
/** /**
* @return the worldUnloadTask * @return the loaded instance of Worlds
*/ */
public BukkitTask getWorldUnloadTask() { public Worlds getWorlds() {
return worldUnloadTask; 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() { public BukkitTask getWorldUnloadTask() {
return announcerTask; return worldUnloadTask;
} }
/** /**
@ -680,20 +694,6 @@ public class DungeonsXL extends BRPlugin {
return dLootInventories; return dLootInventories;
} }
/**
* @return the editWorlds
*/
public List<EditWorld> getEditWorlds() {
return editWorlds;
}
/**
* @return the gameWorlds
*/
public List<GameWorld> getGameWorlds() {
return gameWorlds;
}
/** /**
* @return the games * @return the games
*/ */

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Block> 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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -16,6 +16,7 @@
*/ */
package io.github.dre2n.dungeonsxl.world; package io.github.dre2n.dungeonsxl.world;
import io.github.dre2n.commons.util.NumberUtil;
import java.io.File; import java.io.File;
import java.util.Set; import java.util.Set;
@ -24,23 +25,68 @@ import java.util.Set;
*/ */
public class Worlds { public class Worlds {
/*private Set<ResourceWorld> resourceWorlds; private Set<ResourceWorld> resources;
private Set<InstanceWorld> instances;
public Worlds(File folder) { public Worlds(File folder) {
for (File file : folder.listFiles()) { for (File file : folder.listFiles()) {
resourceWorlds.add(new ResourceWorld()); if (file.isDirectory()) {
resources.add(new ResourceWorld(file));
}
} }
}*/ }
@Deprecated /* Getters and setters */
public static boolean exists(String name) { /**
for (File world : io.github.dre2n.dungeonsxl.DungeonsXL.MAPS.listFiles()) { * @return the ResourceWorld that has this name
if (world.isDirectory() && world.getName().equalsIgnoreCase(name)) { */
return true; 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<ResourceWorld> getResources() {
return resources;
}
/**
* @return the loaded InstanceWorlds in the world container
*/
public Set<InstanceWorld> getInstances() {
return instances;
} }
} }