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
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public abstract class LocalizedRemoteModRepository implements RemoteModRepositor
protected abstract SortType getBackedRemoteModRepositorySortOrder();

@Override
public SearchResult search(DownloadProvider downloadProvider, String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, SortType sort, SortOrder sortOrder) throws IOException {
public SearchResult search(DownloadProvider downloadProvider, 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(downloadProvider, gameVersion, category, pageOffset, pageSize, searchFilter, sort, sortOrder);
return getBackedRemoteModRepository().search(downloadProvider, gameVersion, category, pageOffset, pageSize, searchFilter, sort, sortOrder, loaderType);
}

Set<String> englishSearchFiltersSet = new HashSet<>(INITIAL_CAPACITY);
Expand All @@ -66,7 +66,7 @@ public SearchResult search(DownloadProvider downloadProvider, String gameVersion
RemoteMod[] searchResultArray = new RemoteMod[pageSize];
int totalPages, chineseIndex = 0, englishIndex = pageSize - 1;
{
SearchResult searchResult = getBackedRemoteModRepository().search(downloadProvider, gameVersion, category, pageOffset, pageSize, String.join(" ", englishSearchFiltersSet), getBackedRemoteModRepositorySortOrder(), sortOrder);
SearchResult searchResult = getBackedRemoteModRepository().search(downloadProvider, 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?");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void loadVersion(Profile profile, String version) {

if (!searchInitialized) {
searchInitialized = true;
search("", null, 0, "", RemoteModRepository.SortType.POPULARITY);
search("", null, 0, "", RemoteModRepository.SortType.POPULARITY, RemoteModRepository.LoaderType.ALL);
}

if (versionSelection) {
Expand Down Expand Up @@ -158,7 +158,7 @@ public void selectVersion(String versionID) {
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);
Expand All @@ -174,7 +174,7 @@ private void search(String userGameVersion, RemoteModRepository.Category categor
: "";
}
}).thenApplyAsync(
gameVersion -> repository.search(downloadProvider, gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC)
gameVersion -> repository.search(downloadProvider, gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC, loader)
).whenComplete(Schedulers.javafx(), (result, exception) -> {
if (searchID != currentSearchID) {
return;
Expand All @@ -188,7 +188,7 @@ private void search(String userGameVersion, RemoteModRepository.Category categor
} else {
failed.set(true);
pageCount.set(-1);
retrySearch = () -> search(userGameVersion, category, pageOffset, searchFilter, sort);
retrySearch = () -> search(userGameVersion, category, pageOffset, searchFilter, sort, loader);
}
}).executor(true);
}
Expand Down Expand Up @@ -361,6 +361,16 @@ protected ModDownloadListPageSkin(DownloadListPage control) {
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 -> {
Expand All @@ -376,7 +386,8 @@ protected ModDownloadListPageSkin(DownloadListPage control) {
.orElse(null),
pageOffset == -1 ? 0 : pageOffset,
nameField.getText(),
sortComboBox.getSelectionModel().getSelectedItem());
sortComboBox.getSelectionModel().getSelectedItem(),
loaderComboBox.getSelectionModel().getSelectedItem());
};

control.listenerHolder.add(FXUtils.observeWeak(
Expand All @@ -386,7 +397,8 @@ protected ModDownloadListPageSkin(DownloadListPage control) {
gameVersionField.getSelectionModel().selectedItemProperty(),
categoryComboBox.getSelectionModel().selectedItemProperty(),
nameField.textProperty(),
sortComboBox.getSelectionModel().selectedItemProperty()
sortComboBox.getSelectionModel().selectedItemProperty(),
loaderComboBox.getSelectionModel().selectedItemProperty()
));

HBox actionsBox = new HBox(8);
Expand Down Expand Up @@ -493,6 +505,7 @@ protected ModDownloadListPageSkin(DownloadListPage control) {
gameVersionField.setOnAction(searchAction);
categoryComboBox.setOnAction(searchAction);
sortComboBox.setOnAction(searchAction);
loaderComboBox.setOnAction(searchAction);
}

SpinnerPane spinnerPane = new SpinnerPane();
Expand Down
6 changes: 6 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,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
Expand Down
6 changes: 6 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,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=開啟檔案失敗
Expand Down
6 changes: 6 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,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=打开文件失败
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ enum SortType {
TOTAL_DOWNLOADS
}

enum LoaderType {
ALL,
FORGE,
NEOFORGE,
FABRIC,
QUILT
}

enum SortOrder {
ASC,
DESC
Expand Down Expand Up @@ -84,8 +92,7 @@ public int getTotalPages() {
}
}

SearchResult search(DownloadProvider downloadProvider, String gameVersion, @Nullable Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder)
throws IOException;
SearchResult search(DownloadProvider downloadProvider, 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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,22 @@ private int toModsSearchSortField(SortType sort) {
}
}

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) {
Expand All @@ -109,21 +125,28 @@ private int calculateTotalPages(Response<List<CurseAddon>> response, int pageSiz
}

@Override
public SearchResult search(DownloadProvider downloadProvider, String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder) throws IOException {
public SearchResult search(DownloadProvider downloadProvider, 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 = withApiKey(HttpRequest.GET(downloadProvider.injectURL(NetworkUtils.withQuery(PREFIX + "/v1/mods/search", mapOf(
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)))))))

Map<String,String> params = new HashMap<>(Map.of(
"gameId", "432",
"classId",Integer.toString(section),
"categoryId",Integer.toString(categoryId),
"gameVersion", gameVersion,
"searchFilter", searchFilter,
"sortField", Integer.toString(toModsSearchSortField(sortType)),
"sortOrder", toSortOrder(sortOrder),
"index", Integer.toString(pageOffset * pageSize),
"pageSize", Integer.toString(pageSize)));

if (loaderType != LoaderType.ALL) {
params.put("modLoaderTypes", String.format("[%s]", toModsSearchModloaderField(loaderType)));
}

Response<List<CurseAddon>> response = withApiKey(HttpRequest.GET(downloadProvider.injectURL(NetworkUtils.withQuery(PREFIX + "/v1/mods/search", params))))
.getJson(Response.typeOf(listTypeOf(CurseAddon.class)));
if (searchFilter.isEmpty()) {
return new SearchResult(response.getData().stream().map(CurseAddon::toMod), calculateTotalPages(response, pageSize));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,25 @@ private static String convertSortType(SortType sortType) {
}

@Override
public SearchResult search(DownloadProvider downloadProvider, String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sort, SortOrder sortOrder) throws IOException {
public SearchResult search(DownloadProvider downloadProvider, 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)),
Expand Down