Skip to content

Commit 9ec2c40

Browse files
Windows fix
1 parent a633604 commit 9ec2c40

6 files changed

Lines changed: 114 additions & 32 deletions

File tree

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ Apply named patches to the source:
8080
./gradlew modApply -Pargs=server,mod1,mod2,mod3
8181
```
8282

83-
Patches are applied in order. If a patch fails, it likely depends on another.
83+
Patches are applied in order. If a patch fails:
84+
- Already applied? Use `modRevert` first
85+
- Conflicting mod? Revert the other mod first
8486

8587
### Reverting Mods
8688

@@ -90,15 +92,17 @@ Reverse patches (in reverse order):
9092
./gradlew modRevert -Pargs=server,mod1,mod2,mod3
9193
```
9294

95+
If revert fails, the patch was likely already reverted or never applied.
96+
9397
### Packing Mods
9498

9599
Pack changed classes into a zip for distribution:
96100
```bash
97-
./gradlew modPack -Pargs=client,mod1,mod2,mod3
98-
./gradlew modPack -Pargs=server,mod1,mod2,mod3
101+
./gradlew modPackClient
102+
./gradlew modPackServer
99103
```
100104

101-
This applies the patches first, then compares against the base and outputs to `mods/client.zip` or `mods/server.zip`.
105+
Compiles current source and outputs changed classes to `mods/client.zip` or `mods/server.zip`.
102106

103107
### Using with PrismLauncher
104108

build.gradle

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,17 @@ task modGen {
138138
}
139139
}
140140

