diff --git a/.gitignore b/.gitignore
index d6dc0d7a3e..b03f74fc5d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,19 +9,24 @@
#idea
/.idea
+/*/out
/classes
*.iml
#gradle
/build
/.gradle
-/mdk/.gradle
-/mdk/build
+/*/build
+/*/.gradle
-#occupational hazards
+# Projects repo, either ignore it, or ignore patches.
/projects/mcp/
/projects/clean/
/projects/forge/
+/projects/fmlonly/
+#/patches/
+
+#occupational hazards
/projects/**/build/
/projects/**/out/
/projects/**/run/
@@ -31,16 +36,11 @@ src/generated/resources/.cache/
#Patch rejects
/patches-/
-*.patch.rej
+#*.patch.rej
+/projects/*/rejects/
# FML changelog
changelog.txt
*.py
*.7z
/logs/
-
-/projects/forge/rejects/
-
-# Srg2Source causes import bugs on these patches. If you intentionnally change these, remove the ignore.
-/patches/minecraft/net/minecraft/client/renderer/ViewFrustum.java.patch
-/patches/minecraft/net/minecraft/data/BlockModelDefinition.java.patch
diff --git a/Jenkinsfile b/Jenkinsfile
index b9ba1c1648..a04f76131a 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -6,7 +6,7 @@ pipeline {
}
agent {
docker {
- image 'gradle:jdk8'
+ image 'gradle:7-jdk16'
args '-v forgegc:/home/gradle/.gradle/'
}
}
@@ -69,7 +69,7 @@ pipeline {
steps {
withCredentials([usernamePassword(credentialsId: 'maven-forge-user', usernameVariable: 'MAVEN_USER', passwordVariable: 'MAVEN_PASSWORD')]) {
withGradle {
- sh './gradlew ${GRADLE_ARGS} :forge:publish -PkeystoreKeyPass=${KEYSTORE_KEYPASS} -PkeystoreStorePass=${KEYSTORE_STOREPASS} -Pkeystore=${KEYSTORE} -PcrowdinKey=${CROWDIN}'
+ sh './gradlew ${GRADLE_ARGS} publish -PkeystoreKeyPass=${KEYSTORE_KEYPASS} -PkeystoreStorePass=${KEYSTORE_STOREPASS} -Pkeystore=${KEYSTORE} -PcrowdinKey=${CROWDIN}'
}
}
}
@@ -88,7 +88,7 @@ pipeline {
}
steps {
withGradle {
- sh './gradlew ${GRADLE_ARGS} :forge:publish -PcrowdinKey=${CROWDIN}'
+ sh './gradlew ${GRADLE_ARGS} publish -PcrowdinKey=${CROWDIN}'
}
}
}
diff --git a/build.gradle b/build.gradle
index 653a19ab46..8f203194b3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -16,10 +16,11 @@ import java.util.Date
import java.util.LinkedHashMap
import net.minecraftforge.forge.tasks.*
import static net.minecraftforge.forge.tasks.Util.*
+import net.minecraftforge.gradle.common.tasks.ApplyBinPatches
import net.minecraftforge.gradle.common.tasks.DownloadMavenArtifact
import net.minecraftforge.gradle.common.tasks.ExtractInheritance
import net.minecraftforge.gradle.common.tasks.SignJar
-import net.minecraftforge.gradle.patcher.tasks.ReobfuscateJar
+import net.minecraftforge.gradle.userdev.tasks.RenameJar
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.plugins.ide.eclipse.model.SourceFolder
@@ -30,9 +31,7 @@ plugins {
id 'eclipse'
}
-Util.init() //Init all our extension methods
-
-println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
+Util.init() //Init all our extension methods!
ext {
JAR_SIGNER = null
@@ -44,17 +43,128 @@ ext {
]
}
MAPPING_CHANNEL = 'official'
- MAPPING_VERSION = '1.16.5'
- MC_VERSION = '1.16.5'
- MCP_VERSION = '20210115.111550'
- SPI_VERSION = '3.2.0'
+ MAPPING_VERSION = '1.17.1'
+ MC_VERSION = '1.17.1'
+ MCP_VERSION = '20210706.113038'
+ SPI_VERSION = '4.0.9'
+ ACCESSTRANSFORMERS_VERSION = '8.0.4'
+ COREMODS_VERSION = '5.0.1'
+ EVENTBUS_VERSION = '5.0.3'
+ MODLAUNCHER_VERSION = '9.0.7'
+ SECUREJARHANDLER_VERSION = '0.9.44'
+ BOOTSTRAPLAUNCHER_VERSION = '0.1.15'
+ ASM_VERSION = '9.1'
+ INSTALLER_VERSION = '2.1.4'
+
+ GIT_INFO = gradleutils.gitInfo
+ VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, '[0-9]', MC_VERSION)
+ // FML_VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, 'FML', MC_VERSION)
+ FORGE_VERSION = VERSION.substring(MC_VERSION.length() + 1)
+
+ SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.10.0'
+ VIGNETTE = 'net.minecraftforge.lex:vignette:0.2.0.16'
+ BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.0.12:fatjar'
+ INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.2.7'
+ JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
+}
+
+println('Version: ' + VERSION +
+ ' Java: ' + System.getProperty('java.version') +
+ ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ')' +
+ ' Arch: ' + System.getProperty('os.arch'))
+
+def extraTxts = [
+ rootProject.file('CREDITS.txt'),
+ rootProject.file('LICENSE.txt')
+]
+
+def changelog = rootProject.file('build/changelog.txt')
+if (changelog.exists())
+ extraTxts += changelog
+
+subprojects {
+ apply plugin: 'maven-publish'
+ apply plugin: 'eclipse'
+ apply plugin: 'java'
+
+ group = 'net.minecraftforge'
+ version = VERSION
+ //println(name + ' Version: ' + version)
+
+ ext {
+ isNonStable = { String version ->
+ def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { ver -> version.toUpperCase().contains(ver) }
+ def regex = /^[0-9,.v-]+(-r)?$/
+ return !stableKeyword && !(version ==~ regex)
+ }
+ }
+
+ repositories {
+ mavenLocal()
+ mavenCentral()
+ maven {
+ name = 'forge'
+ url = 'https://maven.minecraftforge.net/'
+ }
+ }
+
+ java.toolchain.languageVersion = JavaLanguageVersion.of(16)
+
+ publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ // Normal Maven/old gradle doesn't support '2.+' version wildcards
+ // For now we just suppress. We *should* force the resolution to pinned versions.
+ suppressPomMetadataWarningsFor('apiElements')
+ suppressPomMetadataWarningsFor('runtimeElements')
+ pom {
+ name = project.name
+ description = 'Modifactions to Minecraft to enable mod developers.'
+ url = 'https://github.com/MinecraftForge/MinecraftForge'
+
+ scm {
+ url = 'https://github.com/MinecraftForge/MinecraftForge'
+ connection = 'scm:git:git://github.com/MinecraftForge/MinecraftForge.git'
+ developerConnection = 'scm:git:git@github.com:MinecraftForge/MinecraftForge.git'
+ }
+
+ issueManagement {
+ system = 'github'
+ url = 'https://github.com/MinecraftForge/MinecraftForge/issues'
+ }
+
+ licenses {
+ license {
+ name = 'LGPL 2.1'
+ url = 'https://github.com/MinecraftForge/MinecraftForge/blob/1.13-pre/LICENSE.txt'
+ distribution = 'repo'
+ }
+ }
+ }
+ }
+ }
+ repositories {
+ maven {
+ if (System.env.MAVEN_USER) {
+ url 'https://maven.minecraftforge.net/releases/'
+ authentication {
+ basic(BasicAuthentication)
+ }
+ credentials {
+ username = System.env.MAVEN_USER ?: 'not'
+ password = System.env.MAVEN_PASSWORD ?: 'set'
+ }
+ } else {
+ url 'file://' + rootProject.file('repo').getAbsolutePath()
+ }
+ }
+ }
+ }
}
project(':mcp') {
apply plugin: 'net.minecraftforge.gradle.mcp'
- repositories {
- mavenLocal()
- }
+ tasks.withType(AbstractPublishToMaven.class).forEach{tsk -> tsk.enabled = false } // We don't want to publish anything
mcp {
config MC_VERSION + '-' + MCP_VERSION
pipeline = 'joined'
@@ -63,20 +173,13 @@ project(':mcp') {
project(':clean') {
evaluationDependsOn(':mcp')
- apply plugin: 'eclipse'
apply plugin: 'net.minecraftforge.gradle.patcher'
-
- java.toolchain.languageVersion = JavaLanguageVersion.of(8)
-
- repositories {
- mavenLocal()
- mavenCentral()
- }
-
+ tasks.withType(AbstractPublishToMaven.class).forEach{tsk -> tsk.enabled = false } // We don't want to publish anything
+
dependencies {
implementation 'net.minecraftforge:forgespi:' + SPI_VERSION
}
-
+
patcher {
parent = project(':mcp')
mcVersion = MC_VERSION
@@ -86,7 +189,9 @@ project(':clean') {
runs {
clean_client {
+ client true
taskName 'clean_client'
+ ideaModule "${rootProject.name}.${project.name}.main"
main 'net.minecraft.client.main.Main'
workingDirectory project.file('run')
@@ -99,7 +204,9 @@ project(':clean') {
}
clean_server {
+ client false
taskName 'clean_server'
+ ideaModule "${rootProject.name}.${project.name}.main"
main 'net.minecraft.server.Main'
workingDirectory project.file('run')
@@ -108,46 +215,578 @@ project(':clean') {
}
}
-project(':forge') {
+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}"
+
+ installer "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}"
+ installer "org.ow2.asm:asm:${ASM_VERSION}"
+ installer "org.ow2.asm:asm-commons:${ASM_VERSION}"
+ installer "org.ow2.asm:asm-tree:${ASM_VERSION}"
+ installer "org.ow2.asm:asm-util:${ASM_VERSION}"
+ installer "org.ow2.asm:asm-analysis:${ASM_VERSION}"
+ installer "net.minecraftforge:accesstransformers:${ACCESSTRANSFORMERS_VERSION}"
+ installer 'org.antlr:antlr4-runtime:4.9.1' //Dep of AccessTransformer
+ installer "net.minecraftforge:eventbus:${EVENTBUS_VERSION}"
+ installer "net.minecraftforge:forgespi:${SPI_VERSION}"
+ installer "net.minecraftforge:coremods:${COREMODS_VERSION}"
+ installer "cpw.mods:modlauncher:${MODLAUNCHER_VERSION}"
+ installer 'net.minecraftforge:unsafe:0.2.+'
+ installer 'com.electronwill.night-config:core:3.6.3'
+ installer 'com.electronwill.night-config:toml:3.6.3'
+ installer 'org.apache.maven:maven-artifact:3.6.3'
+ installer 'org.apache.commons:commons-lang3:3.8.1'
+ installer 'net.jodah:typetools:0.8.3'
+ installer 'org.apache.logging.log4j:log4j-api:2.14.1'
+ installer 'org.apache.logging.log4j:log4j-core:2.14.1'
+ installer 'net.minecrell:terminalconsoleappender:1.2.0'
+ installer 'org.jline:jline-reader:3.12.+' //Dep of TerminaalConsoleeAppender
+ installer 'org.jline:jline-terminal:3.12.+' //Dep of TerminaalConsoleeAppender
+ installer 'net.sf.jopt-simple:jopt-simple:5.0.4'
+ // installer 'org.spongepowered:mixin:0.8.3'
+ installer 'org.openjdk.nashorn:nashorn-core:15.1.1'
+ installer 'com.google.guava:guava:21.0'
+ installer 'com.google.code.gson:gson:2.8.0'
+
+ /*
+ installer 'org.lwjgl:lwjgl:3.2.2'
+ installer 'org.lwjgl:lwjgl-glfw:3.2.2'
+ installer 'org.lwjgl:lwjgl-opengl:3.2.2'
+ installer 'org.lwjgl:lwjgl-stb:3.2.2'
+ */
+}
+
+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 = VIGNETTE
+ args = [
+ '--jar-in', '{input}',
+ '--jar-out', '{output}',
+ '--mapping-format', 'tsrg2',
+ '--mappings', '{mappings}',
+ // '--stable',
+ '--create-inits', '--fix-param-annotations', '--fernflower-meta'
+ ]
+ mappings = prj.tasks.createMcp2Srg.srg
+ input = prj.tasks.getByName("download${side}Slim").output
+ output = 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()}") {
+ onlyIf {
+ JAR_SIGNER != null && t.state.failure == null
+ }
+ def jarsigner = JAR_SIGNER == null ? [:] : JAR_SIGNER
+ alias = 'forge'
+ storePass = jarsigner.storepass
+ keyPass = jarsigner.keypass
+ keyStore = jarsigner.keystore
+ inputFile = t.archiveFile.get().asFile
+ outputFile = t.archiveFile.get().asFile
+ doFirst {
+ prj.logger.lifecycle('Signing: ' + inputFile)
+ }
+ }
+ t.finalizedBy(signTask)
+ }
+ }
+
+ 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)
+ modules.add(lib.name)
+ }
+ for (child in prj.ext.PACKED_DEPS) {
+ libraries.add(Util.getMavenDep(rootProject.tasks.findByPath(child)))
+ }
+ //libraries.add("${project.group}:${project.name}:${project.version}:launcher")
+ 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}'
+
+ property 'nativesDirectory', '{natives}'
+
+ args '--launchTarget', "${launchPrefix}clientuserdev"
+ args '--version', 'MOD_DEV'
+ args '--assetIndex', '{asset_index}'
+ args '--assetsDir', '{assets_root}'
+ }
+
+ server {
+ environment 'MOD_CLASSES', '{source_roots}'
+ environment 'MCP_MAPPINGS', '{mcp_mappings}'
+
+ args '--launchTarget', "${launchPrefix}serveruserdev"
+ }
+
+ data {
+ environment 'MOD_CLASSES', '{source_roots}'
+ environment 'MCP_MAPPINGS', '{mcp_mappings}'
+
+ args '--launchTarget', "${launchPrefix}datauserdev"
+ args '--assetIndex', '{asset_index}'
+ args '--assetsDir', '{assets_root}'
+ }
+ }
+ }
+
+ def userdevRuns = prj.tasks.userdevConfig.runs
+ for (def run : prj.patcher.runs + userdevRuns) {
+ if (run.parents) continue // We already added this to the parent run config
+ //run.property 'bsl.debug', 'true'
+ run.main 'cpw.mods.bootstraplauncher.BootstrapLauncher'
+
+ run.args '--gameDir', '.'
+ run.args '--fml.forgeVersion', FORGE_VERSION
+ run.args '--fml.mcVersion', MC_VERSION
+ run.args '--fml.forgeGroup', prj.group
+ run.args '--fml.mcpVersion', MCP_VERSION
+
+ if (run.name.contains('client')) {
+ run.client true
+ } else {
+ run.client false
+ }
+
+ // SecureJarHandler bootstrap values.
+ run.property 'legacyClassPath', '{runtime_classpath}'
+ run.property 'ignoreList', prj.configurations.moduleonly.files.collect {it.name}.join(',') + ",client-extra,fmlcore,javafmllanguage,mclanguage,${prj.name}-${prj.version},${prj.rootProject.ext.MC_VERSION}-${prj.name}${prj.version.substring(prj.rootProject.ext.MC_VERSION.length())}"
+ run.property 'mergeModules', 'jna-5.8.0.jar,jna-platform-58.0.jar,java-objc-bridge-1.0.0.jar'
+ if (userdevRuns.contains(run)) {
+ run.jvmArgs '-p', '{modules}'
+ } else {
+ run.jvmArgs '-p', prj.configurations.moduleonly.files.collect { it.path }.join(File.pathSeparator)
+ }
+ run.jvmArgs '--add-modules', 'ALL-MODULE-PATH'
+ run.jvmArgs '--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler'
+ run.jvmArgs '--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler'
+ 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
+ run.workingDirectory prj.file('run')
+
+ if (run.name.contains('client') || run.name.contains('data')) {
+ 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'
+ }
+ }
+
+ def MODULE_PATH = Util.getArtifacts(prj, prj.configurations.moduleonly, false).values().collect{"libraries/${it.downloads.artifact.path}"}
+ def CLASS_PATH = Util.getArtifacts(prj, prj.configurations.installer, false).values().collect{"libraries/${it.downloads.artifact.path}"} +
+ [
+ 'libraries/' + Util.getMavenPath(rootProject.tasks.findByPath(':fmlloader:jar')),
+ "libraries/net/minecraft/server/${MC_VERSION}-${MCP_VERSION}/server-${MC_VERSION}-${MCP_VERSION}-extra.jar"
+ ]
+ def tokens = [
+ TASK: prj.name.equals('forge') ? 'forgeserver' : 'fmlserver',
+ MAVEN_PATH: prj.ext.MAVEN_PATH.toString(),
+ FORGE_VERSION: FORGE_VERSION,
+ MC_VERSION: MC_VERSION,
+ MCP_VERSION: MCP_VERSION,
+ FORGE_GROUP: prj.group,
+ IGNORE_LIST: Util.getArtifacts(prj, prj.configurations.moduleonly, false).values().collect{it.downloads.artifact.path.rsplit('/', 1)[1]}.join(','),
+ MODULES: 'ALL-MODULE-PATH'
+ ]
+
+ prj.afterEvaluate {
+ prj.installerJar {
+ from(rootProject.file('server_files/')) {
+ 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"
+ }
+
+ from(rootProject.file('server_files/args.txt')) {
+ filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(';'), CLASS_PATH: CLASS_PATH.join(';')])
+ rename { 'data/win_args.txt' }
+ }
+
+ from(rootProject.file('server_files/args.txt')) {
+ filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(':'), CLASS_PATH: CLASS_PATH.join(':')])
+ rename { 'data/unix_args.txt' }
+ }
+ }
+ }
+}
+
+def symlink = file("$rootDir/fmlonly/src/fmlcommon")
+def symlinkValid = symlink.exists() && symlink.directory
+
+if (symlinkValid)
+project(':fmlonly') {
+ evaluationDependsOn(':mcp')
+ apply plugin: 'java-library'
+ apply plugin: 'net.minecraftforge.gradle.patcher'
+
+ ext {
+ MCP_ARTIFACT = project(':mcp').mcp.config.get()
+ PACKED_DEPS = [':fmlcore:jar', ':fmlloader:jar', ':javafmllanguage:jar', ':mclanguage:jar']
+ MAVEN_PATH = "${group.replace('.', '/')}/${project.name}/${VERSION}"
+ }
+
+ sourceSets {
+ main {
+ java {
+ srcDirs = ["$rootDir/fmlonly/src/fmlcommon/java", "$rootDir/fmlonly/src/main/java"]
+ }
+ resources {
+ srcDirs = ["$rootDir/fmlonly/src/fmlcommon/resources", "$rootDir/fmlonly/src/main/resources"]
+ }
+ }
+ }
+
+ configurations {
+ moduleonly
+ installer {
+ // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
+ transitive = false
+ }
+ api.extendsFrom(installer)
+ }
+
+ // TODO: Better coordination between project dependencies and the installer.
+ dependencies {
+ implementation project(':fmlcore')
+ implementation project(':fmlloader')
+ implementation project(':javafmllanguage')
+ implementation project(':mclanguage')
+ runtimeOnly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
+ }
+ dependencies sharedDeps
+
+ patcher {
+ parent = project(':mcp')
+ mcVersion = MC_VERSION
+ patchedSrc = file('src/main/java')
+
+ mappings channel: MAPPING_CHANNEL, version: MAPPING_VERSION
+ runs {
+ fmlonly_client {
+ args '--launchTarget', 'fmlclientdev'
+ ideaModule "${rootProject.name}.${project.name}.main"
+
+ mods {
+ minecraft { source sourceSets.main }
+ }
+ }
+ fmlonly_server {
+ args '--launchTarget', 'fmlserverdev'
+ ideaModule "${rootProject.name}.${project.name}.main"
+
+ mods {
+ minecraft { source sourceSets.main }
+ }
+ }
+ }
+ }
+
+ sharedFmlonlyForge.call(project)
+
+ task launcherJson(type: LauncherJson) {
+ packedDependencies = [':fmlloader:jar']
+ doFirst {
+ def fmlonly_client = project(':fmlonly').patcher.runs.fmlonly_client
+ json = [
+ _comment_: comment,
+ id: id,
+ time: timestamp,
+ releaseTime: timestamp,
+ type: 'release',
+ mainClass: 'cpw.mods.bootstraplauncher.BootstrapLauncher',
+ inheritsFrom: MC_VERSION,
+ logging: {},
+ arguments: [
+ game: ['--launchTarget', 'fmlclient',
+ '--fml.forgeVersion', FORGE_VERSION,
+ '--fml.mcVersion', MC_VERSION,
+ '--fml.forgeGroup', project.group,
+ '--fml.mcpVersion', MCP_VERSION],
+ jvm: ['-DlegacyClassPath=${classpath}',
+ "-DignoreList=${fmlonly_client.properties.ignoreList}",
+ "-DmergeModules=${fmlonly_client.properties.mergeModules}",
+ '-DlibraryDirectory=${library_directory}',
+ '-p', Util.getArtifacts(project, configurations.moduleonly, false).values().collect{"\${library_directory}/${it.downloads.artifact.path}"}.join('${classpath_separator}'),
+ '--add-modules', 'ALL-MODULE-PATH',
+ '--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
+ '--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
+ '--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
+ ]
+ ],
+ libraries: []
+ ]
+ }
+ }
+
+ task installerJson(type: InstallerJson) {
+ icon = rootProject.file('icon.ico')
+ packedDependencies = PACKED_DEPS
+
+ doFirst {
+ def libs = libraries
+ json = [
+ _comment_: launcherJson.comment,
+ spec: 1,
+ profile: project.name,
+ version: launcherJson.id,
+ path: null,
+ minecraft: MC_VERSION,
+ serverJarPath: '{LIBRARY_DIR}/net/minecraft/server/{MINECRAFT_VERSION}/server-{MINECRAFT_VERSION}.jar',
+ welcome: "Welcome to the simple FML installer.",
+ data: [
+ MAPPINGS: [
+ client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings@txt]",
+ server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings@txt]"
+ ],
+ MOJMAPS: [
+ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:mappings@txt]",
+ server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:mappings@txt]"
+ ],
+ MERGED_MAPPINGS: [
+ client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]",
+ server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]"
+ ],
+ MC_SLIM: [
+ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:slim]",
+ server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]"
+ ],
+ MC_SLIM_SHA: [
+ client: "'${downloadClientSlim.output.get().asFile.sha1()}'",
+ server: "'${downloadServerSlim.output.get().asFile.sha1()}'"
+ ],
+ MC_EXTRA: [
+ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:extra]",
+ server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:extra]"
+ ],
+ MC_EXTRA_SHA: [
+ client: "'${downloadClientExtra.output.get().asFile.sha1()}'",
+ server: "'${downloadServerExtra.output.get().asFile.sha1()}'"
+ ],
+ MC_SRG: [
+ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:srg]",
+ server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:srg]"
+ ],
+ /*MC_SRG_SHA: [
+ client: "'${createClientSRG.output.sha1()}'",
+ server: "'${createServerSRG.output.sha1()}'"
+ ],*/
+ MCP_VERSION: [
+ client: "'${MCP_VERSION}'",
+ server: "'${MCP_VERSION}'"
+ ]
+ ],
+ processors: [
+ [
+ sides: ['server'],
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'EXTRACT_FILES',
+ '--archive', '{INSTALLER}',
+
+ '--from', 'data/run.sh',
+ '--to', '{ROOT}/run.sh',
+ '--exec', '{ROOT}/run.sh',
+ //'--from', "data/run_fml_${VERSION.replace('-', '_').sh",
+ //'--to', '{ROOT}/run_fml_${VERSION.replace('-', '_').sh',
+ //'--exec', '{ROOT}/run_fml_${VERSION.replace('-', '_').sh',
+
+ '--from', 'data/run.bat',
+ '--to', '{ROOT}/run.bat',
+ //'--from', 'data/run_fml_${VERSION.replace('-', '_').bat',
+ //'--to', '{ROOT}/run_fml_${VERSION.replace('-', '_').bat',
+
+ '--from', 'data/user_jvm_args.txt',
+ '--to', '{ROOT}/user_jvm_args.txt',
+ '--optional', '{ROOT}/user_jvm_args.txt',
+
+ '--from', 'data/win_args.txt',
+ '--to', "{ROOT}/libraries/${MAVEN_PATH}/win_args.txt",
+
+ '--from', 'data/unix_args.txt',
+ '--to', "{ROOT}/libraries/${MAVEN_PATH}/unix_args.txt"
+ ]
+ ], [
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'MCP_DATA',
+ '--input', "[${MCP_ARTIFACT.descriptor}]",
+ '--output', '{MAPPINGS}',
+ '--key', 'mappings'
+ ]
+ ], [
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'DOWNLOAD_MOJMAPS',
+ '--version', MC_VERSION,
+ '--side', '{SIDE}',
+ '--output', '{MOJMAPS}'
+ ]
+ ], [
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'MERGE_MAPPING',
+ '--left', '{MAPPINGS}',
+ '--right', '{MOJMAPS}',
+ '--output', '{MERGED_MAPPINGS}',
+ '--classes', '--reverse-right'
+ ]
+ ], [
+ jar: JAR_SPLITTER,
+ classpath: getClasspath(project, libs, JAR_SPLITTER),
+ args: [
+ '--input', '{MINECRAFT_JAR}',
+ '--slim', '{MC_SLIM}',
+ '--extra', '{MC_EXTRA}',
+ '--srg', '{MERGED_MAPPINGS}'
+ ],
+ outputs: [
+ '{MC_SLIM}': '{MC_SLIM_SHA}',
+ '{MC_EXTRA}': '{MC_EXTRA_SHA}'
+ ]
+ ], [
+ jar: VIGNETTE,
+ classpath: getClasspath(project, libs, VIGNETTE),
+ args: [
+ '--jar-in', '{MC_SLIM}',
+ '--jar-out', '{MC_SRG}',
+ '--mapping-format', 'tsrg2',
+ '--mappings', '{MERGED_MAPPINGS}',
+ // '--stable',
+ '--create-inits', '--fix-param-annotations', '--fernflower-meta'
+ ]/*,
+ outputs: [
+ '{MC_SRG}': '{MC_SRG_SHA}'
+ ]
+ */
+ ]
+ ]
+ ]
+ getClasspath(project, libs, MCP_ARTIFACT.descriptor) //Tell it to download mcp_config
+ }
+ }
+
+ task installerJar(type: InstallerJar) {
+ packedDependencies = PACKED_DEPS
+ from(extraTxts)
+ //TODO: make FML installer logo?
+ from(rootProject.file('/forge_installer_logo.png')) {
+ rename { 'big_logo.png' }
+ }
+ }
+
+ publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ artifact universalJar
+ artifact installerJar
+ artifact userdevJar
+ artifact sourcesJar
+ }
+ }
+ }
+
+ // Since we need the modules in the bootstrap, we need to make sure they are compiled before we do each run
+ afterEvaluate { prepareRuns.dependsOn(':fmlcore:jar', ':fmlloader:jar', ':javafmllanguage:jar', ':mclanguage:jar') }
+}
+
+project(':forge') {
evaluationDependsOn(':clean')
apply plugin: 'java-library'
- apply plugin: 'maven-publish'
- apply plugin: 'eclipse'
apply plugin: 'net.minecraftforge.gradle.patcher'
apply plugin: 'org.cadixdev.licenser'
- java.toolchain.languageVersion = JavaLanguageVersion.of(8)
- group = 'net.minecraftforge'
-
sourceSets {
- fmllauncher {
- java {
- srcDirs = ["$rootDir/src/fmllauncher/java"]
- }
- resources {
- srcDirs = ["$rootDir/src/fmllauncher/resources"]
- }
- }
main {
- compileClasspath += sourceSets.fmllauncher.runtimeClasspath
- runtimeClasspath += sourceSets.fmllauncher.runtimeClasspath
java {
- srcDirs = ["$rootDir/src/main/java"]
+ srcDirs = [
+ "$rootDir/src/main/java",
+ "$rootDir/src/fmlcommon/java"
+ ]
}
resources {
srcDirs = [
"$rootDir/src/main/resources",
- "$rootDir/src/generated/resources"
+ "$rootDir/src/generated/resources",
+ "$rootDir/src/fmlcommon/resources"
]
}
}
test {
- compileClasspath += sourceSets.fmllauncher.runtimeClasspath
- runtimeClasspath += sourceSets.fmllauncher.runtimeClasspath
java {
srcDirs = [
- "$rootDir/src/test/java",
- "$rootDir/src/fmllaunchertest/java"
+ "$rootDir/src/test/java"
]
}
resources {
@@ -157,47 +796,41 @@ project(':forge') {
]
}
}
- userdev {
- compileClasspath += sourceSets.main.runtimeClasspath
- runtimeClasspath += sourceSets.main.runtimeClasspath
- java {
- srcDirs = ["$rootDir/src/userdev/java"]
- }
- resources {
- srcDirs = ["$rootDir/src/userdev/resources"]
- }
- }
- userdev_test {
- compileClasspath += sourceSets.userdev.runtimeClasspath
- runtimeClasspath += sourceSets.userdev.runtimeClasspath
- compileClasspath += sourceSets.test.runtimeClasspath
- runtimeClasspath += sourceSets.test.runtimeClasspath
- }
}
//Eclipse adds the sourcesets twice, once where we tell it to, once in the projects folder. No idea why. So delete them
eclipse.classpath.file.whenMerged { cls -> cls.entries.removeIf { e -> e instanceof SourceFolder && e.path.startsWith('src/') && !e.path.startsWith('src/main/') } }
- repositories {
- mavenLocal()
- mavenCentral()
- }
-
ext {
- GIT_INFO = gradleutils.gitInfo
- SPEC_VERSION = GIT_INFO.tag
+ SPEC_VERSION = gradleutils.gitInfo.tag
// The new versioning sceme is -..
// ForgeMC is a unique identifier for every MC version we have supported.
// Essentially, the same as the old, except dropping the first number, and the builds are no longer unique.
MCP_ARTIFACT = project(':mcp').mcp.config.get()
- SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.10.0'
- SPECIAL_SOURCE_MCP = 'net.md-5:SpecialSource:1.8.5'
VERSION_JSON = project(':mcp').file('build/mcp/downloadJson/version.json')
- BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.0.12:fatjar'
- INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.2.6'
+ PACKED_DEPS = [':fmlcore:jar', ':fmlloader:jar', ':javafmllanguage:jar', ':mclanguage:jar']
+ MAVEN_PATH = "${group.replace('.', '/')}/${project.name}/${VERSION}"
}
- version = gradleutils.getMCTagOffsetBranchVersion(MC_VERSION)
- println('Forge Version: ' + version)
+ configurations {
+ installer {
+ // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
+ transitive = false
+ }
+ moduleonly
+ api.extendsFrom(installer)
+ }
+
+ dependencies {
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
+ testImplementation 'org.junit.vintage:junit-vintage-engine:5.+'
+ testImplementation 'org.opentest4j:opentest4j:1.2.0' // needed for junit 5
+ testImplementation 'org.hamcrest:hamcrest-all:1.3' // needs advanced matching for list order
+ implementation project(':fmlcore')
+ implementation project(':fmlloader')
+ implementation project(':javafmllanguage')
+ implementation project(':mclanguage')
+ }
+ dependencies sharedDeps
patcher {
excs.from file("$rootDir/src/main/resources/forge.exc")
@@ -210,32 +843,11 @@ project(':forge') {
runs {
forge_client {
- taskName 'forge_client'
-
- main 'net.minecraftforge.userdev.LaunchTesting'
- workingDirectory project.file('run')
-
- environment 'target', 'fmldevclient'
- environment 'assetIndex', '{asset_index}'
- environment 'assetDirectory', downloadAssets.output
- environment 'nativesDirectory', extractNatives.output.get().asFile
-
- environment 'MC_VERSION', MC_VERSION
- environment 'MCP_VERSION', MCP_VERSION
- environment 'FORGE_GROUP', project.group
- environment 'FORGE_SPEC', SPEC_VERSION
- environment 'FORGE_VERSION', project.version.substring(MC_VERSION.length() + 1)
- environment 'LAUNCHER_VERSION', SPEC_VERSION
- property 'org.lwjgl.system.SharedLibraryExtractDirectory', 'lwjgl_dll'
property 'eventbus.checkTypesOnDispatch', 'true'
-
- ideaModule "${rootProject.name}.${project.name}.userdev"
-
+ args '--launchTarget', 'forgeclientdev'
+ ideaModule "${rootProject.name}.${project.name}.main"
mods {
- forge {
- source sourceSets.main
- source sourceSets.userdev
- }
+ minecraft { source sourceSets.main }
}
}
@@ -245,34 +857,19 @@ project(':forge') {
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
- ideaModule "${rootProject.name}.${project.name}.userdev_test"
+ ideaModule "${rootProject.name}.${project.name}.test"
mods {
- forge { source sourceSets.main }
tests { sources sourceSets.test }
}
}
forge_server {
- taskName 'forge_server'
-
- main 'net.minecraftforge.userdev.LaunchTesting'
- workingDirectory project.file('run')
-
- environment 'target', 'fmldevserver'
-
- environment 'MC_VERSION', MC_VERSION
- environment 'MCP_VERSION', MCP_VERSION
- environment 'FORGE_GROUP', project.group
- environment 'FORGE_SPEC', SPEC_VERSION
- environment 'FORGE_VERSION', project.version.substring(MC_VERSION.length() + 1)
- environment 'LAUNCHER_VERSION', SPEC_VERSION
- property 'eventbus.checkTypesOnDispatch', 'true'
-
- ideaModule "${rootProject.name}.${project.name}.userdev"
+ args '--launchTarget', 'forgeserverdev'
+ ideaModule "${rootProject.name}.${project.name}.main"
mods {
- forge { source sourceSets.main }
+ minecraft { source sourceSets.main }
}
}
@@ -282,39 +879,30 @@ project(':forge') {
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
- ideaModule "${rootProject.name}.${project.name}.userdev_test"
+ ideaModule "${rootProject.name}.${project.name}.test"
mods {
- forge { source sourceSets.main }
tests { sources sourceSets.test }
}
}
+ def forgeDataArgs = [
+ '--mod', 'forge',
+ '--all',
+ '--output', rootProject.file('src/generated/resources/'),
+ '--validate',
+ '--existing', sourceSets.main.resources.srcDirs[0]
+ ]
forge_data {
taskName 'forge_data'
-
- main 'net.minecraftforge.userdev.LaunchTesting'
- workingDirectory project.file('run')
-
- environment 'target', 'fmldevdata'
- environment 'assetIndex', '{asset_index}'
- environment 'assetDirectory', downloadAssets.output
-
- environment 'MC_VERSION', MC_VERSION
- environment 'MCP_VERSION', MCP_VERSION
- environment 'FORGE_GROUP', project.group
- environment 'FORGE_SPEC', SPEC_VERSION
- environment 'FORGE_VERSION', project.version.substring(MC_VERSION.length() + 1)
- environment 'LAUNCHER_VERSION', SPEC_VERSION
-
- ideaModule "${rootProject.name}.${project.name}.userdev"
+ args '--launchTarget', 'forgedatadev'
+ ideaModule "${rootProject.name}.${project.name}.main"
mods {
- forge { source sourceSets.main }
+ minecraft { source sourceSets.main }
}
-
- args '--mod', 'forge', '--all', '--output', rootProject.file('src/generated/resources/'), '--validate',
- '--existing', sourceSets.main.resources.srcDirs[0]
+
+ args forgeDataArgs
}
forge_test_data {
@@ -323,32 +911,39 @@ project(':forge') {
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
- ideaModule "${rootProject.name}.${project.name}.userdev_test"
+ ideaModule "${rootProject.name}.${project.name}.test"
mods {
- tests { sources sourceSets.test }
+ 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', 'data_gen_test',
+ '--mod', 'piston_event_test',
+ '--mod', 'global_loot_test',
+ '--mod', 'scaffolding_test',
+ '--mod', 'custom_tag_types_test',
+ '--mod', 'new_model_loader_test',
+ '--output', rootProject.file('src/generated_test/resources/'),
+ '--existing', sourceSets.main.resources.srcDirs[0],
+ '--existing', sourceSets.test.resources.srcDirs[0]
}
-
- args '--flat', '--all', '--validate',
- '--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',
- '--output', rootProject.file('src/generated_test/resources/'),
- '--existing', sourceSets.main.resources.srcDirs[0],
- '--existing', sourceSets.test.resources.srcDirs[0]
}
}
}
-
+
ext {
MANIFESTS = [
'/': [
'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
- 'GitCommit': GIT_INFO.abbreviatedId,
- 'Git-Branch': GIT_INFO.branch
+ 'GitCommit': gradleutils.gitInfo.abbreviatedId,
+ 'Git-Branch': gradleutils.gitInfo.branch
] as LinkedHashMap,
'net/minecraftforge/versions/forge/': [
'Specification-Title': 'Forge',
@@ -389,104 +984,22 @@ project(':forge') {
'Implementation-Title': 'FML Launcher',
'Implementation-Version': SPEC_VERSION,
'Implementation-Vendor': 'Forge'
- ] as LinkedHashMap,
- 'net/minecraftforge/fml/userdev/': [
- 'Specification-Title': 'Forge User Development',
- 'Specification-Vendor': 'Forge Development LLC',
- 'Specification-Version': SPEC_VERSION,
- 'Implementation-Title': project.group,
- 'Implementation-Version': project.version.substring(MC_VERSION.length() + 1),
- 'Implementation-Vendor': 'Forge Development LLC'
] as LinkedHashMap
]
}
-
- configurations {
- installer {
- transitive = false //Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
- }
- api.extendsFrom(installer)
- fmllauncherImplementation.extendsFrom(installer, implementation)
- }
- dependencies {
- installer 'org.ow2.asm:asm:9.1'
- installer 'org.ow2.asm:asm-commons:9.1'
- installer 'org.ow2.asm:asm-tree:9.1'
- installer 'org.ow2.asm:asm-util:9.1'
- installer 'org.ow2.asm:asm-analysis:9.1'
- installer 'cpw.mods:modlauncher:8.0.9'
- installer 'cpw.mods:grossjava9hacks:1.3.3'
- installer 'net.minecraftforge:accesstransformers:3.0.1'
- installer 'org.antlr:antlr4-runtime:4.9.1' //Dep of AccessTransformer
- installer 'net.minecraftforge:eventbus:4.0.+'
- installer 'net.minecraftforge:forgespi:' + SPI_VERSION
- installer 'net.minecraftforge:coremods:4.0.+'
- installer 'net.minecraftforge:unsafe:0.2.+'
- installer 'com.electronwill.night-config:core:3.6.3'
- installer 'com.electronwill.night-config:toml:3.6.3'
- installer 'org.jline:jline:3.12.+'
- installer 'org.apache.maven:maven-artifact:3.6.3'
- installer 'net.jodah:typetools:0.8.3'
- installer 'org.apache.logging.log4j:log4j-api:2.11.2'
- installer 'org.apache.logging.log4j:log4j-core:2.11.2'
- installer 'net.minecrell:terminalconsoleappender:1.2.0'
- installer 'net.sf.jopt-simple:jopt-simple:5.0.4'
- installer 'org.spongepowered:mixin:0.8.2'
- // This is org.openjdk.nashorn:nashorn-core:15.1.1 repackaged so it doesn't crash on JREs < 15.
- // See: https://github.com/LexManos/NashornLegacyPackager
- installer 'net.minecraftforge:nashorn-core-compat:15.1.1.1'
- fmllauncherImplementation 'com.google.guava:guava:21.0'
- fmllauncherImplementation 'com.google.code.gson:gson:2.8.0'
- fmllauncherImplementation 'org.lwjgl:lwjgl:3.2.2'
- fmllauncherImplementation 'org.lwjgl:lwjgl-glfw:3.2.2'
- fmllauncherImplementation 'org.lwjgl:lwjgl-opengl:3.2.2'
- fmllauncherImplementation 'org.lwjgl:lwjgl-stb:3.2.2'
- testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
- testImplementation 'org.junit.vintage:junit-vintage-engine:5.+'
- testImplementation 'org.opentest4j:opentest4j:1.2.0' // needed for junit 5
- testImplementation 'org.hamcrest:hamcrest-all:1.3' // needs advanced matching for list order
- }
-
- def extraTxts = [
- rootProject.file('CREDITS.txt'),
- rootProject.file('LICENSE.txt')
- ]
-
- def changelog = rootProject.file('build/changelog.txt')
- if (changelog.exists())
- extraTxts += changelog
-
+
task crowdin(type: Crowdin) {
key = project.hasProperty('crowdinKey') ? project.crowdinKey : null
//TODO: Merge our english.json?
}
-
- // We apply the bin patches we just created to make a jar that is JUST our changes
- ['Client', 'Server', 'Joined'].each { side ->
- def gen = tasks.getByName("gen${side}BinPatches")
- gen.tool = BINPATCH_TOOL
- task "apply${side}BinPatches"(type: net.minecraftforge.gradle.common.tasks.ApplyBinPatches, dependsOn: gen) {
- clean = gen.cleanJar
- patch = gen.output
- tool = BINPATCH_TOOL
- }
- def srgTask = tasks.getByName(patcher.notchObf ? 'createMcp2Obf' : 'createMcp2Srg')
- // Create SRG named Vanilla jars, using the SpecialSource we have in the installer
- task "create${side}SRG"(type: net.minecraftforge.gradle.userdev.tasks.RenameJar, dependsOn: srgTask) {
- tool = SPECIAL_SOURCE_MCP + ':shaded'
- args = ['--stable', '--in-jar', '{input}', '--out-jar', '{output}', '--srg-in', '{mappings}']
- mappings = srgTask.output
- input = gen.cleanJar
- output = file("build/create${name}SRG/output.jar")
- }
- }
-
+ sharedFmlonlyForge.call(project)
+
task downloadLibraries(type: DownloadLibraries, dependsOn: ':mcp:setupMCP') {
input = VERSION_JSON
output = rootProject.file('build/libraries/')
}
-
+
task extractInheritance(type: ExtractInheritance, dependsOn: [genJoinedBinPatches, downloadLibraries]) {
tool = INSTALLER_TOOLS + ':fatjar'
input = genJoinedBinPatches.cleanJar
@@ -494,38 +1007,21 @@ project(':forge') {
}
task findFieldInstanceChecks(type: FieldCompareFinder, dependsOn: ['createJoinedSRG']) {
- jar = tasks.getByName('createJoinedSRG').output
+ jar = createJoinedSRG.output
output = rootProject.file('src/main/resources/coremods/field_to_instanceof.json')
fields {
+ /* 1.17 changed most things to use Tags. So this isn't nessasary anymore so just make an empty list
bows {
- cls = 'net/minecraft/item/Items'
- name = 'field_151031_f'
- replacement = 'net/minecraft/item/BowItem'
+ cls = 'net/minecraft/world/item/Items'
+ name = 'f_42411_'
+ replacement = 'net/minecraft/world/item/BowItem'
}
crossbows {
- cls = 'net/minecraft/item/Items'
- name = 'field_222114_py'
- replacement = 'net/minecraft/item/CrossbowItem'
- }
- filled_map {
- cls = 'net/minecraft/item/Items'
- name = 'field_151098_aY'
- replacement = 'net/minecraft/item/FilledMapItem'
- blacklist 'net/minecraft/client/gui/screen/inventory/CartographyTableScreen', 'func_230450_a_', '(Lcom/mojang/blaze3d/matrix/MatrixStack;FII)V'
- blacklist 'net/minecraft/client/renderer/entity/ItemFrameRenderer', 'func_225623_a_', '(Lnet/minecraft/entity/item/ItemFrameEntity;FFLcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;I)V'
- blacklist 'net/minecraft/item/crafting/MapCloningRecipe'
- blacklist 'net/minecraft/item/crafting/MapExtendingRecipe'
- }
- fishing_rod {
- cls = 'net/minecraft/item/Items'
- name = 'field_151112_aM'
- replacement = 'net/minecraft/item/FishingRodItem'
- }
- shears {
- cls = 'net/minecraft/item/Items'
- name = 'field_151097_aZ'
- replacement = 'net/minecraft/item/ShearsItem'
+ cls = 'net/minecraft/world/item/Items'
+ name = 'f_42717_'
+ replacement = 'net/minecraft/world/item/CrossbowItem'
}
+ */
}
}
@@ -541,7 +1037,7 @@ project(':forge') {
}
task checkExcs(type: CheckExcs, dependsOn: jar) {
- binary = jar.archiveFile
+ binary = jar.archiveFile.get().asFile
excs.from patcher.excs
}
@@ -556,127 +1052,80 @@ project(':forge') {
patchDir = file("$rootDir/patches")
autoFix = false
}
+
genPatches {
finalizedBy checkPatches
autoHeader true
lineEnding = '\n'
}
- task launcherJson(dependsOn: ['signUniversalJar', 'signLauncherJar']) {
- inputs.file universalJar.archiveFile
- inputs.file { launcherJar.archiveFile }
- ext {
- output = file('build/version.json')
- vanilla = project(':mcp').file('build/mcp/downloadJson/version.json')
- timestamp = iso8601Now()
- comment = [
- "Please do not automate the download and installation of Forge.",
- "Our efforts are supported by ads from the download page.",
- "If you MUST automate this, please consider supporting the project through https://www.patreon.com/LexManos/"
- ]
- def idx = project.version.indexOf('-')
- id = project.version.substring(0, idx) + "-${project.name}" + project.version.substring(idx)
- }
- inputs.file vanilla
- outputs.file output
- doLast {
- def json_vanilla = vanilla.json()
- def json = [
+ task launcherJson(type: LauncherJson) {
+ packedDependencies = [':fmlloader:jar']
+ doFirst {
+ def forge_client = project(':forge').patcher.runs.forge_client
+ json = [
_comment_: comment,
id: id,
time: timestamp,
releaseTime: timestamp,
type: 'release',
- mainClass: 'cpw.mods.modlauncher.Launcher',
+ mainClass: 'cpw.mods.bootstraplauncher.BootstrapLauncher',
inheritsFrom: MC_VERSION,
logging: {},
arguments: [
- game: ['--launchTarget', 'fmlclient', '--fml.forgeVersion', "${project.version.substring(MC_VERSION.length() + 1)}", '--fml.mcVersion', "${MC_VERSION}", '--fml.forgeGroup', "${project.group}", '--fml.mcpVersion', "${MCP_VERSION}"],
- // Support running with Java 8 and up, including 16
- jvm: [
- // Allow these JVM args to not crash Java 8
- '-XX:+IgnoreUnrecognizedVMOptions',
- // ModLauncher uses sun.security.util.ManifestEntryVerifier and needs access to it
- '--add-exports=java.base/sun.security.util=ALL-UNNAMED',
- // JDK bug, not fixed properly - https://bugs.openjdk.java.net/browse/JDK-8186019
- '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming',
- // ModLauncher reflects field 'jv' in java.util.jar.JarVerifier
- '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
+ game: ['--launchTarget', 'forgeclient',
+ '--fml.forgeVersion', FORGE_VERSION,
+ '--fml.mcVersion', MC_VERSION,
+ '--fml.forgeGroup', project.group,
+ '--fml.mcpVersion', MCP_VERSION],
+ jvm: ['-DlegacyClassPath=${classpath}',
+ "-DignoreList=${forge_client.properties.ignoreList}",
+ "-DmergeModules=${forge_client.properties.mergeModules}",
+ '-DlibraryDirectory=${library_directory}',
+ '-p', Util.getArtifacts(project, configurations.moduleonly, false).values().collect{'${library_directory}/' + it.downloads.artifact.path}.join('${classpath_separator}'),
+ '--add-modules', 'ALL-MODULE-PATH',
+ '--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
+ '--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
+ '--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
]
],
- libraries: [
- [
- //Package our launcher jar as the 'main' jar Mojang's launcher loads. It will in turn load Forge's regular jars itself.
- name: "${project.group}:${project.name}:${project.version}",
- downloads: [
- artifact: [
- path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar",
- url: "", //Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier
- sha1: launcherJar.archiveFile.get().asFile.sha1(),
- size: launcherJar.archiveFile.get().asFile.length()
- ]
- ]
- ]
- ]
+ libraries: []
]
-
- def artifacts = getArtifacts(project, project.configurations.installer, false)
- artifacts.each { key, lib ->
- json.libraries.add(lib)
- }
-
- output.text = new JsonBuilder(json).toPrettyString()
}
}
- task installerJson(dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches/*, createClientSRG, createServerSRG*/]) {
+ task installerJson(type: InstallerJson, dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches]) {
ext {
- output = file('build/install_profile.json')
- JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
+ // remove :fatjar
+ BIN_PATCHER = BINPATCH_TOOL.substring(0, BINPATCH_TOOL.length() - 1 - BINPATCH_TOOL.split(':')[3].length())
}
+ input.from applyClientBinPatches.output, applyServerBinPatches.output, genClientBinPatches.toolJar, launcherJson.output
+ icon = rootProject.file('icon.ico')
+ packedDependencies = PACKED_DEPS
+
doFirst {
- ext.BIN_PATCHER = BINPATCH_TOOL.substring(0, BINPATCH_TOOL.length() - 1 - BINPATCH_TOOL.split(':')[3].length())
- }
- inputs.file applyClientBinPatches.output
- inputs.file applyServerBinPatches.output
- inputs.file genClientBinPatches.toolJar
- inputs.file launcherJson.output
- /*
- inputs.file createClientSRG.output
- inputs.file createServerSRG.output
- */
- outputs.file output
- doLast {
- def libs = [
- "${project.group}:${project.name}:${project.version}:universal": [
- name: "${project.group}:${project.name}:${project.version}:universal",
- downloads: [
- artifact: [
- path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}-universal.jar",
- url: "", //Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier
- sha1: universalJar.archiveFile.get().asFile.sha1(),
- size: universalJar.archiveFile.get().asFile.length()
- ]
- ]
- ]
- ]
- def json = [
+ def libs = libraries
+ json = [
_comment_: launcherJson.comment,
- spec: 0,
+ spec: 1,
profile: project.name,
version: launcherJson.id,
- icon: "data:image/png;base64," + new String(Base64.getEncoder().encode(Files.readAllBytes(rootProject.file("icon.ico").toPath()))),
- json: '/version.json',
- path: "${project.group}:${project.name}:${project.version}",
- logo: '/big_logo.png',
+ path: null,
minecraft: MC_VERSION,
- welcome: "Welcome to the simple ${project.name.capitalize()} installer.",
- mirrorList: "https://files.minecraftforge.net/mirrors-2.0.json",
+ serverJarPath: '{LIBRARY_DIR}/net/minecraft/server/{MINECRAFT_VERSION}/server-{MINECRAFT_VERSION}.jar',
data: [
MAPPINGS: [
client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings@txt]",
server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings@txt]"
],
+ MOJMAPS: [
+ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:mappings@txt]",
+ server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:mappings@txt]"
+ ],
+ MERGED_MAPPINGS: [
+ client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]",
+ server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]"
+ ],
BINPATCH: [
client: '/data/client.lzma',
server: '/data/server.lzma'
@@ -686,16 +1135,16 @@ project(':forge') {
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]"
],
MC_SLIM_SHA: [
- client: "'${tasks.getByName('downloadClientSlim').output.get().asFile.sha1()}'",
- server: "'${tasks.getByName('downloadServerSlim').output.get().asFile.sha1()}'"
+ client: "'${downloadClientSlim.output.get().asFile.sha1()}'",
+ server: "'${downloadServerSlim.output.get().asFile.sha1()}'"
],
MC_EXTRA: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:extra]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:extra]"
],
MC_EXTRA_SHA: [
- client: "'${tasks.getByName('downloadClientExtra').output.get().asFile.sha1()}'",
- server: "'${tasks.getByName('downloadServerExtra').output.get().asFile.sha1()}'"
+ client: "'${downloadClientExtra.output.get().asFile.sha1()}'",
+ server: "'${downloadServerExtra.output.get().asFile.sha1()}'"
],
MC_SRG: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:srg]",
@@ -720,6 +1169,36 @@ project(':forge') {
],
processors: [
[
+ sides: ['server'],
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'EXTRACT_FILES',
+ '--archive', '{INSTALLER}',
+
+ '--from', 'data/run.sh',
+ '--to', '{ROOT}/run.sh',
+ '--exec', '{ROOT}/run.sh',
+ //'--from', "data/run_forge_${VERSION.replace('-', '_').sh",
+ //'--to', '{ROOT}/run_forge_${VERSION.replace('-', '_').sh',
+ //'--exec', '{ROOT}/run_forge_${VERSION.replace('-', '_').sh',
+
+ '--from', 'data/run.bat',
+ '--to', '{ROOT}/run.bat',
+ //'--from', 'data/run_forge_${VERSION.replace('-', '_').bat',
+ //'--to', '{ROOT}/run_forge_${VERSION.replace('-', '_').bat',
+
+ '--from', 'data/user_jvm_args.txt',
+ '--to', '{ROOT}/user_jvm_args.txt',
+ '--optional', '{ROOT}/user_jvm_args.txt',
+
+ '--from', 'data/win_args.txt',
+ '--to', "{ROOT}/libraries/${MAVEN_PATH}/win_args.txt",
+
+ '--from', 'data/unix_args.txt',
+ '--to', "{ROOT}/libraries/${MAVEN_PATH}/unix_args.txt"
+ ]
+ ], [
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
@@ -728,6 +1207,25 @@ project(':forge') {
'--output', '{MAPPINGS}',
'--key', 'mappings'
]
+ ], [
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'DOWNLOAD_MOJMAPS',
+ '--version', MC_VERSION,
+ '--side', '{SIDE}',
+ '--output', '{MOJMAPS}'
+ ]
+ ], [
+ jar: INSTALLER_TOOLS,
+ classpath: getClasspath(project, libs, INSTALLER_TOOLS),
+ args: [
+ '--task', 'MERGE_MAPPING',
+ '--left', '{MAPPINGS}',
+ '--right', '{MOJMAPS}',
+ '--output', '{MERGED_MAPPINGS}',
+ '--classes', '--reverse-right'
+ ]
], [
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
@@ -735,20 +1233,22 @@ project(':forge') {
'--input', '{MINECRAFT_JAR}',
'--slim', '{MC_SLIM}',
'--extra', '{MC_EXTRA}',
- '--srg', '{MAPPINGS}'
+ '--srg', '{MERGED_MAPPINGS}'
],
outputs: [
'{MC_SLIM}': '{MC_SLIM_SHA}',
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
- jar: SPECIAL_SOURCE_MCP,
- classpath: getClasspath(project, libs, SPECIAL_SOURCE_MCP),
+ jar: VIGNETTE,
+ classpath: getClasspath(project, libs, VIGNETTE),
args: [
- //'--stable', Java 9 Is borked, https://bugs.openjdk.java.net/browse/JDK-8184940 TODO: find a fix.
- '--in-jar', '{MC_SLIM}',
- '--out-jar', '{MC_SRG}',
- '--srg-in', '{MAPPINGS}'
+ '--jar-in', '{MC_SLIM}',
+ '--jar-out', '{MC_SRG}',
+ '--mapping-format', 'tsrg2',
+ '--mappings', '{MERGED_MAPPINGS}',
+ // '--stable',
+ '--create-inits', '--fix-param-annotations', '--fernflower-meta'
]/*,
outputs: [
'{MC_SRG}': '{MC_SRG_SHA}'
@@ -761,34 +1261,21 @@ project(':forge') {
'--clean', '{MC_SRG}',
'--output', '{PATCHED}',
'--apply', '{BINPATCH}'
- ],
+ ]/*, Because Vignette is unstable, it screws with the entry order of the binpatched jar, so we can't use the hash right now
+ // Re-enable this when https://github.com/CadixDev/Vignette/issues/1 is solved
outputs: [
'{PATCHED}': '{PATCHED_SHA}'
- ]
+ ]*/
]
]
]
getClasspath(project, libs, MCP_ARTIFACT.descriptor) //Tell it to download mcp_config
- json.libraries = libs.values().sort{a,b -> a.name.compareTo(b.name)}
-
- output.text = new JsonBuilder(json).toPrettyString()
}
}
-
- ['client', 'server'].each { side ->
- ['slim', 'extra'].each { type ->
- def name = "download${side.capitalize()}${type.capitalize()}"
- task "${name}"(type: DownloadMavenArtifact) {
- artifact = "net.minecraft:${side}:${MC_VERSION}-${MCP_VERSION}:${type}"
- }
- installerJson.dependsOn(name)
- installerJson.inputs.file(tasks.getByName(name).output)
- }
- }
-
+
universalJar {
from extraTxts
-
+
// add crowdin locales
from { crowdin.output.present && crowdin.output.get().asFile.exists() ? zipTree(crowdin.output) : null}
dependsOn crowdin
@@ -804,94 +1291,21 @@ project(':forge') {
}
}
}
-
- task launcherJar(type: Jar) {
- classifier 'launcher'
- from sourceSets.fmllauncher.output
- doFirst {
- def classpath = new StringBuilder()
- def artifacts = getArtifacts(project, project.configurations.installer, false)
- artifacts.each { key, lib ->
- classpath += "libraries/${lib.downloads.artifact.path} "
- }
- classpath += "libraries/net/minecraft/server/${MC_VERSION}-${MCP_VERSION}/server-${MC_VERSION}-${MCP_VERSION}-extra.jar"
-
- MANIFESTS.each{ pkg, values ->
- if (pkg == '/') {
- manifest.attributes(values += [
- 'Main-Class': 'net.minecraftforge.server.ServerMain',
- 'Class-Path': classpath.toString(),
- 'ServerLaunchArgs': [
- '--gameDir', '.',
- '--launchTarget', 'fmlserver',
- '--fml.forgeVersion', "${project.version.substring(MC_VERSION.length() + 1)}".toString(),
- '--fml.mcpVersion', MCP_VERSION,
- '--fml.mcVersion', MC_VERSION,
- '--fml.forgeGroup', project.group
- ].join(' ')
- ])
- } else {
- manifest.attributes(values, pkg)
- }
- }
- }
- }
-
- task downloadInstaller(type: DownloadMavenArtifact) {
- artifact = 'net.minecraftforge:installer:2.1.+:shrunk'
- changing = true
- }
-
- task installerJar(type: Zip, dependsOn: [downloadInstaller, installerJson, launcherJson, genClientBinPatches, genServerBinPatches, 'signUniversalJar', 'signLauncherJar']) {
- archiveClassifier = 'installer'
- archiveExtension = 'jar' //Needs to be Zip task to not override Manifest, so set extension
- destinationDirectory = file('build/libs')
+
+ task installerJar(type: InstallerJar, dependsOn: [genClientBinPatches, genServerBinPatches, 'signUniversalJar', launcherJson]) {
+ packedDependencies = PACKED_DEPS
from(extraTxts)
- from(rootProject.file('/installer_logo.png')) {
- rename{'big_logo.png'}
+ from(rootProject.file('/forge_installer_logo.png')) {
+ rename { 'big_logo.png' }
}
- from(rootProject.file('/src/main/resources/url.png'))
from(genClientBinPatches.output) {
- rename{'data/client.lzma'}
+ rename { 'data/client.lzma' }
}
from(genServerBinPatches.output) {
- rename{'data/server.lzma'}
- }
- from(universalJar) {
- into "/maven/${project.group.replace('.', '/')}/${project.name}/${project.version}/"
- }
- from(launcherJar) {
- into "/maven/${project.group.replace('.', '/')}/${project.name}/${project.version}/"
- rename { "${project.name}-${project.version}.jar" }
- }
- from(installerJson.output)
- from(launcherJson.output)
- if (downloadInstaller.output.present) {
- from(zipTree(downloadInstaller.output)) {
- duplicatesStrategy = 'exclude'
- }
+ rename { 'data/server.lzma' }
}
}
-
- [universalJar, launcherJar, installerJar].each { t ->
- task "sign${t.name.capitalize()}"(type: SignJar, dependsOn: t) {
- onlyIf {
- JAR_SIGNER != null && t.state.failure == null
- }
- def jarsigner = JAR_SIGNER == null ? [:] : JAR_SIGNER
- alias = 'forge'
- storePass = jarsigner.storepass
- keyPass = jarsigner.keypass
- keyStore = jarsigner.keystore
- inputFile = t.archiveFile
- outputFile = t.archiveFile
- doFirst {
- project.logger.lifecycle('Signing: ' + inputFile)
- }
- }
- t.finalizedBy(tasks.getByName("sign${t.name.capitalize()}"))
- }
-
+
task makeMdk(type: Zip) {
archiveBaseName = project.name
archiveClassifier = 'mdk'
@@ -923,78 +1337,7 @@ project(':forge') {
rename 'gitattributes\\.txt', '.gitattributes'
}
}
-
- userdevConfig {
- def artifacts = getArtifacts(project, project.configurations.installer, true)
- artifacts.each { key, lib ->
- libraries.add(lib.name)
- }
- libraries.add("${project.group}:${project.name}:${project.version}:launcher")
- runs {
- client {
- main 'net.minecraftforge.userdev.LaunchTesting'
- // Support mod devs running on Java 8 and up, including 16
- jvmArgs '-XX:+IgnoreUnrecognizedVMOptions'
- jvmArgs '--add-exports=java.base/sun.security.util=ALL-UNNAMED'
- jvmArgs '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming'
- jvmArgs '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
-
- environment 'target', 'fmluserdevclient'
- environment 'assetIndex', '{asset_index}'
- environment 'assetDirectory', '{assets_root}'
- environment 'nativesDirectory', '{natives}'
-
- environment 'MC_VERSION', "${MC_VERSION}"
- environment 'FORGE_GROUP', "${project.group}"
- environment 'MCP_VERSION', "${MCP_VERSION}"
- environment 'MOD_CLASSES', '{source_roots}'
- environment 'MCP_MAPPINGS', '{mcp_mappings}'
- environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
- }
-
- server {
- main 'net.minecraftforge.userdev.LaunchTesting'
-
- // Support mod devs running on Java 8 and up, including 16
- jvmArgs '-XX:+IgnoreUnrecognizedVMOptions'
- jvmArgs '--add-exports=java.base/sun.security.util=ALL-UNNAMED'
- jvmArgs '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming'
- jvmArgs '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
-
- environment 'target', 'fmluserdevserver'
-
- environment 'MC_VERSION', "${MC_VERSION}"
- environment 'FORGE_GROUP', "${project.group}"
- environment 'MCP_VERSION', "${MCP_VERSION}"
- environment 'MOD_CLASSES', '{source_roots}'
- environment 'MCP_MAPPINGS', '{mcp_mappings}'
- environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
- }
-
- data {
- main 'net.minecraftforge.userdev.LaunchTesting'
-
- // Support mod devs running on Java 8 and up, including 16
- jvmArgs '-XX:+IgnoreUnrecognizedVMOptions'
- jvmArgs '--add-exports=java.base/sun.security.util=ALL-UNNAMED'
- jvmArgs '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming'
- jvmArgs '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
-
- environment 'target', 'fmluserdevdata'
- environment 'assetIndex', '{asset_index}'
- environment 'assetDirectory', '{assets_root}'
-
- environment 'MC_VERSION', "${MC_VERSION}"
- environment 'FORGE_GROUP', "${project.group}"
- environment 'MCP_VERSION', "${MCP_VERSION}"
- environment 'MOD_CLASSES', '{source_roots}'
- environment 'MCP_MAPPINGS', '{mcp_mappings}'
- environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
- }
- }
- }
-
license {
header = file("$rootDir/LICENSE-header.txt")
@@ -1021,44 +1364,12 @@ project(':forge') {
}
}
- task userdevExtras(type:Jar) {
- dependsOn classes
- from sourceSets.userdev.output
- classifier 'userdev-temp'
- }
-
reobfJar {
tool = SPECIAL_SOURCE + ':shaded'
}
- task userdevExtrasReobf(type: ReobfuscateJar) {
- dependsOn userdevExtras, createMcp2Srg
- input = tasks.userdevExtras.archiveFile
- classpath.from project.configurations.userdevCompileClasspath
- srg = tasks.createMcp2Srg.output
- tool = SPECIAL_SOURCE + ':shaded'
- }
-
- userdevJar {
- dependsOn tasks.userdevExtrasReobf
- from (zipTree(tasks.userdevExtrasReobf.output)) {
- into '/inject/'
- }
- from (sourceSets.userdev.output.resourcesDir) {
- into '/inject/'
- }
- }
-
- extractRangeMap {
- dependencies.from jar.archiveFile
- sources.from sourceSets.userdev.java.srcDirs
- }
- applyRangeMap {
- sources.from sourceSets.userdev.java.srcDirs
- }
-
tasks.eclipse.dependsOn('genEclipseRuns')
-
+
if (project.hasProperty('UPDATE_MAPPINGS')) {
extractRangeMap {
sources.from sourceSets.test.java.srcDirs
@@ -1069,7 +1380,7 @@ project(':forge') {
}
sourceSets.test.java.srcDirs.each { extractMappedNew.addTarget it }
}
-
+
publishing {
publications {
mavenJava(MavenPublication) {
@@ -1084,55 +1395,17 @@ project(':forge') {
artifact makeMdk
artifact userdevJar
artifact sourcesJar
- artifact launcherJar
-
- pom {
- name = 'forge'
- description = 'Modifactions to Minecraft to enable mod developers.'
- url = 'https://github.com/MinecraftForge/MinecraftForge'
-
- scm {
- url = 'https://github.com/MinecraftForge/MinecraftForge'
- connection = 'scm:git:git://github.com/MinecraftForge/MinecraftForge.git'
- developerConnection = 'scm:git:git@github.com:MinecraftForge/MinecraftForge.git'
- }
-
- issueManagement {
- system = 'github'
- url = 'https://github.com/MinecraftForge/MinecraftForge/issues'
- }
-
- licenses {
- license {
- name = 'LGPL 2.1'
- url = 'https://github.com/MinecraftForge/MinecraftForge/blob/1.13-pre/LICENSE.txt'
- distribution = 'repo'
- }
- }
- }
- }
- }
- repositories {
- maven {
- if (System.env.MAVEN_USER) {
- url "https://maven.minecraftforge.net/releases/"
- authentication {
- basic(BasicAuthentication)
- }
- credentials {
- username = System.env.MAVEN_USER ?: 'not'
- password = System.env.MAVEN_PASSWORD ?: 'set'
- }
- } else {
- url 'file://' + rootProject.file('repo').getAbsolutePath()
- }
}
}
}
+ // Since we need the modules in the bootstrap, we need to make sure they are compiled before we do each run
+ afterEvaluate { prepareRuns.dependsOn(':fmlcore:jar', ':fmlloader:jar', ':javafmllanguage:jar', ':mclanguage:jar') }
}
//evaluationDependsOnChildren()
-task setup() {
+task setup() { //These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above
dependsOn ':clean:extractMapped'
- dependsOn ':forge:extractMapped' //These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above
+ if (symlinkValid)
+ dependsOn ':fmlonly:extractMapped'
+ dependsOn ':forge:extractMapped'
}
diff --git a/buildSrc/.gitignore b/buildSrc/.gitignore
index abc78ba75a..2979d33310 100644
--- a/buildSrc/.gitignore
+++ b/buildSrc/.gitignore
@@ -1,2 +1,3 @@
/.gradle/
/build/
+/out/
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index b644cd621b..f2d3e1fe1a 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -1,9 +1,9 @@
repositories {
- maven { url = 'https://maven.minecraftforge.net/' }
+ maven { url = 'https://maven.minecraftforge.net/' }
mavenCentral()
}
dependencies {
implementation 'org.ow2.asm:asm:9.1'
implementation 'org.ow2.asm:asm-tree:9.1'
- implementation 'net.minecraftforge:srgutils:0.4.+'
+ implementation 'net.minecraftforge:srgutils:0.4.+'
}
\ No newline at end of file
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy
index 74f5fc8d35..85a7ab610a 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy
@@ -1,9 +1,10 @@
package net.minecraftforge.forge.tasks
import net.minecraftforge.srgutils.IMappingFile
-import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
+
+import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy
index c9b7fd4bbc..cdc65a5859 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy
@@ -1,12 +1,18 @@
package net.minecraftforge.forge.tasks
-import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
+
+import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
-import org.objectweb.asm.*
+
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.Type
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckPatches.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckPatches.groovy
index e6633cf074..64a0407552 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckPatches.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckPatches.groovy
@@ -17,8 +17,8 @@ abstract class CheckPatches extends DefaultTask {
@TaskAction
protected void exec() {
def hasS2SArtifact = [
- Paths.get("patches/minecraft/net/minecraft/client/renderer/ViewFrustum.java.patch"),
- Paths.get("patches/minecraft/net/minecraft/data/BlockModelDefinition.java.patch")
+ Paths.get("patches/minecraft/net/minecraft/client/renderer/ViewArea.java.patch"),
+ Paths.get("patches/minecraft/net/minecraft/data/models/blockstates/Variant.java.patch")
]
def verified = true;
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy
index 6dd6453e29..ab16229872 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy
@@ -1,8 +1,9 @@
package net.minecraftforge.forge.tasks
-import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
+
+import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibraries.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibraries.groovy
index 342146a5f3..b5e233cc6f 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibraries.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibraries.groovy
@@ -1,12 +1,15 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
+import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
-import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.OutputDirectory
import java.nio.file.Files
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/FieldCompareFinder.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/FieldCompareFinder.groovy
index 9134db369d..56648b5e95 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/FieldCompareFinder.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/FieldCompareFinder.groovy
@@ -1,11 +1,20 @@
package net.minecraftforge.forge.tasks
import groovy.transform.EqualsAndHashCode
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.Internal
-import org.gradle.api.tasks.Nested
-import org.gradle.api.tasks.Optional
+
+import java.util.ArrayList
+import java.util.HashMap
+import java.util.TreeMap
+import java.util.TreeSet
+import java.util.function.BiConsumer
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.*
+
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.FieldNode
import org.objectweb.asm.tree.MethodNode
import static org.objectweb.asm.Opcodes.*
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/InstallerJar.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/InstallerJar.groovy
new file mode 100644
index 0000000000..91e196d25e
--- /dev/null
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/InstallerJar.groovy
@@ -0,0 +1,44 @@
+package net.minecraftforge.forge.tasks
+
+import org.gradle.api.tasks.bundling.Zip
+import org.gradle.api.tasks.*
+import org.gradle.api.provider.SetProperty
+
+abstract class InstallerJar extends Zip {
+ @Input @Optional abstract SetProperty getPackedDependencies()
+
+ InstallerJar() {
+ archiveClassifier.set('installer')
+ archiveExtension.set('jar') // Needs to be Zip task to not override Manifest, so set extension
+ destinationDirectory.set(project.layout.buildDirectory.dir('libs'))
+
+ def installerJson = project.tasks.installerJson
+ def launcherJson = project.tasks.launcherJson
+ def downloadInstaller = project.tasks.downloadInstaller
+
+ dependsOn(installerJson, launcherJson, downloadInstaller)
+ from(installerJson, launcherJson)
+
+ from(project.rootProject.file('/src/main/resources/url.png'))
+ project.afterEvaluate {
+ from(project.zipTree(downloadInstaller.output)) {
+ duplicatesStrategy = 'exclude'
+ }
+
+ if (!System.env.MAVEN_USER) {
+ dependsOn(project.universalJar)
+ from(project.universalJar) {
+ into '/maven/' + project.group.replace('.', '/') + '/' + project.universalJar.archiveBaseName.get() + '/' + project.version + '/'
+ }
+
+ packedDependencies.get().forEach {
+ def jarTask = project.rootProject.getTasks().findByPath(it)
+ dependsOn(jarTask)
+ from(jarTask) {
+ into '/maven/' + jarTask.project.group.replace('.', '/') + '/' + jarTask.archiveBaseName.get() + '/' + jarTask.project.version + '/'
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/InstallerJson.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/InstallerJson.groovy
new file mode 100644
index 0000000000..4842c9f607
--- /dev/null
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/InstallerJson.groovy
@@ -0,0 +1,81 @@
+package net.minecraftforge.forge.tasks
+
+import groovy.json.JsonBuilder
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.ConfigurableFileCollection
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.Property
+import org.gradle.api.provider.SetProperty
+import org.gradle.api.tasks.*
+
+import java.nio.file.Files
+
+abstract class InstallerJson extends DefaultTask {
+ @OutputFile abstract RegularFileProperty getOutput()
+ @InputFiles abstract ConfigurableFileCollection getInput()
+ @Input @Optional abstract SetProperty getPackedDependencies()
+ @Input @Optional final Map libraries = new LinkedHashMap<>()
+ @Input Map json = new LinkedHashMap<>()
+ @InputFile abstract RegularFileProperty getIcon()
+ @Input abstract Property getLauncherJsonName()
+ @Input abstract Property getLogo()
+ @Input abstract Property getMirrors()
+ @Input abstract Property getWelcome()
+
+ InstallerJson() {
+ getLauncherJsonName().convention('/version.json')
+ getLogo().convention('/big_logo.png')
+ getMirrors().convention('https://files.minecraftforge.net/mirrors-2.0.json')
+ getWelcome().convention("Welcome to the simple ${project.name.capitalize()} installer.")
+
+ getOutput().convention(project.layout.buildDirectory.file('install_profile.json'))
+
+ ['client', 'server'].each { side ->
+ ['slim', 'extra'].each { type ->
+ def tsk = project.tasks.getByName("download${side.capitalize()}${type.capitalize()}")
+ dependsOn(tsk)
+ input.from(tsk.output)
+ }
+ def tsk = project.tasks.getByName("create${side.capitalize()}SRG")
+ dependsOn(tsk)
+ input.from(tsk.output)
+ }
+
+
+ project.afterEvaluate {
+ (packedDependencies.get().collect{ project.rootProject.tasks.findByPath(it) } + [project.universalJar]).forEach {
+ dependsOn(it)
+ input.from it.archiveFile
+ }
+ }
+ }
+
+ @TaskAction
+ protected void exec() {
+ def libs = libraries
+ for (def child : packedDependencies.get().collect{ project.rootProject.tasks.findByPath(it) } + [project.universalJar]) {
+ def dep = Util.getMavenDep(child)
+ def path = Util.getMavenPath(child)
+ libs.put(dep.toString(), [
+ name: dep,
+ downloads: [
+ artifact: [
+ path: path,
+ url: "https://maven.minecraftforge.net/${path}",
+ sha1: child.archiveFile.get().asFile.sha1(),
+ size: child.archiveFile.get().asFile.length()
+ ]
+ ]
+ ])
+ }
+ json.libraries = libs.values().sort{a,b -> a.name.compareTo(b.name)}
+ json.icon = "data:image/png;base64," + new String(Base64.getEncoder().encode(Files.readAllBytes(icon.get().asFile.toPath())))
+ json.json = launcherJsonName.get()
+ json.logo = logo.get()
+ if (!mirrors.get().isEmpty())
+ json.mirrorList = mirrors.get()
+ json.welcome = welcome.get()
+
+ Files.writeString(output.get().getAsFile().toPath(), new JsonBuilder(json).toPrettyString())
+ }
+}
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/LauncherJson.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/LauncherJson.groovy
new file mode 100644
index 0000000000..20e684fd8b
--- /dev/null
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/LauncherJson.groovy
@@ -0,0 +1,71 @@
+package net.minecraftforge.forge.tasks
+
+import groovy.json.JsonBuilder
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.ConfigurableFileCollection
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.SetProperty
+import org.gradle.api.tasks.*
+
+import java.nio.file.Files
+
+import static net.minecraftforge.forge.tasks.Util.getArtifacts
+import static net.minecraftforge.forge.tasks.Util.iso8601Now
+
+abstract class LauncherJson extends DefaultTask {
+ @OutputFile abstract RegularFileProperty getOutput()
+ @InputFiles abstract ConfigurableFileCollection getInput()
+ @Input Map json = new LinkedHashMap<>()
+ @Input @Optional abstract SetProperty getPackedDependencies()
+
+ @Internal final vanilla = project.project(':mcp').file('build/mcp/downloadJson/version.json')
+ @Internal final timestamp = iso8601Now()
+ @Internal final comment = [
+ "Please do not automate the download and installation of Forge.",
+ "Our efforts are supported by ads from the download page.",
+ "If you MUST automate this, please consider supporting the project through https://www.patreon.com/LexManos/"
+ ]
+ @Internal final id = "${project.rootProject.ext.MC_VERSION}-${project.name}${project.version.substring(project.rootProject.ext.MC_VERSION.length())}"
+
+ LauncherJson() {
+ getOutput().convention(project.layout.buildDirectory.file('version.json'))
+
+ dependsOn(':fmlloader:jar', 'universalJar')
+ getInput().from(project.tasks.universalJar.archiveFile,
+ project.project(':fmlloader').jar.archiveFile,
+ vanilla)
+
+ project.afterEvaluate {
+ packedDependencies.get().forEach {
+ def jarTask = project.rootProject.tasks.findByPath(it)
+ dependsOn(jarTask)
+ input.from jarTask.archiveFile
+ }
+ }
+ }
+
+ @TaskAction
+ protected void exec() {
+ if (!json.libraries)
+ json.libraries = []
+ getArtifacts(project, project.configurations.installer, false).each { key, lib -> json.libraries.add(lib) }
+ getArtifacts(project, project.configurations.moduleonly, false).each { key, lib -> json.libraries.add(lib) }
+
+ packedDependencies.get().collect{ project.rootProject.tasks.findByPath(it) }.forEach {
+ def path = Util.getMavenPath(it)
+
+ json.libraries.add([
+ name: Util.getMavenDep(it),
+ downloads: [
+ artifact: [
+ path: path,
+ url: "https://maven.minecraftforge.net/${path}",
+ sha1: it.archiveFile.get().asFile.sha1(),
+ size: it.archiveFile.get().asFile.length()
+ ]
+ ]
+ ])
+ }
+ Files.writeString(output.get().asFile.toPath(), new JsonBuilder(json).toPrettyString())
+ }
+}
diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy
index e3bd7f0129..2a785fb2bc 100644
--- a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy
+++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy
@@ -2,8 +2,10 @@ package net.minecraftforge.forge.tasks
import groovy.json.JsonSlurper
+import java.io.File
import java.security.MessageDigest
import java.text.SimpleDateFormat
+import java.util.Date
public class Util {
static void init() {
@@ -90,6 +92,17 @@ public class Util {
}
return ret
}
+
+ public static def getMavenPath(task) {
+ def classifier = task.archiveClassifier.get()
+ def dep = "${task.project.group}:${task.project.name}:${task.project.version}" + (classifier == '' ? '' : ':' + classifier)
+ return "${task.project.group.replace('.', '/')}/${task.project.name}/${task.project.version}/${task.project.name}-${task.project.version}".toString() + (classifier == '' ? '' : '-' + classifier) + '.jar'
+ }
+
+ public static def getMavenDep(task) {
+ def classifier = task.archiveClassifier.get()
+ return "${task.project.group}:${task.project.name}:${task.project.version}" + (classifier == '' ? '' : ':' + classifier)
+ }
public static def iso8601Now() { new Date().iso8601() }
diff --git a/fmlcore/build.gradle b/fmlcore/build.gradle
new file mode 100644
index 0000000000..86b1a19290
--- /dev/null
+++ b/fmlcore/build.gradle
@@ -0,0 +1,64 @@
+plugins {
+ id 'com.github.ben-manes.versions'
+ id 'org.javamodularity.moduleplugin' version '1.8.3' apply false
+}
+apply plugin: 'java-library'
+apply plugin: 'jacoco'
+apply plugin: 'org.javamodularity.moduleplugin'
+
+dependencyUpdates.rejectVersionIf { isNonStable(it.candidate.version) }
+
+dependencies {
+ compileOnly('org.jetbrains:annotations:21.0.1')
+ implementation(project(':fmlloader'))
+ api('net.minecraftforge:eventbus:5.0.+')
+ implementation('commons-io:commons-io:2.5')
+}
+
+task sourcesJar(type: Jar) {
+ archiveClassifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+ext {
+ MANIFESTS = [
+ '': [
+ 'FMLModType': 'LIBRARY',
+ 'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
+ 'Git-Commit': GIT_INFO.abbreviatedId,
+ 'Git-Branch': GIT_INFO.branch,
+ 'Build-Number': "${System.getenv('BUILD_NUMBER')?:0}"
+ ] as LinkedHashMap,
+ 'net/minecraftforge/fml/loading/': [
+ 'Specification-Title': 'FMLLoader',
+ 'Specification-Vendor': 'Forge Development LLC',
+ 'Specification-Version': '1',
+ 'Implementation-Title': 'FML Loader',
+ 'Implementation-Version': '1.0',
+ 'Implementation-Vendor': 'Forge'
+ ] as LinkedHashMap
+ ]
+}
+
+jar.doFirst {
+ MANIFESTS.each { pkg, values ->
+ if (pkg == '')
+ manifest.attributes(values)
+ else
+ manifest.attributes(values, pkg)
+ }
+}
+
+tasks.withType(JavaCompile) {
+ options.compilerArgs << '-Xlint:unchecked'
+}
+
+artifacts {
+ archives jar
+ archives sourcesJar
+}
+
+publishing.publications.mavenJava(MavenPublication) {
+ from components.java
+ artifact sourcesJar
+}
\ No newline at end of file
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java b/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java
new file mode 100644
index 0000000000..c6e300657d
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java
@@ -0,0 +1,36 @@
+package net.minecraftforge.fml;
+
+import cpw.mods.modlauncher.util.ServiceLoaderUtils;
+import net.minecraftforge.eventbus.api.BusBuilder;
+import net.minecraftforge.eventbus.api.IEventBus;
+import net.minecraftforge.fml.config.IConfigEvent;
+import net.minecraftforge.fml.loading.FMLLoader;
+
+import java.util.ServiceLoader;
+import java.util.function.Supplier;
+
+public class Bindings {
+ private static final Bindings INSTANCE = new Bindings();
+
+ private final IBindingsProvider provider;
+
+ private Bindings() {
+ final var providers = ServiceLoaderUtils.streamServiceLoader(()->ServiceLoader.load(FMLLoader.getGameLayer(), IBindingsProvider.class), sce->{}).toList();
+ if (providers.size() != 1) {
+ throw new IllegalStateException("Could not find bindings provider");
+ }
+ this.provider = providers.get(0);
+ }
+
+ public static Supplier getForgeBus() {
+ return INSTANCE.provider.getForgeBusSupplier();
+ }
+
+ public static Supplier getMessageParser() {
+ return INSTANCE.provider.getMessageParser();
+ }
+
+ public static Supplier getConfigConfiguration() {
+ return INSTANCE.provider.getConfigConfiguration();
+ }
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/CrashReportCallables.java b/fmlcore/src/main/java/net/minecraftforge/fml/CrashReportCallables.java
new file mode 100644
index 0000000000..0644b2f0cc
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/CrashReportCallables.java
@@ -0,0 +1,32 @@
+package net.minecraftforge.fml;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Supplier;
+
+public class CrashReportCallables {
+ private static final List crashCallables = Collections.synchronizedList(new ArrayList<>());
+
+ public static void registerCrashCallable(ISystemReportExtender callable)
+ {
+ crashCallables.add(callable);
+ }
+
+ public static void registerCrashCallable(String headerName, Supplier reportGenerator) {
+ registerCrashCallable(new ISystemReportExtender() {
+ @Override
+ public String getLabel() {
+ return headerName;
+ }
+ @Override
+ public String get() {
+ return reportGenerator.get();
+ }
+ });
+ }
+
+ public static List allCrashCallables() {
+ return List.copyOf(crashCallables);
+ }
+}
diff --git a/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java b/fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
similarity index 65%
rename from src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
index 3343369fef..475b52d2fa 100644
--- a/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
@@ -21,20 +21,19 @@ package net.minecraftforge.fml;
import static net.minecraftforge.fml.Logging.LOADING;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
-import net.minecraftforge.fml.event.lifecycle.ParallelDispatchEvent;
-import org.apache.commons.lang3.time.StopWatch;
+import com.google.common.base.Stopwatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import com.google.common.base.Stopwatch;
-
import net.minecraftforge.forgespi.language.IModInfo;
/**
@@ -52,26 +51,28 @@ public class DeferredWorkQueue
{
private static final Logger LOGGER = LogManager.getLogger();
- private static Map, DeferredWorkQueue> workQueues = new HashMap<>();
+ private static final Map workQueues = new HashMap<>();
- private final ModLoadingStage modLoadingStage;
private final ConcurrentLinkedDeque tasks = new ConcurrentLinkedDeque<>();
+ private final ModLoadingStage modLoadingStage;
- public DeferredWorkQueue(final ModLoadingStage modLoadingStage, Class extends ParallelDispatchEvent> eventClass) {
+ public DeferredWorkQueue(ModLoadingStage modLoadingStage) {
this.modLoadingStage = modLoadingStage;
- workQueues.put(eventClass, this);
+ workQueues.put(modLoadingStage, this);
}
- public static Optional lookup(Optional> parallelClass) {
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+ public static Optional lookup(Optional parallelClass) {
return Optional.ofNullable(workQueues.get(parallelClass.orElse(null)));
}
- void runTasks() {
+ public void runTasks() {
if (tasks.isEmpty()) return;
- LOGGER.debug(LOADING, "Dispatching synchronous work after {}: {} jobs", modLoadingStage, tasks.size());
- StopWatch globalTimer = StopWatch.createStarted();
+ LOGGER.debug(LOADING, "Dispatching synchronous work for work queue {}: {} jobs", modLoadingStage, tasks.size());
+ Stopwatch timer = Stopwatch.createStarted();
tasks.forEach(t->makeRunnable(t, Runnable::run));
- LOGGER.debug(LOADING, "Synchronous work queue completed in {}", globalTimer);
+ timer.stop();
+ LOGGER.debug(LOADING, "Synchronous work queue completed in {}", timer);
}
private static void makeRunnable(TaskInfo ti, Executor executor) {
@@ -93,28 +94,5 @@ public class DeferredWorkQueue
return CompletableFuture.supplyAsync(work, r->tasks.add(new TaskInfo(modInfo, r)));
}
- /**
- * DEPRECATED FOR REMOVAL. Use {@link ParallelDispatchEvent#enqueueWork(Runnable)} or {@link ParallelDispatchEvent#enqueueWork(Supplier)}
- *
- * @param workToEnqueue Runnable to execute later
- * @return a completable future
- */
- @Deprecated
- public static CompletableFuture runLater(Runnable workToEnqueue) {
- return
- Optional.ofNullable(ModLoadingContext.get().getActiveContainer().modLoadingStage.getDeferredWorkQueue())
- .map(wq->wq.enqueueWork(ModLoadingContext.get().getActiveContainer().modInfo, workToEnqueue))
- .orElseGet(()->CompletableFuture.completedFuture(null));
- }
-
- static class TaskInfo
- {
- public final IModInfo owner;
- public final Runnable task;
-
- private TaskInfo(IModInfo owner, Runnable task) {
- this.owner = owner;
- this.task = task;
- }
- }
+ record TaskInfo(IModInfo owner, Runnable task) {}
}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/fml/DistExecutor.java b/fmlcore/src/main/java/net/minecraftforge/fml/DistExecutor.java
similarity index 100%
rename from src/main/java/net/minecraftforge/fml/DistExecutor.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/DistExecutor.java
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/I18NParser.java b/fmlcore/src/main/java/net/minecraftforge/fml/I18NParser.java
new file mode 100644
index 0000000000..c7e3f75a0a
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/I18NParser.java
@@ -0,0 +1,6 @@
+package net.minecraftforge.fml;
+
+public interface I18NParser {
+ String parseMessage(String i18nMessage, Object... args);
+ String stripControlCodes(String toStrip);
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/IBindingsProvider.java b/fmlcore/src/main/java/net/minecraftforge/fml/IBindingsProvider.java
new file mode 100644
index 0000000000..5800dce590
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/IBindingsProvider.java
@@ -0,0 +1,12 @@
+package net.minecraftforge.fml;
+
+import net.minecraftforge.eventbus.api.IEventBus;
+import net.minecraftforge.fml.config.IConfigEvent;
+
+import java.util.function.Supplier;
+
+public interface IBindingsProvider {
+ Supplier getForgeBusSupplier();
+ Supplier getMessageParser();
+ Supplier getConfigConfiguration();
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ICrashCallable.java b/fmlcore/src/main/java/net/minecraftforge/fml/ICrashCallable.java
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/main/java/net/minecraftforge/fml/ExtensionPoint.java b/fmlcore/src/main/java/net/minecraftforge/fml/IExtensionPoint.java
similarity index 76%
rename from src/main/java/net/minecraftforge/fml/ExtensionPoint.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/IExtensionPoint.java
index 23e6c1e342..dbe9c95aeb 100644
--- a/src/main/java/net/minecraftforge/fml/ExtensionPoint.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/IExtensionPoint.java
@@ -19,21 +19,11 @@
package net.minecraftforge.fml;
-import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Supplier;
-import org.apache.commons.lang3.tuple.Pair;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.resources.IResourcePack;
-import net.minecraftforge.fml.packs.ModFileResourcePack;
-
-public class ExtensionPoint
+public interface IExtensionPoint
{
- public static final ExtensionPoint> CONFIGGUIFACTORY = new ExtensionPoint<>();
- public static final ExtensionPoint> RESOURCEPACK = new ExtensionPoint<>();
/**
* Compatibility display test for the mod.
* Used for displaying compatibility with remote servers with the same mod, and on disk saves.
@@ -68,11 +58,5 @@ public class ExtensionPoint
*
*
*/
- public static final ExtensionPoint, BiPredicate>> DISPLAYTEST = new ExtensionPoint<>();
-
- private Class type;
-
- private ExtensionPoint() {
- }
-
+ record DisplayTest(Supplier suppliedVersion, BiPredicate remoteVersionTest) implements IExtensionPoint {}
}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/IModLoadingState.java b/fmlcore/src/main/java/net/minecraftforge/fml/IModLoadingState.java
new file mode 100644
index 0000000000..83fea95e63
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/IModLoadingState.java
@@ -0,0 +1,25 @@
+package net.minecraftforge.fml;
+
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.event.IModBusEvent;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public interface IModLoadingState {
+ String name();
+ String previous();
+ ModLoadingPhase phase();
+ Function message();
+ Optional> inlineRunnable();
+
+ default Optional>> buildTransition(final Executor syncExecutor, final Executor parallelExecutor) {
+ return buildTransition(syncExecutor, parallelExecutor, e->CompletableFuture.runAsync(()->{}, e), e->CompletableFuture.runAsync(()->{}, e));
+ }
+
+ Optional>> buildTransition(Executor syncExecutor, Executor parallelExecutor, Function> preSyncTask, Function> postSyncTask);
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/IModStateProvider.java b/fmlcore/src/main/java/net/minecraftforge/fml/IModStateProvider.java
new file mode 100644
index 0000000000..4888698e15
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/IModStateProvider.java
@@ -0,0 +1,7 @@
+package net.minecraftforge.fml;
+
+import java.util.List;
+
+public interface IModStateProvider {
+ List getAllStates();
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/IModStateTransition.java b/fmlcore/src/main/java/net/minecraftforge/fml/IModStateTransition.java
new file mode 100644
index 0000000000..330008ed27
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/IModStateTransition.java
@@ -0,0 +1,87 @@
+package net.minecraftforge.fml;
+
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.event.IModBusEvent;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+@SuppressWarnings("unchecked")
+public interface IModStateTransition {
+ static IModStateTransition buildNoopTransition() {
+ return new NoopTransition();
+ }
+
+ default CompletableFuture> build(Executor syncExecutor, Executor parallelExecutor, Function> preSyncTask, Function> postSyncTask) {
+ List>> cfs = new ArrayList<>();
+ this.eventFunctionStream().get()
+ .map(f->(EventGenerator)f)
+ .reduce((head, tail)-> addCompletableFutureTaskForModDispatch(syncExecutor, parallelExecutor, cfs, head, ModLoadingStage::currentState, tail))
+ .ifPresent(last-> addCompletableFutureTaskForModDispatch(syncExecutor, parallelExecutor, cfs, last, nextModLoadingStage(), null));
+ final CompletableFuture preSyncTaskCF = preSyncTask.apply(syncExecutor);
+ final CompletableFuture> eventDispatchCF = ModList.gather(cfs).thenCompose(ModList::completableFutureFromExceptionList);
+ final CompletableFuture> postEventDispatchCF = preSyncTaskCF.thenComposeAsync(n -> eventDispatchCF, parallelExecutor).thenApply(r -> {
+ postSyncTask.apply(syncExecutor);
+ return r;
+ });
+ return this.finalActivityGenerator().apply(syncExecutor, postEventDispatchCF);
+ }
+
+ default BiFunction nextModLoadingStage() {
+ return ModLoadingStage::nextState;
+ }
+
+ private EventGenerator addCompletableFutureTaskForModDispatch(final Executor syncExecutor, final Executor parallelExecutor, final List>> completeableFutures, final EventGenerator eventGenerator, BiFunction nextState, final EventGenerator nextGenerator) {
+ completeableFutures.add(((BiFunction, CompletableFuture>>)preDispatchHook()).apply(threadSelector().apply(syncExecutor, parallelExecutor), eventGenerator));
+ completeableFutures.add(ModList.get().futureVisitor(eventGenerator, nextState).apply(threadSelector().apply(syncExecutor, parallelExecutor)));
+ completeableFutures.add(((BiFunction, CompletableFuture>>)postDispatchHook()).apply(threadSelector().apply(syncExecutor, parallelExecutor), eventGenerator));
+ return nextGenerator;
+ }
+
+ Supplier>> eventFunctionStream();
+ ThreadSelector threadSelector();
+ BiFunction>, CompletableFuture>> finalActivityGenerator();
+ BiFunction, CompletableFuture>> preDispatchHook();
+ BiFunction, CompletableFuture>> postDispatchHook();
+
+ interface EventGenerator extends Function {
+ static EventGenerator fromFunction(Function fn) {
+ return fn::apply;
+ }
+ }
+}
+
+record NoopTransition() implements IModStateTransition {
+
+ @Override
+ public Supplier>> eventFunctionStream() {
+ return Stream::of;
+ }
+
+ @Override
+ public ThreadSelector threadSelector() {
+ return ThreadSelector.SYNC;
+ }
+
+ @Override
+ public BiFunction>, CompletableFuture>> finalActivityGenerator() {
+ return (e, t) -> t.thenApplyAsync(Function.identity(), e);
+ }
+
+ @Override
+ public BiFunction, CompletableFuture>> preDispatchHook() {
+ return (t, f)-> CompletableFuture.completedFuture(Collections.emptyList());
+ }
+
+ @Override
+ public BiFunction, CompletableFuture>> postDispatchHook() {
+ return (t, f)-> CompletableFuture.completedFuture(Collections.emptyList());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java b/fmlcore/src/main/java/net/minecraftforge/fml/ISystemReportExtender.java
similarity index 83%
rename from src/main/java/net/minecraftforge/fml/common/ICrashCallable.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ISystemReportExtender.java
index f9f4064be9..fc64a9325d 100644
--- a/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ISystemReportExtender.java
@@ -17,11 +17,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common;
+package net.minecraftforge.fml;
-import net.minecraft.crash.ICrashReportDetail;
+import java.util.function.Supplier;
-public interface ICrashCallable extends ICrashReportDetail
+public interface ISystemReportExtender extends Supplier
{
String getLabel();
}
diff --git a/src/main/java/net/minecraftforge/fml/InterModComms.java b/fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java
similarity index 92%
rename from src/main/java/net/minecraftforge/fml/InterModComms.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java
index 45fadae85b..1c21df0e7b 100644
--- a/src/main/java/net/minecraftforge/fml/InterModComms.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java
@@ -33,38 +33,32 @@ import java.util.stream.StreamSupport;
public class InterModComms
{
- public static final class IMCMessage {
- private final String modId;
- private final String method;
- private final String senderModId;
- private final Supplier> thing;
-
- IMCMessage(String senderModId, String modId, String method, Supplier> thing)
- {
- this.senderModId = senderModId;
- this.modId = modId;
- this.method = method;
- this.thing = thing;
- }
+ public record IMCMessage(String senderModId, String modId, String method, Supplier> messageSupplier) {
/**
+ * Deprecated: use {@link #senderModId()}
* @return The modid of the sender. This is supplied by the caller, or by the active mod container context.
* Consider it unreliable.
*/
+ @Deprecated
public final String getSenderModId() {
return this.senderModId;
}
/**
+ * Deprecated: use {@link #modId()}
* @return The modid being sent to.
*/
+ @Deprecated
public final String getModId() {
return this.modId;
}
/**
+ * Deprecated: use {@link #method()}
* @return The method being sent to.
*/
+ @Deprecated
public final String getMethod() {
return this.method;
}
@@ -72,10 +66,12 @@ public class InterModComms
/**
* @param The type of the message.
* @return A {@link Supplier} of the message.
+ * Use {@link #messageSupplier()}
*/
@SuppressWarnings("unchecked")
+ @Deprecated
public final Supplier getMessageSupplier() {
- return (Supplier)this.thing;
+ return (Supplier) this.messageSupplier;
}
}
diff --git a/src/main/java/net/minecraftforge/fml/LoadingFailedException.java b/fmlcore/src/main/java/net/minecraftforge/fml/LoadingFailedException.java
similarity index 100%
rename from src/main/java/net/minecraftforge/fml/LoadingFailedException.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/LoadingFailedException.java
diff --git a/src/main/java/net/minecraftforge/fml/Logging.java b/fmlcore/src/main/java/net/minecraftforge/fml/Logging.java
similarity index 93%
rename from src/main/java/net/minecraftforge/fml/Logging.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/Logging.java
index d29b9618b5..26efa8544d 100644
--- a/src/main/java/net/minecraftforge/fml/Logging.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/Logging.java
@@ -31,6 +31,7 @@ public class Logging
public static final Marker SPLASH = MarkerManager.getMarker("SPLASH");
public static final Marker CAPABILITIES = MarkerManager.getMarker("CAPABILITIES");
public static final Marker MODELLOADING = MarkerManager.getMarker("MODELLOADING");
+ public static final Marker FORGEMOD = MarkerManager.getMarker("FORGEMOD").addParents(LOADING);
// --log CORE:+DEBUG,SCAN:-OFF
// forge log debug 5
diff --git a/src/main/java/net/minecraftforge/fml/LogicalSide.java b/fmlcore/src/main/java/net/minecraftforge/fml/LogicalSide.java
similarity index 100%
rename from src/main/java/net/minecraftforge/fml/LogicalSide.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/LogicalSide.java
diff --git a/src/main/java/net/minecraftforge/fml/ModContainer.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java
similarity index 86%
rename from src/main/java/net/minecraftforge/fml/ModContainer.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java
index 605582405e..56a44b986a 100644
--- a/src/main/java/net/minecraftforge/fml/ModContainer.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java
@@ -20,10 +20,10 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.config.IConfigEvent;
import net.minecraftforge.fml.config.ModConfig;
-import net.minecraftforge.fml.event.lifecycle.IModBusEvent;
+import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.forgespi.language.IModInfo;
-import org.apache.commons.lang3.tuple.Pair;
import java.util.EnumMap;
import java.util.HashMap;
@@ -58,10 +58,10 @@ public abstract class ModContainer
protected ModLoadingStage modLoadingStage;
protected Supplier> contextExtension;
protected final Map activityMap = new HashMap<>();
- protected final Map> extensionPoints = new IdentityHashMap<>();
+ protected final Map>, Supplier>> extensionPoints = new IdentityHashMap<>();
protected final EnumMap configs = new EnumMap<>(ModConfig.Type.class);
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
- protected Optional> configHandler = Optional.empty();
+ protected Optional> configHandler = Optional.empty();
public ModContainer(IModInfo info)
{
@@ -71,7 +71,7 @@ public abstract class ModContainer
this.modInfo = info;
this.modLoadingStage = ModLoadingStage.CONSTRUCT;
// default displaytest extension checks for version string match
- registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(()->this.modInfo.getVersion().toString(),
+ registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(()->this.modInfo.getVersion().toString(),
(incoming, isNetwork)->Objects.equals(incoming, this.modInfo.getVersion().toString())));
}
@@ -111,7 +111,7 @@ public abstract class ModContainer
public static CompletableFuture buildTransitionHandler(
final ModContainer target,
- final ModLoadingStage.EventGenerator eventGenerator,
+ final IModStateTransition.EventGenerator eventGenerator,
final BiFunction stateChangeHandler,
final Executor executor) {
return CompletableFuture
@@ -126,20 +126,17 @@ public abstract class ModContainer
});
}
- /**
- * @return the modinfo used to create this mod instance
- */
public IModInfo getModInfo()
{
return modInfo;
}
@SuppressWarnings("unchecked")
- public Optional getCustomExtension(ExtensionPoint point) {
+ public Optional getCustomExtension(Class extends IExtensionPoint> point) {
return Optional.ofNullable((T)extensionPoints.getOrDefault(point,()-> null).get());
}
- public void registerExtensionPoint(ExtensionPoint point, Supplier extension)
+ public > void registerExtensionPoint(Class extends IExtensionPoint> point, Supplier extension)
{
extensionPoints.put(point, extension);
}
@@ -148,7 +145,7 @@ public abstract class ModContainer
configs.put(modConfig.getType(), modConfig);
}
- public void dispatchConfigEvent(ModConfig.ModConfigEvent event) {
+ public void dispatchConfigEvent(IConfigEvent event) {
configHandler.ifPresent(configHandler->configHandler.accept(event));
}
diff --git a/src/main/java/net/minecraftforge/fml/ModList.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java
similarity index 87%
rename from src/main/java/net/minecraftforge/fml/ModList.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModList.java
index 889bc557d3..5f685edade 100644
--- a/src/main/java/net/minecraftforge/fml/ModList.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java
@@ -20,11 +20,14 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
-import net.minecraftforge.fml.event.lifecycle.IModBusEvent;
+import net.minecraftforge.fml.event.IModBusEvent;
+import net.minecraftforge.forgespi.language.IModFileInfo;
+import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.ModFileScanData;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
+import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -58,8 +61,8 @@ public class ModList
{
private static Logger LOGGER = LogManager.getLogger();
private static ModList INSTANCE;
- private final List modFiles;
- private final List sortedList;
+ private final List modFiles;
+ private final List sortedList;
private final Map fileById;
private List mods;
private Map indexedMods;
@@ -71,17 +74,17 @@ public class ModList
this.sortedList = sortedList.stream().
map(ModInfo.class::cast).
collect(Collectors.toList());
- this.fileById = this.modFiles.stream().map(ModFileInfo::getMods).flatMap(Collection::stream).
+ this.fileById = this.modFiles.stream().map(IModFileInfo::getMods).flatMap(Collection::stream).
map(ModInfo.class::cast).
collect(Collectors.toMap(ModInfo::getModId, ModInfo::getOwningFile));
- CrashReportExtender.registerCrashCallable("Mod List", this::crashReport);
+ CrashReportCallables.registerCrashCallable("Mod List", this::crashReport);
}
private String getModContainerState(String modId) {
return getModContainerById(modId).map(ModContainer::getCurrentState).map(Object::toString).orElse("NONE");
}
- private String fileToLine(ModFile mf) {
+ private String fileToLine(IModFile mf) {
return String.format("%-50.50s|%-30.30s|%-30.30s|%-20.20s|%-10.10s|Manifest: %s", mf.getFileName(),
mf.getModInfos().get(0).getDisplayName(),
mf.getModInfos().get(0).getModId(),
@@ -111,18 +114,18 @@ public class ModList
return thread;
}
- public List getModFiles()
+ public List getModFiles()
{
return modFiles;
}
- public ModFileInfo getModFileById(String modid)
+ public IModFileInfo getModFileById(String modid)
{
return this.fileById.get(modid);
}
Function>> futureVisitor(
- final ModLoadingStage.EventGenerator eventGenerator,
+ final IModStateTransition.EventGenerator eventGenerator,
final BiFunction stateChange) {
return executor -> gather(
this.mods.stream()
@@ -185,7 +188,7 @@ public class ModList
return mods.stream().filter(mc -> mc.getMod() == obj).findFirst();
}
- public List getMods()
+ public List getMods()
{
return this.sortedList;
}
@@ -205,24 +208,24 @@ public class ModList
if (modFileScanData == null)
{
modFileScanData = this.sortedList.stream().
- map(ModInfo::getOwningFile).
+ map(IModInfo::getOwningFile).
filter(Objects::nonNull).
- map(ModFileInfo::getFile).
+ map(IModFileInfo::getFile).
distinct().
- map(ModFile::getScanResult).
+ map(IModFile::getScanResult).
collect(Collectors.toList());
}
return modFileScanData;
}
- public void forEachModFile(Consumer fileConsumer)
+ public void forEachModFile(Consumer fileConsumer)
{
- modFiles.stream().map(ModFileInfo::getFile).forEach(fileConsumer);
+ modFiles.stream().map(IModFileInfo::getFile).forEach(fileConsumer);
}
- public Stream applyForEachModFile(Function function) {
- return modFiles.stream().map(ModFileInfo::getFile).map(function);
+ public Stream applyForEachModFile(Function function) {
+ return modFiles.stream().map(IModFileInfo::getFile).map(function);
}
public void forEachModContainer(BiConsumer modContainerConsumer) {
diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java
similarity index 66%
rename from src/main/java/net/minecraftforge/fml/ModLoader.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java
index 0462b28d3d..eed6990710 100644
--- a/src/main/java/net/minecraftforge/fml/ModLoader.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java
@@ -20,28 +20,16 @@
package net.minecraftforge.fml;
import com.google.common.collect.ImmutableList;
-import cpw.mods.modlauncher.TransformingClassLoader;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.eventbus.api.Event;
-import net.minecraftforge.fml.config.ConfigTracker;
-import net.minecraftforge.fml.config.ModConfig;
-import net.minecraftforge.fml.event.lifecycle.IModBusEvent;
+import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.FMLLoader;
-import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.fml.loading.LoadingModList;
import net.minecraftforge.fml.loading.moddiscovery.InvalidModIdentifier;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
-import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
-import net.minecraftforge.fml.network.FMLNetworkConstants;
-import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.IModLanguageProvider;
-import net.minecraftforge.registries.GameData;
-import net.minecraftforge.registries.ObjectHolderRegistry;
-import net.minecraftforge.versions.forge.ForgeVersion;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -102,38 +90,37 @@ public class ModLoader
{
private static final Logger LOGGER = LogManager.getLogger();
private static ModLoader INSTANCE;
- private final TransformingClassLoader launchClassLoader;
private final LoadingModList loadingModList;
private final List loadingExceptions;
private final List loadingWarnings;
+ private final ModStateManager stateManager;
private boolean loadingStateValid;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private final Optional> statusConsumer = StartupMessageManager.modLoaderConsumer();
+ private ModList modList;
private ModLoader()
{
INSTANCE = this;
- this.launchClassLoader = FMLLoader.getLaunchClassLoader();
this.loadingModList = FMLLoader.getLoadingModList();
- this.loadingExceptions = FMLLoader.getLoadingModList().
- getErrors().stream().flatMap(ModLoadingException::fromEarlyException).collect(Collectors.toList());
- this.loadingWarnings = FMLLoader.getLoadingModList().
- getBrokenFiles().stream().map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE,
- InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName())).collect(Collectors.toList());
- FMLLoader.getLoadingModList()
- .getModFiles().stream().filter(ModFileInfo::missingLicense) //Search for files with missing licenses
+ this.loadingExceptions = FMLLoader.getLoadingModList().getErrors().stream()
+ .flatMap(ModLoadingException::fromEarlyException)
+ .collect(Collectors.toList());
+ this.loadingWarnings = FMLLoader.getLoadingModList().getBrokenFiles().stream()
+ .map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName()))
+ .collect(Collectors.toList());
+ FMLLoader.getLoadingModList().getModFiles().stream()
+ .filter(ModFileInfo::missingLicense) //Search for files with missing licenses
.filter(modFileInfo -> modFileInfo.getMods().stream().noneMatch(thisModInfo -> this.loadingExceptions.stream().map(ModLoadingException::getModInfo).anyMatch(otherInfo -> otherInfo == thisModInfo))) //Ignore files where any other mod already encountered an error
.map(modFileInfo -> new ModLoadingException(null, ModLoadingStage.VALIDATE, "fml.modloading.missinglicense", null, modFileInfo.getFile()))
.forEach(this.loadingExceptions::add);
- LOGGER.debug(CORE, "Loading Network data for FML net version: {}", FMLNetworkConstants.init());
- CrashReportExtender.registerCrashCallable("ModLauncher", FMLLoader::getLauncherInfo);
- CrashReportExtender.registerCrashCallable("ModLauncher launch target", FMLLoader::launcherHandlerName);
- CrashReportExtender.registerCrashCallable("ModLauncher naming", FMLLoader::getNaming);
- CrashReportExtender.registerCrashCallable("ModLauncher services", this::computeModLauncherServiceList);
- CrashReportExtender.registerCrashCallable("FML", ForgeVersion::getSpec);
- CrashReportExtender.registerCrashCallable("Forge", ()->ForgeVersion.getGroup()+":"+ForgeVersion.getVersion());
- CrashReportExtender.registerCrashCallable("FML Language Providers", this::computeLanguageList);
+ this.stateManager = new ModStateManager();
+ CrashReportCallables.registerCrashCallable("ModLauncher", FMLLoader::getLauncherInfo);
+ CrashReportCallables.registerCrashCallable("ModLauncher launch target", FMLLoader::launcherHandlerName);
+ CrashReportCallables.registerCrashCallable("ModLauncher naming", FMLLoader::getNaming);
+ CrashReportCallables.registerCrashCallable("ModLauncher services", this::computeModLauncherServiceList);
+ CrashReportCallables.registerCrashCallable("FML Language Providers", this::computeLanguageList);
}
private String computeLanguageList() {
@@ -165,11 +152,7 @@ public class ModLoader
statusConsumer.ifPresent(c->c.accept("Waiting for scan to complete"));
FMLLoader.backgroundScanHandler.waitForScanToComplete(periodicTask);
statusConsumer.ifPresent(c->c.accept("Loading mods"));
- final ModList modList = ModList.of(loadingModList
- .getModFiles()
- .stream()
- .map(ModFileInfo::getFile)
- .collect(Collectors.toList()),
+ final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).toList(),
loadingModList.getMods());
if (!this.loadingExceptions.isEmpty()) {
LOGGER.fatal(CORE, "Error during pre-loading phase", loadingExceptions.get(0));
@@ -178,11 +161,11 @@ public class ModLoader
throw new LoadingFailedException(loadingExceptions);
}
statusConsumer.ifPresent(c->c.accept("Building Mod List"));
- final List modContainers = loadingModList.getModFiles().stream().
- map(ModFileInfo::getFile).
- map(mf -> buildMods(mf, launchClassLoader)).
- flatMap(Collection::stream).
- collect(Collectors.toList());
+ final List modContainers = loadingModList.getModFiles().stream()
+ .map(ModFileInfo::getFile)
+ .map(this::buildMods)
+ .mapMulti(Iterable::forEach)
+ .toList();
if (!loadingExceptions.isEmpty()) {
LOGGER.fatal(CORE, "Failed to initialize mod containers", loadingExceptions.get(0));
modList.setLoadedMods(Collections.emptyList());
@@ -190,61 +173,45 @@ public class ModLoader
throw new LoadingFailedException(loadingExceptions);
}
modList.setLoadedMods(modContainers);
- statusConsumer.ifPresent(c->c.accept(String.format("Constructing %d mods", modList.size())));
- dispatchAndHandleError(ModLoadingStage.CONSTRUCT, syncExecutor, parallelExecutor, periodicTask);
- statusConsumer.ifPresent(c->c.accept("Creating registries"));
- dispatchAndHandleError(ModLoadingStage.CREATE_REGISTRIES, syncExecutor, parallelExecutor, periodicTask);
- ObjectHolderRegistry.findObjectHolders();
- CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData());
- statusConsumer.ifPresent(c->c.accept("Adding custom tag types"));
- GameData.setCustomTagTypesFromRegistries();
- statusConsumer.ifPresent(c->c.accept("Populating registries"));
- dispatchAndHandleError(ModLoadingStage.LOAD_REGISTRIES, syncExecutor, parallelExecutor, periodicTask);
- statusConsumer.ifPresent(c->c.accept("Early mod loading complete"));
+ this.modList = modList;
+ statusConsumer.ifPresent(c->c.accept("Dispatching gathering events"));
+ stateManager.getStates(ModLoadingPhase.GATHER).forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask));
+ statusConsumer.ifPresent(c->c.accept("Gathering phase complete"));
}
- public void loadMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Function> beforeSidedEvent, final Function> afterSidedEvent, final Runnable periodicTask) {
- statusConsumer.ifPresent(c->c.accept("Loading mod config"));
- DistExecutor.unsafeRunWhenOn(Dist.CLIENT, ()->()-> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get()));
- ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get());
- statusConsumer.ifPresent(c->c.accept("Mod setup: SETUP"));
- dispatchAndHandleError(ModLoadingStage.COMMON_SETUP, syncExecutor, parallelExecutor, periodicTask);
- statusConsumer.ifPresent(c->c.accept("Mod setup: SIDED SETUP"));
- dispatchAndHandleError(ModLoadingStage.SIDED_SETUP, syncExecutor, parallelExecutor, periodicTask, beforeSidedEvent, afterSidedEvent);
+ public void loadMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
+ statusConsumer.ifPresent(c->c.accept("Performing load phase"));
+ stateManager.getStates(ModLoadingPhase.LOAD).forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask));
statusConsumer.ifPresent(c->c.accept("Mod setup complete"));
}
- public void finishMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask)
- {
- statusConsumer.ifPresent(c->c.accept("Mod setup: ENQUEUE IMC"));
- dispatchAndHandleError(ModLoadingStage.ENQUEUE_IMC, syncExecutor, parallelExecutor, periodicTask);
- statusConsumer.ifPresent(c->c.accept("Mod setup: PROCESS IMC"));
- dispatchAndHandleError(ModLoadingStage.PROCESS_IMC, syncExecutor, parallelExecutor, periodicTask);
- statusConsumer.ifPresent(c->c.accept("Mod setup: Final completion"));
- dispatchAndHandleError(ModLoadingStage.COMPLETE, syncExecutor, parallelExecutor, periodicTask);
- statusConsumer.ifPresent(c->c.accept("Freezing data"));
- GameData.freezeData();
- NetworkRegistry.lock();
- statusConsumer.ifPresent(c->c.accept(String.format("Mod loading complete - %d mods loaded", ModList.get().size())));
+ public void finishMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
+ statusConsumer.ifPresent(c->c.accept("Performing completion phase"));
+ stateManager.getStates(ModLoadingPhase.COMPLETE).forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask));
+ statusConsumer.ifPresent(c->c.accept(String.format("Mod loading complete - %d mods loaded", this.modList.size())));
}
- private void dispatchAndHandleError(ModLoadingStage state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker) {
+ private void dispatchAndHandleError(IModLoadingState state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker) {
if (!isLoadingStateValid()) {
LOGGER.error("Cowardly refusing to process mod state change request from {}", state);
return;
}
- waitForTransition(state, syncExecutor, ticker, state.buildTransition(syncExecutor, parallelExecutor));
+ statusConsumer.ifPresent(c->c.accept(state.message().apply(this.modList)));
+ state.inlineRunnable().ifPresent(a->a.accept(this.modList));
+ state.buildTransition(syncExecutor, parallelExecutor).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t));
}
- private void dispatchAndHandleError(ModLoadingStage state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker, Function> preSyncTask, Function> postSyncTask) {
+ private void dispatchAndHandleError(IModLoadingState state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker, Function> preSyncTask, Function> postSyncTask) {
if (!isLoadingStateValid()) {
LOGGER.error("Cowardly refusing to process mod state change request from {}", state);
return;
}
- waitForTransition(state, syncExecutor, ticker, state.buildTransition(syncExecutor, parallelExecutor, preSyncTask, postSyncTask));
+ statusConsumer.ifPresent(c->c.accept(state.message().apply(this.modList)));
+ state.inlineRunnable().ifPresent(a->a.accept(this.modList));
+ state.buildTransition(syncExecutor, parallelExecutor, preSyncTask, postSyncTask).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t));
}
- private void waitForTransition(final ModLoadingStage state, final ModWorkManager.DrivenExecutor syncExecutor, final Runnable ticker, final CompletableFuture> transition) {
+ private void waitForTransition(final IModLoadingState state, final ModWorkManager.DrivenExecutor syncExecutor, final Runnable ticker, final CompletableFuture> transition) {
while (!transition.isDone()) {
syncExecutor.drive(ticker);
}
@@ -265,12 +232,12 @@ public class ModLoader
.filter(ModLoadingException.class::isInstance)
.map(ModLoadingException.class::cast)
.collect(Collectors.toList());
- LOGGER.fatal(LOADING,"Failed to complete lifecycle event {}, {} errors found", state, modLoadingExceptions.size());
+ LOGGER.fatal(LOADING,"Failed to complete lifecycle event {}, {} errors found", state.name(), modLoadingExceptions.size());
throw new LoadingFailedException(modLoadingExceptions);
}
}
- private List buildMods(final ModFile modFile, final TransformingClassLoader modClassLoader)
+ private List buildMods(final ModFile modFile)
{
final Map modInfoMap = modFile.getModFileInfo().getMods().stream().collect(Collectors.toMap(IModInfo::getModId, Function.identity()));
@@ -278,7 +245,7 @@ public class ModLoader
final List containers = modFile.getScanResult().getTargets()
.entrySet()
.stream()
- .map(e -> buildModContainerFromTOML(modFile, modClassLoader, modInfoMap, e))
+ .map(e -> buildModContainerFromTOML(modFile, modInfoMap, e))
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (containers.size() != modInfoMap.size()) {
@@ -292,14 +259,14 @@ public class ModLoader
return containers.stream().filter(mc -> mc.modLoadingStage != ModLoadingStage.ERROR).collect(Collectors.toList());
}
- private ModContainer buildModContainerFromTOML(final ModFile modFile, final TransformingClassLoader modClassLoader, final Map modInfoMap, final Map.Entry idToProviderEntry) {
+ private ModContainer buildModContainerFromTOML(final ModFile modFile, final Map modInfoMap, final Map.Entry idToProviderEntry) {
try {
final String modId = idToProviderEntry.getKey();
final IModLanguageProvider.IModLanguageLoader languageLoader = idToProviderEntry.getValue();
IModInfo info = Optional.ofNullable(modInfoMap.get(modId)).
// throw a missing metadata error if there is no matching modid in the modInfoMap from the mods.toml file
orElseThrow(()->new ModLoadingException(null, ModLoadingStage.CONSTRUCT, "fml.modloading.missingmetadata", null, modId));
- return languageLoader.loadMod(info, modClassLoader, modFile.getScanResult());
+ return languageLoader.loadMod(info, modFile.getScanResult(), FMLLoader.getGameLayer());
} catch (ModLoadingException mle) {
// exceptions are caught and added to the error list for later handling
loadingExceptions.add(mle);
diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingContext.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java
similarity index 80%
rename from src/main/java/net/minecraftforge/fml/ModLoadingContext.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java
index 2cf73ee4dc..098b065de2 100644
--- a/src/main/java/net/minecraftforge/fml/ModLoadingContext.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingContext.java
@@ -19,14 +19,14 @@
package net.minecraftforge.fml;
-import net.minecraftforge.common.ForgeConfigSpec;
+import net.minecraftforge.fml.config.IConfigSpec;
import net.minecraftforge.fml.config.ModConfig;
import java.util.function.Supplier;
public class ModLoadingContext
{
- private static ThreadLocal context = ThreadLocal.withInitial(ModLoadingContext::new);
+ private static final ThreadLocal context = ThreadLocal.withInitial(ModLoadingContext::new);
private Object languageExtension;
private ModLoadingStage stage;
@@ -50,20 +50,20 @@ public class ModLoadingContext
}
/**
- * Register an {@link ExtensionPoint} with the mod container.
+ * Register an {@link IExtensionPoint} with the mod container.
* @param point The extension point to register
* @param extension An extension operator
* @param The type signature of the extension operator
*/
- public void registerExtensionPoint(ExtensionPoint point, Supplier extension) {
+ public > void registerExtensionPoint(Class extends IExtensionPoint> point, Supplier extension) {
getActiveContainer().registerExtensionPoint(point, extension);
}
- public void registerConfig(ModConfig.Type type, ForgeConfigSpec spec) {
+ public void registerConfig(ModConfig.Type type, IConfigSpec> spec) {
getActiveContainer().addConfig(new ModConfig(type, spec, getActiveContainer()));
}
- public void registerConfig(ModConfig.Type type, ForgeConfigSpec spec, String fileName) {
+ public void registerConfig(ModConfig.Type type, IConfigSpec> spec, String fileName) {
getActiveContainer().addConfig(new ModConfig(type, spec, getActiveContainer(), fileName));
}
diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingException.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingException.java
similarity index 91%
rename from src/main/java/net/minecraftforge/fml/ModLoadingException.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingException.java
index 2aa6400328..71396d2721 100644
--- a/src/main/java/net/minecraftforge/fml/ModLoadingException.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingException.java
@@ -73,7 +73,7 @@ public class ModLoadingException extends RuntimeException
}
public String formatToString() {
- return ForgeI18n.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, errorStage, getCause()), context.stream()).toArray());
+ return Bindings.getMessageParser().get().parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, errorStage, getCause()), context.stream()).toArray());
}
@Override
@@ -85,6 +85,6 @@ public class ModLoadingException extends RuntimeException
return modInfo;
}
public String getCleanMessage() {
- return ForgeI18n.stripControlCodes(formatToString());
+ return Bindings.getMessageParser().get().stripControlCodes(formatToString());
}
}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingPhase.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingPhase.java
new file mode 100644
index 0000000000..05a0b7a05c
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingPhase.java
@@ -0,0 +1,9 @@
+package net.minecraftforge.fml;
+
+public enum ModLoadingPhase {
+ ERROR, // Special state for error handling
+ GATHER,
+ LOAD,
+ COMPLETE,
+ DONE;
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingStage.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingStage.java
new file mode 100644
index 0000000000..d95439e708
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingStage.java
@@ -0,0 +1,51 @@
+/*
+ * Minecraft Forge
+ * Copyright (c) 2016-2021.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package net.minecraftforge.fml;
+
+public enum ModLoadingStage
+{
+ ERROR,
+ VALIDATE,
+ CONSTRUCT,
+ COMMON_SETUP,
+ SIDED_SETUP,
+ ENQUEUE_IMC,
+ PROCESS_IMC,
+ COMPLETE,
+ DONE;
+
+ private final DeferredWorkQueue deferredWorkQueue;
+
+ ModLoadingStage() {
+ deferredWorkQueue = new DeferredWorkQueue(this);
+ }
+
+ ModLoadingStage nextState(Throwable exception) {
+ return exception != null ? ERROR : values()[this.ordinal()+1];
+ }
+
+ public ModLoadingStage currentState(Throwable exception) {
+ return exception != null ? ERROR : this;
+ }
+
+ public DeferredWorkQueue getDeferredWorkQueue() {
+ return deferredWorkQueue;
+ }
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java
new file mode 100644
index 0000000000..d19068f78a
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java
@@ -0,0 +1,33 @@
+package net.minecraftforge.fml;
+
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.event.IModBusEvent;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public record ModLoadingState(String name, String previous, Function message, ModLoadingPhase phase, Optional> inlineRunnable, Optional transition) implements IModLoadingState {
+ @Override
+ public Optional>> buildTransition(final Executor syncExecutor, final Executor parallelExecutor, Function> preSyncTask, Function> postSyncTask) {
+ return transition.map(t->t.build(syncExecutor, parallelExecutor, preSyncTask, postSyncTask));
+ }
+
+ public static ModLoadingState empty(final String name, final String previous, final ModLoadingPhase phase) {
+ return new ModLoadingState(name, previous, ml->"", phase, Optional.empty(), Optional.empty());
+ }
+
+ public static ModLoadingState withTransition(final String name, final String previous, final ModLoadingPhase phase, IModStateTransition transition) {
+ return new ModLoadingState(name, previous, ml->"Processing transition "+name, phase, Optional.empty(), Optional.of(transition));
+ }
+
+ public static ModLoadingState withTransition(final String name, final String previous, final Function message, final ModLoadingPhase phase, IModStateTransition transition) {
+ return new ModLoadingState(name, previous, message, phase, Optional.empty(), Optional.of(transition));
+ }
+ public static ModLoadingState withInline(final String name, final String previous, final ModLoadingPhase phase, Consumer inline) {
+ return new ModLoadingState(name, previous, ml->"Processing work "+name, phase, Optional.of(inline), Optional.empty());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingWarning.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingWarning.java
similarity index 91%
rename from src/main/java/net/minecraftforge/fml/ModLoadingWarning.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingWarning.java
index a87dfb7158..1a037de6fb 100644
--- a/src/main/java/net/minecraftforge/fml/ModLoadingWarning.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingWarning.java
@@ -55,6 +55,6 @@ public class ModLoadingWarning
}
public String formatToString() {
- return ForgeI18n.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, warningStage), context.stream()).toArray());
+ return Bindings.getMessageParser().get().parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, warningStage), context.stream()).toArray());
}
}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java
new file mode 100644
index 0000000000..471b1a3b17
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java
@@ -0,0 +1,38 @@
+package net.minecraftforge.fml;
+
+import com.google.common.graph.GraphBuilder;
+import com.google.common.graph.MutableGraph;
+import cpw.mods.modlauncher.util.ServiceLoaderUtils;
+import net.minecraftforge.fml.loading.FMLLoader;
+import net.minecraftforge.fml.loading.toposort.TopologicalSort;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@SuppressWarnings("UnstableApiUsage")
+public class ModStateManager {
+ static ModStateManager INSTANCE;
+ private final EnumMap> stateMap;
+
+ public ModStateManager() {
+ INSTANCE = this;
+ final var sp = ServiceLoader.load(FMLLoader.getGameLayer(), IModStateProvider.class);
+ this.stateMap = ServiceLoaderUtils.streamWithErrorHandling(sp, sce->{})
+ .map(IModStateProvider::getAllStates)
+ .mapMulti(Iterable::forEach)
+ .collect(Collectors.groupingBy(IModLoadingState::phase, ()->new EnumMap<>(ModLoadingPhase.class), Collectors.toUnmodifiableList()));
+ }
+
+ public List getStates(final ModLoadingPhase phase) {
+ var nodes = stateMap.get(phase);
+ var lookup = nodes.stream().collect(Collectors.toMap(IModLoadingState::name, Function.identity()));
+
+ var graph = GraphBuilder.directed().allowsSelfLoops(false).build();
+ var dummy = ModLoadingState.empty("", "", phase);
+ nodes.forEach(graph::addNode);
+ graph.addNode(dummy);
+ nodes.forEach(n->graph.putEdge(lookup.getOrDefault(n.previous(), dummy), n));
+ return TopologicalSort.topologicalSort(graph, Comparator.comparingInt(nodes::indexOf)).stream().filter(st->st!=dummy).toList();
+ }
+}
diff --git a/src/main/java/net/minecraftforge/fml/ModWorkManager.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModWorkManager.java
similarity index 100%
rename from src/main/java/net/minecraftforge/fml/ModWorkManager.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/ModWorkManager.java
diff --git a/src/main/java/net/minecraftforge/fml/OptionalMod.java b/fmlcore/src/main/java/net/minecraftforge/fml/OptionalMod.java
similarity index 100%
rename from src/main/java/net/minecraftforge/fml/OptionalMod.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/OptionalMod.java
diff --git a/src/main/java/net/minecraftforge/fml/StartupMessageManager.java b/fmlcore/src/main/java/net/minecraftforge/fml/StartupMessageManager.java
similarity index 70%
rename from src/main/java/net/minecraftforge/fml/StartupMessageManager.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/StartupMessageManager.java
index d3b0c6418e..12680cb535 100644
--- a/src/main/java/net/minecraftforge/fml/StartupMessageManager.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/StartupMessageManager.java
@@ -19,8 +19,19 @@
package net.minecraftforge.fml;
+import java.util.Optional;
+import java.util.function.Consumer;
+
public class StartupMessageManager {
public static void addModMessage(final String message) {
net.minecraftforge.fml.loading.progress.StartupMessageManager.addModMessage(message);
}
+
+ public static Optional> modLoaderConsumer() {
+ return net.minecraftforge.fml.loading.progress.StartupMessageManager.modLoaderConsumer();
+ }
+
+ public static Optional> mcLoaderConsumer() {
+ return net.minecraftforge.fml.loading.progress.StartupMessageManager.mcLoaderConsumer();
+ }
}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ThreadSelector.java b/fmlcore/src/main/java/net/minecraftforge/fml/ThreadSelector.java
new file mode 100644
index 0000000000..e6380cc108
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/ThreadSelector.java
@@ -0,0 +1,20 @@
+package net.minecraftforge.fml;
+
+import java.util.concurrent.Executor;
+import java.util.function.BinaryOperator;
+
+public enum ThreadSelector implements BinaryOperator {
+ SYNC((sync, parallel) -> sync),
+ PARALLEL((sync, parallel) -> parallel);
+
+ private final BinaryOperator selector;
+
+ ThreadSelector(final BinaryOperator selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public Executor apply(final Executor sync, final Executor parallel) {
+ return this.selector.apply(sync, parallel);
+ }
+}
diff --git a/src/main/java/net/minecraftforge/fml/VersionChecker.java b/fmlcore/src/main/java/net/minecraftforge/fml/VersionChecker.java
similarity index 89%
rename from src/main/java/net/minecraftforge/fml/VersionChecker.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/VersionChecker.java
index f53bd07164..6d8cd7e6f8 100644
--- a/src/main/java/net/minecraftforge/fml/VersionChecker.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/VersionChecker.java
@@ -24,15 +24,16 @@ import com.google.gson.Gson;
import net.minecraftforge.fml.loading.FMLConfig;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import net.minecraftforge.forgespi.language.IModInfo;
-import net.minecraftforge.versions.mcp.MCPVersion;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.maven.artifact.versioning.ComparableVersion;
+
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.net.http.HttpClient;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
@@ -41,8 +42,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import static net.minecraftforge.fml.VersionChecker.Status.*;
@@ -103,25 +102,7 @@ public class VersionChecker
}
- public static class CheckResult
- {
- @Nonnull
- public final Status status;
- @Nullable
- public final ComparableVersion target;
- @Nullable
- public final Map changes;
- @Nullable
- public final String url;
-
- private CheckResult(@Nonnull Status status, @Nullable ComparableVersion target, @Nullable Map changes, @Nullable String url)
- {
- this.status = status;
- this.target = target;
- this.changes = changes == null ? Collections.emptyMap() : Collections.unmodifiableMap(changes);
- this.url = url;
- }
- }
+ public record CheckResult(VersionChecker.Status status, ComparableVersion target, Map changes, String url) {}
public static void startVersionCheck()
{
@@ -175,13 +156,15 @@ public class VersionChecker
private void process(IModInfo mod)
{
+// HttpClient.newBuilder().build();
Status status = PENDING;
ComparableVersion target = null;
Map changes = null;
String display_url = null;
try
{
- URL url = mod.getUpdateURL();
+ if (mod.getUpdateURL().isEmpty()) return;
+ URL url = mod.getUpdateURL().get();
LOGGER.info("[{}] Starting version check at {}", mod.getModId(), url.toString());
InputStream con = openUrlStream(url);
@@ -197,7 +180,8 @@ public class VersionChecker
Map promos = (Map)json.get("promos");
display_url = (String)json.get("homepage");
- String mcVersion = MCPVersion.getMCVersion();
+// String mcVersion = MCPVersion.getMCVersion();
+ var mcVersion = "1.17";
String rec = promos.get(mcVersion + "-recommended");
String lat = promos.get(mcVersion + "-latest");
ComparableVersion current = new ComparableVersion(mod.getVersion().toString());
@@ -278,9 +262,8 @@ public class VersionChecker
private static List gatherMods()
{
List ret = new LinkedList<>();
- for (ModInfo info : ModList.get().getMods()) {
- URL url = info.getUpdateURL();
- if (url != null)
+ for (IModInfo info : ModList.get().getMods()) {
+ if (info.getUpdateURL().isPresent())
ret.add(info);
}
return ret;
diff --git a/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java
similarity index 98%
rename from src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java
index 4e81783087..a0ff68d490 100644
--- a/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java
@@ -157,7 +157,7 @@ public class ConfigFileTypeHandler {
}
LOGGER.debug(CONFIG, "Config file {} changed, sending notifies", this.modConfig.getFileName());
this.modConfig.getSpec().afterReload();
- this.modConfig.fireEvent(new ModConfig.Reloading(this.modConfig));
+ this.modConfig.fireEvent(IConfigEvent.reloading(this.modConfig));
}
}
}
diff --git a/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java
similarity index 69%
rename from src/main/java/net/minecraftforge/fml/config/ConfigTracker.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java
index 61426d85b0..78ec0b98d5 100644
--- a/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java
@@ -21,33 +21,14 @@ package net.minecraftforge.fml.config;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
-import com.electronwill.nightconfig.toml.TomlFormat;
-import it.unimi.dsi.fastutil.bytes.Byte2ByteOpenCustomHashMap;
-import net.minecraft.client.Minecraft;
-import net.minecraftforge.fml.network.FMLHandshakeMessages;
-import net.minecraftforge.fml.network.NetworkEvent;
-import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.rethrowFunction;
public class ConfigTracker {
private static final Logger LOGGER = LogManager.getLogger();
@@ -55,7 +36,7 @@ public class ConfigTracker {
public static final ConfigTracker INSTANCE = new ConfigTracker();
private final ConcurrentHashMap fileMap;
private final EnumMap> configSets;
- private ConcurrentHashMap> configsByMod;
+ private final ConcurrentHashMap> configsByMod;
private ConfigTracker() {
this.fileMap = new ConcurrentHashMap<>();
@@ -88,22 +69,11 @@ public class ConfigTracker {
this.configSets.get(type).forEach(config -> closeConfig(config, configBasePath));
}
- public List> syncConfigs(boolean isLocal) {
- final Map configData = configSets.get(ModConfig.Type.SERVER).stream().collect(Collectors.toMap(ModConfig::getFileName, mc -> { //TODO: Test cpw's LambdaExceptionUtils on Oracle javac.
- try {
- return Files.readAllBytes(mc.getFullPath());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }));
- return configData.entrySet().stream().map(e->Pair.of("Config "+e.getKey(), new FMLHandshakeMessages.S2CConfigData(e.getKey(), e.getValue()))).collect(Collectors.toList());
- }
-
private void openConfig(final ModConfig config, final Path configBasePath) {
LOGGER.trace(CONFIG, "Loading config file type {} at {} for {}", config.getType(), config.getFileName(), config.getModId());
final CommentedFileConfig configData = config.getHandler().reader(configBasePath).apply(config);
config.setConfigData(configData);
- config.fireEvent(new ModConfig.Loading(config));
+ config.fireEvent(IConfigEvent.loading(config));
config.save();
}
@@ -116,21 +86,12 @@ public class ConfigTracker {
}
}
- public void receiveSyncedConfig(final FMLHandshakeMessages.S2CConfigData s2CConfigData, final Supplier contextSupplier) {
- if (!Minecraft.getInstance().isLocalServer()) {
- Optional.ofNullable(fileMap.get(s2CConfigData.getFileName())).ifPresent(mc-> {
- mc.setConfigData(TomlFormat.instance().createParser().parse(new ByteArrayInputStream(s2CConfigData.getBytes())));
- mc.fireEvent(new ModConfig.Reloading(mc));
- });
- }
- }
-
public void loadDefaultServerConfigs() {
configSets.get(ModConfig.Type.SERVER).forEach(modConfig -> {
final CommentedConfig commentedConfig = CommentedConfig.inMemory();
modConfig.getSpec().correct(commentedConfig);
modConfig.setConfigData(commentedConfig);
- modConfig.fireEvent(new ModConfig.Loading(modConfig));
+ modConfig.fireEvent(IConfigEvent.loading(modConfig));
});
}
@@ -138,4 +99,12 @@ public class ConfigTracker {
return Optional.ofNullable(configsByMod.getOrDefault(modId, Collections.emptyMap()).getOrDefault(type, null)).
map(ModConfig::getFullPath).map(Object::toString).orElse(null);
}
+
+ public Map> configSets() {
+ return configSets;
+ }
+
+ public ConcurrentHashMap fileMap() {
+ return fileMap;
+ }
}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/config/IConfigEvent.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/IConfigEvent.java
new file mode 100644
index 0000000000..b53d3dc5ba
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/IConfigEvent.java
@@ -0,0 +1,24 @@
+package net.minecraftforge.fml.config;
+
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.Bindings;
+
+import java.util.function.Function;
+
+public interface IConfigEvent {
+ record ConfigConfig(Function loading, Function reloading) {}
+ ConfigConfig CONFIGCONFIG = Bindings.getConfigConfiguration().get();
+
+ static IConfigEvent reloading(ModConfig modConfig) {
+ return CONFIGCONFIG.reloading().apply(modConfig);
+ }
+ static IConfigEvent loading(ModConfig modConfig) {
+ return CONFIGCONFIG.loading().apply(modConfig);
+ }
+ ModConfig getConfig();
+
+ @SuppressWarnings("unchecked")
+ default T self() {
+ return (T) this;
+ }
+}
diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/config/IConfigSpec.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/IConfigSpec.java
new file mode 100644
index 0000000000..0257559122
--- /dev/null
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/IConfigSpec.java
@@ -0,0 +1,21 @@
+package net.minecraftforge.fml.config;
+
+import com.electronwill.nightconfig.core.CommentedConfig;
+import com.electronwill.nightconfig.core.UnmodifiableConfig;
+
+public interface IConfigSpec> extends UnmodifiableConfig {
+ @SuppressWarnings("unchecked")
+ default T self() {
+ return (T) this;
+ }
+
+ void acceptConfig(CommentedConfig data);
+
+ boolean isCorrecting();
+
+ boolean isCorrect(CommentedConfig commentedFileConfig);
+
+ int correct(CommentedConfig commentedFileConfig);
+
+ void afterReload();
+}
diff --git a/src/main/java/net/minecraftforge/fml/config/ModConfig.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java
similarity index 77%
rename from src/main/java/net/minecraftforge/fml/config/ModConfig.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java
index d2cbb565b5..f41543bb11 100644
--- a/src/main/java/net/minecraftforge/fml/config/ModConfig.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java
@@ -21,26 +21,25 @@ package net.minecraftforge.fml.config;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
-import net.minecraftforge.common.ForgeConfigSpec;
-import net.minecraftforge.eventbus.api.Event;
+import com.electronwill.nightconfig.toml.TomlFormat;
import net.minecraftforge.fml.ModContainer;
-import net.minecraftforge.fml.event.lifecycle.IModBusEvent;
import net.minecraftforge.fml.loading.StringUtils;
+import java.io.ByteArrayInputStream;
import java.nio.file.Path;
import java.util.concurrent.Callable;
public class ModConfig
{
private final Type type;
- private final ForgeConfigSpec spec;
+ private final IConfigSpec> spec;
private final String fileName;
private final ModContainer container;
private final ConfigFileTypeHandler configHandler;
private CommentedConfig configData;
private Callable saveHandler;
- public ModConfig(final Type type, final ForgeConfigSpec spec, final ModContainer container, final String fileName) {
+ public ModConfig(final Type type, final IConfigSpec> spec, final ModContainer container, final String fileName) {
this.type = type;
this.spec = spec;
this.fileName = fileName;
@@ -49,7 +48,7 @@ public class ModConfig
ConfigTracker.INSTANCE.trackConfig(this);
}
- public ModConfig(final Type type, final ForgeConfigSpec spec, final ModContainer activeContainer) {
+ public ModConfig(final Type type, final IConfigSpec> spec, final ModContainer activeContainer) {
this(type, spec, activeContainer, defaultConfigName(type, activeContainer.getModId()));
}
@@ -69,8 +68,9 @@ public class ModConfig
return configHandler;
}
- public ForgeConfigSpec getSpec() {
- return spec;
+ @SuppressWarnings("unchecked")
+ public > IConfigSpec getSpec() {
+ return (IConfigSpec) spec;
}
public String getModId() {
@@ -83,10 +83,10 @@ public class ModConfig
void setConfigData(final CommentedConfig configData) {
this.configData = configData;
- this.spec.setConfig(this.configData);
+ this.spec.acceptConfig(this.configData);
}
- void fireEvent(final ModConfigEvent configEvent) {
+ void fireEvent(final IConfigEvent configEvent) {
this.container.dispatchConfigEvent(configEvent);
}
@@ -98,6 +98,11 @@ public class ModConfig
return ((CommentedFileConfig)this.configData).getNioPath();
}
+ public void acceptSyncedConfig(byte[] bytes) {
+ setConfigData(TomlFormat.instance().createParser().parse(new ByteArrayInputStream(bytes)));
+ fireEvent(IConfigEvent.reloading(this));
+ }
+
public enum Type {
/**
* Common mod config for configuration that needs to be loaded on both environments.
@@ -133,28 +138,4 @@ public class ModConfig
return StringUtils.toLowerCase(name());
}
}
-
- public static class ModConfigEvent extends Event implements IModBusEvent {
- private final ModConfig config;
-
- ModConfigEvent(final ModConfig config) {
- this.config = config;
- }
-
- public ModConfig getConfig() {
- return config;
- }
- }
-
- public static class Loading extends ModConfigEvent {
- Loading(final ModConfig config) {
- super(config);
- }
- }
-
- public static class Reloading extends ModConfigEvent {
- Reloading(final ModConfig config) {
- super(config);
- }
- }
}
diff --git a/src/main/java/net/minecraftforge/fml/event/lifecycle/IModBusEvent.java b/fmlcore/src/main/java/net/minecraftforge/fml/event/IModBusEvent.java
similarity index 94%
rename from src/main/java/net/minecraftforge/fml/event/lifecycle/IModBusEvent.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/event/IModBusEvent.java
index 79c5ffb1d9..41e0b14d29 100644
--- a/src/main/java/net/minecraftforge/fml/event/lifecycle/IModBusEvent.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/event/IModBusEvent.java
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.event.lifecycle;
+package net.minecraftforge.fml.event;
/**
* Marker interface for events dispatched on the ModLifecycle event bus instead of the primary event bus
diff --git a/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/CertificateHelper.java
similarity index 98%
rename from src/main/java/net/minecraftforge/fml/common/CertificateHelper.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/CertificateHelper.java
index d61a2b0ef0..ae6e296eff 100644
--- a/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/CertificateHelper.java
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common;
+package net.minecraftforge.fml.util;
import com.google.common.collect.ImmutableList;
diff --git a/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/EnhancedRuntimeException.java
similarity index 98%
rename from src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/EnhancedRuntimeException.java
index fde2747a03..fdee96905d 100644
--- a/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/EnhancedRuntimeException.java
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common;
+package net.minecraftforge.fml.util;
import java.io.PrintStream;
import java.io.PrintWriter;
diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderException.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/LoaderException.java
similarity index 91%
rename from src/main/java/net/minecraftforge/fml/common/LoaderException.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/LoaderException.java
index 3e31d0fc8e..373e860c64 100644
--- a/src/main/java/net/minecraftforge/fml/common/LoaderException.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/LoaderException.java
@@ -17,8 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common;
-import net.minecraftforge.fml.common.EnhancedRuntimeException.WrappedPrintStream;
+package net.minecraftforge.fml.util;
public class LoaderException extends EnhancedRuntimeException
diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/LoaderExceptionModCrash.java
similarity index 96%
rename from src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/LoaderExceptionModCrash.java
index 6e866e3024..1031d6e14d 100644
--- a/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/LoaderExceptionModCrash.java
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common;
+package net.minecraftforge.fml.util;
/**
* Prevent LoaderException from adding its own stack trace to the wrapped throwable's stack trace.
diff --git a/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/ObfuscationReflectionHelper.java
similarity index 93%
rename from src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/ObfuscationReflectionHelper.java
index 79b670dafd..52e5dded68 100644
--- a/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/ObfuscationReflectionHelper.java
@@ -17,15 +17,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common;
+package net.minecraftforge.fml.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.StringJoiner;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
import cpw.mods.modlauncher.api.INameMappingService;
import net.minecraftforge.fml.loading.FMLLoader;
import org.apache.logging.log4j.LogManager;
@@ -34,6 +31,8 @@ import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import com.google.common.base.Preconditions;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* Some reflection helper code.
@@ -58,7 +57,7 @@ public class ObfuscationReflectionHelper
* @param name The name to try and remap.
* @return The remapped name, or the original name if it couldn't be remapped.
*/
- @Nonnull
+ @NotNull
public static String remapName(INameMappingService.Domain domain, String name)
{
return FMLLoader.getNameFunction("srg").map(f->f.apply(domain, name)).orElse(name);
@@ -72,7 +71,7 @@ public class ObfuscationReflectionHelper
*
* @param classToAccess The class to find the field on.
* @param instance The instance of the {@code classToAccess}.
- * @param fieldName The SRG (unmapped) name of the field to find (e.g. "field_181725_a").
+ * @param fieldName The SRG (unmapped) name of the field to find (e.g. "f_46443_").
* @param The type of the value.
* @param The type of the {@code classToAccess}.
* @return The value of the field with the specified name in the {@code classToAccess}.
@@ -113,7 +112,7 @@ public class ObfuscationReflectionHelper
* @throws UnableToFindFieldException If there was a problem getting the field.
* @throws UnableToAccessFieldException If there was a problem setting the value of the field.
*/
- public static void setPrivateValue(@Nonnull final Class super T> classToAccess, @Nonnull final T instance, @Nullable final E value, @Nonnull final String fieldName)
+ public static void setPrivateValue(@NotNull final Class super T> classToAccess, @NotNull final T instance, @Nullable final E value, @NotNull final String fieldName)
{
try
{
@@ -138,7 +137,7 @@ public class ObfuscationReflectionHelper
* Throws an exception if the method is not found.
*
* @param clazz The class to find the method on.
- * @param methodName The SRG (unmapped) name of the method to find (e.g. "func_12820_D").
+ * @param methodName The SRG (unmapped) name of the method to find (e.g. "m_5776_").
* @param parameterTypes The parameter types of the method to find.
* @return The method with the specified name and parameters in the given class.
* @throws NullPointerException If {@code clazz} is null.
@@ -147,8 +146,8 @@ public class ObfuscationReflectionHelper
* @throws NullPointerException If {@code parameterTypes} is null.
* @throws UnableToFindMethodException If the method could not be found.
*/
- @Nonnull
- public static Method findMethod(@Nonnull final Class> clazz, @Nonnull final String methodName, @Nonnull final Class>... parameterTypes)
+ @NotNull
+ public static Method findMethod(@NotNull final Class> clazz, @NotNull final String methodName, @NotNull final Class>... parameterTypes)
{
Preconditions.checkNotNull(clazz, "Class to find method on cannot be null.");
Preconditions.checkNotNull(methodName, "Name of method to find cannot be null.");
@@ -181,8 +180,8 @@ public class ObfuscationReflectionHelper
* @throws NullPointerException If {@code parameterTypes} is null.
* @throws UnknownConstructorException If the constructor could not be found.
*/
- @Nonnull
- public static Constructor findConstructor(@Nonnull final Class clazz, @Nonnull final Class>... parameterTypes)
+ @NotNull
+ public static Constructor findConstructor(@NotNull final Class clazz, @NotNull final Class>... parameterTypes)
{
Preconditions.checkNotNull(clazz, "Class to find constructor on cannot be null.");
Preconditions.checkNotNull(parameterTypes, "Parameter types of constructor to find cannot be null.");
@@ -216,7 +215,7 @@ public class ObfuscationReflectionHelper
* Throws an exception if the field is not found.
*
* @param clazz The class to find the field on.
- * @param fieldName The SRG (unmapped) name of the field to find (e.g. "field_181725_a").
+ * @param fieldName The SRG (unmapped) name of the field to find (e.g. "f_46443_").
* @param The type.
* @return The constructor with the specified parameters in the given class.
* @throws NullPointerException If {@code clazz} is null.
@@ -224,8 +223,8 @@ public class ObfuscationReflectionHelper
* @throws IllegalArgumentException If {@code fieldName} is empty.
* @throws UnableToFindFieldException If the field could not be found.
*/
- @Nonnull
- public static Field findField(@Nonnull final Class super T> clazz, @Nonnull final String fieldName)
+ @NotNull
+ public static Field findField(@NotNull final Class super T> clazz, @NotNull final String fieldName)
{
Preconditions.checkNotNull(clazz, "Class to find field on cannot be null.");
Preconditions.checkNotNull(fieldName, "Name of field to find cannot be null.");
diff --git a/src/main/java/net/minecraftforge/fml/common/thread/EffectiveSide.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/thread/EffectiveSide.java
similarity index 95%
rename from src/main/java/net/minecraftforge/fml/common/thread/EffectiveSide.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/thread/EffectiveSide.java
index 61fd6b6c60..c4452f99dd 100644
--- a/src/main/java/net/minecraftforge/fml/common/thread/EffectiveSide.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/thread/EffectiveSide.java
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common.thread;
+package net.minecraftforge.fml.util.thread;
import net.minecraftforge.fml.LogicalSide;
diff --git a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/thread/SidedThreadGroup.java
similarity index 90%
rename from src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/thread/SidedThreadGroup.java
index 2cb7c0de2c..af10af460a 100644
--- a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/thread/SidedThreadGroup.java
@@ -17,14 +17,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common.thread;
+package net.minecraftforge.fml.util.thread;
import net.minecraftforge.fml.LogicalSide;
+import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ThreadFactory;
-import javax.annotation.Nonnull;
-
/**
* A thread group and factory combination which belongs to a {@link LogicalSide}.
*/
@@ -49,7 +48,7 @@ public final class SidedThreadGroup extends ThreadGroup implements ThreadFactory
}
@Override
- public Thread newThread(@Nonnull final Runnable runnable)
+ public Thread newThread(@NotNull final Runnable runnable)
{
return new Thread(this, runnable);
}
diff --git a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java b/fmlcore/src/main/java/net/minecraftforge/fml/util/thread/SidedThreadGroups.java
similarity index 95%
rename from src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java
rename to fmlcore/src/main/java/net/minecraftforge/fml/util/thread/SidedThreadGroups.java
index d87374f0c4..1600462238 100644
--- a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java
+++ b/fmlcore/src/main/java/net/minecraftforge/fml/util/thread/SidedThreadGroups.java
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-package net.minecraftforge.fml.common.thread;
+package net.minecraftforge.fml.util.thread;
import net.minecraftforge.fml.LogicalSide;
diff --git a/fmlloader/build.gradle b/fmlloader/build.gradle
new file mode 100644
index 0000000000..7667c4591f
--- /dev/null
+++ b/fmlloader/build.gradle
@@ -0,0 +1,80 @@
+plugins {
+ id 'com.github.ben-manes.versions'
+ id 'org.javamodularity.moduleplugin' version '1.8.3' apply false
+}
+apply plugin: 'java-library'
+apply plugin: 'jacoco'
+apply plugin: 'org.javamodularity.moduleplugin'
+
+dependencyUpdates.rejectVersionIf { isNonStable(it.candidate.version) }
+configurations.forEach{ it.transitive = false }
+
+dependencies {
+ implementation('net.sf.jopt-simple:jopt-simple:5.0.4')
+ compileOnly('org.jetbrains:annotations:21.0.0')
+ api("org.ow2.asm:asm:${ASM_VERSION}")
+ api("org.ow2.asm:asm-tree:${ASM_VERSION}")
+ api("org.ow2.asm:asm-commons:${ASM_VERSION}")
+ api('net.minecraftforge:forgespi:4.0.+')
+ api('org.apache.logging.log4j:log4j-api:2.14.1')
+ api('com.google.guava:guava:21.0')
+ api('com.google.code.gson:gson:2.8.0')
+ api('org.apache.maven:maven-artifact:3.8.1')
+ api('org.apache.commons:commons-lang3:3.8.1')
+ api('com.electronwill.night-config:core:3.6.3')
+ api('com.electronwill.night-config:toml:3.6.3')
+ api('cpw.mods:modlauncher:9.0.+')
+ api('net.minecraftforge:coremods:5.0.+')
+ implementation("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}")
+ implementation('org.apache.logging.log4j:log4j-core:2.14.1')
+ annotationProcessor('org.apache.logging.log4j:log4j-core:2.14.1')
+ implementation('net.minecraftforge:accesstransformers:8.0.4')
+ implementation('net.minecrell:terminalconsoleappender:1.2.0')
+// implementation('org.jline:jline:3.12.+')
+ testCompileOnly('org.jetbrains:annotations:21.0.0')
+ testRuntimeOnly("cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}")
+}
+
+task sourcesJar(type: Jar) {
+ archiveClassifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+ext {
+ MANIFESTS = [
+ '/': [
+ 'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
+ 'Git-Commit': GIT_INFO.abbreviatedId,
+ 'Git-Branch': GIT_INFO.branch,
+ 'Build-Number': "${System.getenv('BUILD_NUMBER')?:0}",
+ ] as LinkedHashMap,
+ 'net/minecraftforge/fml/loading/': [
+ 'Specification-Title': 'FMLLoader',
+ 'Specification-Vendor': 'Forge Development LLC',
+ 'Specification-Version': '1',
+ 'Implementation-Title': 'FML Loader',
+ 'Implementation-Version': '1.0',
+ 'Implementation-Vendor': 'Forge'
+ ] as LinkedHashMap
+ ]
+}
+
+jar.doFirst {
+ MANIFESTS.each { pkg, values ->
+ manifest.attributes(values, pkg)
+ }
+}
+
+tasks.withType(JavaCompile) {
+ options.compilerArgs << '-Xlint:unchecked'
+}
+
+artifacts {
+ archives jar
+ archives sourcesJar
+}
+
+publishing.publications.mavenJava(MavenPublication) {
+ from components.java
+ artifact sourcesJar
+}
\ No newline at end of file
diff --git a/src/fmllauncher/java/net/minecraftforge/common/asm/CapabilityInjectDefinalize.java b/fmlloader/src/main/java/net/minecraftforge/common/asm/CapabilityInjectDefinalize.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/common/asm/CapabilityInjectDefinalize.java
rename to fmlloader/src/main/java/net/minecraftforge/common/asm/CapabilityInjectDefinalize.java
diff --git a/src/fmllauncher/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java b/fmlloader/src/main/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java
rename to fmlloader/src/main/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java
diff --git a/src/fmllauncher/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java b/fmlloader/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java
rename to fmlloader/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/AdvancedLogMessageAdapter.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/AdvancedLogMessageAdapter.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/AdvancedLogMessageAdapter.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/AdvancedLogMessageAdapter.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/BackgroundWaiter.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/BackgroundWaiter.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/BackgroundWaiter.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/BackgroundWaiter.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/EarlyLoadingException.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/EarlyLoadingException.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/EarlyLoadingException.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/EarlyLoadingException.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLConfig.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java
similarity index 91%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/FMLConfig.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java
index 5ce6746424..88cf4758df 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLConfig.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java
@@ -21,6 +21,7 @@ package net.minecraftforge.fml.loading;
import com.electronwill.nightconfig.core.ConfigSpec;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import com.electronwill.nightconfig.core.file.FileNotFoundAction;
import com.electronwill.nightconfig.core.io.ParsingException;
import com.electronwill.nightconfig.core.io.WritingMode;
import net.minecraftforge.api.distmarker.Dist;
@@ -30,6 +31,7 @@ import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
+import java.util.Objects;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
@@ -50,11 +52,11 @@ public class FMLConfig
private void loadFrom(final Path configFile)
{
- configData = CommentedFileConfig.builder(configFile).sync().
- defaultResource("/META-INF/defaultfmlconfig.toml").
- autosave().autoreload().
- writingMode(WritingMode.REPLACE).
- build();
+ configData = CommentedFileConfig.builder(configFile).sync()
+ .onFileNotFound(FileNotFoundAction.copyData(Objects.requireNonNull(getClass().getResourceAsStream("/META-INF/defaultfmlconfig.toml"))))
+ .autosave().autoreload()
+ .writingMode(WritingMode.REPLACE)
+ .build();
try
{
configData.load();
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLEnvironment.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLEnvironment.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/FMLEnvironment.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLEnvironment.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLLoader.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java
similarity index 71%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/FMLLoader.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java
index de65ff54a4..c439493b27 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLLoader.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java
@@ -20,42 +20,25 @@
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.Launcher;
-import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
-import cpw.mods.modlauncher.TransformingClassLoader;
-import cpw.mods.modlauncher.api.IEnvironment;
-import cpw.mods.modlauncher.api.ILaunchHandlerService;
-import cpw.mods.modlauncher.api.INameMappingService;
-import cpw.mods.modlauncher.api.ITransformationService;
-import cpw.mods.modlauncher.api.ITransformingClassLoader;
-import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
+import cpw.mods.modlauncher.api.*;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
+import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.accesstransformer.service.AccessTransformerService;
import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
-import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer;
-import net.minecraftforge.fml.loading.moddiscovery.ModFile;
-import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
+import net.minecraftforge.fml.loading.moddiscovery.*;
import net.minecraftforge.fml.loading.progress.EarlyProgressVisualization;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
+import net.minecraftforge.fml.loading.targets.CommonLaunchHandler;
import net.minecraftforge.forgespi.Environment;
import net.minecraftforge.forgespi.coremod.ICoreModProvider;
-import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
@@ -72,21 +55,16 @@ public class FMLLoader
private static Dist dist;
private static String naming;
private static LoadingModList loadingModList;
- private static TransformingClassLoader launchClassLoader;
private static RuntimeDistCleaner runtimeDistCleaner;
private static Path gamePath;
- private static Path forgePath;
- private static Path[] mcPaths;
- static String mcVersion;
- private static String mcpVersion;
- static String forgeVersion;
- private static String forgeGroup;
- private static Predicate classLoaderExclusions;
+ private static VersionInfo versionInfo;
private static String launchHandlerName;
- private static FMLCommonLaunchHandler commonLaunchHandler;
+ private static CommonLaunchHandler commonLaunchHandler;
public static Runnable progressWindowTick;
+ private static ModValidator modValidator;
public static BackgroundScanHandler backgroundScanHandler;
private static boolean production;
+ private static IModuleLayerManager moduleLayerManager;
static void onInitialLoad(IEnvironment environment, Set otherServices) throws IncompatibleEnvironmentException
{
@@ -98,8 +76,6 @@ public class FMLLoader
LOGGER.fatal(CORE,"Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor());
throw new IncompatibleEnvironmentException("Incompatible modlauncher found "+modLauncherPackage.getSpecificationVersion());
}
- LOGGER.debug(CORE, "Initializing modjar URL handler");
- URL.setURLStreamHandlerFactory(p->p.equals("modjar") ? new ModJarURLHandler() : null);
accessTransformer = (AccessTransformerService) environment.findLaunchPlugin("accesstransformer").orElseThrow(()-> {
LOGGER.fatal(CORE,"Access Transformer library is missing, we need this to run");
@@ -131,8 +107,7 @@ public class FMLLoader
});
LOGGER.debug(CORE, "Found Runtime Dist Cleaner");
- final ArrayList coreModProviders = new ArrayList<>();
- ServiceLoaderStreamUtils.errorHandlingServiceLoader(ICoreModProvider.class, serviceConfigurationError -> LOGGER.fatal(CORE, "Failed to load a coremod library, expect problems", serviceConfigurationError)).forEach(coreModProviders::add);
+ var coreModProviders = ServiceLoaderUtils.streamWithErrorHandling(ServiceLoader.load(FMLLoader.class.getModule().getLayer(), ICoreModProvider.class), sce -> LOGGER.fatal(CORE, "Failed to load a coremod library, expect problems", sce)).toList();
if (coreModProviders.isEmpty()) {
LOGGER.fatal(CORE, "Found no coremod provider. Cannot run");
@@ -161,7 +136,6 @@ public class FMLLoader
LOGGER.fatal(CORE, "Failed to load NightConfig");
throw new IncompatibleEnvironmentException("Missing NightConfig");
}
- FixSSL.fixup();
}
static void setupLaunchHandler(final IEnvironment environment, final Map arguments)
@@ -169,55 +143,48 @@ public class FMLLoader
final String launchTarget = environment.getProperty(IEnvironment.Keys.LAUNCHTARGET.get()).orElse("MISSING");
final Optional launchHandler = environment.findLaunchHandler(launchTarget);
LOGGER.debug(CORE, "Using {} as launch service", launchTarget);
- if (!launchHandler.isPresent()) {
+ if (launchHandler.isEmpty()) {
LOGGER.fatal(CORE,"Missing LaunchHandler {}, cannot continue", launchTarget);
- throw new RuntimeException("Missing launch handler");
+ throw new RuntimeException("Missing launch handler: " + launchTarget);
}
- if (!(launchHandler.get() instanceof FMLCommonLaunchHandler)) {
+ if (!(launchHandler.get() instanceof CommonLaunchHandler)) {
LOGGER.fatal(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName());
throw new RuntimeException("Incompatible launch handler found");
}
+ commonLaunchHandler = (CommonLaunchHandler)launchHandler.get();
launchHandlerName = launchHandler.get().name();
gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".").toAbsolutePath());
- commonLaunchHandler = (FMLCommonLaunchHandler)launchHandler.get();
naming = commonLaunchHandler.getNaming();
dist = commonLaunchHandler.getDist();
production = commonLaunchHandler.isProduction();
- mcVersion = (String) arguments.get("mcVersion");
- progressWindowTick = EarlyProgressVisualization.INSTANCE.accept(dist, commonLaunchHandler.isData(), mcVersion);
+ versionInfo = new VersionInfo(arguments);
+
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Early Loading!"));
accessTransformer.getExtension().accept(Pair.of(naming, "srg"));
- mcpVersion = (String) arguments.get("mcpVersion");
- forgeVersion = (String) arguments.get("forgeVersion");
- forgeGroup = (String) arguments.get("forgeGroup");
-
- LOGGER.debug(CORE,"Received command line version data : MC Version: '{}' MCP Version: '{}' Forge Version: '{}' Forge group: '{}'", mcVersion, mcpVersion, forgeVersion, forgeGroup);
- forgePath = commonLaunchHandler.getForgePath(mcVersion, forgeVersion, forgeGroup);
- mcPaths = commonLaunchHandler.getMCPaths(mcVersion, mcpVersion, forgeVersion, forgeGroup);
-
- commonLaunchHandler.validatePaths(forgePath, mcPaths, forgeVersion, mcVersion, mcpVersion);
- commonLaunchHandler.setup(environment, arguments);
- classLoaderExclusions = commonLaunchHandler.getPackagePredicate();
-
- languageLoadingProvider = new LanguageLoadingProvider();
- languageLoadingProvider.addForgeLanguage(forgePath);
+ LOGGER.debug(CORE,"Received command line version data : {}", versionInfo);
runtimeDistCleaner.getExtension().accept(dist);
- progressWindowTick.run();
}
- public static Map> beginModScan(final Map arguments)
+ public static List beginModScan(final Map arguments)
{
LOGGER.debug(SCAN,"Scanning for Mod Locators");
modDiscoverer = new ModDiscoverer(arguments);
- backgroundScanHandler = modDiscoverer.discoverMods();
+ modValidator = modDiscoverer.discoverMods();
+ var pluginResources = modValidator.getPluginResources();
+ return List.of(pluginResources);
+ }
+
+ public static List completeScan(IModuleLayerManager layerManager) {
+ progressWindowTick = EarlyProgressVisualization.INSTANCE.accept(dist, commonLaunchHandler.isData(), versionInfo.mcVersion());
+ moduleLayerManager = layerManager;
+ languageLoadingProvider = new LanguageLoadingProvider();
+ backgroundScanHandler = modValidator.stage2Validation();
loadingModList = backgroundScanHandler.getLoadingModList();
- commonLaunchHandler.addLibraries(backgroundScanHandler.getModFiles().getOrDefault(IModFile.Type.LIBRARY, Collections.emptyList()));
- progressWindowTick.run();
- return loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.groupingBy(ModFile::getType));
+ return List.of(modValidator.getModResources());
}
public static ICoreModProvider getCoreModProvider() {
@@ -233,6 +200,10 @@ public class FMLLoader
return modDiscoverer;
}
+ public static CommonLaunchHandler getLaunchHandler() {
+ return commonLaunchHandler;
+ }
+
public static void addAccessTransformer(Path atPath, ModFile modName)
{
LOGGER.debug(SCAN, "Adding Access Transformer in {}", modName.getFilePath());
@@ -244,9 +215,8 @@ public class FMLLoader
return dist;
}
- public static void beforeStart(ITransformingClassLoader launchClassLoader)
+ public static void beforeStart(ClassLoader launchClassLoader)
{
- FMLLoader.launchClassLoader = (TransformingClassLoader) launchClassLoader.getInstance();
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Launching minecraft"));
progressWindowTick.run();
}
@@ -256,28 +226,11 @@ public class FMLLoader
return loadingModList;
}
- public static TransformingClassLoader getLaunchClassLoader()
- {
- return launchClassLoader;
- }
-
public static Path getGamePath()
{
return gamePath;
}
- public static Path getForgePath() {
- return forgePath;
- }
-
- public static Path[] getMCPaths() {
- return mcPaths;
- }
-
- public static Predicate getClassLoaderExclusions() {
- return classLoaderExclusions;
- }
-
public static String getNaming() {
return naming;
}
@@ -286,10 +239,6 @@ public class FMLLoader
return Launcher.INSTANCE.environment().findNameMapping(naming);
}
- public static String getMcpVersion() {
- return mcpVersion;
- }
-
public static String getLauncherInfo() {
return Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.MLIMPL_VERSION.get()).orElse("MISSING");
}
@@ -307,6 +256,14 @@ public class FMLLoader
}
public static boolean isSecureJarEnabled() {
- return Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.SECURED_JARS_ENABLED.get()).orElse(false);
+ return true;
+ }
+
+ public static ModuleLayer getGameLayer() {
+ return moduleLayerManager.getLayer(IModuleLayerManager.Layer.GAME).orElseThrow();
+ }
+
+ public static VersionInfo versionInfo() {
+ return versionInfo;
}
}
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLPaths.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLPaths.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/FMLPaths.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLPaths.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java
similarity index 83%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java
index 0f260650a2..7c4dc9fb16 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java
@@ -19,10 +19,8 @@
package net.minecraftforge.fml.loading;
-import cpw.mods.modlauncher.api.IEnvironment;
-import cpw.mods.modlauncher.api.ITransformationService;
-import cpw.mods.modlauncher.api.ITransformer;
-import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
+import cpw.mods.jarhandling.SecureJar;
+import cpw.mods.modlauncher.api.*;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionSpecBuilder;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
@@ -30,14 +28,16 @@ import net.minecraftforge.forgespi.Environment;
import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.jetbrains.annotations.NotNull;
-import javax.annotation.Nonnull;
import java.nio.file.Path;
import java.util.AbstractMap;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
@@ -47,7 +47,6 @@ import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class FMLServiceProvider implements ITransformationService
{
-
private static final Logger LOGGER = LogManager.getLogger();
private ArgumentAcceptingOptionSpec modsOption;
private ArgumentAcceptingOptionSpec modListsOption;
@@ -67,6 +66,12 @@ public class FMLServiceProvider implements ITransformationService
private String targetForgeGroup;
private Map arguments;
+ public FMLServiceProvider()
+ {
+ final String markerselection = System.getProperty("forge.logging.markers", "");
+ Arrays.stream(markerselection.split(",")).forEach(marker -> System.setProperty("forge.logging.marker." + marker.toLowerCase(Locale.ROOT), "ACCEPT"));
+ }
+
@Override
public String name()
{
@@ -97,28 +102,22 @@ public class FMLServiceProvider implements ITransformationService
}
@Override
- public void beginScanning(final IEnvironment environment) {
- throw new IllegalStateException("WHY ARE YOU HERE??????");
+ public List beginScanning(final IEnvironment environment) {
+ LOGGER.debug(CORE,"Initiating mod scan");
+ return FMLLoader.beginModScan(arguments);
}
@Override
- public List> runScan(final IEnvironment environment) {
- LOGGER.debug(CORE,"Initiating mod scan");
- final Map> foundFiles = FMLLoader.beginModScan(arguments);
- return foundFiles
- .values()
- .stream()
- .flatMap(Collection::stream)
- .map(modFile -> new AbstractMap.SimpleImmutableEntry<>(modFile.getFileName(), modFile.getFilePath()))
- .collect(Collectors.toList());
+ public List completeScan(final IModuleLayerManager layerManager) {
+ return FMLLoader.completeScan(layerManager);
}
@Override
public void onLoad(IEnvironment environment, Set otherServices) throws IncompatibleEnvironmentException
{
- LOGGER.debug("Injecting tracing printstreams for STDOUT/STDERR.");
- System.setOut(new TracingPrintStream(LogManager.getLogger("STDOUT"), System.out));
- System.setErr(new TracingPrintStream(LogManager.getLogger("STDERR"), System.err));
+// LOGGER.debug("Injecting tracing printstreams for STDOUT/STDERR.");
+// System.setOut(new TracingPrintStream(LogManager.getLogger("STDOUT"), System.out));
+// System.setErr(new TracingPrintStream(LogManager.getLogger("STDERR"), System.err));
FMLLoader.onInitialLoad(environment, otherServices);
}
@@ -148,9 +147,8 @@ public class FMLServiceProvider implements ITransformationService
targetMcpMappings = option.value(mappingsOption);
}
- @Nonnull
@Override
- public List transformers()
+ public @NotNull List transformers()
{
LOGGER.debug(CORE, "Loading coremod transformers");
return new ArrayList<>(FMLLoader.getCoreModProvider().getCoreModTransformers());
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FileUtils.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FileUtils.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/FileUtils.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/FileUtils.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/JarVersionLookupHandler.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java
similarity index 84%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java
index 1ea6c5c6d5..4992a0c172 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java
@@ -19,7 +19,9 @@
package net.minecraftforge.fml.loading;
-import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
+import cpw.mods.modlauncher.Launcher;
+import cpw.mods.modlauncher.api.IModuleLayerManager;
+import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.forgespi.language.IModLanguageProvider;
import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator;
@@ -49,13 +51,12 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
-import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.rethrowFunction;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
+import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class LanguageLoadingProvider
{
private static final Logger LOGGER = LogManager.getLogger();
- private final LanguageClassLoader languageClassLoader;
private final List languageProviders = new ArrayList<>();
private final ServiceLoader serviceLoader;
private final Map languageProviderMap = new HashMap<>();
@@ -71,7 +72,6 @@ public class LanguageLoadingProvider
}
private static class ModLanguageWrapper {
-
private final IModLanguageProvider modLanguageProvider;
private final ArtifactVersion version;
@@ -92,26 +92,14 @@ public class LanguageLoadingProvider
}
- private static class LanguageClassLoader extends URLClassLoader
- {
- public LanguageClassLoader() {
- super(new URL[0]);
- }
- @Override
- public void addURL(final URL url) {
- LOGGER.debug(CORE, "Adding {} to languageloader classloader", url);
- super.addURL(url);
- }
-
- }
LanguageLoadingProvider() {
- languageClassLoader = new LanguageClassLoader();
- serviceLoader = ServiceLoader.load(IModLanguageProvider.class, languageClassLoader);
+ var sl = Launcher.INSTANCE.environment().findModuleLayerManager().flatMap(lm->lm.getLayer(IModuleLayerManager.Layer.PLUGIN)).orElseThrow();
+ serviceLoader = ServiceLoader.load(sl, IModLanguageProvider.class);
loadLanguageProviders();
}
private void loadLanguageProviders() {
- LOGGER.debug(CORE, "Found {} language providers", ServiceLoaderStreamUtils.toList(serviceLoader).size());
+ LOGGER.debug(CORE, "Found {} language providers", ServiceLoaderUtils.streamServiceLoader(()->serviceLoader, sce->LOGGER.fatal("Problem with language loaders")).count());
serviceLoader.forEach(languageProviders::add);
languageProviders.forEach(lp -> {
@@ -122,7 +110,7 @@ public class LanguageLoadingProvider
throw new RuntimeException("Huh?", e);
}
Optional implementationVersion = JarVersionLookupHandler.getImplementationVersion(lp.getClass());
- String impl = implementationVersion.orElse(Files.isDirectory(lpPath) ? FMLLoader.forgeVersion.split("\\.")[0] : null);
+ String impl = implementationVersion.orElse(Files.isDirectory(lpPath) ? FMLLoader.versionInfo().forgeVersion().split("\\.")[0] : null);
if (impl == null) {
LOGGER.fatal(CORE, "Found unversioned language provider {}", lp.name());
throw new RuntimeException("Failed to find implementation version for language provider "+ lp.name());
@@ -147,7 +135,7 @@ public class LanguageLoadingProvider
private void addLanguagePaths(final Stream langPaths) {
languageProviders.clear();
languageProviderMap.clear();
- langPaths.peek(languagePaths::add).map(Path::toFile).map(File::toURI).map(rethrowFunction(URI::toURL)).forEach(languageClassLoader::addURL);
+// langPaths.peek(languagePaths::add).map(Path::toFile).map(File::toURI).map(rethrowFunction(URI::toURL)).forEach(languageClassLoader::addURL);
}
public void addAdditionalLanguages(List modFiles)
@@ -167,11 +155,11 @@ public class LanguageLoadingProvider
final String languageFileName = mf.getLocator() instanceof ExplodedDirectoryLocator ? "in-development" : mf.getFileName();
final ModLanguageWrapper mlw = languageProviderMap.get(modLoader);
if (mlw == null) {
- LOGGER.error("Missing language {} version {} wanted by {}", modLoader, modLoaderVersion, languageFileName);
+ LOGGER.error(LOADING,"Missing language {} version {} wanted by {}", modLoader, modLoaderVersion, languageFileName);
throw new EarlyLoadingException("Missing language "+modLoader, null, Collections.singletonList(new EarlyLoadingException.ExceptionData("fml.language.missingversion", modLoader, modLoaderVersion, languageFileName, "null")));
}
if (!VersionSupportMatrix.testVersionSupportMatrix(modLoaderVersion, modLoader, "languageloader", (llid, range) -> range.containsVersion(mlw.getVersion()))) {
- LOGGER.error("Missing language {} version {} wanted by {}, found {}", modLoader, modLoaderVersion, languageFileName, mlw.getVersion());
+ LOGGER.error(LOADING,"Missing language {} version {} wanted by {}, found {}", modLoader, modLoaderVersion, languageFileName, mlw.getVersion());
throw new EarlyLoadingException("Missing language "+ modLoader + " matching range "+modLoaderVersion + " found "+mlw.getVersion(), null, Collections.singletonList(new EarlyLoadingException.ExceptionData("fml.language.missingversion", modLoader, modLoaderVersion, languageFileName, mlw.getVersion())));
}
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/LauncherVersion.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LauncherVersion.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/LauncherVersion.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/LauncherVersion.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LibraryFinder.java
similarity index 82%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/LibraryFinder.java
index faa9d45665..8332ed38cf 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/LibraryFinder.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LibraryFinder.java
@@ -36,11 +36,10 @@ public class LibraryFinder {
private static Path libsPath;
static Path findLibsPath() {
if (libsPath == null) {
- final Path asm = findJarPathFor("org/objectweb/asm/Opcodes.class", "asm");
- // go up SIX parents to find the libs dir
- final Path libs = asm.getParent().getParent().getParent().getParent().getParent().getParent();
- LOGGER.debug(CORE, "Found probable library path {}", libs);
- libsPath = libs;
+ libsPath = Path.of(System.getProperty("libraryDirectory","crazysnowmannonsense/cheezwhizz"));
+ if (!Files.isDirectory(libsPath)) {
+ throw new IllegalStateException("Missing libraryDirectory system property, cannot continue");
+ }
}
return libsPath;
}
@@ -87,4 +86,14 @@ public class LibraryFinder {
LOGGER.debug(CORE,"Forge patches at {} is {}", patchedBinariesPath.toString(), pathStatus(patchedBinariesPath));
return new Path[] { patchedBinariesPath, mcExtrasPath, srgMcPath };
}
+
+ public static Path findPathForMaven(final String group, final String artifact, final String extension, final String classifier, final String version) {
+ return findLibsPath().resolve(MavenCoordinateResolver.get(group, artifact, extension, classifier, version));
+ }
+ public static Path findPathForMaven(final String maven) {
+ return findLibsPath().resolve(MavenCoordinateResolver.get(maven));
+ }
+ public static Path getFMLCorePath() {
+ return findLibsPath().resolve(MavenCoordinateResolver.get("net.minecraftforge:fmlcore:1.0"));
+ }
}
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/LoadingModList.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java
similarity index 98%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/LoadingModList.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java
index 831d111829..7c5247cbcd 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/LoadingModList.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java
@@ -41,8 +41,6 @@ public class LoadingModList
private final List modFiles;
private final List sortedList;
private final Map fileById;
- @SuppressWarnings("unused")
- private BackgroundScanHandler scanner;
private final List preLoadErrors;
private List brokenFiles;
@@ -94,7 +92,6 @@ public class LoadingModList
public void addForScanning(BackgroundScanHandler backgroundScanHandler)
{
- this.scanner = backgroundScanHandler;
backgroundScanHandler.setLoadingModList(this);
modFiles.stream()
.map(ModFileInfo::getFile)
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/LogMarkers.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LogMarkers.java
similarity index 92%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/LogMarkers.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/LogMarkers.java
index d9d8ed5f4b..00f015fbcb 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/LogMarkers.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LogMarkers.java
@@ -27,5 +27,4 @@ public class LogMarkers {
public static final Marker LOADING = MarkerManager.getMarker("LOADING");
public static final Marker SCAN = MarkerManager.getMarker("SCAN");
public static final Marker SPLASH = MarkerManager.getMarker("SPLASH");
- public static final Marker FORGEMOD = MarkerManager.getMarker("FORGEMOD").addParents(LOADING);
}
diff --git a/src/userdev/java/net/minecraftforge/userdev/MCPNamingService.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java
similarity index 71%
rename from src/userdev/java/net/minecraftforge/userdev/MCPNamingService.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java
index 7f55f177f3..1279980b10 100644
--- a/src/userdev/java/net/minecraftforge/userdev/MCPNamingService.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java
@@ -1,23 +1,4 @@
-/*
- * Minecraft Forge
- * Copyright (c) 2016-2021.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation version 2.1
- * of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package net.minecraftforge.userdev;
+package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.api.INameMappingService;
import org.apache.commons.lang3.tuple.Pair;
@@ -47,7 +28,7 @@ public class MCPNamingService implements INameMappingService {
@Override
public String mappingVersion() {
- return "1234";
+ return "1234"; //TODO: Minecraft Version?
}
@Override
@@ -92,19 +73,14 @@ public class MCPNamingService implements INameMappingService {
return fields.getOrDefault(origin, origin);
}
-
- private static void loadMappings(final String mappingFileName, BiConsumer mapStore)
- {
- URL path = ClassLoader.getSystemResource(mappingFileName); //We EXPLICITLY go throught the SystemClassLoader here because this is dev-time only. And will be on the root classpath.
+ private static void loadMappings(final String mappingFileName, BiConsumer mapStore) {
+ URL path = ClassLoader.getSystemResource(mappingFileName); //We EXPLICITLY go through the SystemClassLoader here because this is dev-time only. And will be on the root classpath.
if (path == null)
return;
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(path.openStream())))
- {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(path.openStream()))) {
reader.lines().skip(1).map(e -> e.split(",")).forEach(e -> mapStore.accept(e[0], e[1]));
- }
- catch (IOException e1)
- {
+ } catch (IOException e1) {
LOGGER.error(CORE, "Error reading mappings", e1);
}
}
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java
similarity index 100%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java
similarity index 76%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java
index bc6d0a7871..08a4c4241c 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java
@@ -20,6 +20,7 @@
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
+import cpw.mods.modlauncher.api.NamedPath;
import cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService;
import org.apache.logging.log4j.LogManager;
@@ -29,40 +30,30 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Stream;
import java.util.zip.ZipFile;
public class ModDirTransformerDiscoverer implements ITransformerDiscoveryService {
@Override
- public List candidates(final Path gameDirectory) {
+ public List candidates(final Path gameDirectory) {
ModDirTransformerDiscoverer.scan(gameDirectory);
- return ModDirTransformerDiscoverer.transformers;
+ return List.copyOf(found);
}
- private static List transformers = new ArrayList<>();
- private static List locators = new ArrayList<>();
+ private final static List found = new ArrayList<>();
public static List allExcluded() {
- ArrayList paths = new ArrayList<>();
- paths.addAll(transformers);
- paths.addAll(locators);
- return paths;
- }
-
- public static List getExtraLocators() {
- return locators;
+ return found.stream().map(np->np.paths()[0]).toList();
}
private static void scan(final Path gameDirectory) {
final Path modsDir = gameDirectory.resolve(FMLPaths.MODSDIR.relative()).toAbsolutePath().normalize();
- transformers = new ArrayList<>();
- locators = new ArrayList<>();
if (!Files.exists(modsDir)) {
// Skip if the mods dir doesn't exist yet.
return;
}
- try {
- Files.createDirectories(modsDir);
- Files.walk(modsDir, 1).forEach(ModDirTransformerDiscoverer::visitFile);
+ try (var walk = Files.walk(modsDir, 1)){
+ walk.forEach(ModDirTransformerDiscoverer::visitFile);
} catch (IOException | IllegalStateException ioe) {
LogManager.getLogger().error("Error during early discovery", ioe);
}
@@ -74,9 +65,9 @@ public class ModDirTransformerDiscoverer implements ITransformerDiscoveryService
if (LamdbaExceptionUtils.uncheck(() -> Files.size(path)) == 0) return;
try (ZipFile zf = new ZipFile(new File(path.toUri()))) {
if (zf.getEntry("META-INF/services/cpw.mods.modlauncher.api.ITransformationService") != null) {
- transformers.add(path);
+ found.add(new NamedPath(zf.getName(), path));
} else if (zf.getEntry("META-INF/services/net.minecraftforge.forgespi.locating.IModLocator") != null) {
- locators.add(path);
+ found.add(new NamedPath(zf.getName(), path));
}
} catch (IOException ioe) {
LogManager.getLogger().error("Zip Error when loading jar file {}", path, ioe);
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModJarURLHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModJarURLHandler.java
similarity index 88%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/ModJarURLHandler.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/ModJarURLHandler.java
index bde21bcbce..0e96c8b24f 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModJarURLHandler.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModJarURLHandler.java
@@ -70,13 +70,13 @@ public class ModJarURLHandler extends URLStreamHandler
@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();
- }
+// 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
diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java
similarity index 64%
rename from src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java
rename to fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java
index aa749dd98d..87d1856b29 100644
--- a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModSorter.java
+++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java
@@ -42,6 +42,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static java.util.stream.Collectors.*;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class ModSorter
@@ -57,22 +58,20 @@ public class ModSorter
this.modFiles = modFiles;
}
- public static LoadingModList sort(List mods)
+ public static LoadingModList sort(List mods, final List errors)
{
final ModSorter ms = new ModSorter(mods);
try {
ms.buildUniqueList();
} catch (EarlyLoadingException e) {
// We cannot build any list with duped mods. We have to abort immediately and report it
- return LoadingModList.of(ms.forgeAndMC, ms.forgeAndMC.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).collect(Collectors.toList()), e);
+ return LoadingModList.of(ms.forgeAndMC, ms.forgeAndMC.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).collect(toList()), e);
}
- // try and locate languages and validate dependencies
- List missingLangs = ms.findLanguages();
- List missingDeps = ms.verifyDependencyVersions();
- final List failedList = Stream.concat(missingLangs.stream(), missingDeps.stream()).collect(Collectors.toList());
+ // try and validate dependencies
+ final List failedList = Stream.concat(ms.verifyDependencyVersions().stream(), errors.stream()).toList();
// if we miss one or the other, we abort now
if (!failedList.isEmpty()) {
- return LoadingModList.of(ms.forgeAndMC, ms.forgeAndMC.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).collect(Collectors.toList()), new EarlyLoadingException("failure to validate mod list", null, failedList));
+ return LoadingModList.of(ms.forgeAndMC, ms.forgeAndMC.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).collect(toList()), new EarlyLoadingException("failure to validate mod list", null, failedList));
} else {
// Otherwise, lets try and sort the modlist and proceed
EarlyLoadingException earlyLoadingException = null;
@@ -85,35 +84,21 @@ public class ModSorter
}
}
- private List findLanguages() {
- List errorData = new ArrayList<>();
- modFiles.forEach(modFile -> {
- try {
- modFile.identifyLanguage();
- } catch (EarlyLoadingException e) {
- errorData.addAll(e.getAllData());
- }
- });
- return errorData;
- }
-
@SuppressWarnings("UnstableApiUsage")
private void sort()
{
// lambdas are identity based, so sorting them is impossible unless you hold reference to them
final MutableGraph graph = GraphBuilder.directed().build();
AtomicInteger counter = new AtomicInteger();
- Map infos = modFiles
- .stream()
+ Map infos = modFiles.stream()
.map(ModFile::getModFileInfo)
- .collect(Collectors.toMap(Function.identity(), e -> counter.incrementAndGet()));
+ .collect(toMap(Function.identity(), e -> counter.incrementAndGet()));
infos.keySet().forEach(i -> graph.addNode((ModFileInfo) i));
- modFiles
- .stream()
+ modFiles.stream()
.map(ModFile::getModInfos)
- .flatMap(Collection::stream)
+ .mapMulti(Iterable::forEach)
.map(IModInfo::getDependencies)
- .flatMap(Collection::stream)
+ .mapMulti(Iterable::forEach)
.forEach(dep -> addDependency(graph, dep));
final List