diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/Type.java b/api/src/main/java/com/viaversion/viaversion/api/type/Type.java index 378ca54ab..5fb7eed53 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/Type.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/Type.java @@ -179,7 +179,7 @@ public abstract class Type implements ByteBufReader, ByteBufWriter { public static final Type FLAT_VAR_INT_ITEM_ARRAY_VAR_INT = new ArrayType<>(FLAT_VAR_INT_ITEM); public static final Type ITEM1_20_2 = new Item1_20_2Type(); - public static final Type ITEM1_20_2_ARRAY_VAR_INT = new ArrayType<>(ITEM1_20_2); + public static final Type ITEM1_20_2_VAR_INT_ARRAY = new ArrayType<>(ITEM1_20_2); /* Actual Class */ private final Class outputClass; diff --git a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java index 1b1421734..e2e01e715 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java @@ -83,6 +83,9 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; +import org.checkerframework.checker.nullness.qual.Nullable; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -103,8 +106,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Function; -import org.checkerframework.checker.nullness.qual.Nullable; -import us.myles.ViaVersion.api.protocol.ProtocolRegistry; public class ProtocolManagerImpl implements ProtocolManager { private static final Protocol BASE_PROTOCOL = new BaseProtocol(); @@ -135,7 +136,7 @@ public class ProtocolManagerImpl implements ProtocolManager { // Base Protocol registerBaseProtocol(BASE_PROTOCOL, Range.lessThan(Integer.MIN_VALUE)); registerBaseProtocol(new BaseProtocol1_7(), Range.lessThan(ProtocolVersion.v1_16.getVersion())); - registerBaseProtocol(new BaseProtocol1_16(), Range.atLeast(ProtocolVersion.v1_16.getVersion())); + registerBaseProtocol(new BaseProtocol1_16(), Range.closed(ProtocolVersion.v1_16.getVersion(), ProtocolVersion.v1_20.getVersion())); registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_9, ProtocolVersion.v1_8); registerProtocol(new Protocol1_9_1To1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getVersion(), ProtocolVersion.v1_9_2.getVersion()), ProtocolVersion.v1_9.getVersion()); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_16.java b/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_16.java index 089e56d8b..07d3abed1 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_16.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_16.java @@ -19,15 +19,11 @@ package com.viaversion.viaversion.protocols.base; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.type.Type; + import java.util.UUID; public class BaseProtocol1_16 extends BaseProtocol1_7 { - @Override - protected boolean finishLoginAfterGameprofile() { - return false; // Start CONFIGURATION phase after the serverbound ack - } - @Override protected UUID passthroughLoginUUID(final PacketWrapper wrapper) throws Exception { return wrapper.passthrough(Type.UUID); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_7.java b/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_7.java index 9c0069d30..979756085 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_7.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol1_7.java @@ -121,7 +121,7 @@ public class BaseProtocol1_7 extends AbstractProtocol { // Login Success Packet registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> { ProtocolInfo info = wrapper.user().getProtocolInfo(); - if (finishLoginAfterGameprofile()) { + if (info.getProtocolVersion() < ProtocolVersion.v1_20_2.getVersion()) { info.setState(State.PLAY); } @@ -166,8 +166,6 @@ public class BaseProtocol1_7 extends AbstractProtocol { }); registerServerbound(ServerboundLoginPackets.LOGIN_ACKNOWLEDGED, wrapper -> wrapper.user().getProtocolInfo().setState(State.CONFIGURATION)); - // TODO AAAAAAAAAAAAAAAAA - registerServerbound(ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION, wrapper -> wrapper.user().getProtocolInfo().setState(State.PLAY)); } @Override @@ -192,8 +190,4 @@ public class BaseProtocol1_7 extends AbstractProtocol { } return UUID.fromString(uuidString); } - - protected boolean finishLoginAfterGameprofile() { - return true; - } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/base/ServerboundLoginPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/base/ServerboundLoginPackets.java index f0cfaed24..7a30257a7 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/base/ServerboundLoginPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/base/ServerboundLoginPackets.java @@ -23,9 +23,8 @@ import com.viaversion.viaversion.api.protocol.packet.State; public enum ServerboundLoginPackets implements ServerboundPacketType { HELLO, // 0x00 ENCRYPTION_KEY, // 0x01 - CUSTOM_QUERY, // 0x02 - CUSTOM_QUERY_ANSWER, // 0x03 - LOGIN_ACKNOWLEDGED; // 0x04 + CUSTOM_QUERY_ANSWER, // 0x02 + LOGIN_ACKNOWLEDGED; // 0x03 @Override public final int getId() { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_19_3to1_19_1/rewriter/RecipeRewriter1_19_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_19_3to1_19_1/rewriter/RecipeRewriter1_19_3.java index 7254633a3..165822278 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_19_3to1_19_1/rewriter/RecipeRewriter1_19_3.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_19_3to1_19_1/rewriter/RecipeRewriter1_19_3.java @@ -48,7 +48,7 @@ public class RecipeRewriter1_19_3 extends Recip wrapper.passthrough(Type.STRING); // Group wrapper.passthrough(Type.VAR_INT); // Crafting book category handleIngredients(wrapper); - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } @Override @@ -59,7 +59,7 @@ public class RecipeRewriter1_19_3 extends Recip for (int i = 0; i < ingredients; i++) { handleIngredient(wrapper); } - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } @Override @@ -67,7 +67,7 @@ public class RecipeRewriter1_19_3 extends Recip wrapper.passthrough(Type.STRING); // Group wrapper.passthrough(Type.VAR_INT); // Crafting book category handleIngredient(wrapper); - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result wrapper.passthrough(Type.FLOAT); // EXP wrapper.passthrough(Type.VAR_INT); // Cooking time } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/Protocol1_20_2To1_20.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/Protocol1_20_2To1_20.java index 5dd3404f8..705c1f0e9 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/Protocol1_20_2To1_20.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/Protocol1_20_2To1_20.java @@ -28,19 +28,24 @@ import com.viaversion.viaversion.api.rewriter.EntityRewriter; import com.viaversion.viaversion.api.rewriter.ItemRewriter; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.data.entity.EntityTrackerBase; +import com.viaversion.viaversion.exception.CancelException; +import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl; +import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets; import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4; import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ServerboundPackets1_19_4; -import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.BlockItemPacketRewriter1_20_2; -import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.EntityPacketRewriter1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2; +import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.BlockItemPacketRewriter1_20_2; +import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.EntityPacketRewriter1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.FakeProtocolState; import com.viaversion.viaversion.rewriter.SoundRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.UUID; @@ -57,8 +62,6 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol { + wrapper.user().get(FakeProtocolState.class).setGameProfileSent(true); + }); + registerServerbound(State.LOGIN, ServerboundLoginPackets.LOGIN_ACKNOWLEDGED.getId(), -1, wrapper -> { + System.out.println("Login acknowleged!"); + wrapper.user().getProtocolInfo().setState(State.PLAY); wrapper.user().get(FakeProtocolState.class).setConfigurationState(true); wrapper.cancel(); }); + cancelServerbound(State.LOGIN, ServerboundLoginPackets.CUSTOM_QUERY_ANSWER.getId()); // TODO ? + // TODO Make sure this is called in other protocols as well/the base protocol registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION.getId(), -1, wrapper -> { wrapper.user().get(FakeProtocolState.class).setConfigurationState(false); + System.out.println("NOW PLAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"); wrapper.cancel(); }); - registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), ServerboundPackets1_19_4.PLUGIN_MESSAGE.getId(), wrapper -> { + registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, wrapper -> { + if (wrapper.user().getProtocolInfo().getState() == State.PLAY) { + wrapper.setPacketType(ServerboundPackets1_19_4.PLUGIN_MESSAGE); + } else { + wrapper.user().get(FakeProtocolState.class).addPacketToQueue(wrapper, false); + wrapper.cancel(); + } }); registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), ServerboundPackets1_19_4.KEEP_ALIVE.getId(), wrapper -> { }); @@ -120,47 +138,55 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol { public BlockItemPacketRewriter1_20_2(final Protocol1_20_2To1_20 protocol) { - super(protocol); + super(protocol, Type.ITEM1_20_2, Type.ITEM1_20_2_VAR_INT_ARRAY); } @Override @@ -37,5 +48,250 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter { + wrapper.passthrough(Type.VAR_INT); // Transaction id + wrapper.write(Type.NAMELESS_NBT, wrapper.read(Type.NBT)); + }); + + protocol.registerClientbound(ClientboundPackets1_19_4.BLOCK_ENTITY_DATA, wrapper -> { + wrapper.passthrough(Type.POSITION1_14); // Position + wrapper.passthrough(Type.VAR_INT); // Type + wrapper.write(Type.NAMELESS_NBT, wrapper.read(Type.NBT)); + }); + + protocol.registerClientbound(ClientboundPackets1_19_4.CHUNK_DATA, wrapper -> { + final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user()); + final Type chunkType = new Chunk1_18Type(tracker.currentWorldSectionHeight(), + MathUtil.ceilLog2(Protocol1_20To1_19_4.MAPPINGS.getBlockStateMappings().mappedSize()), + MathUtil.ceilLog2(tracker.biomesSent())); + final Chunk chunk = wrapper.read(chunkType); + + final Type newChunkType = new Chunk1_20_2Type(tracker.currentWorldSectionHeight(), + MathUtil.ceilLog2(Protocol1_20To1_19_4.MAPPINGS.getBlockStateMappings().mappedSize()), + MathUtil.ceilLog2(tracker.biomesSent())); + wrapper.write(newChunkType, chunk); + }); + + // Weeeeeeeeeeeeeeeeeeeeeeeeeeeeee + protocol.registerClientbound(ClientboundPackets1_19_4.WINDOW_ITEMS, new PacketHandlers() { + @Override + public void register() { + map(Type.UNSIGNED_BYTE); // Window id + map(Type.VAR_INT); // State id + handler(wrapper -> { + wrapper.write(Type.ITEM1_20_2_VAR_INT_ARRAY, wrapper.read(Type.FLAT_ITEM_ARRAY_VAR_INT)); // Items + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Carried item + }); + } + }); + protocol.registerClientbound(ClientboundPackets1_19_4.SET_SLOT, new PacketHandlers() { + @Override + public void register() { + map(Type.UNSIGNED_BYTE); // Window id + map(Type.VAR_INT); // State id + map(Type.SHORT); // Slot id + map(Type.FLAT_VAR_INT_ITEM, Type.ITEM1_20_2); // Item + } + }); + protocol.registerClientbound(ClientboundPackets1_19_4.ADVANCEMENTS, wrapper -> { + wrapper.passthrough(Type.BOOLEAN); // Reset/clear + int size = wrapper.passthrough(Type.VAR_INT); // Mapping size + for (int i = 0; i < size; i++) { + wrapper.passthrough(Type.STRING); // Identifier + + // Parent + if (wrapper.passthrough(Type.BOOLEAN)) + wrapper.passthrough(Type.STRING); + + // Display data + if (wrapper.passthrough(Type.BOOLEAN)) { + wrapper.passthrough(Type.COMPONENT); // Title + wrapper.passthrough(Type.COMPONENT); // Description + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Icon + wrapper.passthrough(Type.VAR_INT); // Frame type + int flags = wrapper.passthrough(Type.INT); // Flags + if ((flags & 1) != 0) { + wrapper.passthrough(Type.STRING); // Background texture + } + wrapper.passthrough(Type.FLOAT); // X + wrapper.passthrough(Type.FLOAT); // Y + } + + wrapper.passthrough(Type.STRING_ARRAY); // Criteria + + int arrayLength = wrapper.passthrough(Type.VAR_INT); + for (int array = 0; array < arrayLength; array++) { + wrapper.passthrough(Type.STRING_ARRAY); // String array + } + + wrapper.passthrough(Type.BOOLEAN); // Send telemetry + } + }); + protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_EQUIPMENT, new PacketHandlers() { + @Override + public void register() { + map(Type.VAR_INT); // 0 - Entity ID + handler(wrapper -> { + byte slot; + do { + slot = wrapper.passthrough(Type.BYTE); + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + } while ((slot & 0xFFFFFF80) != 0); + }); + } + }); + protocol.registerServerbound(ServerboundPackets1_20_2.CLICK_WINDOW, new PacketHandlers() { + @Override + public void register() { + map(Type.UNSIGNED_BYTE); // Window Id + map(Type.VAR_INT); // State id + map(Type.SHORT); // Slot + map(Type.BYTE); // Button + map(Type.VAR_INT); // Mode + + handler(wrapper -> { + // Affected items + int length = wrapper.passthrough(Type.VAR_INT); + for (int i = 0; i < length; i++) { + wrapper.passthrough(Type.SHORT); // Slot + wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); + } + + // Carried item + wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); + }); + } + }); + protocol.registerClientbound(ClientboundPackets1_19_4.TRADE_LIST, wrapper -> { + wrapper.passthrough(Type.VAR_INT); // Container id + int size = wrapper.passthrough(Type.VAR_INT); + for (int i = 0; i < size; i++) { + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Input + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Output + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Second Item + + wrapper.passthrough(Type.BOOLEAN); // Trade disabled + wrapper.passthrough(Type.INT); // Number of tools uses + wrapper.passthrough(Type.INT); // Maximum number of trade uses + + wrapper.passthrough(Type.INT); // XP + wrapper.passthrough(Type.INT); // Special price + wrapper.passthrough(Type.FLOAT); // Price multiplier + wrapper.passthrough(Type.INT); // Demand + } + }); + protocol.registerServerbound(ServerboundPackets1_20_2.CREATIVE_INVENTORY_ACTION, new PacketHandlers() { + @Override + public void register() { + map(Type.SHORT); // 0 - Slot + map(Type.ITEM1_20_2, Type.FLAT_VAR_INT_ITEM); // 1 - Clicked Item + } + }); + protocol.registerClientbound(ClientboundPackets1_19_4.SPAWN_PARTICLE, new PacketHandlers() { + @Override + public void register() { + map(Type.VAR_INT); // 0 - Particle ID + map(Type.BOOLEAN); // 1 - Long Distance + map(Type.DOUBLE); // 2 - X + map(Type.DOUBLE); // 3 - Y + map(Type.DOUBLE); // 4 - Z + map(Type.FLOAT); // 5 - Offset X + map(Type.FLOAT); // 6 - Offset Y + map(Type.FLOAT); // 7 - Offset Z + map(Type.FLOAT); // 8 - Particle Data + map(Type.INT); // 9 - Particle Count + handler(wrapper -> { + int id = wrapper.get(Type.VAR_INT, 0); + ParticleMappings mappings = Protocol1_20To1_19_4.MAPPINGS.getParticleMappings(); + if (mappings.isItemParticle(id)) { + wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); + } + }); + } + }); + + new RecipeRewriter1_19_4(protocol) { + @Override + public void handleCraftingShapeless(final PacketWrapper wrapper) throws Exception { + wrapper.passthrough(Type.STRING); // Group + wrapper.passthrough(Type.VAR_INT); // Crafting book category + handleIngredients(wrapper); + + final Item result = wrapper.read(itemType()); + rewrite(result); + wrapper.write(Type.ITEM1_20_2, result); + } + + @Override + public void handleSmelting(final PacketWrapper wrapper) throws Exception { + wrapper.passthrough(Type.STRING); // Group + wrapper.passthrough(Type.VAR_INT); // Crafting book category + handleIngredient(wrapper); + + final Item result = wrapper.read(itemType()); + rewrite(result); + wrapper.write(Type.ITEM1_20_2, result); + + wrapper.passthrough(Type.FLOAT); // EXP + wrapper.passthrough(Type.VAR_INT); // Cooking time + } + + @Override + public void handleCraftingShaped(final PacketWrapper wrapper) throws Exception { + final int ingredients = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT); + wrapper.passthrough(Type.STRING); // Group + wrapper.passthrough(Type.VAR_INT); // Crafting book category + for (int i = 0; i < ingredients; i++) { + handleIngredient(wrapper); + } + + final Item result = wrapper.read(itemType()); + rewrite(result); + wrapper.write(Type.ITEM1_20_2, result); + + wrapper.passthrough(Type.BOOLEAN); // Show notification + } + + @Override + public void handleStonecutting(final PacketWrapper wrapper) throws Exception { + wrapper.passthrough(Type.STRING); // Group + handleIngredient(wrapper); + + final Item result = wrapper.read(itemType()); + rewrite(result); + wrapper.write(Type.ITEM1_20_2, result); + } + + @Override + public void handleSmithing(final PacketWrapper wrapper) throws Exception { + handleIngredient(wrapper); // Base + handleIngredient(wrapper); // Addition + + final Item result = wrapper.read(itemType()); + rewrite(result); + wrapper.write(Type.ITEM1_20_2, result); + } + + @Override + public void handleSmithingTransform(final PacketWrapper wrapper) throws Exception { + handleIngredient(wrapper); // Template + handleIngredient(wrapper); // Base + handleIngredient(wrapper); // Additions + + final Item result = wrapper.read(itemType()); + rewrite(result); + wrapper.write(Type.ITEM1_20_2, result); + } + + @Override + protected void handleIngredient(final PacketWrapper wrapper) throws Exception { + final Item[] items = wrapper.read(itemArrayType()); + wrapper.write(Type.ITEM1_20_2_VAR_INT_ARRAY, items); + for (final Item item : items) { + rewrite(item); + } + } + }.register(ClientboundPackets1_19_4.DECLARE_RECIPES); } } \ No newline at end of file diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java index 00bf5cc73..3444edc39 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java @@ -18,11 +18,10 @@ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types; import com.viaversion.viaversion.api.minecraft.entities.EntityType; -import com.viaversion.viaversion.api.minecraft.metadata.Metadata; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.packet.State; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.version.Types1_20; @@ -32,8 +31,6 @@ import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2; import com.viaversion.viaversion.rewriter.EntityRewriter; -import java.util.List; - public final class EntityPacketRewriter1_20_2 extends EntityRewriter { public EntityPacketRewriter1_20_2(final Protocol1_20_2To1_20 protocol) { @@ -95,6 +92,11 @@ public final class EntityPacketRewriter1_20_2 extends EntityRewriter { + wrapper.passthrough(Type.VAR_INT); // Entity id + wrapper.passthrough(Type.VAR_INT); // Effect id + wrapper.passthrough(Type.BYTE); // Amplifier + wrapper.passthrough(Type.VAR_INT); // Duration + wrapper.passthrough(Type.BYTE); // Flags + if (wrapper.passthrough(Type.BOOLEAN)) { + wrapper.write(Type.NAMELESS_NBT, wrapper.read(Type.NBT)); // Factor data + } + }); } @Override diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/RecipeRewriter1_20_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/RecipeRewriter1_20_2.java new file mode 100644 index 000000000..1feeb15bb --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/rewriter/RecipeRewriter1_20_2.java @@ -0,0 +1,41 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion 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 com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter; + +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.protocol.Protocol; +import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4; + +public class RecipeRewriter1_20_2 extends RecipeRewriter1_19_4 { + + public RecipeRewriter1_20_2(final Protocol protocol) { + super(protocol); + } + + @Override + protected Type itemType() { + return Type.ITEM1_20_2; + } + + @Override + protected Type itemArrayType() { + return Type.ITEM1_20_2_VAR_INT_ARRAY; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/storage/FakeProtocolState.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/storage/FakeProtocolState.java index 250ce0016..6f433306d 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/storage/FakeProtocolState.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/storage/FakeProtocolState.java @@ -18,10 +18,18 @@ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage; import com.viaversion.viaversion.api.connection.StorableObject; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl; +import io.netty.buffer.ByteBuf; + +import java.util.ArrayList; +import java.util.List; public class FakeProtocolState implements StorableObject { + private final List packetQueue = new ArrayList<>(); private boolean configurationState; + private boolean gameProfileSent; public boolean isConfigurationState() { return configurationState; @@ -31,8 +39,42 @@ public class FakeProtocolState implements StorableObject { this.configurationState = configurationState; } + public void addPacketToQueue(final PacketWrapper wrapper, final boolean clientbound) { + packetQueue.add(new QueuedPacket(((PacketWrapperImpl) wrapper).getInputBuffer().copy(), clientbound)); // TODO + } + + public List packetQueue() { + return packetQueue; + } + + public boolean hasGameProfileBeenSent() { + return gameProfileSent; + } + + public void setGameProfileSent(final boolean gameProfileSent) { + this.gameProfileSent = gameProfileSent; + } + @Override public boolean clearOnServerSwitch() { return false; } + + public static final class QueuedPacket { + private final ByteBuf buf; + private final boolean clientbound; + + private QueuedPacket(final ByteBuf buf, final boolean clientbound) { + this.buf = buf; + this.clientbound = clientbound; + } + + public ByteBuf buf() { + return buf; + } + + public boolean clientbound() { + return clientbound; + } + } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/types/Chunk1_20_2Type.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/types/Chunk1_20_2Type.java new file mode 100644 index 000000000..78a6fbcc9 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/types/Chunk1_20_2Type.java @@ -0,0 +1,102 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2023 ViaVersion 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 com.viaversion.viaversion.protocols.protocol1_20_2to1_20.types; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.google.common.base.Preconditions; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity; +import com.viaversion.viaversion.api.minecraft.chunks.Chunk; +import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18; +import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.types.minecraft.BaseChunkType; +import com.viaversion.viaversion.api.type.types.version.ChunkSectionType1_18; +import com.viaversion.viaversion.api.type.types.version.Types1_18; +import io.netty.buffer.ByteBuf; + +import java.util.ArrayList; +import java.util.List; + +public final class Chunk1_20_2Type extends Type { + private final ChunkSectionType1_18 sectionType; + private final int ySectionCount; + + public Chunk1_20_2Type(final int ySectionCount, final int globalPaletteBlockBits, final int globalPaletteBiomeBits) { + super(Chunk.class); + Preconditions.checkArgument(ySectionCount > 0); + this.sectionType = new ChunkSectionType1_18(globalPaletteBlockBits, globalPaletteBiomeBits); + this.ySectionCount = ySectionCount; + } + + @Override + public Chunk read(final ByteBuf buffer) throws Exception { + final int chunkX = buffer.readInt(); + final int chunkZ = buffer.readInt(); + final CompoundTag heightMap = Type.NAMELESS_NBT.read(buffer); + + // Read sections + final ByteBuf sectionsBuf = buffer.readBytes(Type.VAR_INT.readPrimitive(buffer)); + final ChunkSection[] sections = new ChunkSection[ySectionCount]; + try { + for (int i = 0; i < ySectionCount; i++) { + sections[i] = sectionType.read(sectionsBuf); + } + } finally { + sectionsBuf.release(); + } + + final int blockEntitiesLength = Type.VAR_INT.readPrimitive(buffer); + final List blockEntities = new ArrayList<>(blockEntitiesLength); + for (int i = 0; i < blockEntitiesLength; i++) { + blockEntities.add(Types1_18.BLOCK_ENTITY.read(buffer)); + } + + return new Chunk1_18(chunkX, chunkZ, sections, heightMap, blockEntities); + } + + @Override + public void write(final ByteBuf buffer, final Chunk chunk) throws Exception { + buffer.writeInt(chunk.getX()); + buffer.writeInt(chunk.getZ()); + + Type.NAMELESS_NBT.write(buffer, chunk.getHeightMap()); + + final ByteBuf sectionBuffer = buffer.alloc().buffer(); + try { + for (final ChunkSection section : chunk.getSections()) { + sectionType.write(sectionBuffer, section); + } + sectionBuffer.readerIndex(0); + Type.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes()); + buffer.writeBytes(sectionBuffer); + } finally { + sectionBuffer.release(); // release buffer + } + + Type.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size()); + for (final BlockEntity blockEntity : chunk.blockEntities()) { + Types1_18.BLOCK_ENTITY.write(buffer, blockEntity); + } + } + + @Override + public Class getBaseClass() { + return BaseChunkType.class; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/BlockRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/BlockRewriter.java index 77b1fa331..db9f96e78 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/BlockRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/BlockRewriter.java @@ -42,10 +42,16 @@ import org.checkerframework.checker.nullness.qual.Nullable; public class BlockRewriter { private final Protocol protocol; private final Type positionType; + private final Type nbtType; public BlockRewriter(Protocol protocol, Type positionType) { + this(protocol, positionType, Type.NBT); + } + + public BlockRewriter(Protocol protocol, Type positionType, Type nbtType) { this.protocol = protocol; this.positionType = positionType; + this.nbtType = nbtType; } public void registerBlockAction(C packetType) { @@ -203,7 +209,7 @@ public class BlockRewriter { public void registerBlockEntityData(C packetType, @Nullable Consumer blockEntityHandler) { protocol.registerClientbound(packetType, wrapper -> { - final Position position = wrapper.passthrough(Type.POSITION1_14); + final Position position = wrapper.passthrough(positionType); final int blockEntityId = wrapper.read(Type.VAR_INT); final Mappings mappings = protocol.getMappingData().getBlockEntityMappings(); @@ -214,7 +220,7 @@ public class BlockRewriter { } final CompoundTag tag; - if (blockEntityHandler != null && (tag = wrapper.passthrough(Type.NBT)) != null) { + if (blockEntityHandler != null && (tag = wrapper.passthrough(nbtType)) != null) { final BlockEntity blockEntity = new BlockEntityImpl(BlockEntity.pack(position.x(), position.z()), (short) position.y(), blockEntityId, tag); blockEntityHandler.accept(blockEntity); } diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java index 24c96aebc..d03e2c799 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java @@ -31,9 +31,17 @@ import org.checkerframework.checker.nullness.qual.Nullable; public abstract class ItemRewriter> extends RewriterBase implements com.viaversion.viaversion.api.rewriter.ItemRewriter { + private final Type itemType; + private final Type itemArrayType; protected ItemRewriter(T protocol) { + this(protocol, Type.FLAT_VAR_INT_ITEM, Type.FLAT_VAR_INT_ITEM_ARRAY); + } + + public ItemRewriter(T protocol, Type itemType, Type itemArrayType) { super(protocol); + this.itemType = itemType; + this.itemArrayType = itemArrayType; } // These two methods always return the same item instance *for now* @@ -74,12 +82,12 @@ public abstract class ItemRewriter { - Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); + Item[] items = wrapper.passthrough(itemArrayType); for (Item item : items) { handleItemToClient(item); } - handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Carried item + handleItemToClient(wrapper.passthrough(itemType)); // Carried item }); } }); @@ -123,8 +131,8 @@ public abstract class ItemRewriter type) { + public void registerAdvancements1_20(C packetType) { protocol.registerClientbound(packetType, wrapper -> { wrapper.passthrough(Type.BOOLEAN); // Reset/clear int size = wrapper.passthrough(Type.VAR_INT); // Mapping size @@ -319,7 +326,7 @@ public abstract class ItemRewriter { for (int i = 0; i < ingredientsNo; i++) { handleIngredient(wrapper); } - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } public void handleCraftingShapeless(PacketWrapper wrapper) throws Exception { wrapper.passthrough(Type.STRING); // Group handleIngredients(wrapper); - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } public void handleSmelting(PacketWrapper wrapper) throws Exception { wrapper.passthrough(Type.STRING); // Group handleIngredient(wrapper); - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result wrapper.passthrough(Type.FLOAT); // EXP wrapper.passthrough(Type.VAR_INT); // Cooking time } @@ -102,13 +102,13 @@ public class RecipeRewriter { public void handleStonecutting(PacketWrapper wrapper) throws Exception { wrapper.passthrough(Type.STRING); // Group handleIngredient(wrapper); - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } public void handleSmithing(PacketWrapper wrapper) throws Exception { handleIngredient(wrapper); // Base handleIngredient(wrapper); // Addition - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } public void handleSimpleRecipe(final PacketWrapper wrapper) throws Exception { @@ -119,7 +119,7 @@ public class RecipeRewriter { handleIngredient(wrapper); // Template handleIngredient(wrapper); // Base handleIngredient(wrapper); // Additions - rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result + rewrite(wrapper.passthrough(itemType())); // Result } public void handleSmithingTrim(final PacketWrapper wrapper) throws Exception { @@ -135,7 +135,7 @@ public class RecipeRewriter { } protected void handleIngredient(final PacketWrapper wrapper) throws Exception { - final Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); + final Item[] items = wrapper.passthrough(itemArrayType()); for (final Item item : items) { rewrite(item); } @@ -153,4 +153,12 @@ public class RecipeRewriter { void accept(PacketWrapper wrapper) throws Exception; } + + protected Type itemType() { + return Type.FLAT_VAR_INT_ITEM; + } + + protected Type itemArrayType() { + return Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT; + } }