From 892091073e2ed664664fbdf880ac09ee8575705e Mon Sep 17 00:00:00 2001 From: FlorianMichael <60033407+FlorianMichael@users.noreply.github.com> Date: Tue, 18 Jul 2023 05:46:04 +0200 Subject: [PATCH] Implemented AlphaInventoryProvider (Fixed Issue 11 from https://github.com/ViaVersion/ViaFabricPlus/issues/178) --- .../impl/ViaFabricPlusVLLoader.java | 2 + .../ViaFabricPlusAlphaInventoryProvider.java | 89 +++++++++++++++++++ .../protocolhack/util/ItemTranslator.java | 46 ++++++++-- 3 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialegacy/ViaFabricPlusAlphaInventoryProvider.java diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/impl/ViaFabricPlusVLLoader.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/impl/ViaFabricPlusVLLoader.java index 35758d35..3dbda640 100644 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/impl/ViaFabricPlusVLLoader.java +++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/impl/ViaFabricPlusVLLoader.java @@ -38,6 +38,7 @@ import de.florianmichael.viafabricplus.protocolhack.provider.viaversion.ViaFabri import net.raphimc.viabedrock.protocol.providers.BlobCacheProvider; import net.raphimc.viabedrock.protocol.providers.NettyPipelineProvider; import net.raphimc.viabedrock.protocol.providers.TransferProvider; +import net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.providers.AlphaInventoryProvider; import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicMPPassProvider; import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicWorldHeightProvider; import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.providers.OldAuthProvider; @@ -67,6 +68,7 @@ public class ViaFabricPlusVLLoader extends VLLoader { providers.use(EncryptionProvider.class, new ViaFabricPlusEncryptionProvider()); providers.use(GameProfileFetcher.class, new ViaFabricPlusGameProfileFetcher()); providers.use(ClassicMPPassProvider.class, new ViaFabricPlusClassicMPPassProvider()); + providers.use(AlphaInventoryProvider.class, new ViaFabricPlusAlphaInventoryProvider()); providers.use(NettyPipelineProvider.class, new ViaFabricPlusNettyPipelineProvider()); providers.use(BlobCacheProvider.class, new ViaFabricPlusBlobCacheProvider()); diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialegacy/ViaFabricPlusAlphaInventoryProvider.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialegacy/ViaFabricPlusAlphaInventoryProvider.java new file mode 100644 index 00000000..062e7b08 --- /dev/null +++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/vialegacy/ViaFabricPlusAlphaInventoryProvider.java @@ -0,0 +1,89 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus + * Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.florianmichael.viafabricplus.protocolhack.provider.vialegacy; + +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.item.Item; +import de.florianmichael.viafabricplus.protocolhack.util.ItemTranslator; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.item.ItemStack; +import net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.providers.AlphaInventoryProvider; +import net.raphimc.vialegacy.protocols.beta.protocol1_0_0_1tob1_8_0_1.types.Typesb1_8_0_1; +import net.raphimc.vialoader.util.VersionEnum; + +import java.util.List; + +import static net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.Protocolb1_0_1_1_1toa1_2_3_5_1_2_6.copyItems; + +public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider { + + @Override + public boolean usesInventoryTracker() { + return false; + } + + protected Item[] getMinecraftContainerItems(final List trackingItems) { + final var items = new Item[trackingItems.size()]; + + for (int i = 0; i < items.length; i++) { + final var alphaItem = trackingItems.get(i); + if (alphaItem.isEmpty()) continue; + + items[i] = ItemTranslator.minecraftToViaVersion(alphaItem, Typesb1_8_0_1.CREATIVE_ITEM, VersionEnum.b1_8tob1_8_1.getVersion()); + } + return copyItems(items); + } + + @Override + public Item[] getMainInventoryItems(UserConnection user) { + if (getPlayer() == null) return new Item[37]; + + return getMinecraftContainerItems(getPlayer().getInventory().main); + } + + @Override + public Item[] getCraftingInventoryItems(UserConnection user) { + if (getPlayer() == null) return new Item[4]; + + return getMinecraftContainerItems(getPlayer().playerScreenHandler.getCraftingInput().getInputStacks()); + } + + @Override + public Item[] getArmorInventoryItems(UserConnection user) { + if (getPlayer() == null) return new Item[4]; + + return getMinecraftContainerItems(getPlayer().getInventory().armor); + } + + @Override + public Item[] getContainerItems(UserConnection user) { + if (getPlayer() == null) return new Item[37]; + + return getMinecraftContainerItems(getPlayer().currentScreenHandler.getStacks()); + } + + @Override + public void addToInventory(UserConnection user, Item item) { + getPlayer().getInventory().insertStack(ItemTranslator.viaVersionToMinecraft(item, VersionEnum.b1_8tob1_8_1.getVersion())); + } + + protected ClientPlayerEntity getPlayer() { + return MinecraftClient.getInstance().player; + } +} diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/util/ItemTranslator.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/util/ItemTranslator.java index 4f1ccf67..10aa27f5 100644 --- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/util/ItemTranslator.java +++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/util/ItemTranslator.java @@ -22,11 +22,11 @@ import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; import com.viaversion.viaversion.api.protocol.packet.Direction; -import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.State; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.connection.UserConnectionImpl; import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl; +import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.InventoryTracker; import io.netty.buffer.Unpooled; import net.minecraft.SharedConstants; import net.minecraft.item.ItemStack; @@ -34,6 +34,10 @@ import net.minecraft.network.NetworkSide; import net.minecraft.network.NetworkState; import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket; +import net.minecraft.registry.Registries; +import net.raphimc.vialegacy.protocols.beta.protocol1_0_0_1tob1_8_0_1.ClientboundPacketsb1_8; +import net.raphimc.vialegacy.protocols.release.protocol1_4_4_5to1_4_2.types.Types1_4_2; +import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.storage.WindowTracker; import java.util.List; import java.util.stream.Collectors; @@ -42,24 +46,56 @@ public class ItemTranslator { private final static UserConnection DUMMY_USER_CONNECTION = new UserConnectionImpl(null, false); public static Item minecraftToViaVersion(final ItemStack stack, final int targetVersion) { + return minecraftToViaVersion(stack, Type.ITEM, targetVersion); + } + + public static Item minecraftToViaVersion(final ItemStack stack, final Type item, final int targetVersion) { final List protocolPath = Via.getManager().getProtocolManager().getProtocolPath(SharedConstants.getProtocolVersion(), targetVersion); if (protocolPath == null) return null; - final CreativeInventoryActionC2SPacket dummyPacket = new CreativeInventoryActionC2SPacket(36, stack); - final PacketByteBuf emptyBuf = new PacketByteBuf(Unpooled.buffer()); + final var dummyPacket = new CreativeInventoryActionC2SPacket(36, stack); + final var emptyBuf = new PacketByteBuf(Unpooled.buffer()); dummyPacket.write(emptyBuf); final int id = NetworkState.PLAY.getPacketId(NetworkSide.SERVERBOUND, dummyPacket); try { - final PacketWrapper wrapper = new PacketWrapperImpl(id, emptyBuf, DUMMY_USER_CONNECTION); + final var wrapper = new PacketWrapperImpl(id, emptyBuf, DUMMY_USER_CONNECTION); wrapper.apply(Direction.SERVERBOUND, State.PLAY, 0, protocolPath.stream().map(ProtocolPathEntry::protocol).collect(Collectors.toList())); wrapper.read(Type.SHORT); - return wrapper.read(Type.ITEM); + return wrapper.read(item); } catch (Exception e) { e.printStackTrace(); } return null; } + + public static ItemStack viaVersionToMinecraft(final Item item, final int targetVersion) { + final List protocolPath = Via.getManager().getProtocolManager().getProtocolPath(SharedConstants.getProtocolVersion(), targetVersion); + if (protocolPath == null) return null; + + DUMMY_USER_CONNECTION.put(new WindowTracker(DUMMY_USER_CONNECTION)); + DUMMY_USER_CONNECTION.put(new InventoryTracker()); + + try { + final var wrapper = new PacketWrapperImpl(ClientboundPacketsb1_8.SET_SLOT.getId(), null, DUMMY_USER_CONNECTION); + wrapper.write(Type.BYTE, (byte) 0); // Window ID + wrapper.write(Type.SHORT, (short) 0); // Slot + wrapper.write(Types1_4_2.NBTLESS_ITEM, item); // Item + + wrapper.resetReader(); + + wrapper.apply(Direction.CLIENTBOUND, State.PLAY, 0, protocolPath.stream().map(ProtocolPathEntry::protocol).collect(Collectors.toList()), true); + + wrapper.read(Type.UNSIGNED_BYTE); + wrapper.read(Type.VAR_INT); + wrapper.read(Type.SHORT); + + final var viaItem = wrapper.read(Type.FLAT_VAR_INT_ITEM); + return new ItemStack(() -> Registries.ITEM.get(viaItem.identifier()), viaItem.amount()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } }