11package com.replaymod.gradle.preprocess
22
3+ import net.fabricmc.mappings.MappingsProvider
4+ import org.cadixdev.lorenz.io.MappingFormats
35import org.gradle.api.Plugin
46import org.gradle.api.Project
57import org.gradle.api.Task
@@ -10,22 +12,28 @@ import org.gradle.api.tasks.compile.AbstractCompile
1012
1113import org.gradle.kotlin.dsl.*
1214import java.io.File
13- import java.util.*
1415
1516class PreprocessPlugin : Plugin <Project > {
1617 override fun apply (project : Project ) {
17- val kotlin = project.plugins.hasPlugin(" kotlin" )
18+ val parent = project.parent
19+ if (parent == null ) {
20+ project.extensions.create(" preprocess" , RootPreprocessExtension ::class )
21+ return
22+ }
1823
19- val coreVersionFile = project.file(" ../mainVersion" )
20- val mappingFiles = findMappingFiles(project)
24+ val rootExtension = parent.extensions.getByType<RootPreprocessExtension >()
25+ val graph = rootExtension.rootNode ? : throw IllegalStateException (" Preprocess graph was not configured." )
26+ val projectNode = graph.findNode(project.name) ? : throw IllegalStateException (" Prepocess graph does not contain ${project.name} ." )
2127
22- val parent = project.parent !!
23- val coreVersion = coreVersionFile .readText().toInt ()
24- val mcVersion = project.getMcVersion()
28+ val coreProjectFile = project.file( " ../mainProject " )
29+ val coreProject = coreProjectFile .readText().trim ()
30+ val mcVersion = projectNode.mcVersion
2531 project.extra[" mcVersion" ] = mcVersion
2632 val ext = project.extensions.create(" preprocess" , PreprocessExtension ::class , project.objects, mcVersion)
2733
28- if (coreVersion == mcVersion) {
34+ val kotlin = project.plugins.hasPlugin(" kotlin" )
35+
36+ if (coreProject == project.name) {
2937 project.the<SourceSetContainer >().configureEach {
3038 java.setSrcDirs(listOf (parent.file(" src/$name /java" )))
3139 resources.setSrcDirs(listOf (parent.file(" src/$name /resources" )))
@@ -37,37 +45,10 @@ class PreprocessPlugin : Plugin<Project> {
3745 }
3846 }
3947 } else {
40- val core = project.byVersion(coreVersion)
41- val mappingFile: File ?
42- val inherited: Project ?
43- if (coreVersion < mcVersion) {
44- // Upgrading older core to newer version
45- // Grab the next mapping at or below our version
46- // e.g. if we're on 1.13.2, that'll be 11302 which maps 1.13.2 to 1.12.2
47- val entry = mappingFiles.floorEntry(mcVersion)
48- if (entry == null || entry.key <= coreVersion) {
49- inherited = core
50- mappingFile = null
51- } else {
52- mappingFile = entry.value
53- // Inherit from the version directly below the mapping we"re using
54- val inheritedVersion = mappingFiles.lowerKey(entry.key)
55- inherited = inheritedVersion?.let { project.byVersion(it) } ? : core
56- }
57- } else {
58- // Dowgrading newer core to older versions
59- // Grab the next mapping on our way to the newer core version (i.e. the one right above our version)
60- val entry = mappingFiles.higherEntry(mcVersion)
61- if (entry == null || entry.key > coreVersion) {
62- inherited = core
63- mappingFile = null
64- } else {
65- mappingFile = entry.value
66- // Inherit from the version which the mapping belongs to
67- // e.g. if we're on 1.12.2 then the mapping maps 1.13.2 to 1.12.2 and will be labeled 11302
68- inherited = project.byVersion(entry.key)
69- }
70- }
48+ val inheritedLink = projectNode.links.find { it.first.findNode(coreProject) != null }
49+ val reverseMappings = inheritedLink != null
50+ val (inheritedNode, mappingFile) = inheritedLink ? : graph.findParent(projectNode)!!
51+ val inherited = parent.evaluationDependsOn(inheritedNode.project)
7152
7253 project.the<SourceSetContainer >().configureEach {
7354 val inheritedSourceSet = inherited.the<SourceSetContainer >()[name]
@@ -84,7 +65,7 @@ class PreprocessPlugin : Plugin<Project> {
8465 compileTask(inherited.tasks[" compile${cName} Kotlin" ] as AbstractCompile )
8566 }
8667 mapping = mappingFile
87- reverseMapping = coreVersion < mcVersion
68+ reverseMapping = reverseMappings
8869 vars.convention(ext.vars)
8970 keywords.convention(ext.keywords)
9071 }
@@ -98,7 +79,7 @@ class PreprocessPlugin : Plugin<Project> {
9879 generated = preprocessedKotlin
9980 compileTask(inherited.tasks[" compile${cName} Kotlin" ] as AbstractCompile )
10081 mapping = mappingFile
101- reverseMapping = coreVersion < mcVersion
82+ reverseMapping = reverseMappings
10283 vars.convention(ext.vars)
10384 keywords.convention(ext.keywords)
10485 }
@@ -120,14 +101,32 @@ class PreprocessPlugin : Plugin<Project> {
120101 }
121102
122103 project.afterEvaluate {
104+ val prepareTaskName = " prepareMappingsForPreprocessor"
123105 val projectIntermediaryMappings = project.intermediaryMappings
124106 val inheritedIntermediaryMappings = inherited.intermediaryMappings
125- if (inheritedIntermediaryMappings != null && projectIntermediaryMappings != null ) {
126- tasks.withType<PreprocessTask >().configureEach {
127- sourceMappings = inheritedIntermediaryMappings.first
128- destinationMappings = projectIntermediaryMappings.first
129- (inheritedIntermediaryMappings.second + projectIntermediaryMappings.second).forEach { dependsOn(it) }
107+ val projectNotchMappings = project.notchMappings
108+ val inheritedNotchMappings = inherited.notchMappings
109+ val sourceSrg = project.buildDir.resolve(prepareTaskName).resolve(" source.srg" )
110+ val destinationSrg = project.buildDir.resolve(prepareTaskName).resolve(" destination.srg" )
111+ val prepareTask = if (inheritedIntermediaryMappings != null && projectIntermediaryMappings != null
112+ && inheritedIntermediaryMappings.type == projectIntermediaryMappings.type) {
113+ tasks.register(prepareTaskName) {
114+ bakeNamedToIntermediaryMappings(inheritedIntermediaryMappings, sourceSrg)
115+ bakeNamedToIntermediaryMappings(projectIntermediaryMappings, destinationSrg)
116+ }
117+ } else if (inheritedNotchMappings != null && projectNotchMappings != null
118+ && inheritedNode.mcVersion == projectNode.mcVersion) {
119+ tasks.register(prepareTaskName) {
120+ bakeNamedToOfficialMappings(inheritedNotchMappings, inheritedIntermediaryMappings, sourceSrg)
121+ bakeNamedToOfficialMappings(projectNotchMappings, projectIntermediaryMappings, destinationSrg)
130122 }
123+ } else {
124+ throw IllegalStateException (" Failed to find mappings from $inherited to $project ." )
125+ }
126+ tasks.withType<PreprocessTask >().configureEach {
127+ sourceMappings = sourceSrg
128+ destinationMappings = destinationSrg
129+ dependsOn(prepareTask)
131130 }
132131 }
133132
@@ -146,42 +145,74 @@ class PreprocessPlugin : Plugin<Project> {
146145 }
147146
148147 doLast {
149- coreVersionFile .writeText(mcVersion.toString() )
148+ coreProjectFile .writeText(project.name )
150149 }
151150 }
152151 }
153152 }
154153}
155154
156- private fun Project.getMcVersion (): Int = (name.split(" ." ) + listOf (" " )).let { (major, minor, patch) ->
157- " $major${minor.padStart(2 , ' 0' )}${patch.padStart(2 , ' 0' )} " .toInt()
155+ private fun Task.bakeNamedToIntermediaryMappings (mappings : Mappings , destination : File ) {
156+ mappings.tasks.forEach { this .dependsOn(it) }
157+ inputs.file(mappings.file)
158+ outputs.file(destination)
159+ doLast {
160+ val mapping = if (mappings.format == " tiny" ) {
161+ val tiny = mappings.file.inputStream().use { MappingsProvider .readTinyMappings(it) }
162+ TinyReader (tiny, " named" , " intermediary" , false ).read()
163+ } else {
164+ MappingFormats .byId(mappings.format).read(mappings.file.toPath())
165+ }
166+ MappingFormats .SRG .write(mapping, destination.toPath())
167+ }
158168}
159169
160- private fun Project.byVersion (version : Int ): Project {
161- val name = " ${version/ 10000 } .${version/ 100 % 100 }${if (version% 100 == 0 ) " " else " .${version% 100 } " } "
162- return project.parent!! .evaluationDependsOn(name)
170+ private fun Task.bakeNamedToOfficialMappings (mappings : Mappings , namedToIntermediaryMappings : Mappings ? , destination : File ) {
171+ mappings.tasks.forEach { this .dependsOn(it) }
172+ namedToIntermediaryMappings?.tasks?.forEach { dependsOn(it) }
173+ inputs.file(mappings.file)
174+ namedToIntermediaryMappings?.let { inputs.file(it.file) }
175+ outputs.file(destination)
176+ doLast {
177+ val mapping = if (mappings.format == " tiny" ) {
178+ val tiny = mappings.file.inputStream().use { MappingsProvider .readTinyMappings(it) }
179+ TinyReader (tiny, " named" , " official" , false ).read()
180+ } else {
181+ val iMappings = namedToIntermediaryMappings!!
182+ val iMapSet = MappingFormats .byId(iMappings.format).read(iMappings.file.toPath())
183+ val oMapSet = MappingFormats .byId(mappings.format).read(mappings.file.toPath())
184+ oMapSet.join(iMapSet.reverse()).reverse()
185+ }
186+ MappingFormats .SRG .write(mapping, destination.toPath())
187+ }
163188}
164189
165- private fun findMappingFiles (project : Project ): NavigableMap <Int , File > =
166- project.file(" ../" ).listFiles()!! .mapNotNull {
167- val mappingFile = File (it, " mapping.txt" )
168- if (mappingFile.exists()) {
169- val (major, minor, patch) = it.name.split(" ." ) + listOf (null )
170- val version = " $major${minor?.padStart(2 , ' 0' )}${(patch ? : " " ).padStart(2 , ' 0' )} "
171- Pair (version.toInt(), mappingFile)
172- } else {
173- null
174- }
175- }.toMap(TreeMap ())
176-
177-
178- private val Project .intermediaryMappings: Pair <File , List <Task >>?
190+ private val Project .intermediaryMappings: Mappings ?
179191 get() {
180192 project.tasks.findByName(" genSrgs" )?.let { // FG2
181- return Pair ( it.property(" mcpToSrg" ) as File , listOf (it))
193+ return Mappings ( " searge " , it.property(" mcpToSrg" ) as File , " srg " , listOf (it))
182194 }
183195 project.tasks.findByName(" createMcpToSrg" )?.let { // FG3
184- return Pair ( it.property(" output" ) as File , listOf (it))
196+ return Mappings ( " searge " , it.property(" output" ) as File , " tsrg " , listOf (it))
185197 }
198+ tinyMappings?.let { return Mappings (" yarn" , it, " tiny" , emptyList()) }
186199 return null
187200 }
201+
202+ data class Mappings (val type : String , val file : File , val format : String , val tasks : List <Task >)
203+
204+ private val Project .notchMappings: Mappings ?
205+ get() {
206+ project.tasks.findByName(" extractSrg" )?.let { // FG3
207+ return Mappings (" notch" , it.property(" output" ) as File , " tsrg" , listOf (it))
208+ }
209+ tinyMappings?.let { return Mappings (" notch" , it, " tiny" , emptyList()) }
210+ return null
211+ }
212+
213+ private val Project .tinyMappings: File ?
214+ get() {
215+ val extension = extensions.findByName(" minecraft" ) ? : return null
216+ if (! extension.javaClass.name.contains(" LoomGradleExtension" )) return null
217+ return extension.withGroovyBuilder { getProperty(" mappingsProvider" ) }.withGroovyBuilder { getProperty(" MAPPINGS_TINY" ) } as File
218+ }
0 commit comments