mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-22 18:46:27 +01:00
c2fd399caf
* add config for sand duping (#352)
* Lithium: cache chunk gen sea level (#349)
based off: a55cfd1c91
* PaperPR: Inline shift fields in EnumDirection (#350)
* Introducing: Yatoclip (#360)
* New async nbt cache (#347)
* update pom
* whoops
* Try to address path issue and improve Jenkins build speed
* Detailed lag and crash reports (#369)
Added "Suspected Plugins" to Watchdog and crash reports
* Drop sand duping
* Add branch specific versions
* Remove copyright
* Revert mysql-connector-java version bump
* Small fixes
* More detailed lag and crash reports
* Don't use branch information when generating metadata
* Fix Jenkins Builds version command
* Fixup patches
* Fix patch notes
* Pull Request compatibility for branch detection
* Fix Pull Request compatibility for branch detection
* Set context classloader before launch
* Inject server jar to SystemClassLoader before launch
* Try fix compile in java8
* Run tests on CodeMC and Github Actions
Co-authored-by: Simon Gardling <Titaniumtown@gmail.com>
Co-authored-by: Zoe <duplexsys@protonmail.com>
Co-authored-by: Hugo Planque <12386279+HookWoods@users.noreply.github.com>
316 lines
14 KiB
Diff
316 lines
14 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Hugo Planque <hookwood01@gmail.com>
|
|
Date: Mon, 18 Jan 2021 11:27:08 +0100
|
|
Subject: [PATCH] New Network System
|
|
|
|
Co-authored-by: Ivan Pekov <ivan@mrivanplays.com>
|
|
|
|
diff --git a/pom.xml b/pom.xml
|
|
index 6109699411c349c4965de6dbdbd9f8454bc18b10..0bbc7badb1f597357d0fce7cd0f5faf5eb1d0eb5 100644
|
|
--- a/pom.xml
|
|
+++ b/pom.xml
|
|
@@ -56,6 +56,14 @@
|
|
<version>4.1.58.Final</version>
|
|
</dependency>
|
|
<!-- Tuinity end - fix compile issue (cannot see new api) by moving netty include BEFORE server jar -->
|
|
+ <!-- Yatopia start - Add IOUring beta support -->
|
|
+ <dependency>
|
|
+ <groupId>io.netty.incubator</groupId>
|
|
+ <artifactId>netty-incubator-transport-native-io_uring</artifactId>
|
|
+ <version>0.0.3.Final</version>
|
|
+ <classifier>linux-x86_64</classifier>
|
|
+ </dependency>
|
|
+ <!-- Yatopia end -->
|
|
<dependency>
|
|
<groupId>io.papermc</groupId>
|
|
<artifactId>minecraft-server</artifactId>
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 87cf9cd88d1fb5ae70d19e5618ebfb67d281304a..a1c2bea7c93433434b4e4dfd0bb4b9620657c40d 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -1740,6 +1740,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
|
return true;
|
|
}
|
|
|
|
+ public final boolean isUsingNativeTransport() { return l(); } // Yatopia - OBFHELPER
|
|
public abstract boolean l();
|
|
|
|
public boolean getPVP() {
|
|
diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java
|
|
index 0668d383db1f3a81d1053954d72678c7ac5aecec..d22f0ee3f7f2daa8323d454aca1f94733b249333 100644
|
|
--- a/src/main/java/net/minecraft/server/ServerConnection.java
|
|
+++ b/src/main/java/net/minecraft/server/ServerConnection.java
|
|
@@ -11,6 +11,7 @@ import io.netty.channel.ChannelInitializer;
|
|
import io.netty.channel.ChannelOption;
|
|
import io.netty.channel.EventLoopGroup;
|
|
import io.netty.channel.epoll.Epoll;
|
|
+import io.netty.channel.epoll.EpollChannelOption; // Yatopia
|
|
import io.netty.channel.epoll.EpollEventLoopGroup;
|
|
import io.netty.channel.epoll.EpollServerSocketChannel;
|
|
import io.netty.channel.nio.NioEventLoopGroup;
|
|
@@ -26,6 +27,7 @@ import java.util.List;
|
|
import javax.annotation.Nullable;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
+import org.yatopiamc.yatopia.server.network.NetworkType; // Yatopia
|
|
|
|
public class ServerConnection {
|
|
|
|
@@ -52,15 +54,29 @@ public class ServerConnection {
|
|
}
|
|
// Paper end
|
|
|
|
+ // Yatopia start - New network system
|
|
+ private final NetworkType networkType;
|
|
+ private final EventLoopGroup boss, worker;
|
|
+ // Yatopia end
|
|
+
|
|
public ServerConnection(MinecraftServer minecraftserver) {
|
|
this.e = minecraftserver;
|
|
this.c = true;
|
|
+
|
|
+ // Yatopia start - New network system
|
|
+ this.networkType = NetworkType.bestType(minecraftserver, LOGGER);
|
|
+ this.boss = networkType.createEventLoopGroup(NetworkType.LoopGroupType.BOSS);
|
|
+ this.worker = networkType.createEventLoopGroup(NetworkType.LoopGroupType.WORKER);
|
|
+ // Yatopia end
|
|
}
|
|
|
|
public void a(@Nullable InetAddress inetaddress, int i) throws IOException {
|
|
+ /* // Yatopia start - New network system
|
|
List list = this.listeningChannels;
|
|
+ */
|
|
|
|
synchronized (this.listeningChannels) {
|
|
+ /*
|
|
Class oclass;
|
|
LazyInitVar lazyinitvar;
|
|
|
|
@@ -73,16 +89,25 @@ public class ServerConnection {
|
|
lazyinitvar = ServerConnection.a;
|
|
ServerConnection.LOGGER.info("Using default channel type");
|
|
}
|
|
+ */
|
|
+
|
|
|
|
// Tuinity start - indicate Velocity natives in use
|
|
ServerConnection.LOGGER.info("Tuinity: Using " + com.velocitypowered.natives.util.Natives.compress.getLoadedVariant() + " compression from Velocity.");
|
|
ServerConnection.LOGGER.info("Tuinity: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity.");
|
|
// Tuinity end
|
|
|
|
- this.listeningChannels.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer<Channel>() {
|
|
+ ServerConnection.LOGGER.info("Yatopia: Using " + networkType.getName() + " network type.");
|
|
+ ServerBootstrap serverBootstrap = new ServerBootstrap();
|
|
+
|
|
+ if (org.yatopiamc.yatopia.server.YatopiaConfig.tcpFastOpen && networkType == NetworkType.EPOLL) {
|
|
+ serverBootstrap.option(EpollChannelOption.TCP_FASTOPEN, 3); // Will improve the connection with some speed
|
|
+ }
|
|
+ this.listeningChannels.add((((serverBootstrap).channelFactory(networkType.getServerSocketChannelFactory())).childHandler(new ChannelInitializer<Channel>() {
|
|
protected void initChannel(Channel channel) throws Exception {
|
|
try {
|
|
channel.config().setOption(ChannelOption.TCP_NODELAY, true);
|
|
+ channel.config().setOption(ChannelOption.IP_TOS, 0x18); // Change the priority of the packet to immediate
|
|
} catch (ChannelException channelexception) {
|
|
;
|
|
}
|
|
@@ -97,7 +122,8 @@ public class ServerConnection {
|
|
channel.pipeline().addLast("packet_handler", (ChannelHandler) object);
|
|
((NetworkManager) object).setPacketListener(new HandshakeListener(ServerConnection.this.e, (NetworkManager) object));
|
|
}
|
|
- }).group((EventLoopGroup) lazyinitvar.a()).localAddress(inetaddress, i)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit
|
|
+ }).group(boss, worker).localAddress(inetaddress, i)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit
|
|
+ // Yatopia end
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java b/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
|
index c2dc5265552ebd429111253c70481003a4be29dd..c67654e8701b9da6499d442048429149daae7150 100644
|
|
--- a/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
|
+++ b/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
|
@@ -271,4 +271,17 @@ public class YatopiaConfig {
|
|
logPlayerLoginLoc = getBoolean("settings.log-player-login-location", logPlayerLoginLoc);
|
|
}
|
|
|
|
+ public static boolean ioUringBeta = false;
|
|
+ public static boolean tcpFastOpen = false;
|
|
+ public static boolean debugNetwork = false;
|
|
+ private static void newNetworkSystem() {
|
|
+ ioUringBeta = getBoolean("network.io-uring", ioUringBeta);
|
|
+ if (config.get("network.ftcp-fastopen") != null) {
|
|
+ config.set("network.tcp-fastopen", getBoolean("network.ftcp-fastopen", tcpFastOpen));
|
|
+ config.set("network.ftcp-fastopen", null);
|
|
+ }
|
|
+ tcpFastOpen = getBoolean("network.tcp-fastopen", tcpFastOpen);
|
|
+ debugNetwork = getBoolean("network.debug", debugNetwork);
|
|
+ }
|
|
+
|
|
}
|
|
diff --git a/src/main/java/org/yatopiamc/yatopia/server/network/NettyThreadFactory.java b/src/main/java/org/yatopiamc/yatopia/server/network/NettyThreadFactory.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..3e74e23f3cc44b7547d9f8575b411059e0e65449
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/yatopiamc/yatopia/server/network/NettyThreadFactory.java
|
|
@@ -0,0 +1,27 @@
|
|
+package org.yatopiamc.yatopia.server.network;
|
|
+
|
|
+import io.netty.util.concurrent.FastThreadLocalThread;
|
|
+import java.util.concurrent.ThreadFactory;
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
+
|
|
+/**
|
|
+ * Based off of Velocity's VelocityNettyThreadFactory
|
|
+ */
|
|
+public class NettyThreadFactory implements ThreadFactory {
|
|
+
|
|
+ private final AtomicInteger threadNumber = new AtomicInteger();
|
|
+ private final String networkTypeName, loopGroupTypeName;
|
|
+
|
|
+ public NettyThreadFactory(String networkTypeName, String loopGroupTypeName) {
|
|
+ this.networkTypeName = networkTypeName;
|
|
+ this.loopGroupTypeName = loopGroupTypeName;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Thread newThread(Runnable r) {
|
|
+ return new FastThreadLocalThread(
|
|
+ r,
|
|
+ "Netty " + networkTypeName + " " + loopGroupTypeName + " #" + threadNumber.getAndIncrement()
|
|
+ );
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/org/yatopiamc/yatopia/server/network/NetworkType.java b/src/main/java/org/yatopiamc/yatopia/server/network/NetworkType.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..6c387f29e4db7e1574a2bbb119465c48b8ed2f90
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/yatopiamc/yatopia/server/network/NetworkType.java
|
|
@@ -0,0 +1,129 @@
|
|
+package org.yatopiamc.yatopia.server.network;
|
|
+
|
|
+import io.netty.channel.ChannelFactory;
|
|
+import io.netty.channel.EventLoopGroup;
|
|
+import io.netty.channel.epoll.Epoll;
|
|
+import io.netty.channel.epoll.EpollEventLoopGroup;
|
|
+import io.netty.channel.epoll.EpollServerSocketChannel;
|
|
+import io.netty.channel.kqueue.KQueue;
|
|
+import io.netty.channel.kqueue.KQueueEventLoopGroup;
|
|
+import io.netty.channel.kqueue.KQueueServerSocketChannel;
|
|
+import io.netty.channel.nio.NioEventLoopGroup;
|
|
+import io.netty.channel.socket.ServerSocketChannel;
|
|
+import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
+import io.netty.incubator.channel.uring.IOUring;
|
|
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
|
|
+import io.netty.incubator.channel.uring.IOUringServerSocketChannel;
|
|
+
|
|
+import java.util.concurrent.ThreadFactory;
|
|
+import java.util.function.BiFunction;
|
|
+
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.apache.logging.log4j.Level;
|
|
+import org.apache.logging.log4j.Logger;
|
|
+import org.spigotmc.SpigotConfig;
|
|
+import org.yatopiamc.yatopia.server.YatopiaConfig;
|
|
+
|
|
+/**
|
|
+ * Based off of Velocity's TransportType
|
|
+ */
|
|
+public enum NetworkType {
|
|
+ NIO("NIO", NioServerSocketChannel::new, (name, type) -> new NioEventLoopGroup(8, createThreadFactory(name, type))),
|
|
+
|
|
+ EPOLL("Epoll", EpollServerSocketChannel::new, (name, type) -> new EpollEventLoopGroup(8, createThreadFactory(name, type))),
|
|
+
|
|
+ IOURING("IOUring", IOUringServerSocketChannel::new, (name, type) -> new IOUringEventLoopGroup(8, createThreadFactory(name, type))),
|
|
+
|
|
+ KQUEUE("KQueue", KQueueServerSocketChannel::new, (name, type) -> new KQueueEventLoopGroup(8, createThreadFactory(name, type)));
|
|
+
|
|
+ public final String name;
|
|
+ public final ChannelFactory<? extends ServerSocketChannel> serverSocketChannelFactory;
|
|
+ public final BiFunction<String, LoopGroupType, EventLoopGroup> eventLoopGroupFactory;
|
|
+
|
|
+ NetworkType(final String name,
|
|
+ final ChannelFactory<? extends ServerSocketChannel> serverSocketChannelFactory,
|
|
+ final BiFunction<String, LoopGroupType, EventLoopGroup> eventLoopGroupFactory) {
|
|
+ this.name = name;
|
|
+ this.serverSocketChannelFactory = serverSocketChannelFactory;
|
|
+ this.eventLoopGroupFactory = eventLoopGroupFactory;
|
|
+ }
|
|
+
|
|
+ public String getName() {
|
|
+ return name;
|
|
+ }
|
|
+
|
|
+ public ChannelFactory<? extends ServerSocketChannel> getServerSocketChannelFactory() {
|
|
+ return serverSocketChannelFactory;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ return this.name;
|
|
+ }
|
|
+
|
|
+ public EventLoopGroup createEventLoopGroup(final LoopGroupType type) {
|
|
+ return this.eventLoopGroupFactory.apply(this.name, type);
|
|
+ }
|
|
+
|
|
+ private static ThreadFactory createThreadFactory(final String name, final LoopGroupType type) {
|
|
+ return new NettyThreadFactory(name, type.toString());
|
|
+ }
|
|
+
|
|
+ public static NetworkType bestType(MinecraftServer minecraftServer, Logger logger) {
|
|
+ if (!minecraftServer.isUsingNativeTransport()) {
|
|
+ return NIO;
|
|
+ }
|
|
+ // Actually, there is a decompression problem with zlib from bungeecord that makes
|
|
+ // IOUring not available on spigot server with bungeecord
|
|
+ // https://github.com/netty/netty-incubator-transport-io_uring/issues/40
|
|
+ // Looks like iouring send very small compressed packet and trigger PacketDecompressor
|
|
+ if (!SpigotConfig.bungee && YatopiaConfig.ioUringBeta && MinecraftServer.getServer().ax() < 0) {
|
|
+ if (IOUring.isAvailable()) {
|
|
+ return IOURING;
|
|
+ } else if (YatopiaConfig.debugNetwork) {
|
|
+ logger.log(Level.ERROR, "IOUring is not working: {}", exceptionMessage(IOUring.unavailabilityCause()));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (Epoll.isAvailable()) {
|
|
+ return EPOLL;
|
|
+ } else if (YatopiaConfig.debugNetwork) {
|
|
+ logger.log(Level.ERROR, "Epoll is not working: {}", exceptionMessage(Epoll.unavailabilityCause()));
|
|
+ }
|
|
+
|
|
+ if (KQueue.isAvailable()) {
|
|
+ return KQUEUE;
|
|
+ } else if (YatopiaConfig.debugNetwork) {
|
|
+ logger.log(Level.ERROR, "KQueue is not working: {}", exceptionMessage(KQueue.unavailabilityCause()));
|
|
+ }
|
|
+
|
|
+ return NIO;
|
|
+ }
|
|
+
|
|
+ private static String exceptionMessage(Throwable throwable) {
|
|
+ StackTraceElement[] trace = throwable.getStackTrace();
|
|
+ return getClassNameFromString(throwable.getClass().getName()) + " : " + throwable.getMessage() +
|
|
+ ((trace.length > 0) ? " @ " + throwable.getStackTrace()[0].getClassName() + ":" + throwable.getStackTrace()[0].getLineNumber() : "");
|
|
+ }
|
|
+
|
|
+ private static String getClassNameFromString(String className) {
|
|
+ int i = className.lastIndexOf('.');
|
|
+ return i > 0 ? className.substring(i + 1) : className;
|
|
+ }
|
|
+
|
|
+ public enum LoopGroupType {
|
|
+ BOSS("Boss"),
|
|
+ WORKER("Worker");
|
|
+
|
|
+ private final String name;
|
|
+
|
|
+ LoopGroupType(final String name) {
|
|
+ this.name = name;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ return this.name;
|
|
+ }
|
|
+ }
|
|
+}
|