From 18666f58b18364f428f8f538c2812f13bb9fd881 Mon Sep 17 00:00:00 2001 From: StevenRS11 Date: Wed, 25 Jun 2014 04:37:40 -0400 Subject: [PATCH] Added versioning to save files and DimensionType --- .../commands/CommandResetDungeons.java | 5 +- .../mod_pocketDim/core/DDTeleporter.java | 2 +- .../mod_pocketDim/core/DimensionType.java | 41 ++++ .../core/IDimRegistrationCallback.java | 2 +- .../mod_pocketDim/core/NewDimData.java | 33 +-- .../mod_pocketDim/core/PocketManager.java | 45 ++-- .../mod_pocketDim/core/PocketType.java | 16 -- .../mod_pocketDim/helpers/Compactor.java | 6 +- .../mod_pocketDim/items/ItemDDKey.java | 4 +- .../mod_pocketDim/saving/DDSaveHandler.java | 9 +- .../saving/DimDataProcessor.java | 105 ++++++-- .../mod_pocketDim/saving/OldSaveImporter.java | 30 ++- .../mod_pocketDim/saving/PackedDimData.java | 9 +- .../mod_pocketDim/saving/PackedLinkTail.java | 5 +- .../mod_pocketDim/watcher/ClientDimData.java | 21 +- .../mod_pocketDim/watcher/ClientLinkData.java | 21 +- .../mod_pocketDim/world/PocketBuilder.java | 13 +- .../dimdoors/text/Dim_Data_Schema_v1-0-0.json | 229 ++++++++++++++++++ ...a.json => Dim_Data_Schema_v982405775.json} | 5 +- 19 files changed, 477 insertions(+), 124 deletions(-) create mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/core/DimensionType.java delete mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/core/PocketType.java create mode 100644 src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v1-0-0.json rename src/main/resources/assets/dimdoors/text/{Dim_Data_Schema.json => Dim_Data_Schema_v982405775.json} (98%) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java index 09783385..3c84bdf2 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; @@ -46,13 +47,13 @@ public class CommandResetDungeons extends DDCommandBase for (NewDimData data : PocketManager.getDimensions()) { - if(DimensionManager.getWorld(data.id())==null&&data.isDungeon()) + if(DimensionManager.getWorld(data.id())==null&&data.getDimensionType() == DimensionType.DUNGEON) { resetCount++; dungeonCount++; dimsToDelete.add(data.id()); } - else if(data.isDungeon()) + else if(data.getDimensionType() == DimensionType.DUNGEON) { dimsToFix.add(data.id()); dungeonCount++; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java index 17c6e69e..f102e967 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java @@ -498,7 +498,7 @@ public class DDTeleporter case DUNGEON: return PocketBuilder.generateNewDungeonPocket(link, properties); case POCKET: - return PocketBuilder.generateNewPocket(link, properties,door); + return PocketBuilder.generateNewPocket(link, properties, door, DimensionType.POCKET); case PERSONAL: return setupPersonalLink(link, properties, entity, door); case SAFE_EXIT: diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimensionType.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimensionType.java new file mode 100644 index 00000000..c7ba2963 --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimensionType.java @@ -0,0 +1,41 @@ +package StevenDimDoors.mod_pocketDim.core; + +public enum DimensionType +{ + // WARNING: Don't modify these values carelessly or you'll risk breaking existing worlds! + ROOT(0,false), + POCKET(1,true), + DUNGEON(2,true), + PERSONAL(3,true); + + DimensionType(int index, boolean isPocket) + { + this.index = index; + this.isPocket = isPocket; + } + + public final int index; + public final boolean isPocket; + + /** + * Get the DimensionType given an index. I feel like there should be a better way to do this. + * @param index + * @return + */ + public static DimensionType getTypeFromIndex(int index) + { + for(DimensionType type : DimensionType.values()) + { + if(type.index == index) + { + return type; + } + } + return null; + } + + public boolean isPocketDimension() + { + return this.isPocket; + } +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/IDimRegistrationCallback.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/IDimRegistrationCallback.java index 04a0c389..f233096d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/IDimRegistrationCallback.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/IDimRegistrationCallback.java @@ -2,5 +2,5 @@ package StevenDimDoors.mod_pocketDim.core; public interface IDimRegistrationCallback { - public NewDimData registerDimension(int dimensionID, int rootID); + public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 095b792e..612117bc 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -130,10 +130,10 @@ public abstract class NewDimData implements IPackable protected int id; protected Map linkMapping; protected List linkList; - protected boolean isDungeon; protected boolean isFilled; protected int depth; protected int packDepth; + protected DimensionType type; protected NewDimData parent; protected NewDimData root; protected List children; @@ -143,18 +143,12 @@ public abstract class NewDimData implements IPackable protected boolean modified; public IUpdateWatcher linkWatcher; - protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon, - IUpdateWatcher linkWatcher) + protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher linkWatcher) { - // The isPocket flag is redundant. It's meant as an integrity safeguard. - if (isPocket && (parent == null)) + if (type != DimensionType.ROOT && (parent == null)) { throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension."); } - if (isDungeon && !isPocket) - { - throw new IllegalArgumentException("A dimensional dungeon must also be a pocket dimension."); - } this.id = id; this.linkMapping = new TreeMap(); //Should be stored in oct tree -- temporary solution @@ -162,7 +156,7 @@ public abstract class NewDimData implements IPackable this.children = new ArrayList(); this.parent = parent; this.packDepth = 0; - this.isDungeon = isDungeon; + this.type = type; this.isFilled = false; this.orientation = 0; this.origin = null; @@ -186,7 +180,7 @@ public abstract class NewDimData implements IPackable } } - protected NewDimData(int id, NewDimData root) + protected NewDimData(int id, NewDimData root, DimensionType type) { // This constructor is meant for client-side code only if (root == null) @@ -200,7 +194,7 @@ public abstract class NewDimData implements IPackable this.children = new ArrayList(); this.parent = null; this.packDepth = 0; - this.isDungeon = false; + this.type = type; this.isFilled = false; this.orientation = 0; this.origin = null; @@ -422,11 +416,10 @@ public abstract class NewDimData implements IPackable return (root != this); } - public boolean isDungeon() + public DimensionType getDimensionType() { - return isDungeon; + return this.type; } - public boolean isFilled() { return isFilled; @@ -500,7 +493,7 @@ public abstract class NewDimData implements IPackable public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon) { - if (!isDungeon) + if (this.type != DimensionType.DUNGEON) { throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension."); } @@ -655,7 +648,7 @@ public abstract class NewDimData implements IPackable linkList = null; children.clear(); children = null; - isDungeon = false; + type = null; isFilled = false; depth = Integer.MIN_VALUE; packDepth = Integer.MIN_VALUE; @@ -696,10 +689,10 @@ public abstract class NewDimData implements IPackable { children.add(childLink.source().toPoint3D()); } - PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType().index); + PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType()); Links.add(new PackedLinkData(link.point,parentPoint,tail,link.orientation,children,link.lock)); - PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType().index); + PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType()); if(Tails.contains(tempTail)) { Tails.add(tempTail); @@ -718,7 +711,7 @@ public abstract class NewDimData implements IPackable originPoint=this.origin.toPoint3D(); } return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation, - isDungeon, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails); + type, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails); // FIXME: IMPLEMENTATION PLZTHX //I tried } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java index 1c8cba5b..4cbca5f5 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java @@ -42,16 +42,16 @@ public class PocketManager // instances of NewDimData going through PocketManager. In turn, that enforces // that any link destinations must be real dimensions controlled by PocketManager. - public InnerDimData(int id, InnerDimData parent, boolean isPocket, boolean isDungeon, + public InnerDimData(int id, InnerDimData parent, DimensionType type, IUpdateWatcher linkWatcher) { - super(id, parent, isPocket, isDungeon, linkWatcher); + super(id, parent, type, linkWatcher); } - public InnerDimData(int id, InnerDimData root) + public InnerDimData(int id, NewDimData root, DimensionType type) { // This constructor is meant for client-side code only - super(id, root); + super(id, root, type); } } @@ -90,7 +90,7 @@ public class PocketManager @Override public void onCreated(ClientDimData data) { - registerClientDimension(data.ID, data.RootID); + registerClientDimension(data.ID, data.rootID, data.type); } @Override @@ -114,9 +114,9 @@ public class PocketManager // exposing a private constructor ONLY to a very specific trusted class. @Override - public NewDimData registerDimension(int dimensionID, int rootID) + public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type) { - return registerClientDimension(dimensionID, rootID); + return registerClientDimension(dimensionID, rootID, type); } } @@ -177,7 +177,7 @@ public class PocketManager } //Register Limbo DDProperties properties = DDProperties.instance(); - registerDimension(properties.LimboDimensionID, null, false, false); + registerDimension(properties.LimboDimensionID, null, DimensionType.ROOT); loadInternal(); @@ -192,10 +192,15 @@ public class PocketManager { InnerDimData dimData; + DimensionType type = DimensionType.getTypeFromIndex(packedData.DimensionType); + if(type == null) + { + throw new IllegalArgumentException("Invalid dimension type"); + } //register roots if(packedData.ID==packedData.ParentID) { - dimData = new InnerDimData(packedData.ID, null, false, false, linkWatcher); + dimData = new InnerDimData(packedData.ID, null, type, linkWatcher); dimData.root=dimData; dimData.parent=dimData; dimData.depth=packedData.Depth; @@ -207,7 +212,7 @@ public class PocketManager else //register children { InnerDimData test = PocketManager.dimensionData.get(packedData.ParentID); - dimData = new InnerDimData(packedData.ID, test,true, packedData.IsDungeon, linkWatcher); + dimData = new InnerDimData(packedData.ID, test, type, linkWatcher); dimData.isFilled=packedData.IsFilled; dimData.origin = new Point4D(packedData.Origin.getX(),packedData.Origin.getY(),packedData.Origin.getZ(),packedData.ID); dimData.root=PocketManager.getDimensionData(packedData.RootID); @@ -421,7 +426,7 @@ public class PocketManager public static NewDimData registerDimension(World world) { - return registerDimension(world.provider.dimensionId, null, false, false); + return registerDimension(world.provider.dimensionId, null, DimensionType.ROOT); } public static NewDimData registerPersonalPocket(NewDimData parent, String playerName) @@ -434,12 +439,12 @@ public class PocketManager DDProperties properties = DDProperties.instance(); int dimensionID = DimensionManager.getNextFreeDimId(); DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID); - NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, true, false); + NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, DimensionType.PERSONAL); personalPocketsMapping.put(playerName, data); return data; } - public static NewDimData registerPocket(NewDimData parent, boolean isDungeon) + public static NewDimData registerPocket(NewDimData parent, DimensionType type) { if (parent == null) { @@ -449,7 +454,7 @@ public class PocketManager DDProperties properties = DDProperties.instance(); int dimensionID = DimensionManager.getNextFreeDimId(); DimensionManager.registerDimension(dimensionID, properties.PocketProviderID); - return registerDimension(dimensionID, (InnerDimData) parent, true, isDungeon); + return registerDimension(dimensionID, (InnerDimData) parent, type); } /** * Registers a dimension with DD but NOT with forge. @@ -459,7 +464,7 @@ public class PocketManager * @param isDungeon * @return */ - private static NewDimData registerDimension(int dimensionID, InnerDimData parent, boolean isPocket, boolean isDungeon) + private static NewDimData registerDimension(int dimensionID, InnerDimData parent, DimensionType type) { if (dimensionData.containsKey(dimensionID)) { @@ -469,7 +474,7 @@ public class PocketManager } throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered."); } - InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher); + InnerDimData dimension = new InnerDimData(dimensionID, parent, type, linkWatcher); dimensionData.put(dimensionID, dimension); if (!dimension.isPocketDimension()) { @@ -481,7 +486,7 @@ public class PocketManager } @SideOnly(Side.CLIENT) - private static NewDimData registerClientDimension(int dimensionID, int rootID) + private static NewDimData registerClientDimension(int dimensionID, int rootID, DimensionType type) { System.out.println("Registered dim "+dimensionID+" on the client."); // No need to raise events heres since this code should only run on the client side @@ -498,7 +503,7 @@ public class PocketManager dimension = dimensionData.get(dimensionID); if (dimension == null) { - dimension = new InnerDimData(dimensionID, root); + dimension = new InnerDimData(dimensionID, root, type); dimensionData.put(dimension.id(), dimension); } } @@ -538,9 +543,11 @@ public class PocketManager return null; } NewDimData dimension = PocketManager.dimensionData.get(dimensionID); + + // if we do not have a record of it, then it must be a root if (dimension == null) { - dimension = registerDimension(dimensionID, null, false, false); + dimension = registerDimension(dimensionID, null, DimensionType.ROOT); } return dimension; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketType.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketType.java deleted file mode 100644 index ba3da9d4..00000000 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketType.java +++ /dev/null @@ -1,16 +0,0 @@ -package StevenDimDoors.mod_pocketDim.core; - -public enum PocketType -{ - // WARNING: Don't modify these values carelessly or you'll risk breaking existing worlds! - NORMAL(0), - DUNGEON(1), - PERSONAL(2); - - PocketType(int index) - { - this.index = index; - } - - public final int index; -} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/Compactor.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/Compactor.java index 13eff900..a19dc9f3 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/Compactor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/Compactor.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.HashSet; import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.IDimRegistrationCallback; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; @@ -67,13 +68,14 @@ public class Compactor { int id = input.readInt(); int rootID = input.readInt(); + DimensionType type = DimensionType.getTypeFromIndex(input.readInt()); if (rootIDs.add(rootID)) { - callback.registerDimension(rootID, rootID); + callback.registerDimension(rootID, rootID, type); } // Don't check if (id != rootID) - we want to retrieve the reference anyway - NewDimData dimension = callback.registerDimension(id, rootID); + NewDimData dimension = callback.registerDimension(id, rootID, type); int linkCount = input.readInt(); for (int h = 0; h < linkCount; h++) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemDDKey.java b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemDDKey.java index 1721317a..a93ec030 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemDDKey.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemDDKey.java @@ -103,7 +103,7 @@ public class ItemDDKey extends Item world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F); } PocketManager.getDimensionData(world).lock(link, !link.getLockState()); - PocketManager.getLinkWatcher().update(new ClientLinkData(link.source(),link.getLock())); + PocketManager.getLinkWatcher().update(new ClientLinkData(link)); } else { @@ -116,7 +116,7 @@ public class ItemDDKey extends Item { world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F); PocketManager.getDimensionData(world).createLock(link, itemStack, world.rand.nextInt(Integer.MAX_VALUE)); - PocketManager.getLinkWatcher().update(new ClientLinkData(link.source(),link.getLock())); + PocketManager.getLinkWatcher().update(new ClientLinkData(link)); } } return false; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java index a13c2cd9..ae3c5af9 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/saving/DDSaveHandler.java @@ -12,6 +12,7 @@ import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; @@ -157,7 +158,7 @@ public class DDSaveHandler } if(isMissing) { - packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails)); + packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, DimensionType.getTypeFromIndex(packedDim.DimensionType), packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails)); packedDims.put(packedDim.ID, packedDim); } return children; @@ -175,12 +176,12 @@ public class DDSaveHandler { ArrayList fosterChildren = new ArrayList(); fosterChildren.add(packedDim.ID); - + DimensionType type = DimensionType.getTypeFromIndex(packedDim.DimensionType); //fix pockets without parents if(!packedDims.containsKey(packedDim.ParentID)) { //Fix the orphan by changing its root to its parent, re-connecting it to the list - packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails)); + packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation,type, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails)); packedDims.put(packedDim.ID, packedDim); } //fix pockets whose parents have forgotten about them @@ -189,7 +190,7 @@ public class DDSaveHandler { //find the root, and fix it by adding the orphan's ID to its children fosterChildren.addAll(fosterParent.ChildIDs); - fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, fosterParent.IsDungeon, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails)); + fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, type, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails)); packedDims.put(fosterParent.ID, fosterParent); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java b/src/main/java/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java index cf3f479a..b6880f62 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/saving/DimDataProcessor.java @@ -1,30 +1,37 @@ package StevenDimDoors.mod_pocketDim.saving; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; -import StevenDimDoors.mod_pocketDim.Point3D; +import java.util.HashMap; +import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor; import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException; import StevenDimDoors.mod_pocketDim.util.JSONValidator; -import StevenDimDoors.mod_pocketDim.util.Point4D; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; public class DimDataProcessor extends BaseConfigurationProcessor { - private static final String JSON_SCHEMA_PATH = "/assets/dimdoors/text/Dim_Data_Schema.json"; + public final String JSON_VERSION_PROPERTY_NAME = "SAVE_DATA_VERSION_ID_INSTANCE"; + private HashMap SAVE_DATA_DEFINITIONS; private static final JsonParser jsonParser = new JsonParser(); + public static final String currentSaveVersionPath = "/assets/dimdoors/text/Dim_Data_Schema_v1-0-0.json"; + + //TODO dont load the schemas every time + public DimDataProcessor() + { + SAVE_DATA_DEFINITIONS = new HashMap(); + SAVE_DATA_DEFINITIONS.put(982405775, "/assets/dimdoors/text/Dim_Data_Schema_v982405775.json"); + SAVE_DATA_DEFINITIONS.put(PackedDimData.SAVE_DATA_VERSION_ID, currentSaveVersionPath); + + } @Override public PackedDimData readFromStream(InputStream inputStream) throws ConfigurationProcessingException @@ -58,38 +65,96 @@ public class DimDataProcessor extends BaseConfigurationProcessor try { //ensure our json object corresponds to our schema - validateJson(ele); + JSONValidator.validate(getSaveDataSchema(ele.getAsJsonObject()), ele); outputStream.write(ele.toString().getBytes("UTF-8")); outputStream.close(); } catch (Exception e) { // not sure if this is kosher, we need it to explode, but not by throwing the IO exception. - throw new ConfigurationProcessingException("Incorrectly formatted save data"); - } + throw new ConfigurationProcessingException("Could not access save data"); + } + } + public PackedDimData readDimDataJson(JsonReader reader) throws IOException { JsonElement ele = jsonParser.parse(reader); - this.validateJson(ele); + JsonObject schema = this.getSaveDataSchema(ele.getAsJsonObject()); + JSONValidator.validate(schema, ele); + ele = processSaveData(schema, ele.getAsJsonObject()); + GsonBuilder gsonBuilder = new GsonBuilder(); return gsonBuilder.create().fromJson(ele, PackedDimData.class); } /** - * checks our json against the dim data schema - * @param data + * Gets the schema that corresponds to a version of our save data + * @param obj * @return - * @throws IOException + * @throws IOException */ - public boolean validateJson(JsonElement data) throws IOException + public JsonObject getSaveDataSchema(JsonObject obj) { - InputStream in = this.getClass().getResourceAsStream(JSON_SCHEMA_PATH); + String schemaPath = this.SAVE_DATA_DEFINITIONS.get(obj.get(JSON_VERSION_PROPERTY_NAME).getAsInt()); + + if(schemaPath == null) + { + throw new IllegalStateException("Invalid save data version"); + } + InputStream in = this.getClass().getResourceAsStream(schemaPath); JsonReader reader = new JsonReader(new InputStreamReader(in)); - JSONValidator.validate((JsonObject) jsonParser.parse(reader), data); - reader.close(); - in.close(); - return true; + + JsonObject schema = jsonParser.parse(reader).getAsJsonObject(); + try + { + reader.close(); + in.close(); + } + catch (IOException e) + { + System.err.println("Could not load Json Save Data definitions"); + e.printStackTrace(); + throw new IllegalStateException("Could not load Json Save Data definitions"); + } + return schema; + } + + /** + * I use this method to update old save data files to the new format before actually loading them. + * @return + */ + public JsonObject processSaveData(JsonObject schema, JsonObject save) + { + if(save.get(JSON_VERSION_PROPERTY_NAME).getAsInt()== 982405775) + { + DimensionType type; + + //see if the dim is a pocket + if(save.get("RootID").getAsInt() != save.get("ID").getAsInt()) + { + if(save.get("IsDungeon").getAsBoolean()) + { + type = DimensionType.DUNGEON; + } + else + { + type = DimensionType.POCKET; + } + } + else + { + type = DimensionType.ROOT; + } + + save.remove("IsDungeon"); + save.addProperty("DimensionType",type.index); + save.remove(this.JSON_VERSION_PROPERTY_NAME); + save.addProperty(this.JSON_VERSION_PROPERTY_NAME, PackedDimData.SAVE_DATA_VERSION_ID); + } + + JSONValidator.validate(this.getSaveDataSchema(save), save); + return save; } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/saving/OldSaveImporter.java b/src/main/java/StevenDimDoors/mod_pocketDim/saving/OldSaveImporter.java index 13ae45a4..31940e88 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/saving/OldSaveImporter.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/saving/OldSaveImporter.java @@ -2,17 +2,16 @@ package StevenDimDoors.mod_pocketDim.saving; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; - import StevenDimDoors.mod_pocketDim.DimData; import StevenDimDoors.mod_pocketDim.LinkData; -import StevenDimDoors.mod_pocketDim.Point3D; - import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream; +import StevenDimDoors.mod_pocketDim.Point3D; +import StevenDimDoors.mod_pocketDim.core.DimensionType; +import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.util.Point4D; public class OldSaveImporter @@ -77,7 +76,7 @@ public class OldSaveImporter { Point4D source = new Point4D(link.locXCoord,link.locYCoord,link.locZCoord,link.locDimID); Point4D destintion = new Point4D(link.destXCoord,link.destYCoord,link.destZCoord,link.destDimID); - PackedLinkTail tail = new PackedLinkTail(destintion, link.linkOrientation); + PackedLinkTail tail = new PackedLinkTail(destintion, LinkType.NORMAL); List children = new ArrayList(); PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children, null); @@ -86,13 +85,30 @@ public class OldSaveImporter allPackedLinks.add(newPackedLink); } PackedDimData dim; + DimensionType type; + if(data.isPocket) { - dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, data.dungeonGenerator!=null, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null); + if(data.dungeonGenerator!=null) + { + type = DimensionType.DUNGEON; + } + else + { + type = DimensionType.POCKET; + } } else { - dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, data.dungeonGenerator!=null, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null); + type = DimensionType.ROOT; + } + if(data.isPocket) + { + dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null); + } + else + { + dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null); } newPackedDimData.put(dim.ID,dim); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java index 60a033d0..3a026b76 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedDimData.java @@ -3,14 +3,15 @@ package StevenDimDoors.mod_pocketDim.saving; import java.util.List; import StevenDimDoors.mod_pocketDim.Point3D; +import StevenDimDoors.mod_pocketDim.core.DimensionType; public class PackedDimData { // These fields will be public since this is a simple data container - public final static long SAVE_DATA_VERSION_ID = 982405775L; + public final static int SAVE_DATA_VERSION_ID = 100; public final long SAVE_DATA_VERSION_ID_INSTANCE = SAVE_DATA_VERSION_ID; public final int ID; - public final boolean IsDungeon; + public final int DimensionType; public final boolean IsFilled; public final int Depth; public final int PackDepth; @@ -26,7 +27,7 @@ public class PackedDimData // 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,PackedDungeonData dungeonData, Point3D origin, List childIDs, List links, + DimensionType type, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List childIDs, List links, List tails) { ID = id; @@ -35,7 +36,7 @@ public class PackedDimData ParentID = parentID; RootID = rootID; Orientation = orientation; - IsDungeon = isDungeon; + DimensionType = type.index; IsFilled = isFilled; DungeonData = dungeonData; Origin = origin; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java b/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java index 64c2466f..f5521c7e 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/saving/PackedLinkTail.java @@ -1,5 +1,6 @@ package StevenDimDoors.mod_pocketDim.saving; +import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.util.Point4D; public class PackedLinkTail @@ -7,10 +8,10 @@ public class PackedLinkTail public final Point4D destination; public final int linkType; - public PackedLinkTail(Point4D destination, int linkType) + public PackedLinkTail(Point4D destination, LinkType linkType) { this.destination=destination; - this.linkType=linkType; + this.linkType=linkType.index; } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java index c0df886c..666e28ca 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java @@ -3,37 +3,42 @@ package StevenDimDoors.mod_pocketDim.watcher; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; - +import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.NewDimData; public class ClientDimData { //We'll use public fields since this is just a data container and it's immutable public final int ID; - public final int RootID; + public final int rootID; + public final DimensionType type; - public ClientDimData(int id, int rootID) + public ClientDimData(int id, int rootID, DimensionType type) { ID = id; - RootID = rootID; + this.rootID = rootID; + this.type = type; } public ClientDimData(NewDimData dimension) { ID = dimension.id(); - RootID = dimension.root().id(); + this.rootID = dimension.root().id(); + this.type = dimension.getDimensionType(); } public void write(DataOutputStream output) throws IOException { output.writeInt(ID); - output.writeInt(RootID); + output.writeInt(rootID); + output.writeInt(type.index); } public static ClientDimData read(DataInputStream input) throws IOException { int id = input.readInt(); - int rootId = input.readInt(); - return new ClientDimData(id, rootId); + int rootID = input.readInt(); + int index = input.readInt(); + return new ClientDimData(id, rootID, DimensionType.getTypeFromIndex(index)); } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java index 9694c628..434b17df 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java @@ -5,33 +5,41 @@ import java.io.DataOutputStream; import java.io.IOException; import StevenDimDoors.mod_pocketDim.core.DDLock; import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.util.Point4D; public class ClientLinkData { - public Point4D point; - public DDLock lock; - + public final Point4D point; + public final DDLock lock; + public final LinkType type; + public ClientLinkData(DimLink link) { this.point = link.source(); + this.type = link.linkType(); if (link.hasLock()) { lock = link.getLock(); } + else + { + lock = null; + } } - public ClientLinkData(Point4D point, DDLock lock) + public ClientLinkData(Point4D point, LinkType type, DDLock lock) { this.point = point; this.lock = lock; + this.type = type; } public void write(DataOutputStream output) throws IOException { Point4D.write(point, output); - + output.write(this.type.index); boolean hasLock = this.lock != null; output.writeBoolean(hasLock); @@ -45,11 +53,12 @@ public class ClientLinkData public static ClientLinkData read(DataInputStream input) throws IOException { Point4D point = Point4D.read(input); + LinkType type = LinkType.getLinkTypeFromIndex(input.readInt()); DDLock lock = null; if (input.readBoolean()) { lock = new DDLock(input.readBoolean(), input.readInt()); } - return new ClientLinkData(point, lock); + return new ClientLinkData(point, type, lock); } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java index 6f6e356b..13bda158 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java @@ -14,6 +14,7 @@ import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.DimensionType; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; @@ -99,7 +100,7 @@ public class PocketBuilder // Register a new dimension NewDimData parent = PocketManager.getDimensionData(link.source().getDimension()); - NewDimData dimension = PocketManager.registerPocket(parent, true); + NewDimData dimension = PocketManager.registerPocket(parent, DimensionType.DUNGEON); //Load a world World world = PocketManager.loadDimension(dimension.id()); @@ -142,7 +143,7 @@ public class PocketBuilder DungeonSchematic schematic = pair.getSecond(); //Register a new dimension - NewDimData dimension = PocketManager.registerPocket(parent, true); + NewDimData dimension = PocketManager.registerPocket(parent, DimensionType.DUNGEON); //Load a world World world = PocketManager.loadDimension(dimension.id()); @@ -248,9 +249,9 @@ public class PocketBuilder schematic.getLength() <= DungeonHelper.MAX_DUNGEON_LENGTH); } - public static boolean generateNewPocket(DimLink link, DDProperties properties, Block door) + public static boolean generateNewPocket(DimLink link, DDProperties properties, Block door, DimensionType type) { - return generateNewPocket(link, DEFAULT_POCKET_SIZE, DEFAULT_POCKET_WALL_THICKNESS, properties, door); + return generateNewPocket(link, DEFAULT_POCKET_SIZE, DEFAULT_POCKET_WALL_THICKNESS, properties, door, type); } private static int getDoorOrientation(Point4D source, DDProperties properties) @@ -373,7 +374,7 @@ public class PocketBuilder } } - public static boolean generateNewPocket(DimLink link, int size, int wallThickness, DDProperties properties, Block door) + public static boolean generateNewPocket(DimLink link, int size, int wallThickness, DDProperties properties, Block door, DimensionType type) { validatePocketSetup(link, size, wallThickness, properties, door); @@ -381,7 +382,7 @@ public class PocketBuilder { //Register a new dimension NewDimData parent = PocketManager.getDimensionData(link.source().getDimension()); - NewDimData dimension = PocketManager.registerPocket(parent, false); + NewDimData dimension = PocketManager.registerPocket(parent, type); //Load a world diff --git a/src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v1-0-0.json b/src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v1-0-0.json new file mode 100644 index 00000000..cd2d416a --- /dev/null +++ b/src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v1-0-0.json @@ -0,0 +1,229 @@ +{ + "type":"object", + "$schema": "http://json-schema.org/draft-04/schema", + + "description": "A serialized Dim Data object", + "properties":{ + "ChildIDs": { + "type":"array", + "items": { + "type": "number" + } + }, + "Depth": { + "type":"number" + }, + "ID": { + "type":"number" + }, + "DimensionType": { + "type":"number" + }, + "IsFilled": { + "type":"boolean" + }, + "DungeonData": { + "type": "object", + + "properties": { + "Weight": { + "type": "number" + }, + "IsOpen": { + "type": "boolean" + }, + "IsInternal": { + "type": "boolean" + }, + "SchematicPath": { + "type": "string" + }, + "SchematicName": { + "type": "string" + }, + "DungeonTypeName": { + "type": "string" + }, + "DungeonPackName": { + "type": "string" + } + }, + "required": [ + "Weight", + "IsOpen", + "IsInternal", + "SchematicPath", + "SchematicName", + "DungeonTypeName", + "DungeonPackName" + ] + }, + "Links": { + "type":"array", + "items": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items":{ + "type": "number" + } + }, + "orientation": { + "type": "number" + }, + "source": { + "type": "object", + "properties": { + "x": { + "type": "integer" + }, + "y": { + "type": "integer" + }, + "z": { + "type": "integer" + }, + "dimension": { + "type": "integer" + } + }, + "required": [ + "x", + "y", + "z", + "dimension" + ] + }, + "parent": { + "type": "object", + "properties": { + "x": { + "type": "integer" + }, + "y": { + "type": "integer" + }, + "z": { + "type": "integer" + } + }, + "required": [ + "x", + "y", + "z" + ] + }, + "tail": { + "type": "object", + "properties": { + "linkType" : { + "type": "number" + }, + "destination":{ + "type": "object", + "properties": { + "x": { + "type": "integer" + }, + "y": { + "type": "integer" + }, + "z": { + "type": "integer" + }, + "dimension": { + "type": "integer" + } + }, + "required": [ + "x", + "y", + "z", + "dimension" + ] + } + }, + "required": [ + "linkType" + ] + }, + "lock":{ + "type": "object", + "properties": { + "lockState": { + "type": "boolean" + }, + "lockKey": { + "type": "number" + } + }, + "required": [ + "lockState", + "lockKey" + ] + + } + }, + "required": [ + "children", + "orientation", + "source", + "parent", + "tail" + ] + } + }, + "Orientation": { + "type":"number" + }, + "Origin": { + "type":"object", + "properties":{ + "x": { + "type":"number" + }, + "y": { + "type":"number" + }, + "z": { + "type":"number" + } + }, + "required": [ + "x", + "y", + "z" + ] + }, + "PackDepth": { + "type":"number" + }, + "ParentID": { + "type":"number" + }, + "RootID": { + "type":"number" + }, + "SAVE_DATA_VERSION_ID_INSTANCE": { + "type":"number" + }, + "Tails": { + "type":"array" + } + }, + "required": ["Tails", + "SAVE_DATA_VERSION_ID_INSTANCE", + "RootID", + "ParentID", + "PackDepth", + "Origin", + "Orientation", + "Links", + "IsFilled", + "ID", + "DimensionType", + "Depth", + "ChildIDs" + ] +} diff --git a/src/main/resources/assets/dimdoors/text/Dim_Data_Schema.json b/src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v982405775.json similarity index 98% rename from src/main/resources/assets/dimdoors/text/Dim_Data_Schema.json rename to src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v982405775.json index 33d503d6..84d8cd3a 100644 --- a/src/main/resources/assets/dimdoors/text/Dim_Data_Schema.json +++ b/src/main/resources/assets/dimdoors/text/Dim_Data_Schema_v982405775.json @@ -19,9 +19,6 @@ "IsDungeon": { "type":"boolean" }, - "PocketType": { - "type":"number" - }, "IsFilled": { "type":"boolean" }, @@ -224,8 +221,8 @@ "Orientation", "Links", "IsFilled", - "IsDungeon", "ID", + "IsDungeon", "Depth", "ChildIDs" ]