From 9883e790c47a3d7eaaa29be953519363a7655314 Mon Sep 17 00:00:00 2001 From: asiekierka Date: Sat, 13 Dec 2014 19:32:16 +0100 Subject: [PATCH] fix blueprints over ~32k not working (#2289) --- .../builders/TileBlueprintLibrary.java | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/common/buildcraft/builders/TileBlueprintLibrary.java b/common/buildcraft/builders/TileBlueprintLibrary.java index 571ca8ec..66d89b3e 100644 --- a/common/buildcraft/builders/TileBlueprintLibrary.java +++ b/common/buildcraft/builders/TileBlueprintLibrary.java @@ -39,6 +39,7 @@ import buildcraft.core.utils.Utils; */ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, ICommandReceiver { private static final int PROGRESS_TIME = 100; + private static final int CHUNK_SIZE = 16384; public SimpleInventory inv = new SimpleInventory(4, "Blueprint Library", 1); @@ -54,6 +55,9 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, public int pageId = 0; + private BlueprintId blueprintDownloadId; + private byte[] blueprintDownload; + public TileBlueprintLibrary() { } @@ -261,16 +265,35 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, if ("requestSelectedBlueprint".equals(command)) { if (isOutputConsistent()) { if (selected > -1 && selected < currentPage.size()) { + // Work around 32k max limit on client->server final BlueprintBase bpt = BuildCraftBuilders.clientDB .load(currentPage.get(selected)); + final byte[] bptData = bpt.getData(); + final int chunks = (bptData.length + CHUNK_SIZE - 1) / CHUNK_SIZE; - BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadBlueprintToServer", + BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadServerBegin", new CommandWriter() { - public void write(ByteBuf data) { - bpt.id.writeData(data); - Utils.writeByteArray(data, bpt.getData()); - } - })); + public void write(ByteBuf data) { + bpt.id.writeData(data); + data.writeShort(chunks); + } + })); + + for (int i = 0; i < chunks; i++) { + final int chunk = i; + final int start = CHUNK_SIZE * chunk; + final int length = Math.min(CHUNK_SIZE, bptData.length - start); + BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadServerChunk", + new CommandWriter() { + public void write(ByteBuf data) { + data.writeShort(chunk); + data.writeShort(length); + data.writeBytes(bptData, start, length); + } + })); + } + + BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadServerEnd", null)); } else { BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadNothingToServer", null)); } @@ -298,15 +321,24 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, setInventorySlotContents(2, null); downloadingPlayer = null; - } else if ("uploadBlueprintToServer".equals(command)) { - BlueprintId id = new BlueprintId(); - id.readData(stream); - byte[] data = Utils.readByteArray(stream); + } else if ("uploadServerBegin".equals(command)) { + blueprintDownloadId = new BlueprintId(); + blueprintDownloadId.readData(stream); + blueprintDownload = new byte[CHUNK_SIZE * stream.readUnsignedShort()]; + } else if ("uploadServerChunk".equals(command)) { + int start = stream.readUnsignedShort() * CHUNK_SIZE; + int length = stream.readUnsignedShort(); + if (blueprintDownload != null) { + stream.readBytes(blueprintDownload, start, length); + } else { + stream.skipBytes(length); + } + } else if ("uploadServerEnd".equals(command)) { try { - NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a); + NBTTagCompound nbt = CompressedStreamTools.func_152457_a(blueprintDownload, NBTSizeTracker.field_152451_a); BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt); - bpt.setData(data); - bpt.id = id; + bpt.setData(blueprintDownload); + bpt.id = blueprintDownloadId; BuildCraftBuilders.serverDB.add(bpt); setInventorySlotContents(3, bpt.getStack()); @@ -315,6 +347,8 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, e.printStackTrace(); } + blueprintDownloadId = null; + blueprintDownload = null; downloadingPlayer = null; } }