diff --git a/src/main/java/org/mcphackers/mcp/tasks/TaskBuild.java b/src/main/java/org/mcphackers/mcp/tasks/TaskBuild.java index 78a10a6..654bc18 100644 --- a/src/main/java/org/mcphackers/mcp/tasks/TaskBuild.java +++ b/src/main/java/org/mcphackers/mcp/tasks/TaskBuild.java @@ -2,14 +2,19 @@ import static org.mcphackers.mcp.MCPPaths.*; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Stream; import org.mcphackers.mcp.MCP; import org.mcphackers.mcp.MCPPaths; import org.mcphackers.mcp.tasks.mode.TaskParameter; import org.mcphackers.mcp.tools.FileUtil; +import org.mcphackers.mcp.tools.Util; public class TaskBuild extends TaskStaged { /* @@ -40,12 +45,12 @@ protected Stage[] setStages() { Path buildJar = MCPPaths.get(mcp, BUILD_JAR, localSide); Path buildZip = MCPPaths.get(mcp, BUILD_ZIP, localSide); FileUtil.createDirectories(MCPPaths.get(mcp, BUILD)); + List assets = collectChangedAssets(bin); if (mcp.getOptions().getBooleanParameter(TaskParameter.FULL_BUILD)) { Files.deleteIfExists(buildJar); Files.copy(originalJar, buildJar); List reobfClasses = FileUtil.walkDirectory(reobfDir, path -> !Files.isDirectory(path)); FileUtil.packFilesToZip(buildJar, reobfClasses, reobfDir); - List assets = FileUtil.walkDirectory(bin, path -> !Files.isDirectory(path) && !path.getFileName().toString().endsWith(".class")); FileUtil.packFilesToZip(buildJar, assets, bin); FileUtil.deleteFileInAZip(buildJar, "/META-INF/MOJANG_C.DSA"); FileUtil.deleteFileInAZip(buildJar, "/META-INF/MOJANG_C.SF"); @@ -54,7 +59,6 @@ protected Stage[] setStages() { } else { Files.deleteIfExists(buildZip); FileUtil.compress(reobfDir, buildZip); - List assets = FileUtil.walkDirectory(bin, path -> !Files.isDirectory(path) && !path.getFileName().toString().endsWith(".class")); FileUtil.packFilesToZip(buildZip, assets, bin); } } @@ -62,6 +66,46 @@ protected Stage[] setStages() { }; } + /** + * Collects only assets (non-class resources) whose contents differ from the + * hash recorded by the last MD5 update, or that have no recorded hash at all. + * Avoids packaging untouched resources into the build output. + */ + private List collectChangedAssets(Path bin) throws IOException { + final Map originalHashes = readMD5Hashes(MCPPaths.get(mcp, MD5, side)); + return FileUtil.walkDirectory(bin, path -> { + if (Files.isDirectory(path) || path.getFileName().toString().endsWith(".class")) { + return false; + } + String key = bin.relativize(path).toString().replace("\\", "/"); + String original = originalHashes.get(key); + if (original == null) { + return true; + } + try { + return !original.equals(Util.getMD5(path)); + } catch (IOException e) { + return true; + } + }); + } + + private static Map readMD5Hashes(Path md5File) throws IOException { + Map hashes = new HashMap<>(); + if (!Files.exists(md5File)) { + return hashes; + } + try (Stream lines = Files.lines(md5File)) { + lines.forEach(line -> { + String[] tokens = line.split(" "); + if (tokens.length == 2) { + hashes.put(tokens[0], tokens[1]); + } + }); + } + return hashes; + } + @Override public void setProgress(int progress) { switch (step) { diff --git a/src/main/java/org/mcphackers/mcp/tasks/TaskReobfuscate.java b/src/main/java/org/mcphackers/mcp/tasks/TaskReobfuscate.java index 069cabf..b7cd956 100644 --- a/src/main/java/org/mcphackers/mcp/tasks/TaskReobfuscate.java +++ b/src/main/java/org/mcphackers/mcp/tasks/TaskReobfuscate.java @@ -101,15 +101,22 @@ private void reobfuscate() throws IOException { return false; } String obfClassName = entry.getName().replace(".class", ""); - // Force inner classes to compare outer class hash - String className = obfClassName; - int index = className.indexOf('$'); - if (index != -1) { - className = className.substring(0, index); - } - String deobfName = reversedNames.get(className); + // Try to resolve the deobfuscated name. If the inner-class entry + // has no direct mapping, fall back to the outer class. + String deobfName = reversedNames.get(obfClassName); if (deobfName == null) { - deobfName = className; + int dollar = obfClassName.indexOf('$'); + if (dollar != -1) { + deobfName = reversedNames.get(obfClassName.substring(0, dollar)); + } + if (deobfName == null) { + deobfName = obfClassName; + } + } + // MD5 hashes are recorded per outer class, so strip any inner-class suffix. + int innerIdx = deobfName.indexOf('$'); + if (innerIdx != -1) { + deobfName = deobfName.substring(0, innerIdx); } String hash = originalHashes.get(deobfName); String hashModified = recompHashes.get(deobfName);