rework dsl, add mod configurations (remapped), add support for other mappings #3
|
@ -10,7 +10,7 @@ object ProjectStorage {
|
||||||
|
|
||||||
fun get(project: Project): ProjectData {
|
fun get(project: Project): ProjectData {
|
||||||
if (!data.containsKey(project)) {
|
if (!data.containsKey(project)) {
|
||||||
data[project] = ProjectData(null, null, null, null, null)
|
data[project] = ProjectData(null, null, null, null, null, null)
|
||||||
}
|
}
|
||||||
return data[project]!!
|
return data[project]!!
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,6 @@ class ProjectData(
|
||||||
var minecraftVersion: String?,
|
var minecraftVersion: String?,
|
||||||
var remappedGameJarPath: Path?,
|
var remappedGameJarPath: Path?,
|
||||||
var mappings: MappingBundle?,
|
var mappings: MappingBundle?,
|
||||||
var mappingsName: String?
|
var mappingsName: String?,
|
||||||
|
var targetNamespace: String?
|
||||||
)
|
)
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.frogmc.phytotelma.ext
|
package dev.frogmc.phytotelma.ext
|
||||||
|
|
||||||
import dev.frogmc.phytotelma.PhytotelmaPlugin
|
import dev.frogmc.phytotelma.PhytotelmaPlugin
|
||||||
|
import dev.frogmc.phytotelma.mappings.renameDstNamespace
|
||||||
import dev.frogmc.thyroxine.api.data.MappingBundle
|
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||||
import dev.frogmc.thyroxine.parser.tiny.TinyV2Parser
|
import dev.frogmc.thyroxine.parser.tiny.TinyV2Parser
|
||||||
import dev.frogmc.thyroxine.provider.MojmapProvider
|
import dev.frogmc.thyroxine.provider.MojmapProvider
|
||||||
|
@ -22,19 +23,15 @@ abstract class MinecraftConfiguration @Inject constructor(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var version: String? = null
|
var version: String? = null
|
||||||
var mappings: Provider<MappingBundle> = mojmapParchment()
|
internal var mappings: Provider<MappingBundle> = mojmapParchment()
|
||||||
private lateinit var mappingsName: String
|
internal lateinit var mappingsName: String
|
||||||
|
internal lateinit var targetNamespace: String
|
||||||
internal fun mappingsName(): String {
|
|
||||||
return mappingsName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun mojmapParchment(): Provider<MappingBundle> {
|
fun mojmapParchment(): Provider<MappingBundle> {
|
||||||
return mojmapParchment {}
|
return mojmapParchment {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mojmapParchment(action: Action<ParchmentConfiguration>): Provider<MappingBundle> {
|
fun mojmapParchment(action: Action<ParchmentConfiguration>): Provider<MappingBundle> {
|
||||||
mappingsName = "mojmap"
|
|
||||||
return project.provider {
|
return project.provider {
|
||||||
val conf = objects.newInstance(ParchmentConfiguration::class.java)
|
val conf = objects.newInstance(ParchmentConfiguration::class.java)
|
||||||
conf.gameVersion = version
|
conf.gameVersion = version
|
||||||
|
@ -44,12 +41,13 @@ abstract class MinecraftConfiguration @Inject constructor(
|
||||||
if (conf.version == null) {
|
if (conf.version == null) {
|
||||||
conf.version = ParchmentProvider.findForMinecraftVersion(conf.gameVersion)
|
conf.version = ParchmentProvider.findForMinecraftVersion(conf.gameVersion)
|
||||||
}
|
}
|
||||||
|
mappingsName = "mojmap($version)+parchment(${conf.gameVersion}, ${conf.version})"
|
||||||
|
|
||||||
return@provider MappingBundle.merge(
|
return@provider MappingBundle.merge(
|
||||||
MojmapProvider.get(
|
MojmapProvider.get(
|
||||||
version,
|
version,
|
||||||
cacheDir.resolve("net/minecraft/client/$version/client-$version.txt")
|
cacheDir.resolve("net/minecraft/client/$version/client-$version.txt")
|
||||||
).orElseThrow(),
|
).orElseThrow().reverse(),
|
||||||
ParchmentProvider.getParchment(
|
ParchmentProvider.getParchment(
|
||||||
version,
|
version,
|
||||||
cacheDir.resolve("org/parchmentmc/parchment/${conf.gameVersion}/${conf.version}")
|
cacheDir.resolve("org/parchmentmc/parchment/${conf.gameVersion}/${conf.version}")
|
||||||
|
@ -58,23 +56,35 @@ abstract class MinecraftConfiguration @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun mojmap(): Provider<MappingBundle> {
|
||||||
|
return project.provider {
|
||||||
|
val cacheDir = PhytotelmaPlugin.globalCacheDir
|
||||||
|
mappingsName = "mojmap($version)"
|
||||||
|
return@provider MojmapProvider.get(
|
||||||
|
version,
|
||||||
|
cacheDir.resolve("net/minecraft/client/$version/client-$version.txt")
|
||||||
|
).orElseThrow().reverse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun quiltMappings(action: Action<VersionConfiguration>): Provider<MappingBundle> {
|
fun quiltMappings(action: Action<VersionConfiguration>): Provider<MappingBundle> {
|
||||||
mappingsName = "quilt"
|
|
||||||
return project.provider {
|
return project.provider {
|
||||||
val conf = objects.newInstance(VersionConfiguration::class.java)
|
val conf = objects.newInstance(VersionConfiguration::class.java)
|
||||||
action.execute(conf)
|
action.execute(conf)
|
||||||
if (conf.version == null) {
|
if (conf.version == null) {
|
||||||
error("No version provided for quilt mappings!")
|
error("No version provided for quilt mappings!")
|
||||||
}
|
}
|
||||||
|
mappingsName = "quilt(${conf.version})"
|
||||||
|
targetNamespace = "quilt"
|
||||||
|
// Use qm via intermediary because hashed publications are broken
|
||||||
return@provider twoStepMappings(
|
return@provider twoStepMappings(
|
||||||
"org.quiltmc:hashed:$version",
|
"net.fabricmc:intermediary:$version:v2",
|
||||||
"org.quiltmc:quilt-mappings:${conf.version}:v2"
|
"org.quiltmc:quilt-mappings:${conf.version}:intermediary-v2"
|
||||||
)
|
).renameDstNamespace(targetNamespace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun twoStepMappings(action: Action<TwoStepMappingsConfiguration>): Provider<MappingBundle> {
|
fun twoStepMappings(action: Action<TwoStepMappingsConfiguration>): Provider<MappingBundle> {
|
||||||
mappingsName = "custom/two-step"
|
|
||||||
return project.provider {
|
return project.provider {
|
||||||
val conf = objects.newInstance(TwoStepMappingsConfiguration::class.java)
|
val conf = objects.newInstance(TwoStepMappingsConfiguration::class.java)
|
||||||
action.execute(conf)
|
action.execute(conf)
|
||||||
|
@ -84,37 +94,34 @@ abstract class MinecraftConfiguration @Inject constructor(
|
||||||
if (conf.second == null) {
|
if (conf.second == null) {
|
||||||
error("No version provided for second mapping step!")
|
error("No version provided for second mapping step!")
|
||||||
}
|
}
|
||||||
return@provider twoStepMappings(conf.first!!, conf.second!!)
|
mappingsName = "custom/two-step(${conf.first!!}, ${conf.second!!})"
|
||||||
|
val bundle = twoStepMappings(conf.first!!, conf.second!!)
|
||||||
|
targetNamespace = bundle.flattenData().dstNamespace
|
||||||
|
return@provider bundle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tinyMappings(action: Action<NameConfiguration>): Provider<MappingBundle> {
|
fun tinyMappings(action: Action<NameConfiguration>): Provider<MappingBundle> {
|
||||||
mappingsName = "custom/tiny"
|
|
||||||
return project.provider {
|
return project.provider {
|
||||||
val conf = objects.newInstance(NameConfiguration::class.java)
|
val conf = objects.newInstance(NameConfiguration::class.java)
|
||||||
action.execute(conf)
|
action.execute(conf)
|
||||||
if (conf.name == null) {
|
if (conf.name == null) {
|
||||||
error("No maven coordinate provided for tiny mappings!")
|
error("No maven coordinate provided for tiny mappings!")
|
||||||
}
|
}
|
||||||
return@provider tinyMappings(conf.name!!)
|
mappingsName = "custom/tiny(${conf.name})"
|
||||||
}
|
val bundle = tinyMappings(conf.name!!)
|
||||||
}
|
targetNamespace = bundle.flattenData().dstNamespace
|
||||||
|
|
||||||
fun mappings(action: Action<MappingBundle>): Provider<MappingBundle> {
|
|
||||||
mappingsName = "custom"
|
|
||||||
return project.provider {
|
|
||||||
val bundle = MappingBundle()
|
|
||||||
action.execute(bundle)
|
|
||||||
return@provider bundle
|
return@provider bundle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun layer(action: Action<LayerConfiguration>): Provider<MappingBundle> {
|
fun mappings(action: Action<MappingBundle>): Provider<MappingBundle> {
|
||||||
return project.provider {
|
return project.provider {
|
||||||
val config = objects.newInstance(LayerConfiguration::class.java)
|
val bundle = MappingBundle()
|
||||||
action.execute(config)
|
action.execute(bundle)
|
||||||
|
mappingsName = "custom(${bundle.srcNamespaces()}, ${bundle.dstNamespaces()})"
|
||||||
return@provider MappingBundle.merge(*config.layers.map { it.get() }.toTypedArray())
|
targetNamespace = bundle.flattenData().dstNamespace
|
||||||
|
return@provider bundle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,48 @@
|
||||||
package dev.frogmc.phytotelma.ext
|
package dev.frogmc.phytotelma.ext
|
||||||
|
|
||||||
import dev.frogmc.phytotelma.Constants
|
import dev.frogmc.phytotelma.Constants
|
||||||
|
import dev.frogmc.phytotelma.PhytotelmaPlugin
|
||||||
import dev.frogmc.phytotelma.ProjectStorage
|
import dev.frogmc.phytotelma.ProjectStorage
|
||||||
import dev.frogmc.phytotelma.VersionChecker
|
import dev.frogmc.phytotelma.VersionChecker
|
||||||
import dev.frogmc.phytotelma.accesswidener.AccessWidener
|
import dev.frogmc.phytotelma.accesswidener.AccessWidener
|
||||||
import dev.frogmc.phytotelma.build.PhytotelmaBuildTask
|
import dev.frogmc.phytotelma.build.PhytotelmaBuildTask
|
||||||
import dev.frogmc.phytotelma.common.Env
|
import dev.frogmc.phytotelma.common.Env
|
||||||
|
import dev.frogmc.phytotelma.mappings.renameDstNamespace
|
||||||
import dev.frogmc.phytotelma.run.AssetDownloader
|
import dev.frogmc.phytotelma.run.AssetDownloader
|
||||||
import dev.frogmc.phytotelma.run.RunConfigGenerator
|
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.data.MappingBundle
|
||||||
|
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.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
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.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.io.path.createParentDirectories
|
import kotlin.io.path.createParentDirectories
|
||||||
import kotlin.io.path.deleteExisting
|
import kotlin.io.path.deleteExisting
|
||||||
import kotlin.io.path.exists
|
import kotlin.io.path.exists
|
||||||
import kotlin.io.path.notExists
|
import kotlin.io.path.notExists
|
||||||
|
|
||||||
abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val project: Project, private val objects: ObjectFactory) : PhytotelmaGradleExtension {
|
abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
|
private val project: Project,
|
||||||
|
private val objects: ObjectFactory
|
||||||
|
) : PhytotelmaGradleExtension {
|
||||||
|
|
||||||
private fun setupTasks() {
|
private fun setupTasks() {
|
||||||
project.tasks.register("genSources") {task ->
|
project.tasks.register("genSources") { task ->
|
||||||
task.group = Constants.TASK_GROUP
|
task.group = Constants.TASK_GROUP
|
||||||
task.actions.add {
|
task.actions.add {
|
||||||
val projectData = ProjectStorage.get(it.project)
|
val projectData = ProjectStorage.get(it.project)
|
||||||
|
@ -49,7 +61,8 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val pro
|
||||||
val options = mutableMapOf<String, Any>()
|
val options = mutableMapOf<String, Any>()
|
||||||
println("Preparing Parchment...")
|
println("Preparing Parchment...")
|
||||||
val javadocs = ProjectStorage.get(project).mappings!!
|
val javadocs = ProjectStorage.get(project).mappings!!
|
||||||
options[IFabricJavadocProvider.PROPERTY_NAME] = FrogJavadocProvider(javadocs.docsForNamespace(Constants.DEV_NAMESPACE))
|
options[IFabricJavadocProvider.PROPERTY_NAME] =
|
||||||
|
FrogJavadocProvider(javadocs.docsForNamespace(Constants.DEV_NAMESPACE))
|
||||||
|
|
||||||
println("Decompiling...")
|
println("Decompiling...")
|
||||||
val logger = PrintStreamLogger(PrintStream(System.out))
|
val logger = PrintStreamLogger(PrintStream(System.out))
|
||||||
|
@ -74,7 +87,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.tasks.register(Constants.GEN_RUN_CONFIGS_TASK) {task ->
|
project.tasks.register(Constants.GEN_RUN_CONFIGS_TASK) { task ->
|
||||||
task.group = Constants.TASK_GROUP
|
task.group = Constants.TASK_GROUP
|
||||||
task.doFirst {
|
task.doFirst {
|
||||||
RunConfigGenerator.generate(project)
|
RunConfigGenerator.generate(project)
|
||||||
|
@ -107,7 +120,24 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val pro
|
||||||
}
|
}
|
||||||
|
|
||||||
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("build").dependsOn(buildTask)
|
project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME).dependsOn(buildTask)
|
||||||
|
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast {
|
||||||
|
val storage = ProjectStorage.get(project)
|
||||||
|
if (storage.targetNamespace != "mojmap") {
|
||||||
|
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(storage.targetNamespace, "mojmap")
|
||||||
|
it.outputs.files.forEach { file ->
|
||||||
|
val temp = Files.createTempFile("", file.name)
|
||||||
|
Files.copy(file.toPath(), temp, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
Thyroxine.remap(mappings, temp, file.toPath(), false, false)
|
||||||
|
Files.deleteIfExists(temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
project.tasks.register(Constants.UPDATE_AW_TASK) { task ->
|
project.tasks.register(Constants.UPDATE_AW_TASK) { task ->
|
||||||
task.group = Constants.TASK_GROUP
|
task.group = Constants.TASK_GROUP
|
||||||
|
@ -115,6 +145,29 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val pro
|
||||||
AccessWidener.apply(project, ProjectStorage.get(it.project).remappedGameJarPath!!)
|
AccessWidener.apply(project, ProjectStorage.get(it.project).remappedGameJarPath!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val configuration = project.configurations.create("modImplemenation") {
|
||||||
|
it.isCanBeResolved = true
|
||||||
|
it.isCanBeConsumed = false
|
||||||
|
}
|
||||||
|
project.afterEvaluate {
|
||||||
|
remapModDependencies(configuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun remapModDependencies(configuration: Configuration) {
|
||||||
|
// TODO
|
||||||
|
val mappings =
|
||||||
|
ProjectStorage.get(project).mappings!!.forNamespaces("mojmap", ProjectStorage.get(project).targetNamespace)
|
||||||
|
val targetPath = ProjectStorage.get(project).localCacheDir!!
|
||||||
|
val remappedPaths = mutableListOf<Path>()
|
||||||
|
configuration.resolvedConfiguration.resolvedArtifacts.forEach {
|
||||||
|
val remappedPath = targetPath.resolve(it.id.toString().replace(":", "/").replace(".", "/"))
|
||||||
|
remappedPaths.add(remappedPath)
|
||||||
|
|
||||||
|
configuration.dependencies.removeIf { d -> d.group + ":" + d.name + ":" + d.version == it.id.toString() }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun minecraft(action: Action<MinecraftConfiguration>) {
|
override fun minecraft(action: Action<MinecraftConfiguration>) {
|
||||||
|
@ -135,7 +188,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val pro
|
||||||
projectData.minecraftVersion = version
|
projectData.minecraftVersion = version
|
||||||
|
|
||||||
val mappings = mcConf.mappings.get()
|
val mappings = mcConf.mappings.get()
|
||||||
println("Using mappings: "+mcConf.mappingsName())
|
println("Using mappings: " + mcConf.mappingsName)
|
||||||
projectData.mappings = mappings
|
projectData.mappings = mappings
|
||||||
|
|
||||||
val clientJar = VersionChecker.downloadClient(project, version)
|
val clientJar = VersionChecker.downloadClient(project, version)
|
||||||
|
@ -145,11 +198,14 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val pro
|
||||||
projectData.remappedGameJarPath = remappedJar
|
projectData.remappedGameJarPath = remappedJar
|
||||||
println("Time to setup Minecraft!")
|
println("Time to setup Minecraft!")
|
||||||
val applyAW = AccessWidener.needsUpdate(project)
|
val applyAW = AccessWidener.needsUpdate(project)
|
||||||
if (remappedJar.notExists() || applyAW || mcConf.mappingsName() != projectData.mappingsName) {
|
if (remappedJar.notExists() || applyAW || mcConf.mappingsName != projectData.mappingsName) {
|
||||||
projectData.mappingsName = mcConf.mappingsName()
|
projectData.mappingsName = mcConf.mappingsName
|
||||||
println("Remapping the game...")
|
println("Remapping the game...")
|
||||||
Thyroxine.remap(mappings.forNamespaces("official", "named"),
|
projectData.targetNamespace = mcConf.targetNamespace
|
||||||
clientJar, remappedJar, true, true)
|
Thyroxine.remap(
|
||||||
|
mappings.forNamespaces("official", mcConf.targetNamespace),
|
||||||
|
clientJar, remappedJar, true, true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
project.dependencies.add(
|
project.dependencies.add(
|
||||||
|
|
21
src/main/kotlin/dev/frogmc/phytotelma/mappings/Mappings.kt
Normal file
21
src/main/kotlin/dev/frogmc/phytotelma/mappings/Mappings.kt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package dev.frogmc.phytotelma.mappings
|
||||||
|
|
||||||
|
import dev.frogmc.thyroxine.api.data.DocumentationData
|
||||||
|
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||||
|
import dev.frogmc.thyroxine.api.data.MappingData
|
||||||
|
|
||||||
|
fun MappingBundle.renameDstNamespace(newDst: String): MappingBundle {
|
||||||
|
val renamed = MappingBundle()
|
||||||
|
val oldData = flattenData()
|
||||||
|
val newData = MappingData(oldData.srcNamespace, newDst)
|
||||||
|
val newDocs = DocumentationData(newDst)
|
||||||
|
|
||||||
|
oldData.apply {
|
||||||
|
newData.classes.putAll(classes)
|
||||||
|
newData.fields.putAll(fields)
|
||||||
|
newData.methods.putAll(methods)
|
||||||
|
newData.parameters.putAll(parameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
return renamed.insert(newData, newDocs.insert(get(oldData.dstNamespace)))
|
||||||
|
}
|
Loading…
Reference in a new issue