diff --git a/StevenDimDoors/mod_pocketDim/EventHookContainer.java b/StevenDimDoors/mod_pocketDim/EventHookContainer.java index aeaa0d3d..6191018c 100644 --- a/StevenDimDoors/mod_pocketDim/EventHookContainer.java +++ b/StevenDimDoors/mod_pocketDim/EventHookContainer.java @@ -89,7 +89,7 @@ public class EventHookContainer } @ForgeSubscribe - public void onWorldsave(WorldEvent.Save event) + public void onWorldSave(WorldEvent.Save event) { if (event.world.provider.dimensionId == 0) { diff --git a/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java b/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java index 73e68084..6144d4d1 100644 --- a/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java +++ b/StevenDimDoors/mod_pocketDim/blocks/BlockDimWall.java @@ -3,11 +3,6 @@ package StevenDimDoors.mod_pocketDim.blocks; import java.util.List; import java.util.Random; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -import StevenDimDoors.mod_pocketDim.mod_pocketDim; - import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; @@ -20,6 +15,9 @@ import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.Icon; import net.minecraft.world.World; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; public class BlockDimWall extends Block { @@ -69,14 +67,7 @@ public class BlockDimWall extends Block @Override public Icon getIcon(int par1, int par2) { - if (par2 == 1) - { - return blockIcon[par2]; - } - else - { - return blockIcon[0]; - } + return (par2 != 1) ? blockIcon[0] : blockIcon[1]; } @Override @@ -119,8 +110,13 @@ public class BlockDimWall extends Block if (playerEquip instanceof ItemBlock) { - Block block = Block.blocksList[playerEquip.itemID]; - if (!Block.isNormalCube(playerEquip.itemID) || block instanceof BlockContainer || block.blockID == this.blockID) + // SenseiKiwi: Using getBlockID() rather than the raw itemID is critical. + // Some mods may override that function and use item IDs outside the range + // of the block list. + + int blockID = ((ItemBlock) playerEquip).getBlockID(); + Block block = Block.blocksList[blockID]; + if (!Block.isNormalCube(blockID) || block instanceof BlockContainer || blockID == this.blockID) { return false; } diff --git a/StevenDimDoors/mod_pocketDim/commands/IItemDimDoor.java b/StevenDimDoors/mod_pocketDim/commands/IItemDimDoor.java deleted file mode 100644 index 472bc9ca..00000000 --- a/StevenDimDoors/mod_pocketDim/commands/IItemDimDoor.java +++ /dev/null @@ -1,5 +0,0 @@ -package StevenDimDoors.mod_pocketDim.commands; - -public interface IItemDimDoor { - -} diff --git a/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java b/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java index 03703dee..7ae67d46 100644 --- a/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java +++ b/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java @@ -174,7 +174,7 @@ public class DDTeleporter player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5); break; default: - player.setPositionAndUpdate(x, y - 1, z); + player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5); break; } } @@ -207,7 +207,8 @@ public class DDTeleporter entity.worldObj.updateEntityWithOptionalForce(entity, false); break; default: - DDTeleporter.setEntityPosition(entity, x, y, z); + DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 0.5); + entity.worldObj.updateEntityWithOptionalForce(entity, false); break; } } @@ -228,7 +229,7 @@ public class DDTeleporter setEntityPosition(entity, x + 0.5, y, z + 1.5); break; default: - setEntityPosition(entity, x, y, z); + setEntityPosition(entity, x + 0.5, y, z + 0.5); break; } } @@ -556,10 +557,10 @@ public class DDTeleporter return false; } - Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY(), source.getZ()); + Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ()); if (destination != null) { - current.root().setDestination(link, source.getX(), source.getY(), source.getZ()); + current.root().setDestination(link, destination.getX(), destination.getY(), destination.getZ()); return true; } } diff --git a/StevenDimDoors/mod_pocketDim/core/DimLink.java b/StevenDimDoors/mod_pocketDim/core/DimLink.java index 10cba752..c3800c31 100644 --- a/StevenDimDoors/mod_pocketDim/core/DimLink.java +++ b/StevenDimDoors/mod_pocketDim/core/DimLink.java @@ -15,7 +15,16 @@ public abstract class DimLink protected DimLink(Point4D source, DimLink parent, int orientation) { +<<<<<<< HEAD this.orientation=orientation; +======= + if (parent.source.getDimension() != source.getDimension()) + { + // Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails + throw new IllegalArgumentException("source and parent.source must have the same dimension."); + } + +>>>>>>> 25446453cba6f491cc0745803f448dd000d453cc this.parent = parent; this.source = source; this.tail = parent.tail; diff --git a/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/StevenDimDoors/mod_pocketDim/core/NewDimData.java index c0c272a8..05ab685c 100644 --- a/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -57,13 +57,17 @@ public abstract class NewDimData if (nextParent == null) { throw new IllegalArgumentException("nextParent cannot be null."); - } - + } if (this == nextParent) { //Ignore this request silently return false; } + if (nextParent.source.getDimension() != source.getDimension()) + { + // Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails + throw new IllegalArgumentException("source and parent.source must have the same dimension."); + } //Release children for (DimLink child : children) @@ -106,22 +110,22 @@ public abstract class NewDimData } } - private static Random random = new Random(); + protected static Random random = new Random(); - private final int id; - private final Map linkMapping; - private final List linkList; - private final boolean isDungeon; - private boolean isFilled; - private final int depth; - private int packDepth; - private final NewDimData parent; - private final NewDimData root; - private final List children; - private Point4D origin; - private int orientation; - private DungeonData dungeon; - private final IUpdateWatcher linkWatcher; + protected int id; + protected Map linkMapping; + protected List linkList; + protected boolean isDungeon; + protected boolean isFilled; + protected int depth; + protected int packDepth; + protected NewDimData parent; + protected NewDimData root; + protected List children; + protected Point4D origin; + protected int orientation; + protected DungeonData dungeon; + protected IUpdateWatcher linkWatcher; protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon, IUpdateWatcher linkWatcher) diff --git a/StevenDimDoors/mod_pocketDim/core/PocketManager.java b/StevenDimDoors/mod_pocketDim/core/PocketManager.java index eda89472..3c992fcb 100644 --- a/StevenDimDoors/mod_pocketDim/core/PocketManager.java +++ b/StevenDimDoors/mod_pocketDim/core/PocketManager.java @@ -13,6 +13,9 @@ import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.helpers.Compactor; import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder; +import StevenDimDoors.mod_pocketDim.saving.DDSaveHandler; +import StevenDimDoors.mod_pocketDim.saving.IPackable; +import StevenDimDoors.mod_pocketDim.saving.PackedDimData; import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.watcher.ClientDimData; import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource; @@ -25,7 +28,7 @@ import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy; */ public class PocketManager { - private static class InnerDimData extends NewDimData + private static class InnerDimData extends NewDimData implements IPackable { // This class allows us to instantiate NewDimData indirectly without exposing // a public constructor from NewDimData. It's meant to stop us from constructing @@ -43,6 +46,49 @@ public class PocketManager // This constructor is meant for client-side code only super(id, root); } + + public void clear() + { + // If this dimension has a parent, remove it from its parent's list of children + if (parent != null) + { + parent.children.remove(this); + } + // Remove this dimension as the parent of its children + for (NewDimData child : children) + { + child.parent = null; + } + // Clear all fields + id = Integer.MIN_VALUE; + linkMapping.clear(); + linkMapping = null; + linkList.clear(); + linkList = null; + children.clear(); + children = null; + isDungeon = false; + isFilled = false; + depth = Integer.MIN_VALUE; + packDepth = Integer.MIN_VALUE; + origin = null; + orientation = Integer.MIN_VALUE; + dungeon = null; + linkWatcher = null; + } + + @Override + public String name() + { + return String.valueOf(id); + } + + @Override + public PackedDimData pack() + { + // FIXME: IMPLEMENTATION PLZTHX + return null; + } } private static class ClientLinkWatcher implements IUpdateWatcher @@ -140,44 +186,44 @@ public class PocketManager isLoading = false; } - public boolean clearPocket(NewDimData dimension) + public boolean resetDungeon(NewDimData target) { - if (!dimension.isPocketDimension() || DimensionManager.getWorld(dimension.id()) != null) + // We can't reset the dimension if it's currently loaded or if it's not a dungeon. + // We cast to InnerDimData so that if anyone tries to be a smartass and create their + // own version of NewDimData, this will throw an exception. + InnerDimData dimension = (InnerDimData) target; + if (dimension.isDungeon() && DimensionManager.getWorld(dimension.id()) == null) { - return false; + File saveDirectory = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id()); + if (DeleteFolder.deleteFolder(saveDirectory)) + { + dimension.setFilled(false); + return true; + } } - - File save = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id()); - DeleteFolder.deleteFolder(save); - dimension.setFilled(false); - //FIXME: Reset door information? - return true; + return false; } - public static boolean deletePocket(NewDimData dimension, boolean deleteFolder) + public static boolean deletePocket(NewDimData target, boolean deleteFolder) { - //FIXME: Shouldn't the links in and out of this dimension be altered somehow? Otherwise we have links pointing - //into a deleted dimension! - - //Checks to see if the pocket is loaded or isn't actually a pocket. + // We can't delete the dimension if it's currently loaded or if it's not actually a pocket. + // We cast to InnerDimData so that if anyone tries to be a smartass and create their + // own version of NewDimData, this will throw an exception. + InnerDimData dimension = (InnerDimData) target; if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null) { - dimensionData.remove(dimension.id()); - DimensionManager.unregisterDimension(dimension.id()); if (deleteFolder) { - File save = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id()); - DeleteFolder.deleteFolder(save); + File saveDirectory = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id()); + DeleteFolder.deleteFolder(saveDirectory); } - //Raise the dim deleted event + dimensionData.remove(dimension.id()); + // Raise the dim deleted event dimWatcher.onDeleted(new ClientDimData(dimension)); - //dimension.implode()??? -- more like delete, but yeah + dimension.clear(); return true; } - else - { - return false; - } + return false; } private static void registerPockets(DDProperties properties) @@ -222,32 +268,29 @@ public class PocketManager * loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler */ private static void loadInternal() - { - // SenseiKiwi: This is a temporary function for testing purposes. - // We'll move on to using a text-based format in the future. - + { if (!DimensionManager.getWorld(OVERWORLD_DIMENSION_ID).isRemote && DimensionManager.getCurrentSaveRootDirectory() != null) { - System.out.println("Loading Dimensional Doors save data..."); - /*File saveFile = new File(DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat"); + // Load and register blacklisted dimension IDs - setState(saveData);*/ - System.out.println("Loaded successfully!"); + // Load save data + System.out.println("Loading Dimensional Doors save data..."); + if (DDSaveHandler.loadAll()) + { + System.out.println("Loaded successfully!"); + } } } public static void save() { - // SenseiKiwi: This is a temporary function for testing purposes. - // We'll move on to using a text-based format in the future. - if (!isLoaded) { return; } World world = DimensionManager.getWorld(OVERWORLD_DIMENSION_ID); - if (world == null || world.isRemote || DimensionManager.getCurrentSaveRootDirectory() != null) + if (world == null || world.isRemote || DimensionManager.getCurrentSaveRootDirectory() == null) { return; } @@ -256,30 +299,23 @@ public class PocketManager { return; } - isSaving = true; + try { System.out.println("Writing Dimensional Doors save data..."); - /*String tempPath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.tmp"; - String savePath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat"; - File tempFile = new File(tempPath); - File saveFile = new File(savePath); - DataOutputStream writer = new DataOutputStream(new FileOutputStream(tempFile)); - getState().writeToStream(writer); - writer.close(); - saveFile.delete(); - tempFile.renameTo(saveFile);*/ - System.out.println("Saved successfully!"); + if ( DDSaveHandler.saveAll(dimensionData.values()) ) + { + System.out.println("Saved successfully!"); + } } - /*catch (FileNotFoundException e) + catch (Exception e) { - e.printStackTrace(); + // Wrap the exception in a RuntimeException so functions that call + // PocketManager.save() don't need to catch it. We want MC to + // crash if something really bad happens rather than ignoring it! + throw new RuntimeException(e); } - catch (IOException e) - { - e.printStackTrace(); - }*/ finally { isSaving = false; diff --git a/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java b/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java index bd2a2348..f7341929 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java @@ -3,11 +3,9 @@ package StevenDimDoors.mod_pocketDim.helpers; import java.util.List; import net.minecraft.world.World; -import net.minecraftforge.common.ForgeChunkManager.Ticket; import net.minecraftforge.common.ForgeChunkManager; - +import net.minecraftforge.common.ForgeChunkManager.Ticket; import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold; import com.google.common.collect.Lists; diff --git a/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java b/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java index 78963fc7..6207f71d 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java @@ -33,29 +33,11 @@ import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfigReader; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType; import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor; import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException; +import StevenDimDoors.mod_pocketDim.util.FileFilters; import StevenDimDoors.mod_pocketDim.util.WeightedContainer; public class DungeonHelper { - //TODO: File-handling functionality should be spun off to a helper class later - private static class DirectoryFilter implements FileFilter - { - @Override - public boolean accept(File file) - { - return file.isDirectory(); - } - } - - private static class SchematicFileFilter implements FileFilter - { - @Override - public boolean accept(File file) - { - return file.isFile() && file.getName().endsWith(SCHEMATIC_FILE_EXTENSION); - } - } - private static DungeonHelper instance = null; private static DDProperties properties = null; @@ -387,7 +369,7 @@ public class DungeonHelper File[] packFiles; ArrayList packFilePaths; File directory = new File(path); - SchematicFileFilter schematicFileFilter = new SchematicFileFilter(); + FileFilter schematicFileFilter = new FileFilters.FileExtensionFilter(SCHEMATIC_FILE_EXTENSION); //Check that the Ruins pack has been loaded if (RuinsPack == null) @@ -411,7 +393,7 @@ public class DungeonHelper schematics = null; //Release memory //Load the custom dungeon packs - packDirectories = directory.listFiles(new DirectoryFilter()); + packDirectories = directory.listFiles(new FileFilters.DirectoryFilter()); if (packDirectories != null) { //Loop through each directory, which is assumed to be a dungeon pack diff --git a/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java b/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java index 1ac85198..34e8b8db 100644 --- a/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java +++ b/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java @@ -218,10 +218,12 @@ public class yCoordHelper return target; } - public static Point3D findDropPoint(World world, int x, int y, int z) + public static Point3D findDropPoint(World world, int x, int startY, int z) { - /*// Find a simple 2-block-high air gap + // Find a simple 2-block-high air gap // Search across a 3x3 column + final int GAP_HEIGHT = 2; + int localX = x < 0 ? (x % 16) + 16 : (x % 16); int localZ = z < 0 ? (z % 16) + 16 : (z % 16); int cornerX = x - localX; @@ -231,56 +233,45 @@ public class yCoordHelper Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4); + int y, dx, dz, index; int height = world.getActualHeight(); - int y, dx, dz, blockID; - boolean isSafe; - boolean hasBlocks; - Block block; - int layers = 0; + int[] gaps = new int[9]; - // Check if a 3x3 layer of blocks is empty - // If we find a layer that contains replaceable blocks, it can - // serve as the base where we'll place the player and door. - for (y = Math.min(startY + 2, height - 1); y >= 0; y--) + // Check 3x3 layers of blocks for air spaces + for (y = Math.min(startY, height - 1); y > 0; y--) { - isSafe = true; - hasBlocks = false; - for (dx = -1; dx <= 1 && isSafe; dx++) + for (dx = -1, index = 0; dx <= 1; dx++) { - for (dz = -1; dz <= 1 && isSafe; dz++) + for (dz = -1; dz <= 1; dz++, index++) { - blockID = chunk.getBlockID(localX + dx, y, localZ + dz); - if (blockID != 0) - { - block = Block.blocksList[blockID]; - if (!block.blockMaterial.isReplaceable()) - { - if (layers >= 3) - { - return new Point3D(localX + cornerX, y + 1, localZ + cornerZ); - } - isSafe = false; - } - hasBlocks = true; + if (chunk.getBlockID(localX + dx, y, localZ + dz) != 0) + { + gaps[index] = 0; + } + else + { + gaps[index]++; } } } - if (isSafe) + // Check if an acceptable gap exists in the center of the search column + if (gaps[index / 2] == GAP_HEIGHT) { - layers++; - if (hasBlocks) + return new Point3D(localX + cornerX, y + GAP_HEIGHT - 1, localZ + cornerZ); + } + // Check the other positions in the column + for (dx = -1, index = 0; dx <= 1; dx++) + { + for (dz = -1; dz <= 1; dz++, index++) { - if (layers >= 3) + if (gaps[index] == GAP_HEIGHT) { - return new Point3D(localX + cornerX, y, localZ + cornerZ); + return new Point3D(localX + cornerX + dx, y + GAP_HEIGHT - 1, localZ + cornerZ + dz); } - layers = 0; } } } - return null;*/ - // Temporary measure to not break the build - return new Point3D(x, y - 2, z); + return null; } public static int adjustDestinationY(int y, int worldHeight, int entranceY, int dungeonHeight) diff --git a/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java b/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java new file mode 100644 index 00000000..fe63994c --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java @@ -0,0 +1,136 @@ +package StevenDimDoors.mod_pocketDim.saving; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import net.minecraftforge.common.DimensionManager; +import StevenDimDoors.mod_pocketDim.util.FileFilters; + +import com.google.common.io.Files; + +public class DDSaveHandler +{ + public static boolean loadAll() + { + // SenseiKiwi: Loading up our save data is not as simple as just reading files. + // To properly restore dimensions, we need to make sure we always load + // a dimension's parent and root before trying to load it. We'll use + // topological sorting to determine the order in which to recreate the + // dimension objects such that we respect those dependencies. + // Links must be loaded after instantiating all the dimensions and must + // be checked against our dimension blacklist. + + // Don't surround this code with try-catch. Our mod should crash if an error + // occurs at this level, since it could lead to some nasty problems. + + String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/"; + File dataDirectory = new File(basePath); + + // Check if the folder exists. If it doesn't, just return. + if (!dataDirectory.exists()) + { + return true; + } + + // Load the dimension blacklist + // --insert code here-- + + // List any dimension data files and read each dimension + DimDataProcessor reader = new DimDataProcessor(); + List packedDims = new ArrayList(); + FileFilter dataFileFilter = new FileFilters.RegexFileFilter("dim_-?\\d+\\.txt"); + + File[] dataFiles = dataDirectory.listFiles(dataFileFilter); + for (File dataFile : dataFiles) + { + PackedDimData packedDim = readDimension(dataFile, reader); + } + return true; + } + + private static PackedDimData readDimension(File dataFile, DimDataProcessor reader) + { + try + { + return reader.readFromFile(dataFile); + } + catch (Exception e) + { + System.err.println("Could not read dimension data from: " + dataFile.getAbsolutePath()); + System.err.println("The following error occurred:"); + printException(e, false); + return null; + } + } + + public static boolean saveAll(Iterable> dimensions) throws IOException + { + // Create the data directory for our dimensions + // Don't catch exceptions here. If we can't create this folder, + // the mod should crash to let the user know early on. + + String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/"; + File basePathFile = new File(basePath); + Files.createParentDirs(basePathFile); + basePathFile = null; + basePath += "dim_"; + + boolean succeeded = true; + DimDataProcessor writer = new DimDataProcessor(); + for (IPackable dimension : dimensions) + { + succeeded &= writeDimension(dimension, writer, basePath); + } + return succeeded; + } + + private static boolean writeDimension(IPackable dimension, DimDataProcessor writer, String basePath) + { + try + { + File tempFile = new File(basePath + (dimension.name() + ".tmp")); + File saveFile = new File(basePath + (dimension.name() + ".txt")); + writer.writeToFile(tempFile, dimension.pack()); + saveFile.delete(); + tempFile.renameTo(saveFile); + return true; + } + catch (Exception e) + { + System.err.println("Could not save data for dimension #" + dimension.name() + ". The following error occurred:"); + printException(e, false); + return false; + } + } + + private static void printException(Exception e, boolean verbose) + { + if (e.getCause() == null) + { + if (verbose) + { + e.printStackTrace(); + } + else + { + System.err.println(e.getMessage()); + } + } + else + { + System.out.println(e.getMessage()); + System.err.println("Caused by an underlying error:"); + if (verbose) + { + e.getCause().printStackTrace(); + } + else + { + System.err.println(e.getCause().getMessage()); + } + } + } +} diff --git a/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java b/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java new file mode 100644 index 00000000..61021824 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java @@ -0,0 +1,28 @@ +package StevenDimDoors.mod_pocketDim.saving; + +import java.io.InputStream; +import java.io.OutputStream; + +import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor; +import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException; + +public class DimDataProcessor extends BaseConfigurationProcessor +{ + + @Override + public PackedDimData readFromStream(InputStream inputStream) + throws ConfigurationProcessingException + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void writeToStream(OutputStream outputStream, PackedDimData data) + throws ConfigurationProcessingException + { + // TODO Auto-generated method stub + + } + +} diff --git a/StevenDimDoors/mod_pocketDim/saving/IPackable.java b/StevenDimDoors/mod_pocketDim/saving/IPackable.java new file mode 100644 index 00000000..78908d8c --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/saving/IPackable.java @@ -0,0 +1,7 @@ +package StevenDimDoors.mod_pocketDim.saving; + +public interface IPackable +{ + public String name(); + public T pack(); +} diff --git a/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java b/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java new file mode 100644 index 00000000..38af8f18 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java @@ -0,0 +1,42 @@ +package StevenDimDoors.mod_pocketDim.saving; + +import java.util.List; + +import StevenDimDoors.mod_pocketDim.Point3D; + +public class PackedDimData +{ + // These fields will be public since this is a simple data container + public final int ID; + public final boolean IsDungeon; + public final boolean IsFilled; + public final int Depth; + public final int PackDepth; + public final int ParentID; + public final int RootID; + public final Point3D Origin; + public final int Orientation; + public final List ChildIDs; + public final List Links; + public final List Tails; + + // FIXME Missing dungeon data, not sure how to include it + + public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation, + boolean isDungeon, boolean isFilled, Point3D origin, List childIDs, List links, + List tails) + { + ID = id; + Depth = depth; + PackDepth = packDepth; + ParentID = parentID; + RootID = rootID; + Orientation = orientation; + IsDungeon = isDungeon; + IsFilled = isFilled; + Origin = origin; + ChildIDs = childIDs; + Links = links; + Tails = tails; + } +} diff --git a/StevenDimDoors/mod_pocketDim/saving/PackedLinkData.java b/StevenDimDoors/mod_pocketDim/saving/PackedLinkData.java new file mode 100644 index 00000000..f82e74af --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/saving/PackedLinkData.java @@ -0,0 +1,6 @@ +package StevenDimDoors.mod_pocketDim.saving; + +public class PackedLinkData +{ + +} diff --git a/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java b/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java new file mode 100644 index 00000000..c5a1bb75 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java @@ -0,0 +1,6 @@ +package StevenDimDoors.mod_pocketDim.saving; + +public class PackedLinkTail +{ + +} diff --git a/StevenDimDoors/mod_pocketDim/util/FileFilters.java b/StevenDimDoors/mod_pocketDim/util/FileFilters.java new file mode 100644 index 00000000..efd4e3bc --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/util/FileFilters.java @@ -0,0 +1,51 @@ +package StevenDimDoors.mod_pocketDim.util; + +import java.io.File; +import java.io.FileFilter; +import java.util.regex.Pattern; + +public class FileFilters +{ + private FileFilters() { } + + public static class DirectoryFilter implements FileFilter + { + @Override + public boolean accept(File file) + { + return file.isDirectory(); + } + } + + public static class FileExtensionFilter implements FileFilter + { + private final String extension; + + public FileExtensionFilter(String extension) + { + this.extension = extension; + } + + @Override + public boolean accept(File file) + { + return file.isFile() && file.getName().endsWith(extension); + } + } + + public static class RegexFileFilter implements FileFilter + { + private final Pattern pattern; + + public RegexFileFilter(String expression) + { + this.pattern = Pattern.compile(expression); + } + + @Override + public boolean accept(File file) + { + return file.isFile() && pattern.matcher(file.getName()).matches(); + } + } +}