3232import io .netty .bootstrap .ServerBootstrap ;
3333import io .netty .channel .Channel ;
3434import io .netty .channel .ChannelFuture ;
35- import io .netty .channel .ChannelHandlerContext ;
36- import io .netty .channel .ChannelInboundHandlerAdapter ;
3735import io .netty .channel .ChannelInitializer ;
38- import io .netty .channel .ChannelOutboundHandlerAdapter ;
39- import io .netty .channel .ChannelPromise ;
4036import io .netty .channel .EventLoopGroup ;
4137import io .netty .channel .local .LocalAddress ;
4238import io .netty .util .AttributeKey ;
4642import lombok .Getter ;
4743import lombok .RequiredArgsConstructor ;
4844import net .md_5 .bungee .api .ProxyServer ;
45+ import net .md_5 .bungee .api .ProxyServer .Unsafe ;
4946import net .md_5 .bungee .api .config .ListenerInfo ;
5047import net .md_5 .bungee .api .event .ProxyReloadEvent ;
5148import net .md_5 .bungee .api .plugin .Listener ;
5249import net .md_5 .bungee .api .plugin .Plugin ;
5350import net .md_5 .bungee .event .EventHandler ;
5451import net .md_5 .bungee .netty .PipelineUtils ;
55- import net .md_5 .bungee .protocol .MinecraftEncoder ;
56- import net .md_5 .bungee .protocol .Varint21LengthFieldPrepender ;
52+ import net .md_5 .bungee .protocol .channel .BungeeChannelInitializer ;
5753
5854@ RequiredArgsConstructor
5955public final class BungeeInjector extends CommonPlatformInjector implements Listener {
60- private static final String BUNGEE_INIT = "connect-bungee-init" ;
6156
6257 private final ConnectLogger logger ;
6358 private final ProxyServer proxy ;
@@ -69,17 +64,27 @@ public final class BungeeInjector extends CommonPlatformInjector implements List
6964 public boolean inject () {
7065 try {
7166 // Can everyone just switch to Velocity please :)
67+ // :( ~BungeeCord Collaborator
68+
69+ Unsafe unsafe = ProxyServer .getInstance ().unsafe ();
70+ BungeeChannelInitializer frontend = unsafe .getFrontendChannelInitializer ();
71+ unsafe .setFrontendChannelInitializer (BungeeChannelInitializer .create (channel -> {
72+ if (!frontend .getChannelAcceptor ().accept (channel )) {
73+ return false ;
74+ }
75+ injectClient (channel , true );
76+ return true ;
77+ }));
78+
79+ BungeeChannelInitializer backend = unsafe .getBackendChannelInitializer ();
80+ unsafe .setBackendChannelInitializer (BungeeChannelInitializer .create (channel -> {
81+ if (!backend .getChannelAcceptor ().accept (channel )) {
82+ return false ;
83+ }
84+ injectClient (channel , false );
85+ return true ;
86+ }));
7287
73- // Field framePrepender = ReflectionUtils.getField(PipelineUtils.class, "framePrepender");
74- //
75- // // Required in order to inject into both Geyser <-> proxy AND proxy <-> server
76- // // (Instead of just replacing the ChannelInitializer which is only called for
77- // // player <-> proxy)
78- // BungeeCustomPrepender customPrepender = new BungeeCustomPrepender(
79- // this, ReflectionUtils.castedStaticValue(framePrepender)
80- // );
81- //
82- // BungeeReflectionUtils.setFieldValue(null, framePrepender, customPrepender);
8388 initializeLocalChannel0 ();
8489 injected = true ;
8590 return true ;
@@ -129,6 +134,13 @@ private void initializeLocalChannel0() throws Exception {
129134 "Connect does not currently support multiple listeners with injection! " +
130135 "Please reach out to us on our Discord at https://minekube.com/discord so we can hear feedback on your setup." );
131136 }
137+
138+ try {
139+ ProxyServer .class .getMethod ("unsafe" );
140+ } catch (NoSuchMethodException e ) {
141+ throw new UnsupportedOperationException ("You're using an outdated version of BungeeCord - please update. Thank you!" );
142+ }
143+
132144 ListenerInfo listenerInfo = proxy .getConfig ().getListeners ().stream ().findFirst ().orElseThrow (
133145 IllegalStateException ::new );
134146
@@ -202,7 +214,7 @@ protected void initChannel(Channel ch) throws Exception {
202214 if (channelInitializer == null ) {
203215 // Proxy has finished initializing; we can safely grab this variable without fear of plugins modifying it
204216 // (Older versions of ViaVersion replace this to inject)
205- channelInitializer = PipelineUtils . SERVER_CHILD ;
217+ channelInitializer = proxy . unsafe (). getFrontendChannelInitializer (). getChannelInitializer () ;
206218 }
207219 initChannel .invoke (channelInitializer , ch );
208220 }
@@ -258,75 +270,7 @@ public void onProxyReload(ProxyReloadEvent event) {
258270 // End of logic from GeyserMC
259271
260272 void injectClient (Channel channel , boolean clientToProxy ) {
261- if (!channel .isOpen ()) {
262- return ;
263- }
264-
265- if (channel .pipeline ().get (MinecraftEncoder .class ) == null ) {
266- logger .debug (
267- "Minecraft encoder not found while injecting! {}" ,
268- String .join (", " , channel .pipeline ().names ())
269- );
270- return ;
271- }
272-
273273 injectAddonsCall (channel , !clientToProxy );
274274 addInjectedClient (channel );
275275 }
276-
277- @ RequiredArgsConstructor
278- private static final class BungeeCustomPrepender extends Varint21LengthFieldPrepender {
279- private final BungeeInjector injector ;
280- private final Varint21LengthFieldPrepender original ;
281-
282- @ Override
283- public void handlerAdded (ChannelHandlerContext ctx ) throws Exception {
284- original .handlerAdded (ctx );
285- // The Minecraft encoder being in the pipeline isn't present until later
286-
287- if (ctx .channel ().parent () != null ) {
288- // Client <-> Proxy
289- ctx .pipeline ().addBefore (
290- PipelineUtils .FRAME_DECODER , BUNGEE_INIT ,
291- new BungeeClientToProxyInjectInitializer (injector )
292- );
293- } else {
294- // Proxy <-> Server
295- ctx .pipeline ().addLast (
296- BUNGEE_INIT , new BungeeProxyToServerInjectInitializer (injector )
297- );
298- }
299- }
300- }
301-
302- @ RequiredArgsConstructor
303- private static final class BungeeClientToProxyInjectInitializer
304- extends ChannelInboundHandlerAdapter {
305-
306- private final BungeeInjector injector ;
307-
308- @ Override
309- public void channelRead (ChannelHandlerContext ctx , Object msg ) throws Exception {
310- injector .injectClient (ctx .channel (), true );
311-
312- ctx .pipeline ().remove (this );
313- super .channelRead (ctx , msg );
314- }
315- }
316-
317- @ RequiredArgsConstructor
318- private static final class BungeeProxyToServerInjectInitializer
319- extends ChannelOutboundHandlerAdapter {
320-
321- private final BungeeInjector injector ;
322-
323- @ Override
324- public void write (ChannelHandlerContext ctx , Object msg , ChannelPromise promise )
325- throws Exception {
326- injector .injectClient (ctx .channel (), false );
327-
328- ctx .pipeline ().remove (this );
329- super .write (ctx , msg , promise );
330- }
331- }
332- }
276+ }
0 commit comments