Refactor to use naming service, and provide an MCP naming service when
in userdev. Step 1 to supporting loading SRG mods in userdev. Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
parent
323fdb014d
commit
cdbd842494
|
@ -288,8 +288,8 @@ project(':forge') {
|
|||
installer 'org.ow2.asm:asm:6.2'
|
||||
installer 'org.ow2.asm:asm-commons:6.2'
|
||||
installer 'org.ow2.asm:asm-tree:6.2'
|
||||
installer 'cpw.mods:modlauncher:0.12.+'
|
||||
installer 'net.minecraftforge:accesstransformers:0.15.+:shadowed'
|
||||
installer 'cpw.mods:modlauncher:1.0.+'
|
||||
installer 'net.minecraftforge:accesstransformers:0.16.+:shadowed'
|
||||
installer 'net.minecraftforge:eventbus:0.8.+:service'
|
||||
installer 'net.minecraftforge:forgespi:0.11.+'
|
||||
installer 'net.minecraftforge:coremods:0.4.+'
|
||||
|
|
|
@ -80,4 +80,9 @@ public class FMLClientLaunchProvider extends FMLCommonLaunchHandler implements I
|
|||
{
|
||||
return Dist.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNaming() {
|
||||
return "srg";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,4 +135,6 @@ public abstract class FMLCommonLaunchHandler
|
|||
return Optional.empty();
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract String getNaming();
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@ import net.minecraftforge.forgespi.Environment;
|
|||
public class FMLEnvironment
|
||||
{
|
||||
public static final Dist dist = FMLLoader.getDist();
|
||||
public static final String naming = FMLLoader.getNaming();
|
||||
|
||||
static void setupInteropEnvironment(IEnvironment environment) {
|
||||
environment.computePropertyIfAbsent(IEnvironment.Keys.NAMING.get(), v->naming);
|
||||
environment.computePropertyIfAbsent(Environment.Keys.DIST.get(), v->dist);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,27 +19,35 @@
|
|||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import cpw.mods.modlauncher.Launcher;
|
||||
import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
|
||||
import cpw.mods.modlauncher.TransformingClassLoader;
|
||||
import cpw.mods.modlauncher.api.IEnvironment;
|
||||
import cpw.mods.modlauncher.api.ILaunchHandlerService;
|
||||
import cpw.mods.modlauncher.api.INameMappingService;
|
||||
import cpw.mods.modlauncher.api.ITransformationService;
|
||||
import cpw.mods.modlauncher.api.ITransformingClassLoader;
|
||||
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
|
||||
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
|
||||
import net.minecraftforge.accesstransformer.service.AccessTransformerService;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.forgespi.Environment;
|
||||
import net.minecraftforge.forgespi.coremod.ICoreModProvider;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -49,12 +57,13 @@ import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
|
|||
public class FMLLoader
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static ILaunchPluginService accessTransformer;
|
||||
private static AccessTransformerService accessTransformer;
|
||||
private static ModDiscoverer modDiscoverer;
|
||||
private static ICoreModProvider coreModProvider;
|
||||
private static ILaunchPluginService eventBus;
|
||||
private static LanguageLoadingProvider languageLoadingProvider;
|
||||
private static Dist dist;
|
||||
private static String naming;
|
||||
private static LoadingModList loadingModList;
|
||||
private static TransformingClassLoader launchClassLoader;
|
||||
private static RuntimeDistCleaner runtimeDistCleaner;
|
||||
|
@ -73,14 +82,14 @@ public class FMLLoader
|
|||
LOGGER.debug(CORE,"FML {} loading", version);
|
||||
final Package modLauncherPackage = ITransformationService.class.getPackage();
|
||||
LOGGER.debug(CORE,"FML found ModLauncher version : {}", modLauncherPackage.getImplementationVersion());
|
||||
if (!modLauncherPackage.isCompatibleWith("1.0")) {
|
||||
if (!modLauncherPackage.isCompatibleWith("2.0")) {
|
||||
LOGGER.fatal(CORE,"Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor());
|
||||
throw new IncompatibleEnvironmentException("Incompatible modlauncher found "+modLauncherPackage.getSpecificationVersion());
|
||||
}
|
||||
LOGGER.debug(CORE, "Initializing modjar URL handler");
|
||||
URL.setURLStreamHandlerFactory(p->p.equals("modjar") ? new ModJarURLHandler() : null);
|
||||
|
||||
accessTransformer = environment.findLaunchPlugin("accesstransformer").orElseThrow(()-> {
|
||||
accessTransformer = (AccessTransformerService) environment.findLaunchPlugin("accesstransformer").orElseThrow(()-> {
|
||||
LOGGER.fatal(CORE,"Access Transformer library is missing, we need this to run");
|
||||
return new IncompatibleEnvironmentException("Missing AccessTransformer, cannot run");
|
||||
});
|
||||
|
@ -160,7 +169,9 @@ public class FMLLoader
|
|||
gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".").toAbsolutePath());
|
||||
|
||||
FMLCommonLaunchHandler commonLaunchHandler = (FMLCommonLaunchHandler)launchHandler.get();
|
||||
naming = commonLaunchHandler.getNaming();
|
||||
dist = commonLaunchHandler.getDist();
|
||||
accessTransformer.getExtension().accept(Pair.of(naming, "srg"));
|
||||
|
||||
mcVersion = (String) arguments.get("mcVersion");
|
||||
mcpVersion = (String) arguments.get("mcpVersion");
|
||||
|
@ -245,4 +256,12 @@ public class FMLLoader
|
|||
public static Predicate<String> getClassLoaderExclusions() {
|
||||
return classLoaderExclusions;
|
||||
}
|
||||
|
||||
public static String getNaming() {
|
||||
return naming;
|
||||
}
|
||||
|
||||
public static Optional<BiFunction<INameMappingService.Domain, String, String>> getNameFunction(final String naming) {
|
||||
return Launcher.INSTANCE.environment().findNameMapping(naming);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import cpw.mods.modlauncher.api.IEnvironment;
|
||||
import cpw.mods.modlauncher.api.ILaunchHandlerService;
|
||||
import cpw.mods.modlauncher.api.ITransformingClassLoader;
|
||||
|
@ -27,7 +26,6 @@ import net.minecraftforge.api.distmarker.Dist;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -74,4 +72,10 @@ public class FMLServerLaunchProvider extends FMLCommonLaunchHandler implements I
|
|||
{
|
||||
return Dist.DEDICATED_SERVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNaming() {
|
||||
return "srg";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ public class FMLServiceProvider implements ITransformationService
|
|||
private String targetMcpVersion;
|
||||
private String targetMcpMappings;
|
||||
private String targetForgeGroup;
|
||||
private Map<String, Object> arguments;
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
|
@ -63,13 +64,12 @@ public class FMLServiceProvider implements ITransformationService
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IEnvironment environment)
|
||||
{
|
||||
LOGGER.debug(CORE,"Setting up basic FML game directories");
|
||||
public void initialize(IEnvironment environment) {
|
||||
LOGGER.debug(CORE, "Setting up basic FML game directories");
|
||||
FMLPaths.setup(environment);
|
||||
LOGGER.debug(CORE,"Loading configuration");
|
||||
LOGGER.debug(CORE, "Loading configuration");
|
||||
FMLConfig.load();
|
||||
final Map<String, Object> arguments = new HashMap<>();
|
||||
arguments = new HashMap<>();
|
||||
arguments.put("modLists", modListsArgumentList);
|
||||
arguments.put("mods", modsArgumentList);
|
||||
arguments.put("mavenRoots", mavenRootsArgumentList);
|
||||
|
@ -82,6 +82,10 @@ public class FMLServiceProvider implements ITransformationService
|
|||
FMLLoader.setupLaunchHandler(environment, arguments);
|
||||
FMLEnvironment.setupInteropEnvironment(environment);
|
||||
Environment.build(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginScanning(final IEnvironment environment) {
|
||||
LOGGER.debug(CORE,"Initiating mod scan");
|
||||
FMLLoader.beginModScan(arguments);
|
||||
}
|
||||
|
|
|
@ -18,19 +18,17 @@
|
|||
*/
|
||||
|
||||
package net.minecraftforge.fml.common;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import cpw.mods.modlauncher.api.INameMappingService;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
|
@ -59,25 +57,9 @@ public class ObfuscationReflectionHelper
|
|||
|
||||
|
||||
|
||||
public static String[] remapNames(String... names)
|
||||
public static String remapName(INameMappingService.Domain domain, String name)
|
||||
{
|
||||
loadMappings();
|
||||
if (map.isEmpty())
|
||||
return names;
|
||||
|
||||
String[] mappedNames = new String[names.length];
|
||||
int i = 0;
|
||||
for (String name : names)
|
||||
mappedNames[i++] = map.getOrDefault(name, name);
|
||||
return mappedNames;
|
||||
}
|
||||
|
||||
public static String remapName(String name)
|
||||
{
|
||||
loadMappings();
|
||||
if (map.isEmpty())
|
||||
return name;
|
||||
return map.getOrDefault(name, name);
|
||||
return FMLLoader.getNameFunction("srg").map(f->f.apply(domain, name)).orElse(name);
|
||||
}
|
||||
|
||||
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, int fieldIndex)
|
||||
|
@ -99,16 +81,16 @@ public class ObfuscationReflectionHelper
|
|||
{
|
||||
try
|
||||
{
|
||||
return (T)findField(classToAccess, remapName(fieldName)).get(instance);
|
||||
return (T)findField(classToAccess, remapName(INameMappingService.Domain.FIELD, fieldName)).get(instance);
|
||||
}
|
||||
catch (UnableToFindFieldException e)
|
||||
{
|
||||
LOGGER.error("Unable to locate field {} ({}) on type {}", fieldName, remapName(fieldName), classToAccess.getName(), e);
|
||||
LOGGER.error(REFLECTION,"Unable to locate field {} ({}) on type {}", fieldName, remapName(INameMappingService.Domain.FIELD, fieldName), classToAccess.getName(), e);
|
||||
throw e;
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
LOGGER.error("Unable to access field {} ({}) on type {}", fieldName, remapName(fieldName), classToAccess.getName(), e);
|
||||
LOGGER.error(REFLECTION,"Unable to access field {} ({}) on type {}", fieldName, remapName(INameMappingService.Domain.FIELD, fieldName), classToAccess.getName(), e);
|
||||
throw new UnableToAccessFieldException(e);
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +114,7 @@ public class ObfuscationReflectionHelper
|
|||
{
|
||||
try
|
||||
{
|
||||
findField(classToAccess, remapName(fieldName)).set(instance, value);
|
||||
findField(classToAccess, remapName(INameMappingService.Domain.FIELD, fieldName)).set(instance, value);
|
||||
}
|
||||
catch (UnableToFindFieldException e)
|
||||
{
|
||||
|
@ -166,7 +148,7 @@ public class ObfuscationReflectionHelper
|
|||
|
||||
try
|
||||
{
|
||||
Method m = clazz.getDeclaredMethod(remapName(methodName), parameterTypes);
|
||||
Method m = clazz.getDeclaredMethod(remapName(INameMappingService.Domain.METHOD, methodName), parameterTypes);
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
|
@ -229,38 +211,6 @@ public class ObfuscationReflectionHelper
|
|||
}
|
||||
}
|
||||
|
||||
private static void loadMappings()
|
||||
{
|
||||
if (loaded)
|
||||
return;
|
||||
|
||||
synchronized(map) //Just in case?
|
||||
{
|
||||
if (loaded) //Incase something else loaded while we were here, jump out
|
||||
return;
|
||||
for (String file : new String[]{"fields.csv", "methods.csv"})
|
||||
{
|
||||
URL path = ClassLoader.getSystemResource(file); //We EXPLICITLY go throught the SystemClassLoader here because this is dev-time only. And will be on the root classpath.
|
||||
if (path == null)
|
||||
continue;
|
||||
|
||||
int count = map.size();
|
||||
LOGGER.info(REFLECTION, "Loading Mappings: {}", path);
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(path.openStream())))
|
||||
{
|
||||
reader.lines().skip(1).map(e -> e.split(",")).forEach(e -> map.put(e[0], e[1]));
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
LOGGER.error(REFLECTION, "Error reading mappings", e1);
|
||||
}
|
||||
LOGGER.info(REFLECTION, "Loaded {} entries", map.size() - count);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Add SRG names to these exception?
|
||||
public static class UnableToAccessFieldException extends RuntimeException
|
||||
{
|
||||
private UnableToAccessFieldException(Exception e)
|
||||
|
|
|
@ -107,4 +107,10 @@ public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implement
|
|||
@Override
|
||||
protected void validatePaths(final Path forgePath, final Path[] mcPaths, final String forgeVersion, final String mcVersion, final String mcpVersion) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNaming() {
|
||||
return "mcp";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,4 +92,10 @@ public class FMLDevServerLaunchProvider extends FMLCommonLaunchHandler implement
|
|||
{
|
||||
return Dist.DEDICATED_SERVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNaming() {
|
||||
return "srg";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -89,4 +89,10 @@ public abstract class FMLUserdevLaunchProvider extends FMLCommonLaunchHandler {
|
|||
mcJars = LibraryFinder.findJarPathFor("en_us.json","mcdata", mcDataPath);
|
||||
return new Path[] {mcJars};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNaming() {
|
||||
return "mcp";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.userdev;
|
||||
|
||||
import cpw.mods.modlauncher.api.INameMappingService;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
|
||||
|
||||
public class MCPNamingService implements INameMappingService {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private HashMap<String, String> methods;
|
||||
private HashMap<String, String> fields;
|
||||
|
||||
@Override
|
||||
public String mappingName() {
|
||||
return "srgtomcp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mappingVersion() {
|
||||
return "1234";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map.Entry<String, String> understanding() {
|
||||
return Pair.of("srg", "mcp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiFunction<Domain, String, String> namingFunction() {
|
||||
return this::findMapping;
|
||||
}
|
||||
|
||||
private String findMapping(final Domain domain, final String srgName) {
|
||||
switch (domain) {
|
||||
case CLASS:
|
||||
return srgName;
|
||||
case FIELD:
|
||||
return findFieldMapping(srgName);
|
||||
case METHOD:
|
||||
return findMethodMapping(srgName);
|
||||
}
|
||||
return srgName;
|
||||
}
|
||||
|
||||
private String findMethodMapping(final String origin) {
|
||||
if (methods == null) {
|
||||
HashMap<String,String> tmpmethods = new HashMap<>(1000);
|
||||
loadMappings("methods.csv", tmpmethods::put);
|
||||
methods = tmpmethods;
|
||||
LOGGER.debug(CORE, "Loaded {} method mappings from methods.csv", methods.size());
|
||||
}
|
||||
return methods.getOrDefault(origin, origin);
|
||||
}
|
||||
|
||||
private String findFieldMapping(final String origin) {
|
||||
if (fields == null) {
|
||||
HashMap<String,String> tmpfields = new HashMap<>(1000);
|
||||
loadMappings("fields.csv", tmpfields::put);
|
||||
fields = tmpfields;
|
||||
LOGGER.debug(CORE, "Loaded {} field mappings from fields.csv", fields.size());
|
||||
}
|
||||
return fields.getOrDefault(origin, origin);
|
||||
}
|
||||
|
||||
|
||||
private static void loadMappings(final String mappingFileName, BiConsumer<String, String> mapStore)
|
||||
{
|
||||
URL path = ClassLoader.getSystemResource(mappingFileName); //We EXPLICITLY go throught the SystemClassLoader here because this is dev-time only. And will be on the root classpath.
|
||||
if (path == null)
|
||||
return;
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(path.openStream())))
|
||||
{
|
||||
reader.lines().skip(1).map(e -> e.split(",")).forEach(e -> mapStore.accept(e[0], e[1]));
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
LOGGER.error(CORE, "Error reading mappings", e1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
net.minecraftforge.userdev.MCPNamingService
|
Loading…
Reference in New Issue