Readded separate encoder/decoder netty elements

This commit is contained in:
RaphiMC 2023-04-07 02:05:04 +02:00
parent c951723c3c
commit 46a4ac8ab0
3 changed files with 138 additions and 57 deletions

View File

@ -17,82 +17,31 @@
*/
package net.raphimc.vialegacy.netty;
import com.google.common.collect.EvictingQueue;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import net.raphimc.vialegacy.ViaLegacy;
import net.raphimc.vialegacy.api.splitter.PreNettyPacketType;
import net.raphimc.vialegacy.api.splitter.PreNettySplitter;
import java.util.List;
public class PreNettyLengthCodec extends ByteToMessageCodec<ByteBuf> {
protected final UserConnection user;
private final EvictingQueue<Integer> lastPackets = EvictingQueue.create(8);
protected final PreNettyLengthRemover encoder;
protected final PreNettyLengthPrepender decoder;
public PreNettyLengthCodec(final UserConnection user) {
this.user = user;
this.encoder = new PreNettyLengthRemover(user);
this.decoder = new PreNettyLengthPrepender(user);
}
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) {
Type.VAR_INT.readPrimitive(in); // length
out.writeByte(Type.VAR_INT.readPrimitive(in) & 255); // id
out.writeBytes(in); // content
this.encoder.encode(ctx, in, out);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (!in.isReadable() || in.readableBytes() <= 0) {
return;
}
final PreNettySplitter splitter = this.user.get(PreNettySplitter.class);
if (splitter == null) {
ViaLegacy.getPlatform().getLogger().severe("Received data, but no splitter is set");
return;
}
while (in.readableBytes() > 0) {
in.markReaderIndex();
final int packetId = in.readUnsignedByte();
final PreNettyPacketType packetType = splitter.getPacketType(packetId);
if (packetType == null) {
ViaLegacy.getPlatform().getLogger().severe("Encountered undefined packet: " + packetId + " in " + splitter.getProtocolName());
ViaLegacy.getPlatform().getLogger().severe(ByteBufUtil.hexDump(in.readSlice(in.readableBytes())));
ViaLegacy.getPlatform().getLogger().severe("Last 8 read packet ids: " + this.lastPackets);
ctx.channel().close();
return;
}
this.lastPackets.add(packetId);
try {
final int begin = in.readerIndex();
packetType.getPacketReader().accept(this.user, in);
final int length = in.readerIndex() - begin;
in.readerIndex(begin);
int totalLength = length;
for (int i = 1; i < 5; ++i) {
if ((packetId & -1 << i * 7) == 0) {
totalLength += i;
break;
}
}
final ByteBuf buf = ctx.alloc().buffer();
Type.VAR_INT.writePrimitive(buf, totalLength); // Length
Type.VAR_INT.writePrimitive(buf, packetId); // id
buf.writeBytes(in.readSlice(length)); // content
out.add(buf);
} catch (IndexOutOfBoundsException e) { // Not enough data
in.resetReaderIndex();
return;
}
}
this.decoder.decode(ctx, in, out);
}
}

View File

@ -0,0 +1,91 @@
/*
* This file is part of ViaLegacy - https://github.com/RaphiMC/ViaLegacy
* Copyright (C) 2023 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.netty;
import com.google.common.collect.EvictingQueue;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import net.raphimc.vialegacy.ViaLegacy;
import net.raphimc.vialegacy.api.splitter.PreNettyPacketType;
import net.raphimc.vialegacy.api.splitter.PreNettySplitter;
import java.util.List;
public class PreNettyLengthPrepender extends ByteToMessageDecoder {
protected final UserConnection user;
private final EvictingQueue<Integer> lastPackets = EvictingQueue.create(8);
public PreNettyLengthPrepender(final UserConnection user) {
this.user = user;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (!in.isReadable() || in.readableBytes() <= 0) {
return;
}
final PreNettySplitter splitter = this.user.get(PreNettySplitter.class);
if (splitter == null) {
ViaLegacy.getPlatform().getLogger().severe("Received data, but no splitter is set");
return;
}
while (in.readableBytes() > 0) {
in.markReaderIndex();
final int packetId = in.readUnsignedByte();
final PreNettyPacketType packetType = splitter.getPacketType(packetId);
if (packetType == null) {
ViaLegacy.getPlatform().getLogger().severe("Encountered undefined packet: " + packetId + " in " + splitter.getProtocolName());
ViaLegacy.getPlatform().getLogger().severe(ByteBufUtil.hexDump(in.readSlice(in.readableBytes())));
ViaLegacy.getPlatform().getLogger().severe("Last 8 read packet ids: " + this.lastPackets);
ctx.channel().close();
return;
}
this.lastPackets.add(packetId);
try {
final int begin = in.readerIndex();
packetType.getPacketReader().accept(this.user, in);
final int length = in.readerIndex() - begin;
in.readerIndex(begin);
int totalLength = length;
for (int i = 1; i < 5; ++i) {
if ((packetId & -1 << i * 7) == 0) {
totalLength += i;
break;
}
}
final ByteBuf buf = ctx.alloc().buffer();
Type.VAR_INT.writePrimitive(buf, totalLength); // length
Type.VAR_INT.writePrimitive(buf, packetId); // id
buf.writeBytes(in.readSlice(length)); // content
out.add(buf);
} catch (IndexOutOfBoundsException e) { // Not enough data
in.resetReaderIndex();
return;
}
}
}
}

View File

@ -0,0 +1,41 @@
/*
* This file is part of ViaLegacy - https://github.com/RaphiMC/ViaLegacy
* Copyright (C) 2023 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.netty;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class PreNettyLengthRemover extends MessageToByteEncoder<ByteBuf> {
protected final UserConnection user;
public PreNettyLengthRemover(final UserConnection user) {
this.user = user;
}
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) {
Type.VAR_INT.readPrimitive(in); // length
out.writeByte(Type.VAR_INT.readPrimitive(in) & 255); // id
out.writeBytes(in); // content
}
}