From 8b72e4bd17445a2a9eba9f2ffd0f49a2021ef0a7 Mon Sep 17 00:00:00 2001 From: Raoul Van den Berge Date: Mon, 18 Jul 2016 23:37:56 +0200 Subject: [PATCH] Send over ID's instead of stacks over the net, should fix #193 --- .../java/refinedstorage/RefinedStorage.java | 3 +- .../refinedstorage/RefinedStorageUtils.java | 28 ++++++++++++-- .../api/network/IGridHandler.java | 8 ++-- .../api/storage/IGroupedStorage.java | 7 ++++ .../apiimpl/network/GridHandler.java | 18 ++++++--- .../apiimpl/storage/ClientStack.java | 32 ++++++++++++++++ .../apiimpl/storage/GroupedStorage.java | 11 ++++++ .../gui/GuiCraftingSettings.java | 10 ++--- src/main/java/refinedstorage/gui/GuiGrid.java | 38 ++++++++----------- .../network/MessageGridCraftingStart.java | 14 +++---- .../network/MessageGridDelta.java | 28 +++++++------- .../network/MessageGridPull.java | 14 +++---- .../network/MessageGridUpdate.java | 13 +++---- .../tile/controller/TileController.java | 5 ++- 14 files changed, 147 insertions(+), 82 deletions(-) create mode 100755 src/main/java/refinedstorage/apiimpl/storage/ClientStack.java diff --git a/src/main/java/refinedstorage/RefinedStorage.java b/src/main/java/refinedstorage/RefinedStorage.java index 779d4424f..d4afca352 100755 --- a/src/main/java/refinedstorage/RefinedStorage.java +++ b/src/main/java/refinedstorage/RefinedStorage.java @@ -14,6 +14,7 @@ import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; +import refinedstorage.apiimpl.storage.ClientStack; import refinedstorage.proxy.CommonProxy; import java.util.ArrayList; @@ -44,7 +45,7 @@ public final class RefinedStorage { } }; - public List items = new ArrayList(); + public List items = new ArrayList(); public int cableUsage; public int constructorUsage; diff --git a/src/main/java/refinedstorage/RefinedStorageUtils.java b/src/main/java/refinedstorage/RefinedStorageUtils.java index b81a77c81..7261c3fbb 100755 --- a/src/main/java/refinedstorage/RefinedStorageUtils.java +++ b/src/main/java/refinedstorage/RefinedStorageUtils.java @@ -1,7 +1,9 @@ package refinedstorage; +import io.netty.buffer.ByteBuf; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagIntArray; @@ -12,6 +14,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.wrapper.InvWrapper; @@ -21,6 +24,7 @@ import org.apache.commons.lang3.ArrayUtils; import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.storage.CompareFlags; +import refinedstorage.apiimpl.storage.ClientStack; import refinedstorage.item.ItemUpgrade; import java.util.HashSet; @@ -334,10 +338,6 @@ public final class RefinedStorageUtils { return network.extractItem(stack, size, CompareFlags.COMPARE_DAMAGE | CompareFlags.COMPARE_NBT); } - public static ItemStack getItem(INetworkMaster network, ItemStack stack) { - return network.getStorage().get(stack, CompareFlags.COMPARE_DAMAGE | CompareFlags.COMPARE_NBT); - } - public static ICraftingPattern getPattern(INetworkMaster network, ItemStack stack) { return network.getPattern(stack, CompareFlags.COMPARE_DAMAGE | CompareFlags.COMPARE_NBT); } @@ -345,4 +345,24 @@ public final class RefinedStorageUtils { public static boolean hasPattern(INetworkMaster network, ItemStack stack) { return RefinedStorageUtils.getPattern(network, stack) != null; } + + public static void writeClientStack(ByteBuf buf, INetworkMaster network, ItemStack stack) { + buf.writeInt(Item.getIdFromItem(stack.getItem())); + buf.writeInt(stack.stackSize); + buf.writeInt(stack.getItemDamage()); + ByteBufUtils.writeTag(buf, stack.getTagCompound()); + buf.writeInt(getItemStackHashCode(stack)); + buf.writeBoolean(RefinedStorageUtils.hasPattern(network, stack)); + } + + public static ClientStack readClientStack(ByteBuf buf) { + ItemStack stack = new ItemStack(Item.getItemById(buf.readInt()), buf.readInt(), buf.readInt()); + stack.setTagCompound(ByteBufUtils.readTag(buf)); + + return new ClientStack(buf.readInt(), stack, buf.readBoolean()); + } + + public static int getItemStackHashCode(ItemStack stack) { + return stack.getItem().hashCode() * (stack.getItemDamage() + 1) * (stack.hasTagCompound() ? stack.getTagCompound().hashCode() : 1); + } } diff --git a/src/main/java/refinedstorage/api/network/IGridHandler.java b/src/main/java/refinedstorage/api/network/IGridHandler.java index b79760c3d..373c28e2f 100755 --- a/src/main/java/refinedstorage/api/network/IGridHandler.java +++ b/src/main/java/refinedstorage/api/network/IGridHandler.java @@ -12,11 +12,11 @@ public interface IGridHandler { /** * Called when a player tries to extract an item from the grid. * - * @param stack The item we're trying to extract + * @param id The ID of the item we're trying to extract * @param flags How we are extracting, see {@link GridExtractFlags} * @param player The player that is attempting the extraction */ - void onExtract(ItemStack stack, int flags, EntityPlayerMP player); + void onExtract(int id, int flags, EntityPlayerMP player); /** * Called when a player tries to insert an item to the grid. @@ -38,10 +38,10 @@ public interface IGridHandler { /** * Called when a player requested crafting for an item. * - * @param stack The item we're requesting crafting for + * @param id The ID of the item we're requesting crafting for * @param quantity The amount of that item that has to be crafted */ - void onCraftingRequested(ItemStack stack, int quantity); + void onCraftingRequested(int id, int quantity); /** * Called when a player wants to cancel a crafting task. diff --git a/src/main/java/refinedstorage/api/storage/IGroupedStorage.java b/src/main/java/refinedstorage/api/storage/IGroupedStorage.java index a31a78e01..0d349f98d 100755 --- a/src/main/java/refinedstorage/api/storage/IGroupedStorage.java +++ b/src/main/java/refinedstorage/api/storage/IGroupedStorage.java @@ -40,6 +40,13 @@ public interface IGroupedStorage { */ ItemStack get(ItemStack stack, int flags); + /** + * Gets an item from the network by ID. + * + * @return The {@link ItemStack}, do NOT modify + */ + ItemStack get(int id); + /** * @return All items in this storage network */ diff --git a/src/main/java/refinedstorage/apiimpl/network/GridHandler.java b/src/main/java/refinedstorage/apiimpl/network/GridHandler.java index 05e51bcc5..806811846 100755 --- a/src/main/java/refinedstorage/apiimpl/network/GridHandler.java +++ b/src/main/java/refinedstorage/apiimpl/network/GridHandler.java @@ -20,8 +20,8 @@ public class GridHandler implements IGridHandler { } @Override - public void onExtract(ItemStack stack, int flags, EntityPlayerMP player) { - ItemStack item = RefinedStorageUtils.getItem(network, stack); + public void onExtract(int id, int flags, EntityPlayerMP player) { + ItemStack item = network.getStorage().get(id); if (item == null) { return; @@ -34,7 +34,7 @@ public class GridHandler implements IGridHandler { ItemStack held = player.inventory.getItemStack(); if (single) { - if (held != null && (!RefinedStorageUtils.compareStackNoQuantity(stack, held) || held.stackSize + 1 > held.getMaxStackSize())) { + if (held != null && (!RefinedStorageUtils.compareStackNoQuantity(item, held) || held.stackSize + 1 > held.getMaxStackSize())) { return; } } else if (player.inventory.getItemStack() != null) { @@ -55,9 +55,9 @@ public class GridHandler implements IGridHandler { // NO OP, the quantity already set (64) is needed for shift } - size = Math.min(size, stack.getItem().getItemStackLimit(stack)); + size = Math.min(size, item.getItem().getItemStackLimit(item)); - ItemStack took = RefinedStorageUtils.extractItem(network, stack, size); + ItemStack took = RefinedStorageUtils.extractItem(network, item, size); if (took != null) { if ((flags & GridExtractFlags.EXTRACT_SHIFT) == GridExtractFlags.EXTRACT_SHIFT) { @@ -112,11 +112,17 @@ public class GridHandler implements IGridHandler { } @Override - public void onCraftingRequested(ItemStack stack, int quantity) { + public void onCraftingRequested(int id, int quantity) { if (quantity <= 0 || quantity > MAX_CRAFTING_PER_REQUEST) { return; } + ItemStack stack = network.getStorage().get(id); + + if (stack == null) { + return; + } + int quantityPerRequest = 0; ICraftingPattern pattern = RefinedStorageUtils.getPattern(network, stack); diff --git a/src/main/java/refinedstorage/apiimpl/storage/ClientStack.java b/src/main/java/refinedstorage/apiimpl/storage/ClientStack.java new file mode 100755 index 000000000..5f19592fc --- /dev/null +++ b/src/main/java/refinedstorage/apiimpl/storage/ClientStack.java @@ -0,0 +1,32 @@ +package refinedstorage.apiimpl.storage; + +import net.minecraft.item.ItemStack; + +public class ClientStack { + private int id; + private ItemStack stack; + private boolean craftable; + + public ClientStack(int id, ItemStack stack, boolean craftable) { + this.id = id; + this.stack = stack; + this.craftable = craftable; + } + + public int getId() { + return id; + } + + public ItemStack getStack() { + return stack; + } + + public boolean isCraftable() { + return craftable; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ClientStack && ((ClientStack) obj).getId() == id; + } +} diff --git a/src/main/java/refinedstorage/apiimpl/storage/GroupedStorage.java b/src/main/java/refinedstorage/apiimpl/storage/GroupedStorage.java index 6a93326f6..21855ae17 100755 --- a/src/main/java/refinedstorage/apiimpl/storage/GroupedStorage.java +++ b/src/main/java/refinedstorage/apiimpl/storage/GroupedStorage.java @@ -105,6 +105,17 @@ public class GroupedStorage implements IGroupedStorage { return null; } + @Override + public ItemStack get(int id) { + for (ItemStack stack : this.stacks.values()) { + if (RefinedStorageUtils.getItemStackHashCode(stack) == id) { + return stack; + } + } + + return null; + } + @Override public Collection getStacks() { return stacks.values(); diff --git a/src/main/java/refinedstorage/gui/GuiCraftingSettings.java b/src/main/java/refinedstorage/gui/GuiCraftingSettings.java index c7fc7d96e..634d9369c 100755 --- a/src/main/java/refinedstorage/gui/GuiCraftingSettings.java +++ b/src/main/java/refinedstorage/gui/GuiCraftingSettings.java @@ -4,11 +4,11 @@ import com.google.common.primitives.Ints; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiTextField; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; import net.minecraftforge.fml.client.FMLClientHandler; import org.lwjgl.input.Keyboard; import refinedstorage.RefinedStorage; import refinedstorage.apiimpl.network.GridHandler; +import refinedstorage.apiimpl.storage.ClientStack; import refinedstorage.container.ContainerCraftingSettings; import refinedstorage.network.MessageGridCraftingStart; @@ -19,13 +19,13 @@ public class GuiCraftingSettings extends GuiBase { private GuiTextField amountField; private GuiGrid gui; - private ItemStack stack; + private ClientStack stack; private GuiButton startButton; private GuiButton cancelButton; private GuiButton[] incrementButtons = new GuiButton[6]; - public GuiCraftingSettings(GuiGrid gui, EntityPlayer player, ItemStack stack) { - super(new ContainerCraftingSettings(player, stack), 172, 99); + public GuiCraftingSettings(GuiGrid gui, EntityPlayer player, ClientStack stack) { + super(new ContainerCraftingSettings(player, stack.getStack()), 172, 99); this.gui = gui; this.stack = stack; @@ -124,7 +124,7 @@ public class GuiCraftingSettings extends GuiBase { Integer quantity = Ints.tryParse(amountField.getText()); if (quantity != null && quantity > 0 && quantity <= GridHandler.MAX_CRAFTING_PER_REQUEST) { - RefinedStorage.INSTANCE.network.sendToServer(new MessageGridCraftingStart(stack, quantity)); + RefinedStorage.INSTANCE.network.sendToServer(new MessageGridCraftingStart(stack.getId(), quantity)); close(); } diff --git a/src/main/java/refinedstorage/gui/GuiGrid.java b/src/main/java/refinedstorage/gui/GuiGrid.java index 469617b5b..5b904435a 100755 --- a/src/main/java/refinedstorage/gui/GuiGrid.java +++ b/src/main/java/refinedstorage/gui/GuiGrid.java @@ -5,7 +5,6 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -14,6 +13,7 @@ import net.minecraftforge.fml.common.FMLCommonHandler; import org.apache.commons.lang3.StringUtils; import refinedstorage.RefinedStorage; import refinedstorage.api.network.GridExtractFlags; +import refinedstorage.apiimpl.storage.ClientStack; import refinedstorage.block.EnumGridType; import refinedstorage.container.ContainerGrid; import refinedstorage.gui.sidebutton.SideButtonGridSearchBoxMode; @@ -33,11 +33,11 @@ import java.io.IOException; import java.util.*; public class GuiGrid extends GuiBase { - private Comparator quantityComparator = new Comparator() { + private Comparator quantityComparator = new Comparator() { @Override - public int compare(ItemStack left, ItemStack right) { - int leftSize = left.stackSize; - int rightSize = right.stackSize; + public int compare(ClientStack left, ClientStack right) { + int leftSize = left.getStack().stackSize; + int rightSize = right.getStack().stackSize; if (leftSize == rightSize) { return 0; @@ -53,13 +53,13 @@ public class GuiGrid extends GuiBase { } }; - private Comparator nameComparator = new Comparator() { + private Comparator nameComparator = new Comparator() { @Override - public int compare(ItemStack left, ItemStack right) { + public int compare(ClientStack left, ClientStack right) { if (grid.getSortingDirection() == TileGrid.SORTING_DIRECTION_ASCENDING) { - return left.getDisplayName().compareTo(right.getDisplayName()); + return left.getStack().getDisplayName().compareTo(right.getStack().getDisplayName()); } else if (grid.getSortingDirection() == TileGrid.SORTING_DIRECTION_DESCENDING) { - return right.getDisplayName().compareTo(left.getDisplayName()); + return right.getStack().getDisplayName().compareTo(left.getStack().getDisplayName()); } return 0; @@ -69,7 +69,7 @@ public class GuiGrid extends GuiBase { private GuiTextField searchField; private ContainerGrid container; - private List items = new ArrayList(); + private List items = new ArrayList(); private IGrid grid; private int slotNumber; @@ -124,10 +124,10 @@ public class GuiGrid extends GuiBase { String query = searchField.getText().trim().toLowerCase(); if (!query.isEmpty()) { - Iterator t = items.iterator(); + Iterator t = items.iterator(); while (t.hasNext()) { - ItemStack item = t.next(); + ItemStack item = t.next().getStack(); if (query.startsWith("@")) { String[] parts = query.split(" "); @@ -266,9 +266,7 @@ public class GuiGrid extends GuiBase { } if (slot < items.size()) { - ItemStack stack = items.get(slot); - - drawItem(x, y, stack, true, formatQuantity(stack.stackSize, slot)); + drawItem(x, y, items.get(slot).getStack(), true, formatQuantity(items.get(slot).getStack().stackSize, slot)); } if (inBounds(x, y, 16, 16, mouseX, mouseY) || !grid.isConnected()) { @@ -296,11 +294,7 @@ public class GuiGrid extends GuiBase { } if (isOverSlotWithItem()) { - /** - * Some mods modify the NBT tag in {@link Item#addInformation(ItemStack, EntityPlayer, List, boolean)} - * and that would cause a client and server desync between the items and that makes pulling fail. - */ - drawTooltip(mouseX, mouseY, items.get(slotNumber).copy()); + drawTooltip(mouseX, mouseY, items.get(slotNumber).getStack()); } if (isOverClear(mouseX, mouseY)) { @@ -362,7 +356,7 @@ public class GuiGrid extends GuiBase { } if (isOverSlotWithItem() && (held == null || (held != null && clickedButton == 2))) { - if (items.get(slotNumber).stackSize == 0 || (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown())) { + if (items.get(slotNumber).isCraftable() && (items.get(slotNumber).getStack().stackSize == 0 || (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown()))) { FMLCommonHandler.instance().showGuiScreen(new GuiCraftingSettings(this, container.getPlayer(), items.get(slotNumber))); } else { int flags = 0; @@ -379,7 +373,7 @@ public class GuiGrid extends GuiBase { flags |= GridExtractFlags.EXTRACT_SINGLE; } - RefinedStorage.INSTANCE.network.sendToServer(new MessageGridPull(items.get(slotNumber), flags)); + RefinedStorage.INSTANCE.network.sendToServer(new MessageGridPull(items.get(slotNumber).getId(), flags)); } } } diff --git a/src/main/java/refinedstorage/network/MessageGridCraftingStart.java b/src/main/java/refinedstorage/network/MessageGridCraftingStart.java index 4c09de335..e0d610f9e 100755 --- a/src/main/java/refinedstorage/network/MessageGridCraftingStart.java +++ b/src/main/java/refinedstorage/network/MessageGridCraftingStart.java @@ -3,33 +3,31 @@ package refinedstorage.network; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import refinedstorage.api.network.IGridHandler; import refinedstorage.container.ContainerGrid; public class MessageGridCraftingStart extends MessageHandlerPlayerToServer implements IMessage { - private ItemStack stack; + private int id; private int quantity; public MessageGridCraftingStart() { } - public MessageGridCraftingStart(ItemStack stack, int quantity) { - this.stack = stack; + public MessageGridCraftingStart(int id, int quantity) { + this.id = id; this.quantity = quantity; } @Override public void fromBytes(ByteBuf buf) { - stack = ByteBufUtils.readItemStack(buf); + id = buf.readInt(); quantity = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { - ByteBufUtils.writeItemStack(buf, stack); + buf.writeInt(id); buf.writeInt(quantity); } @@ -41,7 +39,7 @@ public class MessageGridCraftingStart extends MessageHandlerPlayerToServer { + private INetworkMaster network; private ItemStack stack; private int delta; - private boolean craftable; + + private ClientStack clientStack; public MessageGridDelta() { } - public MessageGridDelta(ItemStack stack, int delta, boolean craftable) { + public MessageGridDelta(INetworkMaster network, ItemStack stack, int delta) { + this.network = network; this.stack = stack; this.delta = delta; - this.craftable = craftable; } @Override public void fromBytes(ByteBuf buf) { - stack = ByteBufUtils.readItemStack(buf); + clientStack = RefinedStorageUtils.readClientStack(buf); delta = buf.readInt(); - craftable = buf.readBoolean(); } @Override public void toBytes(ByteBuf buf) { - ByteBufUtils.writeItemStack(buf, stack); + RefinedStorageUtils.writeClientStack(buf, network, stack); buf.writeInt(delta); - buf.writeBoolean(craftable); } @Override public IMessage onMessage(MessageGridDelta message, MessageContext ctx) { - for (ItemStack stack : RefinedStorage.INSTANCE.items) { - if (RefinedStorageUtils.compareStackNoQuantity(stack, message.stack)) { - if (stack.stackSize + message.delta == 0 && !message.craftable) { + for (ClientStack stack : RefinedStorage.INSTANCE.items) { + if (stack.equals(message.clientStack)) { + if (stack.getStack().stackSize + message.delta == 0 && !message.clientStack.isCraftable()) { RefinedStorage.INSTANCE.items.remove(stack); } else { - stack.stackSize += message.delta; + stack.getStack().stackSize += message.delta; } return null; } } - RefinedStorage.INSTANCE.items.add(ItemHandlerHelper.copyStackWithSize(message.stack, message.delta)); + RefinedStorage.INSTANCE.items.add(message.clientStack); return null; } diff --git a/src/main/java/refinedstorage/network/MessageGridPull.java b/src/main/java/refinedstorage/network/MessageGridPull.java index 9e3b7c088..fae730e05 100755 --- a/src/main/java/refinedstorage/network/MessageGridPull.java +++ b/src/main/java/refinedstorage/network/MessageGridPull.java @@ -3,33 +3,31 @@ package refinedstorage.network; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import refinedstorage.api.network.IGridHandler; import refinedstorage.container.ContainerGrid; public class MessageGridPull extends MessageHandlerPlayerToServer implements IMessage { - private ItemStack stack; + private int id; private int flags; public MessageGridPull() { } - public MessageGridPull(ItemStack stack, int flags) { - this.stack = stack; + public MessageGridPull(int id, int flags) { + this.id = id; this.flags = flags; } @Override public void fromBytes(ByteBuf buf) { - stack = ByteBufUtils.readItemStack(buf); + id = buf.readInt(); flags = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { - ByteBufUtils.writeItemStack(buf, stack); + buf.writeInt(id); buf.writeInt(flags); } @@ -41,7 +39,7 @@ public class MessageGridPull extends MessageHandlerPlayerToServer { private INetworkMaster network; - private List items = new ArrayList(); + private List items = new ArrayList(); public MessageGridUpdate() { } @@ -28,10 +29,7 @@ public class MessageGridUpdate implements IMessage, IMessageHandler