diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java index 328020b49d..1660d593e5 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -82,6 +82,7 @@ public class ModLoader private boolean loadingStateValid; @SuppressWarnings("OptionalUsedAsFieldOrParameterType") private final Optional> statusConsumer = StartupMessageManager.modLoaderConsumer(); + private final Set completedStates = new HashSet<>(); private ModList modList; private ModLoader() @@ -200,6 +201,7 @@ public class ModLoader statusConsumer.ifPresent(c->c.accept(state.message().apply(this.modList))); state.inlineRunnable().ifPresent(a->a.accept(this.modList)); state.buildTransition(syncExecutor, parallelExecutor).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t)); + completedStates.add(state); } private void dispatchAndHandleError(IModLoadingState state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker, Function> preSyncTask, Function> postSyncTask) { @@ -210,6 +212,7 @@ public class ModLoader statusConsumer.ifPresent(c->c.accept(state.message().apply(this.modList))); state.inlineRunnable().ifPresent(a->a.accept(this.modList)); state.buildTransition(syncExecutor, parallelExecutor, preSyncTask, postSyncTask).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t)); + completedStates.add(state); } private void waitForTransition(final IModLoadingState state, final ModWorkManager.DrivenExecutor syncExecutor, final Runnable ticker, final CompletableFuture transition) { @@ -296,6 +299,11 @@ public class ModLoader return get().loadingStateValid; } + public boolean hasCompletedState(final String stateName) { + IModLoadingState state = stateManager.findState(stateName); + return completedStates.contains(state); + } + public void runEventGenerator(Function generator) { if (!loadingStateValid) { LOGGER.error("Cowardly refusing to send event generator to a broken mod state"); diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java index e4be1c0009..7cd81e69df 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java @@ -39,4 +39,13 @@ public class ModStateManager { nodes.forEach(n->graph.putEdge(lookup.getOrDefault(n.previous(), dummy), n)); return TopologicalSort.topologicalSort(graph, Comparator.comparingInt(nodes::indexOf)).stream().filter(st->st!=dummy).toList(); } + + public IModLoadingState findState(final String stateName) { + return stateMap.values() + .stream() + .flatMap(Collection::stream) + .filter(mls -> mls.name().equals(stateName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unknown IModLoadingState: " + stateName)); + } } diff --git a/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch b/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch index a72a4f0950..871b786d09 100644 --- a/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch @@ -16,10 +16,11 @@ } public static Material m_173381_(WoodType p_173382_) { -@@ -209,5 +_,13 @@ +@@ -208,6 +_,23 @@ + case SINGLE: default: return p_110773_; - } ++ } + } + + /** @@ -28,5 +29,14 @@ + public static void addWoodType(WoodType woodType) { + f_110743_.put(woodType, m_173385_(woodType)); + f_244291_.put(woodType, m_245275_(woodType)); ++ } ++ ++ static { ++ if (net.minecraftforge.fml.ModLoader.isLoadingStateValid() && !net.minecraftforge.fml.ModLoader.get().hasCompletedState("LOAD_REGISTRIES")) { ++ com.mojang.logging.LogUtils.getLogger().error( ++ "net.minecraft.client.renderer.Sheets loaded too early, modded registry-based materials may not work correctly", ++ new IllegalStateException("net.minecraft.client.renderer.Sheets loaded too early") ++ ); + } } }