Fixed codec
This commit is contained in:
parent
5ffea5bc96
commit
b91d767163
|
|
@ -5,7 +5,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "org.adde0109"
|
group = "org.adde0109"
|
||||||
version = "1.5.0"
|
version = "1.5.0-tst12"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,39 @@
|
||||||
package org.adde0109.ambassador.forge.packet;
|
package org.adde0109.ambassador.forge.packet;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
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) {
|
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.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.DecoderException;
|
import io.netty.handler.codec.DecoderException;
|
||||||
import io.netty.handler.codec.MessageToMessageCodec;
|
import io.netty.handler.codec.MessageToMessageCodec;
|
||||||
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.adde0109.ambassador.Ambassador;
|
import org.adde0109.ambassador.Ambassador;
|
||||||
import org.adde0109.ambassador.forge.packet.*;
|
import org.adde0109.ambassador.forge.packet.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ForgeLoginWrapperCodec extends MessageToMessageCodec<DeferredByteBufHolder, IForgeLoginWrapperPacket<?>> {
|
public class ForgeLoginWrapperCodec extends MessageToMessageCodec<DeferredByteBufHolder, IForgeLoginWrapperPacket<?>> {
|
||||||
|
|
||||||
private final boolean FML3;
|
private final boolean FML3;
|
||||||
private final List<Integer> loginWrapperIDs = new ArrayList<>();
|
private final Map<Integer, Context> loginWrapperContexts = new HashMap<>();
|
||||||
|
|
||||||
public ForgeLoginWrapperCodec(boolean fml3) {
|
public ForgeLoginWrapperCodec(boolean fml3) {
|
||||||
FML3 = 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
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, DeferredByteBufHolder in, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, DeferredByteBufHolder in, List<Object> out) throws Exception {
|
||||||
|
|
||||||
ByteBuf buf = in.content();
|
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();
|
int originalReaderIndex = buf.readerIndex();
|
||||||
|
|
||||||
String channel;
|
if (!context.getChannelName().equals("fml:handshake")) {
|
||||||
|
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||||
try {
|
} else {
|
||||||
Context context;
|
int length = ProtocolUtils.readVarInt(buf);
|
||||||
if (in instanceof LoginPluginMessagePacket msg && msg.getChannel().equals("fml:loginwrapper")) {
|
int packetID = ProtocolUtils.readVarInt(buf);
|
||||||
channel = ProtocolUtils.readString(buf);
|
if (context instanceof Context.ClientContext clientContext) {
|
||||||
context = Context.createContext(msg.getId(), channel);
|
switch (packetID) {
|
||||||
} else if (in instanceof LoginPluginResponsePacket msg && loginWrapperIDs.remove(Integer.valueOf(msg.getId()))) {
|
case 2:
|
||||||
channel = ProtocolUtils.readString(buf);
|
out.add(ModListReplyPacket.read(buf, clientContext));
|
||||||
context = Context.createClientContext(msg.getId(), msg.isSuccess(), channel);
|
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 {
|
} else {
|
||||||
//Not a loginWrapperPacket
|
switch (packetID) {
|
||||||
buf.readerIndex(originalReaderIndex);
|
case 1:
|
||||||
ctx.fireChannelRead(in.retain());
|
out.add(ModListPacket.read(buf, context, FML3));
|
||||||
return;
|
break;
|
||||||
}
|
case 3:
|
||||||
|
out.add(RegistryPacket.read(buf, context, FML3));
|
||||||
if (!channel.equals("fml:handshake")) {
|
break;
|
||||||
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
case 4:
|
||||||
} else {
|
out.add(ConfigDataPacket.read(buf, context, FML3));
|
||||||
int length = ProtocolUtils.readVarInt(buf);
|
break;
|
||||||
int packetID = ProtocolUtils.readVarInt(buf);
|
case 5:
|
||||||
if (context instanceof Context.ClientContext clientContext) {
|
if (FML3) {
|
||||||
switch (packetID) {
|
out.add(ModDataPacket.read(buf, context));
|
||||||
case 2:
|
|
||||||
out.add(ModListReplyPacket.read(buf, clientContext));
|
|
||||||
break;
|
break;
|
||||||
case 99:
|
}
|
||||||
out.add(new ACKPacket(clientContext));
|
default:
|
||||||
break;
|
//Undo decoding
|
||||||
default:
|
buf.readerIndex(originalReaderIndex);
|
||||||
throw new DecoderException("Unrecognised packet ID: " + packetID);
|
out.add(GenericForgeLoginWrapperPacket.read(buf, context));
|
||||||
}
|
if (Ambassador.getInstance().config.isDebugMode()) {
|
||||||
} else {
|
Ambassador.getInstance().logger.warn(
|
||||||
switch (packetID) {
|
"Unrecognised packet id received from server on fml:handshake: " + 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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 {
|
protected void encode(ChannelHandlerContext ctx, IForgeLoginWrapperPacket<?> msg, List<Object> out) throws Exception {
|
||||||
ByteBuf wrapped;
|
ByteBuf wrapped;
|
||||||
|
|
||||||
|
boolean data = !(msg.getContext() instanceof Context.ClientContext clientContext && !clientContext.success());
|
||||||
|
|
||||||
|
boolean includeLength = !(msg instanceof GenericForgeLoginWrapperPacket);
|
||||||
|
|
||||||
String channel = msg.getContext().getChannelName();
|
String channel = msg.getContext().getChannelName();
|
||||||
|
|
||||||
wrapped = Unpooled.buffer();
|
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) {
|
if (msg.getContext() instanceof Context.ClientContext clientContext) {
|
||||||
out.add(new LoginPluginResponsePacket(clientContext.getResponseID(), clientContext.success(), wrapped));
|
out.add(new LoginPluginResponsePacket(clientContext.getResponseID(), clientContext.success(), wrapped));
|
||||||
} else {
|
} else {
|
||||||
out.add(new LoginPluginMessagePacket(msg.getContext().getResponseID(), "fml:loginwrapper", wrapped));
|
out.add(new LoginPluginMessagePacket(msg.getContext().getResponseID(), "fml:loginwrapper", wrapped));
|
||||||
if (!(msg instanceof ModDataPacket)) { //ModDataPacket doesn't require a response
|
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