1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2025-12-19 14:59:20 +00:00

Fixed Proxy <-> Server injection

This commit is contained in:
Tim203
2021-09-10 23:12:58 +02:00
parent cd02009dd4
commit cced369d7e

View File

@@ -26,11 +26,10 @@
package org.geysermc.floodgate.inject.bungee; package org.geysermc.floodgate.inject.bungee;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -44,6 +43,8 @@ import org.geysermc.floodgate.util.ReflectionUtils;
@RequiredArgsConstructor @RequiredArgsConstructor
public final class BungeeInjector extends CommonPlatformInjector { public final class BungeeInjector extends CommonPlatformInjector {
private static final String BUNGEE_INIT = "floodgate-bungee-init";
private final FloodgateLogger logger; private final FloodgateLogger logger;
@Getter private boolean injected; @Getter private boolean injected;
@@ -58,7 +59,7 @@ public final class BungeeInjector extends CommonPlatformInjector {
// (Instead of just replacing the ChannelInitializer which is only called for // (Instead of just replacing the ChannelInitializer which is only called for
// player <-> proxy) // player <-> proxy)
BungeeCustomPrepender customPrepender = new BungeeCustomPrepender( BungeeCustomPrepender customPrepender = new BungeeCustomPrepender(
ReflectionUtils.getCastedValue(null, framePrepender), logger this, ReflectionUtils.getCastedValue(null, framePrepender)
); );
BungeeReflectionUtils.setFieldValue(null, framePrepender, customPrepender); BungeeReflectionUtils.setFieldValue(null, framePrepender, customPrepender);
@@ -82,47 +83,76 @@ public final class BungeeInjector extends CommonPlatformInjector {
return false; return false;
} }
public void injectClient(Channel channel, boolean clientToProxy) { void injectClient(Channel channel, boolean clientToProxy) {
if (!channel.isOpen()) {
return;
}
if (channel.pipeline().get(MinecraftEncoder.class) == null) {
logger.debug(
"Minecraft encoder not found while injecting! {}",
String.join(", ", channel.pipeline().names())
);
return;
}
injectAddonsCall(channel, !clientToProxy); injectAddonsCall(channel, !clientToProxy);
addInjectedClient(channel); addInjectedClient(channel);
} }
private static final String BUNGEE_INIT = "floodgate-bungee-init";
@RequiredArgsConstructor @RequiredArgsConstructor
private final class BungeeCustomPrepender extends Varint21LengthFieldPrepender { private static final class BungeeCustomPrepender extends Varint21LengthFieldPrepender {
private final BungeeInjector injector;
private final Varint21LengthFieldPrepender original; private final Varint21LengthFieldPrepender original;
private final FloodgateLogger logger;
@Override @Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception { public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
original.handlerAdded(ctx); original.handlerAdded(ctx);
// The Minecraft encoder being in the pipeline isn't present until later // The Minecraft encoder being in the pipeline isn't present until later
ctx.pipeline().addBefore(PipelineUtils.FRAME_DECODER, BUNGEE_INIT,
new ChannelInboundHandlerAdapter() { if (ctx.channel().parent() != null) {
@Override // Client <-> Proxy
public void channelRead(ChannelHandlerContext ctx, Object msg) ctx.pipeline().addBefore(
throws Exception { PipelineUtils.FRAME_DECODER, BUNGEE_INIT,
if (ctx.channel().pipeline().get(MinecraftEncoder.class) == null) { new BungeeClientToProxyInjectInitializer(injector)
logger.debug("Minecraft encoder class not found while " + );
"injecting!"); } else {
} else { // Proxy <-> Server
ctx.channel().pipeline().addFirst(new BungeeInjectorInitializer()); ctx.pipeline().addLast(
} BUNGEE_INIT, new BungeeProxyToServerInjectInitializer(injector)
ctx.channel().pipeline().remove(BUNGEE_INIT); );
super.channelRead(ctx, msg); }
}
});
} }
} }
private final class BungeeInjectorInitializer extends ChannelInitializer<Channel> { @RequiredArgsConstructor
private static final class BungeeClientToProxyInjectInitializer
extends ChannelInboundHandlerAdapter {
private final BungeeInjector injector;
@Override @Override
protected void initChannel(Channel channel) { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (!channel.isOpen()) { injector.injectClient(ctx.channel(), true);
return;
} ctx.pipeline().remove(this);
injectClient(channel, channel.parent() != null); super.channelRead(ctx, msg);
}
}
@RequiredArgsConstructor
private static final class BungeeProxyToServerInjectInitializer
extends ChannelOutboundHandlerAdapter {
private final BungeeInjector injector;
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
throws Exception {
injector.injectClient(ctx.channel(), false);
ctx.pipeline().remove(this);
super.write(ctx, msg, promise);
} }
} }
} }