diff options
11 files changed, 398 insertions, 242 deletions
@@ -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 |