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