diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 50208ded..5bc740b3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.13.1" asm = "9.8" tiny-remapper = "0.11.1" -unimined-mapping-library = "1.2.1" +unimined-mapping-library = "1.2.2" binarypatcher = "1.1.1" neo_binarypatcher = "4.0.7" diff --git a/src/api/kotlin/xyz/wagyourtail/unimined/api/mapping/MappingsConfig.kt b/src/api/kotlin/xyz/wagyourtail/unimined/api/mapping/MappingsConfig.kt index 8400a6e8..141fb225 100644 --- a/src/api/kotlin/xyz/wagyourtail/unimined/api/mapping/MappingsConfig.kt +++ b/src/api/kotlin/xyz/wagyourtail/unimined/api/mapping/MappingsConfig.kt @@ -35,7 +35,7 @@ abstract class MappingsConfig>(val project: Project, val mi }) { private var innerDevNamespace: Namespace by FinalizeOnRead(LazyMutable { - if (minecraft.minecraftData.mcVersionCompare("1.21.11", minecraft.version) <= 0) { + if (minecraft.minecraftData.mcVersionCompare("1.21.11", minecraft.version) < 0) { return@LazyMutable Namespace("official") } namespaces.entries.firstOrNull { it.value }?.key ?: error("No \"Named\" namespace found for devNamespace, if this is correct, set devNamespace explicitly") diff --git a/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/MappingsProvider.kt b/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/MappingsProvider.kt index cbd2429f..12c325d8 100644 --- a/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/MappingsProvider.kt +++ b/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/MappingsProvider.kt @@ -321,6 +321,13 @@ open class MappingsProvider(project: Project, minecraft: MinecraftConfig, subKey override fun mojmap() { + // 26.1+ is unmapped. We return here otherwise Neo and Forge try to download mappings + if (!minecraft.obfuscated) { + devNamespace("official") + devFallbackNamespace("official") + return + } + mojmapIvy() val mappings = when (envType) { EnvType.CLIENT, EnvType.JOINED -> "client" diff --git a/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/aw/AccessWidenerApplier.kt b/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/aw/AccessWidenerApplier.kt index c71d2f5b..9f7ba09e 100644 --- a/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/aw/AccessWidenerApplier.kt +++ b/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/aw/AccessWidenerApplier.kt @@ -75,6 +75,8 @@ object AccessWidenerApplier { fun nsName(config: MappingsConfig<*>, namespace: Namespace) = if (config.devNamespace != namespace) { "intermediary" // -_- + } else if (config.minecraft.minecraftData.mcVersionCompare(config.minecraft.version, "1.21.11") > 0) { + "official" } else { "named" } diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/MinecraftProvider.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/MinecraftProvider.kt index 64dd6c13..e3c37359 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/MinecraftProvider.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/MinecraftProvider.kt @@ -511,7 +511,7 @@ open class MinecraftProvider(project: Project, sourceSet: SourceSet) : Minecraft description = "Remaps $inputTask's output jar" asJar.archiveClassifier.set(classifier) } - project.tasks.getByName("assemble").dependsOn("remap" + inputTask.name.capitalized()) + project.tasks.getByName("build").dependsOn("remap" + inputTask.name.capitalized()) } else { project.logger.warn( "[Unimined/Minecraft ${project.path}:${sourceSet.name}] Could not find default task '${inputTaskName.withSourceSet(sourceSet)} for $sourceSet." diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/access/transformer/AccessTransformerMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/access/transformer/AccessTransformerMinecraftTransformer.kt index 631a5066..44f8ed1d 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/access/transformer/AccessTransformerMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/access/transformer/AccessTransformerMinecraftTransformer.kt @@ -31,7 +31,9 @@ interface AccessTransformerMinecraftTransformer : AccessTransformerPatcher, Acce companion object { fun getDefaultDependency(project: Project, provider: MinecraftProvider): Dependency { - return if (provider.minecraftData.metadata.javaVersion >= JavaVersion.VERSION_21) + return if (provider.minecraftData.metadata.javaVersion >= JavaVersion.VERSION_25) + project.dependencies.create("net.neoforged.accesstransformers:at-cli:13.0.3") + else if (provider.minecraftData.metadata.javaVersion >= JavaVersion.VERSION_21) project.dependencies.create("net.neoforged.accesstransformers:at-cli:11.0.2") else project.dependencies.create("net.neoforged:accesstransformers:9.0.3") @@ -124,6 +126,18 @@ interface AccessTransformerMinecraftTransformer : AccessTransformerPatcher, Acce ).use { ATWriter.writeData(list, it::append) } + + // Fix whitespaces in ATs that can cause forge to fail on 1.8.9+ + if (!legacyATFormat) { + val lines = temp.bufferedReader().readLines() + temp.bufferedWriter().use { + writer -> lines.filter { s -> !s.startsWith(" ") }.forEach { + writer.write(it) + writer.newLine() + } + } + } + try { project.execOps.javaexec { spec -> if (useToolchains) { diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt index 3741bbe8..d8b33952 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt @@ -155,7 +155,7 @@ abstract class FabricLikeMinecraftTransformer( var mainClass: JsonObject? = null override fun beforeMappingsResolve() { - if (!customIntermediaries) { + if (!customIntermediaries && provider.obfuscated) { addIntermediaryMappings() } } diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt index 030a61e9..2a474329 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt @@ -24,7 +24,7 @@ open class MinecraftForgeMinecraftTransformer(project: Project, provider: Minecr override var useUnionRelaunch: Boolean by FinalizeOnRead(provider.minecraftData.mcVersionCompare(provider.version, "1.20.3") >= 0) init { - atDependency = project.dependencies.create("net.minecraftforge:accesstransformers:8.2.2") + atDependency = project.dependencies.create("net.minecraftforge:accesstransformers:8.2.14") atMainClass = "net.minecraftforge.accesstransformer.TransformerProcessor" } diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/NeoForgedMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/NeoForgedMinecraftTransformer.kt index 1e25aad5..62e75401 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/NeoForgedMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/NeoForgedMinecraftTransformer.kt @@ -42,7 +42,10 @@ open class NeoForgedMinecraftTransformer(project: Project, provider: MinecraftPr project.dependencies.create("net.neoforged:forge:${provider.version}-$dep:universal") } else { var version = provider.version.removePrefix("1.") - if (!version.contains(".")) { + + if (provider.minecraftData.mcVersionCompare(provider.version, "26.1") >= 0) { + version = "${provider.version}.0" + } else if (!version.contains(".")) { version = "$version.0" } project.dependencies.create("net.neoforged:neoforge:$version.$dep:universal") diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/FG3MinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/FG3MinecraftTransformer.kt index f92ac2bd..5e92a4b7 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/FG3MinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/FG3MinecraftTransformer.kt @@ -45,6 +45,14 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr project, parent.provider, jarModProvider = "forge", providerName = "${parent.providerName}-FG3" ) { + val isModernNeo by lazy { + providerName.equals("NeoForged-FG3", true) && !provider.obfuscated + } + + val isModernForge by lazy { + providerName.equals("MinecraftForge-FG3", true) && !provider.obfuscated + } + val cacheDir by lazy { val forgeUniversal = parent.forge.dependencies.last() provider.minecraftData.mcVersionFolder.resolve(providerName).resolve(forgeUniversal.version!!) @@ -86,6 +94,7 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr } override fun defaultProdNamespace(): Namespace { + if (!provider.obfuscated) return provider.mappings.checkedNs("official") return if (userdevCfg["mcp"].asString.contains("neoform") || provider.minecraftData.mcVersionCompare( provider.version, "1.20.5" @@ -129,7 +138,7 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr } open val obfNamespace by lazy { - if (userdevCfg["notchObf"]?.asBoolean == true) "official" + if (userdevCfg["notchObf"]?.asBoolean == true || !provider.obfuscated) "official" else if (userdevCfg["mcp"].asString.contains("neoform")) "mojmap" else "searge" } @@ -179,7 +188,7 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr config.insertBefore( "forgeInject", config.FunctionStep( "mcpCleanup", null, mutableMapOf(), MCPConfig.Function( - "net.minecraftforge:mcpcleanup:2.3.6", + listOf("net.minecraftforge:mcpcleanup:2.3.6"), null, listOf( "--input", @@ -187,7 +196,8 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr "--output", "{output}" ), - listOf() + listOf(), + null ) ), mapOf("input" to { @@ -313,6 +323,7 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr override fun beforeMappingsResolve() { project.logger.info("[Unimined/ForgeTransformer] FG3: beforeMappingsResolve") + if (!provider.obfuscated) return provider.mappings { if (obfNamespace == "mojmap") { mojmap() @@ -362,7 +373,7 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr val mainClass = get("main").asString if (!mainClass.startsWith("net.minecraftforge.legacydev")) { project.logger.info("[Unimined/ForgeTransformer] Inserting mcp mappings") - if (obfNamespace != "mojmap") { + if (obfNamespace != "mojmap" && provider.obfuscated) { provider.minecraftLibraries.dependencies.add( project.dependencies.create(project.files(parent.srgToMCPAsMCP)) ) @@ -403,8 +414,10 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr if (output.path.exists() && !project.unimined.forceReload) { return output } - if (userdevCfg["notchObf"]?.asBoolean == true) { + if (userdevCfg["notchObf"]?.asBoolean == true || isModernForge) { executeMcp("merge", output.path) + } else if (isModernNeo) { + executeMcp("preProcessJar", output.path) } else { executeMcp("rename", output.path) } @@ -786,9 +799,8 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr } private fun fixForge(baseMinecraft: MinecraftJar): MinecraftJar { - if (!baseMinecraft.patches.contains("fixForge") && baseMinecraft.mappingNamespace != provider.mappings.checkedNs( - "official" - ) + if (!baseMinecraft.patches.contains("fixForge") && + (!provider.obfuscated || baseMinecraft.mappingNamespace != provider.mappings.checkedNs("official")) ) { val target = MinecraftJar( baseMinecraft, @@ -803,6 +815,7 @@ open class FG3MinecraftTransformer(project: Project, val parent: ForgeLikeMinecr try { target.path.openZipFileSystem(mapOf("mutable" to true)).use { out -> out.getPath("binpatches.pack.lzma").deleteIfExists() + out.getPath("binpatches-joined.lzma").deleteIfExists() } } catch (e: Throwable) { target.path.deleteIfExists() diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/mcpconfig/MCPConfig.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/mcpconfig/MCPConfig.kt index b19dccda..7a5fa5d8 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/mcpconfig/MCPConfig.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/fg3/mcpconfig/MCPConfig.kt @@ -16,7 +16,6 @@ import xyz.wagyourtail.unimined.api.unimined import xyz.wagyourtail.unimined.internal.minecraft.MinecraftProvider import xyz.wagyourtail.unimined.mapping.EnvType import xyz.wagyourtail.unimined.mapping.Namespace -import xyz.wagyourtail.unimined.mapping.formats.FormatReader import xyz.wagyourtail.unimined.mapping.formats.FormatRegistry import xyz.wagyourtail.unimined.mapping.jvms.four.two.one.InternalName import xyz.wagyourtail.unimined.mapping.visitor.ClassVisitor @@ -50,6 +49,12 @@ class MCPConfig( } } + private val specVersion by lazy { + configJson.getAsJsonPrimitive("spec").asInt + } + + private val isSpec6 get() = specVersion >= 6 + private val data by lazy { buildMap { for ((key, value) in configJson.getAsJsonObject("data").entrySet()) { @@ -77,13 +82,32 @@ class MCPConfig( private val functions by lazy { buildMap { - for ((name, function) in configJson.getAsJsonObject("functions").entrySet()) { - put(name, Function( - function.asJsonObject.getAsJsonPrimitive("version").asString, - function.asJsonObject.getAsJsonPrimitive("java_version")?.asString, - function.asJsonObject.getAsJsonArray("args")?.map { it.asString } ?: listOf(), - function.asJsonObject.getAsJsonArray("jvmargs")?.map { it.asString } ?: listOf(), - )) + for ((name, fn) in configJson.getAsJsonObject("functions").entrySet()) { + val o = fn.asJsonObject + + if (isSpec6) { + put( + name, + Function( + classpath = o.getAsJsonArray("classpath").map { it.asString }, + mainClass = o.getAsJsonPrimitive("main_class")?.asString, + args = o.getAsJsonArray("args")?.map { it.asString } ?: emptyList(), + jvmargs = o.getAsJsonArray("jvmargs")?.map { it.asString } ?: emptyList(), + javaVersion = o.getAsJsonPrimitive("java_version")?.asInt + ) + ) + } else { + put( + name, + Function( + classpath = listOf(o.getAsJsonPrimitive("version").asString), + mainClass = null, + args = o.getAsJsonArray("args")?.map { it.asString } ?: emptyList(), + jvmargs = o.getAsJsonArray("jvmargs")?.map { it.asString } ?: emptyList(), + javaVersion = o.getAsJsonPrimitive("java_version")?.asInt + ) + ) + } } }.toMutableMap() } @@ -147,6 +171,7 @@ class MCPConfig( vars["prefix"] = { data.getValue("patches") } PatchStep(name, prevStep, vars) } + "preProcessJar" -> FunctionStep(name, prevStep, vars, functions.getValue(type)) in functions.keys -> FunctionStep(name, prevStep, vars, functions.getValue(type)) else -> error("Unknown step type: $type") } @@ -230,91 +255,82 @@ class MCPConfig( val function: Function, ) : ConfigStep { - val dependency = project.dependencies.create(function.version) - - val configuration by lazy { - val config = project.configurations.detachedConfiguration() - config.dependencies.add(dependency) - config + private val configuration by lazy { + project.configurations.detachedConfiguration().apply { + function.classpath.forEach { + dependencies.add(project.dependencies.create(it)) + } + } } - open fun resolveVariable(varName: String, output: Path): String { - if (varName == "output") { - return output.absolutePathString() + open fun resolveVariable(varName: String, output: Path): String = + when (varName) { + "output" -> output.absolutePathString() + "log" -> output.resolveSibling("log.txt").absolutePathString() + else -> variables[varName]?.invoke() + ?: extractData(varName).absolutePathString() } - if (varName == "log") { - return output.resolveSibling("log.txt").absolutePathString() - } - if (variables.containsKey(varName)) { - return variables.getValue(varName).invoke() - } - return extractData(varName).absolutePathString() - } - fun List.mapVariables(output: Path) = buildList { - for (arg in this@mapVariables) { - add(arg.replace(Regex("\\{([^}]+)}")) { - resolveVariable(it.groups[1]!!.value, output) - }) + private fun List.mapVariables(output: Path) = + map { + it.replace(Regex("\\{([^}]+)}")) { m -> + resolveVariable(m.groupValues[1], output) + } } - } override fun execute(dir: Path): StepResult { val output = dir.resolve("${name}Output.jar") - if (!output.exists() || project.unimined.forceReload) { + if (!output.exists() || project.unimined.forceReload) output.deleteIfExists() - project - project.execOps.javaexec { - if (useToolchains) { - val toolchain = project.extensions.getByType(JavaToolchainService::class.java) - if (function.java_version != null) { - it.executable = try { - toolchain.launcherFor { - it.languageVersion.set(JavaLanguageVersion.of(function.java_version.toInt())) - }.get() - } catch (e: GradleException) { - throw IllegalStateException("Failed to find java version ${function.java_version}", e) - }.executablePath.asFile.absolutePath - } else { - it.executable = try { - toolchain.launcherFor { - it.languageVersion.set(JavaLanguageVersion.of(provider.minecraftData.metadata.javaVersion.majorVersion.toInt())) - }.get() - } catch (e: GradleException) { - throw IllegalStateException("Failed to find java version ${function.java_version}", e) - }.executablePath.asFile.absolutePath - } + project.execOps.javaexec { + if (useToolchains) { + val toolchain = project.extensions.getByType(JavaToolchainService::class.java) + if (function.javaVersion != null) { + it.executable = try { + toolchain.launcherFor { + it.languageVersion.set(JavaLanguageVersion.of(function.javaVersion.toInt())) + }.get() + } catch (e: GradleException) { + throw IllegalStateException("Failed to find java version ${function.javaVersion}", e) + }.executablePath.asFile.absolutePath } else { - if (JavaVersion.current() < (JavaVersion.toVersion(function.java_version ?: 8))) { - error("current java version ${JavaVersion.current()} is less than required java version ${function.java_version} to run ${function.version}") - } + it.executable = try { + toolchain.launcherFor { + it.languageVersion.set(JavaLanguageVersion.of(provider.minecraftData.metadata.javaVersion.majorVersion.toInt())) + }.get() + } catch (e: GradleException) { + throw IllegalStateException("Failed to find java version ${function.javaVersion}", e) + }.executablePath.asFile.absolutePath } - - val mainClass: String - try { - JarFile(configuration.getFiles(dependency, "jar").single()).use { jarFile -> - mainClass = jarFile.manifest.mainAttributes.getValue(Attributes.Name.MAIN_CLASS) - } - } catch (e: IOException) { - throw IOException("Could not determine main class for $dependency", e) + } else { + if (JavaVersion.current() < (JavaVersion.toVersion(function.javaVersion ?: 8))) { + error("current java version ${JavaVersion.current()} is less than required java version ${function.javaVersion} to run ${function.classpath}") } + } - it.mainClass.set(mainClass) - it.classpath(configuration) - it.args(function.args.mapVariables(output)) - it.jvmArgs(function.jvmargs.mapVariables(output)) + it.classpath(configuration) - project.logger.info("[Unimined/MCPConfig] Executing: ${it.executable} ${it.jvmArgs} ${it.mainClass} ${it.args}") - project.suppressLogs(it) - }.assertNormalExitValue().rethrowFailure() + if (function.mainClass != null) { + // spec ≥6 + it.mainClass.set(function.mainClass) + } else { + val jar = configuration.first() + JarFile(jar).use { jf -> + it.mainClass.set( + jf.manifest.mainAttributes.getValue(Attributes.Name.MAIN_CLASS) ?: error("No Main-Class in manifest of $jar") + ) + } + } - } + it.args(function.args.mapVariables(output)) + it.jvmArgs(function.jvmargs.mapVariables(output)) + project.suppressLogs(it) + }.assertNormalExitValue().rethrowFailure() return StepResult(name, output) } - } inner class StripStep( @@ -438,7 +454,7 @@ class MCPConfig( prev: String?, variables: MutableMap String> ) : FunctionStep(name, prev, variables, Function( - "net.minecraftforge:DiffPatch:2.0.12", + listOf("net.minecraftforge:DiffPatch:2.0.12"), null, listOf( "-p", @@ -459,7 +475,8 @@ class MCPConfig( "{input}", "{patches}", ), - listOf() + listOf(), + javaVersion = null )) { override fun resolveVariable(varName: String, output: Path): String { @@ -491,10 +508,11 @@ class MCPConfig( ) data class Function( - val version: String, - val java_version: String?, + val classpath: List, + val mainClass: String?, val args: List, - val jvmargs: List + val jvmargs: List, + val javaVersion: Int? ) } \ No newline at end of file