141-
task modPack {
141+
task modPackClient {
142142
group = 'mods'
143-
dependsOn modApply, ':client:compileJava', ':server:compileJava'
144-
doLast {
145-
def p = project.hasProperty('args') ? project.args.split(',') : null
146-
if (!p || p.length < 2) throw new RuntimeException("Usage: -Pargs=side,mod1,mod2")
147-
Mod.pack(rootDir, p[0])
148-
}
143+
dependsOn ':client:compileJava'
144+
doLast { Mod.pack(rootDir, 'client') }
149145
}
150146

151-
project(':client').tasks.compileJava.mustRunAfter modApply
152-
project(':server').tasks.compileJava.mustRunAfter modApply
147+
task modPackServer {
148+
group = 'mods'
149+
dependsOn ':server:compileJava'
150+
doLast { Mod.pack(rootDir, 'server') }
151+
}
153152

154153
task setupServer { group = 'setup'; dependsOn snapServer }
155154
task setupClient { group = 'setup'; dependsOn snapClient }

buildSrc/build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
plugins {
2+
id 'java'
3+
id 'groovy'
4+
}
5+
6+
repositories {
7+
mavenCentral()
8+
}
9+
10+
dependencies {
11+
implementation 'io.github.java-diff-utils:java-diff-utils:4.15'
12+
}

buildSrc/src/main/java/Patcher.java

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,76 @@
1+
import com.github.difflib.DiffUtils;
2+
import com.github.difflib.UnifiedDiffUtils;
3+
import com.github.difflib.patch.Patch;
4+
import com.github.difflib.patch.PatchFailedException;
15
import java.io.*;
26
import java.nio.file.*;
7+
import java.util.*;
38
import java.util.zip.*;
49

510
public class Patcher {
611

712
public static void apply(File dir, File patch) throws Exception {
813
if (!patch.exists()) return;
914

10-
Utils.run(dir, "patch", "-p1", "-i", patch.getAbsolutePath());
15+
for (var e : parse(patch).entrySet()) {
16+
File f = new File(dir, e.getKey());
17+
if (!f.exists()) throw new RuntimeException("File not found: " + e.getKey());
18+
19+
List<String> orig = Files.readAllLines(f.toPath());
20+
Patch<String> p = UnifiedDiffUtils.parseUnifiedDiff(e.getValue());
21+
22+
try {
23+
Files.write(f.toPath(), DiffUtils.patch(orig, p));
24+
} catch (PatchFailedException ex) {
25+
throw new RuntimeException("Patch failed for " + e.getKey() + ": " + ex.getMessage());
26+
}
27+
}
1128
}
1229

1330
public static void unapply(File dir, File patch) throws Exception {
1431
if (!patch.exists()) return;
1532

16-
Utils.run(dir, "patch", "-R", "-p1", "-i", patch.getAbsolutePath());
33+
for (var e : parse(patch).entrySet()) {
34+
File f = new File(dir, e.getKey());
35+
if (!f.exists()) throw new RuntimeException("File not found: " + e.getKey());
36+
37+
List<String> cur = Files.readAllLines(f.toPath());
38+
Patch<String> p = UnifiedDiffUtils.parseUnifiedDiff(e.getValue());
39+
List<String> result = DiffUtils.unpatch(cur, p);
40+
41+
try {
42+
List<String> check = DiffUtils.patch(result, p);
43+
if (!check.equals(cur))
44+
throw new RuntimeException("Revert failed for " + e.getKey() + ": mismatch");
45+
} catch (PatchFailedException ex) {
46+
throw new RuntimeException("Revert failed for " + e.getKey() + ": " + ex.getMessage());
47+
}
48+
49+
Files.write(f.toPath(), result);
50+
}
51+
}
52+
53+
private static Map<String, List<String>> parse(File patch) throws IOException {
54+
Map<String, List<String>> m = new LinkedHashMap<>();
55+
List<String> lines = Files.readAllLines(patch.toPath());
56+
List<String> cur = null;
57+
String file = null;
58+
59+
for (String line : lines) {
60+
if (line.startsWith("--- a/")) {
61+
if (cur != null && file != null) m.put(file, cur);
62+
file = line.substring(6).split("\t")[0];
63+
64+
cur = new ArrayList<>();
65+
cur.add(line);
66+
} else if (cur != null) {
67+
cur.add(line);
68+
}
69+
}
70+
71+
if (cur != null && file != null) m.put(file, cur);
72+
73+
return m;
1774
}
1875

1976
public static void snap(File src, File dest) throws IOException {
@@ -43,22 +100,32 @@ public static void diff(File base, File cur, File out, boolean isZip) throws Exc
43100

44101
StringBuilder sb = new StringBuilder();
45102
for (String pkg : new String[]{"com", "net"}) {
46-
Path pkgPath = tmp.resolve(pkg);
47-
if (!Files.exists(pkgPath)) continue;
103+
Path d = tmp.resolve(pkg);
104+
if (!Files.exists(d)) continue;
48105

49-
Files.walk(pkgPath).filter(p -> p.toString().endsWith(".java")).forEach(p -> {
106+
Files.walk(d).filter(p -> p.toString().endsWith(".java")).forEach(p -> {
50107
String rel = tmp.relativize(p).toString();
51-
File curFile = new File(cur, rel);
52-
if (!curFile.exists()) return;
108+
File f = new File(cur, rel);
109+
if (!f.exists()) return;
53110

54111
try {
55-
String d = Utils.runOut(tmp.toFile(), "diff", "-u", rel, curFile.getAbsolutePath());
56-
if (!d.isEmpty()) {
57-
d = d.replaceFirst("--- " + rel, "--- a/" + rel);
58-
d = d.replaceFirst("\\+\\+\\+ .*", "+++ b/" + rel);
59-
sb.append(d);
112+
List<String> a = Files.readAllLines(p);
113+
List<String> b = Files.readAllLines(f.toPath());
114+
Patch<String> patch = DiffUtils.diff(a, b);
115+
116+
if (!patch.getDeltas().isEmpty()) {
117+
List<String> u = UnifiedDiffUtils.generateUnifiedDiff(rel, rel, a, patch, 3);
118+
for (int i = 0; i < u.size(); i++) {
119+
String line = u.get(i);
120+
if (line.startsWith("--- ")) u.set(i, "--- a/" + rel);
121+
else if (line.startsWith("+++ ")) u.set(i, "+++ b/" + rel);
122+
}
123+
124+
for (String line : u) sb.append(line).append("\n");
60125
}
61-
} catch (Exception e) {}
126+
} catch (IOException e) {
127+
throw new UncheckedIOException(e);
128+
}
62129
});
63130
}
64131

prism-instance/mmc-pack.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
},
88
{
99
"uid": "net.minecraft",
10-
"version": "1.21.11-rc2",
10+
"version": "1.21.11",
1111
"important": true
1212
},
1313
{

prism-instance/patches/custom.unobfuscated.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
"mainJar": {
44
"downloads": {
55
"artifact": {
6-
"sha1": "8e75db09feb89eec8ed7f2a2ae779b3fb1fb7f18",
7-
"size": 36734143,
8-
"url": "https://piston-data.mojang.com/v1/objects/8e75db09feb89eec8ed7f2a2ae779b3fb1fb7f18/client.jar"
6+
"sha1": "4509ee9b65f226be61142d37bf05f8d28b03417b",
7+
"size": 36736553,
8+
"url": "https://piston-data.mojang.com/v1/objects/4509ee9b65f226be61142d37bf05f8d28b03417b/client.jar"
99
}
1010
},
11-
"name": "com.mojang:minecraft:1.21.11-rc2-unobfuscated:client"
11+
"name": "com.mojang:minecraft:1.21.11-unobfuscated:client"
1212
},
1313
"name": "Unobfuscated",
1414
"uid": "custom.unobfuscated",
15-
"version": "1.21.11-rc2"
15+
"version": "1.21.11"
1616
}

0 commit comments

Comments
 (0)