Improved custom payload translation

This commit is contained in:
RaphiMC 2024-02-27 23:44:08 +01:00
parent 7fbb61076b
commit f84adb5e6c
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
6 changed files with 102 additions and 125 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -74,7 +74,7 @@ public class Protocolc0_30toc0_30cpe extends StatelessProtocol<ClientboundPacket
final PacketWrapper brand = PacketWrapper.create(ClientboundPackets1_6_4.PLUGIN_MESSAGE, wrapper.user());
brand.write(Types1_6_4.STRING, "MC|Brand");
final byte[] brandBytes = protocolMetadataStorage.getServerSoftwareName().getBytes(StandardCharsets.UTF_8);
brand.write(Type.SHORT, (short) brandBytes.length); // data length
brand.write(Type.SHORT, (short) brandBytes.length); // length
brand.write(Type.REMAINING_BYTES, brandBytes); // data
wrapper.send(Protocolc0_30toc0_30cpe.class);

View File

@ -33,6 +33,7 @@ import net.raphimc.vialegacy.api.data.ItemList1_6;
import net.raphimc.vialegacy.api.protocol.StatelessProtocol;
import net.raphimc.vialegacy.api.remapper.LegacyItemRewriter;
import net.raphimc.vialegacy.api.splitter.PreNettySplitter;
import net.raphimc.vialegacy.api.util.PacketUtil;
import net.raphimc.vialegacy.protocols.release.protocol1_4_2to1_3_1_2.rewriter.ItemRewriter;
import net.raphimc.vialegacy.protocols.release.protocol1_4_2to1_3_1_2.rewriter.SoundRewriter;
import net.raphimc.vialegacy.protocols.release.protocol1_4_2to1_3_1_2.types.Types1_3_1;
@ -268,11 +269,11 @@ public class Protocol1_4_2to1_3_1_2 extends StatelessProtocol<ClientboundPackets
this.registerClientbound(ClientboundPackets1_3_1.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Types1_6_4.STRING); // channel
handler(wrapper -> {
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<ClientboundPackets
}
wrapper.write(Type.BOOLEAN, false); // unavailable
}
length = PacketUtil.calculateLength(wrapper);
}
wrapper.resetReader();
wrapper.write(Type.STRING, channel); // channel
wrapper.write(Type.UNSIGNED_SHORT, length); // length
});
}
});

View File

@ -46,7 +46,7 @@ public class Protocol1_6_2to1_6_1 extends StatelessProtocol<ClientboundPackets1_
final PacketWrapper brand = PacketWrapper.create(ClientboundPackets1_6_4.PLUGIN_MESSAGE, wrapper.user());
brand.write(Types1_6_4.STRING, "MC|Brand");
final byte[] brandBytes = "legacy".getBytes(StandardCharsets.UTF_8);
brand.write(Type.SHORT, (short) brandBytes.length); // data length
brand.write(Type.SHORT, (short) brandBytes.length); // length
brand.write(Type.REMAINING_BYTES, brandBytes); // data
wrapper.send(Protocol1_6_2to1_6_1.class);

View File

@ -44,8 +44,6 @@ import com.viaversion.viaversion.protocols.base.ClientboundStatusPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundStatusPackets;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
@ -54,6 +52,7 @@ import net.raphimc.vialegacy.api.model.IdAndData;
import net.raphimc.vialegacy.api.protocol.StatelessTransitionProtocol;
import net.raphimc.vialegacy.api.remapper.LegacyItemRewriter;
import net.raphimc.vialegacy.api.splitter.PreNettySplitter;
import net.raphimc.vialegacy.api.util.PacketUtil;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.providers.EncryptionProvider;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter.*;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.*;
@ -737,10 +736,16 @@ public class Protocol1_7_2_5to1_6_4 extends StatelessTransitionProtocol<Clientbo
ClientboundPackets1_7_2.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Types1_6_4.STRING, Type.STRING); // channel
handler(wrapper -> {
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<Clientbo
}
wrapper.passthrough(Type.BOOLEAN); // unavailable
}
length = PacketUtil.calculateLength(wrapper);
}
wrapper.resetReader();
wrapper.write(Type.STRING, channel); // channel
wrapper.write(Type.UNSIGNED_SHORT, length); // length
});
}
}, State.LOGIN, (PacketHandler) PacketWrapper::cancel
@ -843,7 +853,7 @@ public class Protocol1_7_2_5to1_6_4 extends StatelessTransitionProtocol<Clientbo
wrapper.write(Type.UNSIGNED_BYTE, (short) 1); // always 1
wrapper.write(Type.UNSIGNED_BYTE, (short) ServerboundPackets1_6_4.PLUGIN_MESSAGE.getId()); // packet id
wrapper.write(Types1_6_4.STRING, "MC|PingHost"); // channel
wrapper.write(Type.UNSIGNED_SHORT, 3 + 2 * ip.length() + 4); // length
wrapper.write(Type.SHORT, (short) (3 + 2 * ip.length() + 4)); // length
wrapper.write(Type.UNSIGNED_BYTE, (short) wrapper.user().getProtocolInfo().serverProtocolVersion().getVersion()); // protocol Id
wrapper.write(Types1_6_4.STRING, ip); // hostname
wrapper.write(Type.INT, port); // port
@ -1030,50 +1040,34 @@ public class Protocol1_7_2_5to1_6_4 extends StatelessTransitionProtocol<Clientbo
this.registerServerbound(ServerboundPackets1_7_2.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING, Types1_6_4.STRING); // channel
map(Type.SHORT); // length
handler(wrapper -> {
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
});
}
});

