summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-06-19 03:37:52 +0200
committerLinnea Gräf <nea@nea.moe>2024-06-19 03:37:52 +0200
commit4b077b1a9c9a262cf730796f3876a86d6fa1064b (patch)
treea660180847b995d607949bc4e950876efdbc7cde
parent4d778b97ee33485af5236ad6bdfdd2949fd69cc2 (diff)
downloadarchenemy-4b077b1a9c9a262cf730796f3876a86d6fa1064b.tar.gz
archenemy-4b077b1a9c9a262cf730796f3876a86d6fa1064b.tar.bz2
archenemy-4b077b1a9c9a262cf730796f3876a86d6fa1064b.zip
Add more code to make the client run workHEADmaster
-rw-r--r--.gitignore4
-rw-r--r--archenemyexample/build.gradle.kts164
-rw-r--r--archenemyexample/run/logs/latest.log60
-rw-r--r--archenemyexample/settings.gradle.kts6
-rw-r--r--archenemyexample/src/forgeMain/kotlin/moe/nea/aee/forge/Main.kt22
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/AbstractTransformerRepository.kt2
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt248
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/ExtractNativesTask.kt45
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/MojangVersionMetadata.kt61
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/mojang/YarnMappingDependency.kt1
-rw-r--r--plugin/src/main/kotlin/moe/nea/archenemy/util/OSUtil.kt27
11 files changed, 398 insertions, 242 deletions
diff --git a/.gitignore b/.gitignore
index e25fce7..8466e3d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
+run
+
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build
-.idea \ No newline at end of file
+.idea
diff --git a/archenemyexample/build.gradle.kts b/archenemyexample/build.gradle.kts
index ca4313a..6f8a22f 100644
--- a/archenemyexample/build.gradle.kts
+++ b/archenemyexample/build.gradle.kts
@@ -1,100 +1,108 @@
import moe.nea.archenemy.MCSide
plugins {
- kotlin("multiplatform") version "1.9.22"
- id("moe.nea.archenemy.mojang")
+ kotlin("multiplatform") version "1.9.22"
+ id("moe.nea.archenemy.mojang")
}
repositories {
- mavenCentral()
- maven("https://maven.fabricmc.net")
- maven("https://repo.nea.moe/releases")
+ mavenCentral()
+ maven("https://maven.fabricmc.net")
+ maven("https://repo.nea.moe/releases")
mavenLocal()
}
kotlin.jvmToolchain(8)
val whateverAttribute = Attribute.of("whatever", String::class.java)
val allJvm by kotlin.sourceSets.creating {
- this.dependencies {
- }
+ this.dependencies {
+ }
}
val forge = kotlin.jvm("forge") {
- attributes.attribute(whateverAttribute, "forge")
- compilations.named("main").get().run {
- defaultSourceSet.dependsOn(allJvm)
- this.dependencies {
- val mcpMappings = mojang.yarnMappings(dependencies.create("moe.nea.mcp:mcp-yarn:1.8.9:v2"))
- val minecraftClient = mojang.minecraft("1.8.9", MCSide.CLIENT)
- val mappedClient = mojang.mapJar(minecraftClient, mcpMappings, "official", "named")
- implementation(mappedClient)
- implementation("net.minecraft:launchwrapper:1.12")
- mojang.libraries("1.8.9").forEach(::implementation)
- }
- }
+ attributes.attribute(whateverAttribute, "forge")
+ compilations.named("main").get().run {
+ defaultSourceSet.dependsOn(allJvm)
+ this.dependencies {
+ val mcpMappings = mojang.yarnMappings(dependencies.create("moe.nea.mcp:mcp-yarn:1.8.9:v2"))
+ val minecraftClient = mojang.minecraft("1.8.9", MCSide.CLIENT)
+ val mappedClient = mojang.mapJar(minecraftClient, mcpMappings, "official", "named")
+ implementation(mappedClient)
+ implementation("net.minecraft:launchwrapper:1.12")
+ mojang.libraries("1.8.9").forEach(::implementation)
+ }
+ }
}
val mainForge = forge.compilations.getByName("main")
val fabric = kotlin.jvm("fabric") {
- attributes.attribute(whateverAttribute, "fabric")
- compilations.named("main").get().run {
- defaultSourceSet.dependsOn(allJvm)
- this.dependencies {
- val minecraftClient = mojang.minecraft("1.20.2", MCSide.CLIENT)
- val minecraftServer = mojang.minecraft("1.20.2", MCSide.SERVER)
- val intermediaryMappings = mojang.intermediaryMappings("1.20.2")
- val yarnMappings = mojang.yarnMappings(dependencies.create("net.fabricmc:yarn:1.20.2+build.4:v2"))
- val intermediaryClient = mojang.mapJar(
- minecraftClient,
- intermediaryMappings,
- "official",
- "intermediary"
- )
- val intermediaryServer = mojang.mapJar(
- minecraftServer,
- intermediaryMappings,
- "official",
- "intermediary"
- )
- val thingy = mojang.mergeJar(
- intermediaryClient, intermediaryServer
- )
- implementation(
- mojang.mapJar(
- thingy,
- yarnMappings,
- "intermediary",
- "named"
- )
- )
- }
- }
+ attributes.attribute(whateverAttribute, "fabric")
+ compilations.named("main").get().run {
+ defaultSourceSet.dependsOn(allJvm)
+ this.dependencies {
+ val minecraftClient = mojang.minecraft("1.20.2", MCSide.CLIENT)
+ val minecraftServer = mojang.minecraft("1.20.2", MCSide.SERVER)
+ val intermediaryMappings = mojang.intermediaryMappings("1.20.2")
+ val yarnMappings = mojang.yarnMappings(dependencies.create("net.fabricmc:yarn:1.20.2+build.4:v2"))
+ val intermediaryClient = mojang.mapJar(
+ minecraftClient,
+ intermediaryMappings,
+ "official",
+ "intermediary"
+ )
+ val intermediaryServer = mojang.mapJar(
+ minecraftServer,
+ intermediaryMappings,
+ "official",
+ "intermediary"
+ )
+ val thingy = mojang.mergeJar(
+ intermediaryClient, intermediaryServer
+ )
+ implementation(
+ mojang.mapJar(
+ thingy,
+ yarnMappings,
+ "intermediary",
+ "named"
+ )
+ )
+ }
+ }
}
+
+
+
tasks.create("runForge189", JavaExec::class) {
- description = "Run Forge 1.8.9"
- group = ApplicationPlugin.APPLICATION_GROUP
- mainClass.set("net.minecraft.launchwrapper.Launch")
- val downloadTask = archenemyShared.getDownloadAssetsTask("1.8.9")
- dependsOn(downloadTask)
- classpath(mainForge.runtimeDependencyFiles, tasks.getByName("forgeJar"))
- javaLauncher.set(javaToolchains.launcherFor {
- this.languageVersion.set(JavaLanguageVersion.of(8))
- })
- val runFolder = project.file("run")
- runFolder.mkdirs()
- workingDir(runFolder)
- doFirst {
- args(
- "--assetDir",
- downloadTask.getAssetDir().absolutePath,
- "--assetIndex",
- downloadTask.getAssetIndex(),
- "--accessToken",
- "undefined",
- "--gameDir",
- runFolder.absolutePath,
- "--tweakClass",
- "moe.nea.aee.forge.Tweaker"
- )
- }
+ val extractNatives = mojang.natives("1.8.9")
+ dependsOn(extractNatives)
+ description = "Run Forge 1.8.9"
+ group = ApplicationPlugin.APPLICATION_GROUP
+ mainClass.set("net.minecraft.launchwrapper.Launch")
+ val downloadTask = archenemyShared.getDownloadAssetsTask("1.8.9")
+ dependsOn(downloadTask)
+ classpath(mainForge.runtimeDependencyFiles, tasks.getByName("forgeJar"))
+ javaLauncher.set(javaToolchains.launcherFor {
+ this.languageVersion.set(JavaLanguageVersion.of(8))
+ })
+ val runFolder = project.file("run")
+ runFolder.mkdirs()
+ workingDir(runFolder)
+ jvmArguments.add("-Djava.library.path=${extractNatives.getNativeDirectoryPath().absolutePath}")
+ doFirst {
+ args(
+ "--assetsDir",
+ downloadTask.getAssetDir().absolutePath,
+ "--assetIndex",
+ downloadTask.getAssetIndex().id,
+ "--accessToken",
+ "undefined",
+ "--gameDir",
+ runFolder.absolutePath,
+ "--tweakClass",
+ "moe.nea.aee.forge.Tweaker",
+ "--version",
+ "1.8.9"
+ )
+ }
}
diff --git a/archenemyexample/run/logs/latest.log b/archenemyexample/run/logs/latest.log
index 585e475..1b089e9 100644
--- a/archenemyexample/run/logs/latest.log
+++ b/archenemyexample/run/logs/latest.log
@@ -1,24 +1,44 @@
-[16:58:57] [main/INFO]: Loading tweak class name moe.nea.aee.forge.Tweaker
-[16:58:57] [main/INFO]: Using primary tweak class name moe.nea.aee.forge.Tweaker
-[16:58:57] [main/INFO]: Calling tweak class moe.nea.aee.forge.Tweaker
-[16:58:57] [main/INFO]: Launching wrapped minecraft {net.minecraft.client.main.Main}
-[16:58:57] [main/ERROR]: Unable to launch
+[03:34:03] [main/INFO]: Loading tweak class name moe.nea.aee.forge.Tweaker
+[03:34:03] [main/INFO]: Using primary tweak class name moe.nea.aee.forge.Tweaker
+[03:34:03] [main/INFO]: Calling tweak class moe.nea.aee.forge.Tweaker
+[03:34:05] [main/INFO]: Launching wrapped minecraft {net.minecraft.client.main.Main}
+[03:34:08] [Client thread/INFO]: Setting user: Player554
+[03:34:08] [Client thread/INFO]: (Session ID is token:undefined:Player554)
+[03:34:09] [Client thread/ERROR]: Unable to launch
java.lang.reflect.InvocationTargetException
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_302]
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_302]
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_302]
- at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_302]
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_152]
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_152]
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_152]
+ at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_152]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
-Caused by: java.lang.UnsatisfiedLinkError: no lwjgl64 in java.library.path
- at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860) ~[?:1.8.0_302]
- at java.lang.Runtime.loadLibrary0(Runtime.java:871) ~[?:1.8.0_302]
- at java.lang.System.loadLibrary(System.java:1124) ~[?:1.8.0_302]
- at org.lwjgl.Sys$1.run(Sys.java:72) ~[lwjgl-2.9.4-nightly-20150209.jar:?]
- at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_302]
- at org.lwjgl.Sys.doLoadLibrary(Sys.java:66) ~[lwjgl-2.9.4-nightly-20150209.jar:?]
- at org.lwjgl.Sys.loadLibrary(Sys.java:87) ~[lwjgl-2.9.4-nightly-20150209.jar:?]
- at org.lwjgl.Sys.<clinit>(Sys.java:117) ~[lwjgl-2.9.4-nightly-20150209.jar:?]
- at net.minecraft.client.Minecraft.getSystemTime(SourceFile:2539) ~[Minecraft.class:?]
- at net.minecraft.client.main.Main.main(SourceFile:41) ~[Main.class:?]
+Caused by: java.lang.ExceptionInInitializerError
+ at net.minecraft.util.StatCollector.<clinit>(SourceFile:7) ~[StatCollector.class:?]
+ at net.minecraft.item.Item.getUnlocalizedNameInefficiently(SourceFile:250) ~[Item.class:?]
+ at net.minecraft.item.Item.getItemStackDisplayName(SourceFile:321) ~[Item.class:?]
+ at net.minecraft.item.ItemStack.getDisplayName(SourceFile:459) ~[ItemStack.class:?]
+ at net.minecraft.item.ItemStack.getChatComponent(SourceFile:775) ~[ItemStack.class:?]
+ at net.minecraft.stats.StatList.initMiningStats(SourceFile:137) ~[StatList.class:?]
+ at net.minecraft.stats.StatList.init(SourceFile:90) ~[StatList.class:?]
+ at net.minecraft.init.Bootstrap.register(SourceFile:460) ~[Bootstrap.class:?]
+ at net.minecraft.client.Minecraft.<init>(SourceFile:304) ~[Minecraft.class:?]
+ at net.minecraft.client.main.Main.main(SourceFile:124) ~[Main.class:?]
... 6 more
+Caused by: java.lang.NullPointerException
+ at java.io.Reader.<init>(Reader.java:78) ~[?:1.8.0_152]
+ at java.io.InputStreamReader.<init>(InputStreamReader.java:113) ~[?:1.8.0_152]
+ at org.apache.commons.io.IOUtils.readLines(IOUtils.java:986) ~[IOUtils.class:2.4]
+ at net.minecraft.util.StringTranslate.<init>(SourceFile:27) ~[StringTranslate.class:?]
+ at net.minecraft.util.StringTranslate.<clinit>(SourceFile:19) ~[StringTranslate.class:?]
+ at net.minecraft.util.StatCollector.<clinit>(SourceFile:7) ~[StatCollector.class:?]
+ at net.minecraft.item.Item.getUnlocalizedNameInefficiently(SourceFile:250) ~[Item.class:?]
+ at net.minecraft.item.Item.getItemStackDisplayName(SourceFile:321) ~[Item.class:?]
+ at net.minecraft.item.ItemStack.getDisplayName(SourceFile:459) ~[ItemStack.class:?]
+ at net.minecraft.item.ItemStack.getChatComponent(SourceFile:775) ~[ItemStack.class:?]
+ at net.minecraft.stats.StatList.initMiningStats(SourceFile:137) ~[StatList.class:?]
+ at net.minecraft.stats.StatList.init(SourceFile:90) ~[StatList.class:?]
+ at net.minecraft.init.Bootstrap.register(SourceFile:460) ~[Bootstrap.class:?]
+ at net.minecraft.client.Minecraft.<init>(SourceFile:304) ~[Minecraft.class:?]
+ at net.minecraft.client.main.Main.main(SourceFile:124) ~[Main.class:?]
+ ... 6 more
+[03:34:09] [Client Shutdown Thread/INFO]: Stopping server
diff --git a/archenemyexample/settings.gradle.kts b/archenemyexample/settings.gradle.kts
index b50251b..77c74c3 100644
--- a/archenemyexample/settings.gradle.kts
+++ b/archenemyexample/settings.gradle.kts
@@ -8,4 +8,8 @@ pluginManagement {
maven("https://repo.nea.moe/releases")
mavenLocal()
}
-} \ No newline at end of file
+}
+
+plugins {
+ id("org.gradle.toolchains.foojay-resolver-convention") version("0.6.0")
+}
diff --git a/archenemyexample/src/forgeMain/kotlin/moe/nea/aee/forge/Main.kt b/archenemyexample/src/forgeMain/kotlin/moe/nea/aee/forge/Main.kt
index 141949e..827340d 100644
--- a/archenemyexample/src/forgeMain/kotlin/moe/nea/aee/forge/Main.kt
+++ b/archenemyexample/src/forgeMain/kotlin/moe/nea/aee/forge/Main.kt
@@ -5,7 +5,25 @@ import net.minecraft.launchwrapper.LaunchClassLoader
import java.io.File
class Tweaker : ITweaker {
- override fun acceptOptions(args: MutableList<String>?, gameDir: File?, assetsDir: File?, profile: String?) {
+ val arguments = mutableListOf<String>()
+
+ override fun acceptOptions(
+ args: List<String>, gameDir: File?,
+ assetsDir: File?, profile: String?
+ ) {
+ arguments.addAll(args)
+ if (gameDir != null){
+ arguments.add("--gameDir")
+ arguments.add(gameDir.absolutePath)
+ }
+ if (assetsDir != null){
+ arguments.add("--assetsDir")
+ arguments.add(assetsDir.absolutePath)
+ }
+ if (profile != null){
+ arguments.add("--version")
+ arguments.add(profile)
+ }
}
override fun injectIntoClassLoader(classLoader: LaunchClassLoader) {
@@ -16,6 +34,6 @@ class Tweaker : ITweaker {
}
override fun getLaunchArguments(): Array<String> {
- return arrayOf()
+ return arguments.toTypedArray()
}
}
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/AbstractTransformerRepository.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/AbstractTransformerRepository.kt
index 601cb19..a50552a 100644
--- a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/AbstractTransformerRepository.kt
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/AbstractTransformerRepository.kt
@@ -57,7 +57,7 @@ abstract class AbstractTransformerRepository<T : CHashable>(
val provider = providers[hash] ?: error("Unregistered archenemy ${this.repoIdentifier} dependeny")
val coordinate = getCoordinate(provider.t)
require(coordinate.startsWith(identifier.group + ":" + identifier.name + ":" + identifier.version))
- if (identifier.extension == "pom") return Artifact.none()
+ if (identifier.extension == "pom") return Artifact.none() // TODO: resolve original POM (potentially transformed???)
return getArtifact(
getNullsafeIdentifier(identifier),
provider.t,
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 d27f948..8c009e0 100644
--- a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ArchenemyMojangExtension.kt
@@ -9,122 +9,136 @@ import java.io.File
import java.net.URI
abstract class ArchenemyMojangExtension(val project: Project) {
- val sharedExtension = project.rootProject.extensions.getByType(ArchenemySharedExtension::class.java)
-
- private val _registerMinecraftProvider by lazy {
- GradleRepositoryAdapter.add(
- project.repositories,
- "Minecraft Provider",
- sharedExtension.getLocalCacheDirectory().resolve("minecraft-provider"),
- sharedExtension.minecraftProvider
- )
- GradleRepositoryAdapter.add(
- project.repositories,
- "Minecraft Mapped Provider",
- getLocalCacheDirectory().resolve("minecraft-mapped-provider"),
- mappedRepositoryProvider
- )
- GradleRepositoryAdapter.add(
- project.repositories,
- "Minecraft Merged Provider",
- getLocalCacheDirectory().resolve("minecraft-merged-provider"),
- mergedRepositoryProvider
- )
- project.repositories.maven {
- it.name = "Minecraft Libraries"
- it.url = URI("https://libraries.minecraft.net/")
- }
- }
-
- private val mappedRepositoryProvider = MappedRepositoryProvider(this)
- private val mergedRepositoryProvider = MergedRepositoryProvider(this)
-
- fun yarnMappings(dependency: Dependency): MappingDependency {
- dependency as ModuleDependency
- return YarnMappingDependency(this, dependency)
- }
-
- fun officialMappings(version: String, side: MCSide): MappingDependency {
- _registerMinecraftProvider
- val dependency by lazy {
- realize(
- sharedExtension.minecraftProvider.getMappingsDependencyCoordinate(
- MinecraftProvider.MinecraftCoordinate(
- version,
- side
- )
- )
- )
- }
- return OfficialMappingDependency(side, version, project.providers.provider { dependency }).also { it.get() }
- }
-
- fun libraries(version: String): List<String> {
- return sharedExtension.getDownloadVersionMetadataTask(version)
- .getVersionMetadataNow().libraries
- .map { it.name }
- .filter { !it.contains("twitch-platform") && !it.contains("twitch-external-platform") }
- }
-
- fun intermediaryMappings(version: String): MappingDependency {
- return yarnMappings(project.dependencies.create("net.fabricmc:intermediary:$version:v2"))
- }
-
- fun mergeJar(
- base: Dependency,
- overlay: Dependency,
- ): Dependency {
- base as ModuleDependency
- overlay as ModuleDependency
- _registerMinecraftProvider
- return realize(
- mergedRepositoryProvider.getCoordinate(
- MergedRepositoryProvider.Coordinate(base, overlay)
- )
- )
- }
-
- fun mapJar(
- dependency: Dependency,
- mappings: MappingDependency,
- sourceNamespace: String,
- destinationNamespace: String
- ): Dependency {
- dependency as ModuleDependency
- _registerMinecraftProvider
- return realize(
- mappedRepositoryProvider.getDependencyCoordiante(
- MappedRepositoryProvider.MappedCoordinates(
- dependency, mappings, sourceNamespace, destinationNamespace
- )
- )
- )
- }
-
- fun minecraft(version: String, side: MCSide): Dependency {
- _registerMinecraftProvider
- return realize(
- sharedExtension.minecraftProvider.getDependencyCoordinate(
- MinecraftProvider.MinecraftCoordinate(
- version,
- side,
- )
- )
- )
- }
-
- fun realize(dependency: String): Dependency {
- return realize(project.dependencies.create(dependency))
- }
-
- fun realize(dependency: Dependency): Dependency {
- project.configurations.detachedConfiguration(dependency).resolve()
- return dependency
- }
-
- fun getLocalCacheDirectory(): File {
- return sharedExtension.getLocalCacheDirectory().resolve("projectspecific")
- .resolve(if (project == project.rootProject) "__root" else project.path.replace(":", "_"))
- }
+ val sharedExtension = project.rootProject.extensions.getByType(ArchenemySharedExtension::class.java)
+
+ private val _registerMinecraftProvider by lazy {
+ GradleRepositoryAdapter.add(
+ project.repositories,
+ "Minecraft Provider",
+ sharedExtension.getLocalCacheDirectory().resolve("minecraft-provider"),
+ sharedExtension.minecraftProvider
+ )
+ GradleRepositoryAdapter.add(
+ project.repositories,
+ "Minecraft Mapped Provider",
+ getLocalCacheDirectory().resolve("minecraft-mapped-provider"),
+ mappedRepositoryProvider
+ )
+ GradleRepositoryAdapter.add(
+ project.repositories,
+ "Minecraft Merged Provider",
+ getLocalCacheDirectory().resolve("minecraft-merged-provider"),
+ mergedRepositoryProvider
+ )
+ project.repositories.maven {
+ it.name = "Minecraft Libraries"
+ it.url = URI("https://libraries.minecraft.net/")
+ }
+ }
+
+ private val mappedRepositoryProvider = MappedRepositoryProvider(this)
+ private val mergedRepositoryProvider = MergedRepositoryProvider(this)
+
+ fun yarnMappings(dependency: Dependency): MappingDependency {
+ dependency as ModuleDependency
+ return YarnMappingDependency(this, dependency)
+ }
+
+ fun officialMappings(version: String, side: MCSide): MappingDependency {
+ _registerMinecraftProvider
+ val dependency by lazy {
+ realize(
+ sharedExtension.minecraftProvider.getMappingsDependencyCoordinate(
+ MinecraftProvider.MinecraftCoordinate(
+ version,
+ side
+ )
+ )
+ )
+ }
+ return OfficialMappingDependency(side, version, project.providers.provider { dependency }).also { it.get() }
+ }
+
+ fun natives(version: String): ExtractNativesTask {
+ val taskName = "extractNatives$version"
+ var extractNativesTask = project.tasks.findByName(taskName)
+ if (extractNativesTask != null) return extractNativesTask as ExtractNativesTask
+
+ extractNativesTask = project.tasks.create(taskName, ExtractNativesTask::class.java) {
+ it.natives.set(sharedExtension.getDownloadVersionMetadataTask(version)
+ .getVersionMetadataNow().getFilteredLibraries())
+ it.nativeDirectory.set(getLocalCacheDirectory().resolve("extractedNatives/$version"))
+ }
+ return extractNativesTask
+ }
+
+ fun libraries(version: String): List<String> {
+ return sharedExtension.getDownloadVersionMetadataTask(version)
+ .getVersionMetadataNow().getFilteredLibraries()
+ .map {
+ it.getArtifactCoordinate()
+ }
+ }
+
+ fun intermediaryMappings(version: String): MappingDependency {
+ return yarnMappings(project.dependencies.create("net.fabricmc:intermediary:$version:v2"))
+ }
+
+ fun mergeJar(
+ base: Dependency,
+ overlay: Dependency,
+ ): Dependency {
+ base as ModuleDependency
+ overlay as ModuleDependency
+ _registerMinecraftProvider
+ return realize(
+ mergedRepositoryProvider.getCoordinate(
+ MergedRepositoryProvider.Coordinate(base, overlay)
+ )
+ )
+ }
+
+ fun mapJar(
+ dependency: Dependency,
+ mappings: MappingDependency,
+ sourceNamespace: String,
+ destinationNamespace: String
+ ): Dependency {
+ dependency as ModuleDependency
+ _registerMinecraftProvider
+ return realize(
+ mappedRepositoryProvider.getDependencyCoordiante(
+ MappedRepositoryProvider.MappedCoordinates(
+ dependency, mappings, sourceNamespace, destinationNamespace
+ )
+ )
+ )
+ }
+
+ fun minecraft(version: String, side: MCSide): Dependency {
+ _registerMinecraftProvider
+ return realize(
+ sharedExtension.minecraftProvider.getDependencyCoordinate(
+ MinecraftProvider.MinecraftCoordinate(
+ version,
+ side,
+ )
+ )
+ )
+ }
+
+ fun realize(dependency: String): Dependency {
+ return realize(project.dependencies.create(dependency))
+ }
+
+ fun realize(dependency: Dependency): Dependency {
+ project.configurations.detachedConfiguration(dependency).resolve()
+ return dependency
+ }
+
+ 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/ExtractNativesTask.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ExtractNativesTask.kt
new file mode 100644
index 0000000..a3c33ed
--- /dev/null
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/ExtractNativesTask.kt
@@ -0,0 +1,45 @@
+package moe.nea.archenemy.mojang
+
+import moe.nea.archenemy.util.readZipFs
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+import java.io.File
+
+abstract class ExtractNativesTask : DefaultTask() {
+
+ @get:OutputDirectory
+ abstract val nativeDirectory: DirectoryProperty
+
+ @get:Input
+ abstract val natives: ListProperty<MojangVersionMetadata.Library>
+
+ @Internal
+ fun getNativeDirectoryPath(): File {
+ return nativeDirectory.get().asFile
+ }
+
+ @TaskAction
+ fun extractNatives() {
+ val nativeDirectory = nativeDirectory.get().asFile
+ natives.get().forEach {
+ val extract = it.extract ?: return@forEach
+ val file = project.configurations
+ .detachedConfiguration(project.dependencies.create(it.getArtifactCoordinate()))
+ .files
+ .single().toPath()
+ file.readZipFs { path, inputStream ->
+ if (extract.exclude.any { path.startsWith(it) }) return@readZipFs
+ val targetFile = nativeDirectory.resolve(path)
+ targetFile.parentFile.mkdirs()
+ targetFile.outputStream().use { output ->
+ inputStream.copyTo(output)
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MojangVersionMetadata.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MojangVersionMetadata.kt
index 4ef3313..1a6cf87 100644
--- a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MojangVersionMetadata.kt
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/MojangVersionMetadata.kt
@@ -1,31 +1,48 @@
package moe.nea.archenemy.mojang
import kotlinx.serialization.Serializable
+import moe.nea.archenemy.util.OSUtil
@Serializable
data class MojangVersionMetadata(
- val assetIndex: AssetIndex,
- val downloads: Map<String, Download>,
- val libraries: List<Library>
+ val assetIndex: AssetIndex,
+ val downloads: Map<String, Download>,
+ val libraries: List<Library>
) {
- @Serializable
- data class Library(
- val name: String,
- )
- @Serializable
- data class Download(
- val sha1: String,
- val size: Long,
- val url: String,
- )
-
- @Serializable
- data class AssetIndex(
- val id: String,
- val sha1: String,
- val size: Long,
- val totalSize: Long,
- val url: String,
- )
+
+ fun getFilteredLibraries(): List<Library> {
+ return libraries.filter { !it.name.contains("twitch-platform") && !it.name.contains("twitch-external-platform") }
+ }
+
+ @Serializable
+ data class Library(
+ val name: String,
+ val natives: Map<String, String>? = null,
+ val extract: ExtractOptions? = null,
+ ) : java.io.Serializable {
+ fun getArtifactCoordinate(): String {
+ val classifier = natives?.get(OSUtil.getOsClassifier())
+ return name + (if (classifier != null) ":$classifier" else "")
+ }
+
+ @Serializable
+ data class ExtractOptions(val exclude: List<String> = listOf()) : java.io.Serializable
+ }
+
+ @Serializable
+ data class Download(
+ val sha1: String,
+ val size: Long,
+ val url: String,
+ )
+
+ @Serializable
+ data class AssetIndex(
+ val id: String,
+ val sha1: String,
+ val size: Long,
+ val totalSize: Long,
+ val url: String,
+ )
} \ No newline at end of file
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/YarnMappingDependency.kt b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/YarnMappingDependency.kt
index 46b428e..25d2b35 100644
--- a/plugin/src/main/kotlin/moe/nea/archenemy/mojang/YarnMappingDependency.kt
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/mojang/YarnMappingDependency.kt
@@ -66,6 +66,7 @@ class YarnMappingDependency(
)
)
.build()
+ // TODO: this does not copy over the non class file resources, seemingly
OutputConsumerPath.Builder(targetFile.toPath()).build().use { output ->
remapper.readInputs(sourceFile.toPath())
remapper.apply(output)
diff --git a/plugin/src/main/kotlin/moe/nea/archenemy/util/OSUtil.kt b/plugin/src/main/kotlin/moe/nea/archenemy/util/OSUtil.kt
new file mode 100644
index 0000000..bd7a158
--- /dev/null
+++ b/plugin/src/main/kotlin/moe/nea/archenemy/util/OSUtil.kt
@@ -0,0 +1,27 @@
+package moe.nea.archenemy.util
+
+
+object OSUtil {
+ // TODO: replace this with a library
+ enum class OsKind {
+ WINDOWS,
+ LINUX,
+ OSX,
+ }
+
+ fun getOs(): OsKind {
+ val osName = System.getProperty("os.name").lowercase()
+ if (osName.contains("win")) return OsKind.WINDOWS
+ if (osName.contains("nix") || osName.contains("nux")) return OsKind.LINUX
+ if (osName.contains("mac")) return OsKind.OSX
+ error("Unknown OS")
+ }
+
+ fun getOsClassifier(): String {
+ return when (getOs()) {
+ OsKind.WINDOWS -> "windows"
+ OsKind.LINUX -> "linux"
+ OsKind.OSX -> "osx"
+ }
+ }
+} \ No newline at end of file