Fixed codec
This commit is contained in:
parent
5ffea5bc96
commit
b91d767163
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "org.adde0109"
|
||||
version = "1.5.0"
|
||||
version = "1.5.0-tst12"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,39 @@
|
|||
package org.adde0109.ambassador.forge.packet;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
public class ModDataPacket extends GenericForgeLoginWrapperPacket<Context> {
|
||||
public class ModDataPacket implements IForgeLoginWrapperPacket<Context> {
|
||||
private final byte[] content;
|
||||
private final Context context;
|
||||
|
||||
ModDataPacket(byte[] content, Context context) {
|
||||
super(content, context);
|
||||
this.content = content;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
static public ModDataPacket read(ByteBuf input, Context context) {
|
||||
byte[] content = new byte[input.readableBytes()];
|
||||
input.readBytes(content);
|
||||
return new ModDataPacket(content, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf encode() {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
ProtocolUtils.writeVarInt(buf, 5); //PacketID
|
||||
buf.writeBytes(content);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,84 +9,108 @@ import io.netty.buffer.Unpooled;
|
|||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import io.netty.handler.codec.MessageToMessageCodec;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
import org.adde0109.ambassador.forge.packet.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ForgeLoginWrapperCodec extends MessageToMessageCodec<DeferredByteBufHolder, IForgeLoginWrapperPacket<?>> {
|
||||
|
||||
private final boolean FML3;
|
||||
private final List<Integer> loginWrapperIDs = new ArrayList<>();
|
||||
private final Map<Integer, Context> loginWrapperContexts = new HashMap<>();
|
||||
|
||||
public ForgeLoginWrapperCodec(boolean fml3) {
|
||||
FML3 = fml3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptInboundMessage(Object msg) throws Exception {
|
||||
return (msg instanceof LoginPluginMessagePacket
|
||||
&& ((LoginPluginMessagePacket) msg).getChannel().equals("fml:loginwrapper"))
|
||||
|| (msg instanceof LoginPluginResponsePacket
|
||||
&& loginWrapperContexts.containsKey(((LoginPluginResponsePacket) msg).getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, DeferredByteBufHolder in, List<Object> out) throws Exception {
|
||||
|
||||
ByteBuf buf = in.content();
|
||||
|
||||
Context context;
|
||||
if (in instanceof LoginPluginResponsePacket msg) {
|
||||
//Continue from stored context
|
||||
context = Context.fromContext(
|
||||
loginWrapperContexts.remove(((LoginPluginResponsePacket) msg).getId()), msg.isSuccess());
|
||||
if (!msg.isSuccess()) {
|
||||
//Nothing to read, just create an empty packet.
|
||||
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||
return;
|
||||
} else {
|
||||
String channel = ProtocolUtils.readString(buf); //Read the channel even though we know the channel by context.
|
||||
Ambassador.getInstance();
|
||||
}
|
||||
} else {
|
||||
//New context.
|
||||
LoginPluginMessagePacket msg = (LoginPluginMessagePacket) in;
|
||||
String channel = ProtocolUtils.readString(buf);
|
||||
|
||||
context = Context.createContext(msg.getId(), channel);
|
||||
}
|
||||
|
||||
//Decoding of data starts here - channel already read
|
||||
int originalReaderIndex = buf.readerIndex();
|
||||
|
||||
String channel;
|
||||
|
||||
try {
|
||||
Context context;
|
||||
if (in instanceof LoginPluginMessagePacket msg && msg.getChannel().equals("fml:loginwrapper")) {
|
||||
channel = ProtocolUtils.readString(buf);
|
||||
context = Context.createContext(msg.getId(), channel);
|
||||
} else if (in instanceof LoginPluginResponsePacket msg && loginWrapperIDs.remove(Integer.valueOf(msg.getId()))) {
|
||||
channel = ProtocolUtils.readString(buf);
|
||||
context = Context.createClientContext(msg.getId(), msg.isSuccess(), channel);
|
||||
if (!context.getChannelName().equals("fml:handshake")) {
|
||||
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||
} else {
|
||||
int length = ProtocolUtils.readVarInt(buf);
|
||||
int packetID = ProtocolUtils.readVarInt(buf);
|
||||
if (context instanceof Context.ClientContext clientContext) {
|
||||
switch (packetID) {
|
||||
case 2:
|
||||
out.add(ModListReplyPacket.read(buf, clientContext));
|
||||
break;
|
||||
case 99:
|
||||
out.add(new ACKPacket(clientContext));
|
||||
break;
|
||||
default:
|
||||
//Undo decoding
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||
if (Ambassador.getInstance().config.isDebugMode()) {
|
||||
Ambassador.getInstance().logger.warn(
|
||||
"Unrecognised packet id received from client on fml:handshake: " + packetID);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Not a loginWrapperPacket
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
ctx.fireChannelRead(in.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!channel.equals("fml:handshake")) {
|
||||
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||
} else {
|
||||
int length = ProtocolUtils.readVarInt(buf);
|
||||
int packetID = ProtocolUtils.readVarInt(buf);
|
||||
if (context instanceof Context.ClientContext clientContext) {
|
||||
switch (packetID) {
|
||||
case 2:
|
||||
out.add(ModListReplyPacket.read(buf, clientContext));
|
||||
switch (packetID) {
|
||||
case 1:
|
||||
out.add(ModListPacket.read(buf, context, FML3));
|
||||
break;
|
||||
case 3:
|
||||
out.add(RegistryPacket.read(buf, context, FML3));
|
||||
break;
|
||||
case 4:
|
||||
out.add(ConfigDataPacket.read(buf, context, FML3));
|
||||
break;
|
||||
case 5:
|
||||
if (FML3) {
|
||||
out.add(ModDataPacket.read(buf, context));
|
||||
break;
|
||||
case 99:
|
||||
out.add(new ACKPacket(clientContext));
|
||||
break;
|
||||
default:
|
||||
throw new DecoderException("Unrecognised packet ID: " + packetID);
|
||||
}
|
||||
} else {
|
||||
switch (packetID) {
|
||||
case 1:
|
||||
out.add(ModListPacket.read(buf, context, FML3));
|
||||
break;
|
||||
case 3:
|
||||
out.add(RegistryPacket.read(buf, context, FML3));
|
||||
break;
|
||||
case 4:
|
||||
out.add(ConfigDataPacket.read(buf, context, FML3));
|
||||
break;
|
||||
case 5:
|
||||
if (FML3) {
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
out.add(ModDataPacket.read(buf, context));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new DecoderException("Unrecognised packet ID: " + packetID);
|
||||
}
|
||||
}
|
||||
default:
|
||||
//Undo decoding
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||
if (Ambassador.getInstance().config.isDebugMode()) {
|
||||
Ambassador.getInstance().logger.warn(
|
||||
"Unrecognised packet id received from server on fml:handshake: " + packetID);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (DecoderException exception) {
|
||||
Ambassador.getInstance().logger.error("Failed to decode a wrapped Forge login packet: ", exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,21 +118,28 @@ public class ForgeLoginWrapperCodec extends MessageToMessageCodec<DeferredByteBu
|
|||
protected void encode(ChannelHandlerContext ctx, IForgeLoginWrapperPacket<?> msg, List<Object> out) throws Exception {
|
||||
ByteBuf wrapped;
|
||||
|
||||
boolean data = !(msg.getContext() instanceof Context.ClientContext clientContext && !clientContext.success());
|
||||
|
||||
boolean includeLength = !(msg instanceof GenericForgeLoginWrapperPacket);
|
||||
|
||||
String channel = msg.getContext().getChannelName();
|
||||
|
||||
wrapped = Unpooled.buffer();
|
||||
ByteBuf encoded = msg.encode();
|
||||
ProtocolUtils.writeString(wrapped, channel);
|
||||
ProtocolUtils.writeVarInt(wrapped, encoded.readableBytes());
|
||||
wrapped.writeBytes(encoded);
|
||||
encoded.release();
|
||||
|
||||
if (data) {
|
||||
ByteBuf encoded = msg.encode();
|
||||
ProtocolUtils.writeString(wrapped, channel);
|
||||
if (includeLength)
|
||||
ProtocolUtils.writeVarInt(wrapped, encoded.readableBytes());
|
||||
wrapped.writeBytes(encoded);
|
||||
encoded.release();
|
||||
}
|
||||
if (msg.getContext() instanceof Context.ClientContext clientContext) {
|
||||
out.add(new LoginPluginResponsePacket(clientContext.getResponseID(), clientContext.success(), wrapped));
|
||||
} else {
|
||||
out.add(new LoginPluginMessagePacket(msg.getContext().getResponseID(), "fml:loginwrapper", wrapped));
|
||||
if (!(msg instanceof ModDataPacket)) { //ModDataPacket doesn't require a response
|
||||
this.loginWrapperIDs.add(msg.getContext().getResponseID());
|
||||
this.loginWrapperContexts.put(msg.getContext().getResponseID(), msg.getContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user