mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-08-03 11:26:38 -04:00
Merge dbeb69856162eba045cc3ce822563ac60697ab8b into 9969dc60c5278340b6b9a4d7facdde620e99d1f5
This commit is contained in:
commit
17600cae47
@ -41,9 +41,9 @@ public abstract class LocalizedRemoteModRepository implements RemoteModRepositor
|
||||
protected abstract SortType getBackedRemoteModRepositorySortOrder();
|
||||
|
||||
@Override
|
||||
public SearchResult search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, SortType sort, SortOrder sortOrder) throws IOException {
|
||||
public SearchResult search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, SortType sort, SortOrder sortOrder, LoaderType loaderType) throws IOException {
|
||||
if (!StringUtils.containsChinese(searchFilter)) {
|
||||
return getBackedRemoteModRepository().search(gameVersion, category, pageOffset, pageSize, searchFilter, sort, sortOrder);
|
||||
return getBackedRemoteModRepository().search(gameVersion, category, pageOffset, pageSize, searchFilter, sort, sortOrder, loaderType);
|
||||
}
|
||||
|
||||
Set<String> englishSearchFiltersSet = new HashSet<>(INITIAL_CAPACITY);
|
||||
@ -65,7 +65,7 @@ public abstract class LocalizedRemoteModRepository implements RemoteModRepositor
|
||||
RemoteMod[] searchResultArray = new RemoteMod[pageSize];
|
||||
int totalPages, chineseIndex = 0, englishIndex = pageSize - 1;
|
||||
{
|
||||
SearchResult searchResult = getBackedRemoteModRepository().search(gameVersion, category, pageOffset, pageSize, String.join(" ", englishSearchFiltersSet), getBackedRemoteModRepositorySortOrder(), sortOrder);
|
||||
SearchResult searchResult = getBackedRemoteModRepository().search(gameVersion, category, pageOffset, pageSize, String.join(" ", englishSearchFiltersSet), getBackedRemoteModRepositorySortOrder(), sortOrder, loaderType);
|
||||
for (Iterator<RemoteMod> iterator = searchResult.getUnsortedResults().iterator(); iterator.hasNext(); ) {
|
||||
if (chineseIndex > englishIndex) {
|
||||
LOG.warning("Too many search results! Are the backed remote mod repository broken? Or are the API broken?");
|
||||
|
@ -116,7 +116,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
|
||||
if (!searchInitialized) {
|
||||
searchInitialized = true;
|
||||
search("", null, 0, "", RemoteModRepository.SortType.POPULARITY);
|
||||
search("", null, 0, "", RemoteModRepository.SortType.POPULARITY, RemoteModRepository.LoaderType.ALL);
|
||||
}
|
||||
|
||||
if (versionSelection) {
|
||||
@ -155,7 +155,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
FXUtils.runInFX(() -> selectedVersion.set(versionID));
|
||||
}
|
||||
|
||||
private void search(String userGameVersion, RemoteModRepository.Category category, int pageOffset, String searchFilter, RemoteModRepository.SortType sort) {
|
||||
private void search(String userGameVersion, RemoteModRepository.Category category, int pageOffset, String searchFilter, RemoteModRepository.SortType sort, RemoteModRepository.LoaderType loader) {
|
||||
retrySearch = null;
|
||||
setLoading(true);
|
||||
setFailed(false);
|
||||
@ -171,7 +171,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
: "";
|
||||
}
|
||||
}).thenApplyAsync(
|
||||
gameVersion -> repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC)
|
||||
gameVersion -> repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC, loader)
|
||||
).whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
if (searchID != currentSearchID) {
|
||||
return;
|
||||
@ -185,7 +185,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
} else {
|
||||
failed.set(true);
|
||||
pageCount.set(-1);
|
||||
retrySearch = () -> search(userGameVersion, category, pageOffset, searchFilter, sort);
|
||||
retrySearch = () -> search(userGameVersion, category, pageOffset, searchFilter, sort, loader);
|
||||
}
|
||||
}).executor(true);
|
||||
}
|
||||
@ -357,6 +357,16 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
sortComboBox.getSelectionModel().select(0);
|
||||
searchPane.addRow(rowIndex++, new Label(i18n("mods.category")), categoryStackPane, new Label(i18n("search.sort")), sortStackPane);
|
||||
|
||||
StackPane loaderStackPane = new StackPane();
|
||||
JFXComboBox<RemoteModRepository.LoaderType> loaderComboBox = new JFXComboBox<>();
|
||||
loaderStackPane.getChildren().setAll(loaderComboBox);
|
||||
loaderComboBox.prefWidthProperty().bind(loaderStackPane.widthProperty());
|
||||
loaderComboBox.getStyleClass().add("fit-width");
|
||||
loaderComboBox.setConverter(stringConverter(loaderType -> i18n("mods.loader." + loaderType.name().toLowerCase(Locale.ROOT))));
|
||||
loaderComboBox.getItems().setAll(RemoteModRepository.LoaderType.values());
|
||||
loaderComboBox.getSelectionModel().select(0);
|
||||
searchPane.addRow(rowIndex++, new Label(i18n("mods.loader")), loaderStackPane);
|
||||
|
||||
IntegerProperty filterID = new SimpleIntegerProperty(this, "Filter ID", 0);
|
||||
IntegerProperty currentFilterID = new SimpleIntegerProperty(this, "Current Filter ID", -1);
|
||||
EventHandler<ActionEvent> searchAction = e -> {
|
||||
@ -372,7 +382,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
.orElse(null),
|
||||
pageOffset == -1 ? 0 : pageOffset,
|
||||
nameField.getText(),
|
||||
sortComboBox.getSelectionModel().getSelectedItem());
|
||||
sortComboBox.getSelectionModel().getSelectedItem(),
|
||||
loaderComboBox.getSelectionModel().getSelectedItem());
|
||||
};
|
||||
|
||||
control.listenerHolder.add(FXUtils.observeWeak(
|
||||
@ -382,7 +393,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
gameVersionField.getSelectionModel().selectedItemProperty(),
|
||||
categoryComboBox.getSelectionModel().selectedItemProperty(),
|
||||
nameField.textProperty(),
|
||||
sortComboBox.getSelectionModel().selectedItemProperty()
|
||||
sortComboBox.getSelectionModel().selectedItemProperty(),
|
||||
loaderComboBox.getSelectionModel().selectedItemProperty()
|
||||
));
|
||||
|
||||
HBox actionsBox = new HBox(8);
|
||||
@ -489,6 +501,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
gameVersionField.setOnAction(searchAction);
|
||||
categoryComboBox.setOnAction(searchAction);
|
||||
sortComboBox.setOnAction(searchAction);
|
||||
loaderComboBox.setOnAction(searchAction);
|
||||
}
|
||||
|
||||
SpinnerPane spinnerPane = new SpinnerPane();
|
||||
|
@ -1069,6 +1069,12 @@ mods.url=Official Page
|
||||
mods.update_modpack_mod.warning=Updating mods in a modpack can lead to irreparable results, possibly corrupting the modpack so that it cannot launch. Are you sure you want to update?
|
||||
mods.install=Install
|
||||
mods.save_as=Save As
|
||||
mods.loader=Loader
|
||||
mods.loader.all=All
|
||||
mods.loader.fabric=Fabric
|
||||
mods.loader.forge=Forge
|
||||
mods.loader.neoforge=NeoForge
|
||||
mods.loader.quilt=Quilt
|
||||
|
||||
nbt.entries=%s entries
|
||||
nbt.open.failed=Failed to open file
|
||||
|
@ -875,6 +875,12 @@ mods.url=官方頁面
|
||||
mods.update_modpack_mod.warning=更新模組包中的模組可能導致模組包損壞,使模組包無法正常啟動。該操作不可逆,確定要更新嗎?
|
||||
mods.install=安裝到目前實例
|
||||
mods.save_as=下載到本機目錄
|
||||
mods.loader=加載器
|
||||
mods.loader.all=全部
|
||||
mods.loader.fabric=Fabric
|
||||
mods.loader.forge=Forge
|
||||
mods.loader.neoforge=NeoForge
|
||||
mods.loader.quilt=Quilt
|
||||
|
||||
nbt.entries=%s 個條目
|
||||
nbt.open.failed=開啟檔案失敗
|
||||
|
@ -885,6 +885,12 @@ mods.url=官方页面
|
||||
mods.update_modpack_mod.warning=更新整合包中的模组可能导致整合包损坏,使整合包无法正常启动。该操作不可逆,确定要更新吗?
|
||||
mods.install=安装到当前版本
|
||||
mods.save_as=下载到本地文件夹
|
||||
mods.loader=加载器
|
||||
mods.loader.all=全部
|
||||
mods.loader.fabric=Fabric
|
||||
mods.loader.forge=Forge
|
||||
mods.loader.neoforge=NeoForge
|
||||
mods.loader.quilt=Quilt
|
||||
|
||||
nbt.entries=%s 个条目
|
||||
nbt.open.failed=打开文件失败
|
||||
|
@ -46,6 +46,14 @@ public interface RemoteModRepository {
|
||||
TOTAL_DOWNLOADS
|
||||
}
|
||||
|
||||
enum LoaderType {
|
||||
ALL,
|
||||
FORGE,
|
||||
NEOFORGE,
|
||||
FABRIC,
|
||||
QUILT
|
||||
}
|
||||
|
||||
enum SortOrder {
|
||||
ASC,
|
||||
DESC
|
||||
@ -83,8 +91,7 @@ public interface RemoteModRepository {
|
||||
}
|
||||
}
|
||||
|
||||
SearchResult search(String gameVersion, @Nullable Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder)
|
||||
throws IOException;
|
||||
SearchResult search(String gameVersion, @Nullable Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder, LoaderType loaderType) throws IOException;
|
||||
|
||||
Optional<RemoteMod.Version> getRemoteVersionByLocalFile(LocalModFile localModFile, Path file) throws IOException;
|
||||
|
||||
|
@ -84,6 +84,22 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository
|
||||
}
|
||||
}
|
||||
|
||||
private int toModsSearchModloaderField(LoaderType sort) {
|
||||
https://docs.curseforge.com/rest-api/#tocS_MinecraftModLoaderIndex
|
||||
switch (sort) {
|
||||
case FORGE:
|
||||
return 1;
|
||||
case FABRIC:
|
||||
return 4;
|
||||
case QUILT:
|
||||
return 5;
|
||||
case NEOFORGE:
|
||||
return 6;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private String toSortOrder(SortOrder sortOrder) {
|
||||
// https://docs.curseforge.com/#tocS_SortOrder
|
||||
switch (sortOrder) {
|
||||
@ -100,21 +116,29 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder) throws IOException {
|
||||
public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder, LoaderType loaderType) throws IOException {
|
||||
int categoryId = 0;
|
||||
if (category != null && category.getSelf() instanceof CurseAddon.Category) {
|
||||
categoryId = ((CurseAddon.Category) category.getSelf()).getId();
|
||||
}
|
||||
Response<List<CurseAddon>> response = HttpRequest.GET(PREFIX + "/v1/mods/search",
|
||||
pair("gameId", "432"),
|
||||
pair("classId", Integer.toString(section)),
|
||||
pair("categoryId", Integer.toString(categoryId)),
|
||||
pair("gameVersion", gameVersion),
|
||||
pair("searchFilter", searchFilter),
|
||||
pair("sortField", Integer.toString(toModsSearchSortField(sortType))),
|
||||
pair("sortOrder", toSortOrder(sortOrder)),
|
||||
pair("index", Integer.toString(pageOffset * pageSize)),
|
||||
pair("pageSize", Integer.toString(pageSize)))
|
||||
|
||||
List<Pair<String, String>> params = new ArrayList<>();
|
||||
params.add(pair("gameId", "432"));
|
||||
params.add(pair("classId", Integer.toString(section)));
|
||||
params.add(pair("categoryId", Integer.toString(categoryId)));
|
||||
params.add(pair("gameVersion", gameVersion));
|
||||
|
||||
if (loaderType != LoaderType.ALL) {
|
||||
params.add(pair("modLoaderTypes", String.format("[%s]", toModsSearchModloaderField(loaderType))));
|
||||
}
|
||||
|
||||
params.add(pair("searchFilter", searchFilter));
|
||||
params.add(pair("sortField", Integer.toString(toModsSearchSortField(sortType))));
|
||||
params.add(pair("sortOrder", toSortOrder(sortOrder)));
|
||||
params.add(pair("index", Integer.toString(pageOffset * pageSize)));
|
||||
params.add(pair("pageSize", Integer.toString(pageSize)));
|
||||
|
||||
Response<List<CurseAddon>> response = HttpRequest.GET(PREFIX + "/v1/mods/search", params.toArray(new Pair[0]))
|
||||
.header("X-API-KEY", apiKey)
|
||||
.getJson(Response.typeOf(listTypeOf(CurseAddon.class)));
|
||||
if (searchFilter.isEmpty()) {
|
||||
|
@ -79,15 +79,25 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sort, SortOrder sortOrder) throws IOException {
|
||||
public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sort, SortOrder sortOrder, LoaderType loaderType) throws IOException {
|
||||
List<List<String>> facets = new ArrayList<>();
|
||||
facets.add(Collections.singletonList("project_type:" + projectType));
|
||||
if (StringUtils.isNotBlank(gameVersion)) {
|
||||
facets.add(Collections.singletonList("versions:" + gameVersion));
|
||||
}
|
||||
List<String> categorys = new ArrayList<>();
|
||||
|
||||
if (category != null && StringUtils.isNotBlank(category.getId())) {
|
||||
facets.add(Collections.singletonList("categories:" + category.getId()));
|
||||
categorys.add(category.getId());
|
||||
}
|
||||
if (loaderType != null && loaderType != LoaderType.ALL) {
|
||||
categorys.add(loaderType.name());
|
||||
}
|
||||
|
||||
if (!categorys.isEmpty()) {
|
||||
facets.add(Collections.singletonList("categories:" + String.join(",", categorys)));
|
||||
}
|
||||
|
||||
Map<String, String> query = mapOf(
|
||||
pair("query", searchFilter),
|
||||
pair("facets", JsonUtils.UGLY_GSON.toJson(facets)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user