diff --git a/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java b/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java index 5e19068ac..97416ce90 100644 --- a/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java +++ b/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java @@ -25,7 +25,7 @@ import appeng.api.storage.ISpatialDimension; import appeng.api.util.WorldCoord; import appeng.core.AELog; import appeng.core.localization.GuiText; -import appeng.core.worlddata.SpatialDimensionManager; +import appeng.spatial.SpatialDimensionManager; import appeng.items.AEBaseItem; import appeng.spatial.StorageHelper; import net.minecraft.client.util.ITooltipFlag; diff --git a/src/main/java/appeng/spatial/SpatialDimensionExtraData.java b/src/main/java/appeng/spatial/SpatialDimensionExtraData.java new file mode 100644 index 000000000..712b2d15f --- /dev/null +++ b/src/main/java/appeng/spatial/SpatialDimensionExtraData.java @@ -0,0 +1,45 @@ +package appeng.spatial; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; + +import javax.annotation.Nullable; + +/** + * Helps with encoding and decoding the extra data we attach to the + * spatial {@link net.minecraft.world.dimension.DimensionType} as "extra data". + * Keep in mind this data will also be sent to the client unless + * {@link net.minecraftforge.common.ModDimension#write(PacketBuffer, boolean)} is overridden. + */ +public final class SpatialDimensionExtraData { + + private static final int FORMAT_VERSION = 1; + private static final int OFFSET_VERSION = 0; + private static final int OFFSET_CONTENT_SIZE = 1; + + private SpatialDimensionExtraData() { + } + + public static PacketBuffer create(BlockPos contentSize) { + PacketBuffer extraData = new PacketBuffer(Unpooled.buffer()); + extraData.writeByte(FORMAT_VERSION); + extraData.writeBlockPos(contentSize); + // Cut the buffer to minimal size + extraData.capacity(extraData.writerIndex()); + return extraData; + } + + private static boolean checkVersion(PacketBuffer data){ + return data.getByte(OFFSET_VERSION) == FORMAT_VERSION; + } + + public static BlockPos getContentSize(@Nullable PacketBuffer data) { + if (data == null || !checkVersion(data)) { + return BlockPos.ZERO; + } + + data.readerIndex(OFFSET_CONTENT_SIZE); + return data.readBlockPos(); + } +} diff --git a/src/main/java/appeng/core/worlddata/SpatialDimensionManager.java b/src/main/java/appeng/spatial/SpatialDimensionManager.java similarity index 90% rename from src/main/java/appeng/core/worlddata/SpatialDimensionManager.java rename to src/main/java/appeng/spatial/SpatialDimensionManager.java index c6b252c97..15c440fa6 100644 --- a/src/main/java/appeng/core/worlddata/SpatialDimensionManager.java +++ b/src/main/java/appeng/spatial/SpatialDimensionManager.java @@ -16,15 +16,12 @@ * along with Applied Energistics 2. If not, see . */ -package appeng.core.worlddata; +package appeng.spatial; import appeng.api.storage.ISpatialDimension; import appeng.core.AELog; import appeng.core.AppEng; -import appeng.spatial.StorageCellDimension; -import appeng.spatial.StorageCellModDimension; -import io.netty.buffer.Unpooled; import net.minecraft.network.PacketBuffer; import net.minecraft.server.MinecraftServer; import net.minecraft.util.ResourceLocation; @@ -51,8 +48,7 @@ public class SpatialDimensionManager implements ISpatialDimension ResourceLocation dimKey = findFreeDimensionId(); AELog.info("Allocating storage cell dimension '%s' for %d", dimKey); - PacketBuffer extraData = new PacketBuffer(Unpooled.buffer()); - extraData.writeBlockPos(contentSize); + PacketBuffer extraData = SpatialDimensionExtraData.create(contentSize); return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true); } @@ -100,10 +96,6 @@ public class SpatialDimensionManager implements ISpatialDimension DimensionManager.unregisterDimension(cellDim.getId()); } - private static MinecraftServer getServer() { - return ServerLifecycleHooks.getCurrentServer(); - } - @Override public boolean isCellDimension( DimensionType cellDim ) { @@ -128,12 +120,11 @@ public class SpatialDimensionManager implements ISpatialDimension return BlockPos.ZERO; } - PacketBuffer data = cellDim.getData(); - if (data == null) { - return BlockPos.ZERO; - } - data.readerIndex(4); - return data.readBlockPos(); + return SpatialDimensionExtraData.getContentSize(cellDim.getData()); + } + + private static MinecraftServer getServer() { + return ServerLifecycleHooks.getCurrentServer(); } } diff --git a/src/main/java/appeng/spatial/StorageCellDimension.java b/src/main/java/appeng/spatial/StorageCellDimension.java index f1775d4b5..4f65a3058 100644 --- a/src/main/java/appeng/spatial/StorageCellDimension.java +++ b/src/main/java/appeng/spatial/StorageCellDimension.java @@ -43,7 +43,7 @@ public class StorageCellDimension extends Dimension // A region file is 512x512 blocks (32x32 chunks), // to avoid creating the 4 regions around 0,0,0, // we move the origin to the middle of region 0,0 - public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 61, 512 / 2); + public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 64, 512 / 2); public StorageCellDimension(World world, DimensionType dimensionType) { // FIXME: check light value diff --git a/src/test/java/appeng/core/worlddata/SpatialDimensionExtraDataTest.java b/src/test/java/appeng/core/worlddata/SpatialDimensionExtraDataTest.java new file mode 100644 index 000000000..19da64f56 --- /dev/null +++ b/src/test/java/appeng/core/worlddata/SpatialDimensionExtraDataTest.java @@ -0,0 +1,47 @@ +package appeng.core.worlddata; + +import appeng.spatial.SpatialDimensionExtraData; +import io.netty.buffer.Unpooled; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class SpatialDimensionExtraDataTest { + + /** + * The returned buffer should have just the right capacity. + */ + @Test + public void testCreatedBufferSize() { + PacketBuffer buffer = SpatialDimensionExtraData.create(BlockPos.ZERO); + assertEquals(9, buffer.array().length); + } + + @Test + public void testReadWriteSize() { + BlockPos pos = new BlockPos(1, 2, 3); + PacketBuffer buffer = SpatialDimensionExtraData.create(pos); + + PacketBuffer readBackBuf = new PacketBuffer(Unpooled.wrappedBuffer(buffer.array())); + BlockPos actualPos = SpatialDimensionExtraData.getContentSize(readBackBuf); + assertEquals(pos, actualPos); + } + + /** + * Gracefully handle format version errors. + */ + @Test + public void testHandleInvalidFormatVersion() { + BlockPos pos = new BlockPos(1, 2, 3); + PacketBuffer buffer = SpatialDimensionExtraData.create(pos); + buffer.writerIndex(0); + buffer.writeByte(5); + + PacketBuffer readBackBuf = new PacketBuffer(Unpooled.wrappedBuffer(buffer.array())); + BlockPos actualPos = SpatialDimensionExtraData.getContentSize(readBackBuf); + assertEquals(BlockPos.ZERO, actualPos); + } + +} \ No newline at end of file