Fix classloading properly. ModLoadingClassLoader doesn't work

with the proper delegation model. Abandoned it, in favour of injecting
locators into the Transformer classloader directly.
This commit is contained in:
cpw 2019-01-06 15:46:29 -05:00
parent 58c78560fa
commit 1b40618f02
27 changed files with 135 additions and 544 deletions

View File

@ -254,7 +254,7 @@ 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.3.0'
installer 'cpw.mods:modlauncher:0.4.+'
installer 'net.minecraftforge:accesstransformers:0.10+:shadowed'
installer 'net.minecraftforge:eventbus:0.1+:service'
installer 'net.minecraftforge:forgespi:0.1+'

View File

@ -93,7 +93,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
MethodNode ctr = classNode.methods.stream().filter(m -> m.name.equals("<init>") && m.desc.equals(desc)).findFirst().orElse(null);
if (ctr == null)
{
LOGGER.error(()->new AdvancedLogMessageAdapter(sb-> {
LOGGER.fatal(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method with no matching constructor:\n");
sb.append(" Enum: " + classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(desc).append("\n");
@ -104,7 +104,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
if (values == null)
{
LOGGER.error(()->new AdvancedLogMessageAdapter(sb-> {
LOGGER.fatal(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method but we could not find $VALUES. Found:\n");
classNode.fields.stream().filter(f -> (f.access & Opcodes.ACC_STATIC) != 0).
forEach(m -> sb.append(" ").append(m.name).append(" ").append(m.desc).append("\n"));

View File

@ -23,6 +23,7 @@ import com.google.common.collect.ObjectArrays;
import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ILaunchHandlerService;
import cpw.mods.modlauncher.api.ITransformingClassLoader;
import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder;
import net.minecraftforge.api.distmarker.Dist;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -34,6 +35,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.stream.Stream;
public class FMLClientLaunchProvider extends FMLCommonLaunchHandler implements ILaunchHandlerService
{
@ -45,12 +47,6 @@ public class FMLClientLaunchProvider extends FMLCommonLaunchHandler implements I
return "fmlclient";
}
@Override
public Path[] identifyTransformationTargets()
{
return LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()));
}
@Override
public Callable<Void> launchService(String[] arguments, ITransformingClassLoader launchClassLoader)
{

View File

@ -19,18 +19,25 @@
package net.minecraftforge.fml.loading;
import com.google.common.collect.ObjectArrays;
import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformingClassLoader;
import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder;
import net.minecraftforge.api.distmarker.Dist;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.jar.Manifest;
import java.util.stream.Stream;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
@ -59,6 +66,13 @@ public abstract class FMLCommonLaunchHandler
return LibraryFinder.getMCPaths(mcVersion, mcpVersion, forgeVersion, forgeGroup, getDist().isClient() ? "client" : "server");
}
public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) {
Stream.of(LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()))).
forEach(builder::addTransformationPath);
builder.setClassBytesLocator(getClassLoaderLocatorFunction());
builder.setManifestLocator(getClassLoaderManifestLocatorFunction());
}
public void setup(final IEnvironment environment, final Map<String, ?> arguments)
{
@ -85,4 +99,18 @@ public abstract class FMLCommonLaunchHandler
});
}
protected Function<String, Optional<URL>> getClassLoaderLocatorFunction() {
return input->Optional.ofNullable(FMLLoader.getLoadingModList().findURLForResource(input));
}
protected Function<URLConnection, Optional<Manifest>> getClassLoaderManifestLocatorFunction() {
return input -> {
if (input instanceof ModJarURLHandler.ModJarURLConnection) {
return ((ModJarURLHandler.ModJarURLConnection) input).getManifest();
}
return Optional.empty();
};
}
}

View File

@ -24,6 +24,7 @@ import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.io.WritingMode;
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.Arrays;
@ -33,6 +34,7 @@ import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class FMLConfig
{
private static final Logger LOGGER = LogManager.getLogger();
private static FMLConfig INSTANCE = new FMLConfig();
private static ConfigSpec configSpec = new ConfigSpec();
static {
@ -53,9 +55,9 @@ public class FMLConfig
build();
configData.load();
if (!configSpec.isCorrect(configData)) {
LogManager.getLogger().warn(CORE, "Configuration file {} is not correct. Correcting", configFile);
LOGGER.warn(CORE, "Configuration file {} is not correct. Correcting", configFile);
configSpec.correct(configData, (action, path, incorrectValue, correctedValue) ->
LogManager.getLogger().warn(CORE, "Incorrect key {} was corrected from {} to {}", path, incorrectValue, correctedValue));
LOGGER.warn(CORE, "Incorrect key {} was corrected from {} to {}", path, incorrectValue, correctedValue));
}
configData.save();
}
@ -64,8 +66,8 @@ public class FMLConfig
{
final Path configFile = FMLPaths.FMLCONFIG.get();
INSTANCE.loadFrom(configFile);
LogManager.getLogger().debug(CORE, "Loaded FML config from {}", FMLPaths.FMLCONFIG.get());
LogManager.getLogger().debug(CORE, "Splash screen is {}", INSTANCE.splashScreenEnabled());
LOGGER.debug(CORE, "Loaded FML config from {}", FMLPaths.FMLCONFIG.get());
LOGGER.debug(CORE, "Splash screen is {}", INSTANCE.splashScreenEnabled());
}
public boolean splashScreenEnabled() {

View File

@ -50,12 +50,6 @@ public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implement
return "fmldevclient";
}
@Override
public Path[] identifyTransformationTargets()
{
return LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()));
}
@Override
public Path getForgePath(final String mcVersion, final String forgeVersion, final String forgeGroup) {
// In forge dev, we just find the path for ForgeVersion for everything

View File

@ -46,12 +46,6 @@ public class FMLDevServerLaunchProvider extends FMLCommonLaunchHandler implement
return "fmldevserver";
}
@Override
public Path[] identifyTransformationTargets()
{
return LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()));
}
@Override
public Path getForgePath(final String mcVersion, final String forgeVersion, final String forgeGroup) {
// In forge dev, we just find the path for ForgeVersion for everything

View File

@ -75,7 +75,7 @@ public class FMLLoader
final Package modLauncherPackage = ITransformationService.class.getPackage();
LOGGER.debug(CORE,"FML found ModLauncher version : {}", modLauncherPackage.getImplementationVersion());
if (!modLauncherPackage.isCompatibleWith("1.0")) {
LOGGER.error(CORE,"Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor());
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");
@ -86,7 +86,7 @@ public class FMLLoader
final Package atPackage = accessTransformer.getClass().getPackage();
LOGGER.debug(CORE,"FML found AccessTransformer version : {}", atPackage.getImplementationVersion());
if (!atPackage.isCompatibleWith("1.0")) {
LOGGER.error(CORE,"Found incompatible AccessTransformer specification : {}, version {} from {}", atPackage.getSpecificationVersion(), atPackage.getImplementationVersion(), atPackage.getImplementationVendor());
LOGGER.fatal(CORE,"Found incompatible AccessTransformer specification : {}, version {} from {}", atPackage.getSpecificationVersion(), atPackage.getImplementationVersion(), atPackage.getImplementationVendor());
throw new IncompatibleEnvironmentException("Incompatible accesstransformer found "+atPackage.getSpecificationVersion());
}
@ -95,7 +95,7 @@ public class FMLLoader
final Package eventBusPackage = eventBus.getClass().getPackage();
LOGGER.debug(CORE,"FML found EventBus version : {}", eventBusPackage.getImplementationVersion());
if (!eventBusPackage.isCompatibleWith("1.0")) {
LOGGER.error(CORE,"Found incompatible EventBus specification : {}, version {} from {}", eventBusPackage.getSpecificationVersion(), eventBusPackage.getImplementationVersion(), eventBusPackage.getImplementationVendor());
LOGGER.fatal(CORE,"Found incompatible EventBus specification : {}, version {} from {}", eventBusPackage.getSpecificationVersion(), eventBusPackage.getImplementationVersion(), eventBusPackage.getImplementationVendor());
throw new IncompatibleEnvironmentException("Incompatible eventbus found "+eventBusPackage.getSpecificationVersion());
}
@ -106,10 +106,10 @@ public class FMLLoader
ServiceLoader.load(ICoreModProvider.class).forEach(coreModProviders::add);
if (coreModProviders.isEmpty()) {
LOGGER.error(CORE, "Found no coremod provider. Cannot run");
LOGGER.fatal(CORE, "Found no coremod provider. Cannot run");
throw new IncompatibleEnvironmentException("No coremod library found");
} else if (coreModProviders.size() > 1) {
LOGGER.error(CORE, "Found multiple coremod providers : {}. Cannot run", coreModProviders.stream().map(p -> p.getClass().getName()).collect(Collectors.toList()));
LOGGER.fatal(CORE, "Found multiple coremod providers : {}. Cannot run", coreModProviders.stream().map(p -> p.getClass().getName()).collect(Collectors.toList()));
throw new IncompatibleEnvironmentException("Multiple coremod libraries found");
}
@ -124,12 +124,12 @@ public class FMLLoader
final Optional<ILaunchHandlerService> launchHandler = environment.findLaunchHandler(launchTarget);
LOGGER.debug(CORE, "Using {} as launch service", launchTarget);
if (!launchHandler.isPresent()) {
LOGGER.error(CORE,"Missing LaunchHandler {}, cannot continue", launchTarget);
LOGGER.fatal(CORE,"Missing LaunchHandler {}, cannot continue", launchTarget);
throw new RuntimeException("Missing launch handler");
}
if (!(launchHandler.get() instanceof FMLCommonLaunchHandler)) {
LOGGER.error(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName());
LOGGER.fatal(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName());
throw new RuntimeException("Incompatible launch handler found");
}
gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".").toAbsolutePath());
@ -142,7 +142,7 @@ public class FMLLoader
forgeVersion = (String) arguments.get("forgeVersion");
forgeGroup = (String) arguments.get("forgeGroup");
LOGGER.fatal("Received command line version data : MC Version: '{}' MCP Version: '{}' Forge Version: '{}' Forge group: '{}'", mcVersion, mcpVersion, forgeVersion, forgeGroup);
LOGGER.info(CORE,"Received command line version data : MC Version: '{}' MCP Version: '{}' Forge Version: '{}' Forge group: '{}'", mcVersion, mcpVersion, forgeVersion, forgeGroup);
forgePath = commonLaunchHandler.getForgePath(mcVersion, forgeVersion, forgeGroup);
mcPaths = commonLaunchHandler.getMCPaths(mcVersion, mcpVersion, forgeVersion, forgeGroup);

View File

@ -43,12 +43,6 @@ public class FMLServerLaunchProvider extends FMLCommonLaunchHandler implements I
return "fmlserver";
}
@Override
public Path[] identifyTransformationTargets()
{
return ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths());
}
@Override
public Callable<Void> launchService(String[] arguments, ITransformingClassLoader launchClassLoader)
{

View File

@ -41,9 +41,9 @@ public class FileUtils
Files.createDirectory(dirPath);
} catch (IOException e) {
if (e instanceof FileAlreadyExistsException) {
LOGGER.error(CORE,"Failed to create {} directory - there is a file in the way", dirLabel);
LOGGER.fatal(CORE,"Failed to create {} directory - there is a file in the way", dirLabel);
} else {
LOGGER.error(CORE,"Problem with creating {} directory (Permissions?)", dirLabel, e);
LOGGER.fatal(CORE,"Problem with creating {} directory (Permissions?)", dirLabel, e);
}
throw new RuntimeException("Problem creating directory", e);
}

