From aa91af865d837c54acf6be10e599ff1ee3565c57 Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 4 Feb 2019 18:23:58 -0800 Subject: [PATCH] Rework server launching at runtime to include needed default arguments and validate libraries exist. Move Forge config loading to manual while config system is in development. --- build.gradle | 42 +++++++++++++++---- mdk/gradle.properties | 1 + .../fml/loading/FMLClientLaunchProvider.java | 12 +++--- .../fml/loading/FMLCommonLaunchHandler.java | 6 +-- .../loading/FMLDevClientLaunchProvider.java | 9 +++- .../fml/loading/LibraryFinder.java | 7 +--- .../net/minecraftforge/server/ServerMain.java | 41 +++++++++++++++++- .../net/minecraftforge/common/ForgeMod.java | 26 +++++++++++- .../fml/config/ConfigFileTypeHandler.java | 1 - .../FMLUserdevClientLaunchProvider.java | 10 +++++ 10 files changed, 127 insertions(+), 28 deletions(-) diff --git a/build.gradle b/build.gradle index 81eef5b70..fa431934e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { repositories { - mavenLocal() + //mavenLocal() maven { url = 'https://files.minecraftforge.net/maven' } jcenter() mavenCentral() @@ -241,12 +241,12 @@ project(':forge') { 'Implementation-Vendor': 'Forge' ] as LinkedHashMap, 'net/minecraftforge/fml/loading/': [ - 'Specification-Title': 'Launcher', - 'Specification-Vendor': 'Forge Development LLC', - 'Specification-Version': '1', - 'Implementation-Title': 'FML Launcher', - 'Implementation-Version': SPEC_VERSION, - 'Implementation-Vendor': 'Forge' + 'Specification-Title': 'Launcher', + 'Specification-Vendor': 'Forge Development LLC', + 'Specification-Version': '1', + 'Implementation-Title': 'FML Launcher', + 'Implementation-Version': SPEC_VERSION, + 'Implementation-Vendor': 'Forge' ] as LinkedHashMap ] } @@ -695,10 +695,34 @@ project(':forge') { } } } + + task fmllauncherConfig(type: WriteProperties) { + outputFile file('build/server_launcher.properties') + encoding 'UTF8' + doFirst { + def artifacts = getArtifacts(project, project.configurations.installer, false).values().stream().map{a -> a.downloads.artifact.path}.sorted().collect() + [ + "net/minecraft/server/${MC_VERSION}/server-${MC_VERSION}-data.jar", + "net/minecraft/server/${MC_VERSION}/server-${MC_VERSION}-extra.jar" + ] + for (int x = 0; x < artifacts.size(); x++) { + property 'library.' + x.toString().padLeft(3, '0'), "libraries/${artifacts.get(x)}" + } + property 'library.count', artifacts.size() + property 'args', [ + '--gameDir', '.', + '--launchTarget', 'fmlserver', + '--fml.forgeVersion', "${project.version.substring(MC_VERSION.length() + 1)}".toString(), + '--fml.mcpVersion', MCP_VERSION, + '--fml.mcVersion', MC_VERSION, + '--fml.forgeGroup', project.group + ].join(' ') + } + } - task launcherJar(type: Jar) { + task launcherJar(type: Jar, dependsOn: [fmllauncherConfig]) { classifier 'launcher' from sourceSets.fmllauncher.output + from fmllauncherConfig.outputFile doFirst { def classpath = new StringBuilder() def artifacts = getArtifacts(project, project.configurations.installer, false) @@ -865,7 +889,7 @@ project(':forge') { task userdevExtrasReobf(type:TaskReobfuscateJar) { dependsOn userdevExtras, createMcp2Srg input = tasks.userdevExtras.archivePath - classpath = project.configurations.getByName("compile") + classpath = project.configurations.compile srg = tasks.createMcp2Srg.output } diff --git a/mdk/gradle.properties b/mdk/gradle.properties index e9b9fd5ac..878bf1f7e 100644 --- a/mdk/gradle.properties +++ b/mdk/gradle.properties @@ -1,3 +1,4 @@ # Sets default memory used for gradle commands. Can be overridden by user or command line properties. # This is required to provide enough memory for the Minecraft decompilation process. org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false \ No newline at end of file diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLClientLaunchProvider.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLClientLaunchProvider.java index fcf3d8cd7..a8798295c 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLClientLaunchProvider.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLClientLaunchProvider.java @@ -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; @@ -28,14 +27,10 @@ import net.minecraftforge.api.distmarker.Dist; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; 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 { @@ -58,6 +53,13 @@ public class FMLClientLaunchProvider extends FMLCommonLaunchHandler implements I }; } + @Override + public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) + { + super.configureTransformationClassLoader(builder); + builder.addTransformationPath(LibraryFinder.findJarPathFor("com/mojang/realmsclient/RealmsVersion.class", "realms")); + } + @SuppressWarnings("unchecked") @Override public void setup(final IEnvironment environment, final Map arguments) { diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLCommonLaunchHandler.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLCommonLaunchHandler.java index 51937d2dd..d1f0f640d 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLCommonLaunchHandler.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLCommonLaunchHandler.java @@ -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.ITransformingClassLoader; import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder; @@ -68,8 +67,9 @@ public abstract class FMLCommonLaunchHandler } public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) { - Stream.of(LibraryFinder.commonLibPaths(ObjectArrays.concat(FMLLoader.getForgePath(), FMLLoader.getMCPaths()))). - forEach(builder::addTransformationPath); + builder.addTransformationPath(FMLLoader.getForgePath()); + for (Path path : FMLLoader.getMCPaths()) + builder.addTransformationPath(path); builder.setClassBytesLocator(getClassLoaderLocatorFunction()); builder.setManifestLocator(getClassLoaderManifestLocatorFunction()); } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java index 263851bc7..004125a8b 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java @@ -19,10 +19,10 @@ 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; +import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder; import net.minecraftforge.api.distmarker.Dist; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; @@ -64,6 +64,13 @@ public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implement return new Path[] { compiledClasses, resources }; } + @Override + public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) + { + super.configureTransformationClassLoader(builder); + builder.addTransformationPath(LibraryFinder.findJarPathFor("com/mojang/realmsclient/RealmsVersion.class", "realms")); + } + @Override public Callable launchService(String[] arguments, ITransformingClassLoader launchClassLoader) { diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java index 16cc74fab..11ce0f056 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java @@ -47,7 +47,7 @@ public class LibraryFinder { return libsPath; } - static Path findJarPathFor(final String className, final String jarName) { + public static Path findJarPathFor(final String className, final String jarName) { final URL resource = LibraryFinder.class.getClassLoader().getResource(className); return findJarPathFor(className, jarName, resource); } @@ -69,11 +69,6 @@ public class LibraryFinder { } } - public static Path[] commonLibPaths(Path[] extras) { - final Path realms = findJarPathFor("com/mojang/realmsclient/RealmsVersion.class", "realms"); - return ObjectArrays.concat(extras, realms); - } - static Path getForgeLibraryPath(final String mcVersion, final String forgeVersion, final String forgeGroup) { Path forgePath = findLibsPath().resolve(MavenCoordinateResolver.get(forgeGroup, "forge", "", "universal", mcVersion+"-"+forgeVersion)); LOGGER.debug(CORE, "Found forge path {} is {}", forgePath, pathStatus(forgePath)); diff --git a/src/fmllauncher/java/net/minecraftforge/server/ServerMain.java b/src/fmllauncher/java/net/minecraftforge/server/ServerMain.java index 773de7f60..6501499a0 100644 --- a/src/fmllauncher/java/net/minecraftforge/server/ServerMain.java +++ b/src/fmllauncher/java/net/minecraftforge/server/ServerMain.java @@ -19,12 +19,49 @@ package net.minecraftforge.server; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + import com.google.common.collect.ObjectArrays; import cpw.mods.modlauncher.Launcher; public class ServerMain { - public static void main(String[] args) { - final String[] argArray = ObjectArrays.concat(new String[]{"--launchTarget", "fmlserver","--gameDir", "."}, args, String.class); + public static void main(String[] args) throws IOException { + final Properties props = new Properties(); + try(InputStream stream = ServerMain.class.getClassLoader().getResourceAsStream("server_launcher.properties")) { + if (stream == null) { + System.out.println("ERROR: could not load server_launcher.properties, invalid launcher jar, you must specify all arguments"); + return; + } + props.load(stream); + } + + boolean exit = false; + int lib_count = Integer.parseInt(props.getProperty("library.count")); + for (int x = 0; x < lib_count; x++) { + String lib = props.getProperty(String.format("library.%03d", x)); + if (lib == null) { + System.out.println("Invalid server launcher properties, missing library: " + x); + exit = true; + } else if (!new File(lib).exists()) { + System.out.println("Missing library: " + lib); + exit = true; + } + } + + if (exit) + return; + + String defaults = props.getProperty("args"); + if (defaults == null) { + System.out.println("Null default argumetns found, you must specify all arguments."); + return; + } + + System.out.println("Appending default arguments: " + defaults); + final String[] argArray = ObjectArrays.concat(defaults.split(" "), args, String.class); Launcher.main(argArray); } } diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 4bc5a95f0..2edfa2893 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -22,7 +22,6 @@ package net.minecraftforge.common; import net.minecraftforge.fml.FMLWorldPersistenceHook; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.WorldPersistenceHooks; -import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; import net.minecraftforge.fml.event.lifecycle.FMLModIdMappingEvent; @@ -30,9 +29,13 @@ import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import net.minecraftforge.fml.javafmlmod.FMLModLoadingContext; +import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.server.command.ForgeCommand; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; + +import java.nio.file.Path; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -49,6 +52,9 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.electronwill.nightconfig.core.io.WritingMode; + @Mod("forge") public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook { @@ -85,9 +91,27 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook MinecraftForge.EVENT_BUS.addListener(this::serverStarting); MinecraftForge.EVENT_BUS.addListener(this::playerLogin); MinecraftForge.EVENT_BUS.addListener(this::serverStopping); + /* FMLModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.spec); FMLModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ForgeConfig.chunk_spec); FMLModLoadingContext.get().getModEventBus().register(ForgeConfig.class); + */ + //Temporary, until I can talk to CPW about how certian types of config setups + loadConfig(ForgeConfig.spec, FMLPaths.CONFIGDIR.get().resolve("forge.toml")); + loadConfig(ForgeConfig.chunk_spec, FMLPaths.CONFIGDIR.get().resolve("forge_chunk.toml")); + } + + private void loadConfig(ForgeConfigSpec spec, Path path) { + LOGGER.debug(FORGEMOD, "Loading config file {}", path); + final CommentedFileConfig configData = CommentedFileConfig.builder(path) + .sync() + .autosave() + .writingMode(WritingMode.REPLACE) + .build(); + LOGGER.debug(FORGEMOD, "Built TOML config for {}", path.toString()); + configData.load(); + LOGGER.debug(FORGEMOD, "Loaded TOML config file {}", path.toString()); + spec.setConfig(configData); } /* diff --git a/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java b/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java index c75736c3c..2b79b57c6 100644 --- a/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java +++ b/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java @@ -3,7 +3,6 @@ package net.minecraftforge.fml.config; import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.FileWatcher; import com.electronwill.nightconfig.core.io.WritingMode; -import net.minecraftforge.fml.loading.FMLPaths; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/src/userdev/java/net/minecraftforge/userdev/FMLUserdevClientLaunchProvider.java b/src/userdev/java/net/minecraftforge/userdev/FMLUserdevClientLaunchProvider.java index 7d7441c7d..04937aab3 100644 --- a/src/userdev/java/net/minecraftforge/userdev/FMLUserdevClientLaunchProvider.java +++ b/src/userdev/java/net/minecraftforge/userdev/FMLUserdevClientLaunchProvider.java @@ -21,7 +21,10 @@ package net.minecraftforge.userdev; 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 net.minecraftforge.fml.loading.LibraryFinder; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -53,4 +56,11 @@ public class FMLUserdevClientLaunchProvider extends FMLUserdevLaunchProvider imp return null; }; } + + @Override + public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) + { + super.configureTransformationClassLoader(builder); + builder.addTransformationPath(LibraryFinder.findJarPathFor("com/mojang/realmsclient/RealmsVersion.class", "realms")); + } }