diff --git a/src/main/java/de/ellpeck/prettypipes/compat/jei/CraftingTerminalTransferHandler.java b/src/main/java/de/ellpeck/prettypipes/compat/jei/CraftingTerminalTransferHandler.java index 77c55bb..af6f5b0 100644 --- a/src/main/java/de/ellpeck/prettypipes/compat/jei/CraftingTerminalTransferHandler.java +++ b/src/main/java/de/ellpeck/prettypipes/compat/jei/CraftingTerminalTransferHandler.java @@ -1,7 +1,5 @@ package de.ellpeck.prettypipes.compat.jei; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; import de.ellpeck.prettypipes.packets.PacketGhostSlot; import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.terminal.containers.CraftingTerminalContainer; @@ -9,10 +7,11 @@ import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingRecipe; import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; public class CraftingTerminalTransferHandler implements IRecipeTransferHandler { @@ -31,11 +30,11 @@ public class CraftingTerminalTransferHandler implements IRecipeTransferHandler stacks = ArrayListMultimap.create(); + Map stacks = new HashMap<>(); var ingredients = recipeLayout.getItemStacks().getGuiIngredients(); for (var entry : ingredients.entrySet()) { if (entry.getValue().isInput()) - stacks.putAll(entry.getKey() - 1, entry.getValue().getAllIngredients()); + stacks.put(entry.getKey() - 1, new PacketGhostSlot.Entry(entry.getValue().getAllIngredients())); } PacketHandler.sendToServer(new PacketGhostSlot(container.getTile().getBlockPos(), stacks)); return null; diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketGhostSlot.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketGhostSlot.java index 627e1e1..38ad98e 100644 --- a/src/main/java/de/ellpeck/prettypipes/packets/PacketGhostSlot.java +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketGhostSlot.java @@ -1,26 +1,35 @@ package de.ellpeck.prettypipes.packets; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; +import com.google.common.collect.Streams; +import com.mojang.datafixers.util.Pair; import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.terminal.CraftingTerminalBlockEntity; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraftforge.network.NetworkEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.stream.Collectors; public class PacketGhostSlot { private BlockPos pos; - private ListMultimap stacks; + private Map stacks; - public PacketGhostSlot(BlockPos pos, ListMultimap stacks) { + public PacketGhostSlot(BlockPos pos, Map stacks) { this.pos = pos; this.stacks = stacks; } @@ -32,18 +41,18 @@ public class PacketGhostSlot { public static PacketGhostSlot fromBytes(FriendlyByteBuf buf) { var packet = new PacketGhostSlot(); packet.pos = buf.readBlockPos(); - packet.stacks = ArrayListMultimap.create(); + packet.stacks = new HashMap<>(); for (var i = buf.readInt(); i > 0; i--) - packet.stacks.put(buf.readInt(), buf.readItem()); + packet.stacks.put(buf.readInt(), new Entry(buf)); return packet; } public static void toBytes(PacketGhostSlot packet, FriendlyByteBuf buf) { buf.writeBlockPos(packet.pos); buf.writeInt(packet.stacks.size()); - for (var entry : packet.stacks.entries()) { + for (var entry : packet.stacks.entrySet()) { buf.writeInt(entry.getKey()); - buf.writeItem(entry.getValue()); + entry.getValue().write(buf); } } @@ -77,4 +86,67 @@ public class PacketGhostSlot { ctx.get().setPacketHandled(true); } + + public static class Entry { + + private final List stacks; + private final TagKey tag; + + public Entry(List stacks) { + var tag = getTagForStacks(stacks); + if (tag != null) { + this.stacks = null; + this.tag = tag; + } else { + this.stacks = stacks; + this.tag = null; + } + } + + public Entry(FriendlyByteBuf buf) { + if (buf.readBoolean()) { + this.tag = null; + this.stacks = new ArrayList<>(); + for (var i = buf.readInt(); i > 0; i--) + this.stacks.add(buf.readItem()); + } else { + this.stacks = null; + this.tag = TagKey.create(Registry.ITEM_REGISTRY, new ResourceLocation(buf.readUtf())); + } + } + + public List getStacks() { + if (this.stacks != null) + return this.stacks; + return Streams.stream(Registry.ITEM.getTagOrEmpty(this.tag).iterator()) + .filter(h -> h.value() != null & h.value() != Items.AIR) + .map(h -> new ItemStack(h.value())).collect(Collectors.toList()); + } + + public FriendlyByteBuf write(FriendlyByteBuf buf) { + if (this.stacks != null) { + buf.writeBoolean(true); + buf.writeInt(this.stacks.size()); + for (var stack : this.stacks) + buf.writeItem(stack); + } else { + buf.writeBoolean(false); + buf.writeUtf(this.tag.location().toString()); + } + return buf; + } + + private static TagKey getTagForStacks(List stacks) { + return Registry.ITEM.getTags().filter(e -> { + var tag = e.getSecond(); + if (tag.size() != stacks.size()) + return false; + for (var i = 0; i < tag.size(); i++) { + if (stacks.get(i).getItem() != tag.get(i).value()) + return false; + } + return true; + }).map(Pair::getFirst).findFirst().orElse(null); + } + } } diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlockEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlockEntity.java index 4c372e9..be91b82 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlockEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/CraftingTerminalBlockEntity.java @@ -1,7 +1,5 @@ package de.ellpeck.prettypipes.terminal; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Utility; @@ -61,10 +59,10 @@ public class CraftingTerminalBlockEntity extends ItemTerminalBlockEntity { return this.craftItems.getStackInSlot(slot).isEmpty() && !this.ghostItems.getStackInSlot(slot).isEmpty(); } - public void setGhostItems(ListMultimap stacks) { + public void setGhostItems(Map stacks) { this.updateItems(); for (var i = 0; i < this.ghostItems.getSlots(); i++) { - var items = stacks.get(i); + var items = stacks.get(i).getStacks(); if (items.isEmpty()) { this.ghostItems.setStackInSlot(i, ItemStack.EMPTY); continue; @@ -98,9 +96,9 @@ public class CraftingTerminalBlockEntity extends ItemTerminalBlockEntity { } if (!this.level.isClientSide) { - ListMultimap clients = ArrayListMultimap.create(); + Map clients = new HashMap<>(); for (var i = 0; i < this.ghostItems.getSlots(); i++) - clients.put(i, this.ghostItems.getStackInSlot(i)); + clients.put(i, new PacketGhostSlot.Entry(Collections.singletonList(this.ghostItems.getStackInSlot(i)))); PacketHandler.sendToAllLoaded(this.level, this.getBlockPos(), new PacketGhostSlot(this.getBlockPos(), clients)); } } @@ -133,8 +131,7 @@ public class CraftingTerminalBlockEntity extends ItemTerminalBlockEntity { this.requestItemImpl(requested, onItemUnavailable(player, force)); } player.sendMessage(new TranslatableComponent("info." + PrettyPipes.ID + ".sending_ingredients", lowestAvailable).setStyle(Style.EMPTY.applyFormat(ChatFormatting.GREEN)), UUID.randomUUID()); - } - else{ + } else { player.sendMessage(new TranslatableComponent("info." + PrettyPipes.ID + ".hold_alt"), UUID.randomUUID()); } network.endProfile();