32
32
import io .netty .bootstrap .ServerBootstrap ;
33
33
import io .netty .channel .Channel ;
34
34
import io .netty .channel .ChannelFuture ;
35
- import io .netty .channel .ChannelHandlerContext ;
36
- import io .netty .channel .ChannelInboundHandlerAdapter ;
37
35
import io .netty .channel .ChannelInitializer ;
38
- import io .netty .channel .ChannelOutboundHandlerAdapter ;
39
- import io .netty .channel .ChannelPromise ;
40
36
import io .netty .channel .EventLoopGroup ;
41
37
import io .netty .channel .local .LocalAddress ;
42
38
import io .netty .util .AttributeKey ;
46
42
import lombok .Getter ;
47
43
import lombok .RequiredArgsConstructor ;
48
44
import net .md_5 .bungee .api .ProxyServer ;
45
+ import net .md_5 .bungee .api .ProxyServer .Unsafe ;
49
46
import net .md_5 .bungee .api .config .ListenerInfo ;
50
47
import net .md_5 .bungee .api .event .ProxyReloadEvent ;
51
48
import net .md_5 .bungee .api .plugin .Listener ;
52
49
import net .md_5 .bungee .api .plugin .Plugin ;
53
50
import net .md_5 .bungee .event .EventHandler ;
54
51
import 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 ;
57
53
58
54
@ RequiredArgsConstructor
59
55
public final class BungeeInjector extends CommonPlatformInjector implements Listener {
60
- private static final String BUNGEE_INIT = "connect-bungee-init" ;
61
56
62
57
private final ConnectLogger logger ;
63
58
private final ProxyServer proxy ;
@@ -69,17 +64,27 @@ public final class BungeeInjector extends CommonPlatformInjector implements List
69
64
public boolean inject () {
70
65
try {
71
66
// 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
+ }));
72
87
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);
83
88
initializeLocalChannel0 ();
84
89
injected = true ;
85
90
return true ;
@@ -129,6 +134,13 @@ private void initializeLocalChannel0() throws Exception {
129
134
"Connect does not currently support multiple listeners with injection! " +
130
135
"Please reach out to us on our Discord at https://minekube.com/discord so we can hear feedback on your setup." );
131
136
}
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
+
132
144
ListenerInfo listenerInfo = proxy .getConfig ().getListeners ().stream ().findFirst ().orElseThrow (
133
145
IllegalStateException ::new );
134
146
@@ -202,7 +214,7 @@ protected void initChannel(Channel ch) throws Exception {
202
214
if (channelInitializer == null ) {
203
215
// Proxy has finished initializing; we can safely grab this variable without fear of plugins modifying it
204
216
// (Older versions of ViaVersion replace this to inject)
205
- channelInitializer = PipelineUtils . SERVER_CHILD ;
217
+ channelInitializer = proxy . unsafe (). getFrontendChannelInitializer (). getChannelInitializer () ;
206
218
}
207
219
initChannel .invoke (channelInitializer , ch );
208
220
}
@@ -258,75 +270,7 @@ public void onProxyReload(ProxyReloadEvent event) {
258
270
// End of logic from GeyserMC
259
271
260
272
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
-
273
273
injectAddonsCall (channel , !clientToProxy );
274
274
addInjectedClient (channel );
275
275
}
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