mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Resolve "not in event loop" issue on Geyser-Velocity with use-direct-connection enabled (#5720)
This commit is contained in:
@@ -8,6 +8,10 @@ dependencies {
|
||||
annotationProcessor(libs.velocity.api)
|
||||
api(projects.core)
|
||||
|
||||
compileOnly(libs.velocity.proxy)
|
||||
compileOnly(libs.netty.transport.native.io.uring)
|
||||
compileOnly(libs.netty.transport.native.kqueue)
|
||||
|
||||
compileOnlyApi(libs.velocity.api)
|
||||
api(libs.cloud.velocity)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.platform.velocity;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.proxy.network.TransportType;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
@@ -33,18 +34,25 @@ import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.IoEventLoop;
|
||||
import io.netty.channel.IoEventLoopGroup;
|
||||
import io.netty.channel.IoHandler;
|
||||
import io.netty.channel.IoHandlerFactory;
|
||||
import io.netty.channel.MultiThreadIoEventLoopGroup;
|
||||
import io.netty.channel.SingleThreadIoEventLoop;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
import io.netty.channel.epoll.EpollIoHandler;
|
||||
import io.netty.channel.kqueue.KQueueIoHandler;
|
||||
import io.netty.channel.local.LocalAddress;
|
||||
import io.netty.channel.local.LocalIoHandler;
|
||||
import io.netty.channel.nio.NioIoHandler;
|
||||
import io.netty.channel.uring.IoUringIoHandler;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import io.netty.util.concurrent.ThreadAwareExecutor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.network.netty.GeyserInjector;
|
||||
import org.geysermc.geyser.network.netty.IoHandlerWrapper;
|
||||
import org.geysermc.geyser.network.netty.LocalServerChannelWrapper;
|
||||
import org.geysermc.geyser.network.netty.WatchedSingleThreadIoEventLoop;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -86,9 +94,18 @@ public class GeyserVelocityInjector extends GeyserInjector {
|
||||
|
||||
Field workerGroupField = connectionManagerClass.getDeclaredField("workerGroup");
|
||||
workerGroupField.setAccessible(true);
|
||||
EventLoopGroup workerGroup = (EventLoopGroup) workerGroupField.get(connectionManager);
|
||||
IoEventLoopGroup workerGroup = (IoEventLoopGroup) workerGroupField.get(connectionManager);
|
||||
|
||||
EventLoopGroup wrapperGroup = new MultiThreadIoEventLoopGroup(LocalIoHandler.newFactory()) {
|
||||
var factory = LocalIoHandler.newFactory();
|
||||
var nativeFactory = getNativeHandlerFactory();
|
||||
var wrapperFactory = new IoHandlerFactory() {
|
||||
@Override
|
||||
public IoHandler newHandler(ThreadAwareExecutor ioExecutor) {
|
||||
return new IoHandlerWrapper(factory.newHandler(ioExecutor), nativeFactory.newHandler(ioExecutor));
|
||||
}
|
||||
};
|
||||
|
||||
EventLoopGroup wrapperGroup = new MultiThreadIoEventLoopGroup(factory) {
|
||||
@Override
|
||||
protected ThreadFactory newDefaultThreadFactory() {
|
||||
return new DefaultThreadFactory("Geyser Backend Worker Group", Thread.MAX_PRIORITY);
|
||||
@@ -96,7 +113,7 @@ public class GeyserVelocityInjector extends GeyserInjector {
|
||||
|
||||
@Override
|
||||
protected IoEventLoop newChild(Executor executor, IoHandlerFactory ioHandlerFactory, Object... args) {
|
||||
return new WatchedSingleThreadIoEventLoop(workerGroup, this, executor, ioHandlerFactory);
|
||||
return new SingleThreadIoEventLoop(workerGroup, executor, wrapperFactory);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,4 +143,13 @@ public class GeyserVelocityInjector extends GeyserInjector {
|
||||
this.localChannel = channelFuture;
|
||||
this.serverSocketAddress = channelFuture.channel().localAddress();
|
||||
}
|
||||
|
||||
private static IoHandlerFactory getNativeHandlerFactory() {
|
||||
return switch (TransportType.bestType()) {
|
||||
case NIO -> NioIoHandler.newFactory();
|
||||
case EPOLL -> EpollIoHandler.newFactory();
|
||||
case KQUEUE -> KQueueIoHandler.newFactory();
|
||||
case IO_URING -> IoUringIoHandler.newFactory();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user