View File

@ -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<ClientboundPackets1_
this.registerClientbound(ClientboundPackets1_7_2.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // channel
handler(wrapper -> {
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<ClientboundPackets1_
this.registerServerbound(ServerboundPackets1_8.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // channel
handler(wrapper -> {
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<ClientboundPackets1_
return;
}
final PacketWrapper lengthPacketWrapper = PacketWrapper.create(null, wrapper.user());
final ByteBuf lengthBuffer = Unpooled.buffer();
switch (channel) {
case "MC|BEdit":
case "MC|BSign":
final Item item = wrapper.read(Type.ITEM1_8); // book
itemRewriter.handleItemToServer(item);
lengthPacketWrapper.write(Types1_7_6.ITEM, item);
lengthPacketWrapper.writeToBuffer(lengthBuffer);
wrapper.write(Type.SHORT, (short) lengthBuffer.readableBytes()); // length
wrapper.write(Types1_7_6.ITEM, item); // book
break;
case "MC|TrSel":
final int selectedTrade = wrapper.read(Type.INT); // selected trade
lengthPacketWrapper.write(Type.INT, selectedTrade);
lengthPacketWrapper.writeToBuffer(lengthBuffer);
wrapper.write(Type.SHORT, (short) lengthBuffer.readableBytes()); // length
wrapper.write(Type.INT, selectedTrade); // selected trade
break;
case "MC|Brand":
case "MC|ItemName":
final String content = wrapper.read(Type.STRING); // client brand or item name
lengthPacketWrapper.write(Type.REMAINING_BYTES, content.getBytes(StandardCharsets.UTF_8));
lengthPacketWrapper.writeToBuffer(lengthBuffer);
wrapper.write(Type.SHORT, (short) lengthBuffer.readableBytes()); // length
wrapper.write(Type.REMAINING_BYTES, content.getBytes(StandardCharsets.UTF_8)); // client brand or item name
break;
case "MC|AdvCdm":
final byte type = wrapper.read(Type.BYTE); // command block type (0 = Block, 1 = Minecart)
final int posXOrEntityId;
final int posY;
final int posZ;
final byte type = wrapper.passthrough(Type.BYTE); // command block type (0 = Block, 1 = Minecart)
if (type == 0) {
posXOrEntityId = wrapper.read(Type.INT); // x
posY = wrapper.read(Type.INT); // y
posZ = wrapper.read(Type.INT); // z
wrapper.passthrough(Type.INT); // x
wrapper.passthrough(Type.INT); // y
wrapper.passthrough(Type.INT); // z
} else if (type == 1) {
posXOrEntityId = wrapper.read(Type.INT); // entity id
posY = 0;
posZ = 0;
wrapper.passthrough(Type.INT); // entity id
} else {
ViaLegacy.getPlatform().getLogger().warning("Unknown 1.8 command block type: " + type);
wrapper.cancel();
lengthBuffer.release();
return;
}
final String command = wrapper.read(Type.STRING); // command
wrapper.passthrough(Type.STRING); // command
wrapper.read(Type.BOOLEAN); // track output
lengthPacketWrapper.write(Type.BYTE, type);
if (type == 0) {
lengthPacketWrapper.write(Type.INT, posXOrEntityId);
lengthPacketWrapper.write(Type.INT, posY);
lengthPacketWrapper.write(Type.INT, posZ);
} else {
lengthPacketWrapper.write(Type.INT, posXOrEntityId);
}
lengthPacketWrapper.write(Type.STRING, command);
lengthPacketWrapper.writeToBuffer(lengthBuffer);
wrapper.write(Type.SHORT, (short) lengthBuffer.readableBytes()); // length
wrapper.write(Type.BYTE, type); // type
if (type == 0) {
wrapper.write(Type.INT, posXOrEntityId); // x
wrapper.write(Type.INT, posY); // y
wrapper.write(Type.INT, posZ); // z
} else {
wrapper.write(Type.INT, posXOrEntityId); // entity id
}
wrapper.write(Type.STRING, command); // command
break;
case "MC|Beacon":
final int primaryEffect = wrapper.read(Type.INT); // primary effect
final int secondaryEffect = wrapper.read(Type.INT); // secondary effect
lengthPacketWrapper.write(Type.INT, primaryEffect);
lengthPacketWrapper.write(Type.INT, secondaryEffect);
lengthPacketWrapper.writeToBuffer(lengthBuffer);
wrapper.write(Type.SHORT, (short) lengthBuffer.readableBytes()); // length
wrapper.write(Type.INT, primaryEffect); // primary effect
wrapper.write(Type.INT, secondaryEffect); // secondary effect
break;
case "REGISTER":
case "UNREGISTER":
@ -1486,17 +1426,14 @@ public class Protocol1_8to1_7_6_10 extends AbstractProtocol<ClientboundPackets1_
channels = Joiner.on('\0').join(validChannels).getBytes(StandardCharsets.UTF_8);
}
wrapper.write(Type.SHORT, (short) channels.length); // data length
wrapper.write(Type.REMAINING_BYTES, channels); // data
break;
default:
final byte[] data = wrapper.read(Type.REMAINING_BYTES);
wrapper.write(Type.SHORT, (short) data.length); // data length
wrapper.write(Type.REMAINING_BYTES, data); // data
break;
}
lengthBuffer.release();
final short length = (short) PacketUtil.calculateLength(wrapper);
wrapper.resetReader();
wrapper.write(Type.STRING, channel); // channel
wrapper.write(Type.SHORT, length); // length
});
}
});