View File

@ -111,7 +111,7 @@ public class LanguageLoadingProvider
Optional<String> implementationVersion = JarVersionLookupHandler.getImplementationVersion(lp.getClass());
String impl = implementationVersion.orElse(Files.isDirectory(lpPath) ? FMLLoader.forgeVersion.split("\\.")[0] : null);
if (impl == null) {
LOGGER.fatal(CORE, "Found unversioned system classpath language provider {}", lp.name());
LOGGER.fatal(CORE, "Found unversioned language provider {}", lp.name());
throw new RuntimeException("Failed to find implementation version for language provider "+ lp.name());
}
LOGGER.debug(CORE, "Found language provider {}, version {}", lp.name(), impl);

View File

@ -32,7 +32,7 @@ public class LauncherVersion {
String vers = JarVersionLookupHandler.getImplementationVersion(LauncherVersion.class).orElse(System.getProperty("fmllauncher.version"));
if (vers == null) throw new RuntimeException("Missing FMLLauncher version, cannot continue");
launcherVersion = vers;
LOGGER.info(CORE, "Found FMLLauncher version {}", launcherVersion);
LOGGER.debug(CORE, "Found FMLLauncher version {}", launcherVersion);
}
public static String getVersion()

View File

@ -64,7 +64,7 @@ public class LibraryFinder {
LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString());
return path;
} catch (NullPointerException | URISyntaxException e) {
LOGGER.error(CORE, "Failed to find JAR for class {} - {}", resourceName, jarName);
LOGGER.fatal(CORE, "Failed to find JAR for class {} - {}", resourceName, jarName);
throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e);
}
}
@ -89,10 +89,10 @@ public class LibraryFinder {
Path mcDataPath = findLibsPath().resolve(MavenCoordinateResolver.get("net.minecraft", type, "", "data", mcVersion));
Path mcExtrasPath = findLibsPath().resolve(MavenCoordinateResolver.get("net.minecraft", type, "", "extra", mcVersion));
Path patchedBinariesPath = findLibsPath().resolve(MavenCoordinateResolver.get(forgeGroup, "forge", "", type, mcVersion+"-"+forgeVersion));
LOGGER.info("SRG MC at {} is {}", srgMcPath.toString(), pathStatus(srgMcPath));
LOGGER.info("MC Data at {} is {}", mcDataPath.toString(), pathStatus(mcDataPath));
LOGGER.info("MC Extras at {} is {}", mcExtrasPath.toString(), pathStatus(mcExtrasPath));
LOGGER.info("Forge patches at {} is {}", patchedBinariesPath.toString(), pathStatus(patchedBinariesPath));
LOGGER.debug(CORE,"SRG MC at {} is {}", srgMcPath.toString(), pathStatus(srgMcPath));
LOGGER.debug(CORE,"MC Data at {} is {}", mcDataPath.toString(), pathStatus(mcDataPath));
LOGGER.debug(CORE,"MC Extras at {} is {}", mcExtrasPath.toString(), pathStatus(mcExtrasPath));
LOGGER.debug(CORE,"Forge patches at {} is {}", patchedBinariesPath.toString(), pathStatus(patchedBinariesPath));
return new Path[] { patchedBinariesPath, mcDataPath, mcExtrasPath, srgMcPath };
}
}

