From 1596c5ffc5c0d25b896b26bc1cb474669fb3f306 Mon Sep 17 00:00:00 2001 From: SpaceToad Date: Tue, 7 Jan 2014 22:52:10 +0100 Subject: [PATCH] This patch is done in the context of TileLibrary synchronization and RPC implementation. Through the process of implementing RPC, a intrusive simplification in the network message system has been implemented, completely removing the use of PayloadArray. On top of that, ClassMapping is now much more flexible, and doesn't need to be provided with a static size anymore, making it closer to a suitable class for the needs of RPC message passing. The result of this simplification is also a slight optimization of message passing, where certain data needed to be passed over the network (for example on null objects) which is not needed anymore. With regards to the TileLibrary itself, the implementation is yet pretty basic, showcasing the use of RPC to retreive a list of strings computed on the server. --- common/buildcraft/BuildCraftBuilders.java | 6 +- common/buildcraft/BuildCraftCore.java | 4 - .../builders/BlockBlueprintLibrary.java | 5 +- .../builders/TileBlueprintLibrary.java | 55 +- common/buildcraft/builders/TileMarker.java | 8 +- .../builders/blueprints/BlueprintMeta.java | 21 +- .../builders/gui/GuiBlueprintLibrary.java | 38 +- .../buildcraft/builders/gui/GuiTemplate.java | 13 +- .../network/PacketHandlerBuilders.java | 52 +- .../builders/network/PacketLibraryAction.java | 30 -- common/buildcraft/core/ByteBuffer.java | 112 ---- common/buildcraft/core/TileBuildCraft.java | 12 +- .../buildcraft/core/network/ClassMapping.java | 507 ++++++------------ .../core/network/ClassSerializer.java | 23 + .../core/network/PacketHandler.java | 3 +- common/buildcraft/core/network/PacketIds.java | 3 +- .../core/network/PacketPayload.java | 20 +- .../core/network/PacketPayloadArrays.java | 111 ---- .../core/network/PacketPayloadStream.java | 11 +- .../buildcraft/core/network/PacketUpdate.java | 5 +- common/buildcraft/core/network/RPC.java | 6 +- .../buildcraft/core/network/RPCHandler.java | 9 +- common/buildcraft/core/network/RPCSide.java | 5 + .../core/network/TileNetworkData.java | 16 +- .../core/network/TilePacketWrapper.java | 139 ++--- .../transport/gui/ContainerGateInterface.java | 72 ++- 26 files changed, 438 insertions(+), 848 deletions(-) delete mode 100644 common/buildcraft/builders/network/PacketLibraryAction.java delete mode 100644 common/buildcraft/core/ByteBuffer.java create mode 100755 common/buildcraft/core/network/ClassSerializer.java delete mode 100644 common/buildcraft/core/network/PacketPayloadArrays.java create mode 100755 common/buildcraft/core/network/RPCSide.java diff --git a/common/buildcraft/BuildCraftBuilders.java b/common/buildcraft/BuildCraftBuilders.java index 5892aeba..113d587f 100644 --- a/common/buildcraft/BuildCraftBuilders.java +++ b/common/buildcraft/BuildCraftBuilders.java @@ -324,7 +324,7 @@ public class BuildCraftBuilders { new ItemStack(Item.dyePowder, 1, 0), 't', markerBlock, 'y', new ItemStack(Item.dyePowder, 1, 11), 'c', Block.workbench, 'g', BuildCraftCore.goldGearItem, 'C', Block.chest}); -// CoreProxy.proxy.addCraftingRecipe(new ItemStack(builderBlock, 1), new Object[]{"btb", "ycy", "gCg", 'b', + // CoreProxy.proxy.addCraftingRecipe(new ItemStack(builderBlock, 1), new Object[]{"btb", "ycy", "gCg", 'b', // new ItemStack(Item.dyePowder, 1, 0), 't', markerBlock, 'y', new ItemStack(Item.dyePowder, 1, 11), // 'c', Block.workbench, 'g', BuildCraftCore.diamondGearItem, 'C', Block.chest}); @@ -333,8 +333,8 @@ public class BuildCraftBuilders { // 'c', Block.workbench, 'g', BuildCraftCore.diamondGearItem, 'C', // new ItemStack(templateItem, 1)}); -// CoreProxy.proxy.addCraftingRecipe(new ItemStack(libraryBlock, 1), new Object[]{"bbb", "bBb", "bbb", 'b', -// new ItemStack(blueprintItem), 'B', Block.bookShelf}); + CoreProxy.proxy.addCraftingRecipe(new ItemStack(libraryBlock, 1), new Object[]{"bbb", "bBb", "bbb", 'b', + new ItemStack(blueprintItem), 'B', Block.bookShelf}); } @EventHandler diff --git a/common/buildcraft/BuildCraftCore.java b/common/buildcraft/BuildCraftCore.java index 26580b01..79be68b6 100644 --- a/common/buildcraft/BuildCraftCore.java +++ b/common/buildcraft/BuildCraftCore.java @@ -98,7 +98,6 @@ public class BuildCraftCore { public static RenderMode render = RenderMode.Full; public static boolean debugMode = false; public static boolean modifyWorld = false; - public static boolean trackNetworkUsage = false; public static boolean colorBlindMode = false; public static boolean dropBrokenBlocks = true; // Set to false to prevent the filler from dropping broken blocks. public static int itemLifespan = 1200; @@ -182,9 +181,6 @@ public class BuildCraftCore { continuousCurrent.comment = "set to true for allowing machines to be driven by continuous current"; continuousCurrentModel = continuousCurrent.getBoolean(DefaultProps.CURRENT_CONTINUOUS); - Property trackNetwork = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "trackNetworkUsage", false); - trackNetworkUsage = trackNetwork.getBoolean(false); - Property dropBlock = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "dropBrokenBlocks", true); dropBlock.comment = "set to false to prevent fillers from dropping blocks."; dropBrokenBlocks = dropBlock.getBoolean(true); diff --git a/common/buildcraft/builders/BlockBlueprintLibrary.java b/common/buildcraft/builders/BlockBlueprintLibrary.java index 10276562..befd2041 100644 --- a/common/buildcraft/builders/BlockBlueprintLibrary.java +++ b/common/buildcraft/builders/BlockBlueprintLibrary.java @@ -10,11 +10,14 @@ package buildcraft.builders; import buildcraft.BuildCraftBuilders; +import buildcraft.core.CreativeTabBuildCraft; import buildcraft.core.GuiIds; import buildcraft.core.proxy.CoreProxy; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; + import java.util.ArrayList; + import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IconRegister; @@ -32,7 +35,7 @@ public class BlockBlueprintLibrary extends BlockContainer { public BlockBlueprintLibrary(int i) { super(i, Material.wood); - //setCreativeTab(CreativeTabBuildCraft.MACHINES.get()); + setCreativeTab(CreativeTabBuildCraft.MACHINES.get()); setHardness(5F); } diff --git a/common/buildcraft/builders/TileBlueprintLibrary.java b/common/buildcraft/builders/TileBlueprintLibrary.java index 805d5323..d2c7b7cf 100644 --- a/common/buildcraft/builders/TileBlueprintLibrary.java +++ b/common/buildcraft/builders/TileBlueprintLibrary.java @@ -1,23 +1,36 @@ package buildcraft.builders; import buildcraft.BuildCraftBuilders; +import buildcraft.builders.blueprints.BlueprintMeta; import buildcraft.core.TileBuildCraft; import buildcraft.core.blueprints.BptBase; import buildcraft.core.blueprints.BptPlayerIndex; import buildcraft.core.inventory.InvUtils; +import buildcraft.core.network.RPC; +import buildcraft.core.network.RPCHandler; +import buildcraft.core.network.RPCMessageInfo; +import buildcraft.core.network.RPCSide; import buildcraft.core.network.TileNetworkData; import buildcraft.core.proxy.CoreProxy; import buildcraft.core.utils.Utils; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.LinkedList; + +import com.google.common.io.ByteStreams; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import paulscode.sound.Library; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; public class TileBlueprintLibrary extends TileBuildCraft implements IInventory { - public static final int COMMAND_NEXT = 1, COMMAND_PREV = 2, COMMAND_LOCK_UPDATE = 3, COMMAND_DELETE = 4; - public ItemStack[] stack = new ItemStack[4]; public int progressIn = 0; @@ -27,26 +40,18 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory { private ArrayList currentPage; - public @TileNetworkData(staticSize = BuildCraftBuilders.LIBRARY_PAGE_SIZE) - String[] currentNames = new String[BuildCraftBuilders.LIBRARY_PAGE_SIZE]; - public @TileNetworkData - int selected = -1; + public LinkedList currentBlueprint = new LinkedList (); - public @TileNetworkData + int selected = -1; boolean locked = false; public TileBlueprintLibrary() { - for (int i = 0; i < currentNames.length; i++) { - currentNames[i] = ""; - } + } @Override public void initialize() { super.initialize(); - if (CoreProxy.proxy.isSimulating(worldObj)) { - setCurrentPage(getNextPage(null)); - } } public ArrayList getNextPage(String after) { @@ -97,15 +102,25 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory { return result; } + @SideOnly (Side.CLIENT) public void updateCurrentNames() { - currentNames = new String[BuildCraftBuilders.LIBRARY_PAGE_SIZE]; - for (int i = 0; i < currentPage.size(); i++) { - currentNames[i] = currentPage.get(i).getName(); + currentBlueprint.clear(); + RPCHandler.rpcServer(this, "fetchPage", 1); + } + + @RPC (RPCSide.SERVER) + public void fetchPage (int pageId, RPCMessageInfo info) { + for (int i = 0; i < BuildCraftBuilders.LIBRARY_PAGE_SIZE; ++i) { + BlueprintMeta dummyMeta = new BlueprintMeta (); + dummyMeta.name = "Blueprint #" + i; + + RPCHandler.rpcPlayer(this, "receiveBlueprintMeta", info.sender, dummyMeta.name); } - for (int i = currentPage.size(); i < currentNames.length; i++) { - currentNames[i] = ""; - } - sendNetworkUpdate(); + } + + @RPC (RPCSide.CLIENT) + public void receiveBlueprintMeta (String meta) { + currentBlueprint.add(meta); } public ArrayList getCurrentPage() { diff --git a/common/buildcraft/builders/TileMarker.java b/common/buildcraft/builders/TileMarker.java index fe952079..e153b76f 100644 --- a/common/buildcraft/builders/TileMarker.java +++ b/common/buildcraft/builders/TileMarker.java @@ -1,8 +1,8 @@ -/** +/** * Copyright (c) SpaceToad, 2011 * http://www.mod-buildcraft.com - * - * BuildCraft is distributed under the terms of the Minecraft Mod Public + * + * 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 */ @@ -75,7 +75,7 @@ public class TileMarker extends TileBuildCraft implements IAreaProvider { public @TileNetworkData TileWrapper vectO = new TileWrapper(); - public @TileNetworkData(staticSize = 3) + public @TileNetworkData TileWrapper[] vect = { new TileWrapper(), new TileWrapper(), new TileWrapper() }; public @TileNetworkData int xMin, yMin, zMin, xMax, yMax, zMax; diff --git a/common/buildcraft/builders/blueprints/BlueprintMeta.java b/common/buildcraft/builders/blueprints/BlueprintMeta.java index 67c3e5d4..645ebe71 100644 --- a/common/buildcraft/builders/blueprints/BlueprintMeta.java +++ b/common/buildcraft/builders/blueprints/BlueprintMeta.java @@ -1,14 +1,25 @@ package buildcraft.builders.blueprints; +import buildcraft.core.network.TileNetworkData; import net.minecraft.nbt.NBTTagCompound; public class BlueprintMeta { - private final String version = "Blueprint-2.0"; - private BlueprintId id; - private String name; - private String creator; - protected BlueprintMeta() { + @TileNetworkData + public final String version = "Blueprint-2.0"; + + /** + * FIXME: The format of id is not completely supported yet. To improve... + */ + private BlueprintId id; + + @TileNetworkData + public String name; + + @TileNetworkData + public String creator; + + public BlueprintMeta() { } protected BlueprintMeta(BlueprintId id, NBTTagCompound nbt) { diff --git a/common/buildcraft/builders/gui/GuiBlueprintLibrary.java b/common/buildcraft/builders/gui/GuiBlueprintLibrary.java index 11f9be53..a63d45f2 100644 --- a/common/buildcraft/builders/gui/GuiBlueprintLibrary.java +++ b/common/buildcraft/builders/gui/GuiBlueprintLibrary.java @@ -9,23 +9,23 @@ package buildcraft.builders.gui; import buildcraft.BuildCraftBuilders; import buildcraft.builders.TileBlueprintLibrary; -import buildcraft.builders.network.PacketLibraryAction; +import buildcraft.builders.blueprints.BlueprintMeta; import buildcraft.core.DefaultProps; import buildcraft.core.blueprints.BptPlayerIndex; import buildcraft.core.gui.GuiBuildCraft; import buildcraft.core.network.PacketIds; import buildcraft.core.network.PacketPayload; -import buildcraft.core.network.PacketPayloadArrays; import buildcraft.core.proxy.CoreProxy; import buildcraft.core.utils.StringUtils; import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; + import org.lwjgl.opengl.GL11; public class GuiBlueprintLibrary extends GuiBuildCraft { - private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/template_gui.png"); + private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/library_r.png"); EntityPlayer player; TileBlueprintLibrary library; ContainerBlueprintLibrary container; @@ -42,6 +42,7 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { container = (ContainerBlueprintLibrary) inventorySlots; index = BuildCraftBuilders.getPlayerIndex(player.username); + library.updateCurrentNames(); } private GuiButton nextPageButton; private GuiButton prevPageButton; @@ -67,11 +68,11 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { lockButton = new GuiButton(3, j + 127, k + 114, 40, 20, StringUtils.localize("gui.lock")); buttonList.add(lockButton); - if (library.locked) { + /*if (library.locked) { lockButton.displayString = StringUtils.localize("gui.unlock"); } else { lockButton.displayString = StringUtils.localize("gui.lock"); - } + }*/ } @Override @@ -82,21 +83,20 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { fontRenderer.drawString(title, getCenteredOffset(title), 6, 0x404040); int c = 0; - String[] currentNames = library.currentNames; - for (int i = 0; i < currentNames.length; i++) { - String name = currentNames[i]; - if (name == null) { - break; - } + for (String bpt : library.currentBlueprint) { + //String name = currentNames[i]; + + String name = bpt; + if (name.length() > BuildCraftBuilders.MAX_BLUEPRINTS_NAME_SIZE) { name = name.substring(0, BuildCraftBuilders.MAX_BLUEPRINTS_NAME_SIZE); } - if (i == library.selected) { + /*if (i == library.selected) { int l1 = 8; int i2 = 24; drawGradientRect(l1, i2 + 9 * c, l1 + 88, i2 + 9 * (c + 1), 0x80ffffff, 0x80ffffff); - } + }*/ fontRenderer.drawString(name, 9, 25 + 9 * c, 0x404040); c++; @@ -121,16 +121,16 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { @Override public void updateScreen() { - if (library.locked) { + /*if (library.locked) { lockButton.displayString = StringUtils.localize("gui.unlock"); } else { lockButton.displayString = StringUtils.localize("gui.lock"); - } + }*/ } @Override protected void actionPerformed(GuiButton button) { - PacketLibraryAction packet = new PacketLibraryAction(PacketIds.LIBRARY_ACTION, library.xCoord, library.yCoord, library.zCoord); + /*PacketLibraryAction packet = new PacketLibraryAction(PacketIds.LIBRARY_ACTION, library.xCoord, library.yCoord, library.zCoord); if (button == nextPageButton) { packet.actionId = TileBlueprintLibrary.COMMAND_NEXT; } else if (button == prevPageButton) { @@ -140,7 +140,7 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { } else if (deleteButton != null && button == deleteButton) { packet.actionId = TileBlueprintLibrary.COMMAND_DELETE; } - CoreProxy.proxy.sendToServer(packet.getPacket()); + CoreProxy.proxy.sendToServer(packet.getPacket());*/ } @Override @@ -157,13 +157,13 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { int ySlot = (y - 24) / 9; if (ySlot >= 0 && ySlot <= 11) { - if (ySlot < library.currentNames.length) { + /*if (ySlot < library.currentNames.length) { PacketPayloadArrays payload = new PacketPayloadArrays(); payload.intPayload = new int[]{ySlot}; PacketLibraryAction packet = new PacketLibraryAction(PacketIds.LIBRARY_SELECT, library.xCoord, library.yCoord, library.zCoord); packet.actionId = ySlot; CoreProxy.proxy.sendToServer(packet.getPacket()); - } + }*/ } } } diff --git a/common/buildcraft/builders/gui/GuiTemplate.java b/common/buildcraft/builders/gui/GuiTemplate.java index a54f8f1b..680cf74e 100644 --- a/common/buildcraft/builders/gui/GuiTemplate.java +++ b/common/buildcraft/builders/gui/GuiTemplate.java @@ -12,13 +12,16 @@ import buildcraft.core.DefaultProps; import buildcraft.core.gui.GuiBuildCraft; import buildcraft.core.network.PacketIds; import buildcraft.core.network.PacketPayload; -import buildcraft.core.network.PacketPayloadArrays; +import buildcraft.core.network.PacketPayloadStream; import buildcraft.core.network.PacketUpdate; import buildcraft.core.proxy.CoreProxy; import buildcraft.core.utils.StringUtils; + import java.util.Date; + import net.minecraft.inventory.IInventory; import net.minecraft.util.ResourceLocation; + import org.lwjgl.opengl.GL11; public class GuiTemplate extends GuiBuildCraft { @@ -79,17 +82,19 @@ public class GuiTemplate extends GuiBuildCraft { @Override protected void keyTyped(char c, int i) { - if (i != 1 && editMode) { + // FIXME: Not much point to port this to stream payload at this stage, + // should use a RPC instead. + /*if (i != 1 && editMode) { if (c == 13) { editMode = false; return; } - PacketPayloadArrays payload = new PacketPayloadArrays(); + PacketPayloadStream payload = new PacketPayloadStream(); payload.intPayload = new int[]{c}; PacketUpdate packet = new PacketUpdate(PacketIds.ARCHITECT_NAME, template.xCoord, template.yCoord, template.zCoord, payload); CoreProxy.proxy.sendToServer(packet.getPacket()); } else { super.keyTyped(c, i); - } + }*/ } } diff --git a/common/buildcraft/builders/network/PacketHandlerBuilders.java b/common/buildcraft/builders/network/PacketHandlerBuilders.java index 56576f7b..a71483b7 100644 --- a/common/buildcraft/builders/network/PacketHandlerBuilders.java +++ b/common/buildcraft/builders/network/PacketHandlerBuilders.java @@ -3,7 +3,6 @@ package buildcraft.builders.network; import buildcraft.builders.TileArchitect; import buildcraft.builders.TileBlueprintLibrary; import buildcraft.core.network.PacketIds; -import buildcraft.core.network.PacketPayloadArrays; import buildcraft.core.network.PacketUpdate; import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.Player; @@ -23,21 +22,12 @@ public class PacketHandlerBuilders implements IPacketHandler { try { int packetID = data.read(); switch (packetID) { + // FIXME: Replace that by a RPC case PacketIds.ARCHITECT_NAME: PacketUpdate packetA = new PacketUpdate(); packetA.readData(data); onArchitectName((EntityPlayer) player, packetA); break; - case PacketIds.LIBRARY_ACTION: - PacketLibraryAction packetB = new PacketLibraryAction(); - packetB.readData(data); - onLibraryAction((EntityPlayer) player, packetB); - break; - case PacketIds.LIBRARY_SELECT: - PacketLibraryAction packetC = new PacketLibraryAction(); - packetC.readData(data); - onLibrarySelect((EntityPlayer) player, packetC); - break; } } catch (Exception ex) { ex.printStackTrace(); @@ -46,44 +36,12 @@ public class PacketHandlerBuilders implements IPacketHandler { } private void onArchitectName(EntityPlayer player, PacketUpdate packet) { - TileEntity te = player.worldObj.getBlockTileEntity(packet.posX, packet.posY, packet.posZ); + // FIXME: Not much point to port this to stream payload at this stage, + // should use a RPC instead. + /*TileEntity te = player.worldObj.getBlockTileEntity(packet.posX, packet.posY, packet.posZ); if (te instanceof TileArchitect) { ((TileArchitect) te).handleClientInput((char) ((PacketPayloadArrays)packet.payload).intPayload[0]); - } - } - - private void onLibraryAction(EntityPlayer player, PacketLibraryAction packet) { - TileEntity te = player.worldObj.getBlockTileEntity(packet.posX, packet.posY, packet.posZ); - if (te instanceof TileBlueprintLibrary) { - TileBlueprintLibrary tbl = (TileBlueprintLibrary) te; - switch (packet.actionId) { - case TileBlueprintLibrary.COMMAND_DELETE: - tbl.deleteSelectedBpt(); - break; - case TileBlueprintLibrary.COMMAND_LOCK_UPDATE: - tbl.locked = !tbl.locked; - tbl.sendNetworkUpdate(); - break; - case TileBlueprintLibrary.COMMAND_NEXT: - tbl.setCurrentPage(true); - break; - case TileBlueprintLibrary.COMMAND_PREV: - tbl.setCurrentPage(false); - break; - } - } - } - - private void onLibrarySelect(EntityPlayer player, PacketLibraryAction packet) { - TileEntity te = player.worldObj.getBlockTileEntity(packet.posX, packet.posY, packet.posZ); - if (te instanceof TileBlueprintLibrary) { - TileBlueprintLibrary tbl = (TileBlueprintLibrary) te; - int ySlot = packet.actionId; - if (ySlot < tbl.getCurrentPage().size()) { - tbl.selected = ySlot; - } - tbl.sendNetworkUpdate(); - } + }*/ } } diff --git a/common/buildcraft/builders/network/PacketLibraryAction.java b/common/buildcraft/builders/network/PacketLibraryAction.java deleted file mode 100644 index 5aa18491..00000000 --- a/common/buildcraft/builders/network/PacketLibraryAction.java +++ /dev/null @@ -1,30 +0,0 @@ -package buildcraft.builders.network; - -import buildcraft.core.network.PacketCoordinates; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -public class PacketLibraryAction extends PacketCoordinates { - - public int actionId; - - public PacketLibraryAction() { - } - - public PacketLibraryAction(int packetId, int x, int y, int z) { - super(packetId, x, y, z); - } - - @Override - public void writeData(DataOutputStream data) throws IOException { - data.writeInt(actionId); - super.writeData(data); - } - - @Override - public void readData(DataInputStream data) throws IOException { - actionId = data.readInt(); - super.readData(data); - } -} diff --git a/common/buildcraft/core/ByteBuffer.java b/common/buildcraft/core/ByteBuffer.java deleted file mode 100644 index 89784b58..00000000 --- a/common/buildcraft/core/ByteBuffer.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) SpaceToad, 2011 - * 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; - -import java.util.LinkedList; - -public class ByteBuffer { - - LinkedList bytes = new LinkedList(); - - public void writeUnsignedByte(int s) { - bytes.add(s - Byte.MAX_VALUE); - } - - public void writeUnsignedShort(int s) { - writeUnsignedByte(s & 0xFF); - writeUnsignedByte((s >> 8) & 0xFF); - } - - public void writeShort(short s) { - writeUnsignedByte(s & 0xFF); - writeUnsignedByte((s >> 8) & 0xFF); - } - - public void writeInt(int i) { - writeUnsignedByte(i & 0xFF); - writeUnsignedByte((i >> 8) & 0xFF); - writeUnsignedByte((i >> 16) & 0xFF); - writeUnsignedByte((i >> 24) & 0xFF); - } - - public short readUnsignedByte() { - short res = 0; - - if (bytes.size() == 0) - return res; - - res += (short) (bytes.removeFirst() + Byte.MAX_VALUE); - - return res; - } - - public int readUnsignedShort() { - int res = 0; - - if (bytes.size() == 0) - return res; - - res += readUnsignedByte(); - res += readUnsignedByte() << 8; - - return res; - } - - public short readShort() { - short res = 0; - - if (bytes.size() == 0) - return res; - - res += readUnsignedByte(); - res += readUnsignedByte() << 8; - - return res; - } - - public int readInt() { - int res = 0; - - if (bytes.size() == 0) - return res; - - res += readUnsignedByte(); - res += readUnsignedByte() << 8; - res += readUnsignedByte() << 16; - res += readUnsignedByte() << 24; - - return res; - } - - public int[] readIntArray() { - LinkedList ints = new LinkedList(); - - while (bytes.size() > 0) { - ints.add(readInt()); - } - - int[] res = new int[ints.size()]; - - int index = 0; - - for (Integer val : ints) { - res[index] = val; - index++; - } - - return res; - } - - public void writeIntArray(int[] arr) { - for (int i : arr) { - writeInt(i); - } - } -} diff --git a/common/buildcraft/core/TileBuildCraft.java b/common/buildcraft/core/TileBuildCraft.java index 773f46b7..43b7af47 100644 --- a/common/buildcraft/core/TileBuildCraft.java +++ b/common/buildcraft/core/TileBuildCraft.java @@ -10,15 +10,17 @@ package buildcraft.core; import buildcraft.api.power.IPowerReceptor; import buildcraft.core.network.ISynchronizedTile; import buildcraft.core.network.PacketPayload; -import buildcraft.core.network.PacketPayloadArrays; +import buildcraft.core.network.PacketPayloadStream; import buildcraft.core.network.PacketTileUpdate; import buildcraft.core.network.PacketUpdate; import buildcraft.core.network.TilePacketWrapper; import buildcraft.core.proxy.CoreProxy; import buildcraft.core.utils.Utils; + import java.io.IOException; import java.util.HashMap; import java.util.Map; + import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -110,14 +112,14 @@ public abstract class TileBuildCraft extends TileEntity implements ISynchronized @Override public void handleDescriptionPacket(PacketUpdate packet) throws IOException { - if (packet.payload instanceof PacketPayloadArrays) - descriptionPacket.fromPayload(this, (PacketPayloadArrays) packet.payload); + if (packet.payload instanceof PacketPayloadStream) + descriptionPacket.fromPayload(this, (PacketPayloadStream) packet.payload); } @Override public void handleUpdatePacket(PacketUpdate packet) throws IOException { - if (packet.payload instanceof PacketPayloadArrays) - updatePacket.fromPayload(this, (PacketPayloadArrays) packet.payload); + if (packet.payload instanceof PacketPayloadStream) + updatePacket.fromPayload(this, (PacketPayloadStream) packet.payload); } @Override diff --git a/common/buildcraft/core/network/ClassMapping.java b/common/buildcraft/core/network/ClassMapping.java index 5e1899ed..4c9c596c 100644 --- a/common/buildcraft/core/network/ClassMapping.java +++ b/common/buildcraft/core/network/ClassMapping.java @@ -10,45 +10,52 @@ package buildcraft.core.network; import buildcraft.BuildCraftCore; -import buildcraft.core.ByteBuffer; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.LinkedList; import java.util.TreeMap; +/** + * This class implements custom class mapping. There are three advantages in + * using a custom serializer here: + * + * (1) the approach is constructive instead of destructive, that is to say, + * only marked fields will be taken. Granted, this is mostly coding style + * related, but this prevent introduction of useless serialized data by + * mistake. + * + * (2) we can introduce specific serialized types. For example (although not + * yet implemented?) we will be able to implement a tile as a reference to + * this tile through e.g. {x, y, z}, that is know what needs to be serialized, + * know what needs to be referenced, and how to reference it. + * + * (3) again, not yet implemented, but we can in theory have different set + * of serialization depending on the context. + * + * HISTORY NOTE + * + * This was initially developed because the initial network framework only + * allowed for byte, float and int, so more things were needed. To the light + * of current understanding, using only byte would have been good enough. + * + * It seems like the three points above indeed give more value and safety to + * the whole code and make this system still relevant. To be re-evaluated. + * + * QUESTION ON OBJECTS + * + * At the moment, we do not support object creation from this interface, so + * the objects are supposed to be already there and then updated. This may + * not always make sense, in particular in the context of RPC + * + * Non-null arrays of objects are forbidden as well, and they need to be set + * to the same null and non-null elements on both sides. + * + */ public class ClassMapping { - - public static class Reporter { - - Class clas; - int occurences = 0; - int dataInt = 0; - int dataFloat = 0; - int dataString = 0; - int bytes = 0; - - @Override - public String toString() { - String res = clas + ": " + occurences + " times (" + dataInt + ", " + dataFloat + ", " + dataString + " = " + bytes + ")"; - - return res; - } - } - - private static TreeMap report = new TreeMap(); - - public static int report() { - int bytes = 0; - for (Reporter r : report.values()) { - System.out.println(r); - bytes += r.bytes; - } - - report.clear(); - - return bytes; - } - private LinkedList floatFields = new LinkedList(); private LinkedList doubleFields = new LinkedList(); private LinkedList stringFields = new LinkedList(); @@ -56,36 +63,19 @@ public class ClassMapping { private LinkedList intFields = new LinkedList(); private LinkedList booleanFields = new LinkedList(); private LinkedList enumFields = new LinkedList(); - private LinkedList unsignedByteFields = new LinkedList(); private LinkedList objectFields = new LinkedList(); private LinkedList doubleArrayFields = new LinkedList(); private LinkedList shortArrayFields = new LinkedList(); private LinkedList intArrayFields = new LinkedList(); private LinkedList booleanArrayFields = new LinkedList(); - private LinkedList unsignedByteArrayFields = new LinkedList(); private LinkedList stringArrayFields = new LinkedList(); private LinkedList objectArrayFields = new LinkedList(); - private int sizeBytes; - private int sizeFloat; - private int sizeString; - private Field field; private Class clas; - public static class Indexes { - - public Indexes(int initFloat, int initString) { - floatIndex = initFloat; - stringIndex = initString; - } - - int floatIndex = 0; - int stringIndex = 0; - } - @SuppressWarnings({ "rawtypes", "unchecked" }) public ClassMapping(final Class c) { clas = c; @@ -105,32 +95,18 @@ public class ClassMapping { Class fieldClass = (Class) t; if (fieldClass.equals(short.class)) { - sizeBytes += 2; shortFields.add(f); } else if (fieldClass.equals(int.class)) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); - - if (updateAnnotation.intKind() == TileNetworkData.UNSIGNED_BYTE) { - sizeBytes += 1; - unsignedByteFields.add(f); - } else { - sizeBytes += 4; - intFields.add(f); - } + intFields.add(f); } else if (fieldClass.equals(boolean.class)) { - sizeBytes += 1; booleanFields.add(f); } else if (Enum.class.isAssignableFrom(fieldClass)) { - sizeBytes += 1; enumFields.add(f); } else if (fieldClass.equals(String.class)) { - sizeString++; stringFields.add(f); } else if (fieldClass.equals(float.class)) { - sizeFloat++; floatFields.add(f); } else if (fieldClass.equals(double.class)) { - sizeFloat++; doubleFields.add(f); } else { // ADD SOME SAFETY HERE - if we're not child of Object @@ -139,44 +115,22 @@ public class ClassMapping { mapping.field = f; objectFields.add(mapping); - sizeBytes += 1; // to catch null / not null. - - sizeBytes += mapping.sizeBytes; - sizeFloat += mapping.sizeFloat; - sizeString += mapping.sizeString; } } + if (t instanceof Class && ((Class) t).isArray()) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); - - if (updateAnnotation.staticSize() == -1) - throw new RuntimeException("arrays must be provided with an explicit size"); - Class fieldClass = (Class) t; - Class cptClass = fieldClass.getComponentType(); if (cptClass.equals(double.class)) { - sizeFloat += updateAnnotation.staticSize(); doubleArrayFields.add(f); } else if (cptClass.equals(short.class)) { - sizeBytes += updateAnnotation.staticSize() * 2; shortArrayFields.add(f); } else if (cptClass.equals(int.class)) { - updateAnnotation = f.getAnnotation(TileNetworkData.class); - - if (updateAnnotation.intKind() == TileNetworkData.UNSIGNED_BYTE) { - sizeBytes += updateAnnotation.staticSize(); - unsignedByteArrayFields.add(f); - } else { - sizeBytes += updateAnnotation.staticSize() * 4; - intArrayFields.add(f); - } + intArrayFields.add(f); } else if (cptClass.equals(String.class)) { - sizeString += updateAnnotation.staticSize(); stringArrayFields.add(f); } else if (cptClass.equals(boolean.class)) { - sizeBytes += updateAnnotation.staticSize(); booleanArrayFields.add(f); } else { // ADD SOME SAFETY HERE - if we're not child of Object @@ -184,14 +138,6 @@ public class ClassMapping { ClassMapping mapping = new ClassMapping(cptClass); mapping.field = f; objectArrayFields.add(mapping); - - sizeBytes += updateAnnotation.staticSize(); // to catch - // null / - // not null. - - sizeBytes += updateAnnotation.staticSize() * mapping.sizeBytes; - sizeFloat += updateAnnotation.staticSize() * mapping.sizeFloat; - sizeString += updateAnnotation.staticSize() * mapping.sizeString; } } } @@ -208,157 +154,120 @@ public class ClassMapping { } @SuppressWarnings("rawtypes") - public void setData(Object obj, ByteBuffer byteBuffer, float[] floatValues, String[] stringValues, Indexes index) throws IllegalArgumentException, - IllegalAccessException { - - Reporter r = null; - - if (BuildCraftCore.trackNetworkUsage) { - if (!report.containsKey(clas.getName())) { - report.put(clas.getName(), new Reporter()); - } - - r = report.get(clas.getName()); - r.clas = clas; - } else { - r = new Reporter(); - } - - r.occurences++; + public void setData(Object obj, DataOutputStream data) throws IllegalArgumentException, + IllegalAccessException, IOException { for (Field f : shortFields) { - byteBuffer.writeShort(f.getShort(obj)); - r.bytes += 2; - r.dataInt += 1; + data.writeShort(f.getShort(obj)); } for (Field f : intFields) { - byteBuffer.writeInt(f.getInt(obj)); - r.bytes += 4; - r.dataInt += 1; + data.writeInt(f.getInt(obj)); } for (Field f : booleanFields) { - byteBuffer.writeUnsignedByte(f.getBoolean(obj) ? 1 : 0); - r.bytes += 1; - r.dataInt += 1; + data.writeBoolean(f.getBoolean(obj)); } for (Field f : enumFields) { - byteBuffer.writeUnsignedByte(((Enum) f.get(obj)).ordinal()); - r.bytes += 1; - r.dataInt += 1; - } - - for (Field f : unsignedByteFields) { - byteBuffer.writeUnsignedByte(f.getInt(obj)); - r.bytes += 1; - r.dataInt += 1; + data.writeByte(((Enum) f.get(obj)).ordinal()); } for (Field f : floatFields) { - floatValues[index.floatIndex] = f.getFloat(obj); - index.floatIndex++; - r.bytes += 4; - r.dataFloat += 1; + data.writeFloat(f.getFloat(obj)); } for (Field f : doubleFields) { - floatValues[index.floatIndex] = (float) f.getDouble(obj); - index.floatIndex++; - r.bytes += 4; - r.dataFloat += 1; + data.writeFloat((float) f.getDouble(obj)); } for (Field f : stringFields) { - stringValues[index.stringIndex] = (String) f.get(obj); - r.bytes += stringValues[index.stringIndex].length(); - index.stringIndex++; - r.dataString += 1; + data.writeUTF((String) f.get(obj)); } for (ClassMapping c : objectFields) { Object cpt = c.field.get(obj); if (cpt == null) { - byteBuffer.writeUnsignedByte(0); - - for (int i = 0; i < c.sizeBytes; ++i) { - byteBuffer.writeUnsignedByte(0); - r.bytes += 1; - r.dataInt += 1; - } - - index.floatIndex += c.sizeFloat; - index.stringIndex += c.sizeString; + data.writeBoolean(false); } else { - byteBuffer.writeUnsignedByte(1); - r.bytes += 1; - r.dataInt += 1; - - c.setData(cpt, byteBuffer, floatValues, stringValues, index); + data.writeBoolean(true); + c.setData(cpt, data); } } for (Field f : doubleArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + double [] val = (double[]) f.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - floatValues[index.floatIndex] = (float) ((double[]) f.get(obj))[i]; - index.floatIndex++; - r.bytes += 4; - r.dataFloat += 1; + if (val == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeInt(val.length); + + for (int i = 0; i < val.length; ++i) { + data.writeFloat((float) val [i]); + } } } for (Field f : shortArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + short [] val = (short[]) f.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - byteBuffer.writeShort(((short[]) f.get(obj))[i]); - r.bytes += 2; - r.dataInt += 1; + if (val == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeInt(val.length); + + for (int i = 0; i < val.length; ++i) { + data.writeShort(val [i]); + } } } for (Field f : intArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + int [] val = (int[]) f.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - byteBuffer.writeInt(((int[]) f.get(obj))[i]); - r.bytes += 4; - r.dataInt += 1; + if (val == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeInt(val.length); + + for (int i = 0; i < val.length; ++i) { + data.writeShort(val [i]); + } } } for (Field f : booleanArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + boolean [] val = (boolean[]) f.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - byteBuffer.writeUnsignedByte(((boolean[]) f.get(obj))[i] ? 1 : 0); - r.bytes += 1; - r.dataInt += 1; - } - } + if (val == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeInt(val.length); - for (Field f : unsignedByteFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); - - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - byteBuffer.writeUnsignedByte(((int[]) f.get(obj))[i]); - r.bytes += 1; - r.dataInt += 1; + for (int i = 0; i < val.length; ++i) { + data.writeBoolean(val [i]); + } } } for (Field f : stringArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + String [] val = (String[]) f.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - stringValues[index.stringIndex] = ((String[]) f.get(obj))[i]; - r.bytes += stringValues[index.stringIndex].length(); - index.stringIndex++; - r.dataString += 1; + if (val == null) { + data.writeBoolean(false); + } else { + data.writeBoolean(true); + data.writeInt(val.length); + + for (int i = 0; i < val.length; ++i) { + data.writeUTF(val [i]); + } } } @@ -367,212 +276,146 @@ public class ClassMapping { Object[] cpts = (Object[]) c.field.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) + for (int i = 0; i < cpts.length; ++i) if (cpts[i] == null) { - byteBuffer.writeUnsignedByte(0); - - for (int j = 0; j < c.sizeBytes; ++j) { - byteBuffer.writeUnsignedByte(0); - r.bytes += 1; - r.dataInt += 1; - } - - index.floatIndex += c.sizeFloat; - index.stringIndex += c.sizeString; + data.writeBoolean(false); } else { - byteBuffer.writeUnsignedByte(1); - r.bytes += 1; - r.dataInt += 1; - - c.setData(cpts[i], byteBuffer, floatValues, stringValues, index); + data.writeBoolean(true); + data.writeInt(cpts.length); + c.setData(cpts[i], data); } } } @SuppressWarnings("rawtypes") - public void updateFromData(Object obj, ByteBuffer byteBuffer, float[] floatValues, String[] stringValues, Indexes index) throws IllegalArgumentException, - IllegalAccessException { - - Reporter r = null; - - if (BuildCraftCore.trackNetworkUsage) { - if (!report.containsKey(clas.getName())) { - report.put(clas.getName(), new Reporter()); - } - - r = report.get(clas.getName()); - r.clas = clas; - } else { - r = new Reporter(); - } - - r.occurences++; + public void updateFromData(Object obj, DataInputStream data) throws IllegalArgumentException, + IllegalAccessException, IOException { for (Field f : shortFields) { - f.setShort(obj, byteBuffer.readShort()); - r.bytes += 2; - r.dataInt += 1; + f.setShort(obj, data.readShort()); } for (Field f : intFields) { - f.setInt(obj, byteBuffer.readInt()); - r.bytes += 4; - r.dataInt += 1; + f.setInt(obj, data.readInt()); } for (Field f : booleanFields) { - f.setBoolean(obj, byteBuffer.readUnsignedByte() == 1); - r.bytes += 1; - r.dataInt += 1; + f.setBoolean(obj, data.readBoolean()); } for (Field f : enumFields) { - f.set(obj, ((Class) f.getGenericType()).getEnumConstants()[byteBuffer.readUnsignedByte()]); - r.bytes += 1; - r.dataInt += 1; - } - - for (Field f : unsignedByteFields) { - f.setInt(obj, byteBuffer.readUnsignedByte()); - r.bytes += 1; - r.dataInt += 1; + f.set(obj, ((Class) f.getGenericType()).getEnumConstants()[data.readByte()]); } for (Field f : floatFields) { - f.setFloat(obj, floatValues[index.floatIndex]); - index.floatIndex++; - r.bytes += 4; - r.dataFloat += 1; + f.setFloat(obj, data.readFloat()); } for (Field f : doubleFields) { - f.setDouble(obj, floatValues[index.floatIndex]); - index.floatIndex++; - r.bytes += 4; - r.dataFloat += 1; + f.setDouble(obj, data.readFloat()); } for (Field f : stringFields) { - f.set(obj, stringValues[index.stringIndex]); - r.bytes += stringValues[index.stringIndex].length(); - index.stringIndex++; - r.dataString += 1; + f.set(obj, data.readUTF()); } for (ClassMapping c : objectFields) { - boolean isNull = byteBuffer.readUnsignedByte() == 0; - r.bytes += 1; - r.dataInt += 1; + boolean isNull = data.readBoolean(); - if (isNull) { - for (int i = 0; i < c.sizeBytes; ++i) { - byteBuffer.readUnsignedByte(); - } - - index.floatIndex += c.sizeFloat; - index.stringIndex += c.sizeString; - } else { - c.updateFromData(c.field.get(obj), byteBuffer, floatValues, stringValues, index); + if (!isNull) { + // WARNING! Because we consider the object to exist already, + // we perform the following. What if it's not the case? + c.updateFromData(c.field.get(obj), data); } } for (Field f : doubleArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + if (data.readBoolean()) { + int length = data.readInt(); + double[] tmp = new double [length]; - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - ((double[]) f.get(obj))[i] = floatValues[index.floatIndex]; - index.floatIndex++; - r.bytes += 4; - r.dataFloat += 1; + for (int i = 0; i < tmp.length; ++i) { + tmp [i] = data.readFloat(); + } + + f.set(obj, tmp); + } else { + f.set(obj, null); } } for (Field f : shortArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + if (data.readBoolean()) { + int length = data.readInt(); + short[] tmp = new short [length]; - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - ((short[]) f.get(obj))[i] = byteBuffer.readShort(); - r.bytes += 2; - r.dataInt += 1; + for (int i = 0; i < tmp.length; ++i) { + tmp [i] = data.readShort(); + } + f.set(obj, tmp); + } else { + f.set(obj, null); } } for (Field f : intArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + if (data.readBoolean()) { + int length = data.readInt(); + int[] tmp = new int [length]; - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - ((int[]) f.get(obj))[i] = byteBuffer.readInt(); - r.bytes += 4; - r.dataInt += 1; + for (int i = 0; i < tmp.length; ++i) { + tmp [i] = data.readInt(); + } + f.set(obj, tmp); + } else { + f.set(obj, null); } } for (Field f : booleanArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + if (data.readBoolean()) { + int length = data.readInt(); + boolean[] tmp = new boolean [length]; - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - ((boolean[]) f.get(obj))[i] = byteBuffer.readUnsignedByte() == 1; - r.bytes += 1; - r.dataInt += 1; - } - } + for (int i = 0; i < tmp.length; ++i) { + tmp [i] = data.readBoolean(); + } - for (Field f : unsignedByteArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); - - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - ((int[]) f.get(obj))[i] = byteBuffer.readUnsignedByte(); - r.bytes += 1; - r.dataInt += 1; + f.set(obj, tmp); + } else { + f.set(obj, null); } } for (Field f : stringArrayFields) { - TileNetworkData updateAnnotation = f.getAnnotation(TileNetworkData.class); + if (data.readBoolean()) { + int length = data.readInt(); + String [] tmp = new String [length]; - String[] strs = (String[]) f.get(obj); + for (int i = 0; i < tmp.length; ++i) { + tmp [i] = data.readUTF(); + } - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - strs[i] = stringValues[index.stringIndex]; - r.bytes += stringValues[index.stringIndex].length(); - index.stringIndex++; - r.dataString += 1; + f.set(obj, tmp); + } else { + f.set(obj, null); } } for (ClassMapping c : objectArrayFields) { - TileNetworkData updateAnnotation = c.field.getAnnotation(TileNetworkData.class); - Object[] cpts = (Object[]) c.field.get(obj); - for (int i = 0; i < updateAnnotation.staticSize(); ++i) { - boolean isNull = byteBuffer.readUnsignedByte() == 0; - r.bytes += 1; - r.dataInt += 1; + for (int i = 0; i < cpts.length; ++i) { + boolean isNull = data.readBoolean(); - if (isNull) { - for (int j = 0; j < c.sizeBytes; ++j) { - byteBuffer.readUnsignedByte(); - } - - index.floatIndex += c.sizeFloat; - index.stringIndex += c.sizeString; - } else { - c.updateFromData(cpts[i], byteBuffer, floatValues, stringValues, index); + if (!isNull) { + // WARNING! Because we consider the object to exist already, + // we perform the following. What if it's not the case? + c.updateFromData(cpts[i], data); } } } } - - public int[] getSize() { - int[] result = new int[3]; - - result[0] = sizeBytes; - result[1] = sizeFloat; - result[2] = sizeString; - - return result; - } } diff --git a/common/buildcraft/core/network/ClassSerializer.java b/common/buildcraft/core/network/ClassSerializer.java new file mode 100755 index 00000000..81a85c87 --- /dev/null +++ b/common/buildcraft/core/network/ClassSerializer.java @@ -0,0 +1,23 @@ +package buildcraft.core.network; + +import java.util.HashMap; +import java.util.Map; + +public class ClassSerializer { + + @SuppressWarnings("rawtypes") + private static Map classSerializers = new HashMap(); + + + /*if (!updateWrappers.containsKey(this.getClass())) { + updateWrappers.put(this.getClass(), new TilePacketWrapper(this.getClass())); + } + + if (!descriptionWrappers.containsKey(this.getClass())) { + descriptionWrappers.put(this.getClass(), new TilePacketWrapper(this.getClass())); + } + + updatePacket = updateWrappers.get(this.getClass()); + descriptionPacket = descriptionWrappers.get(this.getClass());*/ + +} diff --git a/common/buildcraft/core/network/PacketHandler.java b/common/buildcraft/core/network/PacketHandler.java index ebf5951a..205f6eab 100644 --- a/common/buildcraft/core/network/PacketHandler.java +++ b/common/buildcraft/core/network/PacketHandler.java @@ -3,6 +3,7 @@ package buildcraft.core.network; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; +import java.io.ObjectInputStream; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.INetworkManager; @@ -33,8 +34,8 @@ public class PacketHandler implements IPacketHandler { @Override public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { DataInputStream data = new DataInputStream(new ByteArrayInputStream(packet.data)); - try { + try { int packetID = data.read(); switch (packetID) { case PacketIds.TILE_UPDATE: { diff --git a/common/buildcraft/core/network/PacketIds.java b/common/buildcraft/core/network/PacketIds.java index 660eb36f..5b8ae054 100644 --- a/common/buildcraft/core/network/PacketIds.java +++ b/common/buildcraft/core/network/PacketIds.java @@ -30,7 +30,8 @@ public class PacketIds { public static final int REFINERY_FILTER_SET = 50; public static final int ARCHITECT_NAME = 60; - public static final int LIBRARY_ACTION = 61; + // Trying to replace all library actions by RPC + //public static final int LIBRARY_ACTION = 61; public static final int LIBRARY_SELECT = 62; public static final int ADVANCED_WORKBENCH_SETSLOT = 70; diff --git a/common/buildcraft/core/network/PacketPayload.java b/common/buildcraft/core/network/PacketPayload.java index 98eaa9df..d8461ab5 100644 --- a/common/buildcraft/core/network/PacketPayload.java +++ b/common/buildcraft/core/network/PacketPayload.java @@ -6,24 +6,16 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +/** + * FIXME: Now that packet PayloadArray is removed, it's probably worth removing + * the abstraction, and having just one class for PayloadStream. + */ public abstract class PacketPayload { - - public static enum Type { - - NULL, ARRAY, STREAM - } - - public static PacketPayload makePayload(int type) { - if (type == Type.ARRAY.ordinal()) - return new PacketPayloadArrays(); - if (type == Type.STREAM.ordinal()) - return new PacketPayloadStream(); - return null; + public static PacketPayload makePayload() { + return new PacketPayloadStream(); } public abstract void writeData(DataOutputStream data) throws IOException; public abstract void readData(DataInputStream data) throws IOException; - - public abstract Type getType(); } diff --git a/common/buildcraft/core/network/PacketPayloadArrays.java b/common/buildcraft/core/network/PacketPayloadArrays.java deleted file mode 100644 index 09710642..00000000 --- a/common/buildcraft/core/network/PacketPayloadArrays.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) SpaceToad, 2011-2012 - * 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; - -import buildcraft.core.utils.Utils; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * - * @author CovertJaguar - */ -public class PacketPayloadArrays extends PacketPayload { - - public int[] intPayload = new int[0]; - public float[] floatPayload = new float[0]; - public String[] stringPayload = new String[0]; - - public PacketPayloadArrays() { - } - - public PacketPayloadArrays(int intSize, int floatSize, int stringSize) { - intPayload = new int[intSize]; - floatPayload = new float[floatSize]; - stringPayload = new String[stringSize]; - } - - public void append(PacketPayloadArrays other) { - if (other == null) - return; - - if (other.intPayload.length > 0) { - this.intPayload = Utils.concat(this.intPayload, other.intPayload); - } - if (other.floatPayload.length > 0) { - this.floatPayload = Utils.concat(this.floatPayload, other.floatPayload); - } - if (other.stringPayload.length > 0) { - this.stringPayload = Utils.concat(this.stringPayload, other.stringPayload); - } - - } - - public void append(int[] other) { - if (other == null || other.length < 0) - return; - - this.intPayload = Utils.concat(this.intPayload, other); - } - - public void splitTail(IndexInPayload index) { - PacketPayloadArrays payload = new PacketPayloadArrays(intPayload.length - index.intIndex, floatPayload.length - index.floatIndex, stringPayload.length - - index.stringIndex); - - if (intPayload.length > 0) { - System.arraycopy(intPayload, index.intIndex, payload.intPayload, 0, payload.intPayload.length); - } - if (floatPayload.length > 0) { - System.arraycopy(floatPayload, index.floatIndex, payload.floatPayload, 0, payload.floatPayload.length); - } - if (stringPayload.length > 0) { - System.arraycopy(stringPayload, index.stringIndex, payload.stringPayload, 0, payload.stringPayload.length); - } - } - - @Override - public void writeData(DataOutputStream data) throws IOException { - data.writeInt(intPayload.length); - data.writeInt(floatPayload.length); - data.writeInt(stringPayload.length); - - for (int intData : intPayload) { - data.writeInt(intData); - } - for (float floatData : floatPayload) { - data.writeFloat(floatData); - } - for (String stringData : stringPayload) { - data.writeUTF(stringData); - } - } - - @Override - public void readData(DataInputStream data) throws IOException { - intPayload = new int[data.readInt()]; - floatPayload = new float[data.readInt()]; - stringPayload = new String[data.readInt()]; - - for (int i = 0; i < intPayload.length; i++) { - intPayload[i] = data.readInt(); - } - for (int i = 0; i < floatPayload.length; i++) { - floatPayload[i] = data.readFloat(); - } - for (int i = 0; i < stringPayload.length; i++) { - stringPayload[i] = data.readUTF(); - } - } - - @Override - public Type getType() { - return Type.ARRAY; - } -} diff --git a/common/buildcraft/core/network/PacketPayloadStream.java b/common/buildcraft/core/network/PacketPayloadStream.java index 651d5b2f..8fec395f 100644 --- a/common/buildcraft/core/network/PacketPayloadStream.java +++ b/common/buildcraft/core/network/PacketPayloadStream.java @@ -1,7 +1,7 @@ /* * Copyright (c) SpaceToad, 2011-2012 * 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 @@ -15,10 +15,6 @@ import java.io.IOException; /** * Alternative Packet Payload system. * - * Note, you cannot use a Stream payload and the TileNetworkData annotation at - * the same time. Attempting to do will most likely result in a class cast - * exception somewhere. - * * @author CovertJaguar */ public class PacketPayloadStream extends PacketPayload { @@ -46,9 +42,4 @@ public class PacketPayloadStream extends PacketPayload { public void readData(DataInputStream data) throws IOException { stream = data; } - - @Override - public Type getType() { - return Type.STREAM; - } } diff --git a/common/buildcraft/core/network/PacketUpdate.java b/common/buildcraft/core/network/PacketUpdate.java index afd82b80..e824c11a 100644 --- a/common/buildcraft/core/network/PacketUpdate.java +++ b/common/buildcraft/core/network/PacketUpdate.java @@ -43,7 +43,6 @@ public class PacketUpdate extends BuildCraftPacket { data.writeInt(posZ); if (payload != null) { - data.writeByte(payload.getType().ordinal()); payload.writeData(data); } else { data.writeByte(0); @@ -57,9 +56,7 @@ public class PacketUpdate extends BuildCraftPacket { posY = data.readInt(); posZ = data.readInt(); - byte type = data.readByte(); - - payload = PacketPayload.makePayload(type); + payload = PacketPayload.makePayload(); if (payload != null) payload.readData(data); diff --git a/common/buildcraft/core/network/RPC.java b/common/buildcraft/core/network/RPC.java index d744ee4e..5a590ef7 100755 --- a/common/buildcraft/core/network/RPC.java +++ b/common/buildcraft/core/network/RPC.java @@ -4,8 +4,12 @@ import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import cpw.mods.fml.relauncher.Side; + @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface RPC { - + //FIXME: Take into account side constraints when making calls to check + // they're correclyt made + public RPCSide value() default RPCSide.BOTH; } \ No newline at end of file diff --git a/common/buildcraft/core/network/RPCHandler.java b/common/buildcraft/core/network/RPCHandler.java index 4e4817cb..8264f4e9 100755 --- a/common/buildcraft/core/network/RPCHandler.java +++ b/common/buildcraft/core/network/RPCHandler.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.io.ObjectOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; @@ -63,11 +64,13 @@ public class RPCHandler { } else if (formals [j].equals(String.class)) { // accepted } else if (formals [j].equals(RPCMessageInfo.class)) { + // accepted // FIXME: only if last one } else { - throw new RuntimeException - ("parameter type " + formals [j].getName() + " not supported in RPC."); + // all other will be serialized + //throw new RuntimeException + //("parameter type " + formals [j].getName() + " not supported in RPC."); } } } @@ -144,6 +147,8 @@ public class RPCHandler { data.writeInt((Integer) actuals [i]); } else if (formals [i].equals(String.class)) { data.writeUTF((String) actuals [i]); + } else { + //data.write } } diff --git a/common/buildcraft/core/network/RPCSide.java b/common/buildcraft/core/network/RPCSide.java new file mode 100755 index 00000000..9e7a51c7 --- /dev/null +++ b/common/buildcraft/core/network/RPCSide.java @@ -0,0 +1,5 @@ +package buildcraft.core.network; + +public enum RPCSide { + CLIENT, SERVER, BOTH +} diff --git a/common/buildcraft/core/network/TileNetworkData.java b/common/buildcraft/core/network/TileNetworkData.java index 0c2eab0c..03156a1b 100644 --- a/common/buildcraft/core/network/TileNetworkData.java +++ b/common/buildcraft/core/network/TileNetworkData.java @@ -1,8 +1,8 @@ -/** +/** * Copyright (c) SpaceToad, 2011 * http://www.mod-buildcraft.com - * - * BuildCraft is distributed under the terms of the Minecraft Mod Public + * + * 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 */ @@ -15,14 +15,8 @@ import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @Inherited +//FIXME: Given the usage of this in RPCs, this should be renamed, e.g. +//NetworkData public @interface TileNetworkData { - public static int DEFAULT = 0; - public static int UNSIGNED_BYTE = 1; - public static int UNSIGNED_SHORT = 2; - - int staticSize() default -1; - - int intKind() default DEFAULT; - } diff --git a/common/buildcraft/core/network/TilePacketWrapper.java b/common/buildcraft/core/network/TilePacketWrapper.java index cf978521..750aa642 100644 --- a/common/buildcraft/core/network/TilePacketWrapper.java +++ b/common/buildcraft/core/network/TilePacketWrapper.java @@ -9,12 +9,15 @@ package buildcraft.core.network; -import buildcraft.core.ByteBuffer; -import buildcraft.core.network.ClassMapping.Indexes; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + import net.minecraft.tileentity.TileEntity; public class TilePacketWrapper { - ClassMapping rootMappings[]; @SuppressWarnings("rawtypes") @@ -31,36 +34,25 @@ public class TilePacketWrapper { } } - public PacketPayload toPayload(TileEntity tile) { - int sizeF = 0, sizeS = 0; + public PacketPayload toPayload(final TileEntity tile) { + return new PacketPayloadStream(new PacketPayloadStream.StreamWriter() { + @Override + public void writeData(DataOutputStream data) throws IOException { + data.writeInt(tile.xCoord); + data.writeInt(tile.yCoord); + data.writeInt(tile.zCoord); - for (int i = 0; i < rootMappings.length; ++i) { - int[] size = rootMappings[i].getSize(); - - sizeF += size[1]; - sizeS += size[2]; - } - - PacketPayloadArrays payload = new PacketPayloadArrays(0, sizeF, sizeS); - - ByteBuffer buf = new ByteBuffer(); - - buf.writeInt(tile.xCoord); - buf.writeInt(tile.yCoord); - buf.writeInt(tile.zCoord); - - try { - rootMappings[0].setData(tile, buf, payload.floatPayload, payload.stringPayload, new Indexes(0, 0)); - - payload.intPayload = buf.readIntArray(); - - return payload; - - } catch (Exception e) { - e.printStackTrace(); - - return null; - } + try { + rootMappings[0].setData(tile, data); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }); } public PacketPayload toPayload(Object obj) { @@ -71,78 +63,59 @@ public class TilePacketWrapper { return toPayload(x, y, z, new Object[] { obj }); } - public PacketPayload toPayload(int x, int y, int z, Object[] obj) { + public PacketPayload toPayload(final int x, final int y, final int z, final Object[] obj) { + return new PacketPayloadStream(new PacketPayloadStream.StreamWriter() { + @Override + public void writeData(DataOutputStream data) throws IOException { + data.writeInt(x); + data.writeInt(y); + data.writeInt(z); - int sizeF = 0, sizeS = 0; + for (int i = 0; i < rootMappings.length; ++i) { + try { + rootMappings[i].setData(obj[i], data); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } - for (int i = 0; i < rootMappings.length; ++i) { - int[] size = rootMappings[i].getSize(); - - sizeF += size[1]; - sizeS += size[2]; - } - - PacketPayloadArrays payload = new PacketPayloadArrays(0, sizeF, sizeS); - - ByteBuffer buf = new ByteBuffer(); - - buf.writeInt(x); - buf.writeInt(y); - buf.writeInt(z); - - try { - Indexes ind = new Indexes(0, 0); - - for (int i = 0; i < rootMappings.length; ++i) { - rootMappings[i].setData(obj[i], buf, payload.floatPayload, payload.stringPayload, ind); } - - payload.intPayload = buf.readIntArray(); - - return payload; - - } catch (Exception e) { - e.printStackTrace(); - - return null; - } + }); } - public void fromPayload(TileEntity tile, PacketPayloadArrays packet) { + public void fromPayload(TileEntity tile, PacketPayloadStream packet) { try { - ByteBuffer buf = new ByteBuffer(); - buf.writeIntArray(packet.intPayload); - buf.readInt(); - buf.readInt(); - buf.readInt(); + DataInputStream data = packet.stream; - rootMappings[0].updateFromData(tile, buf, packet.floatPayload, packet.stringPayload, new Indexes(0, 0)); + data.readInt(); + data.readInt(); + data.readInt(); - packet.intPayload = buf.readIntArray(); + rootMappings[0].updateFromData(tile, data); } catch (Exception e) { e.printStackTrace(); } } - public void fromPayload(Object obj, PacketPayloadArrays packet) { + public void fromPayload(Object obj, PacketPayloadStream packet) { fromPayload(new Object[] { obj }, packet); } - public void fromPayload(Object[] obj, PacketPayloadArrays packet) { + public void fromPayload(Object[] obj, PacketPayloadStream packet) { try { - ByteBuffer buf = new ByteBuffer(); - buf.writeIntArray(packet.intPayload); - buf.readInt(); - buf.readInt(); - buf.readInt(); + DataInputStream data = packet.stream; - Indexes ind = new Indexes(0, 0); + data.readInt(); + data.readInt(); + data.readInt(); for (int i = 0; i < rootMappings.length; ++i) { - rootMappings[i].updateFromData(obj[i], buf, packet.floatPayload, packet.stringPayload, ind); + rootMappings[i].updateFromData(obj[i], data); } - - packet.intPayload = buf.readIntArray(); } catch (Exception e) { e.printStackTrace(); } diff --git a/common/buildcraft/transport/gui/ContainerGateInterface.java b/common/buildcraft/transport/gui/ContainerGateInterface.java index c3fec992..048bab14 100644 --- a/common/buildcraft/transport/gui/ContainerGateInterface.java +++ b/common/buildcraft/transport/gui/ContainerGateInterface.java @@ -17,13 +17,13 @@ import buildcraft.core.gui.BuildCraftContainer; import buildcraft.core.network.PacketCoordinates; import buildcraft.core.network.PacketIds; import buildcraft.core.network.PacketPayload; -import buildcraft.core.network.PacketPayloadArrays; import buildcraft.core.network.PacketPayloadStream; import buildcraft.core.network.PacketUpdate; import buildcraft.core.proxy.CoreProxy; import buildcraft.transport.Pipe; import buildcraft.transport.gates.GateDefinition; +import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -132,11 +132,16 @@ public class ContainerGateInterface extends BuildCraftContainer { */ public void updateActions(PacketUpdate packet) { _potentialActions.clear(); - PacketPayloadArrays payload = (PacketPayloadArrays) packet.payload; - int length = payload.intPayload[0]; + PacketPayloadStream payload = (PacketPayloadStream) packet.payload; + try { + int length = payload.stream.readInt(); - for (int i = 0; i < length; i++) { - _potentialActions.add(ActionManager.actions.get(payload.stringPayload[i])); + for (int i = 0; i < length; i++) { + _potentialActions.add(ActionManager.actions.get(payload.stream.readUTF())); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } @@ -147,11 +152,18 @@ public class ContainerGateInterface extends BuildCraftContainer { */ public void updateTriggers(PacketUpdate packet) { _potentialTriggers.clear(); - PacketPayloadArrays payload = (PacketPayloadArrays) packet.payload; - int length = payload.intPayload[0]; + PacketPayloadStream payload = (PacketPayloadStream) packet.payload; - for (int i = 0; i < length; i++) { - _potentialTriggers.add(ActionManager.triggers.get(payload.stringPayload[i])); + try { + int length = payload.stream.readInt(); + + for (int i = 0; i < length; i++) { + String trigger = payload.stream.readUTF(); + _potentialTriggers.add(ActionManager.triggers.get(trigger)); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } @@ -287,14 +299,21 @@ public class ContainerGateInterface extends BuildCraftContainer { private void sendActions(EntityPlayer player) { // Compose update packet - int length = _potentialActions.size(); - PacketPayloadArrays payload = new PacketPayloadArrays(1, 0, length); - payload.intPayload[0] = length; - int i = 0; - for (IAction action : _potentialActions) { - payload.stringPayload[i++] = action.getUniqueTag(); - } + PacketPayloadStream payload = new PacketPayloadStream( + new PacketPayloadStream.StreamWriter() { + @Override + public void writeData(DataOutputStream data) + throws IOException { + + int length = _potentialActions.size(); + data.writeInt(length); + + for (IAction action : _potentialActions) { + data.writeUTF(action.getUniqueTag()); + } + } + }); PacketUpdate packet = new PacketUpdate(PacketIds.GATE_ACTIONS, pipe.container.xCoord, pipe.container.yCoord, pipe.container.zCoord, payload); @@ -309,15 +328,20 @@ public class ContainerGateInterface extends BuildCraftContainer { */ private void sendTriggers(EntityPlayer player) { - // Compose update packet - int length = _potentialTriggers.size(); - PacketPayloadArrays payload = new PacketPayloadArrays(1, 0, length); + PacketPayloadStream payload = new PacketPayloadStream( + new PacketPayloadStream.StreamWriter() { + @Override + public void writeData(DataOutputStream data) + throws IOException { - payload.intPayload[0] = length; - int i = 0; - for (ITrigger trigger : _potentialTriggers) { - payload.stringPayload[i++] = trigger.getUniqueTag(); - } + int length = _potentialTriggers.size(); + data.writeInt(length); + + for (ITrigger trigger : _potentialTriggers) { + data.writeUTF(trigger.getUniqueTag()); + } + } + }); PacketUpdate packet = new PacketUpdate(PacketIds.GATE_TRIGGERS, pipe.container.xCoord, pipe.container.yCoord, pipe.container.zCoord, payload);