1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00
onebeastchris
2025-07-25 18:07:35 +02:00
parent 7a154504cd
commit df4bb4f1c1
15 changed files with 47 additions and 157 deletions

View File

@@ -6,8 +6,6 @@ plugins {
dependencies {
api(projects.core)
compileOnly(libs.netty.transport.native.io.uring)
implementation(libs.cloud.bungee)
implementation(libs.adventure.text.serializer.bungeecord)
compileOnlyApi(libs.bungeecord.proxy)
@@ -15,7 +13,6 @@ dependencies {
platformRelocate("net.md_5.bungee.jni")
platformRelocate("com.fasterxml.jackson")
platformRelocate("io.netty.channel.kqueue") // This is not used because relocating breaks natives, but we must include it or else we get ClassDefNotFound
platformRelocate("net.kyori")
platformRelocate("org.incendo")
platformRelocate("io.leangen.geantyref") // provided by cloud, should also be relocated
@@ -33,16 +30,7 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
dependencies {
exclude(dependency("com.google.*:.*"))
exclude(dependency("io.netty.incubator:.*"))
exclude(dependency("io.netty:netty-transport-native-epoll:.*"))
exclude(dependency("io.netty:netty-transport-native-unix-common:.*"))
exclude(dependency("io.netty:netty-handler:.*"))
exclude(dependency("io.netty:netty-common:.*"))
exclude(dependency("io.netty:netty-buffer:.*"))
exclude(dependency("io.netty:netty-resolver:.*"))
exclude(dependency("io.netty:netty-transport:.*"))
exclude(dependency("io.netty:netty-codec:.*"))
exclude(dependency("io.netty:netty-resolver-dns:.*"))
exclude(dependency("io.netty.*:.*"))
}
}

View File

@@ -26,11 +26,9 @@
package org.geysermc.geyser.platform.bungeecord;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
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;

View File

@@ -102,6 +102,11 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
geyserLogger.warning("Unable to check the versions supported by this proxy! " + e.getMessage());
}
// See https://github.com/SpigotMC/BungeeCord/blob/e62fc6c2916a991e00177c580986d8b1a22fdb41/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java#L138
if (Boolean.getBoolean("bungee.io_uring")) {
System.setProperty("Mcpl.io_uring", "true");
}
if (!this.loadConfig()) {
return;
}

View File

@@ -42,8 +42,6 @@ platformRelocate("me.lucko.commodore")
platformRelocate("org.incendo")
platformRelocate("io.leangen.geantyref") // provided by cloud, should also be relocated
platformRelocate("org.yaml") // Broken as of 1.20
// These dependencies are already present on the platform
provided(libs.viaversion)
tasks.withType<Jar> {
@@ -62,23 +60,8 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
dependencies {
exclude(dependency("com.google.*:.*"))
// We cannot shade Netty, or else native libraries will not load
// Needed because older Spigot builds do not provide the haproxy module
exclude(dependency("io.netty.incubator:.*"))
exclude(dependency("io.netty:netty-transport-classes-epoll:.*"))
exclude(dependency("io.netty:netty-transport-native-epoll:.*"))
exclude(dependency("io.netty:netty-transport-native-unix-common:.*"))
exclude(dependency("io.netty:netty-transport-classes-kqueue:.*"))
exclude(dependency("io.netty:netty-transport-native-kqueue:.*"))
exclude(dependency("io.netty:netty-handler:.*"))
exclude(dependency("io.netty:netty-common:.*"))
exclude(dependency("io.netty:netty-buffer:.*"))
exclude(dependency("io.netty:netty-resolver:.*"))
exclude(dependency("io.netty:netty-transport:.*"))
exclude(dependency("io.netty:netty-codec:.*"))
exclude(dependency("io.netty:netty-codec-dns:.*"))
exclude(dependency("io.netty:netty-resolver-dns:.*"))
exclude(dependency("io.netty:netty-resolver-dns-native-macos:.*"))
exclude("io.netty", libs.netty.codec.haproxy)
// Commodore includes Brigadier
exclude(dependency("com.mojang:.*"))
@@ -88,7 +71,8 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
modrinth {
uploadFile.set(tasks.getByPath("shadowJar"))
gameVersions.addAll("1.16.5", "1.17", "1.17.1", "1.18", "1.18.1", "1.18.2", "1.19",
"1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6")
"1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6",
"1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8")
loaders.addAll("spigot", "paper")
}

View File

@@ -14,7 +14,6 @@ dependencies {
}
implementation(libs.bundles.jline)
implementation(libs.bundles.log4j)
}
@@ -32,11 +31,6 @@ tasks.named<Jar>("jar") {
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
archiveBaseName.set("Geyser-Standalone")
// temporary measure - incubator's io_uring is not compatible with 4.2.1
dependencies {
exclude(dependency("io.netty.incubator:.*"))
}
transform(Log4j2PluginsCacheFileTransformer())
}

View File

@@ -19,31 +19,6 @@ platformRelocate("org.yaml")
platformRelocate("org.incendo")
platformRelocate("io.leangen.geantyref") // provided by cloud, should also be relocated
exclude("com.google.*:*")
// Needed because Velocity provides every dependency except netty-resolver-dns
exclude("io.netty.incubator:.*")
exclude("io.netty:netty-transport-native-epoll:*")
exclude("io.netty:netty-transport-native-unix-common:*")
exclude("io.netty:netty-transport-native-kqueue:*")
exclude("io.netty:netty-handler:*")
exclude("io.netty:netty-common:*")
exclude("io.netty:netty-buffer:*")
exclude("io.netty:netty-resolver:*")
exclude("io.netty:netty-transport:*")
exclude("io.netty:netty-codec:*")
exclude("io.netty:netty-codec-haproxy:*")
exclude("org.slf4j:*")
exclude("org.ow2.asm:*")
// Exclude all Kyori dependencies except the legacy NBT serializer
exclude("net.kyori:adventure-api:*")
exclude("net.kyori:examination-api:*")
exclude("net.kyori:examination-string:*")
exclude("net.kyori:adventure-text-serializer-gson:*")
exclude("net.kyori:adventure-text-serializer-legacy:*")
exclude("net.kyori:adventure-nbt:*")
// These dependencies are already present on the platform
provided(libs.velocity.api)
@@ -56,27 +31,11 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
dependencies {
exclude(dependency("com.google.*:.*"))
// Needed because Velocity provides every dependency except netty-resolver-dns
exclude(dependency("io.netty:netty-transport-native-epoll:.*"))
exclude(dependency("io.netty:netty-transport-native-unix-common:.*"))
exclude(dependency("io.netty:netty-transport-native-kqueue:.*"))
exclude(dependency("io.netty:netty-handler:.*"))
exclude(dependency("io.netty:netty-common:.*"))
exclude(dependency("io.netty:netty-buffer:.*"))
exclude(dependency("io.netty:netty-resolver:.*"))
exclude(dependency("io.netty:netty-transport:.*"))
exclude(dependency("io.netty:netty-codec:.*"))
exclude(dependency("io.netty:netty-codec-haproxy:.*"))
exclude(dependency("io.netty.incubator:.*"))
exclude(dependency("io.netty:.*"))
exclude(dependency("org.slf4j:.*"))
exclude(dependency("org.ow2.asm:.*"))
// Exclude all Kyori dependencies except the legacy NBT serializer
exclude(dependency("net.kyori:adventure-api:.*"))
exclude(dependency("net.kyori:examination-api:.*"))
exclude(dependency("net.kyori:examination-string:.*"))
exclude(dependency("net.kyori:adventure-text-serializer-gson:.*"))
exclude(dependency("net.kyori:adventure-text-serializer-legacy:.*"))
exclude(dependency("net.kyori:adventure-nbt:.*"))
exclude(dependency("net.kyori:.*:.*"))
}
}

