rework dsl, add mod configurations (remapped), add support for other mappings #3
|
@ -7,7 +7,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.frogmc"
|
group = "dev.frogmc"
|
||||||
version = "0.0.1-alpha.12"
|
version = "0.0.1-alpha.13"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
|
@ -18,17 +18,18 @@ repositories {
|
||||||
name = "FrogMC Maven Snapshots"
|
name = "FrogMC Maven Snapshots"
|
||||||
url = uri("https://maven.frogmc.dev/snapshots")
|
url = uri("https://maven.frogmc.dev/snapshots")
|
||||||
}
|
}
|
||||||
|
mavenLocal()
|
||||||
|
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("dev.frogmc:thyroxine:0.0.1-alpha.5")
|
implementation("dev.frogmc:thyroxine:0.0.1-alpha.6")
|
||||||
implementation("org.ow2.asm:asm:9.7")
|
implementation("org.ow2.asm:asm: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"))
|
||||||
implementation("com.electronwill.night-config:toml:3.7.3")
|
implementation("com.electronwill.night-config:toml:3.8.0")
|
||||||
implementation("com.google.jimfs:jimfs:1.3.0")
|
implementation("com.google.jimfs:jimfs:1.3.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,5 @@ 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 DEV_NAMESPACE = "named"
|
||||||
}
|
}
|
|
@ -1,29 +1,12 @@
|
||||||
package dev.frogmc.phytotelma
|
package dev.frogmc.phytotelma
|
||||||
|
|
||||||
import dev.frogmc.phytotelma.accesswidener.AccessWidener
|
|
||||||
import dev.frogmc.phytotelma.build.PhytotelmaBuildTask
|
|
||||||
import dev.frogmc.phytotelma.common.Env
|
|
||||||
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 dev.frogmc.phytotelma.run.AssetDownloader
|
|
||||||
import dev.frogmc.phytotelma.run.RunConfigGenerator
|
|
||||||
import dev.frogmc.phytotelma.run.task.RunGameTask
|
|
||||||
import dev.frogmc.phytotelma.vineflower.ParchmentJavadocProvider
|
|
||||||
import dev.frogmc.thyroxine.provider.ParchmentProvider
|
|
||||||
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
|
||||||
import org.jetbrains.java.decompiler.main.Fernflower
|
|
||||||
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger
|
|
||||||
import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver
|
|
||||||
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences
|
|
||||||
import java.io.PrintStream
|
|
||||||
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
|
||||||
import kotlin.io.path.deleteExisting
|
|
||||||
import kotlin.io.path.exists
|
|
||||||
|
|
||||||
|
|
||||||
class PhytotelmaPlugin : Plugin<Project> {
|
class PhytotelmaPlugin : Plugin<Project> {
|
||||||
|
@ -67,98 +50,6 @@ class PhytotelmaPlugin : Plugin<Project> {
|
||||||
"phytotelma",
|
"phytotelma",
|
||||||
PhytotelmaGradleExtensionImpl::class.java
|
PhytotelmaGradleExtensionImpl::class.java
|
||||||
)
|
)
|
||||||
|
|
||||||
project.extensions.findByType(PhytotelmaGradleExtension::class.java) ?: return
|
|
||||||
|
|
||||||
project.tasks.register("genSources") {task ->
|
|
||||||
task.group = Constants.TASK_GROUP
|
|
||||||
task.actions.add {
|
|
||||||
val projectData = ProjectStorage.get(it.project)
|
|
||||||
val fileName = projectData.remappedGameJarPath!!.fileName.toString()
|
|
||||||
val output =
|
|
||||||
projectData.remappedGameJarPath!!.resolveSibling(
|
|
||||||
fileName.substring(
|
|
||||||
0,
|
|
||||||
fileName.lastIndexOf("-")
|
|
||||||
) + "-sources.jar"
|
|
||||||
)
|
|
||||||
if (output.exists()) {
|
|
||||||
println("Output $output already exists, deleting!")
|
|
||||||
output.deleteExisting()
|
|
||||||
}
|
|
||||||
val options = mutableMapOf<String, Any>()
|
|
||||||
println("Preparing Parchment...")
|
|
||||||
val parchment = ParchmentProvider.getParchment(
|
|
||||||
projectData.minecraftVersion!!,
|
|
||||||
projectData.parchmentVersion!!,
|
|
||||||
globalCacheDir.resolve("org/parchmentmc/parchment/${projectData.minecraftVersion}/${projectData.parchmentVersion}/")
|
|
||||||
)
|
|
||||||
options[IFabricJavadocProvider.PROPERTY_NAME] = ParchmentJavadocProvider(parchment)
|
|
||||||
|
|
||||||
println("Decompiling...")
|
|
||||||
val logger = PrintStreamLogger(PrintStream(System.out))
|
|
||||||
options.putAll(
|
|
||||||
mapOf(
|
|
||||||
IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES to "1",
|
|
||||||
IFernflowerPreferences.BYTECODE_SOURCE_MAPPING to "1",
|
|
||||||
IFernflowerPreferences.REMOVE_SYNTHETIC to "1",
|
|
||||||
IFernflowerPreferences.LOG_LEVEL to "error",
|
|
||||||
IFernflowerPreferences.THREADS to Runtime.getRuntime().availableProcessors().toString(),
|
|
||||||
IFernflowerPreferences.INDENT_STRING to "\t"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val decomp = Fernflower(
|
|
||||||
SingleFileSaver(output.toFile()),
|
|
||||||
options, logger
|
|
||||||
)
|
|
||||||
decomp.addSource(projectData.remappedGameJarPath!!.toFile())
|
|
||||||
|
|
||||||
decomp.decompileContext()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project.tasks.register(Constants.GEN_RUN_CONFIGS_TASK) {task ->
|
|
||||||
task.group = Constants.TASK_GROUP
|
|
||||||
task.doFirst {
|
|
||||||
RunConfigGenerator.generate(project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project.tasks.register(Constants.RUN_CLIENT_TASK, RunGameTask::class.java, Env.CLIENT)
|
|
||||||
project.tasks.register(Constants.RUNT_SERVER_TASK, RunGameTask::class.java, Env.SERVER)
|
|
||||||
|
|
||||||
project.tasks.register(Constants.DOWNLOAD_ASSETS_TASK) { task ->
|
|
||||||
task.group = Constants.TASK_GROUP
|
|
||||||
task.doFirst {
|
|
||||||
AssetDownloader.download(it.project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
project.tasks.getByName("build").dependsOn(buildTask)
|
|
||||||
|
|
||||||
project.tasks.register(Constants.UPDATE_AW_TASK) { task ->
|
|
||||||
task.group = Constants.TASK_GROUP
|
|
||||||
task.actions.addFirst {
|
|
||||||
AccessWidener.apply(project, ProjectStorage.get(it.project).remappedGameJarPath!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package dev.frogmc.phytotelma
|
package dev.frogmc.phytotelma
|
||||||
|
|
||||||
|
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
@ -9,14 +10,17 @@ 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)
|
data[project] = ProjectData(null, null, null, null, null)
|
||||||
}
|
}
|
||||||
return data[project]!!
|
return data[project]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProjectData(var localCacheDir: Path?,
|
class ProjectData(
|
||||||
|
var localCacheDir: Path?,
|
||||||
var minecraftVersion: String?,
|
var minecraftVersion: String?,
|
||||||
var remappedGameJarPath: Path?,
|
var remappedGameJarPath: Path?,
|
||||||
var parchmentVersion: String?)
|
var mappings: MappingBundle?,
|
||||||
|
var mappingsName: String?
|
||||||
|
)
|
|
@ -0,0 +1,174 @@
|
||||||
|
package dev.frogmc.phytotelma.ext
|
||||||
|
|
||||||
|
import dev.frogmc.phytotelma.PhytotelmaPlugin
|
||||||
|
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||||
|
import dev.frogmc.thyroxine.parser.tiny.TinyV2Parser
|
||||||
|
import dev.frogmc.thyroxine.provider.MojmapProvider
|
||||||
|
import dev.frogmc.thyroxine.provider.ParchmentProvider
|
||||||
|
import org.gradle.api.Action
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.nio.file.FileSystems
|
||||||
|
import java.nio.file.Path
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.io.path.readText
|
||||||
|
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||||
|
abstract class MinecraftConfiguration @Inject constructor(
|
||||||
|
private val project: Project,
|
||||||
|
private val objects: ObjectFactory
|
||||||
|
) {
|
||||||
|
|
||||||
|
var version: String? = null
|
||||||
|
var mappings: Provider<MappingBundle> = mojmapParchment()
|
||||||
|
private lateinit var mappingsName: String
|
||||||
|
|
||||||
|
internal fun mappingsName(): String {
|
||||||
|
return mappingsName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mojmapParchment(): Provider<MappingBundle> {
|
||||||
|
return mojmapParchment {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mojmapParchment(action: Action<ParchmentConfiguration>): Provider<MappingBundle> {
|
||||||
|
mappingsName = "mojmap"
|
||||||
|
return project.provider {
|
||||||
|
val conf = objects.newInstance(ParchmentConfiguration::class.java)
|
||||||
|
conf.gameVersion = version
|
||||||
|
action.execute(conf)
|
||||||
|
val cacheDir = PhytotelmaPlugin.globalCacheDir
|
||||||
|
|
||||||
|
if (conf.version == null) {
|
||||||
|
conf.version = ParchmentProvider.findForMinecraftVersion(conf.gameVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
return@provider MappingBundle.merge(
|
||||||
|
MojmapProvider.get(
|
||||||
|
version,
|
||||||
|
cacheDir.resolve("net/minecraft/client/$version/client-$version.txt")
|
||||||
|
).orElseThrow(),
|
||||||
|
ParchmentProvider.getParchment(
|
||||||
|
version,
|
||||||
|
cacheDir.resolve("org/parchmentmc/parchment/${conf.gameVersion}/${conf.version}")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun quiltMappings(action: Action<VersionConfiguration>): Provider<MappingBundle> {
|
||||||
|
mappingsName = "quilt"
|
||||||
|
return project.provider {
|
||||||
|
val conf = objects.newInstance(VersionConfiguration::class.java)
|
||||||
|
action.execute(conf)
|
||||||
|
if (conf.version == null) {
|
||||||
|
error("No version provided for quilt mappings!")
|
||||||
|
}
|
||||||
|
return@provider twoStepMappings(
|
||||||
|
"org.quiltmc:hashed:$version",
|
||||||
|
"org.quiltmc:quilt-mappings:${conf.version}:v2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun twoStepMappings(action: Action<TwoStepMappingsConfiguration>): Provider<MappingBundle> {
|
||||||
|
mappingsName = "custom/two-step"
|
||||||
|
return project.provider {
|
||||||
|
val conf = objects.newInstance(TwoStepMappingsConfiguration::class.java)
|
||||||
|
action.execute(conf)
|
||||||
|
if (conf.first == null) {
|
||||||
|
error("No version provided for first mapping step!")
|
||||||
|
}
|
||||||
|
if (conf.second == null) {
|
||||||
|
error("No version provided for second mapping step!")
|
||||||
|
}
|
||||||
|
return@provider twoStepMappings(conf.first!!, conf.second!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tinyMappings(action: Action<NameConfiguration>): Provider<MappingBundle> {
|
||||||
|
mappingsName = "custom/tiny"
|
||||||
|
return project.provider {
|
||||||
|
val conf = objects.newInstance(NameConfiguration::class.java)
|
||||||
|
action.execute(conf)
|
||||||
|
if (conf.name == null) {
|
||||||
|
error("No maven coordinate provided for tiny mappings!")
|
||||||
|
}
|
||||||
|
return@provider tinyMappings(conf.name!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mappings(action: Action<MappingBundle>): Provider<MappingBundle> {
|
||||||
|
mappingsName = "custom"
|
||||||
|
return project.provider {
|
||||||
|
val bundle = MappingBundle()
|
||||||
|
action.execute(bundle)
|
||||||
|
return@provider bundle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun layer(action: Action<LayerConfiguration>): Provider<MappingBundle> {
|
||||||
|
return project.provider {
|
||||||
|
val config = objects.newInstance(LayerConfiguration::class.java)
|
||||||
|
action.execute(config)
|
||||||
|
|
||||||
|
return@provider MappingBundle.merge(*config.layers.map { it.get() }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun twoStepMappings(intermediary: String, mappings: String): MappingBundle {
|
||||||
|
return MappingBundle.merge(tinyMappings(intermediary), tinyMappings(mappings))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tinyMappings(name: String): MappingBundle {
|
||||||
|
mavenMappings(name).let { path ->
|
||||||
|
FileSystems.newFileSystem(path).use {
|
||||||
|
return TinyV2Parser.parse(it.getPath("mappings/mappings.tiny").readText(StandardCharsets.UTF_8))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UnstableApiUsage")
|
||||||
|
private fun mavenMappings(name: String): Path {
|
||||||
|
|
||||||
|
val configuration = project.configurations.create("mappings") {
|
||||||
|
it.isCanBeResolved = true
|
||||||
|
it.isCanBeDeclared = true
|
||||||
|
}
|
||||||
|
configuration.dependencies.add(project.dependencies.create(name))
|
||||||
|
val path = configuration.resolve().first().toPath()
|
||||||
|
project.configurations.remove(configuration)
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TwoStepMappingsConfiguration {
|
||||||
|
var first: String? = null
|
||||||
|
var second: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ParchmentConfiguration {
|
||||||
|
var gameVersion: String? = null
|
||||||
|
var version: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LayerConfiguration {
|
||||||
|
internal val layers = mutableListOf<Provider<MappingBundle>>()
|
||||||
|
fun add(mappings: Provider<MappingBundle>): LayerConfiguration {
|
||||||
|
layers.add(mappings)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NameConfiguration {
|
||||||
|
var name: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class VersionConfiguration {
|
||||||
|
var version: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
package dev.frogmc.phytotelma.ext
|
package dev.frogmc.phytotelma.ext
|
||||||
|
|
||||||
import org.gradle.api.provider.Provider
|
import org.gradle.api.Action
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
interface PhytotelmaGradleExtension {
|
interface PhytotelmaGradleExtension {
|
||||||
|
|
||||||
fun minecraft(version: String, parchmentGameVersion: String? = null, parchmentVersion: String? = null)
|
fun minecraft(action: Action<MinecraftConfiguration>)
|
||||||
|
|
||||||
fun minecraft(version: Provider<String>, parchmentGameVersion: Provider<String>? = null, parchmentVersion: Provider<String>? = null) {
|
fun loader(action: Action<VersionConfiguration>)
|
||||||
minecraft(version.get(), parchmentGameVersion?.get(), parchmentVersion?.get())
|
|
||||||
}
|
fun froglib(action: Action<VersionConfiguration>)
|
||||||
|
|
||||||
fun loader(version: String)
|
|
||||||
|
|
||||||
fun loader(version: Provider<String>) {
|
|
||||||
loader(version.get())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun froglib(version: String)
|
|
||||||
|
|
||||||
fun froglib(version: Provider<String>) {
|
|
||||||
froglib(version.get())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,200 @@
|
||||||
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.common.Env
|
||||||
|
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.vineflower.FrogJavadocProvider
|
||||||
import dev.frogmc.thyroxine.Thyroxine
|
import dev.frogmc.thyroxine.Thyroxine
|
||||||
import dev.frogmc.thyroxine.parser.ProguardParser
|
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
||||||
import dev.frogmc.thyroxine.provider.MojmapProvider
|
import org.gradle.api.Action
|
||||||
import dev.frogmc.thyroxine.provider.ParchmentProvider
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
|
import org.jetbrains.java.decompiler.main.Fernflower
|
||||||
|
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger
|
||||||
|
import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver
|
||||||
|
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences
|
||||||
|
import java.io.PrintStream
|
||||||
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.exists
|
||||||
import kotlin.io.path.notExists
|
import kotlin.io.path.notExists
|
||||||
|
|
||||||
abstract class PhytotelmaGradleExtensionImpl : PhytotelmaGradleExtension {
|
abstract class PhytotelmaGradleExtensionImpl @Inject constructor(private val project: Project, private val objects: ObjectFactory) : PhytotelmaGradleExtension {
|
||||||
|
|
||||||
@Inject
|
private fun setupTasks() {
|
||||||
abstract fun getProject(): Project
|
project.tasks.register("genSources") {task ->
|
||||||
|
task.group = Constants.TASK_GROUP
|
||||||
|
task.actions.add {
|
||||||
|
val projectData = ProjectStorage.get(it.project)
|
||||||
|
val fileName = projectData.remappedGameJarPath!!.fileName.toString()
|
||||||
|
val output =
|
||||||
|
projectData.remappedGameJarPath!!.resolveSibling(
|
||||||
|
fileName.substring(
|
||||||
|
0,
|
||||||
|
fileName.lastIndexOf("-")
|
||||||
|
) + "-sources.jar"
|
||||||
|
)
|
||||||
|
if (output.exists()) {
|
||||||
|
println("Output $output already exists, deleting!")
|
||||||
|
output.deleteExisting()
|
||||||
|
}
|
||||||
|
val options = mutableMapOf<String, Any>()
|
||||||
|
println("Preparing Parchment...")
|
||||||
|
val javadocs = ProjectStorage.get(project).mappings!!
|
||||||
|
options[IFabricJavadocProvider.PROPERTY_NAME] = FrogJavadocProvider(javadocs.docsForNamespace(Constants.DEV_NAMESPACE))
|
||||||
|
|
||||||
|
println("Decompiling...")
|
||||||
|
val logger = PrintStreamLogger(PrintStream(System.out))
|
||||||
|
options.putAll(
|
||||||
|
mapOf(
|
||||||
|
IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES to "1",
|
||||||
|
IFernflowerPreferences.BYTECODE_SOURCE_MAPPING to "1",
|
||||||
|
IFernflowerPreferences.REMOVE_SYNTHETIC to "1",
|
||||||
|
IFernflowerPreferences.LOG_LEVEL to "error",
|
||||||
|
IFernflowerPreferences.THREADS to Runtime.getRuntime().availableProcessors().toString(),
|
||||||
|
IFernflowerPreferences.INDENT_STRING to "\t"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val decomp = Fernflower(
|
||||||
|
SingleFileSaver(output.toFile()),
|
||||||
|
options, logger
|
||||||
|
)
|
||||||
|
decomp.addSource(projectData.remappedGameJarPath!!.toFile())
|
||||||
|
|
||||||
|
decomp.decompileContext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.tasks.register(Constants.GEN_RUN_CONFIGS_TASK) {task ->
|
||||||
|
task.group = Constants.TASK_GROUP
|
||||||
|
task.doFirst {
|
||||||
|
RunConfigGenerator.generate(project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.tasks.register(Constants.RUN_CLIENT_TASK, RunGameTask::class.java, Env.CLIENT)
|
||||||
|
project.tasks.register(Constants.RUNT_SERVER_TASK, RunGameTask::class.java, Env.SERVER)
|
||||||
|
|
||||||
|
project.tasks.register(Constants.DOWNLOAD_ASSETS_TASK) { task ->
|
||||||
|
task.group = Constants.TASK_GROUP
|
||||||
|
task.doFirst {
|
||||||
|
AssetDownloader.download(it.project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
project.tasks.getByName("build").dependsOn(buildTask)
|
||||||
|
|
||||||
|
project.tasks.register(Constants.UPDATE_AW_TASK) { task ->
|
||||||
|
task.group = Constants.TASK_GROUP
|
||||||
|
task.actions.addFirst {
|
||||||
|
AccessWidener.apply(project, ProjectStorage.get(it.project).remappedGameJarPath!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun minecraft(action: Action<MinecraftConfiguration>) {
|
||||||
|
println("Setting up Tasks...")
|
||||||
|
setupTasks()
|
||||||
|
println("Setting up Minecraft...")
|
||||||
|
val mcConf = objects.newInstance(MinecraftConfiguration::class.java)
|
||||||
|
action.execute(mcConf)
|
||||||
|
|
||||||
|
if (mcConf.version == null) {
|
||||||
|
error("No Minecraft version provided!")
|
||||||
|
}
|
||||||
|
val version = mcConf.version!!
|
||||||
|
|
||||||
|
if (VersionChecker.validateVersion(version, offlineMode = project.gradle.startParameter.isOffline)) {
|
||||||
|
|
||||||
|
val projectData = ProjectStorage.get(project)
|
||||||
|
projectData.minecraftVersion = version
|
||||||
|
|
||||||
|
val mappings = mcConf.mappings.get()
|
||||||
|
println("Using mappings: "+mcConf.mappingsName())
|
||||||
|
projectData.mappings = mappings
|
||||||
|
|
||||||
|
val clientJar = VersionChecker.downloadClient(project, version)
|
||||||
|
val remappedJar =
|
||||||
|
projectData.localCacheDir!!.resolve("net/minecraft/client/$version/client-$version-remapped.jar")
|
||||||
|
remappedJar.createParentDirectories()
|
||||||
|
projectData.remappedGameJarPath = remappedJar
|
||||||
|
println("Time to setup Minecraft!")
|
||||||
|
val applyAW = AccessWidener.needsUpdate(project)
|
||||||
|
if (remappedJar.notExists() || applyAW || mcConf.mappingsName() != projectData.mappingsName) {
|
||||||
|
projectData.mappingsName = mcConf.mappingsName()
|
||||||
|
println("Remapping the game...")
|
||||||
|
Thyroxine.remap(mappings.forNamespaces("official", "named"),
|
||||||
|
clientJar, remappedJar, true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
project.dependencies.add(
|
||||||
|
Constants.MINECRAFT_CONFIGURATION,
|
||||||
|
"net.minecrell:terminalconsoleappender:1.2.0"
|
||||||
|
)
|
||||||
|
VersionChecker.getDependencies(version) {
|
||||||
|
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, it)
|
||||||
|
}
|
||||||
|
VersionChecker.savePomFile(version, remappedJar.parent)
|
||||||
|
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, "net.minecraft:client:$version:remapped")
|
||||||
|
|
||||||
|
println("Generating run configurations...")
|
||||||
|
RunConfigGenerator.generate(project)
|
||||||
|
|
||||||
|
if (applyAW) {
|
||||||
|
project.afterEvaluate {
|
||||||
|
println("Applying AccessWideners...")
|
||||||
|
AccessWidener.apply(project, remappedJar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loader(action: Action<VersionConfiguration>) {
|
||||||
|
val conf = objects.newInstance(VersionConfiguration::class.java)
|
||||||
|
action.execute(conf)
|
||||||
|
if (conf.version == null) {
|
||||||
|
error("No loader version provided!")
|
||||||
|
}
|
||||||
|
project.dependencies.add("implementation", "dev.frogmc:frogloader:${conf.version!!}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun froglib(action: Action<VersionConfiguration>) {
|
||||||
|
val conf = objects.newInstance(VersionConfiguration::class.java)
|
||||||
|
action.execute(conf)
|
||||||
|
if (conf.version == null) {
|
||||||
|
error("No froglib version provided!")
|
||||||
|
}
|
||||||
|
project.dependencies.add("implementation", "dev.frogmc:froglib:${conf.version!!}")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*override fun minecraft(version: String, parchmentGameVersion: String?, parchmentVersion: String?) {
|
||||||
|
|
||||||
override fun minecraft(version: String, parchmentGameVersion: String?, parchmentVersion: String?) {
|
|
||||||
if (VersionChecker.validateVersion(version, offlineMode = getProject().gradle.startParameter.isOffline)) {
|
if (VersionChecker.validateVersion(version, offlineMode = getProject().gradle.startParameter.isOffline)) {
|
||||||
println("Setting up Minecraft...")
|
println("Setting up Minecraft...")
|
||||||
val parchmentGameVer = parchmentGameVersion?: version
|
val parchmentGameVer = parchmentGameVersion?: version
|
||||||
|
@ -41,12 +215,10 @@ abstract class PhytotelmaGradleExtensionImpl : PhytotelmaGradleExtension {
|
||||||
if (remappedJar.notExists() || applyAW) {
|
if (remappedJar.notExists() || applyAW) {
|
||||||
println("Remapping the game...")
|
println("Remapping the game...")
|
||||||
val data = kotlin.runCatching {
|
val data = kotlin.runCatching {
|
||||||
ProguardParser.read(
|
|
||||||
MojmapProvider.get(
|
MojmapProvider.get(
|
||||||
version,
|
version,
|
||||||
clientJar.resolveSibling("client-$version.txt")
|
clientJar.resolveSibling("client-$version.txt")
|
||||||
).orElseThrow()
|
).orElseThrow().reverse()
|
||||||
).reverse()
|
|
||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
val paramMappings = if (parchment.isNotEmpty()) kotlin.runCatching {
|
val paramMappings = if (parchment.isNotEmpty()) kotlin.runCatching {
|
||||||
ParchmentProvider.getParchment(
|
ParchmentProvider.getParchment(
|
||||||
|
@ -62,7 +234,7 @@ abstract class PhytotelmaGradleExtensionImpl : PhytotelmaGradleExtension {
|
||||||
println("Parameter mappings will not be present as the version $parchmentVersion for minecraft version $parchmentGameVer could not be found")
|
println("Parameter mappings will not be present as the version $parchmentVersion for minecraft version $parchmentGameVer could not be found")
|
||||||
}
|
}
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
Thyroxine.remap(data, clientJar, remappedJar, true, paramMappings)
|
Thyroxine.remap(data.forNamespaces("official", "named"), clientJar, remappedJar, true, true)
|
||||||
} else {
|
} else {
|
||||||
error("Failed to remap the game as no mojmap version was found for game version $version. Other mapping formats may be implemented in the future.")
|
error("Failed to remap the game as no mojmap version was found for game version $version. Other mapping formats may be implemented in the future.")
|
||||||
}
|
}
|
||||||
|
@ -101,5 +273,5 @@ abstract class PhytotelmaGradleExtensionImpl : PhytotelmaGradleExtension {
|
||||||
|
|
||||||
override fun froglib(version: String) {
|
override fun froglib(version: String) {
|
||||||
getProject().dependencies.add("implementation", "dev.frogmc:froglib:$version")
|
getProject().dependencies.add("implementation", "dev.frogmc:froglib:$version")
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package dev.frogmc.phytotelma.vineflower
|
||||||
|
|
||||||
|
import dev.frogmc.thyroxine.api.data.DocumentationData
|
||||||
|
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
||||||
|
import org.jetbrains.java.decompiler.struct.StructClass
|
||||||
|
import org.jetbrains.java.decompiler.struct.StructField
|
||||||
|
import org.jetbrains.java.decompiler.struct.StructMethod
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
|
class FrogJavadocProvider(data: DocumentationData) : IFabricJavadocProvider {
|
||||||
|
|
||||||
|
private val classMap = data.classes.stream().collect(Collectors.toMap({ it.name() }, { it }))
|
||||||
|
|
||||||
|
override fun getClassDoc(structClass: StructClass): String? {
|
||||||
|
return classMap[structClass.qualifiedName]?.javadoc?.joinToString("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFieldDoc(structClass: StructClass, structField: StructField): String? {
|
||||||
|
return classMap[structClass.qualifiedName]
|
||||||
|
?.getField(structField.name, structField.descriptor)
|
||||||
|
?.orElse(null)?.javadoc?.joinToString("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMethodDoc(structClass: StructClass, structMethod: StructMethod): String? {
|
||||||
|
return classMap[structClass.qualifiedName]?.getMethod(structMethod.name, structMethod.descriptor)
|
||||||
|
?.orElse(null)?.javadoc?.joinToString("\n")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
package dev.frogmc.phytotelma.vineflower
|
|
||||||
|
|
||||||
import dev.frogmc.thyroxine.api.data.Parchment
|
|
||||||
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
|
||||||
import org.jetbrains.java.decompiler.struct.StructClass
|
|
||||||
import org.jetbrains.java.decompiler.struct.StructField
|
|
||||||
import org.jetbrains.java.decompiler.struct.StructMethod
|
|
||||||
|
|
||||||
class ParchmentJavadocProvider(private val parchment: Parchment) : IFabricJavadocProvider {
|
|
||||||
override fun getClassDoc(structClass: StructClass): String? {
|
|
||||||
return parchment.getClass(structClass.qualifiedName).orElse(null)?.javadoc?.joinToString("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFieldDoc(structClass: StructClass, structField: StructField): String? {
|
|
||||||
return parchment.getClass(structClass.qualifiedName)
|
|
||||||
.flatMap { it.getField(structField.name, structField.descriptor) }
|
|
||||||
.orElse(null)?.javadoc?.joinToString("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getMethodDoc(structClass: StructClass, structMethod: StructMethod): String? {
|
|
||||||
return parchment.getClass(structClass.qualifiedName)
|
|
||||||
.flatMap { it.getMethod(structMethod.name, structMethod.descriptor) }
|
|
||||||
.orElse(null)?.javadoc?.joinToString("\n")
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue