refactor(download): RemoteModRepository
This commit is contained in:
@@ -32,7 +32,6 @@ import javafx.stage.StageStyle;
|
||||
import org.jackhuang.hmcl.Launcher;
|
||||
import org.jackhuang.hmcl.Metadata;
|
||||
import org.jackhuang.hmcl.download.java.JavaRepository;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseModManager;
|
||||
import org.jackhuang.hmcl.setting.Accounts;
|
||||
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
|
||||
import org.jackhuang.hmcl.setting.Profiles;
|
||||
@@ -49,9 +48,7 @@ import org.jackhuang.hmcl.ui.main.LauncherSettingsPage;
|
||||
import org.jackhuang.hmcl.ui.main.RootPage;
|
||||
import org.jackhuang.hmcl.ui.multiplayer.MultiplayerPage;
|
||||
import org.jackhuang.hmcl.ui.versions.GameListPage;
|
||||
import org.jackhuang.hmcl.ui.versions.DownloadListPage;
|
||||
import org.jackhuang.hmcl.ui.versions.VersionPage;
|
||||
import org.jackhuang.hmcl.ui.versions.Versions;
|
||||
import org.jackhuang.hmcl.util.FutureCallback;
|
||||
import org.jackhuang.hmcl.util.Lazy;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
@@ -87,13 +84,6 @@ public final class Controllers {
|
||||
});
|
||||
private static Lazy<RootPage> rootPage = new Lazy<>(RootPage::new);
|
||||
private static DecoratorController decorator;
|
||||
private static Lazy<DownloadListPage> modDownloadListPage = new Lazy<>(() -> {
|
||||
return new DownloadListPage(CurseModManager.SECTION_MODPACK, Versions::downloadModpackImpl) {
|
||||
{
|
||||
state.set(State.fromTitle(i18n("modpack.download")));
|
||||
}
|
||||
};
|
||||
});
|
||||
private static Lazy<DownloadPage> downloadPage = new Lazy<>(DownloadPage::new);
|
||||
private static Lazy<AccountListPage> accountListPage = new Lazy<>(() -> {
|
||||
AccountListPage accountListPage = new AccountListPage();
|
||||
@@ -131,11 +121,6 @@ public final class Controllers {
|
||||
return rootPage.get();
|
||||
}
|
||||
|
||||
// FXThread
|
||||
public static DownloadListPage getModpackDownloadListPage() {
|
||||
return modDownloadListPage.get();
|
||||
}
|
||||
|
||||
// FXThread
|
||||
public static MultiplayerPage getMultiplayerPage() {
|
||||
return multiplayerPage.get();
|
||||
@@ -318,7 +303,6 @@ public final class Controllers {
|
||||
versionPage = null;
|
||||
gameListPage = null;
|
||||
settingsPage = null;
|
||||
modDownloadListPage = null;
|
||||
decorator = null;
|
||||
stage = null;
|
||||
scene = null;
|
||||
|
||||
@@ -24,8 +24,8 @@ import javafx.scene.Node;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import org.jackhuang.hmcl.download.*;
|
||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||
import org.jackhuang.hmcl.mod.DownloadManager;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseModManager;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
||||
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Profiles;
|
||||
@@ -81,7 +81,7 @@ public class DownloadPage extends BorderPane implements DecoratorPage {
|
||||
newGameTab.setNodeSupplier(() -> new VersionsPage(versionPageNavigator, i18n("install.installer.choose", i18n("install.installer.game")), "", DownloadProviders.getDownloadProvider(),
|
||||
"game", versionPageNavigator::onGameSelected));
|
||||
modpackTab.setNodeSupplier(() -> {
|
||||
DownloadListPage page = new DownloadListPage(CurseModManager.SECTION_MODPACK, Versions::downloadModpackImpl);
|
||||
DownloadListPage page = new DownloadListPage(CurseForgeRemoteModRepository.MODPACKS, Versions::downloadModpackImpl);
|
||||
|
||||
JFXButton installLocalModpackButton = new JFXButton(i18n("install.modpack"));
|
||||
installLocalModpackButton.setButtonType(JFXButton.ButtonType.RAISED);
|
||||
@@ -91,10 +91,10 @@ public class DownloadPage extends BorderPane implements DecoratorPage {
|
||||
page.getActions().add(installLocalModpackButton);
|
||||
return page;
|
||||
});
|
||||
modTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MOD, (profile, version, file) -> download(profile, version, file, "mods"), true));
|
||||
resourcePackTab.setNodeSupplier(() -> new DownloadListPage(CurseModManager.SECTION_RESOURCE_PACK, (profile, version, file) -> download(profile, version, file, "resourcepacks")));
|
||||
// customizationTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_CUSTOMIZATION, this::download));
|
||||
worldTab.setNodeSupplier(() -> new DownloadListPage(CurseModManager.SECTION_WORLD));
|
||||
modTab.setNodeSupplier(() -> new ModDownloadListPage((profile, version, file) -> download(profile, version, file, "mods"), true));
|
||||
resourcePackTab.setNodeSupplier(() -> new DownloadListPage(CurseForgeRemoteModRepository.RESOURCE_PACKS, (profile, version, file) -> download(profile, version, file, "resourcepacks")));
|
||||
// customizationTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.CUSTOMIZATIONS, this::download));
|
||||
worldTab.setNodeSupplier(() -> new DownloadListPage(CurseForgeRemoteModRepository.WORLDS));
|
||||
tab = new TabHeader(newGameTab, modpackTab, modTab, resourcePackTab, worldTab);
|
||||
|
||||
Profiles.registerVersionsListener(this::loadVersions);
|
||||
@@ -154,7 +154,7 @@ public class DownloadPage extends BorderPane implements DecoratorPage {
|
||||
setCenter(transitionPane);
|
||||
}
|
||||
|
||||
private void download(Profile profile, @Nullable String version, DownloadManager.Version file, String subdirectoryName) {
|
||||
private void download(Profile profile, @Nullable String version, RemoteModRepository.Version file, String subdirectoryName) {
|
||||
if (version == null) version = profile.getSelectedVersion();
|
||||
|
||||
Path runDirectory = profile.getRepository().hasVersion(version) ? profile.getRepository().getRunDirectory(version).toPath() : profile.getRepository().getBaseDirectory().toPath();
|
||||
|
||||
@@ -40,9 +40,7 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.*;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.mod.DownloadManager;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseAddon;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseModManager;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
@@ -55,14 +53,16 @@ import org.jackhuang.hmcl.ui.construct.SpinnerPane;
|
||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.AggregatedObservableList;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
@@ -74,7 +74,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
private final BooleanProperty failed = new SimpleBooleanProperty(false);
|
||||
private final boolean versionSelection;
|
||||
private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>();
|
||||
private final ListProperty<DownloadManager.Mod> items = new SimpleListProperty<>(this, "items", FXCollections.observableArrayList());
|
||||
private final ListProperty<RemoteModRepository.Mod> items = new SimpleListProperty<>(this, "items", FXCollections.observableArrayList());
|
||||
private final ObservableList<String> versions = FXCollections.observableArrayList();
|
||||
private final StringProperty selectedVersion = new SimpleStringProperty();
|
||||
private final DownloadPage.DownloadCallback callback;
|
||||
@@ -85,23 +85,18 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
protected final StringProperty downloadSource = new SimpleStringProperty();
|
||||
private final WeakListenerHolder listenerHolder = new WeakListenerHolder();
|
||||
private TaskExecutor executor;
|
||||
protected RemoteModRepository repository;
|
||||
|
||||
/**
|
||||
* @see org.jackhuang.hmcl.mod.curse.CurseModManager#SECTION_MODPACK
|
||||
* @see org.jackhuang.hmcl.mod.curse.CurseModManager#SECTION_MOD
|
||||
*/
|
||||
private final int section;
|
||||
|
||||
public DownloadListPage(int section) {
|
||||
this(section, null);
|
||||
public DownloadListPage(RemoteModRepository repository) {
|
||||
this(repository, null);
|
||||
}
|
||||
|
||||
public DownloadListPage(int section, DownloadPage.DownloadCallback callback) {
|
||||
this(section, callback, false);
|
||||
public DownloadListPage(RemoteModRepository repository, DownloadPage.DownloadCallback callback) {
|
||||
this(repository, callback, false);
|
||||
}
|
||||
|
||||
public DownloadListPage(int section, DownloadPage.DownloadCallback callback, boolean versionSelection) {
|
||||
this.section = section;
|
||||
public DownloadListPage(RemoteModRepository repository, DownloadPage.DownloadCallback callback, boolean versionSelection) {
|
||||
this.repository = repository;
|
||||
this.callback = callback;
|
||||
this.versionSelection = versionSelection;
|
||||
}
|
||||
@@ -119,7 +114,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
|
||||
if (!searchInitialized) {
|
||||
searchInitialized = true;
|
||||
search("", 0, 0, "", 0);
|
||||
search("", null, 0, "", 0);
|
||||
}
|
||||
|
||||
if (versionSelection) {
|
||||
@@ -154,7 +149,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
this.loading.set(loading);
|
||||
}
|
||||
|
||||
public void search(String userGameVersion, int category, int pageOffset, String searchFilter, int sort) {
|
||||
public void search(String userGameVersion, RemoteModRepository.Category category, int pageOffset, String searchFilter, int sort) {
|
||||
setLoading(true);
|
||||
setFailed(false);
|
||||
File versionJar = StringUtils.isNotBlank(version.get().getVersion())
|
||||
@@ -173,7 +168,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
}
|
||||
return gameVersion;
|
||||
}).thenApplyAsync(gameVersion -> {
|
||||
return searchImpl(gameVersion, category, section, pageOffset, searchFilter, sort);
|
||||
return repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort);
|
||||
}).whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
setLoading(false);
|
||||
if (exception == null) {
|
||||
@@ -185,14 +180,14 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
}).executor(true);
|
||||
}
|
||||
|
||||
protected Stream<DownloadManager.Mod> searchImpl(String gameVersion, int category, int section, int pageOffset, String searchFilter, int sort) throws Exception {
|
||||
return CurseModManager.searchPaginated(gameVersion, category, section, pageOffset, searchFilter, sort).stream().map(CurseAddon::toMod);
|
||||
}
|
||||
|
||||
protected String getLocalizedCategory(String category) {
|
||||
return i18n("curse.category." + category);
|
||||
}
|
||||
|
||||
protected String getLocalizedCategoryIndent(ModDownloadListPageSkin.CategoryIndented category) {
|
||||
return StringUtils.repeats(' ', category.indent * 4) + getLocalizedCategory(category.getCategory() == null ? "0" : category.getCategory().getId());
|
||||
}
|
||||
|
||||
protected String getLocalizedOfficialPage() {
|
||||
return i18n("mods.curseforge");
|
||||
}
|
||||
@@ -263,7 +258,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
JFXComboBox<String> gameVersionField = new JFXComboBox<>();
|
||||
gameVersionField.setMaxWidth(Double.MAX_VALUE);
|
||||
gameVersionField.setEditable(true);
|
||||
gameVersionField.getItems().setAll(DownloadManager.DEFAULT_GAME_VERSIONS);
|
||||
gameVersionField.getItems().setAll(RemoteModRepository.DEFAULT_GAME_VERSIONS);
|
||||
Label lblGameVersion = new Label(i18n("world.game_version"));
|
||||
searchPane.addRow(rowIndex++, new Label(i18n("mods.name")), nameField, lblGameVersion, gameVersionField);
|
||||
|
||||
@@ -284,17 +279,18 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
|
||||
StackPane categoryStackPane = new StackPane();
|
||||
JFXComboBox<CategoryIndented> categoryComboBox = new JFXComboBox<>();
|
||||
categoryComboBox.getItems().setAll(new CategoryIndented(0, 0));
|
||||
categoryComboBox.getItems().setAll(new CategoryIndented(0, null));
|
||||
categoryStackPane.getChildren().setAll(categoryComboBox);
|
||||
categoryComboBox.prefWidthProperty().bind(categoryStackPane.widthProperty());
|
||||
categoryComboBox.getStyleClass().add("fit-width");
|
||||
categoryComboBox.setPromptText(i18n("mods.category"));
|
||||
categoryComboBox.getSelectionModel().select(0);
|
||||
Task.supplyAsync(() -> CurseModManager.getCategories(getSkinnable().section))
|
||||
categoryComboBox.setConverter(stringConverter(getSkinnable()::getLocalizedCategoryIndent));
|
||||
Task.supplyAsync(() -> getSkinnable().repository.getCategories())
|
||||
.thenAcceptAsync(Schedulers.javafx(), categories -> {
|
||||
List<CategoryIndented> result = new ArrayList<>();
|
||||
result.add(new CategoryIndented(0, 0));
|
||||
for (CurseModManager.Category category : categories) {
|
||||
result.add(new CategoryIndented(0, null));
|
||||
for (RemoteModRepository.Category category : Lang.toIterable(categories)) {
|
||||
resolveCategory(category, 0, result);
|
||||
}
|
||||
categoryComboBox.getItems().setAll(result);
|
||||
@@ -331,8 +327,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
EventHandler<ActionEvent> searchAction = e -> getSkinnable()
|
||||
.search(gameVersionField.getSelectionModel().getSelectedItem(),
|
||||
Optional.ofNullable(categoryComboBox.getSelectionModel().getSelectedItem())
|
||||
.map(CategoryIndented::getCategoryId)
|
||||
.orElse(0),
|
||||
.map(CategoryIndented::getCategory)
|
||||
.orElse(null),
|
||||
0,
|
||||
nameField.getText(),
|
||||
sortComboBox.getSelectionModel().getSelectedIndex());
|
||||
@@ -355,16 +351,16 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
}
|
||||
}, getSkinnable().failedProperty()));
|
||||
|
||||
JFXListView<DownloadManager.Mod> listView = new JFXListView<>();
|
||||
JFXListView<RemoteModRepository.Mod> listView = new JFXListView<>();
|
||||
spinnerPane.setContent(listView);
|
||||
Bindings.bindContent(listView.getItems(), getSkinnable().items);
|
||||
listView.setOnMouseClicked(e -> {
|
||||
if (listView.getSelectionModel().getSelectedIndex() < 0)
|
||||
return;
|
||||
DownloadManager.Mod selectedItem = listView.getSelectionModel().getSelectedItem();
|
||||
RemoteModRepository.Mod selectedItem = listView.getSelectionModel().getSelectedItem();
|
||||
Controllers.navigate(new DownloadPage(getSkinnable(), selectedItem, getSkinnable().getProfileVersion(), getSkinnable().callback));
|
||||
});
|
||||
listView.setCellFactory(x -> new FloatListCell<DownloadManager.Mod>(listView) {
|
||||
listView.setCellFactory(x -> new FloatListCell<RemoteModRepository.Mod>(listView) {
|
||||
TwoLineListItem content = new TwoLineListItem();
|
||||
ImageView imageView = new ImageView();
|
||||
|
||||
@@ -377,7 +373,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControl(DownloadManager.Mod dataItem, boolean empty) {
|
||||
protected void updateControl(RemoteModRepository.Mod dataItem, boolean empty) {
|
||||
if (empty) return;
|
||||
ModTranslations.Mod mod = ModTranslations.getModByCurseForgeId(dataItem.getSlug());
|
||||
content.setTitle(mod != null ? mod.getDisplayName() : dataItem.getTitle());
|
||||
@@ -398,30 +394,25 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
|
||||
private static class CategoryIndented {
|
||||
private final int indent;
|
||||
private final int categoryId;
|
||||
private final RemoteModRepository.Category category;
|
||||
|
||||
public CategoryIndented(int indent, int categoryId) {
|
||||
public CategoryIndented(int indent, RemoteModRepository.Category category) {
|
||||
this.indent = indent;
|
||||
this.categoryId = categoryId;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public int getIndent() {
|
||||
return indent;
|
||||
}
|
||||
|
||||
public int getCategoryId() {
|
||||
return categoryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.repeats(' ', indent) + i18n("curse.category." + categoryId);
|
||||
public RemoteModRepository.Category getCategory() {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
|
||||
private static void resolveCategory(CurseModManager.Category category, int indent, List<CategoryIndented> result) {
|
||||
result.add(new CategoryIndented(indent, category.getId()));
|
||||
for (CurseModManager.Category subcategory : category.getSubcategories()) {
|
||||
private static void resolveCategory(RemoteModRepository.Category category, int indent, List<CategoryIndented> result) {
|
||||
result.add(new CategoryIndented(indent, category));
|
||||
for (RemoteModRepository.Category subcategory : category.getSubcategories()) {
|
||||
resolveCategory(subcategory, indent + 1, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.stage.FileChooser;
|
||||
import org.jackhuang.hmcl.mod.DownloadManager;
|
||||
import org.jackhuang.hmcl.mod.ModManager;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
@@ -69,16 +69,16 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
private final BooleanProperty loaded = new SimpleBooleanProperty(false);
|
||||
private final BooleanProperty loading = new SimpleBooleanProperty(false);
|
||||
private final BooleanProperty failed = new SimpleBooleanProperty(false);
|
||||
private final DownloadManager.Mod addon;
|
||||
private final RemoteModRepository.Mod addon;
|
||||
private final ModTranslations.Mod mod;
|
||||
private final Profile.ProfileVersion version;
|
||||
private final DownloadCallback callback;
|
||||
private final DownloadListPage page;
|
||||
|
||||
private List<DownloadManager.Mod> dependencies;
|
||||
private SimpleMultimap<String, DownloadManager.Version> versions;
|
||||
private List<RemoteModRepository.Mod> dependencies;
|
||||
private SimpleMultimap<String, RemoteModRepository.Version> versions;
|
||||
|
||||
public DownloadPage(DownloadListPage page, DownloadManager.Mod addon, Profile.ProfileVersion version, @Nullable DownloadCallback callback) {
|
||||
public DownloadPage(DownloadListPage page, RemoteModRepository.Mod addon, Profile.ProfileVersion version, @Nullable DownloadCallback callback) {
|
||||
this.page = page;
|
||||
this.addon = addon;
|
||||
this.mod = ModTranslations.getModByCurseForgeId(addon.getSlug());
|
||||
@@ -95,7 +95,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
Task.allOf(
|
||||
Task.supplyAsync(() -> addon.getData().loadDependencies()),
|
||||
Task.supplyAsync(() -> {
|
||||
Stream<DownloadManager.Version> versions = addon.getData().loadVersions();
|
||||
Stream<RemoteModRepository.Version> versions = addon.getData().loadVersions();
|
||||
// if (StringUtils.isNotBlank(version.getVersion())) {
|
||||
// Optional<String> gameVersion = GameVersion.minecraftVersion(versionJar);
|
||||
// if (gameVersion.isPresent()) {
|
||||
@@ -108,9 +108,9 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
.whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
if (exception == null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DownloadManager.Mod> dependencies = (List<DownloadManager.Mod>) result.get(0);
|
||||
List<RemoteModRepository.Mod> dependencies = (List<RemoteModRepository.Mod>) result.get(0);
|
||||
@SuppressWarnings("unchecked")
|
||||
SimpleMultimap<String, DownloadManager.Version> versions = (SimpleMultimap<String, DownloadManager.Version>) result.get(1);
|
||||
SimpleMultimap<String, RemoteModRepository.Version> versions = (SimpleMultimap<String, RemoteModRepository.Version>) result.get(1);
|
||||
|
||||
this.dependencies = dependencies;
|
||||
this.versions = versions;
|
||||
@@ -126,9 +126,9 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
this.state.set(State.fromTitle(addon.getTitle()));
|
||||
}
|
||||
|
||||
private SimpleMultimap<String, DownloadManager.Version> sortVersions(Stream<DownloadManager.Version> versions) {
|
||||
SimpleMultimap<String, DownloadManager.Version> classifiedVersions
|
||||
= new SimpleMultimap<String, DownloadManager.Version>(HashMap::new, ArrayList::new);
|
||||
private SimpleMultimap<String, RemoteModRepository.Version> sortVersions(Stream<RemoteModRepository.Version> versions) {
|
||||
SimpleMultimap<String, RemoteModRepository.Version> classifiedVersions
|
||||
= new SimpleMultimap<String, RemoteModRepository.Version>(HashMap::new, ArrayList::new);
|
||||
versions.forEach(version -> {
|
||||
for (String gameVersion : version.getGameVersions()) {
|
||||
classifiedVersions.put(gameVersion, version);
|
||||
@@ -136,13 +136,13 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
});
|
||||
|
||||
for (String gameVersion : classifiedVersions.keys()) {
|
||||
List<DownloadManager.Version> versionList = (List<DownloadManager.Version>) classifiedVersions.get(gameVersion);
|
||||
versionList.sort(Comparator.comparing(DownloadManager.Version::getDatePublished).reversed());
|
||||
List<RemoteModRepository.Version> versionList = (List<RemoteModRepository.Version>) classifiedVersions.get(gameVersion);
|
||||
versionList.sort(Comparator.comparing(RemoteModRepository.Version::getDatePublished).reversed());
|
||||
}
|
||||
return classifiedVersions;
|
||||
}
|
||||
|
||||
public DownloadManager.Mod getAddon() {
|
||||
public RemoteModRepository.Mod getAddon() {
|
||||
return addon;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
this.failed.set(failed);
|
||||
}
|
||||
|
||||
public void download(DownloadManager.Version file) {
|
||||
public void download(RemoteModRepository.Version file) {
|
||||
if (this.callback == null) {
|
||||
saveAs(file);
|
||||
} else {
|
||||
@@ -182,7 +182,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAs(DownloadManager.Version file) {
|
||||
public void saveAs(RemoteModRepository.Version file) {
|
||||
String extension = StringUtils.substringAfterLast(file.getFile().getFilename(), '.');
|
||||
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
@@ -328,7 +328,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
|
||||
private static final class DependencyModItem extends StackPane {
|
||||
|
||||
DependencyModItem(DownloadListPage page, DownloadManager.Mod addon, Profile.ProfileVersion version, DownloadCallback callback) {
|
||||
DependencyModItem(DownloadListPage page, RemoteModRepository.Mod addon, Profile.ProfileVersion version, DownloadCallback callback) {
|
||||
HBox pane = new HBox(8);
|
||||
pane.setPadding(new Insets(8));
|
||||
pane.setAlignment(Pos.CENTER_LEFT);
|
||||
@@ -355,7 +355,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
}
|
||||
|
||||
private static final class ModItem extends StackPane {
|
||||
ModItem(DownloadManager.Version dataItem, DownloadPage selfPage) {
|
||||
ModItem(RemoteModRepository.Version dataItem, DownloadPage selfPage) {
|
||||
HBox pane = new HBox(8);
|
||||
pane.setPadding(new Insets(8));
|
||||
pane.setAlignment(Pos.CENTER_LEFT);
|
||||
@@ -399,6 +399,6 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault());
|
||||
|
||||
public interface DownloadCallback {
|
||||
void download(Profile profile, @Nullable String version, DownloadManager.Version file);
|
||||
void download(Profile profile, @Nullable String version, RemoteModRepository.Version file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,55 +17,76 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.versions;
|
||||
|
||||
import org.jackhuang.hmcl.mod.DownloadManager;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseAddon;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseModManager;
|
||||
import org.jackhuang.hmcl.mod.modrinth.Modrinth;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
||||
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class ModDownloadListPage extends DownloadListPage {
|
||||
public ModDownloadListPage(int section, DownloadPage.DownloadCallback callback, boolean versionSelection) {
|
||||
super(section, callback, versionSelection);
|
||||
public ModDownloadListPage(DownloadPage.DownloadCallback callback, boolean versionSelection) {
|
||||
super(null, callback, versionSelection);
|
||||
|
||||
repository = new Repository();
|
||||
|
||||
|
||||
supportChinese.set(true);
|
||||
downloadSources.get().setAll("mods.curseforge", "mods.modrinth");
|
||||
downloadSource.set("mods.curseforge");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<DownloadManager.Mod> searchImpl(String gameVersion, int category, int section, int pageOffset, String searchFilter, int sort) throws Exception {
|
||||
if (StringUtils.CHINESE_PATTERN.matcher(searchFilter).find()) {
|
||||
List<ModTranslations.Mod> mods = ModTranslations.searchMod(searchFilter);
|
||||
List<String> searchFilters = new ArrayList<>();
|
||||
int count = 0;
|
||||
for (ModTranslations.Mod mod : mods) {
|
||||
String englishName = mod.getName();
|
||||
if (StringUtils.isNotBlank(mod.getSubname())) {
|
||||
englishName = mod.getSubname();
|
||||
private class Repository implements RemoteModRepository {
|
||||
|
||||
@Override
|
||||
public Stream<Mod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
||||
String newSearchFilter;
|
||||
if (StringUtils.CHINESE_PATTERN.matcher(searchFilter).find()) {
|
||||
List<ModTranslations.Mod> mods = ModTranslations.searchMod(searchFilter);
|
||||
List<String> searchFilters = new ArrayList<>();
|
||||
int count = 0;
|
||||
for (ModTranslations.Mod mod : mods) {
|
||||
String englishName = mod.getName();
|
||||
if (StringUtils.isNotBlank(mod.getSubname())) {
|
||||
englishName = mod.getSubname();
|
||||
}
|
||||
|
||||
searchFilters.add(englishName);
|
||||
|
||||
count++;
|
||||
if (count >= 3) break;
|
||||
}
|
||||
|
||||
searchFilters.add(englishName);
|
||||
|
||||
count++;
|
||||
if (count >= 3) break;
|
||||
newSearchFilter = String.join(" ", searchFilters);
|
||||
} else {
|
||||
newSearchFilter = searchFilter;
|
||||
}
|
||||
return search(gameVersion, category, section, pageOffset, String.join(" ", searchFilters), sort);
|
||||
} else {
|
||||
return search(gameVersion, category, section, pageOffset, searchFilter, sort);
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<DownloadManager.Mod> search(String gameVersion, int category, int section, int pageOffset, String searchFilter, int sort) throws Exception {
|
||||
if ("mods.modrinth".equals(downloadSource.get())) {
|
||||
return Modrinth.searchPaginated(gameVersion, pageOffset, searchFilter).stream().map(Modrinth.ModResult::toMod);
|
||||
} else {
|
||||
return CurseModManager.searchPaginated(gameVersion, category, section, pageOffset, searchFilter, sort).stream().map(CurseAddon::toMod);
|
||||
if ("mods.modrinth".equals(downloadSource.get())) {
|
||||
return ModrinthRemoteModRepository.INSTANCE.search(gameVersion, category, pageOffset, pageSize, newSearchFilter, sort);
|
||||
} else {
|
||||
return CurseForgeRemoteModRepository.MODS.search(gameVersion, category, pageOffset, pageSize, newSearchFilter, sort);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Version> getRemoteVersionByLocalFile(Path file) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Category> getCategories() throws IOException {
|
||||
if ("mods.modrinth".equals(downloadSource.get())) {
|
||||
return ModrinthRemoteModRepository.INSTANCE.getCategories();
|
||||
} else {
|
||||
return CurseForgeRemoteModRepository.MODS.getCategories();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jackhuang.hmcl.download.game.GameAssetDownloadTask;
|
||||
import org.jackhuang.hmcl.game.GameDirectoryType;
|
||||
import org.jackhuang.hmcl.game.GameRepository;
|
||||
import org.jackhuang.hmcl.game.LauncherHelper;
|
||||
import org.jackhuang.hmcl.mod.DownloadManager;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
import org.jackhuang.hmcl.setting.Accounts;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Profiles;
|
||||
@@ -77,15 +77,7 @@ public final class Versions {
|
||||
}
|
||||
}
|
||||
|
||||
public static void downloadModpack() {
|
||||
Profile profile = Profiles.getSelectedProfile();
|
||||
if (profile.getRepository().isLoaded()) {
|
||||
Controllers.getModpackDownloadListPage().loadVersion(profile, null);
|
||||
Controllers.navigate(Controllers.getModpackDownloadListPage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void downloadModpackImpl(Profile profile, String version, DownloadManager.Version file) {
|
||||
public static void downloadModpackImpl(Profile profile, String version, RemoteModRepository.Version file) {
|
||||
Path modpack;
|
||||
URL downloadURL;
|
||||
try {
|
||||
@@ -101,7 +93,7 @@ public final class Versions {
|
||||
new FileDownloadTask(downloadURL, modpack.toFile())
|
||||
.whenComplete(Schedulers.javafx(), e -> {
|
||||
if (e == null) {
|
||||
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack.toFile()));
|
||||
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile, modpack.toFile()));
|
||||
} else {
|
||||
Controllers.dialog(
|
||||
i18n("install.failed.downloading.detail", file.getFile().getUrl()) + "\n" + StringUtils.getStackTrace(e),
|
||||
|
||||
Reference in New Issue
Block a user