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