diff --git a/.gitignore b/.gitignore index 74683483cc..05b99b77fc 100644 --- a/.gitignore +++ b/.gitignore @@ -34,9 +34,9 @@ /projects/**/run/ /projects/**/*.launch /repo/ -src/generated/resources/.cache/ -src/generated_test/resources/.cache/ -src/generated_mdk/resources/.cache/ +src/generated/resources/**/.cache/ +src/generated_test/resources/**/.cache/ +src/generated_mdk/resources/**/.cache/ #Patch rejects #/patches-/ diff --git a/build.gradle b/build.gradle index 39b9888242..83ce5272d5 100644 --- a/build.gradle +++ b/build.gradle @@ -68,6 +68,7 @@ ext { SLF4J_API_VERSION = '1.8.0-beta4' APACHE_MAVEN_ARTIFACT_VERSION = '3.8.5' JARJAR_VERSION = '0.3.19' + JIMFS_VERSION = '1.3.0' // Google's InMemory File System. Used by ForgeDev Tests for now, but could be useful for a lot of things. // These versions should be kept in sync with the version manifest JSON // To use a version newer than the version manifest JSON, the dependency must be added to the installer configuration @@ -276,14 +277,17 @@ project(':clean') { } def sharedDeps = { - moduleonly "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}" - moduleonly "org.ow2.asm:asm:${ASM_VERSION}" - moduleonly "org.ow2.asm:asm-commons:${ASM_VERSION}" - moduleonly "org.ow2.asm:asm-tree:${ASM_VERSION}" - moduleonly "org.ow2.asm:asm-util:${ASM_VERSION}" - moduleonly "org.ow2.asm:asm-analysis:${ASM_VERSION}" - moduleonly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}" - moduleonly "net.minecraftforge:JarJarFileSystems:${JARJAR_VERSION}" + moduleonly("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}") + moduleonly("org.ow2.asm:asm:${ASM_VERSION}") + moduleonly("org.ow2.asm:asm-commons:${ASM_VERSION}") + moduleonly("org.ow2.asm:asm-tree:${ASM_VERSION}") + moduleonly("org.ow2.asm:asm-util:${ASM_VERSION}") + moduleonly("org.ow2.asm:asm-analysis:${ASM_VERSION}") + moduleonly("cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}") + moduleonly("net.minecraftforge:JarJarFileSystems:${JARJAR_VERSION}") + moduleonly("com.google.jimfs:jimfs:${JIMFS_VERSION}") { + transitive = false + } installer "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}" installer "org.ow2.asm:asm:${ASM_VERSION}" @@ -320,50 +324,6 @@ def sharedDeps = { } def sharedFmlonlyForge = { Project prj -> - ['Client', 'Server', 'Joined'].each { side -> - ['slim', 'extra'].each { type -> - prj.task([type: DownloadMavenArtifact], "download${side}${type.capitalize()}") { - artifact = "net.minecraft:${side.toLowerCase()}:${MC_VERSION}-${MCP_VERSION}:${type}" - } - } - - if (side.equals('Joined')) { - prj.task([type: DownloadMavenArtifact], "createJoinedSRG") { - artifact = "net.minecraft:joined:${MC_VERSION}-${MCP_VERSION}:srg" - } - } else { - prj.task([type: RenameJar, dependsOn: prj.tasks.createMcp2Srg], "create${side}SRG") { - tool = FART - args = [ - '--input', '{input}', - '--output', '{output}', - '--names', '{mappings}', - '--ann-fix', '--ids-fix', '--src-fix', '--record-fix' - ] - mappings = prj.tasks.createMcp2Srg.srg - input = prj.tasks.getByName("download${side}Slim").output - output = prj.file("build/create${side}SRG/output.jar") - } - } - - def gen = prj.tasks.getByName("gen${side}BinPatches") - def createSRG = prj.tasks.getByName("create${side}SRG") - gen.dependsOn(createSRG) - gen.tool = BINPATCH_TOOL - gen.cleanJar = createSRG.output - - prj.task([type: ApplyBinPatches, dependsOn: gen], "apply${side}BinPatches") { - clean = gen.cleanJar - patch = gen.output - tool = BINPATCH_TOOL - } - } - - prj.task([type: DownloadMavenArtifact], 'downloadInstaller') { - artifact = "net.minecraftforge:installer:${INSTALLER_VERSION}:shrunk" - changing = true - } - prj.afterEvaluate { [prj.tasks.universalJar, prj.tasks.installerJar].each { t -> def signTask = prj.task([type: SignJar, dependsOn: t], "sign${t.name.capitalize()}") { @@ -383,7 +343,6 @@ def sharedFmlonlyForge = { Project prj -> } prj.tasks.userdevConfig { - def launchPrefix = prj.name == "forge" ? "forge" : "fml" getArtifacts(prj, prj.configurations.installer, true).each { key, lib -> libraries.add(lib.name) } getArtifacts(prj, prj.configurations.moduleonly, true).each { key, lib -> libraries.add(lib.name) @@ -396,46 +355,28 @@ def sharedFmlonlyForge = { Project prj -> inject = '' // We don't have a userdev sourceset anymore. Empty as a gradle workaround... runs { client { - environment 'MOD_CLASSES', '{source_roots}' environment 'MCP_MAPPINGS', '{mcp_mappings}' - - // Natives are loaded from the classpath now in all cases - // property 'nativesDirectory', '{natives}' - if (prj.name == 'forge') { - property 'forge.enableGameTest', 'true' - } - - args '--launchTarget', "${launchPrefix}clientuserdev" + property 'forge.enableGameTest', 'true' + args '--launchTarget', "forge_userdev_client" args '--version', 'MOD_DEV' args '--assetIndex', '{asset_index}' args '--assetsDir', '{assets_root}' } server { - environment 'MOD_CLASSES', '{source_roots}' environment 'MCP_MAPPINGS', '{mcp_mappings}' - - if (prj.name == 'forge') { - property 'forge.enableGameTest', 'true' - } - - args '--launchTarget', "${launchPrefix}serveruserdev" + property 'forge.enableGameTest', 'true' + args '--launchTarget', "forge_userdev_server" } - if (prj.name == 'forge') { - gameTestServer { - environment 'MOD_CLASSES', '{source_roots}' - environment 'MCP_MAPPINGS', '{mcp_mappings}' - - args '--launchTarget', "${launchPrefix}gametestserveruserdev" - } - } + gameTestServer { + environment 'MCP_MAPPINGS', '{mcp_mappings}' + args '--launchTarget', "forge_userdev_server_gametest" + } data { - environment 'MOD_CLASSES', '{source_roots}' environment 'MCP_MAPPINGS', '{mcp_mappings}' - - args '--launchTarget', "${launchPrefix}datauserdev" + args '--launchTarget', "forge_userdev_data" args '--assetIndex', '{asset_index}' args '--assetsDir', '{assets_root}' } @@ -456,11 +397,7 @@ def sharedFmlonlyForge = { Project prj -> run.jvmArgs '-Djava.net.preferIPv6Addresses=system' - if (run.name.contains('client')) { - run.client true - } else { - run.client false - } + run.client run.name.contains('client') // SecureJarHandler bootstrap values. run.property 'ignoreList', prj.configurations.moduleonly.files.collect {it.name.replaceAll(/([-_]([.\d]*\d+)|\.jar$)/, '') }.join(',') + ",client-extra,fmlcore,javafmllanguage,lowcodelanguage,mclanguage,${prj.name}-" @@ -481,42 +418,29 @@ def sharedFmlonlyForge = { Project prj -> run.jvmArgs '--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming' } for (def run : prj.patcher.runs) { - if (run.parents) continue // We already added this to the parent run config + def isTest = run.name.endsWith('_test') + + run.taskName = run.name + run.environment 'FORGE_SPEC', prj.SPEC_VERSION + run.workingDirectory prj.file('run/' + run.name) + run.ideaModule rootProject.name + '.' + prj.name + '.' + (isTest ? 'test' : 'main') + + run.mods { + minecraft { source prj.sourceSets.main } + } + + if (isTest) { + run.property 'forge.enableGameTest', 'true' - if (run.name.contains('client') || run.name.contains('data')) { - // Natives are loaded from the classpath now in all cases - // run.property 'nativesDirectory', prj.extractNatives.output.get().asFile - run.args '--assetsDir', prj.downloadAssets.output - run.args '--assetIndex', "{asset_index}" - } - - if (run.name.contains('client')) { - run.property 'org.lwjgl.system.SharedLibraryExtractDirectory', 'lwjgl_dll' - run.args '--username', 'Dev' - run.args '--version', prj.name - //run.args '--uuid', '0' - run.args '--accessToken', '0' - run.args '--userType', 'mojang' - run.args '--versionType', 'release' - } - - if (prj.name == 'forge') { - run.environment 'FORGE_SPEC', prj.SPEC_VERSION - } - } - - eclipse.project.resourceFilter { - appliesTo = 'FOLDERS' - type = 'EXCLUDE_ALL' - matcher { - id = 'org.eclipse.ui.ide.multiFilter' - arguments = '1.0-name-matches-false-false-run' - } + run.mods { + tests { sources prj.sourceSets.test } + } + } } def MODULE_PATH = Util.getArtifacts(prj, prj.configurations.moduleonly, false).values().collect{"libraries/${it.downloads.artifact.path}"} def tokens = [ - TASK: prj.name.equals('forge') ? 'forgeserver' : 'fmlserver', + TASK: 'forge_server', MAVEN_PATH: prj.ext.MAVEN_PATH.toString(), FORGE_VERSION: FORGE_VERSION, MC_VERSION: MC_VERSION, @@ -560,8 +484,6 @@ def sharedFmlonlyForge = { Project prj -> exclude 'args.txt' filter(ReplaceTokens, tokens: tokens) into('data/') - //rename 'run.sh', "run_forge_${VERSION.replace('-', '_').sh" - //rename 'run.bat', "run_forge_${VERSION.replace('-', '_').bat" } } } @@ -609,10 +531,21 @@ project(':forge') { } } - eclipse.classpath.file.whenMerged { - // Disable optional warnings on the minecraft decompiled source code. It just muddies the warning window and hides warnings in our own codebase - def src = entries.find { it.path == 'src/main/java' } - src.entryAttributes['ignore_optional_problems'] = 'true' + eclipse { + classpath.file.whenMerged { + // Disable optional warnings on the minecraft decompiled source code. It just muddies the warning window and hides warnings in our own codebase + def src = entries.find { it.path == 'src/main/java' } + src.entryAttributes['ignore_optional_problems'] = 'true' + } + + project.resourceFilter { + appliesTo = 'FOLDERS' + type = 'EXCLUDE_ALL' + matcher { + id = 'org.eclipse.ui.ide.multiFilter' + arguments = '1.0-name-matches-false-false-run' + } + } } ext { @@ -661,160 +594,64 @@ project(':forge') { runs { forge_client { - workingDirectory file('run/client') property 'eventbus.checkTypesOnDispatch', 'true' - args '--launchTarget', 'forgeclientdev' - ideaModule "${rootProject.name}.${project.name}.main" - mods { - minecraft { source sourceSets.main } - } + property 'org.lwjgl.system.SharedLibraryExtractDirectory', 'lwjgl_dll' + + args '--launchTarget', 'forge_dev_client', + '--username', 'Dev', + '--version', project.name, + '--accessToken', '0', + '--userType', 'mojang', + '--versionType', 'release', + '--assetsDir', downloadAssets.output, + '--assetIndex', "{asset_index}" } - forge_test_client { - workingDirectory file('run/client_test') + forge_client_test { parent runs.forge_client - taskName 'forge_test_client' - - property 'forge.enableGameTest', 'true' - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.test" - - mods { - tests { sources sourceSets.test } - } } forge_server { - workingDirectory file('run/server') - args '--launchTarget', 'forgeserverdev' - ideaModule "${rootProject.name}.${project.name}.main" - - mods { - minecraft { source sourceSets.main } - } + args '--launchTarget', 'forge_dev_server' } - forge_test_server { - workingDirectory file('run/server_test') + forge_server_test { parent runs.forge_server - taskName 'forge_test_server' - - property 'forge.enableGameTest', 'true' - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.test" - - mods { - tests { sources sourceSets.test } - } } - forge_gameTestServer { - taskName 'forge_gameTestServer' - args '--launchTarget', 'forgegametestserverdev' - ideaModule "${rootProject.name}.${project.name}.main" - - mods { - minecraft { source sourceSets.main } - } + forge_server_gametest { + args '--launchTarget', 'forge_dev_server_gametest' } - forge_test_gameTestServer { - parent runs.forge_gameTestServer - taskName 'forge_test_gameTestServer' - - ideaModule "${rootProject.name}.${project.name}.test" - - mods { - tests { sources sourceSets.test } - } + forge_server_gametest_test { + parent runs.forge_server_gametest } - def forgeDataArgs = [ - '--mod', 'forge', - '--all', - '--output', rootProject.file('src/generated/resources/'), - '--validate', - '--existing', sourceSets.main.resources.srcDirs[0] - ] forge_data { - taskName 'forge_data' - args '--launchTarget', 'forgedatadev' - ideaModule "${rootProject.name}.${project.name}.main" - - mods { - minecraft { source sourceSets.main } - } - - args forgeDataArgs + args '--launchTarget', 'forge_dev_data', + '--mod', 'forge', + '--all', + '--validate', + '--output', rootProject.file('src/generated/resources/'), + '--validate', + '--existing', sourceSets.main.resources.srcDirs[0], + '--assetsDir', downloadAssets.output, + '--assetIndex', "{asset_index}" } - forge_test_data { - parent runs.forge_data - taskName 'forge_test_data' - - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.test" - - mods { - tests { sources sourceSets.test } - } - - afterEvaluate { - // Clear forge's main datagen args - args.removeAll { - forgeDataArgs.contains(it instanceof File ? (it as File).absolutePath : it.toString()) - } - - args '--flat', '--all', '--validate', - '--mod', 'empty', - //'--mod', 'data_gen_test', - //'--mod', 'piston_event_test', - '--mod', 'global_loot_test', - //'--mod', 'scaffolding_test', - //'--mod', 'custom_tag_types_test', - //'--mod', 'new_model_loader_test', - //'--mod', 'remove_tag_datagen_test', - //'--mod', 'tag_based_tool_types', - //'--mod', 'custom_transformtype_test', - //'--mod', 'data_pack_registries_test', - //'--mod', 'biome_modifiers_test', - //'--mod', 'structure_modifiers_test', - //'--mod', 'custom_preset_editor_test', - '--output', rootProject.file('src/generated_test/resources/'), - '--existing', sourceSets.main.resources.srcDirs[0], - '--existing', sourceSets.test.resources.srcDirs[0] - } + forge_data_test { + args '--launchTarget', 'forge_dev_data', + '--mod', '.+', + '--all', + '--validate', + '--output', rootProject.file('src/generated_test/resources/'), + '--existing', sourceSets.main.resources.srcDirs[0], + '--existing', sourceSets.test.resources.srcDirs[0], + '--assetsDir', downloadAssets.output, + '--assetIndex', "{asset_index}" } - forge_mdk_data { - parent runs.forge_data - taskName 'forge_mdk_data' - - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.test" - - mods { - tests { sources sourceSets.test } - } - - afterEvaluate { - // Clear forge's main datagen args - args.removeAll { - forgeDataArgs.contains(it instanceof File ? (it as File).absolutePath : it.toString()) - } - - args '--flat', '--all', '--validate', - '--mod', 'mdk_datagen', - '--output', rootProject.file('src/generated_mdk/resources/'), - '--existing', sourceSets.main.resources.srcDirs[0], - '--existing', sourceSets.test.resources.srcDirs[0] - } - } - } + } } afterEvaluate { @@ -847,7 +684,6 @@ project(':forge') { ext { MANIFESTS = [ '/': [ - 'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), 'GitCommit': gradleutils.gitInfo.abbreviatedId, 'Git-Branch': gradleutils.gitInfo.branch, 'FML-System-Mods': 'forge' @@ -914,7 +750,7 @@ project(':forge') { libraries.addAll downloadLibraries.librariesOutput.map { rf -> Files.readAllLines(rf.asFile.toPath()).stream().map(File::new).collect(java.util.stream.Collectors.toList()) } } - task findFieldInstanceChecks(type: FieldCompareFinder, dependsOn: ['createJoinedSRG']) { + tasks.register("findFieldInstanceChecks", FieldCompareFinder) { jar = createJoinedSRG.output output = rootProject.file('src/main/resources/coremods/field_to_instanceof.json') fields { @@ -933,7 +769,7 @@ project(':forge') { } } - task findFinalizeSpawnTargets(type: BytecodePredicateFinder, dependsOn: ['createJoinedSRG']) { + tasks.register("findFinalizeSpawnTargets", BytecodePredicateFinder) { jar = createJoinedSRG.output output = rootProject.file('src/main/resources/coremods/finalize_spawn_targets.json') predicate = { @@ -952,6 +788,74 @@ project(':forge') { tasks.jar.finalizedBy 'validateDeprecations' + tasks.register("downloadInstaller", DownloadMavenArtifact) { + artifact = "net.minecraftforge:installer:${INSTALLER_VERSION}:shrunk" + changing = true + } + tasks.register("downloadClientSlim", DownloadMavenArtifact) { + artifact = "net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:slim" + } + tasks.register("downloadClientExtra", DownloadMavenArtifact) { + artifact = "net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:extra" + } + tasks.register("downloadServerSlim", DownloadMavenArtifact) { + artifact = "net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim" + } + tasks.register("downloadServerExtra", DownloadMavenArtifact) { + artifact = "net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:extra" + } + tasks.register("downloadJoinedSlim", DownloadMavenArtifact) { + artifact = "net.minecraft:joined:${MC_VERSION}-${MCP_VERSION}:slim" + } + tasks.register("downloadJoinedExtra", DownloadMavenArtifact) { + artifact = "net.minecraft:joined:${MC_VERSION}-${MCP_VERSION}:extra" + } + tasks.register("createJoinedSRG", DownloadMavenArtifact) { + artifact = "net.minecraft:joined:${MC_VERSION}-${MCP_VERSION}:srg" + } + tasks.register("createClientSRG", RenameJar) { + tool = FART + args = ['--input', '{input}', '--output', '{output}', '--names', '{mappings}', '--ann-fix', '--ids-fix', '--src-fix', '--record-fix'] + mappings = createMcp2Srg.srg + input = downloadClientSlim.output + output = file("build/createClientSRG/output.jar") + } + tasks.register("createServerSRG", RenameJar) { + tool = FART + args = ['--input', '{input}', '--output', '{output}', '--names', '{mappings}', '--ann-fix', '--ids-fix', '--src-fix', '--record-fix'] + mappings = createMcp2Srg.srg + input = downloadServerSlim.output + output = file("build/createServerSRG/output.jar") + } + genClientBinPatches { + tool = BINPATCH_TOOL + cleanJar = createClientSRG.output + } + genServerBinPatches { + tool = BINPATCH_TOOL + cleanJar = createServerSRG.output + } + genJoinedBinPatches { + tool = BINPATCH_TOOL + cleanJar = createJoinedSRG.output + } + tasks.register("applyClientBinPatches", ApplyBinPatches) { + tool = BINPATCH_TOOL + clean = genClientBinPatches.cleanJar + patch = genClientBinPatches.output + } + tasks.register("applyServerBinPatches", ApplyBinPatches) { + tool = BINPATCH_TOOL + clean = genServerBinPatches.cleanJar + patch = genServerBinPatches.output + } + tasks.register("applyJoinedBinPatches", ApplyBinPatches) { + tool = BINPATCH_TOOL + clean = genJoinedBinPatches.cleanJar + patch = genJoinedBinPatches.output + } + + tasks.register('checkAll') { dependsOn 'checkLicenses' group = 'checks' @@ -1065,7 +969,7 @@ project(':forge') { inheritsFrom: MC_VERSION, logging: {}, arguments: [ - game: ['--launchTarget', 'forgeclient', + game: ['--launchTarget', 'forge_client', '--fml.forgeVersion', FORGE_VERSION, '--fml.mcVersion', MC_VERSION, '--fml.forgeGroup', project.group, @@ -1369,7 +1273,7 @@ project(':forge') { rename 'gitignore\\.txt', '.gitignore' rename 'gitattributes\\.txt', '.gitattributes' } - from(rootProject.file('src/generated_mdk/resources/')) { + from(rootProject.file('src/generated_test/resources/mdk_datagen/')) { into('src/main/resources/') exclude '**/.cache/' } diff --git a/fmlloader/build.gradle b/fmlloader/build.gradle index 7d29c81b72..ffacc03c0a 100644 --- a/fmlloader/build.gradle +++ b/fmlloader/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}") implementation("net.minecraftforge:accesstransformers:${ACCESSTRANSFORMERS_VERSION}") implementation("net.minecrell:terminalconsoleappender:${TERMINALCONSOLEAPPENDER_VERSION}") + implementation("com.google.jimfs:jimfs:${JIMFS_VERSION}") // implementation("org.jline:jline:${JLINE_VERSION}") implementation("org.apache.logging.log4j:log4j-core:${LOG4J_VERSION}") diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java index 1337ec2f46..517adc0631 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java @@ -56,6 +56,7 @@ public class ObjectHolderDefinalize implements ILaunchPluginService { return lst != null && lst.stream().anyMatch(n -> n.desc.equals(OBJECT_HOLDER)); } + @SuppressWarnings("unused") private String getValue(List lst) { AnnotationNode ann = lst.stream().filter(n -> n.desc.equals(OBJECT_HOLDER)).findFirst().get(); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java index f92012eca7..32bc948558 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java @@ -20,8 +20,6 @@ import org.objectweb.asm.tree.MethodNode; import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; import org.slf4j.Logger; -import org.slf4j.Marker; -import org.slf4j.MarkerFactory; /** * Modifies specified enums to allow runtime extension by making the $VALUES field non-final and diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/BackgroundWaiter.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/BackgroundWaiter.java index cac3c4f5c2..3be9974cd6 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/BackgroundWaiter.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/BackgroundWaiter.java @@ -5,8 +5,6 @@ package net.minecraftforge.fml.loading; -import net.minecraftforge.fml.loading.progress.StartupNotificationManager; - import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/EarlyLoadingException.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/EarlyLoadingException.java index 371fe9e44b..ec2cfe5c72 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/EarlyLoadingException.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/EarlyLoadingException.java @@ -14,6 +14,8 @@ import java.util.List; * or server. */ public class EarlyLoadingException extends RuntimeException { + private static final long serialVersionUID = 2302192216172508006L; + public static class ExceptionData { private final IModInfo modInfo; private final String i18message; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java index 88ed60233e..2c8b7a8735 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java @@ -42,7 +42,6 @@ public class FMLConfig private final String entry; private final Object defaultValue; private final String comment; - private final Class valueType; private final Function entryFunction; ConfigValue(final String entry, final Object defaultValue, final String comment) { @@ -52,7 +51,6 @@ public class FMLConfig this.entry = entry; this.defaultValue = defaultValue; this.comment = comment; - this.valueType = defaultValue.getClass(); this.entryFunction = entryFunction; } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java index 721b9a18f8..d5f7c79430 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java @@ -16,7 +16,6 @@ import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModValidator; import net.minecraftforge.accesstransformer.service.AccessTransformerService; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.loading.progress.StartupNotificationManager; import net.minecraftforge.fml.loading.targets.CommonLaunchHandler; import net.minecraftforge.forgespi.Environment; import net.minecraftforge.forgespi.coremod.ICoreModProvider; @@ -137,6 +136,7 @@ public class FMLLoader throw new RuntimeException("Missing launch handler: " + launchTarget); } + // TODO: What the fuck is the point of using a service if you require a specific concrete class if (!(launchHandler.get() instanceof CommonLaunchHandler)) { LOGGER.error(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName()); throw new RuntimeException("Incompatible launch handler found"); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java index e8647f17f5..d297620d8e 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java @@ -126,6 +126,7 @@ public class FMLServiceProvider implements ITransformationService targetMcpMappings = option.value(mappingsOption); } + @SuppressWarnings("rawtypes") @Override public @NotNull List transformers() { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FileUtils.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FileUtils.java deleted file mode 100644 index 570d8d3789..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FileUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading; - -import java.io.File; -import java.nio.file.Path; - -public class FileUtils -{ - - public static String fileExtension(final Path path) { - String fileName = path.getFileName().toString(); - int idx = fileName.lastIndexOf('.'); - if (idx > -1) { - return fileName.substring(idx+1); - } else { - return ""; - } - } - - public static boolean matchFileName(String path, String... matches) { - // Extract file name from path - String name = path.substring(Math.min(path.lastIndexOf(File.separatorChar) + 1, path.length())); - // Check if it contains any of the desired keywords - for (String match : matches) { - if (name.contains(match)) { - return true; - } - } - return false; - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java index 491b240cce..b3f0c8e5eb 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java @@ -11,6 +11,7 @@ import java.util.Optional; * Finds Version data from a package, with possible default values */ public class JarVersionLookupHandler { + public static Optional getImplementationVersion(final String pkgName) { // Note that with Java 9, you'll probably want the module's version data, hence pulling this out final String pkgVersion = Package.getPackage(pkgName).getImplementationVersion(); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java index e1663a1ea0..edaf98a2bd 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java @@ -9,7 +9,6 @@ import com.mojang.logging.LogUtils; import cpw.mods.modlauncher.Launcher; import cpw.mods.modlauncher.api.IModuleLayerManager; import cpw.mods.modlauncher.util.ServiceLoaderUtils; -import net.minecraftforge.fml.loading.progress.StartupNotificationManager; import net.minecraftforge.forgespi.language.IModLanguageProvider; import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator; import net.minecraftforge.fml.loading.moddiscovery.ModFile; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java index 9609f85638..072ab5d44c 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java @@ -7,7 +7,6 @@ package net.minecraftforge.fml.loading; import com.mojang.logging.LogUtils; import cpw.mods.jarhandling.SecureJar; -import cpw.mods.modlauncher.Launcher; import cpw.mods.modlauncher.api.LamdbaExceptionUtils; import cpw.mods.modlauncher.api.NamedPath; import cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService; @@ -19,8 +18,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.ServiceLoader; -import java.util.zip.ZipFile; import java.util.Set; public class ModDirTransformerDiscoverer implements ITransformerDiscoveryService { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModJarURLHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModJarURLHandler.java deleted file mode 100644 index 19b8220b7e..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModJarURLHandler.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading; - -import com.mojang.logging.LogUtils; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; -import org.slf4j.Logger; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; -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 = LogUtils.getLogger(); - // modjar://modid/path/to/file - @Override - protected URLConnection openConnection(URL url) { - return new ModJarURLConnection(url); - } - - @Override - protected int hashCode(final URL u) { - return Objects.hash(u.getHost(), u.getFile()); - } - - @Override - protected boolean equals(final URL u1, final URL u2) { - return Objects.equals(u1.getProtocol(), u2.getProtocol()) - && Objects.equals(u1.getHost(), u2.getHost()) - && Objects.equals(u1.getFile(), u2.getFile()); - } - - static class ModJarURLConnection extends URLConnection { - private Path resource; - private String modpath; - private String modid; - private Optional 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 - { - 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.size(resource); - } catch (IOException e) { - return -1L; - } - } - - // Used to cache protectiondomains by "top level object" aka the modid - @Override - public URL getURL() { - return LamdbaExceptionUtils.uncheck(()->new URL("modjar://"+modid)); - } - - public Optional getManifest() { - return manifest; - } - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java index ea9e1b35b7..bd40d36555 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java @@ -10,7 +10,6 @@ import com.google.common.graph.MutableGraph; import com.mojang.logging.LogUtils; import cpw.mods.jarhandling.SecureJar; import net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator; -import net.minecraftforge.forgespi.language.IModFileInfo; import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.fml.loading.EarlyLoadingException.ExceptionData; import net.minecraftforge.fml.loading.moddiscovery.ModFile; @@ -72,7 +71,6 @@ public class ModSorter } } - @SuppressWarnings("UnstableApiUsage") private void sort() { // lambdas are identity based, so sorting them is impossible unless you hold reference to them @@ -121,7 +119,6 @@ public class ModSorter .collect(toList()); } - @SuppressWarnings("UnstableApiUsage") private void addDependency(MutableGraph topoGraph, IModInfo.ModVersion dep) { final ModFileInfo self = (ModFileInfo)dep.getOwner().getOwningFile(); @@ -133,6 +130,7 @@ public class ModSorter switch (dep.getOrdering()) { case BEFORE -> topoGraph.putEdge(self, target); case AFTER -> topoGraph.putEdge(target, self); + default -> {} } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java index 12fecc540b..c3c855b1e2 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java @@ -27,8 +27,7 @@ import java.util.Optional; import java.util.function.Function; import java.util.jar.Manifest; -public abstract class AbstractModProvider implements IModProvider -{ +public abstract class AbstractModProvider implements IModProvider { private static final Logger LOGGER = LogUtils.getLogger(); protected static final String MODS_TOML = "META-INF/mods.toml"; protected static final String MANIFEST = "META-INF/MANIFEST.MF"; @@ -36,25 +35,24 @@ public abstract class AbstractModProvider implements IModProvider protected IModLocator.ModFileOrException createMod(Path... path) { var mjm = new ModJarMetadata(); var sj = SecureJar.from( - Manifest::new, - jar -> jar.moduleDataProvider().findFile(MODS_TOML).isPresent() ? mjm : JarMetadata.from(jar, path), - path + Manifest::new, + jar -> jar.moduleDataProvider().findFile(MODS_TOML).isPresent() ? mjm : JarMetadata.from(jar, path), + path ); IModFile mod; var type = sj.moduleDataProvider().getManifest().getMainAttributes().getValue(ModFile.TYPE); - if (type == null) { + if (type == null) type = getDefaultJarModType(); - } + if (sj.moduleDataProvider().findFile(MODS_TOML).isPresent()) { LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MODS_TOML, type, path); mod = new ModFile(sj, this, ModFileParser::modsTomlParser); } else if (type != null) { LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MANIFEST, type, path); mod = new ModFile(sj, this, this::manifestParser, type); - } else { - return new IModLocator.ModFileOrException(null, new ModFileLoadingException("Invalid mod file found "+ Arrays.toString(path))); - } + } else + return new IModLocator.ModFileOrException(null, new ModFileLoadingException("Invalid mod file found " + Arrays.toString(path))); mjm.setModFile(mod); return new IModLocator.ModFileOrException(mod, null); @@ -87,36 +85,19 @@ public abstract class AbstractModProvider implements IModProvider } private record DefaultModFileInfo(IModFile mod, String license, IConfigurable configurable) implements IModFileInfo, IConfigurable { - @Override - public Optional getConfigElement(final String... strings) - { - return Optional.empty(); - } - - @Override - public List getConfigList(final String... strings) - { - return null; - } - + @Override public Optional getConfigElement(final String... strings) { return Optional.empty(); } + @Override public List getConfigList(final String... strings) { return null; } @Override public List getMods() { return Collections.emptyList(); } @Override public List requiredLanguageLoaders() { return Collections.emptyList(); } @Override public boolean showAsResourcePack() { return false; } @Override public Map getFileProperties() { return Collections.emptyMap(); } - @Override - public String getLicense() { return license; } - + @Override public String getLicense() { return license; } @Override public IModFile getFile() { return mod; } @Override public IConfigurable getConfig() { return configurable; } - // These Should never be called as it's only called from ModJarMetadata.version and we bypass that @Override public String moduleName() { return mod.getSecureJar().name(); } @Override public String versionString() { return null; } @Override public List usesServices() { return null; } - - @Override - public String toString() { - return "IModFileInfo(" + mod.getFilePath() + ")"; - } + @Override public String toString() { return "IModFileInfo(" + mod.getFilePath() + ")"; } } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java index 0a8f482ced..347d8d639d 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java @@ -12,12 +12,9 @@ import org.slf4j.Logger; import java.io.File; import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; @@ -25,8 +22,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Stream; -public class ClasspathLocator extends AbstractJarFileModLocator -{ +public class ClasspathLocator extends AbstractJarFileModLocator { private static final Logger LOGGER = LogUtils.getLogger(); private final List legacyClasspath = Arrays.stream(System.getProperty("legacyClassPath", "").split(File.pathSeparator)).map(Path::of).toList(); private boolean enabled = false; @@ -73,22 +69,4 @@ public class ClasspathLocator extends AbstractJarFileModLocator var launchTarget = (String) arguments.get("launchTarget"); enabled = launchTarget != null && launchTarget.contains("dev"); } - - private Path findJarPathFor(final String resourceName, final String jarName, final URL resource) { - try { - Path path; - final URI uri = resource.toURI(); - if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) { - int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/"); - path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl))); - } else { - path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length()))); - } - //LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString()); - return path; - } catch (NullPointerException | URISyntaxException e) { - LOGGER.error(LogMarkers.SCAN, "Failed to find JAR for class {} - {}", resourceName, jarName); - throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e); - } - } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModFileException.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModFileException.java index 1177e18972..8e57e3729e 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModFileException.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/InvalidModFileException.java @@ -11,12 +11,11 @@ import net.minecraftforge.forgespi.locating.ModFileLoadingException; import java.util.Locale; import java.util.Optional; -public class InvalidModFileException extends ModFileLoadingException -{ +public class InvalidModFileException extends ModFileLoadingException { + private static final long serialVersionUID = 1230464325917450374L; private final IModFileInfo modFileInfo; - public InvalidModFileException(String message, IModFileInfo modFileInfo) - { + public InvalidModFileException(String message, IModFileInfo modFileInfo) { super(String.format(Locale.ROOT, "%s (%s)", message, Optional.ofNullable(modFileInfo).map(mf->mf.getFile().getFileName()).orElse("MISSING FILE NAME"))); this.modFileInfo = modFileInfo; } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModAnnotationVisitor.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModAnnotationVisitor.java index d48dd65df3..8fd1fd3e34 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModAnnotationVisitor.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModAnnotationVisitor.java @@ -10,72 +10,58 @@ import org.objectweb.asm.Opcodes; import java.util.LinkedList; -public class ModAnnotationVisitor extends AnnotationVisitor -{ +public class ModAnnotationVisitor extends AnnotationVisitor { private final ModAnnotation annotation; private LinkedList annotations; private boolean array; - private String name; private boolean isSubAnnotation; - public ModAnnotationVisitor(LinkedList annotations, ModAnnotation annotation) - { + public ModAnnotationVisitor(LinkedList annotations, ModAnnotation annotation) { super(Opcodes.ASM9); this.annotations = annotations; this.annotation = annotation; } - public ModAnnotationVisitor(LinkedList annotations, ModAnnotation annotation, String name) - { + public ModAnnotationVisitor(LinkedList annotations, ModAnnotation annotation, String name) { this(annotations, annotation); this.array = true; - this.name = name; annotation.addArray(name); } - public ModAnnotationVisitor(LinkedList annotations, ModAnnotation annotation, boolean isSubAnnotation) - { + public ModAnnotationVisitor(LinkedList annotations, ModAnnotation annotation, boolean isSubAnnotation) { this(annotations, annotation); this.isSubAnnotation = true; } @Override - public void visit(String key, Object value) - { + public void visit(String key, Object value) { annotation.addProperty(key, value); } @Override - public void visitEnum(String name, String desc, String value) - { + public void visitEnum(String name, String desc, String value) { annotation.addEnumProperty(name, desc, value); } @Override - public AnnotationVisitor visitArray(String name) - { + public AnnotationVisitor visitArray(String name) { return new ModAnnotationVisitor(annotations, annotation, name); } + @Override - public AnnotationVisitor visitAnnotation(String name, String desc) - { - ModAnnotation ma = annotations.getFirst(); - final ModAnnotation childAnnotation = ma.addChildAnnotation(name, desc); + public AnnotationVisitor visitAnnotation(String name, String desc) { + var ma = annotations.getFirst(); + var childAnnotation = ma.addChildAnnotation(name, desc); annotations.addFirst(childAnnotation); - return new ModAnnotationVisitor(annotations, childAnnotation,true); + return new ModAnnotationVisitor(annotations, childAnnotation, true); } + @Override - public void visitEnd() - { + public void visitEnd() { if (array) - { annotation.endArray(); - } if (isSubAnnotation) - { - ModAnnotation child = annotations.removeFirst(); - annotations.addLast(child); - } + annotations.addLast(annotations.removeFirst()); } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java index f95c4dedb1..164add39ab 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java @@ -10,7 +10,6 @@ import com.mojang.logging.LogUtils; import cpw.mods.jarhandling.SecureJar; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.LogMarkers; -import net.minecraftforge.fml.loading.progress.StartupNotificationManager; import net.minecraftforge.forgespi.language.IModFileInfo; import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.forgespi.language.IModLanguageProvider; @@ -207,8 +206,11 @@ public class ModFile implements IModFile { this.securityStatus = status; } - public ArtifactVersion getJarVersion() - { + public SecureJar.Status getSecurityStatus() { + return this.securityStatus; + } + + public ArtifactVersion getJarVersion() { return new DefaultArtifactVersion(this.jarVersion); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java index 9d519b5aaa..9cac458341 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java @@ -22,7 +22,6 @@ import java.nio.file.Path; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class ModFileParser { private static final Logger LOGGER = LogUtils.getLogger(); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModListHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModListHandler.java index a9b4a9233d..471d1fb6aa 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModListHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModListHandler.java @@ -7,7 +7,6 @@ package net.minecraftforge.fml.loading.moddiscovery; import com.mojang.logging.LogUtils; import net.minecraftforge.fml.loading.FMLPaths; -import net.minecraftforge.fml.loading.FileUtils; import net.minecraftforge.fml.loading.LogMarkers; import net.minecraftforge.fml.loading.MavenCoordinateResolver; import org.apache.commons.lang3.tuple.Pair; @@ -63,7 +62,7 @@ public class ModListHandler { return Collections.emptyList(); } - String extension = FileUtils.fileExtension(filePath); + String extension = fileExtension(filePath); if (Objects.equals("list",extension)) { return readListFile(filePath).stream().filter(s -> !s.isEmpty()).collect(Collectors.toList()); } else { @@ -72,6 +71,12 @@ public class ModListHandler { return Collections.emptyList(); } + private static String fileExtension(final Path path) { + String fileName = path.getFileName().toString(); + int idx = fileName.lastIndexOf('.'); + return idx > -1 ? fileName.substring(idx+1) : ""; + } + /** * Simple list file, ending in ".list" with one mod coordinate per line * @param filePath path diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java index 08e3275b58..2483ac4397 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java @@ -9,7 +9,6 @@ import com.mojang.logging.LogUtils; import cpw.mods.modlauncher.api.IModuleLayerManager; import cpw.mods.modlauncher.api.ITransformationService; import net.minecraftforge.fml.loading.*; -import net.minecraftforge.fml.loading.progress.StartupNotificationManager; import net.minecraftforge.forgespi.language.IModFileInfo; import net.minecraftforge.forgespi.locating.IModFile; import org.jetbrains.annotations.NotNull; @@ -23,7 +22,7 @@ import java.util.stream.Collectors; public class ModValidator { private static final Logger LOGGER = LogUtils.getLogger(); - private final Map> modFiles; + //private final Map> modFiles; private final List candidatePlugins; private final List candidateMods; private LoadingModList loadingModList; @@ -31,7 +30,7 @@ public class ModValidator { private final List discoveryErrorData; public ModValidator(final Map> modFiles, final List brokenFiles, final List discoveryErrorData) { - this.modFiles = modFiles; + //this.modFiles = modFiles; this.candidateMods = lst(modFiles.get(IModFile.Type.MOD)); this.candidateMods.addAll(lst(modFiles.get(IModFile.Type.GAMELIBRARY))); this.candidatePlugins = lst(modFiles.get(IModFile.Type.LANGPROVIDER)); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/progress/StartupNotificationManager.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/progress/StartupNotificationManager.java index 56b26f739d..2e714d5ed1 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/progress/StartupNotificationManager.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/progress/StartupNotificationManager.java @@ -10,8 +10,6 @@ import com.google.common.base.CharMatcher; import java.util.*; import java.util.function.Consumer; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; public class StartupNotificationManager { private static volatile EnumMap> messages = new EnumMap<>(Message.MessageType.class); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java index 69ce04db9e..cf17ddf779 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java @@ -6,6 +6,8 @@ package net.minecraftforge.fml.loading.targets; import com.mojang.logging.LogUtils; + +import org.jetbrains.annotations.ApiStatus; import org.slf4j.Logger; import java.util.ArrayList; @@ -19,6 +21,7 @@ import java.util.function.Supplier; * A class that attempts to parse command line arguments into key value pairs to allow addition and editing. * Can not use JOptSimple as that doesn't parse out the values for keys unless the spec says it has a value. */ +@ApiStatus.Internal class ArgumentList { private static final Logger LOGGER = LogUtils.getLogger(); private List> entries = new ArrayList<>(); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonClientLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonClientLaunchHandler.java deleted file mode 100644 index 6225f4df06..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonClientLaunchHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import cpw.mods.modlauncher.api.ServiceRunner; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.LibraryFinder; -import net.minecraftforge.fml.loading.VersionInfo; -import net.minecraftforge.api.distmarker.Dist; - -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Stream; - -public abstract class CommonClientLaunchHandler extends CommonLaunchHandler { - @Override public Dist getDist() { return Dist.CLIENT; } - @Override public String getNaming() { return "srg"; } - @Override public boolean isProduction() { return true; } - - @Override - protected ServiceRunner makeService(final String[] arguments, final ModuleLayer gameLayer) { - return ()->clientService(arguments, gameLayer); - } - - @Override - public LocatedPaths getMinecraftPaths() { - final var vers = FMLLoader.versionInfo(); - var mc = LibraryFinder.findPathForMaven("net.minecraft", "client", "", "srg", vers.mcAndMCPVersion()); - var mcextra = LibraryFinder.findPathForMaven("net.minecraft", "client", "", "extra", vers.mcAndMCPVersion()); - var mcstream = Stream.builder().add(mc).add(mcextra); - var modstream = Stream.>builder(); - - processMCStream(vers, mcstream, modstream); - - var fmlcore = LibraryFinder.findPathForMaven(vers.forgeGroup(), "fmlcore", "", "", vers.mcAndForgeVersion()); - var javafmllang = LibraryFinder.findPathForMaven(vers.forgeGroup(), "javafmllanguage", "", "", vers.mcAndForgeVersion()); - var lowcodelang = LibraryFinder.findPathForMaven(vers.forgeGroup(), "lowcodelanguage", "", "", vers.mcAndForgeVersion()); - var mclang = LibraryFinder.findPathForMaven(vers.forgeGroup(), "mclanguage", "", "", vers.mcAndForgeVersion()); - - return new LocatedPaths(mcstream.build().toList(), null, modstream.build().toList(), List.of(fmlcore, javafmllang, lowcodelang, mclang)); - } - - protected abstract void processMCStream(VersionInfo versionInfo, Stream.Builder mc, Stream.Builder> mods); -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java index 5a8ba6d897..19e586ed3b 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java @@ -7,46 +7,30 @@ package net.minecraftforge.fml.loading.targets; import cpw.mods.jarhandling.SecureJar; import cpw.mods.modlauncher.api.ServiceRunner; -import net.minecraftforge.fml.loading.FileUtils; - +import net.minecraftforge.fml.loading.LogMarkers; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.Objects; +import java.util.Map; +import java.util.Optional; import java.util.function.BiPredicate; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Stream; -public abstract class CommonDevLaunchHandler extends CommonLaunchHandler { +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +abstract class CommonDevLaunchHandler extends CommonLaunchHandler { + protected CommonDevLaunchHandler(LaunchType type, String prefix) { + super(type, prefix); + } + @Override public String getNaming() { return "mcp"; } @Override public boolean isProduction() { return false; } - @Override - public LocatedPaths getMinecraftPaths() { - // Minecraft is extra jar {resources} + our exploded directories in dev - final var mcstream = Stream.builder(); - - // The extra jar is on the classpath, so try and pull it out of the legacy classpath - var legacyCP = Objects.requireNonNull(System.getProperty("legacyClassPath"), "Missing legacyClassPath, cannot find client-extra").split(File.pathSeparator); - var extra = findJarOnClasspath(legacyCP, "client-extra"); - - // The MC code/Patcher edits are in exploded directories - final var modstream = Stream.>builder(); - final var mods = getModClasses(); - final var minecraft = mods.remove("minecraft"); - if (minecraft == null) - throw new IllegalStateException("Could not find 'minecraft' mod paths."); - minecraft.stream().distinct().forEach(mcstream::add); - mods.values().forEach(modstream::add); - - mcstream.add(extra); - var mcFilter = getMcFilter(extra, minecraft, modstream); - return new LocatedPaths(mcstream.build().toList(), mcFilter, modstream.build().toList(), getFmlStuff(legacyCP)); - } - @Override protected String[] preLaunch(String[] arguments, ModuleLayer layer) { super.preLaunch(arguments, layer); @@ -79,34 +63,34 @@ public abstract class CommonDevLaunchHandler extends CommonLaunchHandler { return args.getArguments(); } - protected List getFmlStuff(String[] classpath) { - // We also want the FML things, fmlcore, javafmllanguage, mclanguage, I don't like hard coding these, but hey whatever works for now. - return Arrays.stream(classpath) - .filter(e -> FileUtils.matchFileName(e, "fmlcore", "javafmllanguage", "lowcodelanguage", "mclanguage")) - .map(Paths::get) - .toList(); + protected List getLibraries(String[] classpath) { + // TODO: These should all be FMLModType: LIBRARY, find them that way? + // Or at the very least include version info + var fmlcore = findJarOnClasspath(classpath, "fmlcore"); + var javafmllang = findJarOnClasspath(classpath, "javafmllanguage"); + var lowcodelang = findJarOnClasspath(classpath, "lowcodelanguage"); + var mclang = findJarOnClasspath(classpath, "mclanguage"); + return List.of(fmlcore, javafmllang, lowcodelang, mclang); } - protected static Path findJarOnClasspath(String[] classpath, String match) { - return Paths.get(Arrays.stream(classpath) - .filter(e -> FileUtils.matchFileName(e, match)) - .findFirst() - .orElseThrow(() -> new IllegalStateException("Could not find " + match + " in classpath"))); - } - - protected BiPredicate getMcFilter(Path extra, List minecraft, Stream.Builder> mods) { - final var packages = getPackages(); - final var extraPath = extra.toString().replace('\\', '/'); + protected BiPredicate getMcFilter(Path extra, List minecraft) { + var packages = getPackages(); // Pulled out so it is passed to the lambda as value + var extraPath = extra.toString().replace('\\', '/'); // We serve everything, except for things in the forge packages. BiPredicate mcFilter = (path, base) -> { if (base.equals(extraPath) || - path.endsWith("/")) return true; + path.endsWith("/")) return true; for (var pkg : packages) if (path.startsWith(pkg)) return false; return true; }; + return mcFilter; + } + + protected Path getForgeMod(List minecraft) { + var packages = getPackages(); // Pulled out so it is passed to the lambda as value // We need to separate out our resources/code so that we can show up as a different data pack. var modJar = SecureJar.from((path, base) -> { if (!path.endsWith(".class")) return true; @@ -114,14 +98,18 @@ public abstract class CommonDevLaunchHandler extends CommonLaunchHandler { if (path.startsWith(pkg)) return true; return false; }, minecraft.stream().distinct().toArray(Path[]::new)); - //modJar.getPackages().stream().sorted().forEach(System.out::println); - mods.add(List.of(modJar.getRootPath())); - return mcFilter; + //modJar.getPackages().stream().sorted().forEach(System.out::println); + return modJar.getRootPath(); } - protected String[] getPackages() { - return new String[]{ "net/minecraftforge/", "META-INF/services/", "META-INF/coremods.json", "META-INF/mods.toml" }; + private static String[] getPackages() { + return new String[] { + "net/minecraftforge/", + "META-INF/services/", + "META-INF/coremods.json", + "META-INF/mods.toml" + }; } private static String getRandomNumbers(int length) { @@ -131,9 +119,70 @@ public abstract class CommonDevLaunchHandler extends CommonLaunchHandler { @Override protected ServiceRunner makeService(final String[] arguments, final ModuleLayer gameLayer) { - var args = preLaunch(arguments, gameLayer); - return ()->devService(args, gameLayer); + return super.makeService(preLaunch(arguments, gameLayer), gameLayer); } - abstract void devService(final String[] arguments, final ModuleLayer gameLayer) throws Throwable; + // TODO: Get rid of this string based classpath crap when I re-write mod loader + protected static Map> getModClasses() { + var modClasses = Optional.ofNullable(System.getenv("MOD_CLASSES")).orElse(""); + LOGGER.debug(LogMarkers.CORE, "Got mod coordinates {} from env", modClasses); + + /* + * So MOD_CLASSES at the end of the day is a Map> but because we want to shove that into a single string. + * And pass it in as an environment variable.. instead od using json, or a file path, or anything sane, cpw did hacky string stuff + * Basically what we want to do is split the string by File.pathSeperator to get each key-value pair. + * Then we find the magic string "%%" and split on that. Using the first half as the mod id and the second as the path. + * BUT the modID is optional, and if not specified {why wouldn't it be?} it uses "defaultmodid" + * Anyways, it was stream hell, but now it's simpler to debug/understand. + */ + Map> ret = new HashMap<>(); + var entries = modClasses.split(File.pathSeparator); + for (var entry : entries) { + var modid = "defaultmodid"; + var path = entry; + + int idx = entry.indexOf("%%"); + if (idx != -1) { + modid = entry.substring(0, idx); + path = entry.substring(idx + 2); + } + + var p = Paths.get(path); + var lst = ret.computeIfAbsent(modid, k -> new ArrayList<>()); + if (!lst.contains(p)) + lst.add(p); + } + + LOGGER.debug(LogMarkers.CORE, "Found supplied mod coordinates:"); + ret.forEach((k, v) -> { + if (v.size() == 1) + LOGGER.debug(LogMarkers.CORE, "\t{}: {}", k, v.get(0)); + else { + LOGGER.debug(LogMarkers.CORE, "\t{}:", k); + v.forEach(e -> LOGGER.debug("\t\t{}", e)); + } + }); + + return ret; + } + + protected static Path findJarOnClasspath(String[] classpath, String match) { + String ret = null; + + for (var entry : classpath) { + int idx = entry.lastIndexOf(File.separatorChar); + if (idx == -1) continue; + + var name = entry.substring(idx + 1); + if (name.startsWith(match)) { + ret = entry; + break; + } + } + + if (ret == null) + new IllegalStateException("Could not find " + match + " in classpath"); + + return Paths.get(ret); + } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java index 2a9aaf95d3..13d7aa12c7 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java @@ -10,49 +10,52 @@ import cpw.mods.modlauncher.api.ILaunchHandlerService; import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder; import cpw.mods.modlauncher.api.ServiceRunner; import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.LogMarkers; import net.minecraftforge.api.distmarker.Dist; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.Configurator; import org.slf4j.Logger; -import sun.misc.Unsafe; - -import java.io.File; import java.io.IOException; import java.net.URI; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; import java.util.List; -import java.util.Map; -import java.util.Optional; import java.util.function.BiPredicate; -import java.util.stream.Collectors; +/** + * This is required by FMLLoader because ILaunchHandlerService doesn't have the context we need. + * I need to clean this up to make proper api. But that involves editing ModLauncher itself which i'm not gunna do right now. + * + * So until that happens, guess this is public api. + */ public abstract class CommonLaunchHandler implements ILaunchHandlerService { - public record LocatedPaths(List minecraftPaths, BiPredicate minecraftFilter, List> otherModPaths, List otherArtifacts) {} + public record LocatedPaths( + List minecraftPaths, + BiPredicate minecraftFilter, + List> otherModPaths, + List otherArtifacts + ) {} protected static final Logger LOGGER = LogUtils.getLogger(); - public abstract Dist getDist(); + private final LaunchType type; + private final String prefix; + protected CommonLaunchHandler(LaunchType type, String prefix) { + this.type = type; + this.prefix = prefix; + } + + @Override public String name() { return this.prefix + this.type.name(); } + public Dist getDist() { return this.type.dist(); } + public boolean isData() { return this.type.data(); } + public boolean isProduction() { return false; } public abstract String getNaming(); - public boolean isProduction() { - return false; - } - - public boolean isData() { - return false; - } - public abstract LocatedPaths getMinecraftPaths(); @Override public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) { - } protected String[] preLaunch(String[] arguments, ModuleLayer layer) { @@ -69,45 +72,23 @@ public abstract class CommonLaunchHandler implements ILaunchHandlerService { return arguments; } - protected final Map> getModClasses() { - final String modClasses = Optional.ofNullable(System.getenv("MOD_CLASSES")).orElse(""); - LOGGER.debug(LogMarkers.CORE, "Got mod coordinates {} from env", modClasses); - - record ExplodedModPath(String modid, Path path) {} - // "a/b/;c/d/;" -> "modid%%c:\fish\pepper;modid%%c:\fish2\pepper2\;modid2%%c:\fishy\bums;modid2%%c:\hmm" - final var modClassPaths = Arrays.stream(modClasses.split(File.pathSeparator)) - .map(inp -> inp.split("%%", 2)) - .map(splitString -> new ExplodedModPath(splitString.length == 1 ? "defaultmodid" : splitString[0], Paths.get(splitString[splitString.length - 1]))) - .collect(Collectors.groupingBy(ExplodedModPath::modid, Collectors.mapping(ExplodedModPath::path, Collectors.toList()))); - - LOGGER.debug(LogMarkers.CORE, "Found supplied mod coordinates [{}]", modClassPaths); - - //final var explodedTargets = ((Map>)arguments).computeIfAbsent("explodedTargets", a -> new ArrayList<>()); - //modClassPaths.forEach((modlabel,paths) -> explodedTargets.add(new ExplodedDirectoryLocator.ExplodedMod(modlabel, paths))); - return modClassPaths; - } - @Override public ServiceRunner launchService(final String[] arguments, final ModuleLayer gameLayer) { FMLLoader.beforeStart(gameLayer); return makeService(arguments, gameLayer); } - protected abstract ServiceRunner makeService(final String[] arguments, final ModuleLayer gameLayer); - - protected void clientService(final String[] arguments, final ModuleLayer layer) throws Throwable { - runTarget("net.minecraft.client.main.Main", arguments, layer); + protected ServiceRunner makeService(final String[] arguments, final ModuleLayer gameLayer) { + return () -> runTarget(this.type.module(), this.type.main(), arguments, gameLayer); } - protected void serverService(final String[] arguments, final ModuleLayer layer) throws Throwable { - runTarget("net.minecraft.server.Main", arguments, layer); - } + protected record LaunchType(String name, String module, String main, Dist dist, boolean data) {}; + protected static final LaunchType CLIENT = new LaunchType("client", "minecraft", "net.minecraft.client.main.Main", Dist.CLIENT, false); + protected static final LaunchType DATA = new LaunchType("data", "minecraft", "net.minecraft.data.Main", Dist.CLIENT, true); + protected static final LaunchType SERVER = new LaunchType("server", "minecraft", "net.minecraft.server.Main", Dist.DEDICATED_SERVER, false); + protected static final LaunchType SERVER_GAMETEST = new LaunchType("server_gametest", "forge", "net.minecratforge.gametest.GameTestMain", Dist.DEDICATED_SERVER, false); - protected void dataService(final String[] arguments, final ModuleLayer layer) throws Throwable { - runTarget("net.minecraft.data.Main", arguments, layer); - } - - protected void runTarget(final String target, final String[] arguments, final ModuleLayer layer) throws Throwable { - Class.forName(layer.findModule("minecraft").orElseThrow(),target).getMethod("main", String[].class).invoke(null, (Object)arguments); + protected void runTarget(String module, String target, final String[] arguments, final ModuleLayer layer) throws Throwable { + Class.forName(layer.findModule(module).orElseThrow(),target).getMethod("main", String[].class).invoke(null, (Object)arguments); } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonServerLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonServerLaunchHandler.java deleted file mode 100644 index a041f63c47..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonServerLaunchHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import cpw.mods.jarhandling.SecureJar; -import cpw.mods.modlauncher.api.ServiceRunner; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.LibraryFinder; -import net.minecraftforge.fml.loading.VersionInfo; -import net.minecraftforge.api.distmarker.Dist; - -import java.nio.file.Path; -import java.util.List; -import java.util.function.BiPredicate; -import java.util.stream.Stream; - -public abstract class CommonServerLaunchHandler extends CommonLaunchHandler { - @Override public Dist getDist() { return Dist.DEDICATED_SERVER; } - @Override public String getNaming() { return "srg"; } - @Override public boolean isProduction() { return true; } - - @Override - protected ServiceRunner makeService(String[] arguments, ModuleLayer layer) { - return () -> serverService(arguments, layer); - } - - @Override - public LocatedPaths getMinecraftPaths() { - final var vers = FMLLoader.versionInfo(); - var mc = LibraryFinder.findPathForMaven("net.minecraft", "server", "", "srg", vers.mcAndMCPVersion()); - var mcextra = LibraryFinder.findPathForMaven("net.minecraft", "server", "", "extra", vers.mcAndMCPVersion()); - var mcextra_filtered = SecureJar.from( // We only want it for it's resources. So filter everything else out. - (path, base) -> { - return path.equals("META-INF/versions/") || // This is required because it bypasses our filter for the manifest, and it's a multi-release jar. - (!path.endsWith(".class") && - !path.startsWith("META-INF/")); - }, mcextra - ); - - var mcstream = Stream.builder().add(mc).add(mcextra_filtered.getRootPath()); - var modstream = Stream.>builder(); - - BiPredicate filter = processMCStream(vers, mcstream, null, modstream); - - var fmlcore = LibraryFinder.findPathForMaven(vers.forgeGroup(), "fmlcore", "", "", vers.mcAndForgeVersion()); - var javafmllang = LibraryFinder.findPathForMaven(vers.forgeGroup(), "javafmllanguage", "", "", vers.mcAndForgeVersion()); - var lowcodelang = LibraryFinder.findPathForMaven(vers.forgeGroup(), "lowcodelanguage", "", "", vers.mcAndForgeVersion()); - var mclang = LibraryFinder.findPathForMaven(vers.forgeGroup(), "mclanguage", "", "", vers.mcAndForgeVersion()); - - return new LocatedPaths(mcstream.build().toList(), filter, modstream.build().toList(), List.of(fmlcore, javafmllang, lowcodelang, mclang)); - } - - protected abstract BiPredicate processMCStream(VersionInfo versionInfo, Stream.Builder mc, BiPredicate filter, Stream.Builder> mods); -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonUserdevLaunchHandler.java deleted file mode 100644 index cbc31398c2..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonUserdevLaunchHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.VersionInfo; - -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public abstract class CommonUserdevLaunchHandler extends CommonDevLaunchHandler { - @Override - public LocatedPaths getMinecraftPaths() { - final var vers = FMLLoader.versionInfo(); - - // Minecraft is extra jar {resources} + forge jar {patches} - final var mcstream = Stream.builder(); - // Mod code is in exploded directories - final var modstream = Stream.>builder(); - - // The MC extra and forge jars are on the classpath, so try and pull them out - var legacyCP = Objects.requireNonNull(System.getProperty("legacyClassPath"), "Missing legacyClassPath, cannot find userdev jars").split(File.pathSeparator); - var extra = findJarOnClasspath(legacyCP, "client-extra"); - - processStreams(legacyCP, vers, mcstream, modstream); - getModClasses().forEach((modid, paths) -> modstream.add(paths)); - - var minecraft = mcstream.build().collect(Collectors.toList()); - var mcFilter = getMcFilter(extra, minecraft, modstream); - minecraft.add(extra); // Add extra late so the filter is made correctly - return new LocatedPaths(minecraft, mcFilter, modstream.build().toList(), getFmlStuff(legacyCP)); - } - - protected abstract void processStreams(String[] classpath, VersionInfo versionInfo, Stream.Builder mc, Stream.Builder> mods); -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientDevLaunchHandler.java deleted file mode 100644 index 7bae42b620..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientDevLaunchHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeClientDevLaunchHandler extends CommonDevLaunchHandler { - @Override public String name() { return "forgeclientdev"; } - @Override public Dist getDist() { return Dist.CLIENT; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - clientService(arguments, layer); - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientLaunchHandler.java deleted file mode 100644 index bbc51f6a11..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientLaunchHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Stream; - -import net.minecraftforge.fml.loading.LibraryFinder; -import net.minecraftforge.fml.loading.VersionInfo; - -public class ForgeClientLaunchHandler extends CommonClientLaunchHandler { - @Override public String name() { return "forgeclient"; } - - @Override - protected void processMCStream(VersionInfo versionInfo, Stream.Builder mc, Stream.Builder> mods) { - var forgepatches = LibraryFinder.findPathForMaven(versionInfo.forgeGroup(), "forge", "", "client", versionInfo.mcAndForgeVersion()); - var forgejar = LibraryFinder.findPathForMaven(versionInfo.forgeGroup(), "forge", "", "universal", versionInfo.mcAndForgeVersion()); - mc.add(forgepatches); - mods.add(List.of(forgejar)); - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientUserdevLaunchHandler.java deleted file mode 100644 index 08b8d90cc4..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeClientUserdevLaunchHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeClientUserdevLaunchHandler extends ForgeUserdevLaunchHandler { - @Override - public String name() { return "forgeclientuserdev"; } - - @Override - public Dist getDist() { return Dist.CLIENT; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - clientService(arguments, layer); - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDataDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDataDevLaunchHandler.java deleted file mode 100644 index 307e09f5a0..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDataDevLaunchHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeDataDevLaunchHandler extends CommonDevLaunchHandler { - @Override public String name() { return "forgedatadev"; } - @Override public Dist getDist() { return Dist.CLIENT; } - @Override public boolean isData() { return true; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.data.Main").getMethod("main", String[].class).invoke(null, (Object) arguments); - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDataUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDataUserdevLaunchHandler.java deleted file mode 100644 index a5995577f1..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDataUserdevLaunchHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeDataUserdevLaunchHandler extends ForgeUserdevLaunchHandler { - @Override - public String name() { return "forgedatauserdev"; } - - @Override - public Dist getDist() { return Dist.CLIENT; } - - @Override - public boolean isData() { return true; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - dataService(arguments, layer); - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java new file mode 100644 index 0000000000..690ace158b --- /dev/null +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java @@ -0,0 +1,295 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.fml.loading.targets; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.nio.file.spi.FileSystemProvider; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Stream; + +import org.jetbrains.annotations.ApiStatus; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Opcodes; +import com.electronwill.nightconfig.core.Config; +import com.electronwill.nightconfig.core.file.FileNotFoundAction; +import com.electronwill.nightconfig.core.io.WritingMode; +import com.electronwill.nightconfig.toml.TomlParser; +import com.electronwill.nightconfig.toml.TomlWriter; +import com.google.common.jimfs.Jimfs; + +import cpw.mods.niofs.union.UnionFileSystemProvider; + +@ApiStatus.Internal +abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler { + private static final String MODS_TOML = "META-INF/mods.toml"; + private static final String PACK_META = "pack.mcmeta"; + private static final UnionFileSystemProvider UFSP = (UnionFileSystemProvider)FileSystemProvider.installedProviders().stream().filter(fsp->fsp.getScheme().equals("union")).findFirst().orElseThrow(()->new IllegalStateException("Couldn't find UnionFileSystemProvider")); + + private ForgeDevLaunchHandler(LaunchType type) { + super(type, "forge_dev_"); + } + + @Override + public LocatedPaths getMinecraftPaths() { + // Our exploded directories in development include all mods and minecraft itself. + var mods = getModClasses(); + + // The extra jar is on the classpath, so try and pull it out of the legacy classpath + var legacyCP = Objects.requireNonNull(System.getProperty("legacyClassPath"), "Missing legacyClassPath, cannot find client-extra").split(File.pathSeparator); + var extra = findJarOnClasspath(legacyCP, "client-extra"); + + + // Minecraft is extra jar {resources} + our exploded directories in dev + var minecraft = mods.remove("minecraft"); + if (minecraft == null) + throw new IllegalStateException("Could not find 'minecraft' mod paths."); + var mcFilter = getMcFilter(extra, minecraft); + + // The MC code/Patcher edits are in exploded directories + var modstream = Stream.>builder(); + var forge = this.getForgeMod(minecraft); + modstream.add(List.of(forge)); + + // Explode our test mods into a framework that treats them all as separate jars. + var tests = mods.remove("tests"); + if (tests != null) + explodeTestMods(tests).forEach(modstream::add); + + mods.values().forEach(modstream::add); + + return new LocatedPaths( + Stream.concat(minecraft.stream(), List.of(extra).stream()).toList(), + mcFilter, + modstream.build().toList(), + getLibraries(legacyCP) + ); + } + + private List> explodeTestMods(List paths) { + var mod = new ArrayList>(); + var memory = Jimfs.newFileSystem(); + + // First lets find all class files, that have the @Mod annotation and map packages to modids. + var packages = findTestModPackages(paths); + for (var entry : packages.entrySet()) { + var pkg = entry.getKey(); + var modids = entry.getValue(); + + var resourcePaths = new LinkedHashSet(); + // Jump down into the package for resources + paths.stream() + .mapMulti((p, c) -> modids.forEach(id -> c.accept(p.resolve(id)))) + .filter(Files::exists).forEach(resourcePaths::add); + + var root = memory.getPath(modids.iterator().next()); // use the first modid as our root + buildModsToml(resourcePaths, modids, root); + buildPackMeta(resourcePaths, root); + + if (Files.exists(root)) + resourcePaths.add(root); + + // We want just the class files from the root of the input paths. So make a new union with a filter. + var classes = UFSP.newFileSystem( + (path, base) -> { + if (path.endsWith("/")) { + if (path.startsWith("/")) + path = path.substring(1); + return pkg.startsWith(path) || path.startsWith(pkg); + } + return path.endsWith(".class") && path.startsWith(pkg); + }, paths.toArray(Path[]::new)); + // And we want the resources, and none of the classes, just in case things get kinda fucky and somehow a package overlaps a sub package {shading?} + var resources = UFSP.newFileSystem((path, base) -> !path.endsWith(".class"), resourcePaths.toArray(Path[]::new)); + + mod.add(List.of(classes.getRoot(), resources.getRoot())); + } + + return mod; + } + + // Find all the @Mods so we can generate tomls, and so we can pick packages. Right now it doesn't allow mods in parent directories, + // I could make it merge all the way up, but I think this would be fine. + private Map> findTestModPackages(List paths) { + var mods = new HashMap>(); + for (var path : paths) { + try (var files = Files.walk(path)) { + var classes = files + .filter(Files::isRegularFile) + .filter(p -> p.getFileName().toString().endsWith(".class")) + .toList(); + + for (var cls : classes) { + try (var is = Files.newInputStream(cls)) { + var reader = new ClassReader(is); + reader.accept(new ClassVisitor(Opcodes.ASM9) { + private String clsName; + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + this.clsName = name; + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public AnnotationVisitor visitAnnotation(String name, boolean runtime) { + if (!"Lnet/minecraftforge/fml/common/Mod;".equals(name)) + return super.visitAnnotation(name, runtime); + + return new AnnotationVisitor(Opcodes.ASM9) { + @Override + public void visit(String key, Object value) { + if ("value".equals(key)) { + int idx = clsName.lastIndexOf('/'); + var pkg = clsName.substring(0, idx); + mods.computeIfAbsent(pkg, k -> new HashSet<>()).add((String)value); + + idx = pkg.lastIndexOf('/'); + while (idx != -1) { + pkg = pkg.substring(0, idx); + idx = pkg.lastIndexOf('/'); + if (mods.containsKey(pkg)) + throw new IllegalStateException("Invalid ForgeDev test mod layout, conflicting packages: " + pkg + " for " + clsName); + } + } + } + }; + } + }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + } + } + } catch (IOException e) { + sneak(e); + } + } + return mods; + } + + // Builds or update the mods.toml file for all @Mods in this package + private void buildModsToml(Set resources, Set modids, Path root) { + var toml = resources.stream() + .map(p -> p.resolve(MODS_TOML)) + .filter(Files::exists) + .findFirst() + .orElse(null); + + Config cfg = null; + + if (toml != null) + cfg = new TomlParser().parse(toml, FileNotFoundAction.READ_NOTHING); + else + cfg = Config.inMemory(); + + boolean modified = false; + var defaults = Map.of( + "modLoader", "javafml", + "loaderVersion", "[0,)", + "license", "Doesnt fucking matter" + ); + + for (var key : defaults.keySet()) { + if (!cfg.contains(key)) { + cfg.set(key, defaults.get(key)); + modified = true; + } + } + + var modlist = new ArrayList(); + if (cfg.contains("mods")) { + @SuppressWarnings("unchecked") + var existing = ((List)cfg.get("mods")); + modlist.addAll(existing); + } + + for (var modid : modids) { + if (!modlist.stream().anyMatch(c -> modid.equals(c.get("modId")))) { + modified = true; + var tmp = Config.inMemory(); + tmp.set("modId", modid); + modlist.add(tmp); + } + } + + cfg.set("mods", modlist); + + if (modified) { + var target = root.resolve(MODS_TOML); + try { + Files.createDirectories(target.getParent()); + new TomlWriter().write(cfg, target, WritingMode.REPLACE); + } catch (IOException e) { + throw new IllegalStateException("Failed to create in memory toml: " + target, e); + } + } + } + + // This is optional, it just hides a warning screen when starting up. I should probably remove this once I restructure how data gen for test mods work and make it generate there. + private void buildPackMeta(Set paths, Path root) { + var existing = paths.stream() + .map(p -> p.resolve(PACK_META)) + .filter(Files::exists) + .findFirst() + .orElse(null); + + if (existing != null) + return; + var target = root.resolve(PACK_META); + try { + Files.createDirectories(target.getParent()); + Files.writeString(target, + """ + { + "pack": { + "description": "doesn't matter", + "pack_format": 18 + } + } + """, StandardCharsets.UTF_8, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); + } catch (IOException e) { + throw new IllegalStateException("Failed to make in memory pack.mcmeta: " + target, e); + } + } + + @SuppressWarnings("unchecked") + private static R sneak(Throwable e) throws E { + throw (E)e; + } + + public static class Client extends ForgeDevLaunchHandler { + public Client() { + super(CLIENT); + } + } + + public static class Data extends ForgeDevLaunchHandler { + public Data() { + super(DATA); + } + } + + public static class Server extends ForgeDevLaunchHandler { + public Server() { + super(SERVER); + } + } + + public static class ServerGameTest extends ForgeDevLaunchHandler { + public ServerGameTest() { + super(SERVER_GAMETEST); + } + } +} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeGametestDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeGametestDevLaunchHandler.java deleted file mode 100644 index 2ce9e8ea93..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeGametestDevLaunchHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeGametestDevLaunchHandler extends CommonDevLaunchHandler { - @Override public String name() { return "forgegametestserverdev"; } - @Override public Dist getDist() { return Dist.DEDICATED_SERVER; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - Class.forName(layer.findModule("forge").orElseThrow(), "net.minecraftforge.gametest.GameTestMain").getMethod("main", String[].class).invoke(null, (Object)arguments); - } -} \ No newline at end of file diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeGametestUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeGametestUserdevLaunchHandler.java deleted file mode 100644 index 3ada4f71da..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeGametestUserdevLaunchHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeGametestUserdevLaunchHandler extends ForgeUserdevLaunchHandler { - @Override public String name() { return "forgegametestserveruserdev"; } - @Override public Dist getDist() { return Dist.DEDICATED_SERVER; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - Class.forName(layer.findModule("forge").orElseThrow(), "net.minecraftforge.gametest.GameTestMain").getMethod("main", String[].class).invoke(null, (Object)arguments); - } -} \ No newline at end of file diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java new file mode 100644 index 0000000000..feac79b85d --- /dev/null +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.fml.loading.targets; + +import java.nio.file.Path; +import java.util.List; +import java.util.function.BiPredicate; + +import org.jetbrains.annotations.ApiStatus; + +import cpw.mods.jarhandling.SecureJar; +import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.fml.loading.LibraryFinder; +import net.minecraftforge.fml.loading.VersionInfo; + +@ApiStatus.Internal +abstract class ForgeProdLaunchHandler extends CommonLaunchHandler { + protected ForgeProdLaunchHandler(LaunchType type) { + super(type, "forge_"); + } + + @Override public String getNaming() { return "srg"; } + @Override public boolean isProduction() { return true; } + + protected Path mvn(VersionInfo info, String artifact) { + return mvn(info, artifact, ""); + } + protected Path mvn(VersionInfo info, String artifact, String classifier) { + return mvn(info.forgeGroup(), artifact, classifier, info.mcAndForgeVersion()); + } + protected Path mvn(String group, String artifact, String classifier, String version) { + return LibraryFinder.findPathForMaven(group, artifact, "", classifier, version); + } + + @Override + public LocatedPaths getMinecraftPaths() { + var vers = FMLLoader.versionInfo(); + + // Minecraft + var mc = getMCPaths(vers); + + // mods (Forge) + var forgejar = mvn(vers, "forge", "universal"); + + // Libraries + var fmlcore = mvn(vers, "fmlcore"); + var javafmllang = mvn(vers, "javafmllanguage"); + var lowcodelang = mvn(vers, "lowcodelanguage"); + var mclang = mvn(vers, "mclanguage"); + + return new LocatedPaths( + mc, + null, + List.of(List.of(forgejar)), + List.of(fmlcore, javafmllang, lowcodelang, mclang) + ); + } + + protected abstract List getMCPaths(VersionInfo vers); + + public static class Client extends ForgeProdLaunchHandler { + public Client() { + super(CLIENT); + } + + @Override + protected List getMCPaths(VersionInfo vers) { + var mc = mvn("net.minecraft", "client", "srg", vers.mcAndMCPVersion()); + var mcextra = mvn("net.minecraft", "client", "extra", vers.mcAndMCPVersion()); + var patches = mvn(vers, "forge", "client"); + return List.of(mc, mcextra, patches); + } + } + public static class Server extends ForgeProdLaunchHandler { + public Server() { + super(SERVER); + } + + @Override + protected List getMCPaths(VersionInfo vers) { + var mc = mvn("net.minecraft", "server", "srg", vers.mcAndMCPVersion()); + var mcextra = mvn("net.minecraft", "server", "extra", vers.mcAndMCPVersion()); + var patches = mvn(vers, "forge", "server"); + + // TODO: Get rid of this by filtering the file at install time. + // We only want it for it's resources. So filter everything else out. + BiPredicate filter = (path, base) -> { + return path.equals("META-INF/versions/") || // This is required because it bypasses our filter for the manifest, and it's a multi-release jar. + (!path.endsWith(".class") && !path.startsWith("META-INF/")); + }; + mcextra = SecureJar.from(filter, mcextra).getRootPath(); + + return List.of(mc, mcextra, patches); + } + } +} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerDevLaunchHandler.java deleted file mode 100644 index 85f9fd9e84..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerDevLaunchHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeServerDevLaunchHandler extends CommonDevLaunchHandler { - @Override public String name() { return "forgeserverdev"; } - @Override public Dist getDist() { return Dist.DEDICATED_SERVER; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - serverService(arguments, layer); - } -} \ No newline at end of file diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerLaunchHandler.java deleted file mode 100644 index a013f618b8..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerLaunchHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import cpw.mods.modlauncher.api.ILaunchHandlerService; -import net.minecraftforge.fml.loading.LibraryFinder; -import net.minecraftforge.fml.loading.VersionInfo; - -import java.nio.file.Path; -import java.util.List; -import java.util.function.BiPredicate; -import java.util.stream.Stream; - -public class ForgeServerLaunchHandler extends CommonServerLaunchHandler implements ILaunchHandlerService { - @Override public String name() { return "forgeserver"; } - - @Override - protected BiPredicate processMCStream(VersionInfo versionInfo, Stream.Builder mc, BiPredicate filter, Stream.Builder> mods) { - var forgepatches = LibraryFinder.findPathForMaven(versionInfo.forgeGroup(), "forge", "", "server", versionInfo.mcAndForgeVersion()); - var forgejar = LibraryFinder.findPathForMaven(versionInfo.forgeGroup(), "forge", "", "universal", versionInfo.mcAndForgeVersion()); - mc.add(forgepatches); - mods.add(List.of(forgejar)); - return filter; - } -} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerUserdevLaunchHandler.java deleted file mode 100644 index b33cc67f32..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeServerUserdevLaunchHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.loading.targets; - -import net.minecraftforge.api.distmarker.Dist; - -public class ForgeServerUserdevLaunchHandler extends ForgeUserdevLaunchHandler { - @Override public String name() { return "forgeserveruserdev"; } - @Override public Dist getDist() { return Dist.DEDICATED_SERVER; } - - @Override - public void devService(String[] arguments, ModuleLayer layer) throws Throwable { - serverService(arguments, layer); - } -} \ No newline at end of file diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java index 27925e9fa6..60b292348d 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java @@ -5,16 +5,70 @@ package net.minecraftforge.fml.loading.targets; -import net.minecraftforge.fml.loading.VersionInfo; - +import net.minecraftforge.fml.loading.FMLLoader; +import java.io.File; import java.nio.file.Path; import java.util.List; +import java.util.Objects; import java.util.stream.Stream; -public abstract class ForgeUserdevLaunchHandler extends CommonUserdevLaunchHandler { +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler { + private ForgeUserdevLaunchHandler(LaunchType type) { + super(type, "forge_userdev_"); + } + @Override - protected void processStreams(String[] classpath, VersionInfo versionInfo, Stream.Builder mc, Stream.Builder> mods) { - var forge = findJarOnClasspath(classpath, "forge-" + versionInfo.mcAndForgeVersion()); - mc.add(forge); + public LocatedPaths getMinecraftPaths() { + var legacyCP = Objects.requireNonNull(System.getProperty("legacyClassPath"), "Missing legacyClassPath, cannot find userdev jars").split(File.pathSeparator); + var vers = FMLLoader.versionInfo(); + + // Minecraft is extra jar {resources} + forge jar {patches} + // The MC extra and forge jars are on the classpath, so try and pull them out + var extra = findJarOnClasspath(legacyCP, "client-extra"); + var forge = findJarOnClasspath(legacyCP, "forge-" + vers.mcAndForgeVersion()); + // We need to filter the forge jar to just MC code + var filter = getMcFilter(extra, List.of(forge)); + + // Mods is forge classes + anything from MOD_CLASSES + var modstream = Stream.>builder(); + // We want the forge as a seperate mod jar. + var forgemod = this.getForgeMod(List.of(forge)); + modstream.add(List.of(forgemod)); + // Mod code is in exploded directories + getModClasses().forEach((modid, paths) -> modstream.add(paths)); + + return new LocatedPaths( + List.of(forge, extra), + filter, + modstream.build().toList(), + getLibraries(legacyCP) + ); + } + + public static class Client extends ForgeUserdevLaunchHandler { + public Client() { + super(CLIENT); + } + } + + public static class Data extends ForgeUserdevLaunchHandler { + public Data() { + super(DATA); + } + } + + public static class Server extends ForgeUserdevLaunchHandler { + public Server() { + super(SERVER); + } + } + + public static class ServerGameTest extends ForgeUserdevLaunchHandler { + public ServerGameTest() { + super(SERVER_GAMETEST); + } } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/CyclePresentException.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/CyclePresentException.java index e3167e3f5f..31175f5e3c 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/CyclePresentException.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/CyclePresentException.java @@ -11,6 +11,7 @@ import java.util.Set; * An exception thrown for graphs with cycles as an argument for topological sort. */ public final class CyclePresentException extends IllegalArgumentException { + private static final long serialVersionUID = -2609660010927054667L; private final Set> cycles; /** diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/server/ServerMain.java b/fmlloader/src/main/java/net/minecraftforge/fml/server/ServerMain.java deleted file mode 100644 index 2cef0ac850..0000000000 --- a/fmlloader/src/main/java/net/minecraftforge/fml/server/ServerMain.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.fml.server; - -import cpw.mods.modlauncher.InvalidLauncherSetupException; -import cpw.mods.modlauncher.Launcher; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.security.CodeSource; -import java.security.ProtectionDomain; -import java.util.Optional; -import java.util.jar.JarFile; -import java.util.jar.Manifest; - -public class ServerMain { - public static void main(String[] args) { - try { - Class.forName("cpw.mods.modlauncher.Launcher", false, ClassLoader.getSystemClassLoader()); - Class.forName("net.minecraftforge.forgespi.Environment", false, ClassLoader.getSystemClassLoader()); - } catch (ClassNotFoundException cnfe) { - System.err.println("FATAL ERROR, You need to run the installer. The libraries required to launch a server are missing"); - System.exit(1); - } - - final String launchArgs = Optional.ofNullable(ServerMain.class.getProtectionDomain()). - map(ProtectionDomain::getCodeSource). - map(CodeSource::getLocation). - map(ServerMain::urlToManifest). - map(Manifest::getMainAttributes). - map(a -> a.getValue("ServerLaunchArgs")). - orElseThrow(ServerMain::throwMissingManifest); - String[] defaultargs = launchArgs.split(" "); - String[] result = new String[args.length + defaultargs.length]; - System.arraycopy(defaultargs, 0, result, 0, defaultargs.length); - System.arraycopy(args, 0, result, defaultargs.length, args.length); - // separate class, so the exception can resolve - new Runner().runLauncher(result); - } - - private static class Runner { - private void runLauncher(final String[] result) { - try { - Launcher.main(result); - } catch (InvalidLauncherSetupException e) { - System.err.println("The server is missing critical libraries and cannot load. Please run the installer to correct this"); - System.exit(1); - } - } - } - private static Manifest urlToManifest(URL url) { - try { - return new JarFile(new File(url.toURI())).getManifest(); - } catch (URISyntaxException | IOException e) { - return null; - } - } - - private static RuntimeException throwMissingManifest() { - System.err.println("This is not being run from a valid JAR file, essential data is missing."); - return new RuntimeException("Missing the manifest"); - } -} diff --git a/fmlloader/src/main/resources/META-INF/services/cpw.mods.cl.ModularURLHandler.IURLProvider b/fmlloader/src/main/resources/META-INF/services/cpw.mods.cl.ModularURLHandler.IURLProvider deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService b/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService index f0cc3caef5..b4a3ffa7bc 100644 --- a/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService +++ b/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService @@ -1,10 +1,15 @@ -net.minecraftforge.fml.loading.targets.ForgeClientLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeClientDevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeClientUserdevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeServerLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeServerDevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeServerUserdevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeDataDevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeDataUserdevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeGametestDevLaunchHandler -net.minecraftforge.fml.loading.targets.ForgeGametestUserdevLaunchHandler +# Production +net.minecraftforge.fml.loading.targets.ForgeProdLaunchHandler$Client +net.minecraftforge.fml.loading.targets.ForgeProdLaunchHandler$Server + +# Mod Developers +net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Client +net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Data +net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Server +net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$ServerGameTest + +#Working on Forge itself +net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Client +net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Data +net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Server +net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$ServerGameTest diff --git a/src/generated_test/resources/EMPTY b/src/generated_test/resources/EMPTY deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/generated_test/resources/pack.mcmeta b/src/generated_test/resources/empty/pack.mcmeta similarity index 100% rename from src/generated_test/resources/pack.mcmeta rename to src/generated_test/resources/empty/pack.mcmeta diff --git a/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json b/src/generated_test/resources/global_loot_test/data/forge/loot_modifiers/global_loot_modifiers.json similarity index 100% rename from src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json rename to src/generated_test/resources/global_loot_test/data/forge/loot_modifiers/global_loot_modifiers.json diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/bamboo_silk.json b/src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/bamboo_silk.json similarity index 100% rename from src/generated_test/resources/data/global_loot_test/loot_modifiers/bamboo_silk.json rename to src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/bamboo_silk.json diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/dungeon_loot.json b/src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/dungeon_loot.json similarity index 100% rename from src/generated_test/resources/data/global_loot_test/loot_modifiers/dungeon_loot.json rename to src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/dungeon_loot.json diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json b/src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/smelting.json similarity index 100% rename from src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json rename to src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/smelting.json diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json b/src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/wheat_harvest.json similarity index 100% rename from src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json rename to src/generated_test/resources/global_loot_test/data/global_loot_test/loot_modifiers/wheat_harvest.json diff --git a/src/generated_mdk/resources/pack.mcmeta b/src/generated_test/resources/mdk_datagen/pack.mcmeta similarity index 79% rename from src/generated_mdk/resources/pack.mcmeta rename to src/generated_test/resources/mdk_datagen/pack.mcmeta index eca79ae4ae..2a62706c90 100644 --- a/src/generated_mdk/resources/pack.mcmeta +++ b/src/generated_test/resources/mdk_datagen/pack.mcmeta @@ -3,6 +3,6 @@ "description": { "text": "${mod_id} resources" }, - "pack_format": 15 + "pack_format": 18 } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index a826efb21e..913ac60acb 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -20,7 +20,6 @@ import net.minecraft.FileUtil; import net.minecraft.client.Camera; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; -import net.minecraft.client.MouseHandler; import net.minecraft.client.Options; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.color.item.ItemColors; @@ -60,7 +59,6 @@ import net.minecraft.client.renderer.texture.SpriteContents; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.language.I18n; -import net.minecraft.client.resources.metadata.animation.AnimationMetadataSection; import net.minecraft.client.resources.metadata.animation.FrameSize; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.Material; @@ -76,12 +74,10 @@ import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.ChatTypeDecoration; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.ComponentContents; import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.network.chat.Style; import net.minecraft.network.protocol.status.ServerStatus; -import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraft.server.packs.resources.Resource; @@ -97,10 +93,8 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.tooltip.TooltipComponent; -import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.ItemStackLinkedSet; import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.GameType; @@ -151,12 +145,9 @@ import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.client.textures.ForgeTextureMetadata; import net.minecraftforge.client.textures.TextureAtlasSpriteLoaderManager; import net.minecraftforge.common.ForgeConfig; -import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.ForgeI18n; import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.util.MutableHashedLinkedMap; -import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.IExtensionPoint; diff --git a/src/main/java/net/minecraftforge/client/gui/overlay/VanillaGuiOverlay.java b/src/main/java/net/minecraftforge/client/gui/overlay/VanillaGuiOverlay.java index 2de2168562..19011d0d4f 100644 --- a/src/main/java/net/minecraftforge/client/gui/overlay/VanillaGuiOverlay.java +++ b/src/main/java/net/minecraftforge/client/gui/overlay/VanillaGuiOverlay.java @@ -23,6 +23,7 @@ import org.lwjgl.opengl.GL11; /** * All the vanilla {@linkplain IGuiOverlay HUD overlays} in the order that they render. */ +@SuppressWarnings("resource") public enum VanillaGuiOverlay { VIGNETTE("vignette", (gui, guiGraphics, partialTick, screenWidth, screenHeight) -> { if (Minecraft.useFancyGraphics()) { diff --git a/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java b/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java index 7f49f3c437..ae0f138922 100644 --- a/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java +++ b/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java @@ -6,10 +6,10 @@ package net.minecraftforge.data.loading; import net.minecraft.Util; -import net.minecraft.core.HolderLookup; import net.minecraft.data.registries.VanillaRegistries; import net.minecraft.server.Bootstrap; import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.ModWorkManager; import net.minecraftforge.data.event.GatherDataEvent; @@ -19,12 +19,13 @@ import org.apache.logging.log4j.Logger; import java.io.File; import java.nio.file.Path; import java.util.Collection; +import java.util.HashSet; import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.regex.Pattern; public class DatagenModLoader { private static final Logger LOGGER = LogManager.getLogger(); - private static GatherDataEvent.DataGeneratorConfig dataGeneratorConfig; private static ExistingFileHelper existingFileHelper; private static boolean runningDataGen; @@ -32,25 +33,49 @@ public class DatagenModLoader { return runningDataGen; } - public static void begin(final Set mods, final Path path, final Collection inputs, Collection existingPacks, - Set existingMods, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, - final boolean structureValidator, final boolean flat, final String assetIndex, final File assetsDir) { - if (mods.contains("minecraft") && mods.size() == 1) + public static void begin( + Set patterns, Path output, Collection inputs, Collection existingPacks, Set existingMods, + boolean genServer, boolean genClient, boolean genDev, boolean genReports, + boolean validate, boolean flat, String assetIndex, File assetsDir + ) { + if (patterns.contains("minecraft") && patterns.size() == 1) return; - LOGGER.info("Initializing Data Gatherer for mods {}", mods); + runningDataGen = true; Bootstrap.bootStrap(); ModLoader.get().gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{}); - CompletableFuture lookupProvider = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor()); - dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, lookupProvider, serverGenerators, - clientGenerators, devToolGenerators, reportsGenerator, structureValidator, flat); + var lookupProvider = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor()); + + var mods = new HashSet(); + for (var pattern : patterns) { + if (pattern.indexOf('.') == -1) // No wildcard! + mods.add(pattern); + + var m = Pattern.compile('^' + pattern + '$'); + ModList.get().forEachModInOrder(mc -> { + var id = mc.getModId(); + if (!"forge".equals(id) && !"minecraft".equals(id) && m.matcher(id).matches()) + mods.add(id); + }); + } + LOGGER.info("Initializing Data Gatherer for mods {}", mods); + + var config = new GatherDataEvent.DataGeneratorConfig(mods, output, inputs, lookupProvider, genServer, + genClient, genDev, genReports, validate, flat); + if (!mods.contains("forge")) { // If we aren't generating data for forge, automatically add forge as an existing so mods can access forge's data existingMods.add("forge"); } - existingFileHelper = new ExistingFileHelper(existingPacks, existingMods, structureValidator, assetIndex, assetsDir); - ModLoader.get().runEventGenerator(mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p -> dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), - dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig, existingFileHelper)); - dataGeneratorConfig.runAll(); + + existingFileHelper = new ExistingFileHelper(existingPacks, existingMods, validate, assetIndex, assetsDir); + ModLoader.get().runEventGenerator(mc -> new GatherDataEvent( + mc, + config.makeGenerator( + p -> config.isFlat() ? p : p.resolve(mc.getModId()), + config.getMods().contains(mc.getModId()) + ), config, existingFileHelper) + ); + config.runAll(); } } diff --git a/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java b/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java index 84e9f2bb85..d394fed423 100644 --- a/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java +++ b/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java @@ -27,14 +27,12 @@ import java.util.concurrent.Executor; * The event is fired on each reload and lets modders add their own ReloadListeners, for server-side resources. * The event is fired on the {@link MinecraftForge#EVENT_BUS} */ -public class AddReloadListenerEvent extends Event -{ +public class AddReloadListenerEvent extends Event { private final List listeners = new ArrayList<>(); private final ReloadableServerResources serverResources; private final RegistryAccess registryAccess; - public AddReloadListenerEvent(ReloadableServerResources serverResources, RegistryAccess registryAccess) - { + public AddReloadListenerEvent(ReloadableServerResources serverResources, RegistryAccess registryAccess) { this.serverResources = serverResources; this.registryAccess = registryAccess; } @@ -42,21 +40,18 @@ public class AddReloadListenerEvent extends Event /** * @param listener the listener to add to the ResourceManager on reload */ - public void addListener(PreparableReloadListener listener) - { + public void addListener(PreparableReloadListener listener) { listeners.add(new WrappedStateAwareListener(listener)); } - public List getListeners() - { + public List getListeners() { return ImmutableList.copyOf(listeners); } /** * @return The ReloableServerResources being reloaded. */ - public ReloadableServerResources getServerResources() - { + public ReloadableServerResources getServerResources() { return serverResources; } @@ -64,8 +59,7 @@ public class AddReloadListenerEvent extends Event * This context object holds data relevant to the current reload, such as staged tags. * @return The condition context for the currently active reload. */ - public ICondition.IContext getConditionContext() - { + public ICondition.IContext getConditionContext() { return serverResources.getConditionContext(); } @@ -74,8 +68,7 @@ public class AddReloadListenerEvent extends Event * All built-in and dynamic registries are loaded and frozen by this point. * @return The RegistryAccess context for the currently active reload. */ - public RegistryAccess getRegistryAccess() - { + public RegistryAccess getRegistryAccess() { return registryAccess; } diff --git a/src/test/java/net/minecraftforge/debug/CreativeModeTabTest.java b/src/test/java/net/minecraftforge/debug/creativetabs/CreativeModeTabTest.java similarity index 99% rename from src/test/java/net/minecraftforge/debug/CreativeModeTabTest.java rename to src/test/java/net/minecraftforge/debug/creativetabs/CreativeModeTabTest.java index dd3d4cc821..2033c0b745 100644 --- a/src/test/java/net/minecraftforge/debug/CreativeModeTabTest.java +++ b/src/test/java/net/minecraftforge/debug/creativetabs/CreativeModeTabTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only */ -package net.minecraftforge.debug; +package net.minecraftforge.debug.creativetabs; import java.util.List; import net.minecraft.core.registries.Registries; diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java b/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java index c409a712da..ba2f14d752 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java @@ -90,7 +90,7 @@ public class GlobalLootModifiersTest { var entries = event.getEntries(); var vis = TabVisibility.PARENT_AND_SEARCH_TABS; if (event.getTabKey() == Empty.TAB) { - var smelt = new ItemStack(Items.SHEARS); + var smelt = new ItemStack(Items.IRON_AXE); EnchantmentHelper.setEnchantments(ImmutableMap.builder().put(SMELT.get(), 1).build(), smelt); entries.put(smelt, vis); } diff --git a/src/test_old/java/net/minecraftforge/mdk/MdkDatagen.java b/src/test/java/net/minecraftforge/mdk/Datagen.java similarity index 86% rename from src/test_old/java/net/minecraftforge/mdk/MdkDatagen.java rename to src/test/java/net/minecraftforge/mdk/Datagen.java index 63f820bfd7..c4535ac36a 100644 --- a/src/test_old/java/net/minecraftforge/mdk/MdkDatagen.java +++ b/src/test/java/net/minecraftforge/mdk/Datagen.java @@ -16,18 +16,15 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import java.util.Optional; -@Mod(MdkDatagen.MOD_ID) -public class MdkDatagen -{ +@Mod(Datagen.MOD_ID) +public class Datagen { static final String MOD_ID = "mdk_datagen"; - public MdkDatagen() - { - FMLJavaModLoadingContext.get().getModEventBus().addListener(MdkDatagen::gatherData); + public Datagen() { + FMLJavaModLoadingContext.get().getModEventBus().addListener(Datagen::gatherData); } - private static void gatherData(GatherDataEvent event) - { + private static void gatherData(GatherDataEvent event) { var gen = event.getGenerator(); var packOutput = gen.getPackOutput(); gen.addProvider(true, new PackMetadataGenerator(packOutput) diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/global_loot_test/META-INF/mods.toml similarity index 52% rename from src/test/resources/META-INF/mods.toml rename to src/test/resources/global_loot_test/META-INF/mods.toml index 56730474a7..a7bf4e2486 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/global_loot_test/META-INF/mods.toml @@ -1,15 +1,3 @@ -modLoader="javafml" -loaderVersion="[28,)" -license="LGPL v2.1" - -[[mods]] -modId="empty" - -[[mods]] -modId="creative_mode_tab_test" - - - [[mods]] modId="global_loot_test" [[dependencies.global_loot_test]]