From 7e5bd4ecdb56b447ee8debc41e2f7789778a546e Mon Sep 17 00:00:00 2001 From: cpw Date: Sat, 7 Apr 2018 18:15:32 -0400 Subject: [PATCH] Access Transformer. Starting to try and launch things. --- .../net/minecraftforge/fml/LaunchTesting.java | 30 ++++++++- .../fml/loading/FMLDevLaunchProvider.java | 61 +++++++++++++++++++ .../fml/loading/FMLLaunchProvider.java | 5 +- .../minecraftforge/fml/loading/FMLLoader.java | 34 ++++++++++- .../fml/loading/FMLServiceProvider.java | 7 +-- .../loading/moddiscovery/ModDiscoverer.java | 3 + .../fml/loading/moddiscovery/ModFile.java | 8 ++- ...mods.modlauncher.api.ILaunchHandlerService | 3 +- 8 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 src/main/java/net/minecraftforge/fml/loading/FMLDevLaunchProvider.java diff --git a/src/main/java/net/minecraftforge/fml/LaunchTesting.java b/src/main/java/net/minecraftforge/fml/LaunchTesting.java index 020c5e749..0dc90b9a6 100644 --- a/src/main/java/net/minecraftforge/fml/LaunchTesting.java +++ b/src/main/java/net/minecraftforge/fml/LaunchTesting.java @@ -19,16 +19,44 @@ package net.minecraftforge.fml; +import com.google.common.base.Strings; import cpw.mods.modlauncher.Launcher; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; +import java.io.File; +import java.lang.reflect.Field; + public class LaunchTesting { public static void main(String... args) throws InterruptedException { Configurator.setRootLevel(Level.DEBUG); - Launcher.main("--launchTarget", "fml","--gameDir", "projects/run"); + hackNatives(); + Launcher.main("--launchTarget", "devfml","--gameDir", "projects/run", "--accessToken", "blah", "--version", "FMLDev"); Thread.sleep(10000); } + + private static void hackNatives() + { + String paths = System.getProperty("java.library.path"); + String nativesDir = "/home/cpw/.gradle/caches/minecraft/net/minecraft/natives/1.12.2"; + + if (Strings.isNullOrEmpty(paths)) + paths = nativesDir; + else + paths += File.pathSeparator + nativesDir; + + System.setProperty("java.library.path", paths); + + // hack the classloader now. + try + { + final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths"); + sysPathsField.setAccessible(true); + sysPathsField.set(null, null); + } + catch(Throwable t) {} + } + } diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLDevLaunchProvider.java b/src/main/java/net/minecraftforge/fml/loading/FMLDevLaunchProvider.java new file mode 100644 index 000000000..050a12623 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/loading/FMLDevLaunchProvider.java @@ -0,0 +1,61 @@ +/* + * Minecraft Forge + * Copyright (c) 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.loading; + +import cpw.mods.modlauncher.api.ILaunchHandlerService; +import net.minecraft.client.main.Main; + +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.Callable; + +public class FMLDevLaunchProvider implements ILaunchHandlerService +{ + @Override + public String name() + { + return "devfml"; + } + + @Override + public Path[] identifyTransformationTargets() + { + try + { + return new Path[] { + Paths.get(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()) + }; + } + catch (URISyntaxException e) + { + throw new RuntimeException("I can't find myself!"); + } + } + + @Override + public Callable launchService(String[] arguments, ClassLoader launchClassLoader) + { + return () -> { + Main.main(arguments); + return null; + }; + } +} diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLLaunchProvider.java b/src/main/java/net/minecraftforge/fml/loading/FMLLaunchProvider.java index 09fd12ec3..484ac2a59 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLLaunchProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLLaunchProvider.java @@ -20,6 +20,7 @@ package net.minecraftforge.fml.loading; import cpw.mods.modlauncher.api.ILaunchHandlerService; +import net.minecraft.client.main.Main; import java.nio.file.Path; import java.util.concurrent.Callable; @@ -41,6 +42,8 @@ public class FMLLaunchProvider implements ILaunchHandlerService @Override public Callable launchService(String[] arguments, ClassLoader launchClassLoader) { - return () -> { return null; }; + return () -> { + return null; + }; } } diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java b/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java index 025502142..c46a222e0 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java @@ -24,10 +24,18 @@ import cpw.mods.modlauncher.api.ITransformationService; import cpw.mods.modlauncher.api.IncompatibleEnvironmentException; import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.fml.common.FMLPaths; import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer; +import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.forgespi.ICoreModProvider; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Optional; import java.util.ServiceLoader; import java.util.Set; import java.util.stream.Collectors; @@ -81,7 +89,7 @@ public class FMLLoader languageLoadingProvider = new LanguageLoadingProvider(); } - public static void load() + public static void beginModScan() { fmlLog.debug(SCAN,"Scanning for Mod Locators"); modDiscoverer = new ModDiscoverer(); @@ -96,4 +104,28 @@ public class FMLLoader { return languageLoadingProvider; } + + public static void loadAccessTransformer() + { + final URL resource = FMLLoader.class.getClassLoader().getResource("forge_at.cfg"); + if (resource == null) { + throw new RuntimeException("Missing forge_at.cfg file"); + } + try + { + fmlLog.debug(CORE, "Loading forge_at.cfg into access transformer"); + accessTransformer.addResource(Paths.get(resource.toURI()), "forge_at.cfg"); + } + catch (URISyntaxException e) + { + fmlLog.error("Error loading forge_at.cfg file", e); + throw new RuntimeException(e); + } + } + + public static void addAccessTransformer(Path atPath, ModFile modName) + { + fmlLog.debug(SCAN, "Adding Access Transformer in {}", modName.getFilePath()); + accessTransformer.addResource(atPath, modName.getFileName()); + } } diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java b/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java index 0d1c070ba..8c613edfa 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java @@ -25,17 +25,14 @@ import cpw.mods.modlauncher.api.ITransformer; import cpw.mods.modlauncher.api.IncompatibleEnvironmentException; import joptsimple.ArgumentAcceptingOptionSpec; import joptsimple.OptionSpecBuilder; -import net.minecraftforge.coremod.CoreModEngine; import net.minecraftforge.fml.FMLConfig; import net.minecraftforge.fml.common.FMLPaths; import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Set; import java.util.function.BiFunction; -import java.util.stream.Collectors; import static net.minecraftforge.fml.Logging.CORE; import static net.minecraftforge.fml.Logging.fmlLog; @@ -62,7 +59,9 @@ public class FMLServiceProvider implements ITransformationService fmlLog.debug(CORE,"Loading configuration"); FMLConfig.load(); fmlLog.debug(CORE,"Initiating mod scan"); - FMLLoader.load(); + FMLLoader.beginModScan(); + fmlLog.debug(CORE, "Loading access transformers"); + FMLLoader.loadAccessTransformer(); } @Override diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java index de71a15a5..931d9ad0d 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java @@ -23,9 +23,11 @@ import cpw.mods.modlauncher.ServiceLoaderStreamUtils; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.LanguageLoadingProvider; +import java.nio.file.Path; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.ServiceLoader; import java.util.stream.Collectors; @@ -62,6 +64,7 @@ public class ModDiscoverer { mods.forEach(ModFile::identifyMods); fmlLog.debug(SCAN,"Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum()); mods.stream().map(ModFile::getCoreMods).flatMap(List::stream).forEach(FMLLoader.getCoreModProvider()::addCoreMod); + mods.forEach(mod -> mod.getAccessTransformer().ifPresent(path -> FMLLoader.addAccessTransformer(path, mod))); mods.forEach(backgroundScanHandler::submitForScanning); return backgroundScanHandler; } diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java index 8f57bae9f..67659a7c6 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java @@ -22,6 +22,7 @@ package net.minecraftforge.fml.loading.moddiscovery; import net.minecraftforge.fml.loading.IModLanguageProvider; import javax.swing.text.html.Option; +import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.Map; @@ -47,6 +48,7 @@ public class ModFile DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD"); } + public void claimLanguage(String modId, IModLanguageProvider.IModLanguageLoader loader) { this.modInfoMap.get(modId).setLoader(loader); @@ -64,6 +66,7 @@ public class ModFile private ScanResult fileScanResult; private CompletableFuture futureScanResult; private List coreMods; + private Path accessTransformer; private static final Attributes.Name TYPE = new Attributes.Name("FMLModType"); @@ -89,12 +92,16 @@ public class ModFile return modInfos; } + public Optional getAccessTransformer() { + return Optional.ofNullable(Files.exists(accessTransformer) ? accessTransformer : null); + } public void identifyMods() { this.modInfos = ModFileParser.readModList(this); this.modInfos.forEach(mi-> fmlLog.debug(LOADING,"Found mod {} for language {}", mi.getModId(), mi.getModLoader())); this.modInfoMap = this.modInfos.stream().collect(Collectors.toMap(ModInfo::getModId, Function.identity())); this.coreMods = ModFileParser.getCoreMods(this); this.coreMods.forEach(mi-> fmlLog.debug(LOADING,"Found coremod {}", mi.getPath())); + this.accessTransformer = locator.findPath(this, "META-INF", "accesstransformer.cfg"); } @@ -112,7 +119,6 @@ public class ModFile public void scanFile(Consumer pathConsumer) { locator.scanFile(this, pathConsumer); } - public void setFutureScanResult(CompletableFuture future) { this.futureScanResult = future; diff --git a/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService b/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService index 6b6ff6274..4d7e89883 100644 --- a/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService +++ b/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService @@ -1 +1,2 @@ -net.minecraftforge.fml.loading.FMLLaunchProvider \ No newline at end of file +net.minecraftforge.fml.loading.FMLLaunchProvider +net.minecraftforge.fml.loading.FMLDevLaunchProvider \ No newline at end of file