From dcafb4f633443c2fe5ee5aac9f853269588116a4 Mon Sep 17 00:00:00 2001 From: Jonathing Date: Wed, 12 Feb 2025 14:52:53 -0500 Subject: [PATCH] Fix corrupted and invalidly symlinked worlds crashing on level select (#10406) --- .../level/storage/LevelSummary.java.patch | 25 +++++++++++++------ .../common/extensions/IForgeLevelSummary.java | 22 ++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/minecraftforge/common/extensions/IForgeLevelSummary.java diff --git a/patches/minecraft/net/minecraft/world/level/storage/LevelSummary.java.patch b/patches/minecraft/net/minecraft/world/level/storage/LevelSummary.java.patch index 88bd8e5d9e..bb7d684f32 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/LevelSummary.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/LevelSummary.java.patch @@ -1,13 +1,24 @@ --- a/net/minecraft/world/level/storage/LevelSummary.java +++ b/net/minecraft/world/level/storage/LevelSummary.java -@@ -277,6 +_,10 @@ - } - } +@@ -14,7 +_,7 @@ + import net.minecraft.world.level.LevelSettings; + import org.apache.commons.lang3.StringUtils; -+ public boolean isLifecycleExperimental() { -+ return this.settings.getLifecycle().equals(com.mojang.serialization.Lifecycle.experimental()); +-public class LevelSummary implements Comparable { ++public class LevelSummary implements Comparable, net.minecraftforge.common.extensions.IForgeLevelSummary { + public static final Component PLAY_WORLD = Component.translatable("selectWorld.select"); + private final LevelSettings settings; + private final LevelVersion levelVersion; +@@ -275,6 +_,12 @@ + public boolean canRecreate() { + return false; + } + } + ++ // TODO Forge: Remove in 1.22. It is kept here for binary compatibility, but already exists in IForgeLevelSummary ++ @Deprecated(forRemoval = true, since = "1.21.4") ++ public boolean isLifecycleExperimental() { ++ return net.minecraftforge.common.extensions.IForgeLevelSummary.super.isLifecycleExperimental(); + } + public static class SymlinkLevelSummary extends LevelSummary { - private static final Component MORE_INFO_BUTTON = Component.translatable("symlink_warning.more_info"); - private static final Component INFO = Component.translatable("symlink_warning.title").withColor(-65536); diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeLevelSummary.java b/src/main/java/net/minecraftforge/common/extensions/IForgeLevelSummary.java new file mode 100644 index 0000000000..c17a38cc05 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeLevelSummary.java @@ -0,0 +1,22 @@ +package net.minecraftforge.common.extensions; + +import net.minecraft.world.level.storage.LevelSummary; + +public interface IForgeLevelSummary { + private LevelSummary self() { + return (LevelSummary) this; + } + + /** + * Checks if the Forge lifecycle of this level is experimental. This is used to render the experimental warning + * tooltip on the level select screen. + * + * @return {@code true} if the level is experimental + */ + default boolean isLifecycleExperimental() { + // NOTE: Because CorruptedLevelSummary and SymlinkLevelSummary can have null settings, we need to check it + var settings = this.self().getSettings(); + + return settings != null && settings.getLifecycle().equals(com.mojang.serialization.Lifecycle.experimental()); + } +}