mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
Finish up classloading system. Use ModJARURL to locate resources
and enable ModLauncher to use those instead. This allows all mods to load within the scope of the game classloader, removing weird conflicts and class discovery problems.
This commit is contained in:
1 parent
6baddc7e26
commit
fd9c83b65f
21 files changed
+360
-144
No files matched your search
@@ -0,0 +1,37 @@
|
||||
package net.minecraftforge.userdev;
|
||||
|
||||
import cpw.mods.modlauncher.api.ILaunchHandlerService;
|
||||
import cpw.mods.modlauncher.api.ITransformingClassLoader;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
|
||||
|
||||
public class FMLUserdevClientLaunchProvider extends FMLUserdevLaunchProvider implements ILaunchHandlerService {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public Dist getDist() {
|
||||
return Dist.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "fmluserdevclient";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ITransformingClassLoader launchClassLoader)
|
||||
{
|
||||
return () -> {
|
||||
LOGGER.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments);
|
||||
super.beforeStart(launchClassLoader);
|
||||
launchClassLoader.addTargetPackageFilter(getPackagePredicate());
|
||||
Class.forName("net.minecraft.client.main.Main", true, launchClassLoader.getInstance()).getMethod("main", String[].class).invoke(null, (Object)arguments);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package net.minecraftforge.userdev;
|
||||
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import com.google.common.collect.Streams;
|
||||
import cpw.mods.modlauncher.api.IEnvironment;
|
||||
import net.minecraftforge.fml.loading.FMLCommonLaunchHandler;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LibraryFinder;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
|
||||
|
||||
public abstract class FMLUserdevLaunchProvider extends FMLCommonLaunchHandler {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private Path forgeJar;
|
||||
private Path mcJars;
|
||||
|
||||
@Override
|
||||
public Path getForgePath(final String mcVersion, final String forgeVersion, final String forgeGroup) {
|
||||
final URL forgePath = getClass().getClassLoader().getResource("net/minecraftforge/versions/forge/ForgeVersion.class");
|
||||
if (forgePath == null) {
|
||||
LOGGER.fatal(CORE, "Unable to locate forge on the classpath");
|
||||
throw new RuntimeException("Unable to locate forge on the classpath");
|
||||
}
|
||||
forgeJar = LibraryFinder.findJarPathFor("ForgeVersion.class","forge", forgePath);
|
||||
return forgeJar;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void setup(final IEnvironment environment, final Map<String, ?> arguments) {
|
||||
final List<String> mavenRoots = new ArrayList<>((List<String>) arguments.get("mavenRoots"));
|
||||
final List<String> mods = new ArrayList<>((List<String>) arguments.get("mods"));
|
||||
final String forgeVersion = (String) arguments.get("forgeVersion");
|
||||
final String mcVersion = (String) arguments.get("mcVersion");
|
||||
final String mcpVersion = (String) arguments.get("mcpVersion");
|
||||
final String forgeGroup = (String) arguments.get("forgeGroup");
|
||||
final String userdevVersion = mcVersion+"-"+forgeVersion+"_mapped_snapshot_"+mcpVersion;
|
||||
int dirs = forgeGroup.split("\\.").length + 2;
|
||||
Path fjroot = forgeJar;
|
||||
do {
|
||||
fjroot = fjroot.getParent();
|
||||
} while (dirs-- > 0);
|
||||
final String fjpath = fjroot.toString();
|
||||
LOGGER.info(CORE, "Injecting forge as mod {} from maven path {}", userdevVersion, fjpath);
|
||||
mavenRoots.add(fjpath);
|
||||
mods.add(forgeGroup+":userdev:"+userdevVersion);
|
||||
|
||||
try {
|
||||
final Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources("META-INF/mods.toml");
|
||||
final ArrayList<URL> modstoml = Collections.list(resources);
|
||||
modstoml.stream().filter(u-> !u.getPath().contains("!"));
|
||||
|
||||
} catch (IOException e) {
|
||||
LOGGER.fatal("Error trying to find resources", e);
|
||||
throw new RuntimeException("wha?", e);
|
||||
}
|
||||
|
||||
LOGGER.fatal(CORE, "Got mod coordinates {} from env", System.getenv("MOD_CLASSES"));
|
||||
|
||||
final List<Path> modClasses = Arrays.stream(System.getenv("MOD_CLASSES").split(File.pathSeparator)).
|
||||
map(Paths::get).collect(Collectors.toList());
|
||||
|
||||
LOGGER.fatal(CORE, "Processed mod coordinates [{}]", modClasses.stream().map(Object::toString).collect(Collectors.joining(",")));
|
||||
|
||||
((Map<String, List<Pair<Path,List<Path>>>>) arguments).computeIfAbsent("explodedTargets", a->new ArrayList<>()).
|
||||
add(Pair.of(modClasses.get(0), modClasses.subList(1, modClasses.size())));
|
||||
|
||||
|
||||
// generics are gross yea?
|
||||
((Map)arguments).put("mavenRoots", mavenRoots);
|
||||
((Map)arguments).put("mods", mods);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validatePaths(final Path forgePath, final Path[] mcPaths, final String forgeVersion, final String mcVersion, final String mcpVersion) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path[] getMCPaths(final String mcVersion, final String mcpVersion, final String forgeVersion, final String forgeGroup) {
|
||||
final URL mcDataPath = getClass().getClassLoader().getResource("assets/minecraft/lang/en_us.json");
|
||||
if (mcDataPath == null) {
|
||||
LOGGER.fatal(CORE, "Unable to locate minecraft data on the classpath");
|
||||
throw new RuntimeException("Unable to locate minecraft data on the classpath");
|
||||
}
|
||||
mcJars = LibraryFinder.findJarPathFor("en_us.json","mcdata", mcDataPath);
|
||||
return new Path[] {mcJars};
|
||||
}
|
||||
|
||||
public Path[] identifyTransformationTargets()
|
||||
{
|
||||
return LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.minecraftforge.userdev;
|
||||
|
||||
import cpw.mods.modlauncher.api.ILaunchHandlerService;
|
||||
import cpw.mods.modlauncher.api.ITransformingClassLoader;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
|
||||
|
||||
public class FMLUserdevServerLaunchProvider extends FMLUserdevLaunchProvider implements ILaunchHandlerService {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public Dist getDist() {
|
||||
return Dist.DEDICATED_SERVER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "fmluserdevserver";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ITransformingClassLoader launchClassLoader)
|
||||
{
|
||||
return () -> {
|
||||
LOGGER.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments);
|
||||
super.beforeStart(launchClassLoader);
|
||||
launchClassLoader.addTargetPackageFilter(getPackagePredicate());
|
||||
Thread.currentThread().setContextClassLoader(launchClassLoader.getInstance());
|
||||
Class.forName("net.minecraft.server.MinecraftServer", true, launchClassLoader.getInstance()).getMethod("main", String[].class).invoke(null, (Object)arguments);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -57,25 +57,33 @@ public class UserdevLauncher
|
||||
throw new IllegalArgumentException("Environment variable 'assets' must be set to a valid path.");
|
||||
}
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("Environment variable 'target' must be set to 'fmldevclient' or 'fmldevserver'.");
|
||||
throw new IllegalArgumentException("Environment variable 'target' must be set to 'fmluserdevclient' or 'fmluserdevserver'.");
|
||||
}
|
||||
|
||||
if (Objects.equals(target,"fmldevclient")) {
|
||||
String[] launchArgs = new String[]{
|
||||
"--gameDir", ".",
|
||||
"--launchTarget", target,
|
||||
"--fml.forgeVersion", System.getenv("FORGE_VERSION"),
|
||||
"--fml.mcpVersion", System.getenv("MCP_VERSION"),
|
||||
"--fml.mcVersion", System.getenv("MC_VERSION"),
|
||||
"--fml.forgeGroup", System.getenv("FORGE_GROUP")
|
||||
};
|
||||
|
||||
if (Objects.equals(target,"fmluserdevclient")) {
|
||||
hackNatives();
|
||||
Launcher.main("--launchTarget", target,
|
||||
"--gameDir", ".",
|
||||
launchArgs = ObjectArrays.concat(launchArgs, new String[] {
|
||||
"--accessToken", "blah",
|
||||
"--version", "FMLDev",
|
||||
"--assetIndex", "1.13",
|
||||
"--assetsDir", assets,
|
||||
"--userProperties", "{}");
|
||||
} else if (Objects.equals(target, "fmldevserver")) {
|
||||
String[] launchargs = ObjectArrays.concat(new String[] {"--launchTarget", target,
|
||||
"--gameDir", "."}, args, String.class);
|
||||
Launcher.main(launchargs);
|
||||
"--userProperties", "{}"
|
||||
}, String.class);
|
||||
} else if (Objects.equals(target, "fmluserdevserver")) {
|
||||
// we're good
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown value for 'target' property: " + target);
|
||||
}
|
||||
Launcher.main(launchArgs);
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
net.minecraftforge.userdev.FMLUserdevClientLaunchProvider
|
||||
net.minecraftforge.userdev.FMLUserdevServerLaunchProvider
|
||||
-1
@@ -1 +0,0 @@
|
||||
net.minecraftforge.userdev.ClasspathLocator
|
||||
Reference in new issue
Block a user