summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2023-12-10 15:43:14 +0100
committerLinnea Gräf <nea@nea.moe>2023-12-10 15:43:14 +0100
commit17f0faaccb0db837a64b6ce7cecff7f8ab048410 (patch)
treed6dcd51e43d16873c14a696c565c0c343440b19e
parent67bf79815ec27c8b813480c11a45f35ef502fe5b (diff)
downloadarchenemy-17f0faaccb0db837a64b6ce7cecff7f8ab048410.tar.gz
archenemy-17f0faaccb0db837a64b6ce7cecff7f8ab048410.tar.bz2
archenemy-17f0faaccb0db837a64b6ce7cecff7f8ab048410.zip
Add crude mappings/transformer support
-rw-r--r--archenemyexample/build.gradle.kts8
-rw-r--r--archenemyexample/src/forgeMain/kotlin/doStuff.kt2
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt46
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappedRepositoryProvider.kt99
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappingDependency.kt19
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/MinecraftProvider.kt19
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/OfficialMappingDependency.kt42
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/util/GetNullsafeIdentifier.kt14
8 files changed, 232 insertions, 17 deletions
diff --git a/archenemyexample/build.gradle.kts b/archenemyexample/build.gradle.kts
index eb0d9ff..6ed1dbe 100644
--- a/archenemyexample/build.gradle.kts
+++ b/archenemyexample/build.gradle.kts
@@ -19,7 +19,13 @@ kotlin {
compilations.named("main").get().run {
defaultSourceSet.dependsOn(allJvm)
this.dependencies {
- implementation(mojang.minecraft("1.8.9", MCSide.CLIENT))
+ val mappedMinecraft = mojang.mapJar(
+ mojang.minecraft("1.20.2", MCSide.CLIENT) as ModuleDependency,
+ mojang.officialMappings("1.20.2", MCSide.CLIENT),
+ "official",
+ "named"
+ )
+ implementation(mappedMinecraft)
}
}
}
diff --git a/archenemyexample/src/forgeMain/kotlin/doStuff.kt b/archenemyexample/src/forgeMain/kotlin/doStuff.kt
index 659bc2b..1e773ef 100644
--- a/archenemyexample/src/forgeMain/kotlin/doStuff.kt
+++ b/archenemyexample/src/forgeMain/kotlin/doStuff.kt
@@ -1,3 +1,3 @@
actual fun doStuff(args: Int) {
-
+ val x: a = TODO()
} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt
index b3b3cfd..b80fe89 100644
--- a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt
@@ -4,6 +4,8 @@ import moe.nea.archenemy.MCSide
import net.minecraftforge.artifactural.gradle.GradleRepositoryAdapter
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
+import org.gradle.api.artifacts.ModuleDependency
+import java.io.File
import java.net.URI
abstract class ArchenemyMojangExtension(val project: Project) {
@@ -16,12 +18,51 @@ abstract class ArchenemyMojangExtension(val project: Project) {
sharedExtension.getLocalCacheDirectory().resolve("minecraft-provider"),
sharedExtension.minecraftProvider
)
+ GradleRepositoryAdapter.add(
+ project.repositories,
+ "Minecraft Mapped Provider",
+ getLocalCacheDirectory().resolve("minecraft-transformation-provider"),
+ mappedRepositoryProvider
+ )
project.repositories.maven {
it.name = "Minecraft Libraries"
it.url = URI("https://libraries.minecraft.net/")
}
}
+ private val mappedRepositoryProvider = MappedRepositoryProvider(this)
+
+
+ fun officialMappings(version: String, side: MCSide): MappingDependency {
+ _registerMinecraftProvider
+ val dependency by lazy {
+ project.dependencies.create(
+ sharedExtension.minecraftProvider.getMappingsDependencyCoordinate(
+ MinecraftProvider.MinecraftCoordinate(
+ version,
+ side
+ )
+ )
+ )
+ }
+ return OfficialMappingDependency(side, version, project.providers.provider { dependency })
+ }
+
+ fun mapJar(
+ dependency: ModuleDependency,
+ mappings: MappingDependency,
+ sourceNamespace: String,
+ destinationNamespace: String
+ ): Dependency {
+ _registerMinecraftProvider
+ return project.dependencies.create(
+ mappedRepositoryProvider.getDependencyCoordiante(
+ MappedRepositoryProvider.MappedCoordinates(
+ dependency, mappings, sourceNamespace, destinationNamespace
+ )
+ )
+ )
+ }
fun minecraft(version: String, side: MCSide): Dependency {
_registerMinecraftProvider
@@ -35,4 +76,9 @@ abstract class ArchenemyMojangExtension(val project: Project) {
)
}
+ fun getLocalCacheDirectory(): File {
+ return sharedExtension.getLocalCacheDirectory().resolve("projectspecific")
+ .resolve(if (project == project.rootProject) "__root" else project.path.replace(":", "_"))
+ }
+
} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappedRepositoryProvider.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappedRepositoryProvider.kt
new file mode 100644
index 0000000..d176d45
--- /dev/null
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappedRepositoryProvider.kt
@@ -0,0 +1,99 @@
+package moe.nea.archenemy.mojang
+
+import moe.nea.archenemy.DownloadUtils
+import moe.nea.archenemy.util.getNullsafeIdentifier
+import net.minecraftforge.artifactural.api.artifact.Artifact
+import net.minecraftforge.artifactural.api.artifact.ArtifactIdentifier
+import net.minecraftforge.artifactural.api.artifact.ArtifactType
+import net.minecraftforge.artifactural.api.repository.Repository
+import net.minecraftforge.artifactural.base.artifact.StreamableArtifact
+import org.gradle.api.artifacts.ModuleDependency
+import java.security.MessageDigest
+
+class MappedRepositoryProvider(
+ val sharedExtension: ArchenemyMojangExtension
+) : Repository {
+
+ data class MappedCoordinates(
+ val dependency: ModuleDependency,
+ val mappings: MappingDependency,
+ val from: String,
+ val to: String,
+ ) {
+ val transformerHash by lazy {
+ val messageDigest = MessageDigest.getInstance("SHA-256")
+ messageDigest.updateField("name", dependency.name)
+ messageDigest.updateField("from", from)
+ messageDigest.updateField("to", to)
+ messageDigest.updateField("version", dependency.version ?: "null")
+ messageDigest.updateField("group", dependency.group ?: "null")
+ mappings.updateHash(messageDigest)
+ DownloadUtils.bytesToHex(messageDigest.digest())
+ }
+ }
+
+ private val providers = mutableMapOf<String, MappedCoordinates>()
+ private val cacheDir = sharedExtension.getLocalCacheDirectory().resolve("minecraft-transformer-cache")
+
+
+ fun getDependencyCoordiante(coordinates: MappedCoordinates): String {
+ providers[coordinates.transformerHash] = coordinates
+ return "archenemy.remapped.${coordinates.transformerHash}.${coordinates.mappings.title()}-${coordinates.to}.${coordinates.dependency.group}:${coordinates.dependency.name}:${coordinates.dependency.version}"
+ }
+
+ fun getDependencyCoordiante(
+ dependency: ModuleDependency,
+ mappings: MappingDependency,
+ from: String,
+ to: String
+ ): String {
+ val coordinates = MappedCoordinates(dependency, mappings, from, to)
+ return getDependencyCoordiante(coordinates)
+ }
+
+
+ override fun getArtifact(identifier: ArtifactIdentifier?): Artifact {
+ if (identifier == null) return Artifact.none()
+ if (!identifier.group.startsWith("archenemy.remapped.")) return Artifact.none()
+ if (identifier.extension != "jar") return Artifact.none() // TODO: support other artifacts (and poms)
+ val hash = identifier.group.split(".")[2]
+ val coordinates = providers[hash] ?: error("Unregistered mapped dependency $identifier")
+ val (group, name, version) = getDependencyCoordiante(coordinates).split(":")
+ if (group != identifier.group || name != identifier.name || version != identifier.version)
+ error("Inconsistent mapped dependency $identifier (expected $coordinates)")
+
+ return getArtifact(coordinates, getNullsafeIdentifier(identifier)) ?: Artifact.none()
+ }
+
+ private fun getArtifact(coordinates: MappedCoordinates, identifier: ArtifactIdentifier): Artifact? {
+ if ((identifier.classifier ?: "") != "") return null
+ val files = sharedExtension.project.configurations.detachedConfiguration(
+ coordinates.dependency,
+ coordinates.mappings.get()
+ ).also { it.isTransitive = false }.resolve()
+ // TODO: move away from classifiers. those are *evil*.
+ // for now i will just manually append -client
+ // or figure out how loom does it, i suppose
+ val sourceName = listOfNotNull(
+ coordinates.dependency.name,
+ coordinates.dependency.version,
+ coordinates.dependency.artifacts.single().classifier
+ ).joinToString(separator = "-", postfix = ".jar")
+ val sourceFile = files.singleOrNull { it.name == sourceName } ?: return null
+ val mappingsFile = coordinates.mappings.findMapping(files) ?: error("Could not find mappings file")
+ val targetFile = cacheDir.resolve(coordinates.transformerHash + ".jar")
+ targetFile.parentFile.mkdirs()
+ return StreamableArtifact.ofStreamable(identifier, ArtifactType.BINARY) {
+ if (!targetFile.exists()) {
+ coordinates.mappings.applyMapping(
+ mappingsFile = mappingsFile,
+ sourceFile = sourceFile,
+ targetFile = targetFile,
+ sourceNameSpace = coordinates.from,
+ targetNameSpace = coordinates.to
+ )
+ }
+ targetFile.inputStream()
+ }
+ }
+} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappingDependency.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappingDependency.kt
new file mode 100644
index 0000000..a0e1b14
--- /dev/null
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MappingDependency.kt
@@ -0,0 +1,19 @@
+package moe.nea.archenemy.mojang
+
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.provider.Provider
+import java.io.File
+import java.security.MessageDigest
+
+interface MappingDependency : Provider<Dependency> {
+ fun updateHash(digest: MessageDigest)
+ fun title(): String
+ fun findMapping(files: Set<File>): File?
+ fun applyMapping(
+ mappingsFile: File,
+ sourceFile: File,
+ targetFile: File,
+ sourceNameSpace: String,
+ targetNameSpace: String,
+ )
+} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MinecraftProvider.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MinecraftProvider.kt
index 845d3e7..64c1d04 100644
--- a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MinecraftProvider.kt
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MinecraftProvider.kt
@@ -4,6 +4,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import moe.nea.archenemy.DownloadUtils
import moe.nea.archenemy.MCSide
+import moe.nea.archenemy.util.getNullsafeIdentifier
import net.minecraftforge.artifactural.api.artifact.Artifact
import net.minecraftforge.artifactural.api.artifact.ArtifactIdentifier
import net.minecraftforge.artifactural.api.artifact.ArtifactType
@@ -29,7 +30,6 @@ fun MessageDigest.update(text: String) {
class MinecraftProvider(val sharedExtension: ArchenemySharedExtension) : Repository {
-
data class MinecraftCoordinate(
val version: String,
val side: MCSide,
@@ -74,7 +74,7 @@ class MinecraftProvider(val sharedExtension: ArchenemySharedExtension) : Reposit
val downloadType = when (coordinate.side) {
MCSide.CLIENT -> "client"
MCSide.SERVER -> "server"
- } + if (mappings) "-mappings" else ""
+ } + if (mappings) "_mappings" else ""
val download = metadata.downloads[downloadType]
?: throw IOException("Invalid minecraft side $downloadType for ${coordinate.version}")
val targetFile =
@@ -96,21 +96,11 @@ class MinecraftProvider(val sharedExtension: ArchenemySharedExtension) : Reposit
}
}
- fun getNullsafeIdentifier(identifier: ArtifactIdentifier): ArtifactIdentifier {
- return object : ArtifactIdentifier by identifier {
- override fun getClassifier(): String {
- return if (identifier.classifier == null)
- ""
- else
- identifier.classifier
- }
- }
- }
override fun getArtifact(identifier: ArtifactIdentifier?): Artifact {
if (identifier == null) return Artifact.none()
if (identifier.name != "minecraft") return Artifact.none()
- if (!identifier.group.startsWith("archenemy.")) return Artifact.none()
+ if (identifier.group != "archenemy.mojang") return Artifact.none()
if (identifier.extension == "pom") return Artifact.none()
val coordinate =
MinecraftCoordinate(identifier.version, MCSide.valueOf(identifier.classifier.removeSuffix("-mappings")))
@@ -133,6 +123,5 @@ class MinecraftProvider(val sharedExtension: ArchenemySharedExtension) : Reposit
}
return Artifact.none()
}
+}
-
-} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/OfficialMappingDependency.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/OfficialMappingDependency.kt
new file mode 100644
index 0000000..8617ede
--- /dev/null
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/OfficialMappingDependency.kt
@@ -0,0 +1,42 @@
+package moe.nea.archenemy.mojang
+
+import moe.nea.archenemy.MCSide
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.provider.Provider
+import java.io.File
+import java.security.MessageDigest
+
+class OfficialMappingDependency(
+ val side: MCSide,
+ val version: String,
+ val dependency: Provider<Dependency>
+) : MappingDependency,
+ Provider<Dependency> by dependency {
+
+ override fun updateHash(digest: MessageDigest) {
+ digest.update("official")
+ digest.updateField("side", side.toString())
+ digest.updateField("version", version)
+ }
+
+ override fun title(): String {
+ return "official-$side-${version.replace(".","_")}"
+ }
+
+ override fun findMapping(files: Set<File>): File? {
+ return files.singleOrNull {
+ it.name == "minecraft-${version}-${side}-mappings.txt"
+ }
+ }
+
+ override fun applyMapping(
+ mappingsFile: File,
+ sourceFile: File,
+ targetFile: File,
+ sourceNameSpace: String,
+ targetNameSpace: String
+ ) {
+ sourceFile.copyTo(targetFile)
+ }
+
+} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/util/GetNullsafeIdentifier.kt b/plugin/src/main/kotlin/moe/nea/archenemy/util/GetNullsafeIdentifier.kt
new file mode 100644
index 0000000..9d9a422
--- /dev/null
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/util/GetNullsafeIdentifier.kt
@@ -0,0 +1,14 @@
+package moe.nea.archenemy.util
+
+import net.minecraftforge.artifactural.api.artifact.ArtifactIdentifier
+
+fun getNullsafeIdentifier(identifier: ArtifactIdentifier): ArtifactIdentifier {
+ return object : ArtifactIdentifier by identifier {
+ override fun getClassifier(): String {
+ return if (identifier.classifier == null)
+ ""
+ else
+ identifier.classifier
+ }
+ }
+} \ No newline at end of file