diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java index 4c93eb4cb..cb575aac3 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/AbstractProtocol.java @@ -77,6 +77,7 @@ public abstract class AbstractProtocol unmappedClientboundPacketType, @Nullable Class mappedClientboundPacketType, @Nullable Class mappedServerboundPacketType, @Nullable Class unmappedServerboundPacketType) { @@ -97,6 +98,12 @@ public abstract class AbstractProtocol wrapper.user().getProtocolInfo().setState(State.CONFIGURATION)); + } + if (unmappedClientboundPacketType != null && mappedClientboundPacketType != null && unmappedClientboundPacketType != mappedClientboundPacketType) { registerPacketIdChanges( @@ -208,6 +215,12 @@ public abstract class AbstractProtocol> packetTypes = packetTypesProvider.unmappedServerboundPacketTypes(); + final PacketTypeMap packetTypeMap = packetTypes.get(State.PLAY); + return packetTypeMap != null ? packetTypeMap.typeByName("CONFIGURATION_ACKNOWLEDGED") : null; + } + // --------------------------------------------------------------------------------- @Override @@ -361,7 +374,7 @@ public abstract class AbstractProtocol implements ByteBufReader, ByteBufWriter { public static final Type VECTOR3F = new Vector3fType(); public static final Type QUATERNION = new QuaternionType(); public static final Type NBT = new NBTType(); + public static final Type NAMELESS_NBT = new NamelessNBTType(); public static final Type NBT_ARRAY = new ArrayType<>(Type.NBT); public static final Type GLOBAL_POSITION = new GlobalPositionType(); public static final Type OPTIONAL_GLOBAL_POSITION = new GlobalPositionType.OptionalGlobalPositionType(); diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NBTType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NBTType.java index 2538f474a..e4d632533 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NBTType.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NBTType.java @@ -22,15 +22,15 @@ */ package com.viaversion.viaversion.api.type.types.minecraft; -import com.github.steveice10.opennbt.NBTIO; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.limiter.TagLimiter; import com.viaversion.viaversion.api.type.Type; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; -import java.io.DataInput; -import java.io.DataOutput; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.io.IOException; public class NBTType extends Type { @@ -43,23 +43,50 @@ public class NBTType extends Type { @Override public CompoundTag read(ByteBuf buffer) throws Exception { - int readerIndex = buffer.readerIndex(); - byte b = buffer.readByte(); - if (b == 0) { - return null; - } else { - buffer.readerIndex(readerIndex); - return NBTIO.readTag((DataInput) new ByteBufInputStream(buffer), TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL)); - } + return read(buffer, true); } @Override public void write(ByteBuf buffer, CompoundTag object) throws Exception { - if (object == null) { - buffer.writeByte(0); - } else { - ByteBufOutputStream bytebufStream = new ByteBufOutputStream(buffer); - NBTIO.writeTag((DataOutput) bytebufStream, object); + write(buffer, object, ""); + } + + public static CompoundTag read(final ByteBuf buffer, final boolean readName) throws Exception { + final int readerIndex = buffer.readerIndex(); + final byte b = buffer.readByte(); + if (b == 0) { + return null; } + + buffer.readerIndex(readerIndex); + + final ByteBufInputStream in = new ByteBufInputStream(buffer); + final int id = in.readByte(); + if (id != CompoundTag.ID) { + throw new IOException(String.format("Expected root tag to be a CompoundTag, was %s", id)); + } + + if (readName) { + in.skipBytes(in.readUnsignedShort()); + } + + final TagLimiter tagLimiter = TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL); + final CompoundTag tag = new CompoundTag(); + tag.read(in, tagLimiter); + return tag; + } + + public static void write(final ByteBuf buffer, final CompoundTag tag, final @Nullable String name) throws Exception { + if (tag == null) { + buffer.writeByte(0); + return; + } + + final ByteBufOutputStream out = new ByteBufOutputStream(buffer); + out.writeByte(CompoundTag.ID); + if (name != null) { + out.writeUTF(name); + } + tag.write(out); } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NamelessNBTType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NamelessNBTType.java new file mode 100644 index 000000000..833f7ba11 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/minecraft/NamelessNBTType.java @@ -0,0 +1,44 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.type.types.minecraft; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.viaversion.viaversion.api.type.Type; +import io.netty.buffer.ByteBuf; + +public class NamelessNBTType extends Type { + + public NamelessNBTType() { + super(CompoundTag.class); + } + + @Override + public CompoundTag read(final ByteBuf buffer) throws Exception { + return NBTType.read(buffer, false); + } + + @Override + public void write(final ByteBuf buffer, final CompoundTag tag) throws Exception { + NBTType.write(buffer, tag, null); + } +} 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 b02293b7c..089e56d8b 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 @@ -23,6 +23,11 @@ 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 2227ca05c..9c0069d30 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 @@ -33,10 +33,12 @@ import com.viaversion.viaversion.api.protocol.version.VersionProvider; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.protocol.ProtocolManagerImpl; import com.viaversion.viaversion.protocol.ServerProtocolVersionSingleton; +import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2; import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8; import com.viaversion.viaversion.util.ChatColorUtil; import com.viaversion.viaversion.util.GsonUtil; import io.netty.channel.ChannelFuture; + import java.util.List; import java.util.UUID; import java.util.logging.Level; @@ -45,9 +47,6 @@ public class BaseProtocol1_7 extends AbstractProtocol { @Override protected void registerPackets() { - /* Outgoing Packets */ - - // Status Response Packet registerClientbound(ClientboundStatusPackets.STATUS_RESPONSE, new PacketHandlers() { // Status Response Packet @Override public void register() { @@ -122,7 +121,9 @@ public class BaseProtocol1_7 extends AbstractProtocol { // Login Success Packet registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> { ProtocolInfo info = wrapper.user().getProtocolInfo(); - info.setState(State.PLAY); + if (finishLoginAfterGameprofile()) { + info.setState(State.PLAY); + } UUID uuid = passthroughLoginUUID(wrapper); info.setUuid(uuid); @@ -147,7 +148,6 @@ public class BaseProtocol1_7 extends AbstractProtocol { } }); - /* Incoming Packets */ // Login Start Packet registerServerbound(ServerboundLoginPackets.HELLO, wrapper -> { int protocol = wrapper.user().getProtocolInfo().getProtocolVersion(); @@ -164,6 +164,10 @@ public class BaseProtocol1_7 extends AbstractProtocol { future.addListener(f -> wrapper.user().getChannel().close()); } }); + + 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 @@ -188,4 +192,8 @@ 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/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 12518da56..cafab951e 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 @@ -17,24 +17,31 @@ */ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20; +import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types; import com.viaversion.viaversion.api.protocol.AbstractProtocol; +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.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.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.handler.BlockItemPacketHandler1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.handler.EntityPacketHandler1_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.storage.FakeProtocolState; import com.viaversion.viaversion.rewriter.SoundRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.UUID; @@ -50,12 +57,9 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol configuration - // Client/serverbound config finish -> play - // TODO New helper methods for: join game, respawn, + // TODO Updated NBT type used in: block entity, chunk, tag query, entity metadata data, item type, mob effect + + // TODO Handle Enabled features and tags before configuration phase end // TODO Make sure Paper/Velocity handle a 0,0 uuid fine during login // Lesser: @@ -77,15 +81,96 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol { + registerServerbound(State.LOGIN, ServerboundLoginPackets.HELLO.getId(), ServerboundLoginPackets.HELLO.getId(), wrapper -> { wrapper.passthrough(Type.STRING); // Name - final UUID uuid = wrapper.read(Type.OPTIONAL_UUID); - wrapper.write(Type.UUID, uuid != null ? uuid : new UUID(0, 0)); + + final UUID uuid = wrapper.read(Type.UUID); + wrapper.write(Type.OPTIONAL_UUID, uuid); }); + + // Deal with the new CONFIGURATION protocol state the client expects + registerServerbound(State.LOGIN, ServerboundLoginPackets.LOGIN_ACKNOWLEDGED.getId(), -1, wrapper -> { + wrapper.user().get(FakeProtocolState.class).setConfigurationState(true); + wrapper.cancel(); + }); + + registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION.getId(), -1, wrapper -> { + wrapper.user().get(FakeProtocolState.class).setConfigurationState(false); + wrapper.cancel(); + }); + registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), ServerboundPackets1_19_4.PLUGIN_MESSAGE.getId(), wrapper -> { + }); + registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), ServerboundPackets1_19_4.KEEP_ALIVE.getId(), wrapper -> { + }); + registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), ServerboundPackets1_19_4.PONG.getId(), wrapper -> { + }); + registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), ServerboundPackets1_19_4.RESOURCE_PACK_STATUS.getId(), wrapper -> { + }); + + // Sad emoji + cancelClientbound(ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES); + + registerServerbound(ServerboundPackets1_20_2.CONFIGURATION_ACKNOWLEDGED, null, wrapper -> { + wrapper.user().get(FakeProtocolState.class).setConfigurationState(false); + wrapper.cancel(); + }); + + // TODO Check if we can just not send batches (probably fine like this) + cancelServerbound(ServerboundPackets1_20_2.CHUNK_BATCH_RECEIVED); + } + + @Override + public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception { + final boolean configurationState = packetWrapper.user().get(FakeProtocolState.class).isConfigurationState(); + if (direction == Direction.SERVERBOUND) { + // Redirect packets during the fake configuration phase + // This might mess up people using Via API/other protocols down the line, but such is life. We can't have different states for server and client + final State newState = configurationState ? State.CONFIGURATION : state; + super.transform(direction, newState, packetWrapper); + return; + } + + // Make sure we don't send the client any packets from another protocol state + if (configurationState) { + // TODO Queue these packets to send them later + Via.getPlatform().getLogger().warning("Cancelled packet " + packetWrapper.getId() + " sent during configuration state"); + packetWrapper.cancel(); + super.transform(direction, state, packetWrapper); + return; + } + + // Map some of them to their configuration state counterparts + final int unmappedId = packetWrapper.getId(); + if (state == State.PLAY && unmappedId != ClientboundPackets1_19_4.JOIN_GAME.getId()) { + if (unmappedId == ClientboundPackets1_19_4.PLUGIN_MESSAGE.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD); + } else if (unmappedId == ClientboundPackets1_19_4.DISCONNECT.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.DISCONNECT); + } else if (unmappedId == ClientboundPackets1_19_4.KEEP_ALIVE.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.KEEP_ALIVE); + } else if (unmappedId == ClientboundPackets1_19_4.PING.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.PING); + } else if (unmappedId == ClientboundPackets1_19_4.RESOURCE_PACK.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.RESOURCE_PACK); + } else if (unmappedId == ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES); + } else if (unmappedId == ClientboundPackets1_19_4.TAGS.getId()) { + packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_TAGS); + } + return; + } + + super.transform(direction, state, packetWrapper); + } + + @Override + protected @Nullable ServerboundPackets1_20_2 configurationAcknowledgedPacket() { + return null; // Don't handle it in the transitioning protocol } @Override public void init(final UserConnection user) { + user.put(new FakeProtocolState()); addEntityTracker(user, new EntityTrackerBase(user, Entity1_19_4Types.PLAYER)); } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/BlockItemPacketHandler1_20_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/BlockItemPacketHandler1_20_2.java index 8c760e223..172a7f73e 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/BlockItemPacketHandler1_20_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/BlockItemPacketHandler1_20_2.java @@ -19,12 +19,9 @@ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20.handler; import com.viaversion.viaversion.api.minecraft.metadata.ChunkPosition; import com.viaversion.viaversion.api.type.Type; -import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type; import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4; -import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2; -import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.ItemRewriter; public final class BlockItemPacketHandler1_20_2 extends ItemRewriter { @@ -35,27 +32,6 @@ public final class BlockItemPacketHandler1_20_2 extends ItemRewriter blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14); - blockRewriter.registerBlockAction(ClientboundPackets1_19_4.BLOCK_ACTION); - blockRewriter.registerBlockChange(ClientboundPackets1_19_4.BLOCK_CHANGE); - blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_19_4.MULTI_BLOCK_CHANGE); - blockRewriter.registerEffect(ClientboundPackets1_19_4.EFFECT, 1010, 2001); - blockRewriter.registerChunkData1_19(ClientboundPackets1_19_4.CHUNK_DATA, Chunk1_18Type::new); - blockRewriter.registerBlockEntityData(ClientboundPackets1_19_4.BLOCK_ENTITY_DATA); - - registerSetCooldown(ClientboundPackets1_19_4.COOLDOWN); - registerWindowItems1_17_1(ClientboundPackets1_19_4.WINDOW_ITEMS); - registerSetSlot1_17_1(ClientboundPackets1_19_4.SET_SLOT); - registerAdvancements1_20(ClientboundPackets1_19_4.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM); - registerEntityEquipmentArray(ClientboundPackets1_19_4.ENTITY_EQUIPMENT); - registerClickWindow1_17_1(ServerboundPackets1_20_2.CLICK_WINDOW); - registerTradeList1_19(ClientboundPackets1_19_4.TRADE_LIST); - registerCreativeInvAction(ServerboundPackets1_20_2.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM); - registerWindowPropertyEnchantmentHandler(ClientboundPackets1_19_4.WINDOW_PROPERTY); - registerSpawnParticle1_19(ClientboundPackets1_19_4.SPAWN_PARTICLE); - - new RecipeRewriter1_19_4<>(protocol).register(ClientboundPackets1_19_4.DECLARE_RECIPES); - protocol.registerClientbound(ClientboundPackets1_19_4.UNLOAD_CHUNK, wrapper -> { final int x = wrapper.read(Type.INT); final int z = wrapper.read(Type.INT); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/EntityPacketHandler1_20_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/EntityPacketHandler1_20_2.java index f5dc6e47b..e241681b0 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/EntityPacketHandler1_20_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/handler/EntityPacketHandler1_20_2.java @@ -20,11 +20,13 @@ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20.handler; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types; import com.viaversion.viaversion.api.minecraft.entities.EntityType; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; 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; import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20; +import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2; import com.viaversion.viaversion.rewriter.EntityRewriter; public final class EntityPacketHandler1_20_2 extends EntityRewriter { @@ -52,10 +54,12 @@ public final class EntityPacketHandler1_20_2 extends EntityRewriter { - final int blockState = meta.value(); - meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState)); - }); - } - @Override public EntityType typeFromId(final int type) { return Entity1_19_4Types.getTypeFromId(type); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ClientboundPackets1_20_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ClientboundPackets1_20_2.java index 157d16725..4ff89f898 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ClientboundPackets1_20_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ClientboundPackets1_20_2.java @@ -34,8 +34,8 @@ public enum ClientboundPackets1_20_2 implements ClientboundPacketType { BLOCK_CHANGE, // 0x0A BOSSBAR, // 0x0B SERVER_DIFFICULTY, // 0x0C - CHUNK_BATCH_FINISHED, // 0x0D // TODO AAAAAAAAAAAAAAAAAAAAAAAAA - CHUNK_BATCH_START, // 0x0E // TODO AAAAAAAAAAAAAAAAAAAAAAAAA + CHUNK_BATCH_FINISHED, // 0x0D + CHUNK_BATCH_START, // 0x0E CHUNK_BIOMES, // 0x0F CLEAR_TITLES, // 0x10 TAB_COMPLETE, // 0x11 @@ -46,7 +46,7 @@ public enum ClientboundPackets1_20_2 implements ClientboundPacketType { SET_SLOT, // 0x16 COOLDOWN, // 0x17 CUSTOM_CHAT_COMPLETIONS, // 0x18 - PLUGIN_MESSAGE, // 0x19 // TODO AAAAAAAAAAAAAAAAAAAAAAAAA + PLUGIN_MESSAGE, // 0x19 DAMAGE_EVENT, // 0x1A DELETE_CHAT_MESSAGE, // 0x1B DISCONNECT, // 0x1C @@ -122,7 +122,7 @@ public enum ClientboundPackets1_20_2 implements ClientboundPacketType { TITLE_TIMES, // 0x62 ENTITY_SOUND, // 0x63 SOUND, // 0x64 - START_CONFIGURATION, // 0x65 // TODO AAAAAAAAAAAAAAAAAAAAAAAAA + START_CONFIGURATION, // 0x65 STOP_SOUND, // 0x66 SYSTEM_CHAT, // 0x67 TAB_LIST, // 0x68 diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ServerboundPackets1_20_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ServerboundPackets1_20_2.java index be5f8a946..153b980f4 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ServerboundPackets1_20_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/packet/ServerboundPackets1_20_2.java @@ -28,15 +28,15 @@ public enum ServerboundPackets1_20_2 implements ServerboundPacketType { CHAT_COMMAND, // 0x04 CHAT_MESSAGE, // 0x05 CHAT_SESSION_UPDATE, // 0x06 - CHUNK_BATCH_RECEIVED, // 0x07 // TODO AAAAAAAAAAAAAAAAAAAAAAAAA + CHUNK_BATCH_RECEIVED, // 0x07 CLIENT_STATUS, // 0x08 CLIENT_SETTINGS, // 0x09 TAB_COMPLETE, // 0x0A - CONFIGURATION_ACKNOWLEDGED, // 0x0B // TODO AAAAAAAAAAAAAAAAAAAAAAAAA + CONFIGURATION_ACKNOWLEDGED, // 0x0B CLICK_WINDOW_BUTTON, // 0x0C CLICK_WINDOW, // 0x0D CLOSE_WINDOW, // 0x0E - PLUGIN_MESSAGE, // 0x0F // TODO AAAAAAAAAAAAAAAAAAAAAAAAA + PLUGIN_MESSAGE, // 0x0F EDIT_BOOK, // 0x10 ENTITY_NBT_REQUEST, // 0x11 INTERACT_ENTITY, // 0x12 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 new file mode 100644 index 000000000..250ce0016 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_2to1_20/storage/FakeProtocolState.java @@ -0,0 +1,38 @@ +/* + * 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.storage; + +import com.viaversion.viaversion.api.connection.StorableObject; + +public class FakeProtocolState implements StorableObject { + + private boolean configurationState; + + public boolean isConfigurationState() { + return configurationState; + } + + public void setConfigurationState(final boolean configurationState) { + this.configurationState = configurationState; + } + + @Override + public boolean clearOnServerSwitch() { + return false; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java index 76f9ae68f..7eb973c83 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java @@ -45,6 +45,8 @@ import com.viaversion.viaversion.data.entity.DimensionDataImpl; import com.viaversion.viaversion.rewriter.meta.MetaFilter; import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent; import com.viaversion.viaversion.rewriter.meta.MetaHandlerEventImpl; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; @@ -52,7 +54,6 @@ import java.util.List; import java.util.Map; import java.util.logging.Logger; import java.util.stream.Collectors; -import org.checkerframework.checker.nullness.qual.Nullable; public abstract class EntityRewriter> extends RewriterBase implements com.viaversion.viaversion.api.rewriter.EntityRewriter { @@ -468,32 +469,32 @@ public abstract class EntityRewriter { - final CompoundTag registry = wrapper.get(Type.NBT, 0); - final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome"); - final ListTag biomes = biomeRegistry.get("value"); - tracker(wrapper.user()).setBiomesSent(biomes.size()); - }; + return wrapper -> trackBiomeSize(wrapper.user(), wrapper.get(Type.NBT, 0)); + } + + public void trackBiomeSize(final UserConnection connection, final CompoundTag registry) { + final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome"); + final ListTag biomes = biomeRegistry.get("value"); + tracker(connection).setBiomesSent(biomes.size()); + } + + public PacketHandler dimensionDataHandler() { + return wrapper -> cacheDimensionData(wrapper.user(), wrapper.get(Type.NBT, 0)); } /** - * Returns a handler to cache dimension data, later used to get height values and other important info. - * - * @return handler to cache dimension data + * Caches dimension data, later used to get height values and other important info. */ - public PacketHandler dimensionDataHandler() { - return wrapper -> { - final CompoundTag tag = wrapper.get(Type.NBT, 0); - final ListTag dimensions = ((CompoundTag) tag.get("minecraft:dimension_type")).get("value"); - final Map dimensionDataMap = new HashMap<>(dimensions.size()); - for (final Tag dimension : dimensions) { - final CompoundTag dimensionCompound = (CompoundTag) dimension; - final CompoundTag element = dimensionCompound.get("element"); - final String name = (String) dimensionCompound.get("name").getValue(); - dimensionDataMap.put(name, new DimensionDataImpl(element)); - } - tracker(wrapper.user()).setDimensions(dimensionDataMap); - }; + public void cacheDimensionData(final UserConnection connection, final CompoundTag registry) { + final ListTag dimensions = ((CompoundTag) registry.get("minecraft:dimension_type")).get("value"); + final Map dimensionDataMap = new HashMap<>(dimensions.size()); + for (final Tag dimension : dimensions) { + final CompoundTag dimensionCompound = (CompoundTag) dimension; + final CompoundTag element = dimensionCompound.get("element"); + final String name = (String) dimensionCompound.get("name").getValue(); + dimensionDataMap.put(name, new DimensionDataImpl(element)); + } + tracker(connection).setDimensions(dimensionDataMap); } // ---------------------------------------------------------------------------