mirror of https://github.com/FabricMC/yarn.git
Rewrite mc downloading in filament (#3301)
This commit is contained in:
parent
a837ae344b
commit
8349f2bc13
|
@ -0,0 +1,16 @@
|
|||
name: Release Filament
|
||||
on: [workflow_dispatch] # Manual trigger
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: openjdk:18-jdk
|
||||
options: --user root
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- run: ./gradlew :filament:build :filament:publish --stacktrace
|
||||
env:
|
||||
MAVEN_URL: ${{ secrets.MAVEN_URL }}
|
||||
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
|
||||
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
237
build.gradle
237
build.gradle
|
@ -10,7 +10,6 @@ buildscript {
|
|||
dependencies {
|
||||
classpath "cuchaz:enigma-cli:${project.enigma_version}"
|
||||
classpath "net.fabricmc:stitch:${project.stitch_version}"
|
||||
classpath "commons-io:commons-io:2.11.0"
|
||||
classpath "de.undercouch:gradle-download-task:4.1.1"
|
||||
classpath "net.fabricmc.unpick:unpick:${project.unpick_version}"
|
||||
classpath "net.fabricmc.unpick:unpick-format-utils:${project.unpick_version}"
|
||||
|
@ -28,6 +27,10 @@ plugins {
|
|||
|
||||
def minecraft_version = "22w42a"
|
||||
|
||||
filament {
|
||||
minecraftVersion = minecraft_version
|
||||
}
|
||||
|
||||
def ENV = System.getenv()
|
||||
// Fetch build number from Github Actions
|
||||
def build_number = ENV.BUILD_NUMBER ?: "local"
|
||||
|
@ -99,37 +102,27 @@ def mapJarGroup = "jar mapping"
|
|||
def mappingsDir = file("mappings")
|
||||
def cacheFilesMinecraft = file(".gradle/minecraft")
|
||||
def tempDir = file(".gradle/temp")
|
||||
def mergedFile = file("${minecraft_version}-merged.jar")
|
||||
def intermediaryJar = file("${minecraft_version}-intermediary.jar")
|
||||
def unpickedJar = file("${minecraft_version}-intermediary-unpicked.jar")
|
||||
def namedJar = file("${minecraft_version}-named.jar")
|
||||
def versionFile = new File(cacheFilesMinecraft, "${minecraft_version}.json")
|
||||
def clientJar = new File(cacheFilesMinecraft, "${minecraft_version}-client.jar")
|
||||
// The vanilla server bootstrap jar (Contains the real server jar)
|
||||
def serverBootstrapJar = new File(cacheFilesMinecraft, "${minecraft_version}-serverboostrap.jar")
|
||||
// The real server jar, expected from the bootstrap
|
||||
def serverJar = new File(cacheFilesMinecraft, "${minecraft_version}-server.jar")
|
||||
def serverIntermediaryJar = file("${minecraft_version}-server-intermediary.jar")
|
||||
def libraries = new File(cacheFilesMinecraft, "libraries")
|
||||
def libs = new File("build/libs/")
|
||||
|
||||
def minecraftLibraries = tasks.minecraftLibraries.files
|
||||
|
||||
import com.google.common.hash.Hashing
|
||||
import cuchaz.enigma.command.CheckMappingsCommand
|
||||
import cuchaz.enigma.command.ComposeMappingsCommand
|
||||
import cuchaz.enigma.command.ConvertMappingsCommand
|
||||
import cuchaz.enigma.command.MapSpecializedMethodsCommand
|
||||
import groovy.json.JsonSlurper
|
||||
import net.fabricmc.filament.task.MapJarTask
|
||||
import net.fabricmc.stitch.commands.CommandMergeTiny
|
||||
import net.fabricmc.stitch.commands.CommandReorderTiny
|
||||
import net.fabricmc.stitch.commands.CommandRewriteIntermediary
|
||||
import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2
|
||||
import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2
|
||||
import net.fabricmc.stitch.merge.JarMerger
|
||||
import net.fabricmc.nameproposal.MappingNameCompleter
|
||||
import org.apache.commons.io.FileUtils
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
boolean validateChecksum(File file, String checksum) {
|
||||
|
@ -144,85 +137,6 @@ boolean validateChecksum(File file, String checksum) {
|
|||
return false
|
||||
}
|
||||
|
||||
task downloadVersionsManifest {
|
||||
group = setupGroup
|
||||
//inputs.property "mc_ver", minecraft_version
|
||||
inputs.property "currenttime", new Date()
|
||||
def manifestFile = new File(cacheFilesMinecraft, "version_manifest_v2.json")
|
||||
outputs.file(manifestFile)
|
||||
doLast {
|
||||
logger.lifecycle(":downloading minecraft versions manifest")
|
||||
FileUtils.copyURLToFile(new URL("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"), manifestFile)
|
||||
}
|
||||
}
|
||||
|
||||
def getManifestVersion(File manifestFile, String minecraft_version) {
|
||||
def manifest = manifestFile.exists() ? new JsonSlurper().parseText(FileUtils.readFileToString(manifestFile)) : null
|
||||
return manifest != null ? manifest.versions.stream().filter({
|
||||
it.id.equals(minecraft_version)
|
||||
}).findFirst() : java.util.Optional.empty()
|
||||
}
|
||||
|
||||
task downloadWantedVersionManifest(dependsOn: downloadVersionsManifest) {
|
||||
group = setupGroup
|
||||
def manifestFile = downloadVersionsManifest.outputs.files.singleFile
|
||||
def manifestVersion = getManifestVersion(manifestFile, minecraft_version)
|
||||
|
||||
//have to grab the release time as there's a current timestamp on each element?!
|
||||
inputs.property "releaseTime", manifestVersion.isPresent() ? manifestVersion.get().releaseTime : -1
|
||||
|
||||
outputs.file versionFile
|
||||
|
||||
doLast {
|
||||
manifestVersion = getManifestVersion(manifestFile, minecraft_version)
|
||||
//nb need to re-read here in case it didn't exist before
|
||||
if (manifestVersion.isPresent() || versionFile.exists()) {
|
||||
|
||||
if (manifestVersion.isPresent()) {
|
||||
FileUtils.copyURLToFile(new URL(manifestVersion.get().url), versionFile)
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("No version data for Minecraft version ${minecraft_version}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task downloadMcJars(dependsOn: downloadWantedVersionManifest) {
|
||||
group = setupGroup
|
||||
inputs.files versionFile
|
||||
|
||||
outputs.files(clientJar, serverBootstrapJar)
|
||||
|
||||
outputs.upToDateWhen {
|
||||
def version = new JsonSlurper().parseText(FileUtils.readFileToString(versionFile))
|
||||
return clientJar.exists() && serverBootstrapJar.exists() && validateChecksum(clientJar, version.downloads.client.sha1) && validateChecksum(serverBootstrapJar, version.downloads.server.sha1)
|
||||
}
|
||||
|
||||
doLast {
|
||||
if (!versionFile.exists()) {
|
||||
throw new RuntimeException("Can't download the jars without the ${versionFile.name} file!")
|
||||
}
|
||||
|
||||
//reload in case it changed
|
||||
def version = new JsonSlurper().parseText(FileUtils.readFileToString(versionFile))
|
||||
|
||||
logger.lifecycle(":downloading minecraft jars")
|
||||
|
||||
download {
|
||||
src new URL(version.downloads.client.url)
|
||||
dest clientJar
|
||||
overwrite false
|
||||
}
|
||||
|
||||
download {
|
||||
src new URL(version.downloads.server.url)
|
||||
dest serverBootstrapJar
|
||||
overwrite false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task downloadIntermediary(type: Download) {
|
||||
group = buildMappingGroup
|
||||
def url = "https://github.com/FabricMC/intermediary/raw/master/mappings/${minecraft_version}.tiny"
|
||||
|
@ -251,99 +165,6 @@ task downloadIntermediaryV2(type: Download) {
|
|||
}
|
||||
}
|
||||
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
// Extracts the real server jar from the boostrap jar
|
||||
task extractServerJar(dependsOn: downloadMcJars) {
|
||||
group = setupGroup
|
||||
inputs.file serverBootstrapJar
|
||||
outputs.file serverJar
|
||||
|
||||
doLast {
|
||||
new ZipFile(serverBootstrapJar as File).withCloseable { zip ->
|
||||
def serverVersionsEntry = zip.getEntry("META-INF/versions.list")
|
||||
|
||||
if (!serverVersionsEntry) {
|
||||
throw new RuntimeException("Could not find versions.list")
|
||||
}
|
||||
|
||||
def jarPath = null
|
||||
|
||||
zip.getInputStream(serverVersionsEntry).withCloseable { is ->
|
||||
def versions = is.text.split("\t")
|
||||
assert versions.length == 3
|
||||
jarPath = versions[2]
|
||||
}
|
||||
|
||||
def serverJarEntry = zip.getEntry("META-INF/versions/${jarPath}")
|
||||
|
||||
if (!serverJarEntry) {
|
||||
throw new RuntimeException("Failed to find server jar entry ${jarPath}")
|
||||
}
|
||||
|
||||
zip.getInputStream(serverJarEntry).withCloseable { is ->
|
||||
serverJar.bytes = is.readAllBytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task mergeJars(dependsOn: extractServerJar) {
|
||||
group = setupGroup
|
||||
inputs.files (serverJar, clientJar)
|
||||
outputs.file(mergedFile)
|
||||
|
||||
doLast {
|
||||
logger.lifecycle(":merging jars")
|
||||
|
||||
if (mergedFile.exists()) {
|
||||
return
|
||||
}
|
||||
|
||||
def jarMerger = new JarMerger(clientJar, serverJar, mergedFile)
|
||||
jarMerger.merge()
|
||||
jarMerger.close()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task downloadMcLibs(dependsOn: downloadWantedVersionManifest) {
|
||||
group = setupGroup
|
||||
inputs.files versionFile
|
||||
|
||||
outputs.dir(libraries)
|
||||
|
||||
outputs.upToDateWhen { false }
|
||||
|
||||
doLast {
|
||||
if (!versionFile.exists()) {
|
||||
throw new RuntimeException("Can't download the jars without the ${versionFile.name} file!")
|
||||
}
|
||||
|
||||
def version = new JsonSlurper().parseText(FileUtils.readFileToString(versionFile, StandardCharsets.UTF_8))
|
||||
|
||||
logger.lifecycle(":downloading minecraft libraries")
|
||||
|
||||
if (!libraries.exists()) {
|
||||
libraries.mkdirs()
|
||||
}
|
||||
|
||||
version.libraries.each {
|
||||
if (it.downloads.artifact == null) return // TODO: happens for downloads.classifiers - implement properly?
|
||||
|
||||
def downloadUrl = it.downloads.artifact.url
|
||||
|
||||
download {
|
||||
src downloadUrl
|
||||
dest new File(libraries, downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1))
|
||||
overwrite false
|
||||
}
|
||||
|
||||
project.dependencies.add("decompileClasspath", it.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task invertIntermediary(dependsOn: downloadIntermediary, type: FileOutput) {
|
||||
group = buildMappingGroup
|
||||
def v1Input = downloadIntermediary.dest
|
||||
|
@ -388,7 +209,7 @@ task invertIntermediaryv2(dependsOn: downloadIntermediaryV2, type: FileOutput) {
|
|||
}
|
||||
}
|
||||
|
||||
task patchIntermediary(dependsOn: [mergeJars, downloadIntermediary]) {
|
||||
task patchIntermediary(dependsOn: [mergeMinecraftJars, downloadIntermediary]) {
|
||||
group = buildMappingGroup
|
||||
def intermediaryTinyInput = downloadIntermediary.outputs.files.singleFile
|
||||
|
||||
|
@ -400,7 +221,7 @@ task patchIntermediary(dependsOn: [mergeJars, downloadIntermediary]) {
|
|||
doLast {
|
||||
logger.lifecycle(":patching intermediary")
|
||||
String[] args = [
|
||||
mergedFile.getAbsolutePath(),
|
||||
mergeMinecraftJars.output.getAbsolutePath(),
|
||||
intermediaryTinyInput.getAbsolutePath(),
|
||||
outputFile.getAbsolutePath(),
|
||||
"--writeAll"
|
||||
|
@ -410,22 +231,22 @@ task patchIntermediary(dependsOn: [mergeJars, downloadIntermediary]) {
|
|||
}
|
||||
}
|
||||
|
||||
task mapIntermediaryJar(type: MapJarTask, dependsOn: [downloadMcLibs, downloadIntermediary, mergeJars]) {
|
||||
task mapIntermediaryJar(type: MapJarTask, dependsOn: [downloadIntermediary, mergeMinecraftJars]) {
|
||||
group = mapJarGroup
|
||||
output = intermediaryJar
|
||||
input = mergedFile
|
||||
input = mergeMinecraftJars.outputFile
|
||||
mappings = downloadIntermediary.dest
|
||||
classpath.from fileTree(libraries)
|
||||
classpath.from minecraftLibraries
|
||||
from = 'official'
|
||||
to = 'intermediary'
|
||||
}
|
||||
|
||||
task mapServerIntermediaryJar(type: MapJarTask, dependsOn: [downloadMcLibs, downloadIntermediary, extractServerJar]) {
|
||||
task mapServerIntermediaryJar(type: MapJarTask, dependsOn: [downloadIntermediary, extractBundledServer]) {
|
||||
group = mapJarGroup
|
||||
output = serverIntermediaryJar
|
||||
input = serverJar
|
||||
input = extractBundledServer.outputFile
|
||||
mappings = downloadIntermediary.dest
|
||||
classpath.from fileTree(libraries)
|
||||
classpath.from minecraftLibraries
|
||||
from = 'official'
|
||||
to = 'intermediary'
|
||||
}
|
||||
|
@ -643,7 +464,7 @@ task unpickIntermediaryJar(type: JavaExec, dependsOn: [mapIntermediaryJar, "cons
|
|||
doFirst {
|
||||
args intermediaryJar.absolutePath, unpickedJar.absolutePath, remapUnpickDefinitionsIntermediary.output.get().asFile.absolutePath, constantsJar.archiveFile.get().asFile.absolutePath
|
||||
|
||||
configurations.decompileClasspath.files.each {
|
||||
minecraftLibraries.files.forEach {
|
||||
args it.absolutePath
|
||||
}
|
||||
}
|
||||
|
@ -782,7 +603,7 @@ task mapNamedJar(type: MapJarTask, dependsOn: ["mergeV2", "unpickIntermediaryJar
|
|||
output = namedJar
|
||||
input = unpickedJar
|
||||
mappings = mergeV2.output
|
||||
classpath.from fileTree(libraries)
|
||||
classpath.from minecraftLibraries
|
||||
from = 'intermediary'
|
||||
to = 'named'
|
||||
classMappings = [
|
||||
|
@ -792,15 +613,23 @@ task mapNamedJar(type: MapJarTask, dependsOn: ["mergeV2", "unpickIntermediaryJar
|
|||
]
|
||||
}
|
||||
|
||||
def mcLibsDir = file('build/tmp/mclibs')
|
||||
|
||||
// Task to copy all the mc libs into a single directory.
|
||||
task syncDependencies(type: Sync) {
|
||||
from minecraftLibraries
|
||||
into mcLibsDir
|
||||
}
|
||||
|
||||
def fakeSourceDir = file(".gradle/temp/fakeSource")
|
||||
task genFakeSource(type: JavaExec, dependsOn: ["mergeV2", "mapNamedJar"]) {
|
||||
task genFakeSource(type: JavaExec, dependsOn: ["mergeV2", "mapNamedJar", syncDependencies]) {
|
||||
group = "javadoc generation"
|
||||
outputs.upToDateWhen { false }
|
||||
|
||||
mainClass = "net.fabricmc.mappingpoet.Main"
|
||||
classpath configurations.mappingPoet
|
||||
// use merged v2 so we have all namespaces in jd
|
||||
args mergeV2.output.getAbsolutePath(), namedJar.getAbsolutePath(), fakeSourceDir.getAbsolutePath(), libraries.getAbsolutePath()
|
||||
args mergeV2.output.getAbsolutePath(), namedJar.getAbsolutePath(), fakeSourceDir.getAbsolutePath(), mcLibsDir.getAbsolutePath()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle ":Fake source generated"
|
||||
|
@ -814,13 +643,13 @@ task decompileCFR(type: JavaExec, dependsOn: [mapNamedJar]) {
|
|||
|
||||
doFirst {
|
||||
file("namedSrc").deleteDir()
|
||||
classpath = configurations.decompileClasspath
|
||||
classpath.from configurations.decompileClasspath
|
||||
classpath.from minecraftLibraries
|
||||
}
|
||||
}
|
||||
|
||||
javadoc {
|
||||
dependsOn genFakeSource
|
||||
dependsOn downloadMcLibs
|
||||
group = "javadoc generation"
|
||||
outputs.upToDateWhen { false }
|
||||
|
||||
|
@ -878,7 +707,7 @@ javadoc {
|
|||
addBooleanOption 'Xdoclint:accessibility', true
|
||||
}
|
||||
source fileTree(fakeSourceDir) + sourceSets.constants.allJava + sourceSets.packageDocs.allJava
|
||||
classpath = configurations.javadocClasspath.plus downloadMcLibs.outputs.files.asFileTree
|
||||
classpath = configurations.javadocClasspath.plus minecraftLibraries
|
||||
|
||||
doLast {
|
||||
project.copy {
|
||||
|
@ -979,14 +808,6 @@ class FileOutput extends DefaultTask {
|
|||
File output
|
||||
}
|
||||
|
||||
class FileOutputInput extends DefaultTask {
|
||||
@InputFile
|
||||
File input
|
||||
|
||||
@OutputFile
|
||||
File output
|
||||
}
|
||||
|
||||
class WithV2FileOutput extends DefaultTask {
|
||||
@OutputFile
|
||||
File v1Output
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
import org.gradle.util.GradleVersion
|
||||
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'java-gradle-plugin'
|
||||
id 'checkstyle'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
group = 'net.fabricmc'
|
||||
version = project.filament_version
|
||||
|
||||
def ENV = System.getenv()
|
||||
|
||||
// Needed to read the main projects properties
|
||||
def properties = new Properties()
|
||||
file('../gradle.properties').newInputStream().withCloseable {
|
||||
properties.load(it)
|
||||
|
@ -27,6 +34,16 @@ dependencies {
|
|||
implementation "net.fabricmc.unpick:unpick-format-utils:$properties.unpick_version"
|
||||
implementation "net.fabricmc:tiny-mappings-parser:$properties.tiny_mappings_parser_version"
|
||||
implementation "net.fabricmc:tiny-remapper:$properties.tiny_remapper_version"
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
|
||||
|
||||
// Contains a number of useful utilities we can re-use.
|
||||
implementation ("net.fabricmc:fabric-loom:1.0.7") {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
implementation ('net.fabricmc:stitch:0.6.2') {
|
||||
exclude module: 'enigma'
|
||||
}
|
||||
|
||||
testImplementation platform("org.junit:junit-bom:$properties.junit_version")
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
|
@ -54,4 +71,40 @@ gradlePlugin {
|
|||
implementationClass = 'net.fabricmc.filament.FilamentGradlePlugin'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
if (ENV.MAVEN_URL) {
|
||||
repositories.maven {
|
||||
name "fabric"
|
||||
url ENV.MAVEN_URL
|
||||
credentials {
|
||||
username ENV.MAVEN_USERNAME
|
||||
password ENV.MAVEN_PASSWORD
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this task to download the gradle sources next to the api jar, you may need to manually attach the sources jar
|
||||
*/
|
||||
task downloadGradleSources() {
|
||||
doLast {
|
||||
// Awful hack to find the gradle api location
|
||||
def gradleApiFile = project.configurations.detachedConfiguration(dependencies.gradleApi()).files.stream()
|
||||
.filter {
|
||||
it.name.startsWith("gradle-api")
|
||||
}.findFirst().orElseThrow()
|
||||
|
||||
def gradleApiSources = new File(gradleApiFile.absolutePath.replace(".jar", "-sources.jar"))
|
||||
def url = "https://services.gradle.org/distributions/gradle-${GradleVersion.current().getVersion()}-src.zip"
|
||||
|
||||
gradleApiSources.delete()
|
||||
|
||||
println("Downloading (${url}) to (${gradleApiSources})")
|
||||
gradleApiSources << new URL(url).newInputStream()
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
filament_version=0.4.0
|
|
@ -0,0 +1,35 @@
|
|||
package net.fabricmc.filament;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
public abstract class FilamentExtension {
|
||||
public static FilamentExtension get(Project project) {
|
||||
return project.getExtensions().getByType(FilamentExtension.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
protected abstract Project getProject();
|
||||
|
||||
public abstract Property<String> getMinecraftVersion();
|
||||
|
||||
public abstract Property<String> getMinecraftVersionManifestUrl();
|
||||
|
||||
@Inject
|
||||
public FilamentExtension() {
|
||||
getMinecraftVersion().finalizeValueOnRead();
|
||||
getMinecraftVersionManifestUrl().convention("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json").finalizeValueOnRead();
|
||||
}
|
||||
|
||||
public File getCacheDirectory() {
|
||||
return new File(getProject().getRootDir(), ".gradle/filament");
|
||||
}
|
||||
|
||||
public File getMinecraftDirectory() {
|
||||
return new File(getCacheDirectory(), getMinecraftVersion().get());
|
||||
}
|
||||
}
|
|
@ -1,25 +1,86 @@
|
|||
package net.fabricmc.filament;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.TaskContainer;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
import net.fabricmc.filament.task.CombineUnpickDefinitionsTask;
|
||||
import net.fabricmc.filament.task.DownloadTask;
|
||||
import net.fabricmc.filament.task.GeneratePackageInfoMappingsTask;
|
||||
import net.fabricmc.filament.task.JavadocLintTask;
|
||||
import net.fabricmc.filament.task.RemapUnpickDefinitionsTask;
|
||||
import net.fabricmc.filament.task.base.FileOutputTask;
|
||||
import net.fabricmc.filament.task.minecraft.ExtractBundledServerTask;
|
||||
import net.fabricmc.filament.task.minecraft.MergeMinecraftTask;
|
||||
import net.fabricmc.filament.task.minecraft.MinecraftLibrariesTask;
|
||||
import net.fabricmc.filament.task.minecraft.MinecraftVersionMetaTask;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||
|
||||
public final class FilamentGradlePlugin implements Plugin<Project> {
|
||||
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getTasks().register("generatePackageInfoMappings", GeneratePackageInfoMappingsTask.class);
|
||||
project.getTasks().register("javadocLint", JavadocLintTask.class);
|
||||
final FilamentExtension extension = project.getExtensions().create("filament", FilamentExtension.class);
|
||||
final TaskContainer tasks = project.getTasks();
|
||||
|
||||
var combineUnpickDefinitions = project.getTasks().register("combineUnpickDefinitions", CombineUnpickDefinitionsTask.class);
|
||||
project.getTasks().register("remapUnpickDefinitionsIntermediary", RemapUnpickDefinitionsTask.class, task -> {
|
||||
var minecraftMetaTask = tasks.register("downloadMinecraftMeta", MinecraftVersionMetaTask.class);
|
||||
var metaProvider = MinecraftVersionMetaTask.readMetadata(minecraftMetaTask);
|
||||
|
||||
var minecraftClient = tasks.register("downloadMinecraftClientJar", DownloadTask.class, task -> {
|
||||
Provider<MinecraftVersionMeta.Download> downloadProvider = metaProvider.map(meta -> meta.download("client"));
|
||||
task.getUrl().set(downloadProvider.map(MinecraftVersionMeta.Download::url));
|
||||
task.getSha1().set(downloadProvider.map(MinecraftVersionMeta.Download::sha1));
|
||||
|
||||
task.getOutputFile().set(new File(extension.getMinecraftDirectory(), "client.jar"));
|
||||
});
|
||||
var minecraftServer = tasks.register("downloadMinecraftServerJar", DownloadTask.class, task -> {
|
||||
Provider<MinecraftVersionMeta.Download> downloadProvider = metaProvider.map(meta -> meta.download("server"));
|
||||
task.getUrl().set(downloadProvider.map(MinecraftVersionMeta.Download::url));
|
||||
task.getSha1().set(downloadProvider.map(MinecraftVersionMeta.Download::sha1));
|
||||
|
||||
task.getOutputFile().set(new File(extension.getMinecraftDirectory(), "server_bundle.jar"));
|
||||
});
|
||||
var extractBundledServer = tasks.register("extractBundledServer", ExtractBundledServerTask.class, task -> {
|
||||
task.dependsOn(minecraftServer);
|
||||
task.getServerJar().set(getOutput(minecraftServer));
|
||||
task.getOutputFile().set(new File(extension.getMinecraftDirectory(), "server.jar"));
|
||||
});
|
||||
tasks.register("mergeMinecraftJars", MergeMinecraftTask.class, task -> {
|
||||
task.getClientJar().set(getOutput(minecraftClient));
|
||||
task.getServerJar().set(getOutput(extractBundledServer));
|
||||
|
||||
task.getOutputFile().set(new File(extension.getMinecraftDirectory(), "merged.jar"));
|
||||
});
|
||||
tasks.register("generatePackageInfoMappings", GeneratePackageInfoMappingsTask.class);
|
||||
tasks.register("javadocLint", JavadocLintTask.class);
|
||||
|
||||
var combineUnpickDefinitions = tasks.register("combineUnpickDefinitions", CombineUnpickDefinitionsTask.class);
|
||||
tasks.register("remapUnpickDefinitionsIntermediary", RemapUnpickDefinitionsTask.class, task -> {
|
||||
task.dependsOn(combineUnpickDefinitions);
|
||||
task.getInput().set(combineUnpickDefinitions.flatMap(CombineUnpickDefinitionsTask::getOutput));
|
||||
task.getSourceNamespace().set("named");
|
||||
task.getTargetNamespace().set("intermediary");
|
||||
});
|
||||
|
||||
tasks.register("minecraftLibraries", MinecraftLibrariesTask.class, task -> {
|
||||
task.dependsOn(minecraftMetaTask);
|
||||
|
||||
var files = MinecraftVersionMetaTask.readMetadata(minecraftMetaTask)
|
||||
.map(meta -> MinecraftLibrariesTask.getDependencies(project, meta))
|
||||
.map(dependencies -> project.getConfigurations().detachedConfiguration(dependencies).resolve());
|
||||
task.getFiles().from(files);
|
||||
});
|
||||
}
|
||||
|
||||
private Provider<RegularFile> getOutput(TaskProvider<? extends FileOutputTask> taskProvider) {
|
||||
return taskProvider.flatMap(FileOutputTask::getOutputFile);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.workers.WorkAction;
|
||||
import org.gradle.workers.WorkParameters;
|
||||
import org.gradle.workers.WorkQueue;
|
||||
import org.gradle.workers.WorkerExecutor;
|
||||
|
||||
import net.fabricmc.filament.task.base.FileOutputTask;
|
||||
import net.fabricmc.loom.util.download.Download;
|
||||
import net.fabricmc.loom.util.download.DownloadException;
|
||||
|
||||
public abstract class DownloadTask extends FileOutputTask {
|
||||
@Input
|
||||
public abstract Property<String> getUrl();
|
||||
@Input
|
||||
public abstract Property<String> getSha1();
|
||||
|
||||
@Inject
|
||||
protected abstract WorkerExecutor getWorkerExecutor();
|
||||
|
||||
@TaskAction
|
||||
public void run() {
|
||||
WorkQueue workQueue = getWorkerExecutor().noIsolation();
|
||||
workQueue.submit(DownloadAction.class, parameters -> {
|
||||
parameters.getUrl().set(getUrl());
|
||||
parameters.getSha1().set(getSha1());
|
||||
parameters.getOutput().set(getOutputFile());
|
||||
});
|
||||
}
|
||||
|
||||
public interface DownloadParameters extends WorkParameters {
|
||||
Property<String> getUrl();
|
||||
Property<String> getSha1();
|
||||
RegularFileProperty getOutput();
|
||||
}
|
||||
|
||||
public abstract static class DownloadAction implements WorkAction<DownloadParameters> {
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
Download.create(getParameters().getUrl().get())
|
||||
.sha1(getParameters().getSha1().get())
|
||||
.downloadPath(getParameters().getOutput().get().getAsFile().toPath());
|
||||
} catch (DownloadException | URISyntaxException e) {
|
||||
throw new RuntimeException("Failed to download", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -104,7 +104,7 @@ public abstract class JavadocLintTask extends DefaultTask {
|
|||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
var files = FileUtil.toPaths(getParameters().getMappingFiles().getFiles()).toArray(new Path[0]);
|
||||
Path[] files = FileUtil.toPaths(getParameters().getMappingFiles().getFiles()).toArray(new Path[0]);
|
||||
EntryTree<EntryMapping> mappings = EnigmaMappingsReader.readFiles(ProgressListener.none(), files);
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -11,8 +12,6 @@ import javax.inject.Inject;
|
|||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.FileSystemLocation;
|
||||
import org.gradle.api.file.FileVisitDetails;
|
||||
import org.gradle.api.file.FileVisitor;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.MapProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
@ -108,19 +107,11 @@ public abstract class MapJarTask extends DefaultTask {
|
|||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) {
|
||||
Path input = getPath(params.getInput());
|
||||
outputConsumer.addNonClassFiles(input);
|
||||
remapper.readInputs(input);
|
||||
remapper.readInputsAsync(input);
|
||||
|
||||
params.getClasspath().getAsFileTree().visit(new FileVisitor() {
|
||||
@Override
|
||||
public void visitDir(FileVisitDetails dirDetails) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFile(FileVisitDetails fileDetails) {
|
||||
remapper.readClassPath(fileDetails.getFile().toPath());
|
||||
}
|
||||
});
|
||||
for (File file : params.getClasspath().getFiles()) {
|
||||
remapper.readClassPathAsync(file.toPath());
|
||||
}
|
||||
|
||||
remapper.apply(outputConsumer);
|
||||
} finally {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package net.fabricmc.filament.task.base;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
|
||||
import net.fabricmc.filament.FilamentExtension;
|
||||
|
||||
public abstract class FilamentTask extends DefaultTask {
|
||||
@Inject
|
||||
public FilamentTask() {
|
||||
setGroup("filament");
|
||||
}
|
||||
|
||||
@Internal
|
||||
protected FilamentExtension getExtension() {
|
||||
return FilamentExtension.get(getProject());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package net.fabricmc.filament.task.base;
|
||||
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
|
||||
public abstract class FileOutputTask extends FilamentTask {
|
||||
@OutputFile
|
||||
public abstract RegularFileProperty getOutputFile();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.fabricmc.filament.task.minecraft;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import net.fabricmc.filament.task.base.FileOutputTask;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
|
||||
public abstract class ExtractBundledServerTask extends FileOutputTask {
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getServerJar();
|
||||
|
||||
@TaskAction
|
||||
public void run() throws IOException {
|
||||
try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(getServerJar().get().getAsFile().toPath(), false)) {
|
||||
String versionsList = new String(fs.readAllBytes("META-INF/versions.list"), StandardCharsets.UTF_8);
|
||||
String jarPath = "META-INF/versions/" + versionsList.split("\t")[2];
|
||||
Files.copy(fs.getPath(jarPath), getOutputFile().get().getAsFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package net.fabricmc.filament.task.minecraft;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import net.fabricmc.filament.task.base.FileOutputTask;
|
||||
import net.fabricmc.stitch.merge.JarMerger;
|
||||
|
||||
public abstract class MergeMinecraftTask extends FileOutputTask {
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getClientJar();
|
||||
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getServerJar();
|
||||
|
||||
@TaskAction
|
||||
public void run() throws IOException {
|
||||
try (JarMerger jarMerger = new JarMerger(
|
||||
getClientJar().getAsFile().get(),
|
||||
getServerJar().getAsFile().get(),
|
||||
getOutputFile().getAsFile().get())) {
|
||||
jarMerger.merge();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package net.fabricmc.filament.task.minecraft;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.tasks.OutputFiles;
|
||||
|
||||
import net.fabricmc.filament.task.base.FilamentTask;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||
|
||||
public abstract class MinecraftLibrariesTask extends FilamentTask {
|
||||
@OutputFiles
|
||||
public abstract ConfigurableFileCollection getFiles();
|
||||
|
||||
public static Dependency[] getDependencies(Project project, MinecraftVersionMeta meta) {
|
||||
return meta.libraries().stream()
|
||||
.filter(library -> library.artifact() != null)
|
||||
.map(library -> project.getDependencies().create(library.name()))
|
||||
.toArray(Dependency[]::new);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package net.fabricmc.filament.task.minecraft;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import net.fabricmc.filament.FilamentGradlePlugin;
|
||||
import net.fabricmc.filament.task.base.FilamentTask;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.ManifestVersion;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||
import net.fabricmc.loom.util.download.Download;
|
||||
|
||||
public abstract class MinecraftVersionMetaTask extends FilamentTask {
|
||||
@Input
|
||||
public abstract Property<String> getMinecraftVersion();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getMinecraftVersionManifestUrl();
|
||||
|
||||
@OutputFile
|
||||
public abstract RegularFileProperty getVersionManifest();
|
||||
|
||||
@OutputFile
|
||||
public abstract RegularFileProperty getVersionMetadata();
|
||||
|
||||
public MinecraftVersionMetaTask() {
|
||||
// Use the Minecraft version as an input to ensure the task re-runs on upgrade
|
||||
getMinecraftVersion().set(getExtension().getMinecraftVersion());
|
||||
getMinecraftVersionManifestUrl().set(getExtension().getMinecraftVersionManifestUrl());
|
||||
|
||||
getVersionManifest().set(new File(getExtension().getCacheDirectory(), "version_manifest.json"));
|
||||
getVersionMetadata().set(new File(getExtension().getMinecraftDirectory(), "version.json"));
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void run() throws IOException, URISyntaxException {
|
||||
final Path versionManifestPath = getVersionManifest().getAsFile().get().toPath();
|
||||
final Path versionMetadataPath = getVersionMetadata().getAsFile().get().toPath();
|
||||
|
||||
final String versionManifest = Download.create(getMinecraftVersionManifestUrl().get())
|
||||
.downloadString(versionManifestPath);
|
||||
|
||||
final ManifestVersion mcManifest = FilamentGradlePlugin.OBJECT_MAPPER.readValue(versionManifest, ManifestVersion.class);
|
||||
|
||||
ManifestVersion.Versions version = mcManifest.versions().stream()
|
||||
.filter(versions -> versions.id.equalsIgnoreCase(getMinecraftVersion().get()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (version == null) {
|
||||
throw new RuntimeException("Failed to find minecraft version: " + getMinecraftVersion().get());
|
||||
}
|
||||
|
||||
Download.create(version.url)
|
||||
.sha1(version.sha1)
|
||||
.downloadPath(versionMetadataPath);
|
||||
}
|
||||
|
||||
public static Provider<MinecraftVersionMeta> readMetadata(Provider<MinecraftVersionMetaTask> task) {
|
||||
return task.flatMap(t -> readMetadata(t.getVersionMetadata()));
|
||||
}
|
||||
|
||||
public static Provider<MinecraftVersionMeta> readMetadata(RegularFileProperty file) {
|
||||
return file.map(regularFile -> {
|
||||
try {
|
||||
String versionManifest = Files.readString(regularFile.getAsFile().toPath(), StandardCharsets.UTF_8);
|
||||
return FilamentGradlePlugin.OBJECT_MAPPER.readValue(versionManifest, MinecraftVersionMeta.class);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -2,6 +2,10 @@ plugins {
|
|||
id 'net.fabricmc.filament'
|
||||
}
|
||||
|
||||
filament {
|
||||
minecraftVersion = "1.19.2"
|
||||
}
|
||||
|
||||
javadocLint {
|
||||
mappingDirectory = file('mappings')
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@ plugins {
|
|||
id 'net.fabricmc.filament'
|
||||
}
|
||||
|
||||
filament {
|
||||
minecraftVersion = "1.19.2"
|
||||
}
|
||||
|
||||
combineUnpickDefinitions {
|
||||
input = file('unpick-definitions')
|
||||
output = file('combined_definitions.unpick')
|
||||
|
|
|
@ -7,7 +7,7 @@ unpick_version=2.3.0
|
|||
cfr_version=0.1.1
|
||||
name_proposal_version=0.1.4
|
||||
tiny_remapper_version=0.8.2
|
||||
asm_version=9.3
|
||||
asm_version=9.4
|
||||
|
||||
# Javadoc generation/linking
|
||||
fabric_loader_version=0.13.3
|
||||
|
|
Loading…
Reference in New Issue