add mod dependency remapping (using mod* configurations)
- move loader to the minecraft dependencies to stop it from polluting mod poms - add AW validation, fix aw bug - add tasks to clear caches
This commit is contained in:
parent
3883c9cafd
commit
f7ea37bf1a
|
@ -26,6 +26,8 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("dev.frogmc:thyroxine:0.0.1-alpha.6")
|
implementation("dev.frogmc:thyroxine:0.0.1-alpha.6")
|
||||||
implementation("org.ow2.asm:asm:9.7")
|
implementation("org.ow2.asm:asm:9.7")
|
||||||
|
implementation("org.ow2.asm:asm-commons:9.7")
|
||||||
|
implementation("org.ow2.asm:asm-tree:9.7")
|
||||||
implementation("com.google.code.gson:gson:2.10.1")
|
implementation("com.google.code.gson:gson:2.10.1")
|
||||||
implementation("org.vineflower:vineflower:1.10.1")
|
implementation("org.vineflower:vineflower:1.10.1")
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
|
|
@ -12,4 +12,6 @@ object Constants {
|
||||||
const val GEN_RUN_CONFIGS_TASK = "genRunConfigs"
|
const val GEN_RUN_CONFIGS_TASK = "genRunConfigs"
|
||||||
const val RUN_CLIENT_TASK = "runClient"
|
const val RUN_CLIENT_TASK = "runClient"
|
||||||
const val RUNT_SERVER_TASK = "runServer"
|
const val RUNT_SERVER_TASK = "runServer"
|
||||||
|
const val CLEAR_LOCAL_CACHE_TASK = "clearLocalCache"
|
||||||
|
const val CLEAR_GLOBAL_CACHE_TASK = "clearGlobalCache"
|
||||||
}
|
}
|
|
@ -2,8 +2,15 @@ package dev.frogmc.phytotelma
|
||||||
|
|
||||||
import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtension
|
import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtension
|
||||||
import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtensionImpl
|
import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtensionImpl
|
||||||
|
import groovy.util.Node
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.ExcludeRule
|
||||||
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
|
import org.gradle.api.publish.PublishingExtension
|
||||||
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
|
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
|
||||||
|
import org.gradle.configurationcache.extensions.capitalized
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.createDirectories
|
import kotlin.io.path.createDirectories
|
||||||
|
@ -26,6 +33,10 @@ class PhytotelmaPlugin : Plugin<Project> {
|
||||||
}
|
}
|
||||||
|
|
||||||
project.repositories.apply {
|
project.repositories.apply {
|
||||||
|
maven {
|
||||||
|
it.name = "Remapped Mod Dependencies"
|
||||||
|
it.url = project.layout.buildDirectory.asFile.get().resolve("remappedMods").toURI()
|
||||||
|
}
|
||||||
maven {
|
maven {
|
||||||
it.name = "Minecraft/Local"
|
it.name = "Minecraft/Local"
|
||||||
it.url = localCacheDir.toUri()
|
it.url = localCacheDir.toUri()
|
||||||
|
@ -50,9 +61,84 @@ class PhytotelmaPlugin : Plugin<Project> {
|
||||||
"phytotelma",
|
"phytotelma",
|
||||||
PhytotelmaGradleExtensionImpl::class.java
|
PhytotelmaGradleExtensionImpl::class.java
|
||||||
)
|
)
|
||||||
|
|
||||||
|
remappedConfigurationNames.forEach { conf ->
|
||||||
|
project.configurations.create("mod" + conf.key.capitalized()) { c ->
|
||||||
|
c.isCanBeResolved = true
|
||||||
|
c.isCanBeConsumed = false
|
||||||
|
|
||||||
|
project.configurations.getByName(conf.key).extendsFrom(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.tasks.filterIsInstance<PublishToMavenRepository>()
|
||||||
|
.forEach {
|
||||||
|
it.actions.addFirst {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*project.extensions.findByType(PublishingExtension::class.java)
|
||||||
|
.takeIf { it != null }.let { it!! }
|
||||||
|
.publications.filterIsInstance<MavenPublication>().forEach { p ->
|
||||||
|
p.pom {
|
||||||
|
it.withXml {
|
||||||
|
val project = it.asNode().get("project") as Node
|
||||||
|
val dependencies = project.get("dependencies") as Node
|
||||||
|
dependencies.appendNode("dependency")
|
||||||
|
.setValue(
|
||||||
|
"<groupId>dev.frogmc</groupId>\n" +
|
||||||
|
"<artifactId>thyroxine</artifactId>\n" +
|
||||||
|
"<version>0.0.1-alpha.6</version>\n" +
|
||||||
|
"<scope>runtime</scope>"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
project.configurations.register(Constants.INCLUDE_CONFIGURATION) {
|
||||||
|
it.isCanBeResolved = true
|
||||||
|
it.isCanBeConsumed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
project.configurations.register(Constants.MINECRAFT_CONFIGURATION) {
|
||||||
|
project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
||||||
|
project.configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
||||||
|
project.configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
||||||
|
project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
||||||
|
it.isCanBeResolved = false
|
||||||
|
it.isCanBeConsumed = false
|
||||||
|
it.isTransitive = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var globalCacheDir: Path
|
lateinit var globalCacheDir: Path
|
||||||
|
val remappedConfigurationNames = mapOf(
|
||||||
|
JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME to listOf(
|
||||||
|
JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
|
||||||
|
),
|
||||||
|
JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME to listOf(
|
||||||
|
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
|
||||||
|
),
|
||||||
|
JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME to listOf(
|
||||||
|
JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
|
||||||
|
),
|
||||||
|
JavaPlugin.TEST_COMPILE_ONLY_CONFIGURATION_NAME to listOf(
|
||||||
|
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
|
||||||
|
),
|
||||||
|
JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME to listOf(
|
||||||
|
JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
),
|
||||||
|
JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME to listOf(
|
||||||
|
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.gradle.api.artifacts.ProjectDependency
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
import org.gradle.api.plugins.JavaPluginExtension
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
import org.objectweb.asm.*
|
import org.objectweb.asm.*
|
||||||
|
import org.objectweb.asm.tree.ClassNode
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.nio.file.FileSystems
|
import java.nio.file.FileSystems
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
@ -45,18 +46,20 @@ object AccessWidener {
|
||||||
private fun findDependencyAWs(project: Project): Stream<String> {
|
private fun findDependencyAWs(project: Project): Stream<String> {
|
||||||
val conf = project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
|
val conf = project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
|
||||||
val projectDeps = conf.dependencies.filterIsInstance<ProjectDependency>()
|
val projectDeps = conf.dependencies.filterIsInstance<ProjectDependency>()
|
||||||
.mapNotNull { getAWFile(it.dependencyProject) }.stream().flatMap { readTransitiveAW(it) }
|
.mapNotNull { getAWFile(it.dependencyProject) }.flatMap { readTransitiveAW(it) }
|
||||||
val dependencies = conf.resolvedConfiguration.files.map { it.toPath() }.filter { it.exists() && it.isRegularFile() }.stream().flatMap {
|
val dependencies =
|
||||||
|
conf.resolvedConfiguration.files.map { it.toPath() }.filter { it.exists() && it.isRegularFile() }.stream()
|
||||||
|
.flatMap {
|
||||||
FileSystems.newFileSystem(it).use { fs ->
|
FileSystems.newFileSystem(it).use { fs ->
|
||||||
val metadata = fs.getPath(Constants.MOD_METADATA_FILE)
|
val metadata = fs.getPath(Constants.MOD_METADATA_FILE)
|
||||||
PARSER.parse(metadata, FileNotFoundAction.READ_NOTHING)
|
PARSER.parse(metadata, FileNotFoundAction.READ_NOTHING)
|
||||||
.get<String>("frog.extensions.accesswidener")?.let { name ->
|
.get<String>("frog.extensions.accesswidener")?.let { name ->
|
||||||
return@flatMap readTransitiveAW(metadata.resolveSibling(name))
|
return@flatMap readTransitiveAW(metadata.resolveSibling(name)).stream()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@flatMap null
|
return@flatMap null
|
||||||
}.filter { it != null }
|
}.filter { it != null }
|
||||||
return Stream.concat(projectDeps, dependencies)
|
return Stream.concat(projectDeps.stream(), dependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun needsUpdate(project: Project): Boolean {
|
fun needsUpdate(project: Project): Boolean {
|
||||||
|
@ -70,24 +73,75 @@ object AccessWidener {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readAW(project: Project): Stream<String> {
|
fun checkAW(path: Path, gamePath: Path) {
|
||||||
|
val reader = path.bufferedReader(StandardCharsets.UTF_8)
|
||||||
|
if (!HEADER.test(reader.readLine() ?: "")) {
|
||||||
|
error("AccessWidener validation failed (invalid header)")
|
||||||
|
}
|
||||||
|
FileSystems.newFileSystem(gamePath).use { fs ->
|
||||||
|
reader.lines().toList().forEachIndexed { index, line ->
|
||||||
|
val checkString = line.substring(0, line.indexOf("#"))
|
||||||
|
|
||||||
|
if (checkString.isNotEmpty()) {
|
||||||
|
val parts = checkString.split(SEPARATOR)
|
||||||
|
if (parts.size < 3) {
|
||||||
|
error("AccessWidener validation failed in line ${index + 2}: $line")
|
||||||
|
}
|
||||||
|
if (parts[1] == "class") {
|
||||||
|
val target = parts[2]
|
||||||
|
if (fs.getPath(target).notExists()) {
|
||||||
|
error("AccessWidener validation failed in line ${index + 2}: $line (Invalid target)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parts.size < 5) {
|
||||||
|
error("AccessWidener validation failed in line ${index + 2}: $line (Declaration missing)")
|
||||||
|
}
|
||||||
|
val owner = parts[2]
|
||||||
|
val name = parts[3]
|
||||||
|
val desc = parts[4]
|
||||||
|
when (parts[1]) {
|
||||||
|
"method" -> {
|
||||||
|
val classReader = ClassReader(fs.getPath(owner).readBytes())
|
||||||
|
val node = ClassNode()
|
||||||
|
classReader.accept(node, 0)
|
||||||
|
if (node.methods.none { it.name.equals(name) && it.desc.equals(desc) }) {
|
||||||
|
error("AccessWidener validation failed in line ${index + 2}: $line (Could not find target method)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"field" -> {
|
||||||
|
val classReader = ClassReader(fs.getPath(owner).readBytes())
|
||||||
|
val node = ClassNode()
|
||||||
|
classReader.accept(node, 0)
|
||||||
|
if (node.fields.none { it.name.equals(name) && it.desc.equals(desc) }) {
|
||||||
|
error("AccessWidener validation failed in line ${index + 2}: $line (Could not find target field)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readAW(project: Project): List<String> {
|
||||||
val awFile = getAWFile(project)
|
val awFile = getAWFile(project)
|
||||||
println("Found accesswidener in project: $awFile")
|
println("Found accesswidener in project: $awFile")
|
||||||
return awFile?.bufferedReader(StandardCharsets.UTF_8)
|
return awFile?.bufferedReader(StandardCharsets.UTF_8)
|
||||||
.takeIf { HEADER.test(it?.readLine() ?: "") }?.lines()
|
.takeIf { HEADER.test(it?.readLine() ?: "") }?.lines()
|
||||||
?.map { it.replace("transitive-", "") }
|
?.map { it.replace("transitive-", "") }?.toList()
|
||||||
?: Stream.empty()
|
?: emptyList()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readTransitiveAW(path: Path): Stream<String> {
|
private fun readTransitiveAW(path: Path): List<String> {
|
||||||
return path.bufferedReader(StandardCharsets.UTF_8).takeIf { HEADER.test(it.readLine() ?: "") }?.lines()?.filter { it.startsWith("transitive-") }?: Stream.empty()
|
return path.bufferedReader(StandardCharsets.UTF_8).takeIf { HEADER.test(it.readLine() ?: "") }?.lines()
|
||||||
|
?.filter { it.startsWith("transitive-") }?.toList() ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readAllAWs(project: Project): Stream<Entry> {
|
private fun readAllAWs(project: Project): Stream<Entry> {
|
||||||
return Stream.concat(
|
return Stream.concat(
|
||||||
findDependencyAWs(project),
|
findDependencyAWs(project),
|
||||||
readAW(project)
|
readAW(project).stream()
|
||||||
)
|
)
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.map { if (it.contains("#")) it.split("#")[0] else it }.filter { !HEADER.test(it) }
|
.map { if (it.contains("#")) it.split("#")[0] else it }.filter { !HEADER.test(it) }
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package dev.frogmc.phytotelma.ext
|
package dev.frogmc.phytotelma.ext
|
||||||
|
|
||||||
|
import com.electronwill.nightconfig.core.file.FileNotFoundAction
|
||||||
|
import com.electronwill.nightconfig.toml.TomlParser
|
||||||
import dev.frogmc.phytotelma.Constants
|
import dev.frogmc.phytotelma.Constants
|
||||||
import dev.frogmc.phytotelma.PhytotelmaPlugin
|
import dev.frogmc.phytotelma.PhytotelmaPlugin
|
||||||
import dev.frogmc.phytotelma.ProjectStorage
|
import dev.frogmc.phytotelma.ProjectStorage
|
||||||
|
@ -13,28 +15,28 @@ import dev.frogmc.phytotelma.run.RunConfigGenerator
|
||||||
import dev.frogmc.phytotelma.run.task.RunGameTask
|
import dev.frogmc.phytotelma.run.task.RunGameTask
|
||||||
import dev.frogmc.phytotelma.vineflower.FrogJavadocProvider
|
import dev.frogmc.phytotelma.vineflower.FrogJavadocProvider
|
||||||
import dev.frogmc.thyroxine.Thyroxine
|
import dev.frogmc.thyroxine.Thyroxine
|
||||||
|
import dev.frogmc.thyroxine.api.Mapper
|
||||||
import dev.frogmc.thyroxine.api.data.MappingBundle
|
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||||
import dev.frogmc.thyroxine.provider.MojmapProvider
|
import dev.frogmc.thyroxine.provider.MojmapProvider
|
||||||
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Configuration
|
|
||||||
import org.gradle.api.model.ObjectFactory
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.api.plugins.JavaBasePlugin
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
|
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
|
||||||
|
import org.gradle.configurationcache.extensions.capitalized
|
||||||
import org.jetbrains.java.decompiler.main.Fernflower
|
import org.jetbrains.java.decompiler.main.Fernflower
|
||||||
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger
|
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger
|
||||||
import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver
|
import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver
|
||||||
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences
|
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
|
import java.nio.file.FileSystems
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.io.path.createParentDirectories
|
import kotlin.io.path.*
|
||||||
import kotlin.io.path.deleteExisting
|
|
||||||
import kotlin.io.path.exists
|
|
||||||
import kotlin.io.path.notExists
|
|
||||||
|
|
||||||
abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
private val project: Project,
|
private val project: Project,
|
||||||
|
@ -104,24 +106,10 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.configurations.register(Constants.INCLUDE_CONFIGURATION) {
|
|
||||||
it.isCanBeResolved = true
|
|
||||||
it.isCanBeConsumed = false
|
|
||||||
}
|
|
||||||
|
|
||||||
project.configurations.register(Constants.MINECRAFT_CONFIGURATION) {
|
|
||||||
project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
|
||||||
project.configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
|
||||||
project.configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
|
||||||
project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
|
|
||||||
it.isCanBeResolved = false
|
|
||||||
it.isCanBeConsumed = false
|
|
||||||
it.isTransitive = false
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildTask = project.tasks.register(Constants.BUILD_TASK, PhytotelmaBuildTask::class.java)
|
val buildTask = project.tasks.register(Constants.BUILD_TASK, PhytotelmaBuildTask::class.java)
|
||||||
project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME).dependsOn(buildTask)
|
project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME).dependsOn(buildTask)
|
||||||
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast {
|
|
||||||
|
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast { task ->
|
||||||
val storage = ProjectStorage.get(project)
|
val storage = ProjectStorage.get(project)
|
||||||
if (storage.targetNamespace != "mojmap") {
|
if (storage.targetNamespace != "mojmap") {
|
||||||
val mappings = MappingBundle.merge(
|
val mappings = MappingBundle.merge(
|
||||||
|
@ -130,9 +118,52 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
|
PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
|
||||||
).orElseThrow().reverse().renameDstNamespace("mojmap")
|
).orElseThrow().reverse().renameDstNamespace("mojmap")
|
||||||
).forNamespaces(storage.targetNamespace, "mojmap")
|
).forNamespaces(storage.targetNamespace, "mojmap")
|
||||||
it.outputs.files.forEach { file ->
|
val parser = TomlParser()
|
||||||
|
task.outputs.files.forEach { file ->
|
||||||
val temp = Files.createTempFile("", file.name)
|
val temp = Files.createTempFile("", file.name)
|
||||||
Files.copy(file.toPath(), temp, StandardCopyOption.REPLACE_EXISTING)
|
Files.copy(file.toPath(), temp, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
FileSystems.newFileSystem(temp).use { fs ->
|
||||||
|
val metadata = fs.getPath(Constants.MOD_METADATA_FILE)
|
||||||
|
parser.parse(metadata, FileNotFoundAction.READ_NOTHING)
|
||||||
|
.get<String>("frog.extensions.accesswidener")?.let { name ->
|
||||||
|
val aw = metadata.resolveSibling(name)
|
||||||
|
AccessWidener.checkAW(aw, ProjectStorage.get(project).remappedGameJarPath!!)
|
||||||
|
val mapper = Mapper(mappings) { listOf() }
|
||||||
|
val buffer = buildString {
|
||||||
|
aw.forEachLine {
|
||||||
|
if (it.contains("\\t") && !it.startsWith("#")) {
|
||||||
|
val parts = it.split("[\\t #]+".toRegex()).toMutableList()
|
||||||
|
|
||||||
|
if (parts.size > 2) {
|
||||||
|
|
||||||
|
val type = parts[1]
|
||||||
|
when (type) {
|
||||||
|
"class" -> {
|
||||||
|
parts[2] = mapper.map(parts[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
"fields" -> {
|
||||||
|
parts[3] = mapper.mapFieldName(parts[2], parts[3], parts[4])
|
||||||
|
parts[4] = mapper.mapDesc(parts[4])
|
||||||
|
parts[3] = mapper.map(parts[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
"methods" -> {
|
||||||
|
parts[3] = mapper.mapMethodName(parts[2], parts[3], parts[4])
|
||||||
|
parts[4] = mapper.mapMethodDesc(parts[4])
|
||||||
|
parts[2] = mapper.map(parts[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendLine(parts.joinToString("\\t"))
|
||||||
|
return@forEachLine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendLine(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aw.writeText(buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
Thyroxine.remap(mappings, temp, file.toPath(), false, false)
|
Thyroxine.remap(mappings, temp, file.toPath(), false, false)
|
||||||
Files.deleteIfExists(temp)
|
Files.deleteIfExists(temp)
|
||||||
}
|
}
|
||||||
|
@ -146,28 +177,90 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val configuration = project.configurations.create("modImplemenation") {
|
project.tasks.register(Constants.CLEAR_LOCAL_CACHE_TASK) { task ->
|
||||||
it.isCanBeResolved = true
|
task.group = Constants.TASK_GROUP
|
||||||
it.isCanBeConsumed = false
|
task.actions.add {
|
||||||
}
|
clearLocalCache()
|
||||||
project.afterEvaluate {
|
|
||||||
//remapModDependencies(configuration)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun remapModDependencies(configuration: Configuration) {
|
project.tasks.register(Constants.CLEAR_GLOBAL_CACHE_TASK) { task ->
|
||||||
// TODO
|
task.group = Constants.TASK_GROUP
|
||||||
val mappings =
|
task.actions.add {
|
||||||
ProjectStorage.get(project).mappings!!.forNamespaces("mojmap", ProjectStorage.get(project).targetNamespace)
|
clearGlobalCache()
|
||||||
val targetPath = ProjectStorage.get(project).localCacheDir!!
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPathApi::class)
|
||||||
|
private fun clearLocalCache() {
|
||||||
|
ProjectStorage.get(project).localCacheDir?.deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPathApi::class)
|
||||||
|
private fun clearGlobalCache() {
|
||||||
|
PhytotelmaPlugin.globalCacheDir.deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun remapModDependencies() {
|
||||||
|
PhytotelmaPlugin.remappedConfigurationNames.forEach { conf ->
|
||||||
|
val artifacts = project.configurations.getByName("mod" + conf.key.capitalized())
|
||||||
|
.resolvedConfiguration.resolvedArtifacts
|
||||||
|
if (artifacts.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val target = project.configurations.create("mod" + conf.key.capitalized()+"Mapped") { c ->
|
||||||
|
c.isTransitive = false // TODO while this configuration should not be transitive, the original dependency should be!
|
||||||
|
conf.value.forEach {
|
||||||
|
project.configurations.getByName(it).extendsFrom(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val storage = ProjectStorage.get(project)
|
||||||
|
val mappings = MappingBundle.merge(
|
||||||
|
storage.mappings!!.reverse(), MojmapProvider.get(
|
||||||
|
storage.minecraftVersion!!,
|
||||||
|
PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
|
||||||
|
).orElseThrow().reverse().renameDstNamespace("mojmap")
|
||||||
|
).forNamespaces("mojmap", storage.targetNamespace)
|
||||||
|
val targetPath = project.layout.buildDirectory.asFile.get().toPath().resolve("remappedMods")
|
||||||
|
.resolve("dev/frogmc/phytotelma/remapped_mods")
|
||||||
val remappedPaths = mutableListOf<Path>()
|
val remappedPaths = mutableListOf<Path>()
|
||||||
configuration.resolvedConfiguration.resolvedArtifacts.forEach {
|
artifacts.forEach { artifact ->
|
||||||
val remappedPath = targetPath.resolve(it.id.toString().replace(":", "/").replace(".", "/"))
|
println(artifact.file)
|
||||||
|
val id = artifact.id.componentIdentifier.toString().split(":")
|
||||||
|
val group = artifact.moduleVersion.id.group
|
||||||
|
val name = artifact.moduleVersion.id.name
|
||||||
|
val groupname = (group + "_" + name).replace(".", "_")
|
||||||
|
val version = artifact.moduleVersion.id.version
|
||||||
|
val classifier = artifact.classifier
|
||||||
|
val remappedPath = targetPath.resolve(groupname).resolve(version).resolve(artifact.file.name)
|
||||||
|
/*val remappedPath = targetPath.resolve(group.replace(".", "/"))
|
||||||
|
.resolve(name).resolve(version).resolve(artifact.file.name)*/
|
||||||
|
remappedPath.createParentDirectories()
|
||||||
remappedPaths.add(remappedPath)
|
remappedPaths.add(remappedPath)
|
||||||
|
|
||||||
configuration.dependencies.removeIf { d -> d.group + ":" + d.name + ":" + d.version == it.id.toString() }
|
val pom = remappedPath.resolveSibling(artifact.file.name.removeSuffix(".jar")+".pom")
|
||||||
}
|
//val pom = remappedPath.resolveSibling(artifact.file.name.substring(0, artifact.file.name.lastIndexOf("."))+".pom")
|
||||||
|
pom.writeText(
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" +
|
||||||
|
"\t\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
|
||||||
|
"\t<modelVersion>4.0.0</modelVersion>\n" +
|
||||||
|
//"\t<groupId>$group</groupId>\n" +
|
||||||
|
//"\t<artifactId>$name</artifactId>\n" +
|
||||||
|
"\t<groupId>dev.frogmc.phytotelma.remapped_mods</groupId>\n" +
|
||||||
|
"\t<artifactId>$groupname</artifactId>\n" +
|
||||||
|
"\t<version>$version</version>\n" +
|
||||||
|
"</project>"
|
||||||
|
)
|
||||||
|
remappedPaths.add(pom)
|
||||||
|
|
||||||
|
Thyroxine.remap(mappings, artifact.file.toPath(), remappedPath, false, false)
|
||||||
|
|
||||||
|
//project.dependencies.add(conf.key, group+":"+name+":"+version+(classifier?:""))
|
||||||
|
project.dependencies.add(target.name, "dev.frogmc.phytotelma.remapped_mods:$groupname:$version"+(classifier?.let { ":$it" }?:""))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun minecraft(action: Action<MinecraftConfiguration>) {
|
override fun minecraft(action: Action<MinecraftConfiguration>) {
|
||||||
|
@ -227,6 +320,8 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
AccessWidener.apply(project, remappedJar)
|
AccessWidener.apply(project, remappedJar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remapModDependencies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +331,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
if (conf.version == null) {
|
if (conf.version == null) {
|
||||||
error("No loader version provided!")
|
error("No loader version provided!")
|
||||||
}
|
}
|
||||||
project.dependencies.add("implementation", "dev.frogmc:frogloader:${conf.version!!}")
|
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, "dev.frogmc:frogloader:${conf.version!!}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun froglib(action: Action<VersionConfiguration>) {
|
override fun froglib(action: Action<VersionConfiguration>) {
|
||||||
|
@ -245,7 +340,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
if (conf.version == null) {
|
if (conf.version == null) {
|
||||||
error("No froglib version provided!")
|
error("No froglib version provided!")
|
||||||
}
|
}
|
||||||
project.dependencies.add("implementation", "dev.frogmc:froglib:${conf.version!!}")
|
project.dependencies.add("modImplementation", "dev.frogmc:froglib:${conf.version!!}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue