@@ -79,7 +79,7 @@ public final class HMCLModpackProvider implements ModpackProvider {
|
|||||||
|
|
||||||
private final static class HMCLModpack extends Modpack {
|
private final static class HMCLModpack extends Modpack {
|
||||||
@Override
|
@Override
|
||||||
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
|
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) {
|
||||||
return new HMCLModpackInstallTask(((HMCLGameRepository) dependencyManager.getGameRepository()).getProfile(), zipFile, this, name);
|
return new HMCLModpackInstallTask(((HMCLGameRepository) dependencyManager.getGameRepository()).getProfile(), zipFile, this, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ public final class ModpackHelper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<?> getInstallTask(Profile profile, Path zipFile, String name, Modpack modpack) {
|
public static Task<?> getInstallTask(Profile profile, Path zipFile, String name, Modpack modpack, String iconUrl) {
|
||||||
profile.getRepository().markVersionAsModpack(name);
|
profile.getRepository().markVersionAsModpack(name);
|
||||||
|
|
||||||
ExceptionalRunnable<?> success = () -> {
|
ExceptionalRunnable<?> success = () -> {
|
||||||
@@ -208,17 +208,17 @@ public final class ModpackHelper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
|
if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
|
||||||
return modpack.getInstallTask(profile.getDependency(), zipFile, name)
|
return modpack.getInstallTask(profile.getDependency(), zipFile, name, iconUrl)
|
||||||
.whenComplete(Schedulers.defaultScheduler(), success, failure)
|
.whenComplete(Schedulers.defaultScheduler(), success, failure)
|
||||||
.thenComposeAsync(createMultiMCPostInstallTask(profile, (MultiMCInstanceConfiguration) modpack.getManifest(), name))
|
.thenComposeAsync(createMultiMCPostInstallTask(profile, (MultiMCInstanceConfiguration) modpack.getManifest(), name))
|
||||||
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
|
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
|
||||||
else if (modpack.getManifest() instanceof McbbsModpackManifest)
|
else if (modpack.getManifest() instanceof McbbsModpackManifest)
|
||||||
return modpack.getInstallTask(profile.getDependency(), zipFile, name)
|
return modpack.getInstallTask(profile.getDependency(), zipFile, name, iconUrl)
|
||||||
.whenComplete(Schedulers.defaultScheduler(), success, failure)
|
.whenComplete(Schedulers.defaultScheduler(), success, failure)
|
||||||
.thenComposeAsync(createMcbbsPostInstallTask(profile, (McbbsModpackManifest) modpack.getManifest(), name))
|
.thenComposeAsync(createMcbbsPostInstallTask(profile, (McbbsModpackManifest) modpack.getManifest(), name))
|
||||||
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
|
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
|
||||||
else
|
else
|
||||||
return modpack.getInstallTask(profile.getDependency(), zipFile, name)
|
return modpack.getInstallTask(profile.getDependency(), zipFile, name, iconUrl)
|
||||||
.whenComplete(Schedulers.javafx(), success, failure)
|
.whenComplete(Schedulers.javafx(), success, failure)
|
||||||
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
|
.withStagesHint(List.of("hmcl.modpack", "hmcl.modpack.download"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
|
|||||||
newGameTab.setNodeSupplier(loadVersionFor(() -> new VersionsPage(versionPageNavigator, i18n("install.installer.choose", i18n("install.installer.game")), "", DownloadProviders.getDownloadProvider(),
|
newGameTab.setNodeSupplier(loadVersionFor(() -> new VersionsPage(versionPageNavigator, i18n("install.installer.choose", i18n("install.installer.game")), "", DownloadProviders.getDownloadProvider(),
|
||||||
"game", versionPageNavigator::onGameSelected)));
|
"game", versionPageNavigator::onGameSelected)));
|
||||||
modpackTab.setNodeSupplier(loadVersionFor(() -> {
|
modpackTab.setNodeSupplier(loadVersionFor(() -> {
|
||||||
DownloadListPage page = HMCLLocalizedDownloadListPage.ofModPack((profile, __, file) -> {
|
DownloadListPage page = HMCLLocalizedDownloadListPage.ofModPack((profile, __, mod, file) -> {
|
||||||
Versions.downloadModpackImpl(profile, uploadVersion, file);
|
Versions.downloadModpackImpl(profile, uploadVersion, mod, file);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
JFXButton installLocalModpackButton = FXUtils.newRaisedButton(i18n("install.modpack"));
|
JFXButton installLocalModpackButton = FXUtils.newRaisedButton(i18n("install.modpack"));
|
||||||
@@ -94,9 +94,9 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
|
|||||||
page.getActions().add(installLocalModpackButton);
|
page.getActions().add(installLocalModpackButton);
|
||||||
return page;
|
return page;
|
||||||
}));
|
}));
|
||||||
modTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofMod((profile, version, file) -> download(profile, version, file, "mods"), true)));
|
modTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofMod((profile, version, mod, file) -> download(profile, version, file, "mods"), true)));
|
||||||
resourcePackTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofResourcePack((profile, version, file) -> download(profile, version, file, "resourcepacks"), true)));
|
resourcePackTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofResourcePack((profile, version, mod, file) -> download(profile, version, file, "resourcepacks"), true)));
|
||||||
shaderTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofShaderPack((profile, version, file) -> download(profile, version, file, "shaderpacks"), true)));
|
shaderTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofShaderPack((profile, version, mod, file) -> download(profile, version, file, "shaderpacks"), true)));
|
||||||
worldTab.setNodeSupplier(loadVersionFor(() -> new DownloadListPage(CurseForgeRemoteModRepository.WORLDS)));
|
worldTab.setNodeSupplier(loadVersionFor(() -> new DownloadListPage(CurseForgeRemoteModRepository.WORLDS)));
|
||||||
tab = new TabHeader(transitionPane, newGameTab, modpackTab, modTab, resourcePackTab, shaderTab, worldTab);
|
tab = new TabHeader(transitionPane, newGameTab, modpackTab, modTab, resourcePackTab, shaderTab, worldTab);
|
||||||
|
|
||||||
|
|||||||
@@ -180,4 +180,5 @@ public final class LocalModpackPage extends ModpackPage {
|
|||||||
public static final SettingsMap.Key<Modpack> MODPACK_MANIFEST = new SettingsMap.Key<>("MODPACK_MANIFEST");
|
public static final SettingsMap.Key<Modpack> MODPACK_MANIFEST = new SettingsMap.Key<>("MODPACK_MANIFEST");
|
||||||
public static final SettingsMap.Key<Charset> MODPACK_CHARSET = new SettingsMap.Key<>("MODPACK_CHARSET");
|
public static final SettingsMap.Key<Charset> MODPACK_CHARSET = new SettingsMap.Key<>("MODPACK_CHARSET");
|
||||||
public static final SettingsMap.Key<Boolean> MODPACK_MANUALLY_CREATED = new SettingsMap.Key<>("MODPACK_MANUALLY_CREATED");
|
public static final SettingsMap.Key<Boolean> MODPACK_MANUALLY_CREATED = new SettingsMap.Key<>("MODPACK_MANUALLY_CREATED");
|
||||||
|
public static final SettingsMap.Key<String> MODPACK_ICON_URL = new SettingsMap.Key<>("MODPACK_ICON_URL");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
|||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||||
import org.jackhuang.hmcl.util.SettingsMap;
|
import org.jackhuang.hmcl.util.SettingsMap;
|
||||||
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -45,6 +46,7 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
|||||||
private final Profile profile;
|
private final Profile profile;
|
||||||
private final Path file;
|
private final Path file;
|
||||||
private final String updateVersion;
|
private final String updateVersion;
|
||||||
|
private String iconUrl;
|
||||||
|
|
||||||
public ModpackInstallWizardProvider(Profile profile) {
|
public ModpackInstallWizardProvider(Profile profile) {
|
||||||
this(profile, null, null);
|
this(profile, null, null);
|
||||||
@@ -64,12 +66,18 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
|||||||
this.updateVersion = updateVersion;
|
this.updateVersion = updateVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIconUrl(String iconUrl) {
|
||||||
|
this.iconUrl = iconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(SettingsMap settings) {
|
public void start(SettingsMap settings) {
|
||||||
if (file != null)
|
if (file != null)
|
||||||
settings.put(LocalModpackPage.MODPACK_FILE, file);
|
settings.put(LocalModpackPage.MODPACK_FILE, file);
|
||||||
if (updateVersion != null)
|
if (updateVersion != null)
|
||||||
settings.put(LocalModpackPage.MODPACK_NAME, updateVersion);
|
settings.put(LocalModpackPage.MODPACK_NAME, updateVersion);
|
||||||
|
if (StringUtils.isNotBlank(iconUrl))
|
||||||
|
settings.put(LocalModpackPage.MODPACK_ICON_URL, iconUrl);
|
||||||
settings.put(ModpackPage.PROFILE, profile);
|
settings.put(ModpackPage.PROFILE, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +86,7 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
|||||||
ServerModpackManifest serverModpackManifest = settings.get(RemoteModpackPage.MODPACK_SERVER_MANIFEST);
|
ServerModpackManifest serverModpackManifest = settings.get(RemoteModpackPage.MODPACK_SERVER_MANIFEST);
|
||||||
Modpack modpack = settings.get(LocalModpackPage.MODPACK_MANIFEST);
|
Modpack modpack = settings.get(LocalModpackPage.MODPACK_MANIFEST);
|
||||||
String name = settings.get(LocalModpackPage.MODPACK_NAME);
|
String name = settings.get(LocalModpackPage.MODPACK_NAME);
|
||||||
|
String iconUrl = settings.get(LocalModpackPage.MODPACK_ICON_URL);
|
||||||
Charset charset = settings.get(LocalModpackPage.MODPACK_CHARSET);
|
Charset charset = settings.get(LocalModpackPage.MODPACK_CHARSET);
|
||||||
boolean isManuallyCreated = settings.getOrDefault(LocalModpackPage.MODPACK_MANUALLY_CREATED, false);
|
boolean isManuallyCreated = settings.getOrDefault(LocalModpackPage.MODPACK_MANUALLY_CREATED, false);
|
||||||
|
|
||||||
@@ -111,7 +120,7 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
|||||||
return ModpackHelper.getInstallTask(profile, serverModpackManifest, name, modpack)
|
return ModpackHelper.getInstallTask(profile, serverModpackManifest, name, modpack)
|
||||||
.thenRunAsync(Schedulers.javafx(), () -> profile.setSelectedVersion(name));
|
.thenRunAsync(Schedulers.javafx(), () -> profile.setSelectedVersion(name));
|
||||||
} else {
|
} else {
|
||||||
return ModpackHelper.getInstallTask(profile, selected, name, modpack)
|
return ModpackHelper.getInstallTask(profile, selected, name, modpack, iconUrl)
|
||||||
.thenRunAsync(Schedulers.javafx(), () -> profile.setSelectedVersion(name));
|
.thenRunAsync(Schedulers.javafx(), () -> profile.setSelectedVersion(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
|
|||||||
.thenApplyAsync(
|
.thenApplyAsync(
|
||||||
encoding -> ModpackHelper.readModpackManifest(modpackFile, encoding))
|
encoding -> ModpackHelper.readModpackManifest(modpackFile, encoding))
|
||||||
.thenApplyAsync(modpack -> ModpackHelper
|
.thenApplyAsync(modpack -> ModpackHelper
|
||||||
.getInstallTask(repository.getProfile(), modpackFile, modpack.getName(), modpack)
|
.getInstallTask(repository.getProfile(), modpackFile, modpack.getName(), modpack, null)
|
||||||
.executor())
|
.executor())
|
||||||
.thenAcceptAsync(Schedulers.javafx(), executor -> {
|
.thenAcceptAsync(Schedulers.javafx(), executor -> {
|
||||||
Controllers.taskDialog(executor, i18n("modpack.installing"), TaskCancellationAction.NO_CANCEL);
|
Controllers.taskDialog(executor, i18n("modpack.installing"), TaskCancellationAction.NO_CANCEL);
|
||||||
|
|||||||
@@ -157,15 +157,15 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
this.failed.set(failed);
|
this.failed.set(failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void download(RemoteMod.Version file) {
|
public void download(RemoteMod mod, RemoteMod.Version file) {
|
||||||
if (this.callback == null) {
|
if (this.callback == null) {
|
||||||
saveAs(file);
|
saveAs(mod, file);
|
||||||
} else {
|
} else {
|
||||||
this.callback.download(version.getProfile(), version.getVersion(), file);
|
this.callback.download(version.getProfile(), version.getVersion(), mod, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveAs(RemoteMod.Version file) {
|
public void saveAs(RemoteMod mod, RemoteMod.Version file) {
|
||||||
String extension = StringUtils.substringAfterLast(file.getFile().getFilename(), '.');
|
String extension = StringUtils.substringAfterLast(file.getFile().getFilename(), '.');
|
||||||
|
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
@@ -287,7 +287,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
if (targetLoaders.contains(loader)) {
|
if (targetLoaders.contains(loader)) {
|
||||||
list.getContent().addAll(
|
list.getContent().addAll(
|
||||||
ComponentList.createComponentListTitle(i18n("mods.download.recommend", gameVersion)),
|
ComponentList.createComponentListTitle(i18n("mods.download.recommend", gameVersion)),
|
||||||
new ModItem(modVersion, control)
|
new ModItem(control.addon, modVersion, control)
|
||||||
);
|
);
|
||||||
break resolve;
|
break resolve;
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
ComponentList sublist = new ComponentList(() -> {
|
ComponentList sublist = new ComponentList(() -> {
|
||||||
ArrayList<ModItem> items = new ArrayList<>(versions.size());
|
ArrayList<ModItem> items = new ArrayList<>(versions.size());
|
||||||
for (RemoteMod.Version v : versions) {
|
for (RemoteMod.Version v : versions) {
|
||||||
items.add(new ModItem(v, control));
|
items.add(new ModItem(control.addon, v, control));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
});
|
});
|
||||||
@@ -373,7 +373,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
|
|
||||||
private static final class ModItem extends StackPane {
|
private static final class ModItem extends StackPane {
|
||||||
|
|
||||||
ModItem(RemoteMod.Version dataItem, DownloadPage selfPage) {
|
ModItem(RemoteMod mod, RemoteMod.Version dataItem, DownloadPage selfPage) {
|
||||||
VBox pane = new VBox(8);
|
VBox pane = new VBox(8);
|
||||||
pane.setPadding(new Insets(8, 0, 8, 0));
|
pane.setPadding(new Insets(8, 0, 8, 0));
|
||||||
|
|
||||||
@@ -435,7 +435,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RipplerContainer container = new RipplerContainer(pane);
|
RipplerContainer container = new RipplerContainer(pane);
|
||||||
FXUtils.onClicked(container, () -> Controllers.dialog(new ModVersion(dataItem, selfPage)));
|
FXUtils.onClicked(container, () -> Controllers.dialog(new ModVersion(mod, dataItem, selfPage)));
|
||||||
getChildren().setAll(container);
|
getChildren().setAll(container);
|
||||||
|
|
||||||
// Workaround for https://github.com/HMCL-dev/HMCL/issues/2129
|
// Workaround for https://github.com/HMCL-dev/HMCL/issues/2129
|
||||||
@@ -444,7 +444,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class ModVersion extends JFXDialogLayout {
|
private static final class ModVersion extends JFXDialogLayout {
|
||||||
public ModVersion(RemoteMod.Version version, DownloadPage selfPage) {
|
public ModVersion(RemoteMod mod, RemoteMod.Version version, DownloadPage selfPage) {
|
||||||
RemoteModRepository.Type type = selfPage.repository.getType();
|
RemoteModRepository.Type type = selfPage.repository.getType();
|
||||||
|
|
||||||
String title = switch (type) {
|
String title = switch (type) {
|
||||||
@@ -458,7 +458,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
|
|
||||||
VBox box = new VBox(8);
|
VBox box = new VBox(8);
|
||||||
box.setPadding(new Insets(8));
|
box.setPadding(new Insets(8));
|
||||||
ModItem modItem = new ModItem(version, selfPage);
|
ModItem modItem = new ModItem(mod, version, selfPage);
|
||||||
modItem.setMouseTransparent(true); // Item is displayed for info, clicking shouldn't open the dialog again
|
modItem.setMouseTransparent(true); // Item is displayed for info, clicking shouldn't open the dialog again
|
||||||
box.getChildren().setAll(modItem);
|
box.getChildren().setAll(modItem);
|
||||||
SpinnerPane spinnerPane = new SpinnerPane();
|
SpinnerPane spinnerPane = new SpinnerPane();
|
||||||
@@ -484,7 +484,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
if (type == RemoteModRepository.Type.MODPACK || !spinnerPane.isLoading() && spinnerPane.getFailedReason() == null) {
|
if (type == RemoteModRepository.Type.MODPACK || !spinnerPane.isLoading() && spinnerPane.getFailedReason() == null) {
|
||||||
fireEvent(new DialogCloseEvent());
|
fireEvent(new DialogCloseEvent());
|
||||||
}
|
}
|
||||||
selfPage.download(version);
|
selfPage.download(mod, version);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,7 +494,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
if (!spinnerPane.isLoading() && spinnerPane.getFailedReason() == null) {
|
if (!spinnerPane.isLoading() && spinnerPane.getFailedReason() == null) {
|
||||||
fireEvent(new DialogCloseEvent());
|
fireEvent(new DialogCloseEvent());
|
||||||
}
|
}
|
||||||
selfPage.saveAs(version);
|
selfPage.saveAs(mod, version);
|
||||||
});
|
});
|
||||||
|
|
||||||
JFXButton cancelButton = new JFXButton(i18n("button.cancel"));
|
JFXButton cancelButton = new JFXButton(i18n("button.cancel"));
|
||||||
@@ -548,6 +548,6 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface DownloadCallback {
|
public interface DownloadCallback {
|
||||||
void download(Profile profile, @Nullable String version, RemoteMod.Version file);
|
void download(Profile profile, @Nullable String version, RemoteMod mod, RemoteMod.Version file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ final class ModListPageSkin extends SkinBase<ModListPage> {
|
|||||||
repository instanceof CurseForgeRemoteModRepository ? HMCLLocalizedDownloadListPage.ofCurseForgeMod(null, false) : HMCLLocalizedDownloadListPage.ofModrinthMod(null, false),
|
repository instanceof CurseForgeRemoteModRepository ? HMCLLocalizedDownloadListPage.ofCurseForgeMod(null, false) : HMCLLocalizedDownloadListPage.ofModrinthMod(null, false),
|
||||||
remoteMod,
|
remoteMod,
|
||||||
new Profile.ProfileVersion(ModListPageSkin.this.getSkinnable().getProfile(), ModListPageSkin.this.getSkinnable().getInstanceId()),
|
new Profile.ProfileVersion(ModListPageSkin.this.getSkinnable().getProfile(), ModListPageSkin.this.getSkinnable().getInstanceId()),
|
||||||
(profile, version, file) -> org.jackhuang.hmcl.ui.download.DownloadPage.download(profile, version, file, "mods")
|
(profile, version, mod, file) -> org.jackhuang.hmcl.ui.download.DownloadPage.download(profile, version, file, "mods")
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
button.setDisable(false);
|
button.setDisable(false);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public final class Versions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void downloadModpackImpl(Profile profile, String version, RemoteMod.Version file) {
|
public static void downloadModpackImpl(Profile profile, String version, RemoteMod mod, RemoteMod.Version file) {
|
||||||
Path modpack;
|
Path modpack;
|
||||||
URI downloadURL;
|
URI downloadURL;
|
||||||
try {
|
try {
|
||||||
@@ -88,11 +88,14 @@ public final class Versions {
|
|||||||
new FileDownloadTask(downloadURL, modpack)
|
new FileDownloadTask(downloadURL, modpack)
|
||||||
.whenComplete(Schedulers.javafx(), e -> {
|
.whenComplete(Schedulers.javafx(), e -> {
|
||||||
if (e == null) {
|
if (e == null) {
|
||||||
if (version != null) {
|
ModpackInstallWizardProvider installWizardProvider;
|
||||||
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile, modpack, version));
|
if (version != null)
|
||||||
} else {
|
installWizardProvider = new ModpackInstallWizardProvider(profile, modpack, version);
|
||||||
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile, modpack));
|
else
|
||||||
}
|
installWizardProvider = new ModpackInstallWizardProvider(profile, modpack);
|
||||||
|
if (StringUtils.isNotBlank(mod.getIconUrl()))
|
||||||
|
installWizardProvider.setIconUrl(mod.getIconUrl());
|
||||||
|
Controllers.getDecorator().startWizard(installWizardProvider);
|
||||||
} else if (e instanceof CancellationException) {
|
} else if (e instanceof CancellationException) {
|
||||||
Controllers.showToast(i18n("message.cancelled"));
|
Controllers.showToast(i18n("message.cancelled"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public abstract class Modpack {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name);
|
public abstract Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl);
|
||||||
|
|
||||||
public static boolean acceptFile(String path, List<String> blackList, List<String> whiteList) {
|
public static boolean acceptFile(String path, List<String> blackList, List<String> whiteList) {
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public final class CurseModpackProvider implements ModpackProvider {
|
|||||||
|
|
||||||
return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(), description, encoding, manifest) {
|
return new Modpack(manifest.getName(), manifest.getAuthor(), manifest.getVersion(), manifest.getMinecraft().getGameVersion(), description, encoding, manifest) {
|
||||||
@Override
|
@Override
|
||||||
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ public class McbbsModpackManifest implements ModpackManifest, Validation {
|
|||||||
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
|
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
|
||||||
return new Modpack(name, author, version, gameVersion, description, encoding, this) {
|
return new Modpack(name, author, version, gameVersion, description, encoding, this) {
|
||||||
@Override
|
@Override
|
||||||
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
|
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) {
|
||||||
return new McbbsModpackLocalInstallTask(dependencyManager, zipFile, this, McbbsModpackManifest.this, name);
|
return new McbbsModpackLocalInstallTask(dependencyManager, zipFile, this, McbbsModpackManifest.this, name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,15 +22,23 @@ import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
|||||||
import org.jackhuang.hmcl.download.GameBuilder;
|
import org.jackhuang.hmcl.download.GameBuilder;
|
||||||
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
||||||
import org.jackhuang.hmcl.mod.*;
|
import org.jackhuang.hmcl.mod.*;
|
||||||
|
import org.jackhuang.hmcl.task.CacheFileTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
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.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
public class ModrinthInstallTask extends Task<Void> {
|
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 DefaultDependencyManager dependencyManager;
|
||||||
private final DefaultGameRepository repository;
|
private final DefaultGameRepository repository;
|
||||||
@@ -38,17 +46,21 @@ public class ModrinthInstallTask extends Task<Void> {
|
|||||||
private final Modpack modpack;
|
private final Modpack modpack;
|
||||||
private final ModrinthManifest manifest;
|
private final ModrinthManifest manifest;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final String iconUrl;
|
||||||
private final Path run;
|
private final Path run;
|
||||||
private final ModpackConfiguration<ModrinthManifest> config;
|
private final ModpackConfiguration<ModrinthManifest> config;
|
||||||
|
private String iconExt;
|
||||||
|
private Task<Path> downloadIconTask;
|
||||||
private final List<Task<?>> dependents = new ArrayList<>(4);
|
private final List<Task<?>> dependents = new ArrayList<>(4);
|
||||||
private final List<Task<?>> dependencies = new ArrayList<>(1);
|
private final List<Task<?>> dependencies = new ArrayList<>(1);
|
||||||
|
|
||||||
public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, ModrinthManifest manifest, String name) {
|
public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, Modpack modpack, ModrinthManifest manifest, String name, String iconUrl) {
|
||||||
this.dependencyManager = dependencyManager;
|
this.dependencyManager = dependencyManager;
|
||||||
this.zipFile = zipFile;
|
this.zipFile = zipFile;
|
||||||
this.modpack = modpack;
|
this.modpack = modpack;
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.iconUrl = iconUrl;
|
||||||
this.repository = dependencyManager.getGameRepository();
|
this.repository = dependencyManager.getGameRepository();
|
||||||
this.run = repository.getRunDirectory(name);
|
this.run = repository.getRunDirectory(name);
|
||||||
|
|
||||||
@@ -104,6 +116,14 @@ public class ModrinthInstallTask extends Task<Void> {
|
|||||||
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), subDirectories, any -> true, config).withStage("hmcl.modpack"));
|
dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), subDirectories, any -> true, config).withStage("hmcl.modpack"));
|
||||||
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), subDirectories, manifest, ModrinthModpackProvider.INSTANCE, manifest.getName(), manifest.getVersionId(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
|
dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), subDirectories, manifest, ModrinthModpackProvider.INSTANCE, manifest.getName(), manifest.getVersionId(), 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 (SUPPORTED_ICON_EXTS.contains(ext)) {
|
||||||
|
iconExt = ext;
|
||||||
|
dependents.add(downloadIconTask = new CacheFileTask(iconUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
dependencies.add(new ModrinthCompletionTask(dependencyManager, name, manifest));
|
dependencies.add(new ModrinthCompletionTask(dependencyManager, name, manifest));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,5 +153,13 @@ public class ModrinthInstallTask extends Task<Void> {
|
|||||||
Path root = repository.getVersionRoot(name);
|
Path root = repository.getVersionRoot(name);
|
||||||
Files.createDirectories(root);
|
Files.createDirectories(root);
|
||||||
JsonUtils.writeToJsonFile(root.resolve("modrinth.index.json"), manifest);
|
JsonUtils.writeToJsonFile(root.resolve("modrinth.index.json"), manifest);
|
||||||
|
|
||||||
|
if (iconExt != null) {
|
||||||
|
try {
|
||||||
|
Files.copy(downloadIconTask.getResult(), root.resolve("icon." + iconExt));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warning("Failed to copy modpack icon", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public final class ModrinthModpackProvider implements ModpackProvider {
|
|||||||
if (!(modpack.getManifest() instanceof ModrinthManifest modrinthManifest))
|
if (!(modpack.getManifest() instanceof ModrinthManifest modrinthManifest))
|
||||||
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
|
throw new MismatchedModpackTypeException(getName(), modpack.getManifest().getProvider().getName());
|
||||||
|
|
||||||
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new ModrinthInstallTask(dependencyManager, zipFile, modpack, modrinthManifest, name));
|
return new ModpackUpdateTask(dependencyManager.getGameRepository(), name, new ModrinthInstallTask(dependencyManager, zipFile, modpack, modrinthManifest, name, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,8 +58,8 @@ public final class ModrinthModpackProvider implements ModpackProvider {
|
|||||||
ModrinthManifest manifest = JsonUtils.fromNonNullJson(CompressingUtils.readTextZipEntry(zip, "modrinth.index.json"), ModrinthManifest.class);
|
ModrinthManifest manifest = JsonUtils.fromNonNullJson(CompressingUtils.readTextZipEntry(zip, "modrinth.index.json"), ModrinthManifest.class);
|
||||||
return new Modpack(manifest.getName(), "", manifest.getVersionId(), manifest.getGameVersion(), manifest.getSummary(), encoding, manifest) {
|
return new Modpack(manifest.getName(), "", manifest.getVersionId(), manifest.getGameVersion(), manifest.getSummary(), encoding, manifest) {
|
||||||
@Override
|
@Override
|
||||||
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
|
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) {
|
||||||
return new ModrinthInstallTask(dependencyManager, zipFile, this, manifest, name);
|
return new ModrinthInstallTask(dependencyManager, zipFile, this, manifest, name, iconUrl);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public final class MultiMCModpackProvider implements ModpackProvider {
|
|||||||
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, instanceStream, manifest);
|
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, instanceStream, manifest);
|
||||||
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg) {
|
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg) {
|
||||||
@Override
|
@Override
|
||||||
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
|
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) {
|
||||||
return new MultiMCModpackInstallTask(dependencyManager, zipFile, this, cfg, name);
|
return new MultiMCModpackInstallTask(dependencyManager, zipFile, this, cfg, name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class ServerModpackManifest implements ModpackManifest, Validation {
|
|||||||
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
|
.orElseThrow(() -> new IOException("Cannot find game version")).getVersion();
|
||||||
return new Modpack(name, author, version, gameVersion, description, encoding, this) {
|
return new Modpack(name, author, version, gameVersion, description, encoding, this) {
|
||||||
@Override
|
@Override
|
||||||
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name) {
|
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) {
|
||||||
return new ServerModpackLocalInstallTask(dependencyManager, zipFile, this, ServerModpackManifest.this, name);
|
return new ServerModpackLocalInstallTask(dependencyManager, zipFile, this, ServerModpackManifest.this, name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user