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
5 changes: 5 additions & 0 deletions HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;

/**
*
* @author huangyuhui
*/
public abstract class Modpack {

public static final Set<String> SUPPORTED_ICON_EXTS = Set.of("png", "jpg", "jpeg", "bmp", "gif", "webp", "apng");
public static final Set<String> SUPPORTED_ICON_NAMES = Set.of("icon.png", "icon.jpg", "icon.jpeg", "icon.bmp", "icon.gif", "icon.webp", "icon.apng");

private String name;
private String author;
private String version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@
import org.jackhuang.hmcl.download.GameBuilder;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.mod.*;
import org.jackhuang.hmcl.task.CacheFileTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;

import static org.jackhuang.hmcl.util.logging.Logger.LOG;

/**
* Install a downloaded CurseForge modpack.
Expand All @@ -47,8 +50,11 @@ public final class CurseInstallTask extends Task<Void> {
private final Modpack modpack;
private final CurseManifest manifest;
private final String name;
private final String iconUrl;
private final Path run;
private final ModpackConfiguration<CurseManifest> config;
private String iconExt;
private Task<Path> downloadIconTask;
private final List<Task<?>> dependents = new ArrayList<>(4);
private final List<Task<?>> dependencies = new ArrayList<>(1);

Expand All @@ -60,12 +66,13 @@ public final class CurseInstallTask extends Task<Void> {
* @param manifest The manifest content of given CurseForge modpack.
* @param name the new version name
*/
public CurseInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, CurseManifest manifest, String name) {
public CurseInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, CurseManifest manifest, String name, String iconUrl) {
this.dependencyManager = dependencyManager;
this.zipFile = zipFile;
this.modpack = modpack;
this.manifest = manifest;
this.name = name;
this.iconUrl = iconUrl;
this.repository = dependencyManager.getGameRepository();
this.run = repository.getRunDirectory(name);

Expand Down Expand Up @@ -108,6 +115,14 @@ public CurseInstallTask(DefaultDependencyManager dependencyManager, Path zipFile
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), Collections.singletonList(manifest.overrides()), any -> true, config).withStage("hmcl.modpack"));
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), Collections.singletonList(manifest.overrides()), manifest, CurseModpackProvider.INSTANCE, manifest.name(), manifest.version(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));

URI iconUri = NetworkUtils.toURIOrNull(iconUrl);
if (iconUri != null) {
String ext = FileUtils.getExtension(StringUtils.substringAfter(iconUri.getPath(), '/')).toLowerCase(Locale.ROOT);
if (Modpack.SUPPORTED_ICON_EXTS.contains(ext)) {
iconExt = ext;
dependents.add(downloadIconTask = new CacheFileTask(iconUrl));
}
}
dependencies.add(new CurseCompletionTask(dependencyManager, name, manifest));
}

Expand Down Expand Up @@ -137,5 +152,13 @@ public void execute() throws Exception {
Path root = repository.getVersionRoot(name);
Files.createDirectories(root);
JsonUtils.writeToJsonFile(root.resolve("manifest.json"), manifest);

if (iconExt != null && Modpack.SUPPORTED_ICON_NAMES.stream().map(root::resolve).allMatch(Files::notExists)) {
try {
Files.copy(downloadIconTask.getResult(), root.resolve("icon." + iconExt));
} catch (Exception e) {
LOG.warning("Failed to copy modpack icon", e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public Task<?> createUpdateTask(DefaultDependencyManager dependencyManager, Stri
if (!(modpack.getManifest() instanceof CurseManifest curseManifest))
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());

return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new CurseInstallTask(dependencyManager, zipFile, modpack, curseManifest, name));
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new CurseInstallTask(dependencyManager, zipFile, modpack, curseManifest, name, null));
}

@Override
Expand All @@ -69,7 +69,7 @@ public Modpack readManifest(ZipArchiveReader zip, Path file, Charset encoding) t
return new Modpack(manifest.name(), manifest.author(), manifest.version(), manifest.minecraft().gameVersion(), description, encoding, manifest) {
@Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) {
return new CurseInstallTask(dependencyManager, zipFile, this, manifest, name);
return new CurseInstallTask(dependencyManager, zipFile, this, manifest, name, iconUrl);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import static org.jackhuang.hmcl.util.logging.Logger.LOG;

public class ModrinthInstallTask extends Task<Void> {
private static final Set<String> SUPPORTED_ICON_EXTS = Set.of("png", "jpg", "jpeg", "bmp", "gif", "webp", "apng");

private final DefaultDependencyManager dependencyManager;
private final DefaultGameRepository repository;
Expand Down Expand Up @@ -121,7 +120,7 @@ public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipF
URI iconUri = NetworkUtils.toURIOrNull(iconUrl);
if (iconUri != null) {
String ext = FileUtils.getExtension(StringUtils.substringAfter(iconUri.getPath(), '/')).toLowerCase(Locale.ROOT);
if (SUPPORTED_ICON_EXTS.contains(ext)) {
if (Modpack.SUPPORTED_ICON_EXTS.contains(ext)) {
iconExt = ext;
dependents.add(downloadIconTask = new CacheFileTask(iconUrl));
}
Expand Down Expand Up @@ -156,7 +155,7 @@ public void execute() throws Exception {
Files.createDirectories(root);
JsonUtils.writeToJsonFile(root.resolve("modrinth.index.json"), manifest);

if (iconExt != null) {
if (iconExt != null && Modpack.SUPPORTED_ICON_NAMES.stream().map(root::resolve).allMatch(Files::notExists)) {
try {
Files.copy(downloadIconTask.getResult(), root.resolve("icon." + iconExt));
} catch (Exception e) {
Expand Down
Loading