diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/CommonDevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/CommonDevLaunchHandler.java index a11d887c4..a093d00d7 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/CommonDevLaunchHandler.java +++ b/loader/src/main/java/net/neoforged/fml/loading/targets/CommonDevLaunchHandler.java @@ -5,18 +5,30 @@ package net.neoforged.fml.loading.targets; +import java.nio.file.Files; +import java.util.List; import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.neoforged.fml.loading.VersionInfo; import net.neoforged.fml.loading.moddiscovery.locators.NeoForgeDevProvider; import net.neoforged.fml.loading.moddiscovery.locators.UserdevLocator; +import net.neoforged.fml.util.DevEnvUtils; import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * For the NeoForge development environment. */ public abstract class CommonDevLaunchHandler extends CommonLaunchHandler { + private static final Logger LOG = LoggerFactory.getLogger(CommonDevLaunchHandler.class); + + /** + * A file we expect to find in the classpath entry that contains the Minecraft code. + */ + private static final String MINECRAFT_CLASS_PATH = "net/minecraft/server/MinecraftServer.class"; + @Override public boolean isProduction() { return false; @@ -26,13 +38,30 @@ public boolean isProduction() { public void collectAdditionalModFileLocators(VersionInfo versionInfo, Consumer output) { super.collectAdditionalModFileLocators(versionInfo, output); + NeoForgeDevProvider neoForgeProvider = null; var groupedModFolders = getGroupedModFolders(); var minecraftFolders = groupedModFolders.get("minecraft"); - if (minecraftFolders == null) { - throw new IllegalStateException("Expected paths to minecraft classes to be passed via environment"); + if (minecraftFolders != null) { + // A user can theoretically also pass a minecraft folder group when we're in userdev, + // we have to make sure the folder group actually contains a Minecraft class. + for (var candidateFolder : minecraftFolders) { + if (Files.isRegularFile(candidateFolder.resolve(MINECRAFT_CLASS_PATH))) { + LOG.debug("Launching with NeoForge from {}", minecraftFolders); + neoForgeProvider = new NeoForgeDevProvider(minecraftFolders); + break; + } + } + } + + if (neoForgeProvider == null) { + // Userdev is similar to neoforge dev with the only real difference being that the combined + // output of the neoforge and patched mincraft sources are combined into a jar file + var classesRoot = DevEnvUtils.findFileSystemRootOfFileOnClasspath(MINECRAFT_CLASS_PATH); + LOG.debug("Launching with NeoForge from {}", classesRoot); + neoForgeProvider = new NeoForgeDevProvider(List.of(classesRoot)); } - output.accept(new NeoForgeDevProvider(minecraftFolders)); + output.accept(neoForgeProvider); output.accept(new UserdevLocator(groupedModFolders)); } @@ -51,7 +80,7 @@ protected String[] preLaunch(String[] arguments, ModuleLayer layer) { String username = args.get("username"); if (username != null) { // Replace '#' placeholders with random numbers Matcher m = Pattern.compile("#+").matcher(username); - StringBuffer replaced = new StringBuffer(); + var replaced = new StringBuilder(); while (m.find()) { m.appendReplacement(replaced, getRandomNumbers(m.group().length())); } diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/CommonUserdevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/CommonUserdevLaunchHandler.java deleted file mode 100644 index b63667d18..000000000 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/CommonUserdevLaunchHandler.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.fml.loading.targets; - -import java.util.List; -import java.util.function.Consumer; -import net.neoforged.fml.loading.VersionInfo; -import net.neoforged.fml.loading.moddiscovery.locators.NeoForgeDevProvider; -import net.neoforged.fml.loading.moddiscovery.locators.UserdevLocator; -import net.neoforged.fml.util.DevEnvUtils; -import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; - -/** - * For mod development environments. - */ -public abstract class CommonUserdevLaunchHandler extends CommonDevLaunchHandler { - @Override - public void collectAdditionalModFileLocators(VersionInfo versionInfo, Consumer output) { - // Userdev is similar to neoforge dev with the only real difference being that the combined - // output of the neoforge and patched mincraft sources are combined into a jar file - var classesRoot = DevEnvUtils.findFileSystemRootOfFileOnClasspath("net/minecraft/client/Minecraft.class"); - - output.accept(new NeoForgeDevProvider(List.of(classesRoot))); - output.accept(new UserdevLocator(getGroupedModFolders())); - } -} diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/JUnitUserDevLaunchTarget.java b/loader/src/main/java/net/neoforged/fml/loading/targets/JUnitUserDevLaunchTarget.java index 80e4362d7..9b1e029d5 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/JUnitUserDevLaunchTarget.java +++ b/loader/src/main/java/net/neoforged/fml/loading/targets/JUnitUserDevLaunchTarget.java @@ -6,11 +6,18 @@ package net.neoforged.fml.loading.targets; import net.neoforged.api.distmarker.Dist; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A launch target for bootstrapping a slim Minecraft environment in userdev, to be used in JUnit tests. + * + * @deprecated Use {@link JUnitDevLaunchTarget} instead. */ -public class JUnitUserDevLaunchTarget extends NeoForgeUserdevLaunchHandler { +@Deprecated(forRemoval = true) +public class JUnitUserDevLaunchTarget extends CommonDevLaunchHandler { + private static final Logger LOG = LoggerFactory.getLogger(JUnitUserDevLaunchTarget.class); + @Override public Dist getDist() { return Dist.DEDICATED_SERVER; @@ -18,6 +25,7 @@ public Dist getDist() { @Override protected void runService(String[] arguments, ModuleLayer gameLayer) throws Throwable { + LOG.warn("Using deprecated launch target forgejunituserdev. Use forgejunitdev instead."); Class.forName(gameLayer.findModule("neoforge").orElseThrow(), "net.neoforged.neoforge.junit.JUnitMain").getMethod("main", String[].class).invoke(null, (Object) arguments); } diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeClientUserdevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeClientUserdevLaunchHandler.java index fa40f4b5d..486cf8d0b 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeClientUserdevLaunchHandler.java +++ b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeClientUserdevLaunchHandler.java @@ -6,8 +6,16 @@ package net.neoforged.fml.loading.targets; import net.neoforged.api.distmarker.Dist; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @deprecated Use {@link NeoForgeClientDevLaunchHandler} instead. + */ +@Deprecated(forRemoval = true) +public class NeoForgeClientUserdevLaunchHandler extends CommonDevLaunchHandler { + private static final Logger LOG = LoggerFactory.getLogger(NeoForgeClientUserdevLaunchHandler.class); -public class NeoForgeClientUserdevLaunchHandler extends NeoForgeUserdevLaunchHandler { @Override public String name() { return "forgeclientuserdev"; @@ -20,6 +28,7 @@ public Dist getDist() { @Override public void runService(String[] arguments, ModuleLayer layer) throws Throwable { + LOG.warn("Using deprecated launch target forgeclientuserdev. Use forgeclientdev instead."); clientService(arguments, layer); } } diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataDevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataDevLaunchHandler.java index f3eb55c1e..6dbabd627 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataDevLaunchHandler.java +++ b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataDevLaunchHandler.java @@ -25,6 +25,6 @@ public boolean isData() { @Override public void runService(String[] arguments, ModuleLayer layer) throws Throwable { - Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.data.Main").getMethod("main", String[].class).invoke(null, (Object) arguments); + dataService(arguments, layer); } } diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataUserdevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataUserdevLaunchHandler.java index 96ee9a4d3..3447732e8 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataUserdevLaunchHandler.java +++ b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeDataUserdevLaunchHandler.java @@ -6,8 +6,16 @@ package net.neoforged.fml.loading.targets; import net.neoforged.api.distmarker.Dist; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @deprecated Use {@link NeoForgeDataDevLaunchHandler} instead. + */ +@Deprecated(forRemoval = true) +public class NeoForgeDataUserdevLaunchHandler extends CommonDevLaunchHandler { + private static final Logger LOG = LoggerFactory.getLogger(NeoForgeDataUserdevLaunchHandler.class); -public class NeoForgeDataUserdevLaunchHandler extends NeoForgeUserdevLaunchHandler { @Override public String name() { return "forgedatauserdev"; @@ -25,6 +33,7 @@ public boolean isData() { @Override public void runService(String[] arguments, ModuleLayer layer) throws Throwable { + LOG.warn("Using deprecated launch target forgedatauserdev. Use forgedatadev instead."); dataService(arguments, layer); } } diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeServerUserdevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeServerUserdevLaunchHandler.java index 52f697443..04d942419 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeServerUserdevLaunchHandler.java +++ b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeServerUserdevLaunchHandler.java @@ -6,8 +6,16 @@ package net.neoforged.fml.loading.targets; import net.neoforged.api.distmarker.Dist; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @deprecated Use {@link NeoForgeServerDevLaunchHandler} instead. + */ +@Deprecated(forRemoval = true) +public class NeoForgeServerUserdevLaunchHandler extends CommonDevLaunchHandler { + private static final Logger LOG = LoggerFactory.getLogger(NeoForgeServerUserdevLaunchHandler.class); -public class NeoForgeServerUserdevLaunchHandler extends NeoForgeUserdevLaunchHandler { @Override public String name() { return "forgeserveruserdev"; @@ -20,6 +28,7 @@ public Dist getDist() { @Override public void runService(String[] arguments, ModuleLayer layer) throws Throwable { + LOG.warn("Using deprecated launch target forgeserveruserdev. Use forgeserverdev instead."); serverService(arguments, layer); } } diff --git a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeUserdevLaunchHandler.java b/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeUserdevLaunchHandler.java deleted file mode 100644 index f906e3368..000000000 --- a/loader/src/main/java/net/neoforged/fml/loading/targets/NeoForgeUserdevLaunchHandler.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.fml.loading.targets; - -public abstract class NeoForgeUserdevLaunchHandler extends CommonUserdevLaunchHandler {}