View File

@ -34,7 +34,7 @@ public final class MavenVersionAdapter {
try {
return VersionRange.createFromVersionSpec(spec);
} catch (InvalidVersionSpecificationException e) {
LOGGER.error(CORE, "Failed to parse version spec {}", spec, e);
LOGGER.fatal(CORE, "Failed to parse version spec {}", spec, e);
throw new RuntimeException("Failed to parse spec", e);
}
}

View File

@ -19,6 +19,9 @@
package net.minecraftforge.fml.loading;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@ -26,43 +29,62 @@ import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.jar.Manifest;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class ModJarURLHandler extends URLStreamHandler
{
private static final Logger LOGGER = LogManager.getLogger();
// modjar://modid/path/to/file
@Override
protected URLConnection openConnection(URL url) {
return new URLConnection(url) {
private Path resource;
private String modpath;
private String modid;
return new ModJarURLConnection(url);
}
@Override
public void connect()
{
if (resource == null) {
modid = url.getHost();
// trim first char
modpath = url.getPath().substring(1);
resource = FMLLoader.getLoadingModList().getModFileById(modid).getFile().findResource(modpath);
}
static class ModJarURLConnection extends URLConnection {
private Path resource;
private String modpath;
private String modid;
private Optional<Manifest> manifest;
public ModJarURLConnection(final URL url) {
super(url);
}
@Override
public void connect()
{
if (resource == null) {
modid = url.getHost();
// trim first char
modpath = url.getPath().substring(1);
resource = FMLLoader.getLoadingModList().getModFileById(modid).getFile().findResource(modpath);
manifest = FMLLoader.getLoadingModList().getModFileById(modid).getManifest();
}
@Override
public InputStream getInputStream() throws IOException
{
}
@Override
public InputStream getInputStream() throws IOException
{
connect();
LOGGER.trace(CORE, "Loading modjar URL {} got resource {} {}", url, resource, resource != null ? Files.exists(resource) : "missing");
return Files.newInputStream(resource);
}
@Override
public long getContentLengthLong() {
try {
connect();
return Files.newInputStream(resource);
return Files.size(resource);
} catch (IOException e) {
return -1L;
}
}
@Override
public long getContentLengthLong() {
try {
connect();
return Files.size(resource);
} catch (IOException e) {
return -1L;
}
}
};
public Optional<Manifest> getManifest() {
return manifest;
}
}
}

View File

@ -93,7 +93,7 @@ public class ExplodedDirectoryLocator implements IModLocator {
try (Stream<Path> files = Files.find(path, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
files.forEach(pathConsumer);
} catch (IOException e) {
LOGGER.info("Exception scanning {}", path, e);
LOGGER.error(SCAN,"Exception scanning {}", path, e);
}
}
@Override

View File

@ -27,10 +27,8 @@ import net.minecraftforge.fml.loading.StringUtils;
import org.apache.maven.artifact.versioning.VersionRange;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
public class ModFileInfo implements IModFileInfo
@ -99,4 +97,8 @@ public class ModFileInfo implements IModFileInfo
{
return modLoaderVersion;
}
public Optional<Manifest> getManifest() {
return modFile.getLocator().findManifest(modFile.getFilePath());
}
}

View File

@ -1,353 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* 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.common;
import net.minecraftforge.fml.ModLoadingClassLoader;
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
import net.minecraftforge.fml.loading.DefaultModInfos;
/*
public class ForgeModContainer extends FMLModContainer
{
static final Logger log = LogManager.getLogger(ForgeVersion.MOD_ID);
private static ForgeModContainer INSTANCE;
public static ForgeModContainer getInstance()
{
return INSTANCE;
}
private URL updateJSONUrl = null;
public UniversalBucket universalBucket;
public ForgeModContainer()
{
super(new ModMetadata());
ModMetadata meta = getMetadata();
meta.modId = ForgeVersion.MOD_ID;
meta.name = "Minecraft Forge";
meta.version = ForgeVersion.getVersion();
meta.credits = "Made possible with help from many people";
meta.authorList = Arrays.asList("LexManos", "cpw", "fry");
meta.description = "Minecraft Forge is a common open source API allowing a broad range of mods " +
"to work cooperatively together. It allows many mods to be created without " +
"them editing the main Minecraft code.";
meta.url = "http://minecraftforge.net";
meta.screenshots = new String[0];
meta.logoFile = "/forge_logo.png";
try {
updateJSONUrl = new URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json");
} catch (MalformedURLException e) {}
config = null;
File cfgFile = new File(FMLPaths.FMLCONFIG.get().toFile(), "forge.cfg");
config = new Configuration(cfgFile);
syncConfig(true);
INSTANCE = this;
}
@Override
public String getGuiClassName()
{
return "net.minecraftforge.client.gui.ForgeGuiFactory";
}
/**
* By subscribing to the OnConfigChangedEvent we are able to execute code when our config screens are closed.
* This implementation uses the optional configID string to handle multiple Configurations using one event handler.
* /
@SubscribeEvent
public void onConfigChanged(OnConfigChangedEvent event)
{
if (getMetadata().modId.equals(event.getModID()))
{
if ("chunkLoader".equals(event.getConfigID()))
{
ForgeChunkManager.syncConfigDefaults();
ForgeChunkManager.loadConfiguration();
}
else
{
boolean tmpStairs = disableStairSlabCulling;
syncConfig(false);
if (event.isWorldRunning() && tmpStairs != disableStairSlabCulling)
{
FMLCommonHandler.instance().reloadRenderers();
}
}
}
}
@SubscribeEvent
public void missingMapping(RegistryEvent.MissingMappings<Item> event)
{
for (MissingMappings.Mapping<Item> entry : event.getAllMappings())
{
if (entry.key.toString().equals("minecraft:totem")) //This item changed from 1.11 -> 1.11.2
{
ResourceLocation newTotem = new ResourceLocation("minecraft:totem_of_undying");
entry.remap(ForgeRegistries.ITEMS.getValue(newTotem));
}
}
}
@net.minecraftforge.eventbus.api.SubscribeEvent
public void playerLogin(PlayerEvent.PlayerLoggedInEvent event)
{
UsernameCache.setUsername(event.player.getPersistentID(), event.player.getGameProfile().getName());
}
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
bus.register(this);
return true;
}
@Subscribe
public void modConstruction(FMLConstructionEvent evt)
{
InputStream is = ForgeModContainer.class.getResourceAsStream("/META-INF/vanilla_annotations.json");
if (is != null)
JsonAnnotationLoader.loadJson(is, null, evt.getASMHarvestedData());
log.debug("Loading Vanilla annotations: " + is);
List<String> all = Lists.newArrayList();
for (ASMData asm : evt.getASMHarvestedData().getAll(ICrashReportDetail.class.getName().replace('.', '/')))
all.add(asm.getClassName());
for (ASMData asm : evt.getASMHarvestedData().getAll(ICrashCallable.class.getName().replace('.', '/')))
all.add(asm.getClassName());
// Add table classes for mod list tabulation
all.add("net/minecraftforge/common/util/TextTable");
all.add("net/minecraftforge/common/util/TextTable$Column");
all.add("net/minecraftforge/common/util/TextTable$Row");
all.add("net/minecraftforge/common/util/TextTable$Alignment");
all.removeIf(cls -> !cls.startsWith("net/minecraft/") && !cls.startsWith("net/minecraftforge/"));
log.debug("Preloading CrashReport Classes");
Collections.sort(all); //Sort it because I like pretty output ;)
for (String name : all)
{
log.debug("\t{}", name);
try
{
Class.forName(name.replace('/', '.'), false, MinecraftForge.class.getClassLoader());
}
catch (Exception e)
{
log.error("Could not find class for name '{}'.", name, e);
}
}
NetworkRegistry.INSTANCE.register(this, this.getClass(), "*", evt.getASMHarvestedData());
ForgeNetworkHandler.registerChannel(this, evt.getSide());
ConfigManager.sync(this.getModId(), Config.Type.INSTANCE);
MinecraftForge.EVENT_BUS.register(this);
}
@Subscribe
public void preInit(FMLPreInitializationEvent evt)
{
CapabilityItemHandler.register();
CapabilityFluidHandler.register();
CapabilityAnimation.register();
CapabilityEnergy.register();
MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER);
if (FMLCommonHandler.instance().getSide() == Side.CLIENT)
{
MinecraftForge.EVENT_BUS.register(ForgeClientHandler.class);
}
ForgeChunkManager.captureConfig(evt.getModConfigurationDirectory());
MinecraftForge.EVENT_BUS.register(this);
if (!ForgeModContainer.disableVersionCheck)
{
ForgeVersion.startVersionCheck();
}
}
@net.minecraftforge.eventbus.api.SubscribeEvent
public void registrItems(RegistryEvent.Register<Item> event)
{
// Add and register the forge universal bucket, if it's enabled
if(FluidRegistry.isUniversalBucketEnabled())
{
universalBucket = new UniversalBucket();
universalBucket.setUnlocalizedName("forge.bucketFilled");
event.getRegistry().register(universalBucket.setRegistryName(ForgeVersion.MOD_ID, "bucketFilled"));
MinecraftForge.EVENT_BUS.register(universalBucket);
}
}
@Subscribe
public void postInit(FMLPostInitializationEvent evt)
{
registerAllBiomesAndGenerateEvents();
ForgeChunkManager.loadConfiguration();
}
private static void registerAllBiomesAndGenerateEvents()
{
for (Biome biome : ForgeRegistries.BIOMES.getValuesCollection())
{
if (biome.decorator instanceof DeferredBiomeDecorator)
{
DeferredBiomeDecorator decorator = (DeferredBiomeDecorator)biome.decorator;
decorator.fireCreateEventAndReplace(biome);
}
BiomeDictionary.ensureHasTypes(biome);
}
}
@Subscribe
public void onAvailable(FMLLoadCompleteEvent evt)
{
if (shouldSortRecipies)
{
RecipeSorter.sortCraftManager();
}
FluidRegistry.validateFluidRegistry();
}
@Subscribe
public void serverStarting(FMLServerStartingEvent evt)
{
evt.registerServerCommand(new ForgeCommand());
}
@Subscribe
public void serverStopping(FMLServerStoppingEvent evt)
{
WorldWorkerManager.clear();
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
NBTTagCompound forgeData = new NBTTagCompound();
NBTTagCompound dimData = DimensionManager.saveDimensionDataMap();
forgeData.setTag("DimensionData", dimData);
FluidRegistry.writeDefaultFluidList(forgeData);
return forgeData;
}
@Override
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
{
DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null);
FluidRegistry.loadFluidDefaults(tag);
}
@Subscribe
public void mappingChanged(FMLModIdMappingEvent evt)
{
OreDictionary.rebakeMap();
StatList.reinit();
Ingredient.invalidateAll();
FMLCommonHandler.instance().resetClientRecipeBook();
FMLCommonHandler.instance().reloadSearchTrees();
FMLCommonHandler.instance().reloadCreativeSettings();
}
@Override
public File getSource()
{
return FMLForgePlugin.forgeLocation;
}
@Override
public Class<?> getCustomResourcePackClass()
{
if (getSource().isDirectory())
{
return FMLFolderResourcePack.class;
}
else
{
return FMLFileResourcePack.class;
}
}
@Override
public List<String> getOwnedPackages()
{
// All the packages which are part of forge. Only needs updating if new logic is added
// that requires event handlers
return ImmutableList.of(
"net.minecraftforge.classloading",
"net.minecraftforge.client",
"net.minecraftforge.client.event",
"net.minecraftforge.client.event.sound",
"net.minecraftforge.client.model",
"net.minecraftforge.client.model.obj",
"net.minecraftforge.client.model.techne",
"net.minecraftforge.common",
"net.minecraftforge.common.config",
"net.minecraftforge.common.network",
"net.minecraftforge.common.util",
"net.minecraftforge.event",
"net.minecraftforge.event.brewing",
"net.minecraftforge.event.entity",
"net.minecraftforge.event.entity.item",
"net.minecraftforge.event.entity.living",
"net.minecraftforge.event.entity.minecart",
"net.minecraftforge.event.entity.player",
"net.minecraftforge.event.terraingen",
"net.minecraftforge.event.world",
"net.minecraftforge.fluids",
"net.minecraftforge.oredict",
"net.minecraftforge.server",
"net.minecraftforge.server.command",
"net.minecraftforge.transformers"
);
}
@Override
@Nullable
public Certificate getSigningCertificate()
{
Certificate[] certificates = getClass().getProtectionDomain().getCodeSource().getCertificates();
return certificates != null ? certificates[0] : null;
}
@Override
public URL getUpdateUrl()
{
return updateJSONUrl;
}
public ForgeModContainer(ModLoadingClassLoader classLoader)
{
super(DefaultModInfos.forgeModInfo, "net.minecraftforge.common.ForgeMod", classLoader, null);
ForgeConfig.load();
}
}
*/

View File

@ -66,7 +66,7 @@ public class AutomaticEventSubscriber
}
catch (ClassNotFoundException e)
{
LOGGER.error(LOADING, "Failed to load mod class {} for @EventBusSubscriber annotation", ad.getClassType(), e);
LOGGER.fatal(LOADING, "Failed to load mod class {} for @EventBusSubscriber annotation", ad.getClassType(), e);
throw new RuntimeException(e);
}
}

