diff --git a/src/main/java/net/raphimc/vialegacy/api/util/PacketUtil.java b/src/main/java/net/raphimc/vialegacy/api/util/PacketUtil.java new file mode 100644 index 0000000..ddcb04b --- /dev/null +++ b/src/main/java/net/raphimc/vialegacy/api/util/PacketUtil.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaLegacy - https://github.com/RaphiMC/ViaLegacy + * Copyright (C) 2020-2024 RK_01/RaphiMC 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 net.raphimc.vialegacy.api.util; + +import com.viaversion.viaversion.api.protocol.packet.PacketType; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public class PacketUtil { + + public static int calculateLength(final PacketWrapper wrapper) throws Exception { + final PacketType packetType = wrapper.getPacketType(); + wrapper.setPacketType(null); + + final ByteBuf lengthBuffer = Unpooled.buffer(); + wrapper.writeToBuffer(lengthBuffer); + final int length = lengthBuffer.readableBytes(); + lengthBuffer.release(); + + wrapper.setPacketType(packetType); + return length; + } + +} diff --git a/src/main/java/net/raphimc/vialegacy/protocols/classic/protocolc0_28_30toc0_28_30cpe/Protocolc0_30toc0_30cpe.java b/src/main/java/net/raphimc/vialegacy/protocols/classic/protocolc0_28_30toc0_28_30cpe/Protocolc0_30toc0_30cpe.java index 9b8a139..963ea6d 100644 --- a/src/main/java/net/raphimc/vialegacy/protocols/classic/protocolc0_28_30toc0_28_30cpe/Protocolc0_30toc0_30cpe.java +++ b/src/main/java/net/raphimc/vialegacy/protocols/classic/protocolc0_28_30toc0_28_30cpe/Protocolc0_30toc0_30cpe.java @@ -74,7 +74,7 @@ public class Protocolc0_30toc0_30cpe extends StatelessProtocol { - final String channel = wrapper.get(Types1_6_4.STRING, 0); - wrapper.passthrough(Type.SHORT); // length - if (channel.equalsIgnoreCase("MC|TrList")) { + final String channel = wrapper.read(Types1_6_4.STRING); // channel + int length = wrapper.read(Type.SHORT); // length + + if (channel.equals("MC|TrList")) { wrapper.passthrough(Type.INT); // window Id final int count = wrapper.passthrough(Type.UNSIGNED_BYTE); // count for (int i = 0; i < count; i++) { @@ -283,7 +284,12 @@ public class Protocol1_4_2to1_3_1_2 extends StatelessProtocol { - final String channel = wrapper.get(Type.STRING, 0); - wrapper.passthrough(Type.SHORT); // length + final String channel = wrapper.read(Types1_6_4.STRING); // channel + int length = wrapper.read(Type.SHORT); // length + + if (length < 0) { + wrapper.write(Type.STRING, channel); // channel + wrapper.write(Type.UNSIGNED_SHORT, 0); // length + return; + } + if (channel.equals("MC|TrList")) { wrapper.passthrough(Type.INT); // window id final int count = wrapper.passthrough(Type.UNSIGNED_BYTE); // count @@ -752,7 +757,12 @@ public class Protocol1_7_2_5to1_6_4 extends StatelessTransitionProtocol { - final String channel = wrapper.get(Types1_6_4.STRING, 0); - final PacketWrapper lengthPacketWrapper = PacketWrapper.create(null, wrapper.user()); - final ByteBuf lengthBuffer = Unpooled.buffer(); + final String channel = wrapper.read(Type.STRING); // channel + short length = wrapper.read(Type.SHORT); // length switch (channel) { case "MC|BEdit": case "MC|BSign": - final Item item = wrapper.read(Types1_7_6.ITEM); // book - itemRewriter.handleItemToServer(item); - - lengthPacketWrapper.write(Types1_7_6.ITEM, item); - lengthPacketWrapper.writeToBuffer(lengthBuffer); - - wrapper.set(Type.SHORT, 0, (short) lengthBuffer.readableBytes()); // length - wrapper.write(Types1_7_6.ITEM, item); // book + itemRewriter.handleItemToServer(wrapper.passthrough(Types1_7_6.ITEM)); + length = (short) PacketUtil.calculateLength(wrapper); break; case "MC|AdvCdm": final byte type = wrapper.read(Type.BYTE); // command block type if (type == 0) { - final int posX = wrapper.read(Type.INT); // x - final int posY = wrapper.read(Type.INT); // y - final int posZ = wrapper.read(Type.INT); // z - final String command = wrapper.read(Type.STRING); // command - - lengthPacketWrapper.write(Type.INT, posX); - lengthPacketWrapper.write(Type.INT, posY); - lengthPacketWrapper.write(Type.INT, posZ); - lengthPacketWrapper.write(Types1_6_4.STRING, command); - lengthPacketWrapper.writeToBuffer(lengthBuffer); - - wrapper.set(Type.SHORT, 0, (short) lengthBuffer.readableBytes()); // length - wrapper.write(Type.INT, posX); // x - wrapper.write(Type.INT, posY); // y - wrapper.write(Type.INT, posZ); // z - wrapper.write(Types1_6_4.STRING, command); // command + wrapper.passthrough(Type.INT); // x + wrapper.passthrough(Type.INT); // y + wrapper.passthrough(Type.INT); // z + wrapper.passthrough(Type.STRING); // command } else { wrapper.cancel(); + return; } + length = (short) PacketUtil.calculateLength(wrapper); break; } - lengthBuffer.release(); + + wrapper.resetReader(); + wrapper.write(Types1_6_4.STRING, channel); // channel + wrapper.write(Type.SHORT, length); // length }); } }); diff --git a/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/Protocol1_8to1_7_6_10.java b/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/Protocol1_8to1_7_6_10.java index c4c3a4c..ed7c32f 100644 --- a/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/Protocol1_8to1_7_6_10.java +++ b/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/Protocol1_8to1_7_6_10.java @@ -46,12 +46,11 @@ import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets; import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8; import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import net.raphimc.vialegacy.ViaLegacy; import net.raphimc.vialegacy.api.data.ItemList1_6; import net.raphimc.vialegacy.api.model.IdAndData; import net.raphimc.vialegacy.api.remapper.LegacyItemRewriter; +import net.raphimc.vialegacy.api.util.PacketUtil; import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.ClientboundPackets1_7_2; import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.ServerboundPackets1_7_2; import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.data.Particle; @@ -1110,10 +1109,14 @@ public class Protocol1_8to1_7_6_10 extends AbstractProtocol { - final String channel = wrapper.get(Type.STRING, 0); - wrapper.read(Type.SHORT); // length + final String channel = wrapper.read(Type.STRING); // channel + final int length = wrapper.read(Type.UNSIGNED_SHORT); // length + final int availableDataLength = PacketUtil.calculateLength(wrapper); + if (availableDataLength < length) { + throw new IllegalStateException("Custom payload length longer than actual data: " + length + " > " + availableDataLength); + } + wrapper.write(Type.STRING, channel); switch (channel) { case "MC|Brand": { @@ -1361,9 +1364,8 @@ public class Protocol1_8to1_7_6_10 extends AbstractProtocol { - final String channel = wrapper.get(Type.STRING, 0); + final String channel = wrapper.read(Type.STRING); // channel if (ViaLegacy.getConfig().isIgnoreLong1_8ChannelNames() && channel.length() > 16) { if (!Via.getConfig().isSuppressConversionWarnings()) { @@ -1373,95 +1375,33 @@ public class Protocol1_8to1_7_6_10 extends AbstractProtocol