Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/java/org/mcphackers/mcp/MCPPaths.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class MCPPaths {
public static final String VERSION = CONF + "version.json";

public static final String PATCH = "patches/%s.patch";
public static final String PATCHDIR = "patches/%s";

public static final String UPDATE_JAR = "update.jar";

Expand Down
32 changes: 29 additions & 3 deletions src/main/java/org/mcphackers/mcp/tasks/TaskApplyPatch.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package org.mcphackers.mcp.tasks;

import static org.mcphackers.mcp.MCPPaths.PATCH;
import static org.mcphackers.mcp.MCPPaths.PATCHDIR;
import static org.mcphackers.mcp.MCPPaths.SOURCE;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import codechicken.diffpatch.PatchOperation;
import codechicken.diffpatch.util.PatchMode;
import org.mcphackers.mcp.MCP;
import org.mcphackers.mcp.MCPPaths;

public class TaskApplyPatch extends TaskStaged {
private int complete = 0;

public TaskApplyPatch(Side side, MCP instance) {
super(side, instance);
Expand All @@ -23,23 +28,44 @@ public TaskApplyPatch(Side side, MCP instance) {
protected Stage[] setStages() {
return new Stage[] {
stage(getLocalizedStage("patching"), () -> {
final Path patchesPath = MCPPaths.get(mcp, PATCH, side);
final Path patchesRoot = MCPPaths.get(mcp, PATCHDIR, side);
final Path srcPath = MCPPaths.get(mcp, SOURCE, side);
patch(this, srcPath, srcPath, patchesPath);

try (Stream<Path> walker = Files.walk(patchesRoot)) {
List<Path> files = walker.filter((path) -> path.toFile().isFile() && path.toString().endsWith(".patch")).collect(Collectors.toList());
int total = files.size();

// We can't use parallel streams here, since some patches may modify multiple
// files, and that would cause conflicts.

for (Path path : files) {
patch(this, srcPath, srcPath, path);
complete++;
setProgress((int) ((double) complete / (double) total * 100));
}
}

// final Path patchesPath = MCPPaths.get(mcp, PATCH, side);
// final Path srcPath = MCPPaths.get(mcp, SOURCE, side);
// patch(this, srcPath, srcPath, patchesPath);
})
};
}

public static void patch(Task task, Path base, Path out, Path patches) throws IOException {
ByteArrayOutputStream logger = new ByteArrayOutputStream();

PatchOperation patchOperation = PatchOperation.builder()
.basePath(base)
.patchesPath(patches)
.outputPath(out)
.mode(PatchMode.OFFSET)
.build();

boolean success = patchOperation.doPatch();

patchOperation.getSummary().print(new PrintStream(logger), false);

if (!success) {
task.addMessage(logger.toString(), Task.INFO);
task.addMessage("Patching failed!", Task.ERROR);
Expand Down
56 changes: 44 additions & 12 deletions src/main/java/org/mcphackers/mcp/tasks/TaskDownloadSpoutPatch.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,66 @@
package org.mcphackers.mcp.tasks;

import static org.mcphackers.mcp.MCPPaths.PATCH;
import static org.mcphackers.mcp.MCPPaths.SOURCE;
import static org.mcphackers.mcp.MCPPaths.PATCHDIR;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import codechicken.diffpatch.PatchOperation;
import codechicken.diffpatch.util.PatchMode;
import org.mcphackers.mcp.MCP;
import org.mcphackers.mcp.MCPPaths;
import org.mcphackers.mcp.tools.FileUtil;

public class TaskDownloadSpoutPatch extends TaskStaged {
private static final String PATCH_ZIP_URL = "https://github.com/RedstoneWizard08/Grease/archive/refs/heads/main.zip";
private static final String PATCH_PATH_PREFIX = "Grease-main/patches/";

public TaskDownloadSpoutPatch(Side side, MCP instance) {
super(side, instance);
}

@Override
protected Stage[] setStages() {
final Path patchesPath = MCPPaths.get(mcp, PATCHDIR, side);
final Path zipFilePath = patchesPath.resolve("spoutcraft-patches.zip");
final Path patchFolderPath = patchesPath.resolve("spoutcraft-patches");

return new Stage[] {
stage(getLocalizedStage("download", "Spoutcraft's patch file"), () -> {
final Path patchesPath = MCPPaths.get(mcp, PATCH, side);
patchesPath.toFile().mkdirs();
FileUtil.downloadFile("https://raw.githubusercontent.com/ReSpouted/Grease/main/client.patch", patchesPath.resolve("client.patch"));
})
stage(getLocalizedStage("download", "Spoutcraft's patch file"), () -> {
patchesPath.toFile().mkdirs();
// FileUtil.downloadFile("https://raw.githubusercontent.com/ReSpouted/Grease/main/client.patch", patchesPath.resolve("client.patch"));
FileUtil.downloadFile(PATCH_ZIP_URL, zipFilePath);
}),
stage(getLocalizedStage("extract", "Spoutcraft's patch file"), () -> {
ZipInputStream zip = new ZipInputStream(new FileInputStream(zipFilePath.toFile()));
ZipEntry entry = zip.getNextEntry();
byte[] buf = new byte[1024];

while (entry != null) {
if (!entry.isDirectory() && entry.getName().endsWith(".patch")) {
Path outputPath = patchFolderPath.resolve(entry.getName().replaceFirst(PATCH_PATH_PREFIX, ""));

outputPath.getParent().toFile().mkdirs();

FileOutputStream fos = new FileOutputStream(outputPath.toFile());
int len;

while ((len = zip.read(buf)) > 0) {
fos.write(buf, 0, len);
}

fos.close();
}

entry = zip.getNextEntry();
}

zip.closeEntry();
zip.close();
})
};
}

}
6 changes: 4 additions & 2 deletions src/main/java/org/mcphackers/mcp/tasks/mode/TaskMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,10 @@ public class TaskMode {
public static TaskMode APPLY_PATCH = new TaskModeBuilder()
.setName("applypatch")
.setTaskClass(TaskApplyPatch.class)
.setProgressBars(false)
.addRequirement((mcp, side) -> Files.isReadable(MCPPaths.get(mcp, MCPPaths.PATCH, side))
.setProgressBars(true)
// .addRequirement((mcp, side) -> Files.isReadable(MCPPaths.get(mcp, MCPPaths.PATCH, side))
// && Files.isReadable(MCPPaths.get(mcp, MCPPaths.SOURCE, side)))
.addRequirement((mcp, side) -> Files.exists(MCPPaths.get(mcp, MCPPaths.PATCHDIR, side))
&& Files.isReadable(MCPPaths.get(mcp, MCPPaths.SOURCE, side)))
.setParameters(new TaskParameter[]{
TaskParameter.SIDE
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/lang/en_US.lang
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ task.backupsrc = Backup source
task.backupsrc.desc = Pack source files into a zip
task.downloadspoutpatch = Download Spoutcraft's patch
task.applypatch = Apply patch
task.applypatch.desc = Apply patch from patches directory
task.applypatch.desc = Apply patches from patches directory
task.updatemcp = Update RetroMCP
task.updatemcp.desc = Check for updates
task.noDesc = No description provided
Expand Down