diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index 623769e5..94fb2704 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -15,14 +15,13 @@ import carpet.commands.PerimeterInfoCommand; import carpet.commands.PlayerCommand; import carpet.commands.ProfileCommand; import carpet.fakes.MinecraftServerInterface; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import carpet.script.ScriptCommand; import carpet.commands.SpawnCommand; import carpet.commands.TestCommand; import carpet.commands.TickCommand; import carpet.network.ServerNetworkHandler; import carpet.helpers.HopperCounter; -import carpet.helpers.TickSpeed; import carpet.logging.LoggerRegistry; import carpet.script.CarpetScriptServer; import carpet.api.settings.CarpetRule; @@ -129,7 +128,7 @@ public class CarpetServer // static for now - easier to handle all around the co public static void tick(MinecraftServer server) { - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); trm.tick(); HUDController.update_hud(server, null); if (scriptServer != null) scriptServer.tick(); @@ -229,9 +228,6 @@ public class CarpetServer // static for now - easier to handle all around the co extensions.forEach(e -> e.onServerClosed(server)); minecraft_server = null; } - - // this for whatever reason gets called multiple times even when joining; - TickSpeed.resetClient(); } public static void onServerDoneClosing(MinecraftServer server) { diff --git a/src/main/java/carpet/commands/SpawnCommand.java b/src/main/java/carpet/commands/SpawnCommand.java index 62bbb16a..b3edf1c5 100644 --- a/src/main/java/carpet/commands/SpawnCommand.java +++ b/src/main/java/carpet/commands/SpawnCommand.java @@ -4,7 +4,7 @@ import carpet.CarpetSettings; import carpet.fakes.MinecraftServerInterface; import carpet.fakes.SpawnGroupInterface; import carpet.helpers.HopperCounter; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import carpet.utils.CommandHelper; import carpet.utils.Messenger; import carpet.utils.SpawnReporter; @@ -199,8 +199,8 @@ public class SpawnCommand // tick warp 0 - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - trm.tickrate_advance(null, 0, null, null); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + trm.requestGameToWarpSpeed(null, 0, null, null); // tick warp given player CommandSourceStack csource = null; ServerPlayer player = null; @@ -212,7 +212,7 @@ public class SpawnCommand catch (CommandSyntaxException ignored) { } - trm.tickrate_advance(player, ticks, null, csource); + trm.requestGameToWarpSpeed(player, ticks, null, csource); Messenger.m(source, String.format("gi Started spawn test for %d ticks", ticks)); return 1; } diff --git a/src/main/java/carpet/commands/TickCommand.java b/src/main/java/carpet/commands/TickCommand.java index 8f0130ef..5b3bcda4 100644 --- a/src/main/java/carpet/commands/TickCommand.java +++ b/src/main/java/carpet/commands/TickCommand.java @@ -2,7 +2,7 @@ package carpet.commands; import carpet.CarpetSettings; import carpet.fakes.MinecraftServerInterface; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import carpet.network.ServerNetworkHandler; import carpet.utils.CarpetProfiler; import carpet.utils.CommandHelper; @@ -73,33 +73,33 @@ public class TickCommand private static int setTps(CommandSourceStack source, float tps) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - trm.tickrate(tps, true); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + trm.setTickRate(tps, true); queryTps(source); return (int)tps; } private static int queryTps(CommandSourceStack source) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - Messenger.m(source, "w Current tps is: ",String.format("wb %.1f", trm.tickrate)); - return (int) trm.tickrate; + Messenger.m(source, "w Current tps is: ",String.format("wb %.1f", trm.tickrate())); + return (int) trm.tickrate(); } private static int setWarp(CommandSourceStack source, int advance, String tail_command) { ServerPlayer player = source.getPlayer(); // may be null - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - Component message = trm.tickrate_advance(player, advance, tail_command, source); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + Component message = trm.requestGameToWarpSpeed(player, advance, tail_command, source); source.sendSuccess(() -> message, false); return 1; } private static int freezeStatus(CommandSourceStack source) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - if(trm.isPaused()) + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + if(trm.gameIsPaused()) { Messenger.m(source, "gi Freeze Status: Game is "+(trm.deeplyFrozen()?"deeply ":"")+"frozen"); } @@ -112,9 +112,9 @@ public class TickCommand private static int setFreeze(CommandSourceStack source, boolean isDeep, boolean freeze) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); trm.setFrozenState(freeze, isDeep); - if (trm.isPaused()) + if (trm.gameIsPaused()) { Messenger.m(source, "gi Game is "+(isDeep?"deeply ":"")+"frozen"); } @@ -127,24 +127,24 @@ public class TickCommand private static int toggleFreeze(CommandSourceStack source, boolean isDeep) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - return setFreeze(source, isDeep, !trm.isPaused()); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + return setFreeze(source, isDeep, !trm.gameIsPaused()); } private static int step(CommandSourceStack source, int advance) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - trm.add_ticks_to_run_in_pause(advance); + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + trm.stepGameIfPaused(advance); Messenger.m(source, "gi Stepping " + advance + " tick" + (advance != 1 ? "s" : "")); return 1; } private static int toggleSuperHot(CommandSourceStack source) { - TickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); - trm.is_superHot = !trm.is_superHot; + ServerTickRateManager trm = ((MinecraftServerInterface)source.getServer()).getTickRateManager(); + trm.setSuperHot(!trm.isSuperHot()); ServerNetworkHandler.updateSuperHotStateToConnectedPlayers(source.getServer()); - if (trm.is_superHot) + if (trm.isSuperHot()) { Messenger.m(source, "gi Superhot enabled"); } diff --git a/src/main/java/carpet/fakes/ClientLevelInterface.java b/src/main/java/carpet/fakes/ClientLevelInterface.java new file mode 100644 index 00000000..6ecdf58a --- /dev/null +++ b/src/main/java/carpet/fakes/ClientLevelInterface.java @@ -0,0 +1,8 @@ +package carpet.fakes; + +import carpet.helpers.TickRateManager; + +public interface ClientLevelInterface +{ + TickRateManager getTickRateManager(); +} diff --git a/src/main/java/carpet/fakes/MinecraftInterface.java b/src/main/java/carpet/fakes/MinecraftInterface.java new file mode 100644 index 00000000..63553267 --- /dev/null +++ b/src/main/java/carpet/fakes/MinecraftInterface.java @@ -0,0 +1,10 @@ +package carpet.fakes; + +import carpet.helpers.TickRateManager; + +import java.util.Optional; + +public interface MinecraftInterface +{ + Optional getTickRateManager(); +} diff --git a/src/main/java/carpet/fakes/MinecraftServerInterface.java b/src/main/java/carpet/fakes/MinecraftServerInterface.java index ce2466d1..cf3fd479 100644 --- a/src/main/java/carpet/fakes/MinecraftServerInterface.java +++ b/src/main/java/carpet/fakes/MinecraftServerInterface.java @@ -3,7 +3,7 @@ package carpet.fakes; import java.util.Map; import java.util.function.BooleanSupplier; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import carpet.script.CarpetScriptServer; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; @@ -25,5 +25,5 @@ public interface MinecraftServerInterface void addScriptServer(CarpetScriptServer scriptServer); CarpetScriptServer getScriptServer(); - TickRateManager getTickRateManager(); + ServerTickRateManager getTickRateManager(); } diff --git a/src/main/java/carpet/helpers/ServerTickRateManager.java b/src/main/java/carpet/helpers/ServerTickRateManager.java new file mode 100644 index 00000000..775acf0b --- /dev/null +++ b/src/main/java/carpet/helpers/ServerTickRateManager.java @@ -0,0 +1,246 @@ +package carpet.helpers; + +import carpet.CarpetServer; +import carpet.network.ServerNetworkHandler; +import carpet.utils.Messenger; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +public class ServerTickRateManager extends TickRateManager +{ + private long remainingWarpTicks = 0; + private long tickWarpStartTime = 0; + private long scheduledCurrentWarpTicks = 0; + private ServerPlayer warpResponsiblePlayer = null; + private String tickWarpCallback = null; + private CommandSourceStack warpResponsibleSource = null; + + private MinecraftServer server; + + public ServerTickRateManager(MinecraftServer server) { + this.server = server; + } + + public boolean isInWarpSpeed() + { + return tickWarpStartTime != 0; + } + + /** + * Whether or not the game is deeply frozen. + * This can be used for things that you may not normally want + * to freeze, but may need to in some situations. + * This should be checked with {@link #runGameElements} to make sure the + * current tick is actually frozen, not only the game + * + * @return Whether or not the game is deeply frozen. + */ + public boolean deeplyFrozen() + { + return deepFreeze; + } + + /** + * Used to update the frozen state of the game. + * Handles connected clients as well. + * + * @param isPaused Whether or not the game is paused + * @param isDeepFreeze Whether or not the game is deeply frozen + */ + @Override + public void setFrozenState(boolean isPaused, boolean isDeepFreeze) + { + super.setFrozenState(isPaused, isDeepFreeze); + ServerNetworkHandler.updateFrozenStateToConnectedPlayers(server); + } + + + public void resetPlayerActivity() + { + if (playerActivityTimeout < PLAYER_GRACE) + { + playerActivityTimeout = PLAYER_GRACE; + ServerNetworkHandler.updateTickPlayerActiveTimeoutToConnectedPlayers(server); + } + } + + public void stepGameIfPaused(int ticks) + { + playerActivityTimeout = PLAYER_GRACE + ticks; + ServerNetworkHandler.updateTickPlayerActiveTimeoutToConnectedPlayers(server); + } + + public Component requestGameToWarpSpeed(ServerPlayer player, int advance, String callback, CommandSourceStack source) + { + if (0 == advance) + { + tickWarpCallback = null; + if (source != warpResponsibleSource) + { + warpResponsibleSource = null; + } + if (remainingWarpTicks > 0) + { + finishTickWarp(); + warpResponsibleSource = null; + return Messenger.c("gi Warp interrupted"); + } + return Messenger.c("ri No warp in progress"); + } + if (remainingWarpTicks > 0) + { + String who = "Another player"; + if (warpResponsiblePlayer != null) + { + who = warpResponsiblePlayer.getScoreboardName(); + } + return Messenger.c("l " + who + " is already advancing time at the moment. Try later or ask them"); + } + warpResponsiblePlayer = player; + tickWarpStartTime = System.nanoTime(); + scheduledCurrentWarpTicks = advance; + remainingWarpTicks = advance; + tickWarpCallback = callback; + warpResponsibleSource = source; + return Messenger.c("gi Warp speed ...."); + } + + // should be private + public void finishTickWarp() + { + + long completed_ticks = scheduledCurrentWarpTicks - remainingWarpTicks; + double milis_to_complete = System.nanoTime() - tickWarpStartTime; + if (milis_to_complete == 0.0) + { + milis_to_complete = 1.0; + } + milis_to_complete /= 1000000.0; + int tps = (int) (1000.0D * completed_ticks / milis_to_complete); + double mspt = (1.0 * milis_to_complete) / completed_ticks; + scheduledCurrentWarpTicks = 0; + tickWarpStartTime = 0; + if (tickWarpCallback != null) + { + Commands icommandmanager = warpResponsibleSource.getServer().getCommands(); + try + { + icommandmanager.performPrefixedCommand(warpResponsibleSource, tickWarpCallback); + } + catch (Throwable var23) + { + if (warpResponsiblePlayer != null) + { + Messenger.m(warpResponsiblePlayer, "r Command Callback failed - unknown error: ", "rb /" + tickWarpCallback, "/" + tickWarpCallback); + } + } + tickWarpCallback = null; + warpResponsibleSource = null; + } + if (warpResponsiblePlayer != null) + { + Messenger.m(warpResponsiblePlayer, String.format("gi ... Time warp completed with %d tps, or %.2f mspt", tps, mspt)); + warpResponsiblePlayer = null; + } + else + { + Messenger.print_server_message(CarpetServer.minecraft_server, String.format("... Time warp completed with %d tps, or %.2f mspt", tps, mspt)); + } + remainingWarpTicks = 0; + + } + + public boolean continueWarp() + { + if (!runGameElements) + // Returning false so we don't have to run at max speed when doing nothing + { + return false; + } + if (remainingWarpTicks > 0) + { + if (remainingWarpTicks == scheduledCurrentWarpTicks) //first call after previous tick, adjust start time + { + tickWarpStartTime = System.nanoTime(); + } + remainingWarpTicks -= 1; + return true; + } + else + { + finishTickWarp(); + return false; + } + } + + /** + * Functional interface that listens for tickrate changes. This is + * implemented to allow tickrate compatibility with other mods etc. + */ + private final Map> tickrateListeners = new HashMap<>(); + private static final float MIN_TICKRATE = 0.01f; + + //unused - mod compat reasons + @Override + public void setTickRate(float rate) + { + setTickRate(rate, true); + } + + public void setTickRate(float rate, boolean update) + { + super.setTickRate(rate); + if (update) + { + notifyTickrateListeners("carpet"); + } + } + + private void tickrateChanged(String modId, float rate) + { + // Other mods might change the tickrate in a slightly + // different way. Also allow for tickrates that don't + // divide into 1000 here. + + if (rate < MIN_TICKRATE) + { + rate = MIN_TICKRATE; + } + + tickrate = rate; + mspt = 1000.0f / tickrate; + + notifyTickrateListeners(modId); + } + + private void notifyTickrateListeners(String originModId) + { + synchronized (tickrateListeners) + { + for (Map.Entry> listenerEntry : tickrateListeners.entrySet()) + { + if (originModId == null || !originModId.equals(listenerEntry.getKey())) + { + listenerEntry.getValue().accept(originModId, tickrate); + } + } + } + ServerNetworkHandler.updateTickSpeedToConnectedPlayers(server); + } + + public BiConsumer addTickrateListener(String modId, BiConsumer tickrateListener) + { + synchronized (tickrateListeners) + { + tickrateListeners.put(modId, tickrateListener); + } + return this::tickrateChanged; + } +} diff --git a/src/main/java/carpet/helpers/TickRateManager.java b/src/main/java/carpet/helpers/TickRateManager.java index 05347927..dca76a39 100644 --- a/src/main/java/carpet/helpers/TickRateManager.java +++ b/src/main/java/carpet/helpers/TickRateManager.java @@ -1,237 +1,18 @@ package carpet.helpers; -import carpet.CarpetServer; -import carpet.network.ServerNetworkHandler; -import carpet.utils.Messenger; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.network.chat.Component; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; - public class TickRateManager { public static final int PLAYER_GRACE = 2; - public float tickrate = 20.0f; - public float mspt = 50.0f; - public long time_bias = 0; - public long time_warp_start_time = 0; - public long time_warp_scheduled_ticks = 0; - public ServerPlayer time_advancerer = null; - public String tick_warp_callback = null; - public CommandSourceStack tick_warp_sender = null; - public int player_active_timeout = 0; - public boolean process_entities = true; - private boolean deepFreeze = false; - private boolean is_paused = false; - public boolean is_superHot = false; + protected float tickrate = 20.0f; + protected float mspt = 50.0f; + protected int playerActivityTimeout = 0; + protected boolean runGameElements = true; + // deep freeze is onlyu used serverside + protected boolean deepFreeze = false; + protected boolean isGamePaused = false; + protected boolean isSuperHot = false; - private MinecraftServer server; - - public TickRateManager(MinecraftServer server) { - this.server = server; - } - - - /** - * @return Whether or not the game is in a frozen state. - * You should normally use {@link #process_entities} instead, - * since that one accounts for tick steps and superhot - */ - public boolean isPaused() - { - return is_paused; - } - - public boolean process_entities() - { - return process_entities; - } - - /** - * Whether or not the game is deeply frozen. - * This can be used for things that you may not normally want - * to freeze, but may need to in some situations. - * This should be checked with {@link #process_entities} to make sure the - * current tick is actually frozen, not only the game - * - * @return Whether or not the game is deeply frozen. - */ - public boolean deeplyFrozen() - { - return deepFreeze; - } - - /** - * Used to update the frozen state of the game. - * Handles connected clients as well. - * - * @param isPaused Whether or not the game is paused - * @param isDeepFreeze Whether or not the game is deeply frozen - */ - public void setFrozenState(boolean isPaused, boolean isDeepFreeze) - { - is_paused = isPaused; - deepFreeze = isPaused ? isDeepFreeze : false; - ServerNetworkHandler.updateFrozenStateToConnectedPlayers(server); - } - - - public void reset_player_active_timeout() - { - if (player_active_timeout < PLAYER_GRACE) - { - player_active_timeout = PLAYER_GRACE; - ServerNetworkHandler.updateTickPlayerActiveTimeoutToConnectedPlayers(server); - } - } - - public void add_ticks_to_run_in_pause(int ticks) - { - player_active_timeout = PLAYER_GRACE + ticks; - ServerNetworkHandler.updateTickPlayerActiveTimeoutToConnectedPlayers(server); - } - - public Component tickrate_advance(ServerPlayer player, int advance, String callback, CommandSourceStack source) - { - if (0 == advance) - { - tick_warp_callback = null; - if (source != tick_warp_sender) - { - tick_warp_sender = null; - } - if (time_bias > 0) - { - finish_time_warp(); - tick_warp_sender = null; - return Messenger.c("gi Warp interrupted"); - } - return Messenger.c("ri No warp in progress"); - } - if (time_bias > 0) - { - String who = "Another player"; - if (time_advancerer != null) - { - who = time_advancerer.getScoreboardName(); - } - return Messenger.c("l " + who + " is already advancing time at the moment. Try later or ask them"); - } - time_advancerer = player; - time_warp_start_time = System.nanoTime(); - time_warp_scheduled_ticks = advance; - time_bias = advance; - tick_warp_callback = callback; - tick_warp_sender = source; - return Messenger.c("gi Warp speed ...."); - } - - public void finish_time_warp() - { - - long completed_ticks = time_warp_scheduled_ticks - time_bias; - double milis_to_complete = System.nanoTime() - time_warp_start_time; - if (milis_to_complete == 0.0) - { - milis_to_complete = 1.0; - } - milis_to_complete /= 1000000.0; - int tps = (int) (1000.0D * completed_ticks / milis_to_complete); - double mspt = (1.0 * milis_to_complete) / completed_ticks; - time_warp_scheduled_ticks = 0; - time_warp_start_time = 0; - if (tick_warp_callback != null) - { - Commands icommandmanager = tick_warp_sender.getServer().getCommands(); - try - { - icommandmanager.performPrefixedCommand(tick_warp_sender, tick_warp_callback); - } - catch (Throwable var23) - { - if (time_advancerer != null) - { - Messenger.m(time_advancerer, "r Command Callback failed - unknown error: ", "rb /" + tick_warp_callback, "/" + tick_warp_callback); - } - } - tick_warp_callback = null; - tick_warp_sender = null; - } - if (time_advancerer != null) - { - Messenger.m(time_advancerer, String.format("gi ... Time warp completed with %d tps, or %.2f mspt", tps, mspt)); - time_advancerer = null; - } - else - { - Messenger.print_server_message(CarpetServer.minecraft_server, String.format("... Time warp completed with %d tps, or %.2f mspt", tps, mspt)); - } - time_bias = 0; - - } - - public boolean continueWarp() - { - if (!process_entities) - // Returning false so we don't have to run at max speed when doing nothing - { - return false; - } - if (time_bias > 0) - { - if (time_bias == time_warp_scheduled_ticks) //first call after previous tick, adjust start time - { - time_warp_start_time = System.nanoTime(); - } - time_bias -= 1; - return true; - } - else - { - finish_time_warp(); - return false; - } - } - - public void tick() - { - if (player_active_timeout > 0) - { - player_active_timeout--; - } - if (is_paused) - { - process_entities = player_active_timeout >= PLAYER_GRACE; - } - else if (is_superHot) - { - process_entities = player_active_timeout > 0; - } - else - { - process_entities = true; - } - } - - /** - * Functional interface that listens for tickrate changes. This is - * implemented to allow tickrate compatibility with other mods etc. - */ - private final Map> tickrateListeners = new HashMap<>(); - private static final float MIN_TICKRATE = 0.01f; - - //unused - mod compat reasons - public void tickrate(float rate) - { - tickrate(rate, true); - } - - public void tickrate(float rate, boolean update) + public void setTickRate(float rate) { tickrate = rate; long msptt = (long) (1000.0 / tickrate); @@ -240,53 +21,76 @@ public class TickRateManager msptt = 1L; tickrate = 1000.0f; } - - this.mspt = msptt; - - if (update) - { - notifyTickrateListeners("carpet"); - } + mspt = msptt; } - private void tickrateChanged(String modId, float rate) + public float tickrate() { - // Other mods might change the tickrate in a slightly - // different way. Also allow for tickrates that don't - // divide into 1000 here. - - if (rate < MIN_TICKRATE) - { - rate = MIN_TICKRATE; - } - - tickrate = rate; - mspt = 1000.0f / tickrate; - - notifyTickrateListeners(modId); + return tickrate; } - private void notifyTickrateListeners(String originModId) + /** + * @return Whether or not the game is in a frozen state. + * You should normally use {@link #runGameElements} instead, + * since that one accounts for tick steps and superhot + */ + public boolean gameIsPaused() { - synchronized (tickrateListeners) - { - for (Map.Entry> listenerEntry : tickrateListeners.entrySet()) - { - if (originModId == null || !originModId.equals(listenerEntry.getKey())) - { - listenerEntry.getValue().accept(originModId, Float.valueOf(tickrate)); - } - } - } - ServerNetworkHandler.updateTickSpeedToConnectedPlayers(server); + return isGamePaused; } - public BiConsumer addTickrateListener(String modId, BiConsumer tickrateListener) + public float mspt() { + return mspt; + } + + public boolean runsNormally() { - synchronized (tickrateListeners) + return runGameElements; + } + + public boolean isSuperHot() + { + return isSuperHot; + } + + public void setPlayerActiveTimeout(int timeout) + { + playerActivityTimeout = timeout; + } + + public int getPlayerActiveTimeout() + { + return playerActivityTimeout; + } + + public void setFrozenState(boolean isPaused, boolean isDeepFreeze) + { + isGamePaused = isPaused; + deepFreeze = isPaused && isDeepFreeze; + } + + public void setSuperHot(boolean isSuperHot) + { + this.isSuperHot = isSuperHot; + } + + public void tick() + { + if (playerActivityTimeout > 0) { - tickrateListeners.put(modId, tickrateListener); + playerActivityTimeout--; + } + if (isGamePaused) + { + runGameElements = playerActivityTimeout >= PLAYER_GRACE; + } + else if (isSuperHot) + { + runGameElements = playerActivityTimeout > 0; + } + else + { + runGameElements = true; } - return this::tickrateChanged; } } diff --git a/src/main/java/carpet/helpers/TickSpeed.java b/src/main/java/carpet/helpers/TickSpeed.java index a30f437e..e74be60e 100644 --- a/src/main/java/carpet/helpers/TickSpeed.java +++ b/src/main/java/carpet/helpers/TickSpeed.java @@ -10,27 +10,28 @@ import net.minecraft.server.level.ServerPlayer; import carpet.CarpetServer; import carpet.utils.Messenger; +@Deprecated(forRemoval = true, since = "now") public class TickSpeed { - private static Optional gTRM() { + private static Optional gTRM() { if (CarpetServer.minecraft_server == null) return Optional.empty(); return Optional.of(((MinecraftServerInterface)CarpetServer.minecraft_server).getTickRateManager()); } public static boolean process_entities() { - return gTRM().map(trm -> trm.process_entities).orElse(true); + return gTRM().map(ServerTickRateManager::runsNormally).orElse(true); } public static float mspt() { - return gTRM().map(trm -> trm.mspt).orElse(50.0f); + return gTRM().map(ServerTickRateManager::mspt).orElse(50.0f); } public static boolean isPaused() { - return gTRM().map(TickRateManager::isPaused).orElse(false); + return gTRM().map(ServerTickRateManager::gameIsPaused).orElse(false); } public static boolean deeplyFrozen() { - return gTRM().map(TickRateManager::deeplyFrozen).orElse(false); + return gTRM().map(ServerTickRateManager::deeplyFrozen).orElse(false); } public static void setFrozenState(boolean isPaused, boolean isDeepFreeze) { @@ -39,7 +40,7 @@ public class TickSpeed public static void reset_player_active_timeout() { - gTRM().ifPresent(TickRateManager::reset_player_active_timeout); + gTRM().ifPresent(ServerTickRateManager::resetPlayerActivity); } public static void reset() @@ -49,33 +50,33 @@ public class TickSpeed public static void add_ticks_to_run_in_pause(int ticks) { - gTRM().ifPresent(trm -> trm.add_ticks_to_run_in_pause(ticks)); + gTRM().ifPresent(trm -> trm.stepGameIfPaused(ticks)); } public static Component tickrate_advance(ServerPlayer player, int advance, String callback, CommandSourceStack source) { - return gTRM().map(trm -> trm.tickrate_advance(player, advance, callback, source)).orElse(Messenger.c("ri Tickrate management not enabled")); + return gTRM().map(trm -> trm.requestGameToWarpSpeed(player, advance, callback, source)).orElse(Messenger.c("ri Tickrate management not enabled")); } public static void finish_time_warp() { - gTRM().ifPresent(TickRateManager::finish_time_warp); + gTRM().ifPresent(ServerTickRateManager::finishTickWarp); } public static boolean continueWarp() { - return gTRM().map(TickRateManager::continueWarp).orElse(false); + return gTRM().map(ServerTickRateManager::continueWarp).orElse(false); } public static void tick() { - gTRM().ifPresent(TickRateManager::tick); + gTRM().ifPresent(ServerTickRateManager::tick); } //unused - mod compat reasons public static void tickrate(float rate) {tickrate(rate, true);} public static void tickrate(float rate, boolean update) { - gTRM().ifPresent(trm -> trm.tickrate(rate, update)); + gTRM().ifPresent(trm -> trm.setTickRate(rate, update)); } @@ -147,7 +148,7 @@ public class TickSpeed } if (is_paused) { - process_entities = player_active_timeout >= TickRateManager.PLAYER_GRACE; + process_entities = player_active_timeout >= ServerTickRateManager.PLAYER_GRACE; } else if (is_superHot) { diff --git a/src/main/java/carpet/logging/HUDController.java b/src/main/java/carpet/logging/HUDController.java index 6b29a6fa..61678839 100644 --- a/src/main/java/carpet/logging/HUDController.java +++ b/src/main/java/carpet/logging/HUDController.java @@ -3,8 +3,7 @@ package carpet.logging; import carpet.CarpetServer; import carpet.fakes.MinecraftServerInterface; import carpet.helpers.HopperCounter; -import carpet.helpers.TickRateManager; -import carpet.helpers.TickSpeed; +import carpet.helpers.ServerTickRateManager; import carpet.logging.logHelpers.PacketCounter; import carpet.utils.Messenger; import carpet.utils.SpawnReporter; @@ -118,18 +117,18 @@ public class HUDController } private static Component [] send_tps_display(MinecraftServer server) { - final OptionalDouble averageTPS = Arrays.stream(server.tickTimes).average(); - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + OptionalDouble averageTPS = Arrays.stream(server.tickTimes).average(); + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); if (averageTPS.isEmpty()) { return new Component[]{Component.literal("No TPS data available")}; } double MSPT = Arrays.stream(server.tickTimes).average().getAsDouble() * 1.0E-6D; - double TPS = 1000.0D / Math.max((trm.time_warp_start_time != 0)?0.0:trm.mspt, MSPT); - if (trm.isPaused()) { + double TPS = 1000.0D / Math.max(trm.isInWarpSpeed()?0.0:trm.mspt(), MSPT); + if (trm.gameIsPaused()) { TPS = 0; } - String color = Messenger.heatmap_color(MSPT,trm.mspt); + String color = Messenger.heatmap_color(MSPT,trm.mspt()); return new Component[]{Messenger.c( "g TPS: ", String.format(Locale.US, "%s %.1f",color, TPS), "g MSPT: ", String.format(Locale.US,"%s %.1f", color, MSPT))}; diff --git a/src/main/java/carpet/mixins/BoundTickingBlockEntity_tickMixin.java b/src/main/java/carpet/mixins/BoundTickingBlockEntity_tickMixin.java index b36a5c40..370fd25c 100644 --- a/src/main/java/carpet/mixins/BoundTickingBlockEntity_tickMixin.java +++ b/src/main/java/carpet/mixins/BoundTickingBlockEntity_tickMixin.java @@ -1,8 +1,9 @@ package carpet.mixins; +import carpet.fakes.ClientLevelInterface; import carpet.fakes.MinecraftServerInterface; import carpet.helpers.TickRateManager; -import carpet.helpers.TickSpeed; +import carpet.helpers.ServerTickRateManager; import carpet.utils.CarpetProfiler; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; @@ -37,14 +38,16 @@ public class BoundTickingBlockEntity_tickMixin )) private void checkProcessBEs(BlockEntityTicker blockEntityTicker, Level world, BlockPos pos, BlockState state, T blockEntity) { + // these two branches are identical, but we need to check the world type and inferfaces if (world.isClientSide()) { // client - if (TickSpeed.process_entitiesClient()) blockEntityTicker.tick(world, pos, state, blockEntity); + TickRateManager tickRateManager = ((ClientLevelInterface)world).getTickRateManager(); + if (tickRateManager.runsNormally()) blockEntityTicker.tick(world, pos, state, blockEntity); } else { // server ServerLevel serverWorld = (ServerLevel) world; - TickRateManager tickRateManager = ((MinecraftServerInterface)serverWorld.getServer()).getTickRateManager(); - if (tickRateManager.process_entities()) blockEntityTicker.tick(world, pos, state, blockEntity); + ServerTickRateManager serverTickRateManager = ((MinecraftServerInterface)serverWorld.getServer()).getTickRateManager(); + if (serverTickRateManager.runsNormally()) blockEntityTicker.tick(world, pos, state, blockEntity); } } diff --git a/src/main/java/carpet/mixins/ClientLevel_tickSpeedMixin.java b/src/main/java/carpet/mixins/ClientLevel_tickSpeedMixin.java new file mode 100644 index 00000000..50d0de5e --- /dev/null +++ b/src/main/java/carpet/mixins/ClientLevel_tickSpeedMixin.java @@ -0,0 +1,28 @@ +package carpet.mixins; + +import carpet.fakes.ClientLevelInterface; +import carpet.helpers.TickRateManager; +import net.minecraft.client.multiplayer.ClientLevel; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientLevel.class) +public class ClientLevel_tickSpeedMixin implements ClientLevelInterface +{ + + private TickRateManager tickRateManager; + + @Inject(method = "", at = @At("RETURN")) + private void onInit(CallbackInfo ci) + { + this.tickRateManager = new TickRateManager(); + } + + @Override + public TickRateManager getTickRateManager() + { + return tickRateManager; + } +} diff --git a/src/main/java/carpet/mixins/ClientPacketListener_customPacketsMixin.java b/src/main/java/carpet/mixins/ClientPacketListener_customPacketsMixin.java index 64f0735c..ce073645 100644 --- a/src/main/java/carpet/mixins/ClientPacketListener_customPacketsMixin.java +++ b/src/main/java/carpet/mixins/ClientPacketListener_customPacketsMixin.java @@ -1,6 +1,5 @@ package carpet.mixins; -import carpet.helpers.TickSpeed; import carpet.network.CarpetClient; import carpet.network.ClientNetworkHandler; import net.minecraft.client.Minecraft; @@ -34,13 +33,11 @@ public abstract class ClientPacketListener_customPacketsMixin private void onGameJoined(ClientboundLoginPacket packet, CallbackInfo info) { CarpetClient.gameJoined(minecraft.player); - TickSpeed.resetClient(); } @Inject(method = "onDisconnect", at = @At("HEAD")) private void onCMDisconnected(Component reason, CallbackInfo ci) { CarpetClient.disconnect(); - TickSpeed.resetClient(); } } diff --git a/src/main/java/carpet/mixins/LevelRenderer_pausedShakeMixin.java b/src/main/java/carpet/mixins/LevelRenderer_pausedShakeMixin.java index 44b99aaa..941f61ac 100644 --- a/src/main/java/carpet/mixins/LevelRenderer_pausedShakeMixin.java +++ b/src/main/java/carpet/mixins/LevelRenderer_pausedShakeMixin.java @@ -1,8 +1,10 @@ package carpet.mixins; +import carpet.fakes.ClientLevelInterface; import carpet.fakes.MinecraftClientInferface; -import carpet.helpers.TickSpeed; +import carpet.helpers.TickRateManager; import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.LevelRenderer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -15,6 +17,7 @@ public class LevelRenderer_pausedShakeMixin { @Shadow @Final private Minecraft minecraft; + @Shadow private ClientLevel level; float initial = -1234.0f; // require 0 is for optifine being a bitch as it usually is. @@ -25,7 +28,8 @@ public class LevelRenderer_pausedShakeMixin private float changeTickPhase(float previous) { initial = previous; - if (!TickSpeed.process_entitiesClient()) + TickRateManager trm = ((ClientLevelInterface)level).getTickRateManager(); + if (!trm.runsNormally()) return ((MinecraftClientInferface)minecraft).getPausedTickDelta(); return previous; } diff --git a/src/main/java/carpet/mixins/Level_tickMixin.java b/src/main/java/carpet/mixins/Level_tickMixin.java index 898db3d7..d562dbfb 100644 --- a/src/main/java/carpet/mixins/Level_tickMixin.java +++ b/src/main/java/carpet/mixins/Level_tickMixin.java @@ -1,10 +1,12 @@ package carpet.mixins; +import carpet.fakes.ClientLevelInterface; import carpet.fakes.LevelInterface; import carpet.fakes.MinecraftServerInterface; import carpet.helpers.TickRateManager; -import carpet.helpers.TickSpeed; +import carpet.helpers.ServerTickRateManager; import carpet.utils.CarpetProfiler; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.redstone.NeighborUpdater; import org.spongepowered.asm.mixin.Final; @@ -53,55 +55,26 @@ public abstract class Level_tickMixin implements LevelInterface private void endBlockEntities(CallbackInfo ci) { CarpetProfiler.end_current_section(currentSection); } -/* - @Inject(method = "tickBlockEntities", locals = LocalCapture.CAPTURE_FAILHARD, at = @At( - value = "INVOKE", - target = "Lnet/minecraft/class_5562;method_31704()Z", - shift = At.Shift.BEFORE, - ordinal = 0 - )) - private void startTileEntitySection(CallbackInfo ci, Profiler profiler_1, Iterator i, class_5562 lv) - { - entitySection = CarpetProfiler.start_block_entity_section((World)(Object)this, (BlockEntity) lv, CarpetProfiler.TYPE.TILEENTITY); - } - @Redirect(method = "tickBlockEntities", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/class_5562;method_31704()Z", - ordinal = 0 - )) // isRemoved() - private boolean checkProcessTEs(class_5562 class_5562) - { - return class_5562.method_31704() || !TickSpeed.process_entities; // blockEntity can be NULL? happened once with fake player - } - - @Inject(method = "tickBlockEntities", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/class_5562;method_31703()V", - shift = At.Shift.AFTER, - ordinal = 0 - )) - private void endTileEntitySection(CallbackInfo ci) - { - CarpetProfiler.end_current_entity_section(entitySection); - } -*/ @Inject(method = "guardEntityTick", at = @At("HEAD"), cancellable = true) private void startEntity(Consumer consumer_1, Entity e, CallbackInfo ci) { // this shows that probably tick speed controller needs to be accessible through level referring to servers on server and client on clientLevel + // these two branches could also be merged into one generic for cloent and server if (!isClientSide) { ServerLevel serverLevel = (ServerLevel) (Object) this; - TickRateManager trm = ((MinecraftServerInterface)serverLevel.getServer()).getTickRateManager(); - if (!(trm.process_entities() || (e instanceof Player))) + ServerTickRateManager trm = ((MinecraftServerInterface)serverLevel.getServer()).getTickRateManager(); + if (!(trm.runsNormally() || (e instanceof Player))) { ci.cancel(); } } else { - if (!(TickSpeed.process_entitiesClient() || (e instanceof Player) || TickSpeed.isIs_superHotClient() && e.getControllingPassenger() instanceof Player)) + ClientLevel clientLevel = (ClientLevel) (Object) this; + TickRateManager trm = ((ClientLevelInterface)clientLevel).getTickRateManager(); + if (!(trm.runsNormally() || (e instanceof Player) || trm.isSuperHot() && e.getControllingPassenger() instanceof Player)) { ci.cancel(); } diff --git a/src/main/java/carpet/mixins/MinecraftMixin.java b/src/main/java/carpet/mixins/MinecraftMixin.java index 6a871aea..525d0537 100644 --- a/src/main/java/carpet/mixins/MinecraftMixin.java +++ b/src/main/java/carpet/mixins/MinecraftMixin.java @@ -1,7 +1,9 @@ package carpet.mixins; import carpet.CarpetServer; -import carpet.helpers.TickSpeed; +import carpet.fakes.ClientLevelInterface; +import carpet.helpers.TickRateManager; +import carpet.fakes.MinecraftInterface; import carpet.network.CarpetClient; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -12,8 +14,10 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Optional; + @Mixin(Minecraft.class) -public class MinecraftMixin +public class MinecraftMixin implements MinecraftInterface { @Shadow public ClientLevel level; @@ -26,16 +30,19 @@ public class MinecraftMixin @Inject(at = @At("HEAD"), method = "tick") private void onClientTick(CallbackInfo info) { if (this.level != null) { - TickSpeed.tickClient(); - if (CarpetServer.minecraft_server == null) // remote client only ? no - now any client - { - - } else { - // hmm, server should tick, rgiht? - //TickSpeed.tick(); - } - if (!TickSpeed.process_entitiesClient()) + getTickRateManager().ifPresent(TickRateManager::tick); + // hope server doesn't need to tick - should be handled by the server on its own + if (!getTickRateManager().map(TickRateManager::runsNormally).orElse(true)) CarpetClient.shapes.renewShapes(); } } + + @Override + public Optional getTickRateManager() + { + if (this.level != null) { + return Optional.of(((ClientLevelInterface)this.level).getTickRateManager()); + } + return Optional.empty(); + } } diff --git a/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java b/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java index b2604164..1dcbfffd 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java @@ -88,7 +88,7 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve )) public void tickTasks(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - if (!getTickRateManager().process_entities()) + if (!getTickRateManager().runsNormally()) { return; } diff --git a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java index 7962bb0f..6daa46bb 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java @@ -1,8 +1,7 @@ package carpet.mixins; import carpet.fakes.MinecraftServerInterface; -import carpet.helpers.TickRateManager; -import carpet.helpers.TickSpeed; +import carpet.helpers.ServerTickRateManager; import carpet.patches.CopyProfilerResult; import carpet.utils.CarpetProfiler; import net.minecraft.Util; @@ -69,18 +68,18 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantBlockableE private float carpetMsptAccum = 0.0f; - private TickRateManager tickRateManager; + private ServerTickRateManager serverTickRateManager; @Inject(method = "", at = @At("RETURN")) private void onInit(CallbackInfo ci) { - tickRateManager = new TickRateManager((MinecraftServer)(Object)this); + serverTickRateManager = new ServerTickRateManager((MinecraftServer)(Object)this); } @Override - public TickRateManager getTickRateManager() + public ServerTickRateManager getTickRateManager() { - return tickRateManager; + return serverTickRateManager; } /** @@ -111,8 +110,8 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantBlockableE } long msThisTick = 0L; long long_1 = 0L; - float mspt = tickRateManager.mspt; - if (tickRateManager.time_warp_start_time != 0 && tickRateManager.continueWarp()) + float mspt = serverTickRateManager.mspt(); + if (serverTickRateManager.isInWarpSpeed() && serverTickRateManager.continueWarp()) { //making sure server won't flop after the warp or if the warp is interrupted this.nextTickTime = this.lastOverloadWarning = Util.getMillis(); @@ -151,9 +150,9 @@ public abstract class MinecraftServer_tickspeedMixin extends ReentrantBlockableE //this.startMonitor(tickDurationMonitor); this.startMetricsRecordingTick(); this.profiler.push("tick"); - this.tickServer(tickRateManager.time_warp_start_time != 0 ? ()->true : this::haveTime); + this.tickServer(serverTickRateManager.isInWarpSpeed() ? ()->true : this::haveTime); this.profiler.popPush("nextTickWait"); - if (tickRateManager.time_warp_start_time != 0) // clearing all hanging tasks no matter what when warping + if (serverTickRateManager.isInWarpSpeed()) // clearing all hanging tasks no matter what when warping { while(this.runEveryTask()) {Thread.yield();} } diff --git a/src/main/java/carpet/mixins/ServerChunkCache_tickMixin.java b/src/main/java/carpet/mixins/ServerChunkCache_tickMixin.java index 51b7c413..34d69c3e 100644 --- a/src/main/java/carpet/mixins/ServerChunkCache_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerChunkCache_tickMixin.java @@ -2,7 +2,7 @@ package carpet.mixins; import carpet.fakes.MinecraftServerInterface; import carpet.fakes.ThreadedAnvilChunkStorageInterface; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import carpet.utils.CarpetProfiler; import net.minecraft.server.level.DistanceManager; import org.spongepowered.asm.mixin.Final; @@ -80,7 +80,7 @@ public abstract class ServerChunkCache_tickMixin private boolean skipChunkTicking(ServerLevel serverWorld) { boolean debug = serverWorld.isDebug(); - if (!((MinecraftServerInterface)serverWorld.getServer()).getTickRateManager().process_entities()) + if (!((MinecraftServerInterface)serverWorld.getServer()).getTickRateManager().runsNormally()) { // simplified chunk tick iteration assuming world is frozen otherwise as suggested by Hadron67 // to be kept in sync with the original injection source @@ -107,8 +107,8 @@ public abstract class ServerChunkCache_tickMixin { // pausing expiry of tickets // that will prevent also chunks from unloading, so require a deep frozen state - TickRateManager trm = ((MinecraftServerInterface) level.getServer()).getTickRateManager(); - if (!trm.process_entities() && trm.deeplyFrozen()) return; + ServerTickRateManager trm = ((MinecraftServerInterface) level.getServer()).getTickRateManager(); + if (!trm.runsNormally() && trm.deeplyFrozen()) return; distanceManager.purgeStaleTickets(); } diff --git a/src/main/java/carpet/mixins/ServerFunctionManager_tickMixin.java b/src/main/java/carpet/mixins/ServerFunctionManager_tickMixin.java index f428c41d..47152543 100644 --- a/src/main/java/carpet/mixins/ServerFunctionManager_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerFunctionManager_tickMixin.java @@ -20,7 +20,7 @@ public class ServerFunctionManager_tickMixin @Inject(method = "tick", at = @At("HEAD"), cancellable = true) private void beforeDatapacks(CallbackInfo ci) { - if (! ((MinecraftServerInterface)server).getTickRateManager().process_entities()) + if (! ((MinecraftServerInterface)server).getTickRateManager().runsNormally()) { ci.cancel(); } diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_tickMixin.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_tickMixin.java index de670f12..7c8e1315 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_tickMixin.java @@ -27,7 +27,7 @@ public class ServerGamePacketListenerImpl_tickMixin { if (p.getXxa() != 0.0F || p.getZza() != 0.0F || p.isJumping() || p.isShiftKeyDown()) { - ((MinecraftServerInterface)player.getServer()).getTickRateManager().reset_player_active_timeout(); + ((MinecraftServerInterface)player.getServer()).getTickRateManager().resetPlayerActivity(); } } @@ -53,7 +53,7 @@ public class ServerGamePacketListenerImpl_tickMixin { lastMoved = movedBy; lastMovedTick = player.getServer().getTickCount(); - ((MinecraftServerInterface)player.getServer()).getTickRateManager().reset_player_active_timeout(); + ((MinecraftServerInterface)player.getServer()).getTickRateManager().resetPlayerActivity(); } } } diff --git a/src/main/java/carpet/mixins/ServerLevel_tickMixin.java b/src/main/java/carpet/mixins/ServerLevel_tickMixin.java index 3784958f..f68add38 100644 --- a/src/main/java/carpet/mixins/ServerLevel_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerLevel_tickMixin.java @@ -159,13 +159,13 @@ public abstract class ServerLevel_tickMixin extends Level )) private void tickWorldBorder(WorldBorder worldBorder) { - if (((MinecraftServerInterface)getServer()).getTickRateManager().process_entities()) worldBorder.tick(); + if (((MinecraftServerInterface)getServer()).getTickRateManager().runsNormally()) worldBorder.tick(); } @Inject(method = "advanceWeatherCycle", cancellable = true, at = @At("HEAD")) private void tickWeather(CallbackInfo ci) { - if (!((MinecraftServerInterface)getServer()).getTickRateManager().process_entities()) ci.cancel(); + if (!((MinecraftServerInterface)getServer()).getTickRateManager().runsNormally()) ci.cancel(); } @Redirect(method = "tick", at = @At( @@ -174,7 +174,7 @@ public abstract class ServerLevel_tickMixin extends Level )) private void tickTimeConditionally(ServerLevel serverWorld) { - if (((MinecraftServerInterface)getServer()).getTickRateManager().process_entities()) tickTime(); + if (((MinecraftServerInterface)getServer()).getTickRateManager().runsNormally()) tickTime(); } @Redirect(method = "tick", at = @At( @@ -183,7 +183,7 @@ public abstract class ServerLevel_tickMixin extends Level )) private boolean tickPendingBlocks(ServerLevel serverWorld) { - if (!((MinecraftServerInterface)getServer()).getTickRateManager().process_entities()) return true; + if (!((MinecraftServerInterface)getServer()).getTickRateManager().runsNormally()) return true; return serverWorld.isDebug(); // isDebug() } @@ -193,7 +193,7 @@ public abstract class ServerLevel_tickMixin extends Level )) private void tickConditionally(Raids raidManager) { - if (((MinecraftServerInterface)getServer()).getTickRateManager().process_entities()) raidManager.tick(); + if (((MinecraftServerInterface)getServer()).getTickRateManager().runsNormally()) raidManager.tick(); } @Redirect(method = "tick", at = @At( @@ -202,6 +202,6 @@ public abstract class ServerLevel_tickMixin extends Level )) private void tickConditionally(ServerLevel serverWorld) { - if (((MinecraftServerInterface)getServer()).getTickRateManager().process_entities()) runBlockEvents(); + if (((MinecraftServerInterface)getServer()).getTickRateManager().runsNormally()) runBlockEvents(); } } diff --git a/src/main/java/carpet/mixins/Timer_tickSpeedMixin.java b/src/main/java/carpet/mixins/Timer_tickSpeedMixin.java index c8e4f1fe..fdf61ef1 100644 --- a/src/main/java/carpet/mixins/Timer_tickSpeedMixin.java +++ b/src/main/java/carpet/mixins/Timer_tickSpeedMixin.java @@ -1,12 +1,16 @@ package carpet.mixins; -import carpet.helpers.TickSpeed; +import carpet.fakes.MinecraftInterface; +import carpet.helpers.TickRateManager; +import net.minecraft.client.Minecraft; import net.minecraft.client.Timer; import carpet.CarpetSettings; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import java.util.Optional; + @Mixin(Timer.class) public class Timer_tickSpeedMixin { @Redirect(method = "advanceTime", at = @At( @@ -14,9 +18,13 @@ public class Timer_tickSpeedMixin { target = "Lnet/minecraft/client/Timer;msPerTick:F" )) private float adjustTickSpeed(Timer counter) { - if (CarpetSettings.smoothClientAnimations && TickSpeed.process_entitiesClient()) + if (CarpetSettings.smoothClientAnimations) { - return Math.max(50.0f, TickSpeed.msptClient()); + Optional trm = ((MinecraftInterface)Minecraft.getInstance()).getTickRateManager(); + if (trm.isPresent() && trm.get().runsNormally()) + { + return Math.max(50.0f, trm.get().mspt()); + } } return 50f; } diff --git a/src/main/java/carpet/network/ClientNetworkHandler.java b/src/main/java/carpet/network/ClientNetworkHandler.java index 29277402..ab7950f5 100644 --- a/src/main/java/carpet/network/ClientNetworkHandler.java +++ b/src/main/java/carpet/network/ClientNetworkHandler.java @@ -5,7 +5,8 @@ import carpet.CarpetExtension; import carpet.CarpetSettings; import carpet.api.settings.CarpetRule; import carpet.api.settings.InvalidRuleValueException; -import carpet.helpers.TickSpeed; +import carpet.fakes.ClientLevelInterface; +import carpet.helpers.TickRateManager; import carpet.api.settings.SettingsManager; import io.netty.buffer.Unpooled; import java.util.HashMap; @@ -65,15 +66,23 @@ public class ClientNetworkHandler } } }); - dataHandlers.put("TickRate", (p, t) -> TickSpeed.tickrateClient(((NumericTag)t).getAsFloat())); + dataHandlers.put("TickRate", (p, t) -> { + TickRateManager tickRateManager = ((ClientLevelInterface)p.clientLevel).getTickRateManager(); + tickRateManager.setTickRate(((NumericTag) t).getAsFloat()); + }); dataHandlers.put("TickingState", (p, t) -> { CompoundTag tickingState = (CompoundTag)t; - TickSpeed.setFrozenStateClient(tickingState.getBoolean("is_paused"), tickingState.getBoolean("deepFreeze")); + TickRateManager tickRateManager = ((ClientLevelInterface)p.clientLevel).getTickRateManager(); + tickRateManager.setFrozenState(tickingState.getBoolean("is_paused"), tickingState.getBoolean("deepFreeze")); }); dataHandlers.put("SuperHotState", (p, t) -> { - TickSpeed.setSuperHotClient(((ByteTag) t).equals(ByteTag.ONE)); + TickRateManager tickRateManager = ((ClientLevelInterface)p.clientLevel).getTickRateManager(); + tickRateManager.setSuperHot(((ByteTag) t).equals(ByteTag.ONE)); + }); + dataHandlers.put("TickPlayerActiveTimeout", (p, t) -> { + TickRateManager tickRateManager = ((ClientLevelInterface)p.clientLevel).getTickRateManager(); + tickRateManager.setPlayerActiveTimeout(((NumericTag) t).getAsInt()); }); - dataHandlers.put("TickPlayerActiveTimeout", (p, t) -> TickSpeed.setPlayer_active_timeoutClient(((NumericTag)t).getAsInt())); dataHandlers.put("scShape", (p, t) -> { // deprecated // and unused // should remove for 1.17 if (CarpetClient.shapes != null) CarpetClient.shapes.addShape((CompoundTag)t); diff --git a/src/main/java/carpet/network/ServerNetworkHandler.java b/src/main/java/carpet/network/ServerNetworkHandler.java index 4d588286..3a0a0ee8 100644 --- a/src/main/java/carpet/network/ServerNetworkHandler.java +++ b/src/main/java/carpet/network/ServerNetworkHandler.java @@ -6,7 +6,7 @@ import carpet.api.settings.CarpetRule; import carpet.api.settings.RuleHelper; import carpet.fakes.MinecraftServerInterface; import carpet.fakes.ServerGamePacketListenerImplInterface; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import carpet.script.utils.SnoopyCommandSource; import carpet.api.settings.SettingsManager; import io.netty.buffer.Unpooled; @@ -260,29 +260,29 @@ public class ServerNetworkHandler } private DataBuilder withTickRate() { - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); - tag.putFloat("TickRate", trm.tickrate); + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + tag.putFloat("TickRate", trm.tickrate()); return this; } private DataBuilder withFrozenState() { - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); CompoundTag tickingState = new CompoundTag(); - tickingState.putBoolean("is_paused", trm.isPaused()); + tickingState.putBoolean("is_paused", trm.gameIsPaused()); tickingState.putBoolean("deepFreeze", trm.deeplyFrozen()); tag.put("TickingState", tickingState); return this; } private DataBuilder withSuperHotState() { - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); - tag.putBoolean("SuperHotState", trm.is_superHot); + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + tag.putBoolean("SuperHotState", trm.isSuperHot()); return this; } private DataBuilder withTickPlayerActiveTimeout() { - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); - tag.putInt("TickPlayerActiveTimeout", trm.player_active_timeout); + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + tag.putInt("TickPlayerActiveTimeout", trm.getPlayerActiveTimeout()); return this; } private DataBuilder withRule(CarpetRule rule) diff --git a/src/main/java/carpet/patches/TickSyncedBorderExtent.java b/src/main/java/carpet/patches/TickSyncedBorderExtent.java index a1aa4280..a9e8917a 100644 --- a/src/main/java/carpet/patches/TickSyncedBorderExtent.java +++ b/src/main/java/carpet/patches/TickSyncedBorderExtent.java @@ -2,7 +2,7 @@ package carpet.patches; import carpet.CarpetServer; import carpet.fakes.MinecraftServerInterface; -import carpet.helpers.TickRateManager; +import carpet.helpers.ServerTickRateManager; import net.minecraft.server.MinecraftServer; import net.minecraft.util.Mth; import net.minecraft.world.level.border.BorderChangeListener; @@ -96,10 +96,10 @@ public class TickSyncedBorderExtent implements WorldBorder.BorderExtent else { ms = Arrays.stream(server.tickTimes).average().orElseThrow(IllegalStateException::new) * 1.0E-6D; - TickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); - if (trm.time_warp_start_time == 0) // not in time warp + ServerTickRateManager trm = ((MinecraftServerInterface)server).getTickRateManager(); + if (!trm.isInWarpSpeed()) { - ms = Math.max(ms, trm.mspt); + ms = Math.max(ms, trm.mspt()); } } double tps = 1_000.0D / ms; diff --git a/src/main/java/carpet/script/external/Carpet.java b/src/main/java/carpet/script/external/Carpet.java index 1f621831..21182959 100644 --- a/src/main/java/carpet/script/external/Carpet.java +++ b/src/main/java/carpet/script/external/Carpet.java @@ -7,7 +7,6 @@ import carpet.api.settings.RuleHelper; import carpet.api.settings.SettingsManager; import carpet.api.settings.Validator; import carpet.fakes.MinecraftServerInterface; -import carpet.helpers.TickSpeed; import carpet.logging.HUDController; import carpet.network.ServerNetworkHandler; import carpet.patches.EntityPlayerMPFake; @@ -136,7 +135,7 @@ public class Carpet public static boolean isTickProcessingPaused(MinecraftServer server) { - return !((MinecraftServerInterface)server).getTickRateManager().process_entities(); + return !((MinecraftServerInterface)server).getTickRateManager().runsNormally(); } public static void handleExtensionsAPI(CarpetExpression expression) diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 26a4d5c4..936e8c0a 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -188,6 +188,7 @@ "SlimeBlock_customStickyMixin" ], "client": [ + "ClientLevel_tickSpeedMixin", "ShulkerBoxAccessMixin", "Timer_tickSpeedMixin", "MinecraftMixin",