View File

@@ -106,6 +106,11 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
geyserLogger.error("/_____________\\");
}
// Only use io_uring when velocity does as well
if (Boolean.getBoolean("velocity.enable-iouring-transport")) {
System.setProperty("Mcpl.io_uring", "true");
}
if (!loadConfig()) {
return;
}

View File

@@ -28,7 +28,6 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
dependencies {
exclude(dependency("com.google.*:.*"))
exclude(dependency("io.netty:.*"))
exclude(dependency("io.netty.incubator:.*"))
exclude(dependency("org.slf4j:.*"))
exclude(dependency("org.ow2.asm:.*"))
}

View File

@@ -42,9 +42,12 @@ fun Project.relocate(pattern: String) {
}
}
fun Project.exclude(group: String) {
// Excludes all dependencies from a module - except one
fun Project.exclude(group: String, lib: Provider<MinimalExternalModuleDependency>) {
tasks.named<ShadowJar>("shadowJar") {
exclude(group)
dependencies {
exclude { it.moduleGroup == group && it.moduleName != lib.get().module.name }
}
}
}
@@ -58,10 +61,6 @@ fun Project.platformRelocate(pattern: String, exclusion: String = "") {
val providedDependencies = mutableMapOf<String, MutableSet<String>>()
fun getProvidedDependenciesForProject(projectName: String): MutableSet<String> {
return providedDependencies.getOrDefault(projectName, emptySet()).toMutableSet()
}
fun Project.provided(pattern: String, name: String, excludedOn: Int = 0b110) {
providedDependencies.getOrPut(project.name) { mutableSetOf() }
.add("${calcExclusion(pattern, 0b100, excludedOn)}:${calcExclusion(name, 0b10, excludedOn)}")

View File

@@ -24,8 +24,8 @@ provided("io.netty", "netty-transport-native-epoll")
provided("io.netty", "netty-transport-native-unix-common")
provided("io.netty", "netty-transport-classes-kqueue")
provided("io.netty", "netty-transport-native-kqueue")
provided("io.netty.incubator", "netty-incubator-transport-native-io_uring")
provided("io.netty.incubator", "netty-incubator-transport-classes-io_uring")
provided("io.netty", "netty-transport-native-io_uring")
provided("io.netty", "netty-transport-classes-io_uring")
provided("io.netty", "netty-handler")
provided("io.netty", "netty-common")
provided("io.netty", "netty-buffer")
@@ -33,9 +33,6 @@ provided("io.netty", "netty-resolver")
provided("io.netty", "netty-transport")
provided("io.netty", "netty-codec")
provided("io.netty", "netty-codec-base")
provided("io.netty", "netty-resolver-dns")
provided("io.netty", "netty-resolver-dns-native-macos")
provided("io.netty", "netty-resolver-dns-classes-macos")
provided("org.ow2.asm", "asm")
// cloud-fabric/cloud-neoforge jij's all cloud depends already
@@ -93,7 +90,7 @@ tasks {
}
afterEvaluate {
val providedDependencies = getProvidedDependenciesForProject(project.name)
val providedDependencies = providedDependencies[project.name]!!
// These are shaded, no need to JiJ them
configurations["shadow"].dependencies.forEach {shadowed ->

View File

@@ -13,7 +13,7 @@ modrinth {
versionNumber.set(projectVersion(project))
versionType.set("beta")
changelog.set(System.getenv("CHANGELOG") ?: "")
gameVersions.add(libs.minecraft.get().version as String)
gameVersions.addAll("1.21.7", libs.minecraft.get().version as String)
failSilently.set(true)
syncBodyFrom.set(rootProject.file("README.md").readText())

View File

@@ -36,18 +36,17 @@ dependencies {
exclude("io.netty", "*")
}
implementation(libs.netty.resolver.dns)
implementation(libs.netty.resolver.dns.native.macos) { artifact { classifier = "osx-x86_64" } }
implementation(libs.netty.codec.haproxy)
// Network dependencies we are updating ourselves
api(libs.netty.handler)
implementation(libs.netty.codec.haproxy)
api(libs.netty.transport.native.epoll) { artifact { classifier = "linux-x86_64" } }
implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-aarch_64" } }
// kqueue is macos only
implementation(libs.netty.transport.native.kqueue) { artifact { classifier = "osx-x86_64" } }
//api(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-x86_64" } }
//implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-aarch_64" } }
api(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-x86_64" } }
implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-aarch_64" } }
// Adventure text serialization
api(libs.bundles.adventure)

View File

@@ -30,14 +30,10 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollDatagramChannel;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.kqueue.KQueue;
import io.netty.channel.kqueue.KQueueDatagramChannel;
import io.netty.channel.kqueue.KQueueEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.uring.IoUring;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.Future;
import lombok.Getter;
import net.jodah.expiringmap.ExpirationPolicy;
@@ -64,13 +60,13 @@ import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.skin.SkinProvider;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.network.helper.TransportHelper;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.IntFunction;
import java.util.function.Supplier;
import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT;
@@ -90,7 +86,8 @@ public final class GeyserServer {
*/
private static final int MAGIC_RAKNET_LENGTH = 338;
private static final Transport TRANSPORT = compatibleTransport();
// Let MCPL determine the transport type -> less code duplication and risk of ending up with 2 different types
private static final TransportHelper.TransportType TRANSPORT = TransportHelper.TRANSPORT_TYPE;
/**
* See {@link EventLoopGroup#shutdownGracefully(long, long, TimeUnit)}
@@ -124,8 +121,8 @@ public final class GeyserServer {
this.geyser = geyser;
this.listenCount = Bootstraps.isReusePortAvailable() ? Integer.getInteger("Geyser.ListenCount", 2) : 1;
GeyserImpl.getInstance().getLogger().debug("Listen thread count: " + listenCount);
this.group = TRANSPORT.eventLoopGroupFactory().apply(listenCount);
this.childGroup = TRANSPORT.eventLoopGroupFactory().apply(threadCount);
this.group = TRANSPORT.eventLoopGroupFactory().apply(listenCount, new DefaultThreadFactory("GeyserServer", true));
this.childGroup = TRANSPORT.eventLoopGroupFactory().apply(threadCount, new DefaultThreadFactory("GeyserServerChild", true));
this.bootstrap = this.createBootstrap();
// setup SO_REUSEPORT if exists - or, if the option does not actually exist, reset listen count
@@ -201,16 +198,18 @@ public final class GeyserServer {
}
}
@SuppressWarnings("Convert2MethodRef")
private ServerBootstrap createBootstrap() {
if (this.geyser.getConfig().isDebugMode()) {
this.geyser.getLogger().debug("EventLoop type: " + TRANSPORT.datagramChannel());
if (TRANSPORT.datagramChannel() == NioDatagramChannel.class) {
this.geyser.getLogger().debug("Transport type: " + TRANSPORT.method().name());
if (TRANSPORT.datagramChannelClass() == NioDatagramChannel.class) {
if (System.getProperties().contains("disableNativeEventLoop")) {
this.geyser.getLogger().debug("EventLoop type is NIO because native event loops are disabled.");
} else {
// Use lambda here, not method reference, or else NoClassDefFoundError for Epoll/KQueue will not be caught
this.geyser.getLogger().debug("Reason for no Epoll: " + throwableOrCaught(() -> Epoll.unavailabilityCause()));
this.geyser.getLogger().debug("Reason for no KQueue: " + throwableOrCaught(() -> KQueue.unavailabilityCause()));
this.geyser.getLogger().debug("Reason for no IoUring: " + throwableOrCaught(() -> IoUring.unavailabilityCause()));
}
}
}
@@ -229,7 +228,7 @@ public final class GeyserServer {
this.geyser.getLogger().debug("Setting RakNet send cookie to " + rakSendCookie);
return new ServerBootstrap()
.channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannel()))
.channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannelClass()))
.group(group, childGroup)
.option(RakChannelOption.RAK_HANDLE_PING, true)
.option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu())
@@ -429,38 +428,4 @@ public final class GeyserServer {
return defaultValue;
}
}
private static Transport compatibleTransport() {
// FIXME supporting io_uring post 4.2 requires more changes
// if (isClassAvailable("io.netty.incubator.channel.uring.IOUring")
// && IOUring.isAvailable()
// && Boolean.parseBoolean(System.getProperty("Geyser.io_uring"))) {
// return new Transport(IOUringDatagramChannel.class, IOUringEventLoopGroup::new);
// }
if (isClassAvailable("io.netty.channel.epoll.Epoll") && Epoll.isAvailable()) {
return new Transport(EpollDatagramChannel.class, EpollEventLoopGroup::new);
}
if (isClassAvailable("io.netty.channel.kqueue.KQueue") && KQueue.isAvailable()) {
return new Transport(KQueueDatagramChannel.class, KQueueEventLoopGroup::new);
}
return new Transport(NioDatagramChannel.class, NioEventLoopGroup::new);
}
private record Transport(Class<? extends DatagramChannel> datagramChannel, IntFunction<EventLoopGroup> eventLoopGroupFactory) {
}
/**
* Used so implementations can opt to remove these dependencies if so desired
*/
private static boolean isClassAvailable(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}

View File

@@ -52,7 +52,7 @@ import java.util.concurrent.TimeUnit;
* Manages a Minecraft Java session over our LocalChannel implementations.
*/
public final class LocalSession extends ClientNetworkSession {
private static DefaultEventLoopGroup DEFAULT_EVENT_LOOP_GROUP;
private static EventLoopGroup DEFAULT_EVENT_LOOP_GROUP;
private static PreferredDirectByteBufAllocator PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR = null;
private final SocketAddress spoofedRemoteAddress;

View File

@@ -5,7 +5,7 @@ erosion = "1.1-20240521.000109-3"
events = "1.1-SNAPSHOT"
jackson = "2.17.0"
fastutil = "8.5.15-SNAPSHOT"
netty = "4.2.1.Final"
netty = "4.2.3.Final"
guava = "29.0-jre"
gson = "2.3.1" # Provided by Spigot 1.8.8
websocket = "1.5.1"
@@ -14,7 +14,7 @@ protocol-common = "3.0.0.Beta7-20250705.103024-11"
protocol-codec = "3.0.0.Beta7-20250705.103024-11"
raknet = "1.0.0.CR3-20250218.160705-18"
minecraftauth = "4.1.1"
mcprotocollib = "1.21.7-20250712.190650-3"
mcprotocollib = "1.21.7-20250725.134643-4"
adventure = "4.21.0"
adventure-platform = "4.3.0"
junit = "5.9.2"
@@ -35,13 +35,13 @@ viaproxy = "3.3.2-SNAPSHOT"
fabric-loader = "0.16.14"
fabric-api = "0.128.1+1.21.7"
fabric-permissions-api = "0.4.0-SNAPSHOT"
neoforge-minecraft = "21.7.0-beta"
neoforge-minecraft = "21.8.0-beta"
mixin = "0.8.5"
mixinextras = "0.3.5"
minecraft = "1.21.7"
minecraft = "1.21.8"
mockito = "5.+"
runtask = "2.3.1"
runpaperversion = "1.21.7"
runpaperversion = "1.21.8"
runvelocityversion = "3.4.0-SNAPSHOT"
# plugin versions
@@ -81,8 +81,6 @@ adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text
adventure-text-serializer-plain = { group = "net.kyori", name = "adventure-text-serializer-plain", version.ref = "adventure" }
adventure-text-serializer-bungeecord = { group = "net.kyori", name = "adventure-text-serializer-bungeecord", version.ref = "adventure-platform" }
netty-resolver-dns = { group = "io.netty", name = "netty-resolver-dns", version.ref = "netty" }
netty-resolver-dns-native-macos = { group = "io.netty", name = "netty-resolver-dns-native-macos", version.ref = "netty" }
netty-codec-haproxy = { group = "io.netty", name = "netty-codec-haproxy", version.ref = "netty" }
netty-handler = { group = "io.netty", name = "netty-handler", version.ref = "netty" }
netty-transport-native-epoll = { group = "io.netty", name = "netty-transport-native-epoll", version.ref = "netty" }