View File

@ -99,7 +99,7 @@ public final class FMLWorldPersistenceHook implements WorldPersistenceHooks.Worl
}
if (!Objects.equals(modVersion, MavenVersionStringHelper.artifactVersionToString(container.get().getModInfo().getVersion())))
{
LOGGER.info(WORLDPERSISTENCE,"This world was saved with mod {} version {} and it is now at version {}, things may not work well", modId, modVersion, MavenVersionStringHelper.artifactVersionToString(container.get().getModInfo().getVersion()));
LOGGER.warn(WORLDPERSISTENCE,"This world was saved with mod {} version {} and it is now at version {}, things may not work well", modId, modVersion, MavenVersionStringHelper.artifactVersionToString(container.get().getModInfo().getVersion()));
}
}
}

View File

@ -23,6 +23,8 @@ import net.minecraftforge.fml.loading.StringUtils;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import org.apache.commons.lang3.text.ExtendedMessageFormat;
import org.apache.commons.lang3.text.FormatFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.text.FieldPosition;
import java.text.Format;
@ -33,6 +35,7 @@ import java.util.Objects;
import java.util.function.BiConsumer;
public class ForgeI18n {
private static final Logger LOGGER = LogManager.getLogger();
private static Map<String,String> i18n;
private static Map<String,FormatFactory> customFactories;
@ -77,6 +80,7 @@ public class ForgeI18n {
}
public static void loadLanguageData(final Map<String, String> properties) {
LOGGER.debug("Loading I18N data entries: {}", properties.size());
i18n = properties;
}

View File

@ -42,12 +42,14 @@ public class LaunchTesting
final MarkerFilter axformFilter= MarkerFilter.createFilter("AXFORM", Filter.Result.DENY, Filter.Result.NEUTRAL);
final MarkerFilter eventbusFilter = MarkerFilter.createFilter("EVENTBUS", Filter.Result.DENY, Filter.Result.NEUTRAL);
final MarkerFilter distxformFilter = MarkerFilter.createFilter("DISTXFORM", Filter.Result.DENY, Filter.Result.NEUTRAL);
// final MarkerFilter scannerFilter = MarkerFilter.createFilter("SCAN", Filter.Result.DENY, Filter.Result.NEUTRAL);
final LoggerContext logcontext = LoggerContext.getContext(false);
logcontext.getConfiguration().addFilter(classloadingFilter);
logcontext.getConfiguration().addFilter(launchpluginFilter);
logcontext.getConfiguration().addFilter(axformFilter);
logcontext.getConfiguration().addFilter(eventbusFilter);
logcontext.getConfiguration().addFilter(distxformFilter);
// logcontext.getConfiguration().addFilter(axformFilter);
// logcontext.getConfiguration().addFilter(eventbusFilter);
// logcontext.getConfiguration().addFilter(distxformFilter);
// logcontext.getConfiguration().addFilter(scannerFilter);
logcontext.updateLoggers();
String assets = System.getenv().getOrDefault("assetDirectory", "assets");

View File

@ -49,7 +49,6 @@ public class ModLoader
private static ModLoader INSTANCE;
private final TransformingClassLoader launchClassLoader;
private final LoadingModList loadingModList;
private final ModLoadingClassLoader modClassLoader;
private final List<ModLoadingException> loadingExceptions;
private ModLoader()
@ -57,10 +56,8 @@ public class ModLoader
INSTANCE = this;
this.launchClassLoader = FMLLoader.getLaunchClassLoader();
this.loadingModList = FMLLoader.getLoadingModList();
this.modClassLoader = new ModLoadingClassLoader(this.launchClassLoader);
this.loadingExceptions = FMLLoader.getLoadingModList().
getErrors().stream().flatMap(ModLoadingException::fromEarlyException).collect(Collectors.toList());
Thread.currentThread().setContextClassLoader(this.modClassLoader);
}
public static ModLoader get()
@ -80,10 +77,10 @@ public class ModLoader
}
final Stream<ModContainer> modContainerStream = loadingModList.getModFiles().stream().
map(ModFileInfo::getFile).
map(mf -> buildMods(mf, modClassLoader)).
map(mf -> buildMods(mf, launchClassLoader)).
flatMap(Collection::stream);
if (!loadingExceptions.isEmpty()) {
LOGGER.error(CORE, "Failed to initialize mod containers");
LOGGER.fatal(CORE, "Failed to initialize mod containers");
throw new LoadingFailedException(loadingExceptions);
}
modList.setLoadedMods(modContainerStream.collect(Collectors.toList()));
@ -102,7 +99,7 @@ public class ModLoader
event.dispatch(this::accumulateErrors);
}
if (!loadingExceptions.isEmpty()) {
LOGGER.error("Failed to complete lifecycle event {}, {} errors found", event, loadingExceptions.size());
LOGGER.fatal("Failed to complete lifecycle event {}, {} errors found", event, loadingExceptions.size());
throw new LoadingFailedException(loadingExceptions);
}
}
@ -110,7 +107,7 @@ public class ModLoader
loadingExceptions.addAll(errors);
}
private List<ModContainer> buildMods(final ModFile modFile, final ModLoadingClassLoader modClassLoader)
private List<ModContainer> buildMods(final ModFile modFile, final TransformingClassLoader modClassLoader)
{
final Map<String, IModInfo> modInfoMap = modFile.getModFileInfo().getMods().stream().collect(Collectors.toMap(IModInfo::getModId, Function.identity()));

View File

@ -1,82 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* 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.fml;
import cpw.mods.modlauncher.TransformingClassLoader;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.ModJarURLHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.net.URL;
import java.util.function.Predicate;
import static net.minecraftforge.fml.Logging.LOADING;
public class ModLoadingClassLoader extends TransformingClassLoader
{
private static final Logger LOGGER = LogManager.getLogger();
static {
ClassLoader.registerAsParallelCapable();
}
private final Predicate<String> classLoadingPredicate;
private final TransformingClassLoader tcl;
protected ModLoadingClassLoader(final TransformingClassLoader parent) {
super(parent, path->FMLLoader.getLoadingModList().findURLForResource(path));
this.tcl = parent;
this.classLoadingPredicate = FMLLoader.getClassLoaderExclusions();
}
@Override
protected URL locateResource(final String path) {
return FMLLoader.getLoadingModList().findURLForResource(path);
}
@Override
public URL getResource(String name)
{
return locateResource(name);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
Class<?> existingClass = tcl.getLoadedClass(name);
if (existingClass != null) return existingClass;
LOGGER.debug(LOADING, "Loading class {}", name);
if (!classLoadingPredicate.test(name)) {
LOGGER.debug(LOADING, "Delegating to parent {}", name);
return tcl.loadClass(name);
}
return tcl.loadClass(name, this::locateResource);
}
}
@Override
protected URL findResource(String name)
{
return locateResource(name);
}
}

