From c258bba5ec8b301c347c3b384ff298deefbf2beb Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 22 Feb 2023 11:44:56 -0500 Subject: [PATCH] Minor code cleanup --- .../embeddedt/modernfix/ModernFixClient.java | 103 ++-------------- .../embeddedt/modernfix/load/LoadEvents.java | 113 ++++++++++++++++++ .../MinecraftServerMixin.java | 3 +- 3 files changed, 123 insertions(+), 96 deletions(-) create mode 100644 src/main/java/org/embeddedt/modernfix/load/LoadEvents.java diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 4d1a3ce4..1ce231d7 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -1,43 +1,31 @@ package org.embeddedt.modernfix; -import it.unimi.dsi.fastutil.longs.LongIterator; -import net.minecraft.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.ConnectScreen; -import net.minecraft.client.gui.screens.LevelLoadingScreen; -import net.minecraft.client.gui.screens.ProgressScreen; import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.client.server.IntegratedServer; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.*; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.ForcedChunksSavedData; import net.minecraftforge.client.event.GuiOpenEvent; -import net.minecraftforge.common.world.ForgeChunkManager; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent; -import net.minecraftforge.fml.server.ServerLifecycleHooks; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; -import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig; +import org.embeddedt.modernfix.load.LoadEvents; import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen; import java.lang.management.ManagementFactory; -import java.util.concurrent.locks.LockSupport; -import java.util.function.BooleanSupplier; public class ModernFixClient { - public static long worldLoadStartTime; private static int numRenderTicks; public static float gameStartTimeSeconds = -1; + public ModernFixClient() { + if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { + MinecraftForge.EVENT_BUS.register(new LoadEvents()); + } + } + public void resetWorldLoadStateMachine() { numRenderTicks = 0; worldLoadStartTime = -1; @@ -62,79 +50,4 @@ public class ModernFixClient { resetWorldLoadStateMachine(); } } - - private boolean hasFirstPlayerJoined = false; - - @SubscribeEvent - public void serverWillStart(FMLServerAboutToStartEvent event) { - hasFirstPlayerJoined = false; - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) { - if(!hasFirstPlayerJoined && ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { - hasFirstPlayerJoined = true; - MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); - if(server instanceof IntegratedServer) { - handleInitialChunkLoad(); - } - } - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onWorldShow(GuiOpenEvent event) { - if(ServerLifecycleHooks.getCurrentServer() instanceof IntegratedServer && ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { - if(event.getGui() == null && Minecraft.getInstance().level != null) { - /* this means the world is being displayed, check if 441 initialized */ - ServerChunkCache provider = ServerLifecycleHooks.getCurrentServer().overworld().getChunkSource(); - BooleanSupplier worldLoadDone = () -> provider.getTickingGenerated() >= 441; - if(!worldLoadDone.getAsBoolean()) { - DeferredLevelLoadingScreen newScreen = new DeferredLevelLoadingScreen(Minecraft.getInstance().progressListener.get(), worldLoadDone); - event.setGui(newScreen); - } - } else if(event.getGui() instanceof LevelLoadingScreen && Minecraft.getInstance().level == null) { - ProgressScreen loadscreen = new ProgressScreen(); - loadscreen.progressStartNoAbort(new TranslatableComponent("connect.joining")); - event.setGui(loadscreen); - } - } - } - - public static ChunkProgressListener integratedWorldLoadListener; - - private void handleInitialChunkLoad() { - MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); - ServerLevel overworld = server.overworld(); - ServerChunkCache provider = overworld.getChunkSource(); - provider.getLightEngine().setTaskPerBatch(500); - provider.addRegionTicket(TicketType.START, new ChunkPos(overworld.getSharedSpawnPos()), 11, Unit.INSTANCE); - while(provider.getTickingGenerated() < 441) { - server.runAllTasks(); - Thread.yield(); - LockSupport.parkNanos("waiting for world load", 100000L); - server.nextTickTime = Util.getMillis() + 10; - } - for(ServerLevel serverworld1 : server.getAllLevels()) { - ForcedChunksSavedData forcedchunkssavedata = serverworld1.getDataStorage().get(ForcedChunksSavedData::new, "chunks"); - if (forcedchunkssavedata != null) { - LongIterator longiterator = forcedchunkssavedata.getChunks().iterator(); - - while(longiterator.hasNext()) { - long i = longiterator.nextLong(); - ChunkPos chunkpos = new ChunkPos(i); - serverworld1.getChunkSource().updateChunkForced(chunkpos, true); - } - - ForgeChunkManager.reinstatePersistentChunks(serverworld1, forcedchunkssavedata); - } - } - server.runAllTasks(); - server.nextTickTime = Util.getMillis() + 10; - provider.getLightEngine().setTaskPerBatch(5); - if(integratedWorldLoadListener != null) { - integratedWorldLoadListener.stop(); - integratedWorldLoadListener = null; - } - } - } diff --git a/src/main/java/org/embeddedt/modernfix/load/LoadEvents.java b/src/main/java/org/embeddedt/modernfix/load/LoadEvents.java new file mode 100644 index 00000000..a7f6e158 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/load/LoadEvents.java @@ -0,0 +1,113 @@ +package org.embeddedt.modernfix.load; + +import it.unimi.dsi.fastutil.longs.LongIterator; +import net.minecraft.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.LevelLoadingScreen; +import net.minecraft.client.gui.screens.ProgressScreen; +import net.minecraft.client.server.IntegratedServer; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.TicketType; +import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.Unit; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.ForcedChunksSavedData; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.common.world.ForgeChunkManager; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent; +import net.minecraftforge.fml.server.ServerLifecycleHooks; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; +import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen; + +import java.util.concurrent.locks.LockSupport; +import java.util.function.BooleanSupplier; + +/** + * Handles deferring the world load screen. + *
+ * TODO: The vanilla check that at least 441 chunks have been loaded does not check whether they are spawn chunks + * or chunks loaded by the player. Consequently it is possible for loading to finish before every spawn chunk has + * been loaded. However the chunk system has at least been warmed up by this point so the remaining chunks load + * reasonably quickly. + */ +public class LoadEvents { + private boolean hasFirstPlayerJoined = false; + + @SubscribeEvent + public void serverWillStart(FMLServerAboutToStartEvent event) { + hasFirstPlayerJoined = false; + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) { + if(!hasFirstPlayerJoined && ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { + hasFirstPlayerJoined = true; + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + if(server instanceof IntegratedServer) { + handleInitialChunkLoad(); + } + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onWorldShow(GuiOpenEvent event) { + if(ServerLifecycleHooks.getCurrentServer() instanceof IntegratedServer) { + if(event.getGui() == null && Minecraft.getInstance().level != null && integratedWorldLoadListener != null) { + /* this means the world is about to be displayed, check if 441 initialized */ + ServerChunkCache provider = ServerLifecycleHooks.getCurrentServer().overworld().getChunkSource(); + BooleanSupplier worldLoadDone = () -> provider.getTickingGenerated() >= 441; + if(!worldLoadDone.getAsBoolean()) { + DeferredLevelLoadingScreen newScreen = new DeferredLevelLoadingScreen(Minecraft.getInstance().progressListener.get(), worldLoadDone); + event.setGui(newScreen); + } + } else if(event.getGui() instanceof LevelLoadingScreen && Minecraft.getInstance().level == null && ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { + ProgressScreen loadscreen = new ProgressScreen(); + loadscreen.progressStartNoAbort(new TranslatableComponent("connect.joining")); + event.setGui(loadscreen); + } + } + } + + public static ChunkProgressListener integratedWorldLoadListener; + + private void handleInitialChunkLoad() { + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + ServerLevel overworld = server.overworld(); + ServerChunkCache provider = overworld.getChunkSource(); + provider.getLightEngine().setTaskPerBatch(500); + provider.addRegionTicket(TicketType.START, new ChunkPos(overworld.getSharedSpawnPos()), 11, Unit.INSTANCE); + while(provider.getTickingGenerated() < 441) { + server.runAllTasks(); + Thread.yield(); + LockSupport.parkNanos("waiting for world load", 100000L); + server.nextTickTime = Util.getMillis() + 10; + } + for(ServerLevel serverworld1 : server.getAllLevels()) { + ForcedChunksSavedData forcedchunkssavedata = serverworld1.getDataStorage().get(ForcedChunksSavedData::new, "chunks"); + if (forcedchunkssavedata != null) { + LongIterator longiterator = forcedchunkssavedata.getChunks().iterator(); + + while(longiterator.hasNext()) { + long i = longiterator.nextLong(); + ChunkPos chunkpos = new ChunkPos(i); + serverworld1.getChunkSource().updateChunkForced(chunkpos, true); + } + + ForgeChunkManager.reinstatePersistentChunks(serverworld1, forcedchunkssavedata); + } + } + server.runAllTasks(); + server.nextTickTime = Util.getMillis() + 10; + provider.getLightEngine().setTaskPerBatch(5); + if(integratedWorldLoadListener != null) { + integratedWorldLoadListener.stop(); + integratedWorldLoadListener = null; + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java index 2596c9ce..ad0b11a0 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java @@ -7,6 +7,7 @@ import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; import org.embeddedt.modernfix.ModernFixClient; +import org.embeddedt.modernfix.load.LoadEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -31,7 +32,7 @@ public abstract class MinecraftServerMixin { private void skipInitialChunkLoad(ChunkProgressListener arg, CallbackInfo ci) { if(((Object)this) instanceof IntegratedServer) { ci.cancel(); - ModernFixClient.integratedWorldLoadListener = arg; + LoadEvents.integratedWorldLoadListener = arg; this.nextTickTime = Util.getMillis(); this.overworld().getChunkSource().getLightEngine().setTaskPerBatch(5); this.updateMobSpawningFlags();