diff --git a/enigma-cli/build.gradle b/enigma-cli/build.gradle index 152d22ca5..e90302775 100644 --- a/enigma-cli/build.gradle +++ b/enigma-cli/build.gradle @@ -7,6 +7,7 @@ plugins { dependencies { shadow(implementation project(':enigma')) testImplementation(testFixtures(project(':enigma'))) + //implementation("org.quiltmc:quilt-enigma-plugin:2.3.1+local") } application { diff --git a/enigma-cli/src/main/java/org/quiltmc/enigma/command/DropProposedMappingsCommand.java b/enigma-cli/src/main/java/org/quiltmc/enigma/command/DropProposedMappingsCommand.java new file mode 100644 index 000000000..f1364fc33 --- /dev/null +++ b/enigma-cli/src/main/java/org/quiltmc/enigma/command/DropProposedMappingsCommand.java @@ -0,0 +1,91 @@ +package org.quiltmc.enigma.command; + +import org.quiltmc.enigma.api.Enigma; +import org.quiltmc.enigma.api.EnigmaProfile; +import org.quiltmc.enigma.api.EnigmaProject; +import org.quiltmc.enigma.api.ProgressListener; +import org.quiltmc.enigma.api.translation.mapping.serde.MappingSaveParameters; +import org.quiltmc.enigma.api.translation.mapping.serde.MappingsWriter; +import org.tinylog.Logger; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +public class DropProposedMappingsCommand extends Command { + public DropProposedMappingsCommand() { + super(Argument.INPUT_JAR.required(), + Argument.INPUT_MAPPINGS.required(), + Argument.ENIGMA_PROFILE.required(), + Argument.MAPPING_OUTPUT.optional()); + } + + @Override + public void run(String... args) throws Exception { + Path jarIn = getReadablePath(this.getArg(args, 0)); + Path mappingsIn = getReadablePath(this.getArg(args, 1)); + Path profile = getReadablePath(this.getArg(args, 2)); + String mappingsOutArg = this.getArg(args, 3); + Path mappingsOut = mappingsOutArg != null && !mappingsOutArg.isEmpty() ? getReadablePath(mappingsOutArg) : mappingsIn; + + run(jarIn, mappingsIn, profile, mappingsOut); + } + + @Override + public String getName() { + return "drop-proposed-mappings"; + } + + @Override + public String getDescription() { + return "Removes all proposed mapping entries that are the same as manually written entries from the provided mappings."; + } + + public static void run(Path jarIn, Path mappingsIn, Path profilePath, Path mappingsOut) throws Exception { + if (mappingsIn == null) { + Logger.warn("No mappings input specified, skipping."); + return; + } + + Enigma enigma = createEnigma(EnigmaProfile.read(profilePath), null); + + MappingsWriter writer = CommandsUtil.getWriter(enigma, mappingsIn); + EnigmaProject project = openProject(jarIn, mappingsIn, enigma); + + Logger.info("Dropping proposed mappings..."); + + var droppedMappings = project.dropProposedMappings(ProgressListener.createEmpty()); + + if (!droppedMappings.isEmpty()) { + Logger.info("Found and dropped {} duplicate mappings.", droppedMappings.size()); + Logger.info("Writing mappings..."); + + if (mappingsOut == mappingsIn) { + Logger.info("Overwriting input mappings"); + Files.walkFileTree(mappingsIn, new SimpleFileVisitor<>() { + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + }); + + Files.deleteIfExists(mappingsIn); + } + + MappingSaveParameters saveParameters = project.getEnigma().getProfile().getMappingSaveParameters(); + writer.write(project.getRemapper().getMappings(), mappingsOut, ProgressListener.createEmpty(), saveParameters); + } else { + Logger.info("No duplicate proposed mappings found."); + } + } +} diff --git a/enigma-cli/src/main/java/org/quiltmc/enigma/command/Main.java b/enigma-cli/src/main/java/org/quiltmc/enigma/command/Main.java index 5014feb4e..499be66e7 100644 --- a/enigma-cli/src/main/java/org/quiltmc/enigma/command/Main.java +++ b/enigma-cli/src/main/java/org/quiltmc/enigma/command/Main.java @@ -118,6 +118,7 @@ private static void logEnigmaInfo() { register(new MapSpecializedMethodsCommand()); register(new InsertProposedMappingsCommand()); register(new DropInvalidMappingsCommand()); + register(new DropProposedMappingsCommand()); register(new FillClassMappingsCommand()); register(new HelpCommand()); register(new PrintStatsCommand()); diff --git a/enigma/src/main/java/org/quiltmc/enigma/api/EnigmaProject.java b/enigma/src/main/java/org/quiltmc/enigma/api/EnigmaProject.java index 8cc423f3a..5d578386c 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/api/EnigmaProject.java +++ b/enigma/src/main/java/org/quiltmc/enigma/api/EnigmaProject.java @@ -9,6 +9,7 @@ import org.quiltmc.enigma.api.analysis.index.mapping.MappingsIndex; import org.quiltmc.enigma.api.service.ObfuscationTestService; import org.quiltmc.enigma.api.source.TokenType; +import org.quiltmc.enigma.api.translation.mapping.tree.EntryTreeNode; import org.quiltmc.enigma.api.translation.mapping.tree.EntryTreeUtil; import org.quiltmc.enigma.api.translation.mapping.tree.HashEntryTree; import org.quiltmc.enigma.impl.bytecode.translator.TranslationClassVisitor; @@ -40,6 +41,7 @@ import java.io.StringWriter; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -167,6 +169,68 @@ private Collection> dropMappings(EntryTree mappings, Prog return dropper.getDroppedMappings().keySet(); } + public Collection> dropProposedMappings(ProgressListener progress) { + DeltaTrackingTree mappings = this.remapper.getMappings(); + EntryTree proposedMappings = this.remapper.getProposedMappings(); + progress.init((int) proposedMappings.getAllEntries().count(), "Proposed Mappings to check"); + + List> dropped = new ArrayList<>(); + + int steps = 0; + for (EntryTreeNode proposedMapping : proposedMappings) { + progress.step(steps++, proposedMapping.getEntry().getFullName()); + + if (proposedMapping.getValue() == null) { + continue; + } + + if (!mappings.contains(proposedMapping.getEntry())) { + continue; + } + + EntryMapping entryMapping = mappings.get(proposedMapping.getEntry()); + + if (entryMapping.tokenType().isProposed()) { + continue; + } + + if (entryMapping.targetName() == null) { + continue; + } + +// if (entryMapping.javadoc() != null) { +// continue; +// } + +// ParentedEntry parent = ((ParentedEntry) proposedMapping.getEntry()); +// while (parent != null && parent.getParent() != null) { +// parent = (ParentedEntry) parent.getParent(); +// } +// +// if (!parent.getFullName().equals("net/minecraft/unmapped/C_ygpuayyc")) { +// continue; +// } + + if (proposedMapping.getValue().sourcePluginId().equals("quiltmc:name_proposal/delegate_params")) { + continue; + } + + dropped.add(proposedMapping.getEntry()); + + + + if (entryMapping.targetName().equals(proposedMapping.getValue().targetName())) { + if (entryMapping.javadoc() != null) { + mappings.insert(proposedMapping.getEntry(), entryMapping.withName(null, TokenType.OBFUSCATED)); + continue; + } + mappings.remove(proposedMapping.getEntry()); + } + } + + return dropped; + } + public boolean isNavigable(Entry obfEntry) { if (obfEntry instanceof ClassEntry classEntry && this.isAnonymousOrLocal(classEntry)) { return false; diff --git a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/MergedEntryMappingTree.java b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/MergedEntryMappingTree.java index 875f73c1f..8d7eb9cbf 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/MergedEntryMappingTree.java +++ b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/MergedEntryMappingTree.java @@ -1,5 +1,6 @@ package org.quiltmc.enigma.api.translation.mapping.tree; +import org.quiltmc.enigma.api.source.TokenType; import org.quiltmc.enigma.api.translation.Translator; import org.quiltmc.enigma.api.translation.mapping.EntryMap; import org.quiltmc.enigma.api.translation.mapping.EntryMapping; @@ -42,10 +43,15 @@ public EntryMapping remove(Entry entry) { @Override public EntryMapping get(Entry entry) { EntryMapping main = this.mainTree.get(entry); + if (main == null || (main.equals(EntryMapping.OBFUSCATED) && this.secondaryTree.contains(entry))) { return this.secondaryTree.get(entry); } + if (main.tokenType().equals(TokenType.OBFUSCATED) && this.secondaryTree.contains(entry)) { + return EntryMapping.merge(main, this.secondaryTree.get(entry)); + } + return main; }