Skip to content

Commit 0f2c2fd

Browse files
committed
Merge branch 'fix/multimc-modpack-install' of https://github.com/burningtnt/HMCL into prs
2 parents de2e9e8 + b417f2f commit 0f2c2fd

3 files changed

Lines changed: 88 additions & 18 deletions

File tree

HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCInstancePatch.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.util.Collections;
4646
import java.util.HashSet;
4747
import java.util.List;
48+
import java.util.Objects;
4849
import java.util.Set;
4950
import java.util.function.Function;
5051
import java.util.stream.Collectors;
@@ -96,7 +97,10 @@ public final class MultiMCInstancePatch {
9697
@SerializedName("jarMods")
9798
private final List<Library> jarMods;
9899

99-
public MultiMCInstancePatch(int formatVersion, String id, String version, AssetIndexInfo assetIndex, String minecraftArguments, List<String> jvmArgs, String mainClass, int[] javaMajors, Library mainJar, List<String> traits, List<String> tweakers, List<Library> libraries0, List<Library> libraries1, List<Library> mavenFiles, List<Library> jarMods) {
100+
@SerializedName("requires")
101+
private final List<MultiMCManifest.MultiMCManifestCachedRequires> requires;
102+
103+
public MultiMCInstancePatch(int formatVersion, String id, String version, AssetIndexInfo assetIndex, String minecraftArguments, List<String> jvmArgs, String mainClass, int[] javaMajors, Library mainJar, List<String> traits, List<String> tweakers, List<Library> libraries0, List<Library> libraries1, List<Library> mavenFiles, List<Library> jarMods, List<MultiMCManifest.MultiMCManifestCachedRequires> requires) {
100104
this.formatVersion = formatVersion;
101105
this.id = id;
102106
this.version = version;
@@ -112,6 +116,7 @@ public MultiMCInstancePatch(int formatVersion, String id, String version, AssetI
112116
this.libraries1 = libraries1;
113117
this.mavenFiles = mavenFiles;
114118
this.jarMods = jarMods;
119+
this.requires = requires;
115120
}
116121

117122
public int getFormatVersion() {
@@ -177,6 +182,10 @@ public List<Library> getJarMods() {
177182
return nonNullOrEmpty(jarMods);
178183
}
179184

185+
public List<MultiMCManifest.MultiMCManifestCachedRequires> getRequires() {
186+
return nonNullOrEmpty(requires);
187+
}
188+
180189
private static <T> List<T> nonNullOrEmpty(List<T> value) {
181190
return value != null && !value.isEmpty() ? value : Collections.emptyList();
182191
}
@@ -257,6 +266,8 @@ public static ResolvedInstance resolveArtifact(List<MultiMCInstancePatch> patche
257266
}
258267

259268
for (MultiMCInstancePatch patch : patches) {
269+
Objects.requireNonNull(patch, "patch");
270+
260271
if (patch.getFormatVersion() != 1) {
261272
throw new UnsupportedOperationException(
262273
String.format("Unsupported JSON-Patch[%s] format version: %d", patch.getID(), patch.getFormatVersion())

HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCManifest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public String getEqualsVersion() {
8686
return equalsVersion;
8787
}
8888

89-
public String getUid() {
89+
public String getID() {
9090
return uid;
9191
}
9292

HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCModpackInstallTask.java

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,26 @@
4444
import java.nio.file.Files;
4545
import java.nio.file.Path;
4646
import java.util.ArrayList;
47+
import java.util.Collection;
4748
import java.util.Collections;
49+
import java.util.HashMap;
4850
import java.util.List;
51+
import java.util.Map;
4952
import java.util.Objects;
50-
import java.util.stream.Collectors;
5153

5254
/**
5355
* <p>A task transforming MultiMC Modpack Scheme to Official Launcher Scheme.
5456
* The transforming process contains 7 stage:
55-
* General Setup, Load Components, Resolve Json-Patch, Build Artifact,
56-
* Copy Embedded Files, Assemble Game, Download Game and Apply JAR mods.
57+
* <ul>
58+
* <li>General Setup</li>
59+
* <li>Load Components</li>
60+
* <li>Resolve Json-Patch</li>
61+
* <li>Build Artifact</li>
62+
* <li>Copy Embedded Files</li>
63+
* <li>Assemble Game</li>
64+
* <li>Download Game</li>
65+
* <li>Apply JAR mods</li>
66+
* </ul>
5767
* See codes below for detailed implementation.
5868
* </p>
5969
*/
@@ -64,7 +74,6 @@ public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.R
6474
private final MultiMCInstanceConfiguration manifest;
6575
private final String name;
6676
private final DefaultGameRepository repository;
67-
private final List<Task<MultiMCInstancePatch>> patches = new ArrayList<>();
6877
private final List<Task<?>> dependents = new ArrayList<>();
6978
private final List<Task<?>> dependencies = new ArrayList<>();
7079
private final DefaultDependencyManager dependencyManager;
@@ -125,29 +134,74 @@ public void preExecute() throws Exception {
125134
try (FileSystem fs = openModpack()) {
126135
Path root = getRootPath(fs);
127136

137+
List<Task<MultiMCInstancePatch>> patches = new ArrayList<>();
128138
for (MultiMCManifest.MultiMCManifestComponent component : Objects.requireNonNull(
129139
Objects.requireNonNull(manifest.getMmcPack(), "mmc-pack.json").getComponents(), "components"
130140
)) {
131141
String componentID = Objects.requireNonNull(component.getUid(), "Component ID");
132142
Path patchPath = root.resolve(String.format("patches/%s.json", componentID));
133143

134-
Task<String> task;
135144
if (Files.exists(patchPath)) {
136145
if (!Files.isRegularFile(patchPath)) {
137146
throw new IllegalArgumentException("Json-Patch isn't a file: " + componentID);
138147
}
139148

140-
// TODO: Task.completed has unclear compatibility issue.
141-
String text = FileUtils.readText(patchPath, StandardCharsets.UTF_8);
142-
task = Task.supplyAsync(() -> text);
149+
MultiMCInstancePatch patch = MultiMCInstancePatch.read(componentID, FileUtils.readText(patchPath, StandardCharsets.UTF_8));
150+
patches.add(Task.supplyAsync(() -> patch)); // TODO: Task.completed has unclear compatibility issue.
143151
} else {
144-
task = new GetTask(MultiMCComponents.getMetaURL(componentID, component.getVersion()));
152+
patches.add(
153+
new GetTask(MultiMCComponents.getMetaURL(componentID, component.getVersion()))
154+
.thenApplyAsync(s -> MultiMCInstancePatch.read(componentID, s))
155+
);
145156
}
157+
}
158+
dependents.add(new MMCInstancePatchesAssembleTask(patches));
159+
}
160+
}
161+
162+
private static final class MMCInstancePatchesAssembleTask extends Task<List<MultiMCInstancePatch>> {
163+
private final List<Task<MultiMCInstancePatch>> patches;
164+
165+
public MMCInstancePatchesAssembleTask(List<Task<MultiMCInstancePatch>> patches) {
166+
this.patches = patches;
167+
}
168+
169+
@Override
170+
public Collection<? extends Task<?>> getDependents() {
171+
return patches;
172+
}
173+
174+
@Override
175+
public void execute() throws Exception {
176+
Map<String, MultiMCInstancePatch> existed = new HashMap<>();
177+
for (Task<MultiMCInstancePatch> patch : patches) {
178+
MultiMCInstancePatch result = patch.getResult();
146179

147-
Task<MultiMCInstancePatch> task2 = task.thenApplyAsync(s -> MultiMCInstancePatch.read(componentID, s));
148-
patches.add(task2);
149-
dependents.add(task2);
180+
existed.put(result.getID(), result);
150181
}
182+
183+
checking:
184+
while (true) {
185+
for (MultiMCInstancePatch patch : existed.values()) {
186+
for (MultiMCManifest.MultiMCManifestCachedRequires require : patch.getRequires()) {
187+
String componentID = require.getID();
188+
if (!existed.containsKey(componentID)) {
189+
Task<MultiMCInstancePatch> task = new GetTask(MultiMCComponents.getMetaURL(
190+
componentID, Lang.requireNonNullElse(require.getEqualsVersion(), require.getSuggests())
191+
)).thenApplyAsync(s -> MultiMCInstancePatch.read(componentID, s));
192+
task.run();
193+
194+
MultiMCInstancePatch result = Objects.requireNonNull(task.getResult());
195+
existed.put(result.getID(), result);
196+
continue checking;
197+
}
198+
}
199+
}
200+
201+
break;
202+
}
203+
204+
setResult(new ArrayList<>(existed.values()));
151205
}
152206
}
153207

@@ -160,10 +214,15 @@ public List<Task<?>> getDependents() {
160214
@Override
161215
public void execute() throws Exception {
162216
// Stage #3: Build Json-Patch artifact.
163-
MultiMCInstancePatch.ResolvedInstance artifact = MultiMCInstancePatch.resolveArtifact(patches.stream()
164-
.map(value -> Objects.requireNonNull(value.getResult(), "MultiMCInstancePatch"))
165-
.collect(Collectors.toList()), name
166-
);
217+
MultiMCInstancePatch.ResolvedInstance artifact = null;
218+
for (int i = dependents.size() - 1; i >= 0; i--) {
219+
Task<?> task = dependents.get(i);
220+
if (task instanceof MMCInstancePatchesAssembleTask) {
221+
artifact = MultiMCInstancePatch.resolveArtifact(((MMCInstancePatchesAssembleTask) task).getResult(), name);
222+
break;
223+
}
224+
}
225+
Objects.requireNonNull(artifact, "artifact");
167226

168227
// Stage #4: Copy embedded files.
169228
try (FileSystem fs = openModpack()) {

0 commit comments

Comments
 (0)