diff --git a/build.gradle.kts b/build.gradle.kts index c96af4b..82b8d1a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,133 +1,72 @@ plugins { - `java-gradle-plugin` - `kotlin-dsl` `maven-publish` kotlin("jvm") version "1.9.0" id("com.github.johnrengelman.shadow") version "8.1.1" } -group = "lol.bai" -version = providers.environmentVariable("VERSION").getOrElse("9999-local") +allprojects { + apply(plugin = "maven-publish") + apply(plugin = "org.jetbrains.kotlin.jvm") + apply(plugin = "com.github.johnrengelman.shadow") -repositories { - mavenCentral() - maven("https://maven.fabricmc.net/") - maven("https://maven.minecraftforge.net/") - maven("https://libraries.minecraft.net/") -} - -configurations { - create("shade") -} + version = providers.environmentVariable("VERSION").getOrElse("9999-local") + group = "lol.bai.explosion" -dependencies { - val shade by configurations - fun compileOnlyShade(artifact: String, action: ExternalModuleDependency.() -> Unit = {}) { - compileOnly(artifact, action) - shade(artifact, action) + repositories { + mavenCentral() } - implementation("com.google.guava:guava:32.1.2-jre") - implementation("org.apache.maven:maven-artifact:3.8.1") - implementation("com.electronwill.night-config:core:3.7.3") - implementation("com.electronwill.night-config:toml:3.7.3") - implementation("org.apache.logging.log4j:log4j-api:2.22.1") - implementation("org.apache.logging.log4j:log4j-core:2.22.1") - implementation("org.slf4j:slf4j-api:2.0.16") - implementation("com.google.code.gson:gson:2.11.0") - - compileOnlyShade("net.fabricmc:fabric-loader:0.15.10") - shade("net.fabricmc:access-widener:2.1.0") - - compileOnlyShade("com.mojang:logging:1.2.7") { isTransitive = false } - compileOnlyShade("net.minecraftforge:fmlloader:1.20.4-49.0.49") { isTransitive = false } - compileOnlyShade("net.minecraftforge:modlauncher:10.2.1") { isTransitive = false } - compileOnlyShade("net.minecraftforge:securemodules:2.2.12") { isTransitive = false } - compileOnlyShade("net.minecraftforge:forgespi:7.1.5") { isTransitive = false } - compileOnlyShade("net.minecraftforge:JarJarFileSystems:0.3.26") { isTransitive = false } - compileOnlyShade("net.minecraftforge:JarJarMetadata:0.3.26") { isTransitive = false } - compileOnlyShade("net.minecraftforge:JarJarSelector:0.3.26") { isTransitive = false } - compileOnlyShade("net.minecraftforge:unsafe:0.9.2") { isTransitive = false } - compileOnlyShade("net.minecraftforge:mergetool-api:1.0") - - testImplementation(kotlin("test")) -} + kotlin { + jvmToolchain(17) + } -tasks.test { - useJUnitPlatform() -} + configurations { + val shade by creating -kotlin { - jvmToolchain(17) -} - -gradlePlugin { - plugins { - create("explosion") { - id = "lol.bai.explosion" - implementationClass = "lol.bai.explosion.ExplosionPlugin" + compileOnly { + extendsFrom(shade) } } -} -tasks.processResources { - val meta = "${project.group}:${project.name}:${project.version}" - inputs.property("meta", meta) + tasks.shadowJar { + configurations = listOf(project.configurations["shade"]) + archiveClassifier.set("") - filesMatching("__meta.txt") { - expand("meta" to meta) + minimize() + mergeServiceFiles() } -} -tasks.shadowJar { - configurations = listOf(project.configurations["shade"]) - archiveClassifier.set("") - mergeServiceFiles() - - relocate("net.fabricmc", "lol.bai.explosion.internal.lib.net.fabricmc") - relocate("net.minecraftforge", "lol.bai.explosion.internal.lib.net.minecraftforge") - relocate("cpw", "lol.bai.explosion.internal.lib.cpw") - relocate("com.mojang", "lol.bai.explosion.internal.lib.com.mojang") - - exclude("ui/**") - exclude("assets/**") - exclude("fabric*.json") - exclude("log4j2*") - exclude("LICENSE_fabric-loader") - exclude("META-INF/jars/**") - exclude("META-INF/org/apache/logging/**") -} - -tasks.build { - dependsOn("shadowJar") -} - -publishing { - repositories { - maven { - name = "LocalMaven" - url = projectDir.resolve(".localMaven").toURI() - } + tasks.build { + dependsOn("shadowJar") + } - if (providers.environmentVariable("GITHUB_TOKEN").isPresent) { + publishing { + repositories { maven { - url = uri("https://maven.pkg.github.com/badasintended/explosion") - name = "GitHub" - credentials { - username = providers.environmentVariable("GITHUB_ACTOR").get() - password = providers.environmentVariable("GITHUB_TOKEN").get() + name = "LocalMaven" + url = projectDir.resolve(".localMaven").toURI() + } + + if (providers.environmentVariable("GITHUB_TOKEN").isPresent) { + maven { + url = uri("https://maven.pkg.github.com/badasintended/explosion") + name = "GitHub" + credentials { + username = providers.environmentVariable("GITHUB_ACTOR").get() + password = providers.environmentVariable("GITHUB_TOKEN").get() + } } } - } - if (providers.environmentVariable("MAVEN_PASSWORD").isPresent) { - maven { - url = uri("https://maven4.bai.lol") - name = "Badasintended" - credentials { - username = providers.environmentVariable("MAVEN_USERNAME").orNull - password = providers.environmentVariable("MAVEN_PASSWORD").orNull + if (providers.environmentVariable("MAVEN_PASSWORD").isPresent) { + maven { + url = uri("https://maven4.bai.lol") + name = "Badasintended" + credentials { + username = providers.environmentVariable("MAVEN_USERNAME").orNull + password = providers.environmentVariable("MAVEN_PASSWORD").orNull + } } } } diff --git a/explosion-gradle-plugin/build.gradle.kts b/explosion-gradle-plugin/build.gradle.kts new file mode 100644 index 0000000..810fcc0 --- /dev/null +++ b/explosion-gradle-plugin/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + `java-gradle-plugin` + `kotlin-dsl` +} + +dependencies { + implementation("com.google.guava:guava:32.1.2-jre") +} + +gradlePlugin { + plugins { + create("explosion") { + id = "lol.bai.explosion" + implementationClass = "lol.bai.explosion.gradle.ExplosionPlugin" + } + } +} + +tasks.processResources { + val meta = "${project.group}:${project.name}:${project.version}" + inputs.property("meta", meta) + + filesMatching("__meta.txt") { + expand("meta" to meta) + } +} diff --git a/src/main/kotlin/lol/bai/explosion/ExplosionDesc.kt b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionDesc.kt similarity index 89% rename from src/main/kotlin/lol/bai/explosion/ExplosionDesc.kt rename to explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionDesc.kt index a361055..f1e1c2c 100644 --- a/src/main/kotlin/lol/bai/explosion/ExplosionDesc.kt +++ b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionDesc.kt @@ -1,4 +1,4 @@ -package lol.bai.explosion +package lol.bai.explosion.gradle import org.gradle.api.artifacts.ExternalModuleDependency import org.gradle.api.provider.Provider diff --git a/src/main/kotlin/lol/bai/explosion/ExplosionExt.kt b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionExt.kt similarity index 97% rename from src/main/kotlin/lol/bai/explosion/ExplosionExt.kt rename to explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionExt.kt index 3e7ae61..3a2389a 100644 --- a/src/main/kotlin/lol/bai/explosion/ExplosionExt.kt +++ b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionExt.kt @@ -1,4 +1,4 @@ -package lol.bai.explosion +package lol.bai.explosion.gradle import groovy.lang.Closure import groovy.lang.DelegatesTo diff --git a/src/main/kotlin/lol/bai/explosion/ExplosionPlugin.kt b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionPlugin.kt similarity index 60% rename from src/main/kotlin/lol/bai/explosion/ExplosionPlugin.kt rename to explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionPlugin.kt index 44b86b5..2926386 100644 --- a/src/main/kotlin/lol/bai/explosion/ExplosionPlugin.kt +++ b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/ExplosionPlugin.kt @@ -1,10 +1,10 @@ -package lol.bai.explosion +package lol.bai.explosion.gradle -import lol.bai.explosion.internal.ExplosionExtImpl -import lol.bai.explosion.internal.resolver.ResolverTask +import lol.bai.explosion.gradle.internal.ExplosionExtImpl import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.kotlin.dsl.* +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.maven import java.io.File import kotlin.io.path.createDirectories @@ -24,12 +24,6 @@ class ExplosionPlugin : Plugin { repositories.maven(outputDir.toFile()) { name = "ExplodedPluginCache" } - - val resolver = configurations.create(ResolverTask.CONFIGURATION) - dependencies { - resolver(embeddedKotlin("stdlib")) - resolver(ExplosionPlugin::class.java.classLoader.getResource("__meta.txt")!!.readText().trim()) - } } } diff --git a/src/main/kotlin/lol/bai/explosion/internal/ExplosionDescImpl.kt b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ExplosionDescImpl.kt similarity index 95% rename from src/main/kotlin/lol/bai/explosion/internal/ExplosionDescImpl.kt rename to explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ExplosionDescImpl.kt index cd45f56..6e06622 100644 --- a/src/main/kotlin/lol/bai/explosion/internal/ExplosionDescImpl.kt +++ b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ExplosionDescImpl.kt @@ -1,6 +1,6 @@ -package lol.bai.explosion.internal +package lol.bai.explosion.gradle.internal -import lol.bai.explosion.ExplosionDesc +import lol.bai.explosion.gradle.ExplosionDesc import org.gradle.api.Project import org.gradle.api.artifacts.ExternalModuleDependency import org.gradle.api.artifacts.FileCollectionDependency diff --git a/src/main/kotlin/lol/bai/explosion/internal/ExplosionExtImpl.kt b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ExplosionExtImpl.kt similarity index 75% rename from src/main/kotlin/lol/bai/explosion/internal/ExplosionExtImpl.kt rename to explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ExplosionExtImpl.kt index 62694e6..188aaf6 100644 --- a/src/main/kotlin/lol/bai/explosion/internal/ExplosionExtImpl.kt +++ b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ExplosionExtImpl.kt @@ -1,13 +1,14 @@ -package lol.bai.explosion.internal +package lol.bai.explosion.gradle.internal import com.google.common.hash.Hashing -import lol.bai.explosion.ExplosionDesc -import lol.bai.explosion.ExplosionExt -import lol.bai.explosion.internal.resolver.ResolverTask +import lol.bai.explosion.gradle.ExplosionDesc +import lol.bai.explosion.gradle.ExplosionExt import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.Transformer import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.embeddedKotlin import org.gradle.kotlin.dsl.invoke import java.io.File import java.nio.file.Path @@ -33,6 +34,10 @@ open class ExplosionExtImpl( return resolve(path.joinToString(File.separator)) } + private fun log(message: String) { + project.logger.lifecycle("lol.bai.explosion: $message") + } + private fun createPom(loader: String, name: String, version: String, jarPlacer: (Path) -> Unit): BomDependency { val group = "exploded" @@ -72,11 +77,11 @@ open class ExplosionExtImpl( val output = dir.resolve("${hash}-1.pom") if (output.exists()) { - project.logger.lifecycle("Exploded BOM for hash $hash already exists, skipping") + log("Exploded BOM for hash $hash already exists, skipping") return bom } - project.logger.lifecycle("Building exploded BOM for hash $hash") + log("Building exploded BOM for hash $hash") val depTemplate = this.javaClass.classLoader.getResource("bom_dependency.xml")!!.readText() @@ -100,12 +105,14 @@ open class ExplosionExtImpl( .replace("%DEPENDENCIES%", depsStr.toString()) output.writeText(pom) + + log("Done") return bom } private fun resolve( action: Action, - loader: String + loader: String, ) = project.provider { val desc = ExplosionDescImpl(project) action(desc) @@ -127,25 +134,37 @@ open class ExplosionExtImpl( val hash = Hashing.murmur3_128().hashString(hashBuilder.toString(), Charsets.UTF_8).toString() return@provider getOrCreateBom(hash) { - val task = project.tasks.create("__explosion_resolver_" + Any().hashCode()) { - this.loader.set(loader) + val key = "__explosion_resolver_" + Any().hashCode() + val meta = javaClass.classLoader.getResource("__meta.txt")!!.readText().trim() + val (group, _, version) = meta.split(':') + val configuration = project.configurations.create(key) + + project.dependencies { + configuration(embeddedKotlin("stdlib")) + configuration(group, "explosion-resolver-${loader}", version) + } + + val task = project.tasks.create(key) { + this.configuration.set(key) + this.mainClass.set("lol.bai.explosion.resolver.${loader}.MainKt") this.inputDir.set(inputDir.toFile()) this.outputDir.set(outputDir.toFile()) } task.exec() task.enabled = false - val metaLines = outputDir.resolve("__meta.txt").readLines() - val bomDeps = arrayListOf() + project.configurations.remove(configuration) - for (line in metaLines) { - val trimmed = line.trim() - if (trimmed.isEmpty()) continue - val (modFile, modId, version) = trimmed.split("\t") - bomDeps.add(createPom(loader, modId, version) { path -> - outputDir.resolve(modFile).copyTo(path) - }) + val bomDeps = arrayListOf() + outputDir.resolve("__meta.txt").forEachLine { line -> + val trimmed = line.trim() + if (trimmed.isNotEmpty()) { + val (modFile, modId, modVersion) = trimmed.split("\t") + bomDeps.add(createPom(loader, modId, modVersion) { path -> + outputDir.resolve(modFile).copyTo(path) + }) + } } return@getOrCreateBom bomDeps diff --git a/src/main/kotlin/lol/bai/explosion/internal/resolver/ResolverTask.kt b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ResolverTask.kt similarity index 62% rename from src/main/kotlin/lol/bai/explosion/internal/resolver/ResolverTask.kt rename to explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ResolverTask.kt index b4e07e7..6039a1f 100644 --- a/src/main/kotlin/lol/bai/explosion/internal/resolver/ResolverTask.kt +++ b/explosion-gradle-plugin/src/main/kotlin/lol/bai/explosion/gradle/internal/ResolverTask.kt @@ -1,4 +1,4 @@ -package lol.bai.explosion.internal.resolver +package lol.bai.explosion.gradle.internal import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.Property @@ -8,12 +8,8 @@ import org.gradle.work.DisableCachingByDefault @DisableCachingByDefault abstract class ResolverTask : JavaExec() { - companion object { - const val CONFIGURATION = "__explosion_resolver" - } - @get:Input - abstract val loader: Property + abstract val configuration: Property @get:InputDirectory abstract val inputDir: DirectoryProperty @@ -21,15 +17,11 @@ abstract class ResolverTask : JavaExec() { @get:OutputDirectory abstract val outputDir: DirectoryProperty - init { - classpath = project.configurations.getByName(CONFIGURATION) - mainClass.set("lol.bai.explosion.internal.resolver.MainKt") - } - @TaskAction override fun exec() { + classpath = project.configurations.getByName(configuration.get()) + args( - loader.get(), inputDir.asFile.get().absolutePath, outputDir.asFile.get().absolutePath, ) diff --git a/src/main/resources/__meta.txt b/explosion-gradle-plugin/src/main/resources/__meta.txt similarity index 100% rename from src/main/resources/__meta.txt rename to explosion-gradle-plugin/src/main/resources/__meta.txt diff --git a/src/main/resources/artifact.xml b/explosion-gradle-plugin/src/main/resources/artifact.xml similarity index 100% rename from src/main/resources/artifact.xml rename to explosion-gradle-plugin/src/main/resources/artifact.xml diff --git a/src/main/resources/bom_dependency.xml b/explosion-gradle-plugin/src/main/resources/bom_dependency.xml similarity index 100% rename from src/main/resources/bom_dependency.xml rename to explosion-gradle-plugin/src/main/resources/bom_dependency.xml diff --git a/src/main/resources/bom_root.xml b/explosion-gradle-plugin/src/main/resources/bom_root.xml similarity index 100% rename from src/main/resources/bom_root.xml rename to explosion-gradle-plugin/src/main/resources/bom_root.xml diff --git a/explosion-resolver-fabric/build.gradle.kts b/explosion-resolver-fabric/build.gradle.kts new file mode 100644 index 0000000..578b310 --- /dev/null +++ b/explosion-resolver-fabric/build.gradle.kts @@ -0,0 +1,25 @@ +repositories { + maven("https://maven.fabricmc.net/") +} + +dependencies { + shade("net.fabricmc:fabric-loader:0.15.10") + + implementation("net.fabricmc:access-widener:2.1.0") +} + +tasks.shadowJar { + exclude("ui/**") + exclude("assets/**") + exclude("fabric*.json") + exclude("LICENSE_fabric-loader") + exclude("META-INF/jars/**") +} + +publishing { + publications { + create("maven") { + from(components["java"]) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/lol/bai/explosion/internal/fabric/FakeGameProvider.kt b/explosion-resolver-fabric/src/main/kotlin/lol/bai/explosion/resolver/fabric/FakeGameProvider.kt similarity index 97% rename from src/main/kotlin/lol/bai/explosion/internal/fabric/FakeGameProvider.kt rename to explosion-resolver-fabric/src/main/kotlin/lol/bai/explosion/resolver/fabric/FakeGameProvider.kt index 753a932..91413fc 100644 --- a/src/main/kotlin/lol/bai/explosion/internal/fabric/FakeGameProvider.kt +++ b/explosion-resolver-fabric/src/main/kotlin/lol/bai/explosion/resolver/fabric/FakeGameProvider.kt @@ -1,4 +1,4 @@ -package lol.bai.explosion.internal.fabric +package lol.bai.explosion.resolver.fabric import net.fabricmc.loader.impl.game.GameProvider import net.fabricmc.loader.impl.game.patch.GameTransformer diff --git a/explosion-resolver-fabric/src/main/kotlin/lol/bai/explosion/resolver/fabric/Main.kt b/explosion-resolver-fabric/src/main/kotlin/lol/bai/explosion/resolver/fabric/Main.kt new file mode 100644 index 0000000..ef77fa6 --- /dev/null +++ b/explosion-resolver-fabric/src/main/kotlin/lol/bai/explosion/resolver/fabric/Main.kt @@ -0,0 +1,55 @@ +package lol.bai.explosion.resolver.fabric + +import net.fabricmc.api.EnvType +import net.fabricmc.loader.impl.FabricLoaderImpl +import net.fabricmc.loader.impl.discovery.ModResolver +import net.fabricmc.loader.impl.discovery.createModDiscoverer +import net.fabricmc.loader.impl.launch.FabricLauncherBase +import net.fabricmc.loader.impl.launch.knot.Knot +import kotlin.io.path.Path +import kotlin.io.path.moveTo +import kotlin.io.path.name +import kotlin.io.path.writeText + +fun main(args: Array) { + val (inputDirStr, outputDirStr) = args + val inputDir = Path(inputDirStr) + val outputDir = Path(outputDirStr) + + if (FabricLauncherBase.getLauncher() == null) Knot(EnvType.CLIENT) + + val loader = FabricLoaderImpl.INSTANCE.apply { + gameProvider = FakeGameProvider(inputDir) + } + + val candidates = createModDiscoverer(inputDir).discoverMods(loader, mutableMapOf()) + candidates.removeIf { it.id == "java" } + + val candidateIds = hashSetOf() + candidates.forEach { + candidateIds.add(it.id) + candidateIds.addAll(it.provides) + } + + candidates.forEach { candidate -> + candidate.metadata.dependencies = candidate.metadata.dependencies.filter { + candidateIds.contains(it.modId) + } + } + + val meta = StringBuilder() + val mods = ModResolver.resolve(candidates, EnvType.CLIENT, mutableMapOf()) + + for (mod in mods) { + val path = outputDir.resolve("${mod.id}-${mod.version.friendlyString}") + mod.copyToDir(outputDir, false).moveTo(path, overwrite = true) + meta.append(path.name) + .append("\t") + .append(mod.id) + .append("\t") + .append(mod.version.friendlyString) + .append("\n") + } + + outputDir.resolve("__meta.txt").writeText(meta.toString()) +} \ No newline at end of file diff --git a/explosion-resolver-fabric/src/main/kotlin/net/fabricmc/loader/impl/discovery/DiscoveryAccess.kt b/explosion-resolver-fabric/src/main/kotlin/net/fabricmc/loader/impl/discovery/DiscoveryAccess.kt new file mode 100644 index 0000000..35c4614 --- /dev/null +++ b/explosion-resolver-fabric/src/main/kotlin/net/fabricmc/loader/impl/discovery/DiscoveryAccess.kt @@ -0,0 +1,9 @@ +package net.fabricmc.loader.impl.discovery + +import net.fabricmc.loader.impl.metadata.DependencyOverrides +import net.fabricmc.loader.impl.metadata.VersionOverrides +import java.nio.file.Path + +fun createModDiscoverer(dir: Path) = ModDiscoverer(VersionOverrides(), DependencyOverrides(dir)).apply { + addCandidateFinder(DirectoryModCandidateFinder(dir, false)) +} diff --git a/explosion-resolver-forge/build.gradle.kts b/explosion-resolver-forge/build.gradle.kts new file mode 100644 index 0000000..dc7ae7e --- /dev/null +++ b/explosion-resolver-forge/build.gradle.kts @@ -0,0 +1,40 @@ +repositories { + maven("https://maven.minecraftforge.net/") + maven("https://libraries.minecraft.net/") +} + +dependencies { + shade("net.minecraftforge:fmlloader:1.20.4-49.0.49") { isTransitive = false } + + implementation("com.google.guava:guava:32.1.2-jre") + implementation("org.apache.maven:maven-artifact:3.8.1") + implementation("com.electronwill.night-config:core:3.7.3") + implementation("com.electronwill.night-config:toml:3.7.3") + implementation("org.apache.logging.log4j:log4j-api:2.22.1") + implementation("org.apache.logging.log4j:log4j-core:2.22.1") + implementation("org.slf4j:slf4j-api:2.0.16") + implementation("com.google.code.gson:gson:2.11.0") + + implementation("com.mojang:logging:1.2.7") { isTransitive = false } + implementation("net.minecraftforge:modlauncher:10.2.1") { isTransitive = false } + implementation("net.minecraftforge:securemodules:2.2.12") { isTransitive = false } + implementation("net.minecraftforge:forgespi:7.1.5") { isTransitive = false } + implementation("net.minecraftforge:JarJarFileSystems:0.3.26") { isTransitive = false } + implementation("net.minecraftforge:JarJarMetadata:0.3.26") { isTransitive = false } + implementation("net.minecraftforge:JarJarSelector:0.3.26") { isTransitive = false } + implementation("net.minecraftforge:unsafe:0.9.2") { isTransitive = false } + implementation("net.minecraftforge:mergetool-api:1.0") +} + +tasks.shadowJar { + exclude("log4j2*") + exclude("META-INF/org/apache/logging/**") +} + +publishing { + publications { + create("maven") { + from(components["java"]) + } + } +} \ No newline at end of file diff --git a/explosion-resolver-forge/src/main/kotlin/lol/bai/explosion/resolver/forge/Main.kt b/explosion-resolver-forge/src/main/kotlin/lol/bai/explosion/resolver/forge/Main.kt new file mode 100644 index 0000000..a07ae0b --- /dev/null +++ b/explosion-resolver-forge/src/main/kotlin/lol/bai/explosion/resolver/forge/Main.kt @@ -0,0 +1,43 @@ +package lol.bai.explosion.resolver.forge + +import net.minecraftforge.fml.loading.UniqueModListBuilder +import net.minecraftforge.fml.loading.moddiscovery.JarInJarDependencyLocator +import net.minecraftforge.fml.loading.moddiscovery.ModFile +import net.minecraftforge.fml.loading.moddiscovery.createModsFolderLocator +import net.minecraftforge.forgespi.locating.IModFile +import kotlin.io.path.Path +import kotlin.io.path.copyTo +import kotlin.io.path.name +import kotlin.io.path.writeText + +fun main(args: Array) { + val (inputDirStr, outputDirStr) = args + val inputDir = Path(inputDirStr) + val outputDir = Path(outputDirStr) + + val modLocator = createModsFolderLocator(inputDir, "explosion!!!") + val jarJar = JarInJarDependencyLocator() + + val primeModFiles = modLocator.scanMods().map { it.file } + val jarJarModFiles = jarJar.scanMods(primeModFiles) + val combinedModFiles = (primeModFiles + jarJarModFiles).filterIsInstance() + + val meta = StringBuilder() + val uniqueModFiles = UniqueModListBuilder(combinedModFiles) + .buildUniqueList().modFiles + .filter { it.type == IModFile.Type.MOD } + + for (modFile in uniqueModFiles) { + val mod = modFile.modInfos[0] + val path = outputDir.resolve("${mod.modId}-${mod.version}") + modFile.filePath.copyTo(path, overwrite = true) + meta.append(path.name) + .append("\t") + .append(mod.modId) + .append("\t") + .append(mod.version) + .append("\n") + } + + outputDir.resolve("__meta.txt").writeText(meta.toString()) +} \ No newline at end of file diff --git a/explosion-resolver-forge/src/main/kotlin/net/minecraftforge/fml/loading/moddiscovery/DiscoveryAccess.kt b/explosion-resolver-forge/src/main/kotlin/net/minecraftforge/fml/loading/moddiscovery/DiscoveryAccess.kt new file mode 100644 index 0000000..30bcbe3 --- /dev/null +++ b/explosion-resolver-forge/src/main/kotlin/net/minecraftforge/fml/loading/moddiscovery/DiscoveryAccess.kt @@ -0,0 +1,5 @@ +package net.minecraftforge.fml.loading.moddiscovery + +import java.nio.file.Path + +fun createModsFolderLocator(modsFolder: Path, name: String) = ModsFolderLocator(modsFolder, name) \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 194b80d..b6012ff 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,4 +5,8 @@ pluginManagement { } } -rootProject.name = "explosion" \ No newline at end of file +rootProject.name = "explosion" + +include("explosion-gradle-plugin") +include("explosion-resolver-fabric") +include("explosion-resolver-forge") diff --git a/src/main/kotlin/lol/bai/explosion/internal/resolver/Main.kt b/src/main/kotlin/lol/bai/explosion/internal/resolver/Main.kt deleted file mode 100644 index f83685f..0000000 --- a/src/main/kotlin/lol/bai/explosion/internal/resolver/Main.kt +++ /dev/null @@ -1,97 +0,0 @@ -package lol.bai.explosion.internal.resolver - -import lol.bai.explosion.internal.fabric.FakeGameProvider -import net.fabricmc.api.EnvType -import net.fabricmc.loader.impl.FabricLoaderImpl -import net.fabricmc.loader.impl.discovery.ModResolver -import net.fabricmc.loader.impl.discovery.createModDiscoverer -import net.fabricmc.loader.impl.launch.FabricLauncherBase -import net.fabricmc.loader.impl.launch.knot.Knot -import net.minecraftforge.fml.loading.UniqueModListBuilder -import net.minecraftforge.fml.loading.moddiscovery.JarInJarDependencyLocator -import net.minecraftforge.fml.loading.moddiscovery.ModFile -import net.minecraftforge.fml.loading.moddiscovery.createModsFolderLocator -import net.minecraftforge.forgespi.locating.IModFile -import java.nio.file.Path -import kotlin.io.path.* - -fun main(args: Array) { - val (loader, inputDirStr, outputDirStr) = args - - val inputDir = Path(inputDirStr) - val outputDir = Path(outputDirStr) - - when (loader) { - "fabric" -> fabric(inputDir, outputDir) - "forge" -> forge(inputDir, outputDir) - else -> throw IllegalArgumentException("Unsupported loader $loader") - } -} - -private fun fabric(inputDir: Path, outputDir: Path) { - if (FabricLauncherBase.getLauncher() == null) Knot(EnvType.CLIENT) - - val loader = FabricLoaderImpl.INSTANCE.apply { - gameProvider = FakeGameProvider(inputDir) - } - - val candidates = createModDiscoverer(inputDir).discoverMods(loader, mutableMapOf()) - candidates.removeIf { it.id == "java" } - - val candidateIds = hashSetOf() - candidates.forEach { - candidateIds.add(it.id) - candidateIds.addAll(it.provides) - } - - candidates.forEach { candidate -> - candidate.metadata.dependencies = candidate.metadata.dependencies.filter { - candidateIds.contains(it.modId) - } - } - - val meta = StringBuilder() - val mods = ModResolver.resolve(candidates, EnvType.CLIENT, mutableMapOf()) - - for (mod in mods) { - val path = outputDir.resolve("${mod.id}-${mod.version.friendlyString}") - mod.copyToDir(outputDir, false).moveTo(path, overwrite = true) - meta.append(path.name) - .append("\t") - .append(mod.id) - .append("\t") - .append(mod.version.friendlyString) - .append("\n") - } - - outputDir.resolve("__meta.txt").writeText(meta.toString()) -} - -@Suppress("UnstableApiUsage") -private fun forge(inputDir: Path, outputDir: Path) { - val modLocator = createModsFolderLocator(inputDir, "explosion!!!") - val jarJar = JarInJarDependencyLocator() - - val primeModFiles = modLocator.scanMods().map { it.file } - val jarJarModFiles = jarJar.scanMods(primeModFiles) - val combinedModFiles = (primeModFiles + jarJarModFiles).filterIsInstance() - - val meta = StringBuilder() - val uniqueModFiles = UniqueModListBuilder(combinedModFiles) - .buildUniqueList().modFiles - .filter { it.type == IModFile.Type.MOD } - - for (modFile in uniqueModFiles) { - val mod = modFile.modInfos[0] - val path = outputDir.resolve("${mod.modId}-${mod.version}") - modFile.filePath.copyTo(path, overwrite = true) - meta.append(path.name) - .append("\t") - .append(mod.modId) - .append("\t") - .append(mod.version) - .append("\n") - } - - outputDir.resolve("__meta.txt").writeText(meta.toString()) -} \ No newline at end of file