View File

@ -51,9 +51,9 @@ public class ForgeVersion
forgeVersion = vers;
forgeSpec = spec;
forgeGroup = group;
LOGGER.info(CORE, "Found Forge version {}", forgeVersion);
LOGGER.info(CORE, "Found Forge spec {}", forgeSpec);
LOGGER.info(CORE, "Found Forge group {}", forgeGroup);
LOGGER.debug(CORE, "Found Forge version {}", forgeVersion);
LOGGER.debug(CORE, "Found Forge spec {}", forgeSpec);
LOGGER.debug(CORE, "Found Forge group {}", forgeGroup);
}
public static String getVersion()

View File

@ -42,8 +42,8 @@ public class MCPVersion {
}
if (vers == null) throw new RuntimeException("Missing MCP version, cannot continue");
mcpVersion = vers;
LOGGER.info(CORE, "Found MC version information {}", mcVersion);
LOGGER.info(CORE, "Found MCP version information {}", mcpVersion);
LOGGER.debug(CORE, "Found MC version information {}", mcVersion);
LOGGER.debug(CORE, "Found MCP version information {}", mcpVersion);
}
public static String getMCVersion() {
return mcVersion;

View File

@ -1,10 +1,7 @@
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;
@ -52,7 +49,7 @@ public abstract class FMLUserdevLaunchProvider extends FMLCommonLaunchHandler {
fjroot = fjroot.getParent();
} while (dirs-- > 0);
final String fjpath = fjroot.toString();
LOGGER.info(CORE, "Injecting forge as mod {} from maven path {}", userdevVersion, fjpath);
LOGGER.debug(CORE, "Injecting forge as mod {} from maven path {}", userdevVersion, fjpath);
mavenRoots.add(fjpath);
mods.add(forgeGroup+":userdev:"+userdevVersion);
@ -62,7 +59,7 @@ public abstract class FMLUserdevLaunchProvider extends FMLCommonLaunchHandler {
modstoml.stream().filter(u-> !u.getPath().contains("!"));
} catch (IOException e) {
LOGGER.fatal("Error trying to find resources", e);
LOGGER.fatal(CORE,"Error trying to find resources", e);
throw new RuntimeException("wha?", e);
}
@ -97,10 +94,4 @@ public abstract class FMLUserdevLaunchProvider extends FMLCommonLaunchHandler {
mcJars = LibraryFinder.findJarPathFor("en_us.json","mcdata", mcDataPath);
return new Path[] {mcJars};
}
public Path[] identifyTransformationTargets()
{
return LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()));
}
}