From 7cbce377a70ccc2b972391ea7ef566af71b20d3f Mon Sep 17 00:00:00 2001 From: bea4dev Date: Wed, 13 Sep 2023 00:00:28 +0900 Subject: [PATCH] fix Low accuracy tick rate (cherry picked from commit ce9d254a23791403a2b19ee4bb6bb52e175fa5dd) (cherry picked from commit 4e33a5e6d8ab55b2bd39db18df66c1659ab4ffbd) --- .../minestom/server/ServerProcessImpl.java | 3 +++ .../server/network/socket/Server.java | 4 ++++ .../server/network/socket/Worker.java | 7 ++++-- .../server/thread/TickSchedulerThread.java | 24 ++++++++++++++++--- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/minestom/server/ServerProcessImpl.java b/src/main/java/net/minestom/server/ServerProcessImpl.java index 176881ccf..694526fb8 100644 --- a/src/main/java/net/minestom/server/ServerProcessImpl.java +++ b/src/main/java/net/minestom/server/ServerProcessImpl.java @@ -297,6 +297,9 @@ final class ServerProcessImpl implements ServerProcess { // Flush all waiting packets PacketUtils.flush(); + // Server connection tick + server().tick(); + // Monitoring { final double acquisitionTimeMs = Acquirable.resetAcquiringTime() / 1e6D; diff --git a/src/main/java/net/minestom/server/network/socket/Server.java b/src/main/java/net/minestom/server/network/socket/Server.java index 8d3d6310d..6975a9697 100644 --- a/src/main/java/net/minestom/server/network/socket/Server.java +++ b/src/main/java/net/minestom/server/network/socket/Server.java @@ -91,6 +91,10 @@ public final class Server { }, "Ms-entrypoint").start(); } + public void tick() { + this.workers.forEach(Worker::tick); + } + public boolean isOpen() { return !stop; } diff --git a/src/main/java/net/minestom/server/network/socket/Worker.java b/src/main/java/net/minestom/server/network/socket/Worker.java index 6da7723ac..217e0d331 100644 --- a/src/main/java/net/minestom/server/network/socket/Worker.java +++ b/src/main/java/net/minestom/server/network/socket/Worker.java @@ -39,6 +39,10 @@ public final class Worker extends MinestomThread { } } + public void tick() { + this.selector.wakeup(); + } + @Override public void run() { while (server.isOpen()) { @@ -86,7 +90,7 @@ public final class Worker extends MinestomThread { MinecraftServer.getExceptionManager().handleException(t); connection.disconnect(); } - }, MinecraftServer.TICK_MS); + }); } catch (Exception e) { MinecraftServer.getExceptionManager().handleException(e); } @@ -118,7 +122,6 @@ public final class Worker extends MinestomThread { socket.setTcpNoDelay(Server.NO_DELAY); socket.setSoTimeout(30 * 1000); // 30 seconds } - this.selector.wakeup(); } public MessagePassingQueue queue() { diff --git a/src/main/java/net/minestom/server/thread/TickSchedulerThread.java b/src/main/java/net/minestom/server/thread/TickSchedulerThread.java index fcf60b76d..3a9c57451 100644 --- a/src/main/java/net/minestom/server/thread/TickSchedulerThread.java +++ b/src/main/java/net/minestom/server/thread/TickSchedulerThread.java @@ -25,9 +25,27 @@ public final class TickSchedulerThread extends MinestomThread { } catch (Exception e) { serverProcess.exception().handleException(e); } - final long wait = tickStart + tickNs - System.nanoTime(); - assert wait <= tickNs : "Wait time is too long: " + (wait / 1e6) + "ms"; - LockSupport.parkNanos(wait); + fixTickRate(tickNs); } } + + + private final long startTickNs = System.nanoTime(); + private long tick = 1; + + private void fixTickRate(long tickNs) { + long nextTickNs = startTickNs + (tickNs * tick); + if (System.nanoTime() < nextTickNs) { + while (true) { + // Checks in every 1/10 ms to see if the current time has reached the next scheduled time. + Thread.yield(); + LockSupport.parkNanos(100000); + long currentNs = System.nanoTime(); + if (currentNs >= nextTickNs) { + break; + } + } + } + tick++; + } }