From fc3f319153a23bd251d7353ca90aff026f637979 Mon Sep 17 00:00:00 2001 From: LostLuma Date: Thu, 22 Feb 2024 18:58:24 +0100 Subject: [PATCH] Add workaround for softlock in combination with Fastload --- .../java/dynamic_fps/impl/DynamicFPSMod.java | 7 +++- .../dynamic_fps/impl/service/ModCompat.java | 14 ++++++- .../dynamic_fps/impl/service/Platform.java | 4 +- .../impl/util/ModCompatHelper.java | 42 +++++++++++++++++++ .../impl/fabric/service/FabricModCompat.java | 8 ++-- .../impl/fabric/service/FabricPlatform.java | 17 +++----- .../fabric/src/main/resources/fabric.mod.json | 3 -- .../impl/forge/service/ForgeModCompat.java | 17 ++++++-- .../impl/forge/service/ForgePlatform.java | 18 +++----- .../neoforge/service/NeoForgeModCompat.java | 17 ++++++-- .../neoforge/service/NeoForgePlatform.java | 21 +++------- .../impl/quilt/service/QuiltModCompat.java | 8 ++-- .../impl/quilt/service/QuiltPlatform.java | 17 +++----- .../quilt/src/main/resources/quilt.mod.json | 7 ---- 14 files changed, 121 insertions(+), 79 deletions(-) create mode 100644 platforms/common/src/main/java/dynamic_fps/impl/util/ModCompatHelper.java diff --git a/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java b/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java index be22883f..7b40c572 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java @@ -5,6 +5,7 @@ import dynamic_fps.impl.config.DynamicFPSConfig; import dynamic_fps.impl.service.ModCompat; import dynamic_fps.impl.util.Logging; +import dynamic_fps.impl.util.ModCompatHelper; import dynamic_fps.impl.util.OptionsHolder; import dynamic_fps.impl.util.duck.DuckScreen; import dynamic_fps.impl.util.duck.DuckLoadingOverlay; @@ -52,8 +53,12 @@ public class DynamicFPSMod { // Internal "API" for Dynamic FPS itself public static void init() { + ModCompatHelper.init(); + Platform platform = Platform.getInstance(); - Logging.getLogger().info("Dynamic FPS {} active on {}!", platform.modVersion(), platform.getName()); + String version = platform.getModVersion(Constants.MOD_ID).orElseThrow(); + + Logging.getLogger().info("Dynamic FPS {} active on {}!", version, platform.getName()); } public static boolean disabledByUser() { diff --git a/platforms/common/src/main/java/dynamic_fps/impl/service/ModCompat.java b/platforms/common/src/main/java/dynamic_fps/impl/service/ModCompat.java index 97f3c54c..fff5494d 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/service/ModCompat.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/service/ModCompat.java @@ -1,11 +1,21 @@ package dynamic_fps.impl.service; +import java.util.Set; + public interface ModCompat { boolean isDisabled(); boolean disableOverlayOptimization(); - boolean isScreenOptedIn(String className); - boolean isScreenOptedOut(String className); + Set getOptedInScreens(); + Set getOptedOutScreens(); + + default boolean isScreenOptedIn(String className) { + return getOptedInScreens().contains(className); + } + + default boolean isScreenOptedOut(String className) { + return getOptedOutScreens().contains(className); + } static ModCompat getInstance() { return Services.MOD_COMPAT; diff --git a/platforms/common/src/main/java/dynamic_fps/impl/service/Platform.java b/platforms/common/src/main/java/dynamic_fps/impl/service/Platform.java index 36ab0eb4..ea011559 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/service/Platform.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/service/Platform.java @@ -1,15 +1,17 @@ package dynamic_fps.impl.service; import java.nio.file.Path; +import java.util.Optional; public interface Platform { String getName(); - String modVersion(); Path getCacheDir(); Path getConfigDir(); boolean isDevelopmentEnvironment(); + Optional getModVersion(String modId); + void registerStartTickEvent(StartTickEvent event); @FunctionalInterface diff --git a/platforms/common/src/main/java/dynamic_fps/impl/util/ModCompatHelper.java b/platforms/common/src/main/java/dynamic_fps/impl/util/ModCompatHelper.java new file mode 100644 index 00000000..17645045 --- /dev/null +++ b/platforms/common/src/main/java/dynamic_fps/impl/util/ModCompatHelper.java @@ -0,0 +1,42 @@ +package dynamic_fps.impl.util; + +import dynamic_fps.impl.service.ModCompat; +import dynamic_fps.impl.service.Platform; + +import java.util.Arrays; +import java.util.Optional; + +public class ModCompatHelper { + public static void init() { + fixFastloadSoftLock(); + } + + /** + * Fix softlock in combination with Fastload <=3.4.0 due to our screen / loading overlay optimization. + * + * See the issue report for more info. + */ + private static void fixFastloadSoftLock() { + Optional optional = Platform.getInstance().getModVersion("fastload"); + + if (optional.isEmpty()) { + return; + } + + String[] parts = optional.get().split("\\."); + int[] version = Arrays.stream(parts).mapToInt(Integer::parseInt).toArray(); + + if (version.length < 3) { + Logging.getLogger().warn("Unable to parse Fastload version: {}!", optional.get()); + return; + } + + // If a version below 3.4.0 is present opt their custom world loading screen out of our optimization + if (!(version[0] > 3 || version[0] == 3 && (version[1] > 4 || version[1] == 4 && version[2] > 0))) { + ModCompat.getInstance().getOptedOutScreens().add( + "io.github.bumblesoftware.fastload.client.BuildingTerrainScreen" + ); + + } + } +} diff --git a/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricModCompat.java b/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricModCompat.java index 81f5d6b5..d00cd7a6 100644 --- a/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricModCompat.java +++ b/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricModCompat.java @@ -33,13 +33,13 @@ public boolean disableOverlayOptimization() { } @Override - public boolean isScreenOptedIn(String className) { - return optedInScreens.contains(className); + public Set getOptedInScreens() { + return optedInScreens; } @Override - public boolean isScreenOptedOut(String className) { - return optedOutScreens.contains(className); + public Set getOptedOutScreens() { + return optedOutScreens; } private static void parseModMetadata(ModContainer mod) { diff --git a/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricPlatform.java b/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricPlatform.java index 3cd0cfc3..779b445b 100644 --- a/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricPlatform.java +++ b/platforms/fabric/src/main/java/net/lostluma/dynamic_fps/impl/fabric/service/FabricPlatform.java @@ -17,17 +17,6 @@ public String getName() { return "Fabric"; } - @Override - public String modVersion() { - Optional optional = FabricLoader.getInstance().getModContainer(Constants.MOD_ID); - - if (optional.isPresent()) { - return optional.get().getMetadata().getVersion().getFriendlyString(); - } else { - throw new RuntimeException("Own mod container is somehow not available!"); - } - } - @Override public Path getCacheDir() { Path base = FabricLoader.getInstance().getGameDir(); @@ -44,6 +33,12 @@ public boolean isDevelopmentEnvironment() { return FabricLoader.getInstance().isDevelopmentEnvironment(); } + @Override + public Optional getModVersion(String modId) { + Optional optional = FabricLoader.getInstance().getModContainer(modId); + return optional.map(modContainer -> modContainer.getMetadata().getVersion().toString()); + } + @Override public void registerStartTickEvent(StartTickEvent event) { ClientTickEvents.START_CLIENT_TICK.register((minecraft) -> event.onStartTick()); diff --git a/platforms/fabric/src/main/resources/fabric.mod.json b/platforms/fabric/src/main/resources/fabric.mod.json index ee6e2c0a..b763e437 100644 --- a/platforms/fabric/src/main/resources/fabric.mod.json +++ b/platforms/fabric/src/main/resources/fabric.mod.json @@ -41,9 +41,6 @@ "cloth-config": "*", "quilt_loader": "*" }, - "breaks": { - "fastload": "<=3.4.0" - }, "mixins": [ "dynamic_fps.mixins.json", "dynamic_fps-common.mixins.json" diff --git a/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgeModCompat.java b/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgeModCompat.java index f3722f7b..8f6f2548 100644 --- a/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgeModCompat.java +++ b/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgeModCompat.java @@ -4,7 +4,16 @@ import net.minecraft.client.gui.screens.ReceivingLevelScreen; import net.minecraftforge.fml.ModList; +import java.util.HashSet; +import java.util.Set; + public class ForgeModCompat implements ModCompat { + private static final Set optedOutScreens = new HashSet<>(); + + static { + optedOutScreens.add(ReceivingLevelScreen.class.getCanonicalName()); + } + @Override public boolean isDisabled() { return false; @@ -16,12 +25,12 @@ public boolean disableOverlayOptimization() { } @Override - public boolean isScreenOptedIn(String className) { - return false; + public Set getOptedInScreens() { + return Set.of(); } @Override - public boolean isScreenOptedOut(String className) { - return ReceivingLevelScreen.class.getCanonicalName().equals(className); + public Set getOptedOutScreens() { + return optedOutScreens; } } diff --git a/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgePlatform.java b/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgePlatform.java index 70f73858..e195ea62 100644 --- a/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgePlatform.java +++ b/platforms/forge/src/main/java/net/lostluma/dynamic_fps/impl/forge/service/ForgePlatform.java @@ -14,23 +14,11 @@ import java.util.Optional; public class ForgePlatform implements Platform { - @Override public String getName() { return "Forge"; } - @Override - public String modVersion() { - Optional optional = ModList.get().getModContainerById(Constants.MOD_ID); - - if (optional.isPresent()) { - return optional.get().getModInfo().getVersion().toString(); - } else { - throw new RuntimeException("Own mod container is somehow not available!"); - } - } - @Override public Path getCacheDir() { Path base = FMLPaths.GAMEDIR.get(); @@ -47,6 +35,12 @@ public boolean isDevelopmentEnvironment() { return !FMLLoader.isProduction(); } + @Override + public Optional getModVersion(String modId) { + Optional optional = ModList.get().getModContainerById(modId); + return optional.map(modContainer -> modContainer.getModInfo().getVersion().toString()); + } + @Override public void registerStartTickEvent(StartTickEvent event) { DynamicFPSForgeMod.addTickEventListener(event); diff --git a/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgeModCompat.java b/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgeModCompat.java index 7302daee..a0c48fd7 100644 --- a/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgeModCompat.java +++ b/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgeModCompat.java @@ -4,7 +4,16 @@ import net.minecraft.client.gui.screens.ReceivingLevelScreen; import net.neoforged.fml.ModList; +import java.util.HashSet; +import java.util.Set; + public class NeoForgeModCompat implements ModCompat { + private static final Set optedOutScreens = new HashSet<>(); + + static { + optedOutScreens.add(ReceivingLevelScreen.class.getCanonicalName()); + } + @Override public boolean isDisabled() { return false; @@ -16,12 +25,12 @@ public boolean disableOverlayOptimization() { } @Override - public boolean isScreenOptedIn(String className) { - return false; + public Set getOptedInScreens() { + return Set.of(); } @Override - public boolean isScreenOptedOut(String className) { - return ReceivingLevelScreen.class.getCanonicalName().equals(className); + public Set getOptedOutScreens() { + return optedOutScreens; } } diff --git a/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgePlatform.java b/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgePlatform.java index 7fa07c97..d7681582 100644 --- a/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgePlatform.java +++ b/platforms/neoforge/src/main/java/net/lostluma/dynamic_fps/impl/neoforge/service/NeoForgePlatform.java @@ -2,15 +2,11 @@ import dynamic_fps.impl.Constants; import dynamic_fps.impl.service.Platform; -import net.neoforged.bus.EventBus; -import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.ModContainer; import net.neoforged.fml.ModList; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.fml.loading.FMLPaths; -import net.neoforged.neoforge.client.ClientHooks; import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.common.NeoForgeEventHandler; import net.neoforged.neoforge.event.TickEvent; import java.io.IOException; @@ -24,17 +20,6 @@ public String getName() { return "NeoForge"; } - @Override - public String modVersion() { - Optional optional = ModList.get().getModContainerById(Constants.MOD_ID); - - if (optional.isPresent()) { - return optional.get().getModInfo().getVersion().toString(); - } else { - throw new RuntimeException("Own mod container is somehow not available!"); - } - } - @Override public Path getCacheDir() { Path base = FMLPaths.GAMEDIR.get(); @@ -51,6 +36,12 @@ public boolean isDevelopmentEnvironment() { return !FMLLoader.isProduction(); } + @Override + public Optional getModVersion(String modId) { + Optional optional = ModList.get().getModContainerById(modId); + return optional.map(modContainer -> modContainer.getModInfo().getVersion().toString()); + } + @Override public void registerStartTickEvent(StartTickEvent event) { NeoForge.EVENT_BUS.addListener(TickEvent.ClientTickEvent.class, (unused) -> event.onStartTick()); diff --git a/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltModCompat.java b/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltModCompat.java index d32deb60..efc0142b 100644 --- a/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltModCompat.java +++ b/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltModCompat.java @@ -33,13 +33,13 @@ public boolean disableOverlayOptimization() { } @Override - public boolean isScreenOptedIn(String className) { - return optedInScreens.contains(className); + public Set getOptedInScreens() { + return optedInScreens; } @Override - public boolean isScreenOptedOut(String className) { - return optedOutScreens.contains(className); + public Set getOptedOutScreens() { + return optedOutScreens; } private static void parseModMetadata(ModContainer mod) { diff --git a/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltPlatform.java b/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltPlatform.java index 71cb5a1a..f497be75 100644 --- a/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltPlatform.java +++ b/platforms/quilt/src/main/java/net/lostluma/dynamic_fps/impl/quilt/service/QuiltPlatform.java @@ -17,17 +17,6 @@ public String getName() { return "Quilt"; } - @Override - public String modVersion() { - Optional optional = QuiltLoader.getModContainer(Constants.MOD_ID); - - if (optional.isPresent()) { - return optional.get().metadata().version().toString(); - } else { - throw new RuntimeException("Own mod container is somehow not available!"); - } - } - @Override public Path getCacheDir() { return this.ensureDir(QuiltLoader.getCacheDir().resolve(Constants.MOD_ID)); @@ -43,6 +32,12 @@ public boolean isDevelopmentEnvironment() { return QuiltLoader.isDevelopmentEnvironment(); } + @Override + public Optional getModVersion(String modId) { + Optional optional = QuiltLoader.getModContainer(modId); + return optional.map(modContainer -> modContainer.metadata().version().toString()); + } + @Override public void registerStartTickEvent(StartTickEvent event) { ClientTickEvents.START.register((minecraft) -> event.onStartTick()); diff --git a/platforms/quilt/src/main/resources/quilt.mod.json b/platforms/quilt/src/main/resources/quilt.mod.json index e9f6eb80..5bd31f32 100644 --- a/platforms/quilt/src/main/resources/quilt.mod.json +++ b/platforms/quilt/src/main/resources/quilt.mod.json @@ -64,13 +64,6 @@ "versions": "*", "optional": true } - ], - "breaks": [ - { - "id": "fastload", - "versions": "<=3.4.0", - "reason": "Softlock in world loading screen, see https://github.com/BumbleSoftware/Fastload/issues/108" - } ] }, "minecraft": {