Remapped Spigot now compiles with no patches
This commit is contained in:
parent
20d3976520
commit
1b9252da0d
22 changed files with 613 additions and 151 deletions
|
@ -14,6 +14,7 @@ group = "io.papermc.paperweight"
|
|||
version = "1.0.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
maven("https://files.minecraftforge.net/maven/")
|
||||
|
@ -30,7 +31,7 @@ dependencies {
|
|||
implementation("com.github.salomonbrys.kotson:kotson:2.5.0")
|
||||
|
||||
// Cadix
|
||||
implementation("org.cadixdev:lorenz:0.5.3")
|
||||
implementation("org.cadixdev:lorenz:0.5.4-SNAPSHOT")
|
||||
implementation("org.cadixdev:lorenz-asm:0.5.3")
|
||||
implementation("org.cadixdev:mercury:0.1.0-SNAPSHOT")
|
||||
implementation("org.cadixdev:atlas:0.2.0")
|
||||
|
|
|
@ -26,19 +26,21 @@
|
|||
package io.papermc.paperweight
|
||||
|
||||
import io.papermc.paperweight.ext.PaperweightExtension
|
||||
import io.papermc.paperweight.tasks.AddMissingSpigotClassMappings
|
||||
import io.papermc.paperweight.tasks.ApplyAccessTransform
|
||||
import io.papermc.paperweight.tasks.ApplyDiffPatches
|
||||
import io.papermc.paperweight.tasks.ApplyGitPatches
|
||||
import io.papermc.paperweight.tasks.DecompileVanillaJar
|
||||
import io.papermc.paperweight.tasks.DownloadServerJar
|
||||
import io.papermc.paperweight.tasks.ExtractMcpData
|
||||
import io.papermc.paperweight.tasks.ExtractMcpMappings
|
||||
import io.papermc.paperweight.tasks.FilterExcludes
|
||||
import io.papermc.paperweight.tasks.GatherBuildData
|
||||
import io.papermc.paperweight.tasks.GenerateSpigotSrgs
|
||||
import io.papermc.paperweight.tasks.GenerateSrgs
|
||||
import io.papermc.paperweight.tasks.GetRemoteJsons
|
||||
import io.papermc.paperweight.tasks.PatchMcpCsv
|
||||
import io.papermc.paperweight.tasks.RemapSources
|
||||
import io.papermc.paperweight.tasks.RemapVanillaJarSpigot
|
||||
import io.papermc.paperweight.tasks.RemapVanillaJarSrg
|
||||
import io.papermc.paperweight.tasks.RunForgeFlower
|
||||
import io.papermc.paperweight.tasks.RunMcInjector
|
||||
|
@ -46,19 +48,17 @@ import io.papermc.paperweight.tasks.SetupMcpDependencies
|
|||
import io.papermc.paperweight.tasks.SetupSpigotDependencies
|
||||
import io.papermc.paperweight.tasks.WriteLibrariesFile
|
||||
import io.papermc.paperweight.util.Constants
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.Git
|
||||
import io.papermc.paperweight.tasks.RemapSrgSources
|
||||
import io.papermc.paperweight.tasks.RemapVanillaJarSpigot
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.ext
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.maven
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import util.BuildDataInfo
|
||||
|
@ -131,7 +131,6 @@ class Paperweight : Plugin<Project> {
|
|||
private fun createTasks(project: Project) {
|
||||
val cache: File = project.cache
|
||||
val extension: PaperweightExtension = project.ext
|
||||
val configs: ConfigurationContainer = project.configurations
|
||||
|
||||
val initGitSubmodules: TaskProvider<Task> = project.tasks.register("initGitSubmodules") {
|
||||
outputs.upToDateWhen { false }
|
||||
|
@ -177,9 +176,10 @@ class Paperweight : Plugin<Project> {
|
|||
}
|
||||
|
||||
val generateSrgs: TaskProvider<GenerateSrgs> = project.tasks.register<GenerateSrgs>("generateSrgs") {
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
methodsCsv.set(mcpRewrites.flatMap { it.paperMethodCsv })
|
||||
fieldsCsv.set(mcpRewrites.flatMap { it.paperFieldCsv })
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
extraNotchSrgMappings.set(extension.paper.extraNotchSrgMappings)
|
||||
|
||||
notchToSrg.set(cache.resolve(Constants.NOTCH_TO_SRG))
|
||||
notchToMcp.set(cache.resolve(Constants.NOTCH_TO_MCP))
|
||||
|
@ -189,12 +189,20 @@ class Paperweight : Plugin<Project> {
|
|||
mcpToSrg.set(cache.resolve(Constants.MCP_TO_SRG))
|
||||
}
|
||||
|
||||
val addMissingSpigotClassMappings: TaskProvider<AddMissingSpigotClassMappings> = project.tasks.register<AddMissingSpigotClassMappings>("addMissingSpigotClassMappings") {
|
||||
classSrg.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings }))
|
||||
memberSrg.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.memberMappings }))
|
||||
missingClassEntriesSrg.set(extension.paper.missingClassEntriesSrgFile)
|
||||
missingMemberEntriesSrg.set(extension.paper.missingMemberEntriesSrgFile)
|
||||
}
|
||||
|
||||
val generateSpigotSrgs: TaskProvider<GenerateSpigotSrgs> = project.tasks.register<GenerateSpigotSrgs>("generateSpigotSrgs") {
|
||||
notchToSrg.set(generateSrgs.flatMap { it.notchToSrg })
|
||||
srgToMcp.set(generateSrgs.flatMap { it.srgToMcp })
|
||||
classMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings }))
|
||||
memberMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.memberMappings }))
|
||||
classMappings.set(addMissingSpigotClassMappings.flatMap { it.outputClassSrg })
|
||||
memberMappings.set(addMissingSpigotClassMappings.flatMap { it.outputMemberSrg })
|
||||
packageMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.packageMappings }))
|
||||
extraSpigotSrgMappings.set(extension.paper.extraSpigotSrgMappings)
|
||||
|
||||
spigotToSrg.set(cache.resolve(Constants.SPIGOT_TO_SRG))
|
||||
spigotToMcp.set(cache.resolve(Constants.SPIGOT_TO_MCP))
|
||||
|
@ -223,7 +231,6 @@ class Paperweight : Plugin<Project> {
|
|||
|
||||
val remapVanillaJar: TaskProvider<RemapVanillaJarSpigot> = project.tasks.register<RemapVanillaJarSpigot>("remapVanillaJar") {
|
||||
inputJar.set(project.layout.file(filterVanillaJar.map { it.outputs.files.singleFile }))
|
||||
|
||||
classMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings }))
|
||||
memberMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.memberMappings }))
|
||||
packageMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.packageMappings }))
|
||||
|
@ -239,8 +246,13 @@ class Paperweight : Plugin<Project> {
|
|||
finalMapCommand.set(buildDataInfo.map { it.finalMapCommand })
|
||||
}
|
||||
|
||||
val removeSpigotExcludes: TaskProvider<FilterExcludes> = project.tasks.register<FilterExcludes>("removeSpigotExcludes") {
|
||||
inputZip.set(remapVanillaJar.flatMap { it.outputJar })
|
||||
excludesFile.set(extension.craftBukkit.excludesFile)
|
||||
}
|
||||
|
||||
val decompileVanillaJarSpigot: TaskProvider<DecompileVanillaJar> = project.tasks.register<DecompileVanillaJar>("decompileVanillaJarSpigot") {
|
||||
inputJar.set(remapVanillaJar.flatMap { it.outputJar })
|
||||
inputJar.set(removeSpigotExcludes.flatMap { it.outputZip })
|
||||
fernFlowerJar.set(extension.craftBukkit.fernFlowerJar)
|
||||
decompileCommand.set(buildDataInfo.map { it.decompileCommand })
|
||||
}
|
||||
|
@ -283,23 +295,28 @@ class Paperweight : Plugin<Project> {
|
|||
configurationName.set(Constants.SPIGOT_DEP_CONFIG)
|
||||
}
|
||||
|
||||
val remapVanillaJarSrg: TaskProvider<RemapVanillaJarSrg> = project.tasks.register<RemapVanillaJarSrg>("remapVanillaJarSrg") {
|
||||
inputJar.set(project.layout.file(filterVanillaJar.map { it.outputs.files.singleFile }))
|
||||
mappings.set(generateSrgs.flatMap { it.notchToSrg })
|
||||
val remapSpigotJarSrg: TaskProvider<RemapVanillaJarSrg> = project.tasks.register<RemapVanillaJarSrg>("remapSpigotJarSrg") {
|
||||
// Basing off of the Spigot jar lets us inherit the AT modifications Spigot does before decompile
|
||||
inputJar.set(remapVanillaJar.flatMap { it.outputJar })
|
||||
mappings.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
}
|
||||
|
||||
val remapSpigotSources: TaskProvider<RemapSources> = project.tasks.register<RemapSources>("remapSpigotSources") {
|
||||
dependsOn(setupSpigotDependencies)
|
||||
spigotServerDir.set(patchSpigotServer.flatMap { it.outputDir })
|
||||
spigotApiDir.set(patchSpigotApi.flatMap { it.outputDir })
|
||||
spigotToSrg.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
mappings.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
vanillaJar.set(downloadServerJar.flatMap { it.outputJar })
|
||||
vanillaRemappedSpigotJar.set(remapVanillaJar.flatMap { it.outputJar })
|
||||
vanillaRemappedSrgJar.set(remapVanillaJarSrg.flatMap { it.outputJar })
|
||||
vanillaRemappedSpigotJar.set(removeSpigotExcludes.flatMap { it.outputZip })
|
||||
vanillaRemappedSrgJar.set(remapSpigotJarSrg.flatMap { it.outputJar })
|
||||
configuration.set(setupSpigotDependencies.flatMap { it.configurationName })
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
}
|
||||
|
||||
generatedAt.set(cache.resolve(paperTaskOutput("at")))
|
||||
val fixVanillaJarAccess: TaskProvider<ApplyAccessTransform> = project.tasks.register<ApplyAccessTransform>("fixVanillaJarAccess") {
|
||||
inputJar.set(remapSpigotJarSrg.flatMap { it.outputJar })
|
||||
atFile.set(remapSpigotSources.flatMap { it.generatedAt })
|
||||
mapping.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
}
|
||||
|
||||
val remapSrgSourcesSpigot: TaskProvider<RemapSrgSources> = project.tasks.register<RemapSrgSources>("remapSrgSourcesSpigot") {
|
||||
|
@ -312,12 +329,13 @@ class Paperweight : Plugin<Project> {
|
|||
val injectVanillaJarForge: TaskProvider<RunMcInjector> = project.tasks.register<RunMcInjector>("injectVanillaJarForge") {
|
||||
dependsOn(setupMcpDependencies)
|
||||
configuration.set(setupMcpDependencies.flatMap { it.mcInjectorConfig })
|
||||
inputJar.set(remapVanillaJarSrg.flatMap { it.outputJar })
|
||||
inputJar.set(remapSpigotJarSrg.flatMap { it.outputJar })
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
}
|
||||
|
||||
val writeLibrariesFile: TaskProvider<WriteLibrariesFile> = project.tasks.register<WriteLibrariesFile>("writeLibrariesFile") {
|
||||
inputFiles.set(getRemoteJsons.flatMap { it.config.map { conf -> configs[conf].resolve() } })
|
||||
dependsOn(getRemoteJsons)
|
||||
config.set(getRemoteJsons.flatMap { it.config })
|
||||
}
|
||||
|
||||
val decompileVanillaJarForge: TaskProvider<RunForgeFlower> = project.tasks.register<RunForgeFlower>("decompileVanillaJarForge") {
|
||||
|
|
|
@ -32,6 +32,7 @@ open class CraftBukkitExtension(project: Project) {
|
|||
var craftBukkitDir: DirectoryProperty = project.dirWithDefault("work/CraftBukkit")
|
||||
var patchDir: DirectoryProperty = project.dirWithDefault("work/CraftBukkit/nms-patches")
|
||||
var mappingsDir: DirectoryProperty = project.dirWithDefault("work/BuildData/mappings")
|
||||
val excludesFile: RegularFileProperty = project.fileWithDefault("work/BuildData/mappings/bukkit-1.16.1.exclude")
|
||||
var buildDataInfo: RegularFileProperty = project.fileWithDefault("work/BuildData/info.json")
|
||||
var fernFlowerJar: RegularFileProperty = project.fileWithDefault("work/BuildData/bin/fernflower.jar")
|
||||
var specialSourceJar: RegularFileProperty = project.fileWithDefault("work/BuildData/bin/SpecialSource.jar")
|
||||
|
|
|
@ -35,6 +35,10 @@ open class PaperExtension(project: Project) {
|
|||
val paperServerDir: Property<String> = project.objects.property<String>().convention("Paper-Server")
|
||||
|
||||
val mcpRewritesFile: RegularFileProperty = project.fileWithDefault("mcp/mcp-rewrites.txt")
|
||||
val missingClassEntriesSrgFile: RegularFileProperty = project.fileWithDefault("mcp/missing-spigot-class-mappings.csrg")
|
||||
val missingMemberEntriesSrgFile: RegularFileProperty = project.fileWithDefault("mcp/missing-spigot-member-mappings.csrg")
|
||||
val extraNotchSrgMappings: RegularFileProperty = project.fileWithDefault("mcp/extra-notch-srg.tsrg")
|
||||
val extraSpigotSrgMappings: RegularFileProperty = project.fileWithDefault("mcp/extra-spigot-srg.tsrg")
|
||||
val preMapSrgFile: RegularFileProperty = project.fileWithDefault("mcp/paper.srg")
|
||||
val removeListFile: RegularFileProperty = project.fileWithDefault("mcp/remove-list.txt")
|
||||
val memberMoveListFile: RegularFileProperty = project.fileWithDefault("mcp/member-moves.txt")
|
||||
|
|
48
src/main/kotlin/tasks/AddMissingSpigotClassMappings.kt
Normal file
48
src/main/kotlin/tasks/AddMissingSpigotClassMappings.kt
Normal file
|
@ -0,0 +1,48 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.File
|
||||
|
||||
open class AddMissingSpigotClassMappings : DefaultTask() {
|
||||
|
||||
@InputFile
|
||||
val classSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val memberSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val missingClassEntriesSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val missingMemberEntriesSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val outputClassSrg: RegularFileProperty = defaultOutput("class.csrg")
|
||||
@OutputFile
|
||||
val outputMemberSrg: RegularFileProperty = defaultOutput("member.csrg")
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
addLines(classSrg.file, missingClassEntriesSrg.file, outputClassSrg.file)
|
||||
addLines(memberSrg.file, missingMemberEntriesSrg.file, outputMemberSrg.file)
|
||||
}
|
||||
|
||||
private fun addLines(inFile: File, appendFile: File, outputFile: File) {
|
||||
val lines = mutableListOf<String>()
|
||||
inFile.bufferedReader().use { reader ->
|
||||
lines.addAll(reader.readLines())
|
||||
}
|
||||
appendFile.bufferedReader().use { reader ->
|
||||
lines.addAll(reader.readLines())
|
||||
}
|
||||
lines.sort()
|
||||
outputFile.bufferedWriter().use { writer ->
|
||||
lines.forEach(writer::appendln)
|
||||
}
|
||||
}
|
||||
}
|
137
src/main/kotlin/tasks/ApplyAccessTransform.kt
Normal file
137
src/main/kotlin/tasks/ApplyAccessTransform.kt
Normal file
|
@ -0,0 +1,137 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.orNull
|
||||
import org.cadixdev.at.AccessChange
|
||||
import org.cadixdev.at.AccessTransform
|
||||
import org.cadixdev.at.AccessTransformSet
|
||||
import org.cadixdev.at.ModifierChange
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.cadixdev.atlas.Atlas
|
||||
import org.cadixdev.bombe.jar.JarClassEntry
|
||||
import org.cadixdev.bombe.jar.JarEntryTransformer
|
||||
import org.cadixdev.bombe.type.signature.MethodSignature
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.objectweb.asm.ClassReader
|
||||
import org.objectweb.asm.ClassVisitor
|
||||
import org.objectweb.asm.ClassWriter
|
||||
import org.objectweb.asm.FieldVisitor
|
||||
import org.objectweb.asm.MethodVisitor
|
||||
import org.objectweb.asm.Opcodes
|
||||
|
||||
open class ApplyAccessTransform : DefaultTask() {
|
||||
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val atFile: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val mapping: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
ensureParentExists(outputJar.file)
|
||||
ensureDeleted(outputJar.file)
|
||||
|
||||
val at = AccessTransformFormats.FML.read(atFile.file.toPath())
|
||||
val mappings = MappingFormats.TSRG.createReader(mapping.file.toPath()).use { it.read() }
|
||||
val remappedAt = at.remap(mappings)
|
||||
|
||||
Atlas().apply {
|
||||
install {
|
||||
AtJarEntryTransformer(remappedAt)
|
||||
}
|
||||
run(inputJar.file.toPath(), outputJar.file.toPath())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AtJarEntryTransformer(private val at: AccessTransformSet) : JarEntryTransformer {
|
||||
override fun transform(entry: JarClassEntry): JarClassEntry {
|
||||
val reader = ClassReader(entry.contents)
|
||||
val writer = ClassWriter(reader, 0)
|
||||
reader.accept(AccessTransformerVisitor(at, writer), 0)
|
||||
return JarClassEntry(entry.name, entry.time, writer.toByteArray())
|
||||
}
|
||||
}
|
||||
|
||||
class AccessTransformerVisitor(
|
||||
private val at: AccessTransformSet,
|
||||
writer: ClassWriter
|
||||
) : ClassVisitor(Opcodes.ASM7, writer) {
|
||||
|
||||
var classTransform: AccessTransformSet.Class? = null
|
||||
|
||||
override fun visit(
|
||||
version: Int,
|
||||
access: Int,
|
||||
name: String,
|
||||
signature: String?,
|
||||
superName: String?,
|
||||
interfaces: Array<out String>?
|
||||
) {
|
||||
classTransform = at.getClass(name).orNull
|
||||
super.visit(version, classTransform?.get().apply(access), name, signature, superName, interfaces)
|
||||
}
|
||||
|
||||
override fun visitField(
|
||||
access: Int,
|
||||
name: String,
|
||||
descriptor: String,
|
||||
signature: String?,
|
||||
value: Any?
|
||||
): FieldVisitor {
|
||||
return super.visitField(classTransform?.getField(name).apply(access), name, descriptor, signature, value)
|
||||
}
|
||||
|
||||
override fun visitMethod(
|
||||
access: Int,
|
||||
name: String,
|
||||
descriptor: String,
|
||||
signature: String?,
|
||||
exceptions: Array<out String>?
|
||||
): MethodVisitor {
|
||||
val newAccess = classTransform?.getMethod(MethodSignature.of(name, descriptor)).apply(access)
|
||||
return super.visitMethod(newAccess, name, descriptor, signature, exceptions)
|
||||
}
|
||||
|
||||
override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) {
|
||||
super.visitInnerClass(name, outerName, innerName, at.getClass(name).orNull?.get().apply(access))
|
||||
}
|
||||
}
|
||||
|
||||
private const val RESET_ACCESS: Int = (Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED).inv()
|
||||
fun AccessTransform?.apply(currentModifier: Int): Int {
|
||||
if (this == null) {
|
||||
return currentModifier
|
||||
}
|
||||
var value = currentModifier
|
||||
if (this.access != AccessChange.NONE) {
|
||||
value = value and RESET_ACCESS
|
||||
value = value or this.access.modifier
|
||||
}
|
||||
when (this.final) {
|
||||
ModifierChange.REMOVE -> {
|
||||
value = value and Opcodes.ACC_FINAL.inv()
|
||||
}
|
||||
ModifierChange.ADD -> {
|
||||
value = value or Opcodes.ACC_FINAL
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
return value
|
||||
}
|
|
@ -26,9 +26,9 @@ package io.papermc.paperweight.tasks
|
|||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
@ -49,9 +49,7 @@ open class DecompileVanillaJar : DefaultTask() {
|
|||
val decompileCommand: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput())))
|
||||
}
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
|
|
@ -24,11 +24,9 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
@ -48,9 +46,7 @@ open class DownloadServerJar : DefaultTask() {
|
|||
val hash: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput())))
|
||||
}
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.gradle.api.file.DirectoryProperty
|
|||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
|
32
src/main/kotlin/tasks/FilterExcludes.kt
Normal file
32
src/main/kotlin/tasks/FilterExcludes.kt
Normal file
|
@ -0,0 +1,32 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Because Spigot doesn't remap all classes, there are class and package name clashes if we don't do this in the source
|
||||
* remap step. Other than that, we don't need this jar
|
||||
*/
|
||||
open class FilterExcludes : ZippedTask() {
|
||||
|
||||
@InputFile
|
||||
val excludesFile: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
excludesFile.file.useLines { lines ->
|
||||
for (line in lines) {
|
||||
if (line.startsWith('#') || line.isBlank()) {
|
||||
continue
|
||||
}
|
||||
val file = if (line.contains('/')) {
|
||||
rootDir.resolve("$line.class")
|
||||
} else {
|
||||
rootDir.resolve("net/minecraft/server/$line.class")
|
||||
}
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,13 +23,26 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.writeMappings
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.cadixdev.lorenz.merge.DuplicateMergeAction
|
||||
import org.cadixdev.lorenz.merge.DuplicateMergeResult
|
||||
import org.cadixdev.lorenz.merge.MappingSetMerger
|
||||
import org.cadixdev.lorenz.merge.MappingSetMergerHandler
|
||||
import org.cadixdev.lorenz.merge.MergeContext
|
||||
import org.cadixdev.lorenz.model.ClassMapping
|
||||
import org.cadixdev.lorenz.model.FieldMapping
|
||||
import org.cadixdev.lorenz.model.InnerClassMapping
|
||||
import org.cadixdev.lorenz.model.MethodMapping
|
||||
import org.cadixdev.lorenz.model.TopLevelClassMapping
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
open class GenerateSpigotSrgs : DefaultTask() {
|
||||
|
||||
|
@ -43,6 +56,8 @@ open class GenerateSpigotSrgs : DefaultTask() {
|
|||
val memberMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val packageMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val extraSpigotSrgMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val spigotToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
|
@ -59,37 +74,180 @@ open class GenerateSpigotSrgs : DefaultTask() {
|
|||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val classMappingSet = classMappings.asFile.get().reader().use { MappingFormats.CSRG.createReader(it).read() }
|
||||
val memberMappingSet = memberMappings.asFile.get().reader().use { MappingFormats.CSRG.createReader(it).read() }
|
||||
val classMappingSet = MappingFormats.CSRG.createReader(classMappings.file.toPath()).use { it.read() }
|
||||
val memberMappingSet = MappingFormats.CSRG.createReader(memberMappings.file.toPath()).use { it.read() }
|
||||
val mergedMappingSet = MappingSetMerger.create(classMappingSet, memberMappingSet).merge()
|
||||
|
||||
val notchToSpigotSet = classMappingSet.merge(memberMappingSet)
|
||||
|
||||
// Apply the package mappings (Lorenz doesn't currently support this)
|
||||
// Get the new package name
|
||||
val newPackage = packageMappings.asFile.get().readLines()[0].split(Regex("\\s+"))[1]
|
||||
for (topLevelClassMapping in notchToSpigotSet.topLevelClassMappings) {
|
||||
topLevelClassMapping.deobfuscatedName = newPackage + topLevelClassMapping.deobfuscatedName
|
||||
}
|
||||
|
||||
val notchToSrgSet = notchToSrg.asFile.get().reader().use { MappingFormats.TSRG.createReader(it).read() }
|
||||
val srgToMcpSet = srgToMcp.asFile.get().reader().use { MappingFormats.TSRG.createReader(it).read() }
|
||||
// We'll use notch->srg to pick up any classes spigot doesn't map for the package mapping
|
||||
val notchToSrgSet = MappingFormats.TSRG.createReader(notchToSrg.file.toPath()).use { it.read() }
|
||||
|
||||
val srgToSpigotSet = notchToSrgSet.reverse().merge(notchToSpigotSet)
|
||||
val notchToSpigotSet = MappingSetMerger.create(
|
||||
mergedMappingSet,
|
||||
notchToSrgSet,
|
||||
SpigotPackageMergerHandler(newPackage)
|
||||
).merge()
|
||||
|
||||
val mcpToNotchSet = notchToSrgSet.merge(srgToMcpSet).reverse()
|
||||
val mcpToSpigotSet = mcpToNotchSet.merge(notchToSpigotSet)
|
||||
val srgToMcpSet = MappingFormats.TSRG.createReader(srgToMcp.file.toPath()).use { it.read() }
|
||||
|
||||
val spigotToSrgSet = srgToSpigotSet.reverse()
|
||||
val spigotToSrgSet = MappingSetMerger.create(notchToSpigotSet.reverse(), notchToSrgSet).merge()
|
||||
MappingFormats.TSRG.createReader(extraSpigotSrgMappings.file.toPath()).use { it.read(spigotToSrgSet) }
|
||||
|
||||
val mcpToNotchSet = MappingSetMerger.create(notchToSrgSet, srgToMcpSet).merge().reverse()
|
||||
val mcpToSpigotSet = MappingSetMerger.create(mcpToNotchSet, notchToSpigotSet).merge()
|
||||
|
||||
val srgToSpigotSet = spigotToSrgSet.reverse()
|
||||
val spigotToMcpSet = mcpToSpigotSet.reverse()
|
||||
val spigotToNotchSet = notchToSpigotSet.reverse()
|
||||
|
||||
writeMappings(
|
||||
MappingFormats.TSRG,
|
||||
spigotToSrgSet to spigotToSrg.asFile.get(),
|
||||
spigotToMcpSet to spigotToMcp.asFile.get(),
|
||||
spigotToNotchSet to spigotToNotch.asFile.get(),
|
||||
srgToSpigotSet to srgToSpigot.asFile.get(),
|
||||
mcpToSpigotSet to mcpToSpigot.asFile.get(),
|
||||
notchToSpigotSet to notchToSpigot.asFile.get()
|
||||
spigotToSrgSet to spigotToSrg.file,
|
||||
spigotToMcpSet to spigotToMcp.file,
|
||||
spigotToNotchSet to spigotToNotch.file,
|
||||
srgToSpigotSet to srgToSpigot.file,
|
||||
mcpToSpigotSet to mcpToSpigot.file,
|
||||
notchToSpigotSet to notchToSpigot.file
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class SpigotPackageMergerHandler(private val newPackage: String) : MappingSetMergerHandler {
|
||||
|
||||
override fun mergeTopLevelClassMappings(
|
||||
left: TopLevelClassMapping,
|
||||
right: TopLevelClassMapping,
|
||||
target: MappingSet,
|
||||
context: MergeContext
|
||||
): TopLevelClassMapping? {
|
||||
throw IllegalStateException("Unexpectedly merged class: $left")
|
||||
}
|
||||
override fun mergeDuplicateTopLevelClassMappings(
|
||||
left: TopLevelClassMapping,
|
||||
right: TopLevelClassMapping,
|
||||
rightContinuation: TopLevelClassMapping?,
|
||||
target: MappingSet,
|
||||
context: MergeContext
|
||||
): DuplicateMergeResult<TopLevelClassMapping?> {
|
||||
// If both are provided, keep spigot
|
||||
// But don't map members
|
||||
return DuplicateMergeResult(
|
||||
target.createTopLevelClassMapping(left.obfuscatedName, prependPackage(left.deobfuscatedName)),
|
||||
DuplicateMergeAction.MAP_DUPLICATED_MEMBERS
|
||||
)
|
||||
}
|
||||
override fun addLeftTopLevelClassMapping(
|
||||
left: TopLevelClassMapping,
|
||||
target: MappingSet,
|
||||
context: MergeContext
|
||||
): TopLevelClassMapping? {
|
||||
return target.createTopLevelClassMapping(left.obfuscatedName, prependPackage(left.deobfuscatedName))
|
||||
}
|
||||
override fun addRightTopLevelClassMapping(
|
||||
right: TopLevelClassMapping,
|
||||
target: MappingSet,
|
||||
context: MergeContext
|
||||
): TopLevelClassMapping? {
|
||||
// We know we don't need client mappings
|
||||
return if (right.deobfuscatedName.contains("/client/")) {
|
||||
null
|
||||
} else {
|
||||
target.createTopLevelClassMapping(right.obfuscatedName, prependPackage(right.obfuscatedName))
|
||||
}
|
||||
}
|
||||
|
||||
override fun mergeInnerClassMappings(
|
||||
left: InnerClassMapping,
|
||||
right: InnerClassMapping,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): InnerClassMapping? {
|
||||
return target.createInnerClassMapping(left.obfuscatedName, left.deobfuscatedName)
|
||||
}
|
||||
override fun mergeDuplicateInnerClassMappings(
|
||||
left: InnerClassMapping,
|
||||
right: InnerClassMapping,
|
||||
rightContinuation: InnerClassMapping?,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): DuplicateMergeResult<InnerClassMapping?> {
|
||||
return DuplicateMergeResult(
|
||||
target.createInnerClassMapping(left.obfuscatedName, left.deobfuscatedName),
|
||||
DuplicateMergeAction.MAP_DUPLICATED_MEMBERS
|
||||
)
|
||||
}
|
||||
override fun addRightInnerClassMapping(
|
||||
right: InnerClassMapping,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): InnerClassMapping? {
|
||||
// We want to get all of the inner classes from SRG, but not the SRG names
|
||||
return target.createInnerClassMapping(right.obfuscatedName, right.obfuscatedName)
|
||||
}
|
||||
|
||||
override fun mergeFieldMappings(
|
||||
left: FieldMapping,
|
||||
right: FieldMapping,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): FieldMapping? {
|
||||
throw IllegalStateException("Unexpectedly merged field: $left")
|
||||
}
|
||||
override fun mergeDuplicateFieldMappings(
|
||||
left: FieldMapping,
|
||||
right: FieldMapping,
|
||||
rightContinuation: FieldMapping?,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): FieldMapping? {
|
||||
return target.createFieldMapping(left.obfuscatedName, left.deobfuscatedName)
|
||||
}
|
||||
|
||||
override fun mergeMethodMappings(
|
||||
left: MethodMapping,
|
||||
right: MethodMapping,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): MethodMapping? {
|
||||
throw IllegalStateException("Unexpectedly merged method: $left")
|
||||
}
|
||||
override fun mergeDuplicateMethodMappings(
|
||||
left: MethodMapping,
|
||||
right: MethodMapping,
|
||||
rightContinuation: MethodMapping?,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): DuplicateMergeResult<MethodMapping?> {
|
||||
return DuplicateMergeResult(
|
||||
target.createMethodMapping(left.signature, left.deobfuscatedName),
|
||||
// We don't have method parameter mappings to merge anyways
|
||||
DuplicateMergeAction.MAP_NEITHER
|
||||
)
|
||||
}
|
||||
|
||||
// Disable srg member mappings
|
||||
override fun addRightFieldMapping(
|
||||
right: FieldMapping,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): FieldMapping? {
|
||||
return null
|
||||
}
|
||||
override fun addRightMethodMapping(
|
||||
right: MethodMapping,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): MethodMapping? {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun prependPackage(name: String): String {
|
||||
return if (name.contains('/')) {
|
||||
name
|
||||
} else {
|
||||
newPackage + name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,16 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.getCsvReader
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
import io.papermc.paperweight.util.writeMappings
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.cadixdev.lorenz.merge.MappingSetMerger
|
||||
import org.cadixdev.lorenz.model.ClassMapping
|
||||
import org.cadixdev.lorenz.model.InnerClassMapping
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
|
@ -45,6 +48,8 @@ open class GenerateSrgs : DefaultTask() {
|
|||
val methodsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val fieldsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val extraNotchSrgMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val notchToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
|
@ -68,9 +73,8 @@ open class GenerateSrgs : DefaultTask() {
|
|||
val fields = HashMap<String, String>()
|
||||
readCsvs(methods, fields)
|
||||
|
||||
val inSet = inSrg.reader().use {
|
||||
MappingFormats.TSRG.createReader(it).read()
|
||||
}
|
||||
val inSet = MappingFormats.TSRG.createReader(inSrg.toPath()).use { it.read() }
|
||||
MappingFormats.TSRG.createReader(extraNotchSrgMappings.file.toPath()).use { it.read(inSet) }
|
||||
|
||||
ensureParentExists(notchToSrg, notchToMcp, mcpToNotch, mcpToSrg, srgToNotch, srgToMcp)
|
||||
createMappings(inSet, methods, fields)
|
||||
|
@ -90,7 +94,13 @@ open class GenerateSrgs : DefaultTask() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createMappings(notchToSrgSet: MappingSet, methods: Map<String, String>, fields: Map<String, String>) {
|
||||
private fun createMappings(inSet: MappingSet, methods: Map<String, String>, fields: Map<String, String>) {
|
||||
val notchToSrgSet = MappingSet.create()
|
||||
for (mapping in inSet.topLevelClassMappings) {
|
||||
val newMapping = notchToSrgSet.createTopLevelClassMapping(mapping.obfuscatedName, mapping.deobfuscatedName)
|
||||
remapMembers(mapping, newMapping)
|
||||
}
|
||||
|
||||
// We have Notch -> SRG
|
||||
val srgToNotchSet = notchToSrgSet.reverse()
|
||||
|
||||
|
@ -101,7 +111,7 @@ open class GenerateSrgs : DefaultTask() {
|
|||
val srgToMcpSet = MappingSet.create()
|
||||
|
||||
// Create SRG -> MCP from Notch -> SRG and the CSVs
|
||||
for (topLevelClassMapping in notchToSrgSet.topLevelClassMappings) {
|
||||
for (topLevelClassMapping in inSet.topLevelClassMappings) {
|
||||
// MCP and SRG have the same class names
|
||||
val srgToMcpClass = srgToMcpSet.createTopLevelClassMapping(
|
||||
topLevelClassMapping.deobfuscatedName,
|
||||
|
@ -113,7 +123,7 @@ open class GenerateSrgs : DefaultTask() {
|
|||
|
||||
// We have Notch->SRG and SRG->MCP mapping sets now
|
||||
// All other sets can be generated from these two
|
||||
notchToMcpSet = notchToSrgSet.merge(srgToMcpSet)
|
||||
notchToMcpSet = MappingSetMerger.create(notchToSrgSet, srgToMcpSet).merge()
|
||||
mcpToNotchSet = notchToMcpSet.reverse()
|
||||
mcpToSrgSet = srgToMcpSet.reverse()
|
||||
|
||||
|
@ -143,4 +153,27 @@ open class GenerateSrgs : DefaultTask() {
|
|||
mapClass(innerClassMapping, innerOutClass, methods, fields)
|
||||
}
|
||||
}
|
||||
|
||||
private fun remapAnonymousClasses(mapping: InnerClassMapping, target: ClassMapping<*, *>) {
|
||||
val newMapping = if (mapping.obfuscatedName.toIntOrNull() != null) {
|
||||
// This is an anonymous class, keep the index
|
||||
target.createInnerClassMapping(mapping.deobfuscatedName, mapping.deobfuscatedName)
|
||||
} else {
|
||||
target.createInnerClassMapping(mapping.obfuscatedName, mapping.deobfuscatedName)
|
||||
}
|
||||
|
||||
remapMembers(mapping, newMapping)
|
||||
}
|
||||
|
||||
private fun <T : ClassMapping<*, *>> remapMembers(mapping: T, newMapping: T) {
|
||||
for (fieldMapping in mapping.fieldMappings) {
|
||||
newMapping.createFieldMapping(fieldMapping.obfuscatedName, fieldMapping.deobfuscatedName)
|
||||
}
|
||||
for (methodMapping in mapping.methodMappings) {
|
||||
newMapping.createMethodMapping(methodMapping.signature, methodMapping.deobfuscatedName)
|
||||
}
|
||||
for (innerClassMapping in mapping.innerClassMappings) {
|
||||
remapAnonymousClasses(innerClassMapping, newMapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,19 @@ import com.github.salomonbrys.kotson.get
|
|||
import com.github.salomonbrys.kotson.string
|
||||
import com.google.gson.JsonObject
|
||||
import io.papermc.paperweight.util.Constants
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.ext
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.getWithEtag
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import util.MinecraftManifest
|
||||
|
@ -45,6 +51,13 @@ open class GetRemoteJsons : DefaultTask() {
|
|||
@Input
|
||||
val config: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val artifactOutputFile: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider {
|
||||
project.cache.resolve(paperTaskOutput("mc-libraries", "txt"))
|
||||
})
|
||||
}
|
||||
|
||||
init {
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
@ -54,13 +67,15 @@ open class GetRemoteJsons : DefaultTask() {
|
|||
val cache = project.cache
|
||||
val extension = project.ext
|
||||
|
||||
// McManifest.json
|
||||
val mcManifestJson = cache.resolve(Constants.MC_MANIFEST)
|
||||
val mcVersionJson = cache.resolve(Constants.VERSION_JSON)
|
||||
ensureParentExists(mcManifestJson, mcVersionJson)
|
||||
|
||||
// McManifest.json
|
||||
val mcManifestEtag = cache.resolve("${Constants.MC_MANIFEST}.etag")
|
||||
getWithEtag(Constants.MC_MANIFEST_URL, mcManifestJson, mcManifestEtag)
|
||||
val mcManifestText = gson.fromJson<MinecraftManifest>(mcManifestJson.readText())
|
||||
|
||||
val mcVersionJson = cache.resolve(Constants.VERSION_JSON)
|
||||
val mcVersionEtag = mcVersionJson.resolveSibling("${mcVersionJson.name}.etag")
|
||||
getWithEtag(mcManifestText.versions.first { it.id == extension.minecraftVersion.get() }.url, mcVersionJson, mcVersionEtag)
|
||||
|
||||
|
@ -69,8 +84,13 @@ open class GetRemoteJsons : DefaultTask() {
|
|||
}
|
||||
|
||||
val conf = config.get()
|
||||
for (library in jsonObject["libraries"].array) {
|
||||
project.dependencies.add(conf, library["name"].string)
|
||||
artifactOutputFile.file.delete()
|
||||
artifactOutputFile.file.bufferedWriter().use { writer ->
|
||||
for (library in jsonObject["libraries"].array) {
|
||||
val artifact = library["name"].string
|
||||
project.dependencies.add(conf, artifact)
|
||||
writer.appendln(artifact)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
|
@ -39,14 +40,13 @@ import org.cadixdev.mercury.extra.AccessAnalyzerProcessor
|
|||
import org.cadixdev.mercury.extra.BridgeMethodRewriter
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper
|
||||
import org.cadixdev.mercury.util.BombeBindings
|
||||
import org.eclipse.jdt.core.dom.ASTNode
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding
|
||||
import org.eclipse.jdt.core.dom.IVariableBinding
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration
|
||||
import org.eclipse.jdt.core.dom.Modifier
|
||||
import org.eclipse.jdt.core.dom.SimpleName
|
||||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration
|
||||
import org.eclipse.jdt.core.dom.VariableDeclaration
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
@ -67,7 +67,7 @@ open class RemapSources : ZippedTask() {
|
|||
@InputFile
|
||||
val vanillaRemappedSrgJar: RegularFileProperty = project.objects.fileProperty() // Required for post-remap pass
|
||||
@InputFile
|
||||
val spigotToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
val mappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@Input
|
||||
val configuration: Property<String> = project.objects.property()
|
||||
@InputFile
|
||||
|
@ -78,17 +78,13 @@ open class RemapSources : ZippedTask() {
|
|||
val spigotApiDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
|
||||
@OutputFile
|
||||
val generatedAt: RegularFileProperty = project.objects.fileProperty()
|
||||
val generatedAt: RegularFileProperty = defaultOutput("at")
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
val config = mcpConfig(configFile)
|
||||
val constructors = mcpFile(configFile, config.data.constructors)
|
||||
|
||||
val spigotToSrgFile = spigotToSrg.file
|
||||
|
||||
val mappings = spigotToSrgFile.bufferedReader().use { reader ->
|
||||
MappingFormats.TSRG.createReader(reader).read()
|
||||
}
|
||||
val mappings = MappingFormats.TSRG.createReader(mappings.file.toPath()).use { it.read() }
|
||||
|
||||
val srcDir = spigotServerDir.file.resolve("src/main/java")
|
||||
val pass1Dir = rootDir.resolve("pass1")
|
||||
|
@ -98,6 +94,7 @@ open class RemapSources : ZippedTask() {
|
|||
|
||||
val ats = AccessTransformSet.create()
|
||||
|
||||
// Remap any references Spigot maps to SRG
|
||||
Mercury().apply {
|
||||
classPath.addAll(listOf(
|
||||
vanillaJar.asFile.get().toPath(),
|
||||
|
@ -133,7 +130,6 @@ open class RemapSources : ZippedTask() {
|
|||
))
|
||||
|
||||
processors.add(SrgParameterRemapper(constructors))
|
||||
|
||||
rewrite(pass1Dir.toPath(), outDir.toPath())
|
||||
}
|
||||
|
||||
|
@ -178,7 +174,9 @@ class SrgParameterRemapper(constructors: File) : SourceRewriter {
|
|||
}
|
||||
|
||||
for (list in constructorMap.values) {
|
||||
// Put bigger numbers first...just trust me
|
||||
// Put bigger numbers first
|
||||
// Old constructor entries are still present, just with smaller numbers. So we don't want to grab an older
|
||||
// entry
|
||||
list.reverse()
|
||||
}
|
||||
}
|
||||
|
@ -210,32 +208,38 @@ class SrgParameterVisitor(
|
|||
return false
|
||||
}
|
||||
|
||||
val methodDecl = findMethodDeclaration(node) ?: return false
|
||||
val method = binding.declaringMethod ?: return false
|
||||
val variableDecl = context.compilationUnit.findDeclaringNode(binding.variableDeclaration) as VariableDeclaration
|
||||
|
||||
val method = binding.declaringMethod
|
||||
val methodDecl = context.compilationUnit.findDeclaringNode(method) as? MethodDeclaration ?: return false
|
||||
|
||||
handleMethod(node, methodDecl, method, variableDecl)
|
||||
|
||||
handleMethod(node, methodDecl, method)
|
||||
return false
|
||||
}
|
||||
|
||||
private fun handleMethod(node: SimpleName, methodDecl: MethodDeclaration, method: IMethodBinding) {
|
||||
private fun handleMethod(node: SimpleName, methodDecl: MethodDeclaration, method: IMethodBinding, variableDecl: VariableDeclaration) {
|
||||
if (method.isConstructor) {
|
||||
handleConstructor(node, methodDecl, method)
|
||||
handleConstructor(node, methodDecl, method, variableDecl)
|
||||
return
|
||||
}
|
||||
|
||||
val match = MATCHER.matchEntire(method.name) ?: return
|
||||
val isStatic = method.modifiers and Modifier.STATIC != 0
|
||||
|
||||
val index = getParameterIndex(methodDecl, node)
|
||||
var index = getParameterIndex(methodDecl, variableDecl)
|
||||
if (index == -1) {
|
||||
return
|
||||
}
|
||||
if (!isStatic) {
|
||||
index++
|
||||
}
|
||||
|
||||
val paramName = "p_${match.groupValues[1]}_${index + if (isStatic) 0 else 1}_"
|
||||
val paramName = "p_${match.groupValues[1]}_${index}_"
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, paramName, null)
|
||||
}
|
||||
|
||||
private fun handleConstructor(node: SimpleName, methodDecl: MethodDeclaration, method: IMethodBinding) {
|
||||
private fun handleConstructor(node: SimpleName, methodDecl: MethodDeclaration, method: IMethodBinding, variableDecl: VariableDeclaration) {
|
||||
val constructorNodes = constructors[method.declaringClass.binaryName] ?: return
|
||||
|
||||
val constructorNode = constructorNodes.firstOrNull { constructorNode ->
|
||||
|
@ -244,27 +248,20 @@ class SrgParameterVisitor(
|
|||
|
||||
val id = constructorNode.id
|
||||
|
||||
val index = getParameterIndex(methodDecl, node)
|
||||
var index = getParameterIndex(methodDecl, variableDecl)
|
||||
if (index == -1) {
|
||||
return
|
||||
}
|
||||
// Constructors are never static
|
||||
index++
|
||||
|
||||
val paramName = "p_i${id}_${index + 1}_"
|
||||
val paramName = "p_i${id}_${index}_"
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, paramName, null)
|
||||
}
|
||||
|
||||
private fun findMethodDeclaration(node: ASTNode): MethodDeclaration? {
|
||||
var currentNode: ASTNode? = node
|
||||
while (currentNode != null && currentNode !is MethodDeclaration) {
|
||||
currentNode = currentNode.parent
|
||||
}
|
||||
return currentNode as? MethodDeclaration
|
||||
}
|
||||
|
||||
private fun getParameterIndex(methodDecl: MethodDeclaration, name: SimpleName): Int {
|
||||
// Can't find a better way to get the index..
|
||||
private fun getParameterIndex(methodDecl: MethodDeclaration, decl: VariableDeclaration): Int {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val params = methodDecl.parameters() as List<SingleVariableDeclaration>
|
||||
return params.indexOfFirst { it.name.identifier == name.identifier }
|
||||
val params = methodDecl.parameters() as List<VariableDeclaration>
|
||||
return params.indexOfFirst { it === decl }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ package io.papermc.paperweight.tasks
|
|||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import io.papermc.paperweight.util.wrapException
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
|
@ -44,10 +44,13 @@ open class RemapVanillaJarSpigot : DefaultTask() {
|
|||
|
||||
@InputFile
|
||||
val classMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val memberMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val packageMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val accessTransformers: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
|
@ -56,20 +59,21 @@ open class RemapVanillaJarSpigot : DefaultTask() {
|
|||
|
||||
@InputFile
|
||||
val specialSourceJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val specialSource2Jar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@Input
|
||||
val classMapCommand: Property<String> = project.objects.property()
|
||||
|
||||
@Input
|
||||
val memberMapCommand: Property<String> = project.objects.property()
|
||||
|
||||
@Input
|
||||
val finalMapCommand: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput())))
|
||||
}
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
@ -97,7 +101,10 @@ open class RemapVanillaJarSpigot : DefaultTask() {
|
|||
specialSource2Jar,
|
||||
workingDir = workDirName.get(),
|
||||
logFile = logFile,
|
||||
args = *doReplacements(classMapCommand.get(), inputJarPath, classMappingPath, classJarPath)
|
||||
args = *doReplacements(classMapCommand.get(), inputJarPath, classMappingPath, classJarPath) {
|
||||
// ignore excludes, we actually want to map every class
|
||||
it != "-e"
|
||||
}
|
||||
)
|
||||
}
|
||||
println("Applying member mappings...")
|
||||
|
@ -129,14 +136,27 @@ open class RemapVanillaJarSpigot : DefaultTask() {
|
|||
}
|
||||
|
||||
private val indexReg = Regex("\\{(\\d)}")
|
||||
private fun doReplacements(command: String, vararg values: String): Array<String> {
|
||||
return command.split(" ").let { it.subList(3, it.size) }.map {
|
||||
val index = indexReg.matchEntire(it)?.groupValues?.get(1)?.toInt()
|
||||
return@map if (index != null) {
|
||||
values[index]
|
||||
} else {
|
||||
it
|
||||
private fun doReplacements(command: String, vararg values: String, filter: ((String) -> Boolean)? = null): Array<String> {
|
||||
var skipNext = false
|
||||
return command.split(" ").let { it.subList(3, it.size) }
|
||||
.filter {
|
||||
if (skipNext) {
|
||||
skipNext = false
|
||||
return@filter false
|
||||
} else if (filter != null && !filter(it)) {
|
||||
skipNext = true
|
||||
return@filter false
|
||||
} else {
|
||||
return@filter true
|
||||
}
|
||||
}
|
||||
}.toTypedArray()
|
||||
.map {
|
||||
val index = indexReg.matchEntire(it)?.groupValues?.get(1)?.toInt()
|
||||
return@map if (index != null) {
|
||||
values[index]
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,10 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.cadixdev.atlas.Atlas
|
||||
import org.cadixdev.bombe.asm.jar.JarEntryRemappingTransformer
|
||||
import org.cadixdev.lorenz.asm.LorenzRemapper
|
||||
|
@ -48,21 +46,20 @@ open class RemapVanillaJarSrg : DefaultTask() {
|
|||
val mappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput())))
|
||||
}
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
ensureParentExists(outputJar.file)
|
||||
ensureDeleted(outputJar.file)
|
||||
|
||||
val mappings = MappingFormats.TSRG.createReader(mappings.file.toPath()).read()
|
||||
val mappings = MappingFormats.TSRG.createReader(mappings.file.toPath()).use { it.read() }
|
||||
Atlas().apply {
|
||||
install { ctx ->
|
||||
JarEntryRemappingTransformer(LorenzRemapper(mappings, ctx.inheritanceProvider()))
|
||||
}
|
||||
run(inputJar.file.toPath(), outputJar.file.toPath())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ package io.papermc.paperweight.tasks
|
|||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
@ -53,9 +53,7 @@ open class RunForgeFlower : DefaultTask() {
|
|||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput())))
|
||||
}
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
@ -50,13 +49,9 @@ open class RunMcInjector : DefaultTask() {
|
|||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput())))
|
||||
}
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
@OutputFile
|
||||
val logFile: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput("log"))))
|
||||
}
|
||||
val logFile: RegularFileProperty = defaultOutput("log")
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
|
|
@ -23,33 +23,32 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Classpath
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.listProperty
|
||||
import java.io.File
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class WriteLibrariesFile : DefaultTask() {
|
||||
|
||||
@Classpath
|
||||
val inputFiles: ListProperty<File> = project.objects.listProperty()
|
||||
@Input
|
||||
val config: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val outputFile: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput("txt"))))
|
||||
val outputFile: RegularFileProperty = defaultOutput("txt")
|
||||
|
||||
init {
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val files = inputFiles.get()
|
||||
files.sort()
|
||||
val files = project.configurations[config.get()].resolve().sorted()
|
||||
|
||||
outputFile.file.delete()
|
||||
outputFile.file.bufferedWriter().use { writer ->
|
||||
|
|
|
@ -23,12 +23,10 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.fileOrNull
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import io.papermc.paperweight.util.unzip
|
||||
import io.papermc.paperweight.util.zip
|
||||
import org.gradle.api.DefaultTask
|
||||
|
@ -47,9 +45,7 @@ abstract class ZippedTask : DefaultTask() {
|
|||
val inputZip: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@OutputFile
|
||||
val outputZip: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider(project.cache.resolve(paperTaskOutput("zip"))))
|
||||
}
|
||||
val outputZip: RegularFileProperty = defaultOutput("zip")
|
||||
|
||||
abstract fun run(rootDir: File)
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class Git(private var repo: File) {
|
|||
arrayOf("git", *args)
|
||||
}
|
||||
return try {
|
||||
Command(Runtime.getRuntime().exec(cmd, null, repo), cmd.joinToString(separator = " "))
|
||||
Command(ProcessBuilder(*cmd).directory(repo).start(), cmd.joinToString(separator = " "))
|
||||
} catch (e: IOException) {
|
||||
throw PaperweightException("Failed to execute command: ${cmd.joinToString(separator = " ")}", e)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import com.github.salomonbrys.kotson.fromJson
|
|||
import com.google.gson.Gson
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.ext.PaperweightExtension
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.lorenz.io.TextMappingFormat
|
||||
import org.gradle.api.NamedDomainObjectProvider
|
||||
|
@ -42,6 +43,7 @@ import org.gradle.api.provider.Provider
|
|||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.util.Optional
|
||||
|
||||
val gson: Gson = Gson()
|
||||
|
||||
|
@ -52,9 +54,7 @@ inline val Project.cache: File
|
|||
|
||||
fun writeMappings(format: TextMappingFormat, vararg mappings: Pair<MappingSet, File>) {
|
||||
for ((set, file) in mappings) {
|
||||
file.bufferedWriter().use { stream ->
|
||||
format.createWriter(stream).write(set)
|
||||
}
|
||||
format.createWriter(file.toPath()).use { it.write(set) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,10 +111,25 @@ fun Task.ensureDeleted(vararg files: Any) {
|
|||
}
|
||||
}
|
||||
|
||||
fun Project.toProvider(file: File): Provider<RegularFile> {
|
||||
return layout.file(provider { file })
|
||||
inline fun Project.toProvider(crossinline func: () -> File): Provider<RegularFile> {
|
||||
return layout.file(provider { func() })
|
||||
}
|
||||
|
||||
fun Task.defaultOutput(name: String, ext: String): RegularFileProperty {
|
||||
return project.objects.fileProperty().convention(project.toProvider {
|
||||
project.cache.resolve(paperTaskOutput(name, ext))
|
||||
})
|
||||
}
|
||||
fun Task.defaultOutput(ext: String): RegularFileProperty {
|
||||
return defaultOutput(name, ext)
|
||||
}
|
||||
fun Task.defaultOutput(): RegularFileProperty {
|
||||
return defaultOutput("jar")
|
||||
}
|
||||
|
||||
val <T> Optional<T>.orNull: T?
|
||||
get() = orElse(null)
|
||||
|
||||
val RegularFileProperty.file
|
||||
get() = get().asFile
|
||||
val RegularFileProperty.fileOrNull
|
||||
|
|
Loading…
Reference in a new issue