From 955600e7eff46a85b50641af6cbe562ec6864255 Mon Sep 17 00:00:00 2001 From: SpaceToad Date: Mon, 3 Mar 2014 20:49:35 +0100 Subject: [PATCH] fixed serialization of blueprint for the library --- .../buildcraft/api/blueprints/BptBlock.java | 4 +- .../api/blueprints/MappingRegistry.java | 15 +++- common/buildcraft/builders/TileBuilder.java | 19 +++-- .../core/blueprints/BlueprintBase.java | 8 +- .../core/blueprints/BptBuilderBase.java | 2 +- .../network/serializers/ClassMapping.java | 14 +++- .../serializers/SerializerHashMap.java | 65 +++++++++++++++ .../serializers/SerializerInteger.java | 26 ++++++ .../network/serializers/SerializerItem.java | 36 +++++++++ .../network/serializers/SerializerObject.java | 81 +++++++++++++++++++ .../transport/blueprints/BptBlockPipe.java | 7 +- 11 files changed, 250 insertions(+), 27 deletions(-) create mode 100755 common/buildcraft/core/network/serializers/SerializerHashMap.java create mode 100755 common/buildcraft/core/network/serializers/SerializerInteger.java create mode 100755 common/buildcraft/core/network/serializers/SerializerItem.java create mode 100755 common/buildcraft/core/network/serializers/SerializerObject.java diff --git a/common/buildcraft/api/blueprints/BptBlock.java b/common/buildcraft/api/blueprints/BptBlock.java index 772e8239..033a3aca 100644 --- a/common/buildcraft/api/blueprints/BptBlock.java +++ b/common/buildcraft/api/blueprints/BptBlock.java @@ -146,8 +146,8 @@ public class BptBlock { */ public void buildBlock(BptSlotInfo slot, IBptContext context) { // Meta needs to be specified twice, depending on the block behavior - context.world().setBlock(slot.x, slot.y, slot.z, slot.block, slot.meta, 0); - context.world().setBlockMetadataWithNotify(slot.x, slot.y, slot.z, slot.meta,3); + context.world().setBlock(slot.x, slot.y, slot.z, slot.block, slot.meta, 3); + //context.world().setBlockMetadataWithNotify(slot.x, slot.y, slot.z, slot.meta, 3); if (slot.block instanceof BlockContainer) { TileEntity tile = context.world().getTileEntity(slot.x, slot.y, slot.z); diff --git a/common/buildcraft/api/blueprints/MappingRegistry.java b/common/buildcraft/api/blueprints/MappingRegistry.java index 4e4115f3..20b78946 100755 --- a/common/buildcraft/api/blueprints/MappingRegistry.java +++ b/common/buildcraft/api/blueprints/MappingRegistry.java @@ -15,15 +15,22 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import buildcraft.core.network.NetworkData; import buildcraft.core.utils.Utils; public class MappingRegistry { - private HashMap blockToId = new HashMap(); - private ArrayList idToBlock = new ArrayList(); + @NetworkData + public HashMap blockToId = new HashMap(); - private HashMap itemToId = new HashMap(); - private ArrayList idToItem = new ArrayList(); + @NetworkData + public ArrayList idToBlock = new ArrayList(); + + @NetworkData + public HashMap itemToId = new HashMap(); + + @NetworkData + public ArrayList idToItem = new ArrayList(); private void registerItem (Item item) { if (!itemToId.containsKey(item)) { diff --git a/common/buildcraft/builders/TileBuilder.java b/common/buildcraft/builders/TileBuilder.java index 1f10ffaf..00b8c267 100644 --- a/common/buildcraft/builders/TileBuilder.java +++ b/common/buildcraft/builders/TileBuilder.java @@ -20,7 +20,6 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.BuildCraftBuilders; -import buildcraft.api.blueprints.IBptContext; import buildcraft.api.gates.IAction; import buildcraft.api.power.IPowerReceptor; import buildcraft.api.power.PowerHandler; @@ -284,8 +283,6 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, result = null; } - debugForceBlueprintCompletion(result, context); - return result; } @@ -560,6 +557,10 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, builderRobot.setDead(); builderRobot = null; } + + if (!worldObj.isRemote) { + debugForceBlueprintCompletion(); + } } @Override @@ -634,15 +635,13 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, return powerHandler.getPowerReceiver(); } - public void debugForceBlueprintCompletion (BptBuilderBase builder, IBptContext context) { - while (true) { - BptSlot slot = builder.getNextBlock(worldObj, this); + public void debugForceBlueprintCompletion () { + if (bluePrintBuilder != null) { + BptSlot slot = bluePrintBuilder.getNextBlock(worldObj, this); - if (slot == null) { - break; + if (slot != null) { + slot.buildBlock(bluePrintBuilder.context); } - - slot.buildBlock(context); } } diff --git a/common/buildcraft/core/blueprints/BlueprintBase.java b/common/buildcraft/core/blueprints/BlueprintBase.java index dd920467..109fadef 100644 --- a/common/buildcraft/core/blueprints/BlueprintBase.java +++ b/common/buildcraft/core/blueprints/BlueprintBase.java @@ -38,9 +38,8 @@ public abstract class BlueprintBase { @NetworkData public String version = ""; - // This should not need to be synchronized over the network - the - // information deduced from it are on the contents nbt - protected MappingRegistry mapping = new MappingRegistry(); + @NetworkData + public MappingRegistry mapping = new MappingRegistry(); public BlueprintBase() { } @@ -238,10 +237,11 @@ public abstract class BlueprintBase { for (int x = 0; x < sizeX; ++x) { for (int y = 0; y < sizeY; ++y) { - for (int z = 0; z < sizeZ; ++z) + for (int z = 0; z < sizeZ; ++z) { if (contents[x][y][z] != null) { res.contents[x][y][z] = contents[x][y][z].clone(); } + } } } diff --git a/common/buildcraft/core/blueprints/BptBuilderBase.java b/common/buildcraft/core/blueprints/BptBuilderBase.java index a9bfcc15..ca62eb23 100644 --- a/common/buildcraft/core/blueprints/BptBuilderBase.java +++ b/common/buildcraft/core/blueprints/BptBuilderBase.java @@ -19,7 +19,7 @@ public abstract class BptBuilderBase implements IAreaProvider { public BlueprintBase blueprint; int x, y, z; public boolean done; - protected BptContext context; + public BptContext context; public BptBuilderBase(BlueprintBase bluePrint, World world, int x, int y, int z) { this.blueprint = bluePrint; diff --git a/common/buildcraft/core/network/serializers/ClassMapping.java b/common/buildcraft/core/network/serializers/ClassMapping.java index e985421d..049b1daf 100644 --- a/common/buildcraft/core/network/serializers/ClassMapping.java +++ b/common/buildcraft/core/network/serializers/ClassMapping.java @@ -14,11 +14,13 @@ import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.TreeMap; import net.minecraft.block.Block; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import buildcraft.core.network.NetworkData; @@ -62,7 +64,7 @@ import buildcraft.core.utils.Utils; */ public class ClassMapping extends ClassSerializer { - private static SerializationObject anonymousSerializer = new SerializationObject(); + private static SerializerObject anonymousSerializer = new SerializerObject(); private LinkedList floatFields = new LinkedList(); private LinkedList doubleFields = new LinkedList(); @@ -71,6 +73,7 @@ public class ClassMapping extends ClassSerializer { private LinkedList booleanFields = new LinkedList(); private LinkedList enumFields = new LinkedList(); + // TODO: Make a specific serializer for this one private LinkedList arrayListFields = new LinkedList(); class FieldObject { @@ -616,7 +619,11 @@ public class ClassMapping extends ClassSerializer { public static ClassSerializer get (Class clas) { ClassSerializer mapping; - if (!classes.containsKey(clas.getCanonicalName())) { + if (Block.class.isAssignableFrom(clas)) { + mapping = classes.get(Block.class.getCanonicalName()); + } else if (Item.class.isAssignableFrom(clas)) { + mapping = classes.get(Item.class.getCanonicalName()); + } else if (!classes.containsKey(clas.getCanonicalName())) { mapping = new ClassMapping (); registerSerializer(clas, mapping); ((ClassMapping) mapping).analyzeClass(clas); @@ -629,8 +636,11 @@ public class ClassMapping extends ClassSerializer { static { registerSerializer(String.class, new SerializerString()); + registerSerializer(HashMap.class, new SerializerHashMap()); registerSerializer(Block.class, new SerializerBlock()); + registerSerializer(Item.class, new SerializerItem()); registerSerializer(NBTTagCompound.class, new SerializerNBT()); registerSerializer(ItemStack.class, new SerializerItemStack()); + registerSerializer(Integer.class, new SerializerInteger()); } } diff --git a/common/buildcraft/core/network/serializers/SerializerHashMap.java b/common/buildcraft/core/network/serializers/SerializerHashMap.java new file mode 100755 index 00000000..a01f723b --- /dev/null +++ b/common/buildcraft/core/network/serializers/SerializerHashMap.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team + * http://www.mod-buildcraft.com + * + * BuildCraft is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://www.mod-buildcraft.com/MMPL-1.0.txt + */ +package buildcraft.core.network.serializers; + +import io.netty.buffer.ByteBuf; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class SerializerHashMap extends ClassSerializer { + + private static SerializerObject anonymousSerializer = new SerializerObject(); + + @Override + public void write(ByteBuf data, Object o, SerializationContext context) + throws IllegalArgumentException, IllegalAccessException { + + HashMap map = (HashMap) o; + + if (o == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeShort(map.size()); + + Set s = map.entrySet(); + + for (Map.Entry e : s) { + anonymousSerializer.write(data, e.getKey(), context); + anonymousSerializer.write(data, e.getValue(), context); + } + } + } + + @Override + public Object read(ByteBuf data, Object o, SerializationContext context) + throws IllegalArgumentException, IllegalAccessException, + InstantiationException, ClassNotFoundException { + + if (!data.readBoolean()) { + return null; + } else { + int size = data.readShort(); + + HashMap map = new HashMap (); + + for (int i = 0; i < size; ++i) { + Object key = anonymousSerializer.read(data, null, context); + Object value = anonymousSerializer.read(data, null, context); + + map.put(key, value); + } + + return map; + } + } + +} diff --git a/common/buildcraft/core/network/serializers/SerializerInteger.java b/common/buildcraft/core/network/serializers/SerializerInteger.java new file mode 100755 index 00000000..c7e6cdde --- /dev/null +++ b/common/buildcraft/core/network/serializers/SerializerInteger.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team + * http://www.mod-buildcraft.com + * + * BuildCraft is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://www.mod-buildcraft.com/MMPL-1.0.txt + */ +package buildcraft.core.network.serializers; + +import io.netty.buffer.ByteBuf; + +public class SerializerInteger extends ClassSerializer { + + @Override + public void write (ByteBuf data, Object o, SerializationContext context) { + Integer i = (Integer) o; + + data.writeInt(i); + } + + @Override + public Object read (ByteBuf data, Object o, SerializationContext context) { + return new Integer(data.readInt()); + } +} diff --git a/common/buildcraft/core/network/serializers/SerializerItem.java b/common/buildcraft/core/network/serializers/SerializerItem.java new file mode 100755 index 00000000..842be608 --- /dev/null +++ b/common/buildcraft/core/network/serializers/SerializerItem.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team + * http://www.mod-buildcraft.com + * + * BuildCraft is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://www.mod-buildcraft.com/MMPL-1.0.txt + */ +package buildcraft.core.network.serializers; + +import io.netty.buffer.ByteBuf; +import net.minecraft.item.Item; + +public class SerializerItem extends ClassSerializer { + + @Override + public void write (ByteBuf data, Object o, SerializationContext context) { + Item i = (Item) o; + + if (i == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeInt(Item.getIdFromItem(i)); + } + } + + @Override + public Object read (ByteBuf data, Object o, SerializationContext context) { + if (!data.readBoolean()) { + return null; + } else { + return Item.getItemById(data.readInt()); + } + } +} diff --git a/common/buildcraft/core/network/serializers/SerializerObject.java b/common/buildcraft/core/network/serializers/SerializerObject.java new file mode 100755 index 00000000..0003e3e3 --- /dev/null +++ b/common/buildcraft/core/network/serializers/SerializerObject.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team + * http://www.mod-buildcraft.com + * + * BuildCraft is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://www.mod-buildcraft.com/MMPL-1.0.txt + */ +package buildcraft.core.network.serializers; + +import io.netty.buffer.ByteBuf; +import buildcraft.core.utils.Utils; + +public class SerializerObject extends ClassSerializer { + + @Override + public void write(ByteBuf data, Object o, SerializationContext context) + throws IllegalArgumentException, IllegalAccessException { + + if (o == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + Class realClass = o.getClass(); + + ClassSerializer delegateMapping; + + if (context.classToId.containsKey(realClass.getCanonicalName())) { + int index = context.classToId.get(realClass.getCanonicalName()) + 1; + data.writeByte(index); + delegateMapping = context.idToClass.get(index - 1); + } else { + int index = context.classToId.size() + 1; + delegateMapping = ClassMapping.get(realClass); + data.writeByte(index); + Utils.writeUTF(data, realClass.getCanonicalName()); + context.classToId.put(realClass.getCanonicalName(), + context.classToId.size()); + context.idToClass.add(delegateMapping); + } + + if (delegateMapping instanceof ClassMapping) { + ((ClassMapping) delegateMapping).writeClass(o, data, context); + } else { + delegateMapping.write(data, o, context); + } + } + } + + @Override + public Object read(ByteBuf data, Object o, SerializationContext context) + throws IllegalArgumentException, IllegalAccessException, + InstantiationException, ClassNotFoundException { + + if (!data.readBoolean()) { + return null; + } else { + int index = data.readByte(); + + ClassSerializer delegateMapping; + + if (context.idToClass.size() < index) { + String className = Utils.readUTF(data); + + Class cls = Class.forName(className); + delegateMapping = ClassMapping.get(cls); + + context.idToClass.add(ClassMapping.get(cls)); + } else { + delegateMapping = context.idToClass.get(index - 1); + } + + if (delegateMapping instanceof ClassMapping) { + return ((ClassMapping) delegateMapping).readClass(o, data, context); + } else { + return delegateMapping.read(data, o, context); + } + } + } + +} diff --git a/common/buildcraft/transport/blueprints/BptBlockPipe.java b/common/buildcraft/transport/blueprints/BptBlockPipe.java index 28c8a080..04f3b84a 100644 --- a/common/buildcraft/transport/blueprints/BptBlockPipe.java +++ b/common/buildcraft/transport/blueprints/BptBlockPipe.java @@ -41,8 +41,8 @@ public class BptBlockPipe extends BptBlock { Pipe pipe = BlockGenericPipe.getPipe(context.world(), slot.x, slot.y, slot.z); if (BlockGenericPipe.isValid(pipe)) { - return pipe.item == Item.itemRegistry.getObjectById(slot.cpt - .getInteger("pipeId")); + return pipe.item == context.getMappingRegistry().getItemForId( + slot.cpt.getInteger("pipeId")); } else { return false; } @@ -73,8 +73,7 @@ public class BptBlockPipe extends BptBlock { Item.getIdFromItem(context.getMappingRegistry().getItemForId( slot.cpt.getInteger("pipeId")))); - context.world().setBlock(slot.x, slot.y, slot.z, slot.block); - context.world().setBlockMetadataWithNotify(slot.x, slot.y, slot.z, slot.meta, 0); + context.world().setBlock(slot.x, slot.y, slot.z, slot.block, slot.meta, 3); TileEntity tile = context.world().getTileEntity(slot.x, slot.y, slot.z); tile.readFromNBT(slot.cpt);