From b15b5af29377bc4181d2a7f5ff59668f7c92dad1 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Sun, 28 Apr 2024 14:12:33 +0200 Subject: [PATCH] Fix injection logic not taking into accounts that trees might need to be offset by a prefix. (#156) --- README.md | 6 +- .../common/runtime/tasks/DefaultRuntime.java | 4 +- .../tasks/ObfuscatedDependencyMarker.java | 63 ------------------- .../extensions/NeoFormRuntimeExtension.java | 1 + .../tasks/InjectFromFileTreeSource.java | 52 +++++++++++++-- .../util/ZipBuildingFileTreeVisitor.java | 12 +++- 6 files changed, 63 insertions(+), 75 deletions(-) delete mode 100644 common/src/main/java/net/neoforged/gradle/common/tasks/ObfuscatedDependencyMarker.java diff --git a/README.md b/README.md index 70c58d6d4..9041a5dc1 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ plugins { dependencies { // For depending on a Minecraft JAR-file with both client- and server-classes - implementation "net.minecraft:neoform_joined:' + implementation "net.minecraft:neoform_joined:" // For depending on the Minecraft client JAR-file - implementation "net.minecraft:neoform_client:' + implementation "net.minecraft:neoform_client:" // For depending on the Minecraft dedicated server JAR-file - implementation "net.minecraft:neoform_server:' + implementation "net.minecraft:neoform_server:" } ``` diff --git a/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/DefaultRuntime.java b/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/DefaultRuntime.java index 1688bf347..bbd20a108 100644 --- a/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/DefaultRuntime.java +++ b/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/DefaultRuntime.java @@ -49,8 +49,8 @@ public DefaultRuntime() { Map.Entry::getKey, entry -> getNeoFormArchive() .getAsFileTree() - .matching(archive -> archive.include(entry.getValue()) - ))))); + .matching(archive -> archive.include(entry.getValue())) + )))); getOutputDirectory().finalizeValueOnRead(); } diff --git a/common/src/main/java/net/neoforged/gradle/common/tasks/ObfuscatedDependencyMarker.java b/common/src/main/java/net/neoforged/gradle/common/tasks/ObfuscatedDependencyMarker.java deleted file mode 100644 index 81aa6f1bb..000000000 --- a/common/src/main/java/net/neoforged/gradle/common/tasks/ObfuscatedDependencyMarker.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.neoforged.gradle.common.tasks; - -import net.neoforged.gradle.util.AdaptingZipBuildingFileTreeVisitor; -import net.neoforged.gradle.dsl.common.tasks.WithOutput; -import net.neoforged.gradle.dsl.common.tasks.WithWorkspace; -import org.gradle.api.DefaultTask; -import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.tasks.CacheableTask; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; -import org.gradle.api.tasks.TaskAction; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.jar.Attributes; -import java.util.jar.Manifest; -import java.util.zip.ZipOutputStream; - -@CacheableTask -public abstract class ObfuscatedDependencyMarker extends DefaultTask implements WithOutput, WithWorkspace { - - - public ObfuscatedDependencyMarker() { - super(); - getOutput().convention(getProject().getLayout().getBuildDirectory().dir("obfuscated").flatMap(directory -> getObfuscatedJar().map(input -> directory.file(input.getAsFile().getName().substring(0, input.getAsFile().getName().length() - 4) + "-marked.jar")))); - } - - @TaskAction - public void doMark() { - try { - final File outputJar = this.ensureFileWorkspaceReady(getOutput()); - final FileOutputStream fileOutputStream = new FileOutputStream(outputJar); - final ZipOutputStream outputZipStream = new ZipOutputStream(fileOutputStream); - final AdaptingZipBuildingFileTreeVisitor zipBuildingFileTreeVisitor = new AdaptingZipBuildingFileTreeVisitor(outputZipStream, (fileVisitDetails, outputStream) -> { - if (!fileVisitDetails.getRelativePath().getPathString().equals("META-INF/MANIFEST.MF")) { - fileVisitDetails.copyTo(outputStream); - return; - } - try { - Manifest manifest = new Manifest(fileVisitDetails.open()); - Attributes mainAttributes = manifest.getMainAttributes(); - mainAttributes.putValue("Obfuscated", "true"); - mainAttributes.putValue("Obfuscated-By", "NeoGradle"); - - manifest.write(outputStream); - } catch (IOException e) { - throw new RuntimeException("Failed to write manifest", e); - } - }); - getProject().zipTree(getObfuscatedJar().get()).visit(zipBuildingFileTreeVisitor); - outputZipStream.close(); - fileOutputStream.close(); - } catch (IOException e) { - throw new RuntimeException("Failed to create recompiled output jar", e); - } - } - - @InputFile - @PathSensitive(PathSensitivity.NONE) - public abstract RegularFileProperty getObfuscatedJar(); -} diff --git a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java index 36101f366..8a5a46bd4 100644 --- a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java +++ b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java @@ -128,6 +128,7 @@ private static TaskProvider createBuiltIn(final NeoFormRun } }) ); + fileTreeSource.getTreePrefix().set(task.getSymbolicDataSources().map(data -> data.get("inject"))); return fileTreeSource; }) ); diff --git a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/InjectFromFileTreeSource.java b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/InjectFromFileTreeSource.java index c9d99c185..e05fe46f7 100644 --- a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/InjectFromFileTreeSource.java +++ b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/InjectFromFileTreeSource.java @@ -3,13 +3,14 @@ import net.neoforged.gradle.util.ZipBuildingFileTreeVisitor; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileTree; -import org.gradle.api.tasks.InputFiles; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.file.FileVisitDetails; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.*; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.nio.file.Files; +import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** @@ -22,10 +23,15 @@ public abstract class InjectFromFileTreeSource extends AbstractInjectSource { @PathSensitive(PathSensitivity.NONE) public abstract ConfigurableFileCollection getFiles(); + @Optional + @Input + public abstract Property getTreePrefix(); + @Override public byte @Nullable [] tryReadFile(String path) throws IOException { + final String lookupPath = buildTreePrefix() + path; final FileTree matching = getFiles().getAsFileTree().matching(createFilter()) - .matching(pattern -> pattern.include(path)); + .matching(pattern -> pattern.include(lookupPath)); if (matching.isEmpty()) { return null; } @@ -39,6 +45,42 @@ public void copyTo(ZipOutputStream out) throws IOException { } final FileTree source = getFiles().getAsFileTree().matching(createFilter()); - source.visit(new ZipBuildingFileTreeVisitor(out)); + source.visit(new ZipBuildingFileTreeVisitor(out) { + @Override + protected ZipEntry createDirectory(FileVisitDetails fileVisitDetails) { + String path = fileVisitDetails.getRelativePath().getPathString(); + if (path.startsWith(buildTreePrefix())) { + path = path.substring(buildTreePrefix().length()); + } + + if (!path.endsWith("/")) { + path += "/"; + } + + return new ZipEntry(path); + } + + @Override + protected ZipEntry createFile(FileVisitDetails fileVisitDetails) { + String path = fileVisitDetails.getRelativePath().getPathString(); + if (path.startsWith(buildTreePrefix())) { + path = path.substring(buildTreePrefix().length()); + } + + return new ZipEntry(path); + } + }); + } + + private String buildTreePrefix() { + if (getTreePrefix().isPresent()) { + final String prefix = getTreePrefix().get(); + if (!prefix.endsWith("/")) { + return prefix + "/"; + } + return prefix; + } + + return ""; } } diff --git a/utils/src/main/java/net/neoforged/gradle/util/ZipBuildingFileTreeVisitor.java b/utils/src/main/java/net/neoforged/gradle/util/ZipBuildingFileTreeVisitor.java index d0e91d4c1..93e892a01 100644 --- a/utils/src/main/java/net/neoforged/gradle/util/ZipBuildingFileTreeVisitor.java +++ b/utils/src/main/java/net/neoforged/gradle/util/ZipBuildingFileTreeVisitor.java @@ -24,7 +24,7 @@ public ZipBuildingFileTreeVisitor(ZipOutputStream outputZipStream) { @Override public void visitDir(FileVisitDetails fileVisitDetails) { try { - final ZipEntry directoryEntry = new ZipEntry(fileVisitDetails.getRelativePath().getPathString() + "/"); + final ZipEntry directoryEntry = createDirectory(fileVisitDetails); outputZipStream.putNextEntry(directoryEntry); outputZipStream.closeEntry(); } catch (IOException zip) { @@ -33,11 +33,15 @@ public void visitDir(FileVisitDetails fileVisitDetails) { } } } + + protected ZipEntry createDirectory(FileVisitDetails fileVisitDetails) { + return new ZipEntry(fileVisitDetails.getRelativePath().getPathString() + "/"); + } @Override public void visitFile(FileVisitDetails fileVisitDetails) { try { - final ZipEntry fileEntry = new ZipEntry(fileVisitDetails.getRelativePath().getPathString()); + final ZipEntry fileEntry = createFile(fileVisitDetails); outputZipStream.putNextEntry(fileEntry); fileVisitDetails.copyTo(outputZipStream); outputZipStream.closeEntry(); @@ -45,4 +49,8 @@ public void visitFile(FileVisitDetails fileVisitDetails) { throw new RuntimeException("Could not create zip file: " + fileVisitDetails.getRelativePath().getPathString(), e); } } + + protected ZipEntry createFile(FileVisitDetails fileVisitDetails) { + return new ZipEntry(fileVisitDetails.getRelativePath().getPathString()); + } }