diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/DistExecutor.java b/fmlcore/src/main/java/net/minecraftforge/fml/DistExecutor.java
index a58049fd5d..0367576e5e 100644
--- a/fmlcore/src/main/java/net/minecraftforge/fml/DistExecutor.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/DistExecutor.java
@@ -25,7 +25,18 @@ import java.util.function.Supplier;
*
When you want to call one thing on one side, another thing on the other and return a result {@link #safeRunForDist(Supplier, Supplier)}
* When you want to run something on one side {@link #safeRunWhenOn(Dist, Supplier)}
*
+ *
+ * @deprecated Historically, this allowed for safe execution of code on the correct side by exploiting a low-level
+ * detail in Java 8, but in newer versions a simple if check is enough.
+ *
+ * For example:
+ * {@code
+ * if (FMLEnvironment.dist.isClient()) {
+ * // client code here
+ * }
+ * }
*/
+@Deprecated(since = "1.21.5", forRemoval = true)
public final class DistExecutor
{
private static final Logger LOGGER = LogManager.getLogger();
diff --git a/src/main/java/net/minecraftforge/fml/core/ModStateProvider.java b/src/main/java/net/minecraftforge/fml/core/ModStateProvider.java
index 651fee7b50..321fc05f2b 100644
--- a/src/main/java/net/minecraftforge/fml/core/ModStateProvider.java
+++ b/src/main/java/net/minecraftforge/fml/core/ModStateProvider.java
@@ -6,9 +6,9 @@
package net.minecraftforge.fml.core;
import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.IModLoadingState;
import net.minecraftforge.fml.IModStateProvider;
+import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingPhase;
import net.minecraftforge.fml.ModLoadingStage;
import net.minecraftforge.fml.ModLoadingState;
@@ -21,9 +21,12 @@ import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
+import net.minecraftforge.fml.event.lifecycle.ParallelDispatchEvent;
+import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.loading.FMLPaths;
import java.util.List;
+import java.util.function.BiFunction;
/**
* Provider for the core FML mod loading states.
@@ -60,7 +63,7 @@ public class ModStateProvider implements IModStateProvider {
*/
public static final ModLoadingState CONFIG_LOAD = ModLoadingState.of("CONFIG_LOAD", ModLoadingPhase.LOAD)
.withInline(ml -> {
- DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get()));
+ if (FMLEnvironment.dist.isClient()) ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get());
ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get());
});
@@ -71,7 +74,7 @@ public class ModStateProvider implements IModStateProvider {
* @see FMLCommonSetupEvent
* @see ModLoadingStage#COMMON_SETUP
*/
- public static final ModLoadingState COMMON_SETUP = ModLoadingState.of("COMMON_SETUP", ModLoadingPhase.LOAD)
+ public static final ModLoadingState COMMON_SETUP = ModLoadingState.of("COMMON_SETUP", ModLoadingPhase.LOAD)
.after(CONFIG_LOAD)
.withTransition(new ParallelTransition(ModLoadingStage.COMMON_SETUP, FMLCommonSetupEvent::new));
@@ -83,14 +86,16 @@ public class ModStateProvider implements IModStateProvider {
* @see FMLDedicatedServerSetupEvent
* @see ModLoadingStage#SIDED_SETUP
*/
- public static final ModLoadingState SIDED_SETUP = ModLoadingState.of("SIDED_SETUP", ModLoadingPhase.LOAD)
+ public static final ModLoadingState SIDED_SETUP = ModLoadingState.of("SIDED_SETUP", ModLoadingPhase.LOAD)
.after(COMMON_SETUP)
- .withTransition(new ParallelTransition(ModLoadingStage.SIDED_SETUP,
- DistExecutor.unsafeRunForDist(
- () -> () -> FMLClientSetupEvent::new,
- () -> () -> FMLDedicatedServerSetupEvent::new
- )
- ));
+ .withTransition(new ParallelTransition(ModLoadingStage.SIDED_SETUP, createSidedSetupEvent()));
+
+ private static BiFunction createSidedSetupEvent() {
+ if (FMLEnvironment.dist.isClient())
+ return FMLClientSetupEvent::new;
+ else
+ return FMLDedicatedServerSetupEvent::new;
+ }
/**
* First {@linkplain ModLoadingPhase#COMPLETE completion state}, for enqueuing {@link net.minecraftforge.fml.InterModComms}
@@ -99,7 +104,7 @@ public class ModStateProvider implements IModStateProvider {
* @see InterModEnqueueEvent
* @see ModLoadingStage#ENQUEUE_IMC
*/
- public static final ModLoadingState ENQUEUE_IMC = ModLoadingState.of("ENQUEUE_IMC", ModLoadingPhase.COMPLETE)
+ public static final ModLoadingState ENQUEUE_IMC = ModLoadingState.of("ENQUEUE_IMC", ModLoadingPhase.COMPLETE)
.withTransition(new ParallelTransition(ModLoadingStage.ENQUEUE_IMC, InterModEnqueueEvent::new));
/**
diff --git a/src/main/java/net/minecraftforge/server/ServerLifecycleHooks.java b/src/main/java/net/minecraftforge/server/ServerLifecycleHooks.java
index 5e71ee7615..652dbdee70 100644
--- a/src/main/java/net/minecraftforge/server/ServerLifecycleHooks.java
+++ b/src/main/java/net/minecraftforge/server/ServerLifecycleHooks.java
@@ -23,6 +23,7 @@ import net.minecraft.world.level.storage.LevelResource;
import net.minecraftforge.common.world.StructureModifier;
import net.minecraftforge.common.util.LogicalSidedProvider;
import net.minecraftforge.common.world.BiomeModifier;
+import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.network.ConnectionType;
import net.minecraftforge.network.NetworkContext;
import net.minecraftforge.network.NetworkRegistry;
@@ -37,7 +38,6 @@ import net.minecraft.server.MinecraftServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.config.ConfigTracker;
import net.minecraftforge.fml.config.ModConfig;
-import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.event.server.ServerAboutToStartEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
diff --git a/src/test/generated/dist_executor/data/forge/test_instance/dist_executor/prevent_client_on_server.json b/src/test/generated/dist_executor/data/forge/test_instance/dist_executor/prevent_client_on_server.json
new file mode 100644
index 0000000000..3c574d380f
--- /dev/null
+++ b/src/test/generated/dist_executor/data/forge/test_instance/dist_executor/prevent_client_on_server.json
@@ -0,0 +1,7 @@
+{
+ "type": "minecraft:function",
+ "environment": "minecraft:default",
+ "function": "forge:dist_executor/prevent_client_on_server",
+ "max_ticks": 100,
+ "structure": "forge:empty3x3x3"
+}
\ No newline at end of file
diff --git a/src/test/java/net/minecraftforge/debug/dist/DistExecutorTest.java b/src/test/java/net/minecraftforge/debug/dist/DistExecutorTest.java
new file mode 100644
index 0000000000..fca069caa2
--- /dev/null
+++ b/src/test/java/net/minecraftforge/debug/dist/DistExecutorTest.java
@@ -0,0 +1,34 @@
+package net.minecraftforge.debug.dist;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.gametest.framework.GameTestHelper;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import net.minecraftforge.fml.loading.FMLEnvironment;
+import net.minecraftforge.gametest.GameTest;
+import net.minecraftforge.gametest.GameTestNamespace;
+import net.minecraftforge.test.BaseTestMod;
+
+@Mod(DistExecutorTest.MOD_ID)
+@GameTestNamespace("forge")
+public class DistExecutorTest extends BaseTestMod {
+ static final String MOD_ID = "dist_executor";
+
+ public DistExecutorTest(FMLJavaModLoadingContext context) {
+ super(context);
+ }
+
+ @GameTest
+ public static void preventClientOnServer(GameTestHelper helper) {
+ try {
+ if (FMLEnvironment.dist == Dist.CLIENT) {
+ Minecraft.getInstance().getWindow();
+ }
+ } catch (Throwable throwable) {
+ helper.fail("Client class was loaded on server! " + throwable);
+ }
+
+ helper.succeed();
+ }
+}