From 027b329af80c1bfbfb16f2a04e9736c24e48dc51 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Mon, 9 Sep 2013 02:31:11 -0400 Subject: [PATCH 1/5] Completed Unsafe Exit Teleportation Completed the code in yCoordHelper for choosing a point to drop the player when using a Transdimensional Trapdoor. Made changes to DDTeleporter so that the player can be dropped at the specific point we want. This needs further testing, though, since I'm not completely sure it's working right. --- .../mod_pocketDim/core/DDTeleporter.java | 11 ++-- .../mod_pocketDim/helpers/yCoordHelper.java | 65 ++++++++----------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java b/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java index ccfa5855..f12e66a7 100644 --- a/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java +++ b/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java @@ -75,7 +75,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; } } @@ -108,7 +108,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; } } @@ -129,7 +130,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; } } @@ -455,10 +456,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/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) From 6f905050f270047f53c2a62a47b96dec6dc3451f Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Wed, 11 Sep 2013 01:21:12 -0400 Subject: [PATCH 2/5] Minor Change Removed unused import --- StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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; From 1d3038288bb6170fbb4547b96473db7b2f0f8365 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Wed, 11 Sep 2013 02:30:31 -0400 Subject: [PATCH 3/5] Minor Fix in BlockDimWall Fixed an issue that skyboy had pointed out long ago about us using ItemBlock.itemID as a block ID instead of ItemBlock.getBlockID(). That's potentially hazardous because that function was introduced specifically so mods could override it and decouple item IDs from block IDs. --- .../mod_pocketDim/blocks/BlockDimWall.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) 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; } From c2fa4964f858953086f855923814236d57f60930 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Wed, 11 Sep 2013 22:13:42 -0400 Subject: [PATCH 4/5] Progress on New Save Format Integrated the base code for our new save format. It still needs more work but at least some substance is there. Ignore the file not found messages that come up when trying to save the world's data - since we're not actually writing files, an exception occurs when we some later code tries to move non-existent save files. Also moved the FileFilter functionality out of DungeonHelper and into its own class, FileFilters, since it's finally needed more broadly. --- .../mod_pocketDim/EventHookContainer.java | 2 +- .../mod_pocketDim/core/DimLink.java | 6 + .../mod_pocketDim/core/NewDimData.java | 38 ++--- .../mod_pocketDim/core/PocketManager.java | 144 +++++++++++------- .../mod_pocketDim/helpers/DungeonHelper.java | 24 +-- .../mod_pocketDim/saving/DDSaveHandler.java | 136 +++++++++++++++++ .../saving/DimDataProcessor.java | 28 ++++ .../mod_pocketDim/saving/IPackable.java | 7 + .../mod_pocketDim/saving/PackedDimData.java | 42 +++++ .../mod_pocketDim/saving/PackedLinkData.java | 6 + .../mod_pocketDim/saving/PackedLinkTail.java | 6 + .../mod_pocketDim/util/FileFilters.java | 51 +++++++ 12 files changed, 397 insertions(+), 93 deletions(-) create mode 100644 StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java create mode 100644 StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java create mode 100644 StevenDimDoors/mod_pocketDim/saving/IPackable.java create mode 100644 StevenDimDoors/mod_pocketDim/saving/PackedDimData.java create mode 100644 StevenDimDoors/mod_pocketDim/saving/PackedLinkData.java create mode 100644 StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java create mode 100644 StevenDimDoors/mod_pocketDim/util/FileFilters.java 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/core/DimLink.java b/StevenDimDoors/mod_pocketDim/core/DimLink.java index cdf25a6b..f0270a71 100644 --- a/StevenDimDoors/mod_pocketDim/core/DimLink.java +++ b/StevenDimDoors/mod_pocketDim/core/DimLink.java @@ -14,6 +14,12 @@ public abstract class DimLink protected DimLink(Point4D source, DimLink parent) { + 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."); + } + 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 a4803331..12c7f25f 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/DungeonHelper.java b/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java index cebfefb8..42cac914 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/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(); + } + } +} From b5973f58eb8ec7b94dba33717231c2b008cf1430 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Wed, 11 Sep 2013 22:18:24 -0400 Subject: [PATCH 5/5] Deletes IItemDimDoor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doesn't seem like we need it... and it's in the wrong package. Respect the packages! õ_Õ --- StevenDimDoors/mod_pocketDim/commands/IItemDimDoor.java | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 StevenDimDoors/mod_pocketDim/commands/IItemDimDoor.java 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 { - -}