Rewrite mc downloading in filament (#3301)

This commit is contained in:
modmuss50 2022-10-23 19:29:44 +01:00 committed by GitHub
parent a837ae344b
commit 8349f2bc13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 460 additions and 228 deletions

16
.github/workflows/release-filament.yml vendored Normal file
View File

@ -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 }}

View File

@ -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

View File

@ -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()
}
}

View File

@ -0,0 +1 @@
filament_version=0.4.0

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}
}

View File

@ -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<>();

View File

@ -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 {

View File

@ -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());
}
}

View File

@ -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();
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
});
}
}

View File

@ -2,6 +2,10 @@ plugins {
id 'net.fabricmc.filament'
}
filament {
minecraftVersion = "1.19.2"
}
javadocLint {
mappingDirectory = file('mappings')
}

View File

@ -2,6 +2,10 @@ plugins {
id 'net.fabricmc.filament'
}
filament {
minecraftVersion = "1.19.2"
}
combineUnpickDefinitions {
input = file('unpick-definitions')
output = file('combined_definitions.unpick')

View File

@ -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