refactor(mod): ModInfo -> LocalMod
This commit is contained in:
@@ -24,7 +24,7 @@ import javafx.scene.Node;
|
|||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import org.jackhuang.hmcl.download.*;
|
import org.jackhuang.hmcl.download.*;
|
||||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
||||||
import org.jackhuang.hmcl.setting.DownloadProviders;
|
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
@@ -154,7 +154,7 @@ public class DownloadPage extends BorderPane implements DecoratorPage {
|
|||||||
setCenter(transitionPane);
|
setCenter(transitionPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void download(Profile profile, @Nullable String version, RemoteModRepository.Version file, String subdirectoryName) {
|
private void download(Profile profile, @Nullable String version, RemoteMod.Version file, String subdirectoryName) {
|
||||||
if (version == null) version = profile.getSelectedVersion();
|
if (version == null) version = profile.getSelectedVersion();
|
||||||
|
|
||||||
Path runDirectory = profile.getRepository().hasVersion(version) ? profile.getRepository().getRunDirectory(version).toPath() : profile.getRepository().getBaseDirectory().toPath();
|
Path runDirectory = profile.getRepository().hasVersion(version) ? profile.getRepository().getRunDirectory(version).toPath() : profile.getRepository().getBaseDirectory().toPath();
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import org.jackhuang.hmcl.game.GameVersion;
|
import org.jackhuang.hmcl.game.GameVersion;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
@@ -74,7 +75,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
|||||||
private final BooleanProperty failed = new SimpleBooleanProperty(false);
|
private final BooleanProperty failed = new SimpleBooleanProperty(false);
|
||||||
private final boolean versionSelection;
|
private final boolean versionSelection;
|
||||||
private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>();
|
private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>();
|
||||||
private final ListProperty<RemoteModRepository.Mod> items = new SimpleListProperty<>(this, "items", FXCollections.observableArrayList());
|
private final ListProperty<RemoteMod> items = new SimpleListProperty<>(this, "items", FXCollections.observableArrayList());
|
||||||
private final ObservableList<String> versions = FXCollections.observableArrayList();
|
private final ObservableList<String> versions = FXCollections.observableArrayList();
|
||||||
private final StringProperty selectedVersion = new SimpleStringProperty();
|
private final StringProperty selectedVersion = new SimpleStringProperty();
|
||||||
private final DownloadPage.DownloadCallback callback;
|
private final DownloadPage.DownloadCallback callback;
|
||||||
@@ -351,16 +352,16 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
|||||||
}
|
}
|
||||||
}, getSkinnable().failedProperty()));
|
}, getSkinnable().failedProperty()));
|
||||||
|
|
||||||
JFXListView<RemoteModRepository.Mod> listView = new JFXListView<>();
|
JFXListView<RemoteMod> listView = new JFXListView<>();
|
||||||
spinnerPane.setContent(listView);
|
spinnerPane.setContent(listView);
|
||||||
Bindings.bindContent(listView.getItems(), getSkinnable().items);
|
Bindings.bindContent(listView.getItems(), getSkinnable().items);
|
||||||
listView.setOnMouseClicked(e -> {
|
listView.setOnMouseClicked(e -> {
|
||||||
if (listView.getSelectionModel().getSelectedIndex() < 0)
|
if (listView.getSelectionModel().getSelectedIndex() < 0)
|
||||||
return;
|
return;
|
||||||
RemoteModRepository.Mod selectedItem = listView.getSelectionModel().getSelectedItem();
|
RemoteMod selectedItem = listView.getSelectionModel().getSelectedItem();
|
||||||
Controllers.navigate(new DownloadPage(getSkinnable(), selectedItem, getSkinnable().getProfileVersion(), getSkinnable().callback));
|
Controllers.navigate(new DownloadPage(getSkinnable(), selectedItem, getSkinnable().getProfileVersion(), getSkinnable().callback));
|
||||||
});
|
});
|
||||||
listView.setCellFactory(x -> new FloatListCell<RemoteModRepository.Mod>(listView) {
|
listView.setCellFactory(x -> new FloatListCell<RemoteMod>(listView) {
|
||||||
TwoLineListItem content = new TwoLineListItem();
|
TwoLineListItem content = new TwoLineListItem();
|
||||||
ImageView imageView = new ImageView();
|
ImageView imageView = new ImageView();
|
||||||
|
|
||||||
@@ -373,7 +374,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateControl(RemoteModRepository.Mod dataItem, boolean empty) {
|
protected void updateControl(RemoteMod dataItem, boolean empty) {
|
||||||
if (empty) return;
|
if (empty) return;
|
||||||
ModTranslations.Mod mod = ModTranslations.getModByCurseForgeId(dataItem.getSlug());
|
ModTranslations.Mod mod = ModTranslations.getModByCurseForgeId(dataItem.getSlug());
|
||||||
content.setTitle(mod != null ? mod.getDisplayName() : dataItem.getTitle());
|
content.setTitle(mod != null ? mod.getDisplayName() : dataItem.getTitle());
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.mod.ModManager;
|
import org.jackhuang.hmcl.mod.ModManager;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
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 loaded = new SimpleBooleanProperty(false);
|
||||||
private final BooleanProperty loading = new SimpleBooleanProperty(false);
|
private final BooleanProperty loading = new SimpleBooleanProperty(false);
|
||||||
private final BooleanProperty failed = new SimpleBooleanProperty(false);
|
private final BooleanProperty failed = new SimpleBooleanProperty(false);
|
||||||
private final RemoteModRepository.Mod addon;
|
private final RemoteMod addon;
|
||||||
private final ModTranslations.Mod mod;
|
private final ModTranslations.Mod mod;
|
||||||
private final Profile.ProfileVersion version;
|
private final Profile.ProfileVersion version;
|
||||||
private final DownloadCallback callback;
|
private final DownloadCallback callback;
|
||||||
private final DownloadListPage page;
|
private final DownloadListPage page;
|
||||||
|
|
||||||
private List<RemoteModRepository.Mod> dependencies;
|
private List<RemoteMod> dependencies;
|
||||||
private SimpleMultimap<String, RemoteModRepository.Version> versions;
|
private SimpleMultimap<String, RemoteMod.Version> versions;
|
||||||
|
|
||||||
public DownloadPage(DownloadListPage page, RemoteModRepository.Mod addon, Profile.ProfileVersion version, @Nullable DownloadCallback callback) {
|
public DownloadPage(DownloadListPage page, RemoteMod addon, Profile.ProfileVersion version, @Nullable DownloadCallback callback) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.addon = addon;
|
this.addon = addon;
|
||||||
this.mod = ModTranslations.getModByCurseForgeId(addon.getSlug());
|
this.mod = ModTranslations.getModByCurseForgeId(addon.getSlug());
|
||||||
@@ -95,7 +95,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
Task.allOf(
|
Task.allOf(
|
||||||
Task.supplyAsync(() -> addon.getData().loadDependencies()),
|
Task.supplyAsync(() -> addon.getData().loadDependencies()),
|
||||||
Task.supplyAsync(() -> {
|
Task.supplyAsync(() -> {
|
||||||
Stream<RemoteModRepository.Version> versions = addon.getData().loadVersions();
|
Stream<RemoteMod.Version> versions = addon.getData().loadVersions();
|
||||||
// if (StringUtils.isNotBlank(version.getVersion())) {
|
// if (StringUtils.isNotBlank(version.getVersion())) {
|
||||||
// Optional<String> gameVersion = GameVersion.minecraftVersion(versionJar);
|
// Optional<String> gameVersion = GameVersion.minecraftVersion(versionJar);
|
||||||
// if (gameVersion.isPresent()) {
|
// if (gameVersion.isPresent()) {
|
||||||
@@ -108,9 +108,9 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
.whenComplete(Schedulers.javafx(), (result, exception) -> {
|
.whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||||
if (exception == null) {
|
if (exception == null) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<RemoteModRepository.Mod> dependencies = (List<RemoteModRepository.Mod>) result.get(0);
|
List<RemoteMod> dependencies = (List<RemoteMod>) result.get(0);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
SimpleMultimap<String, RemoteModRepository.Version> versions = (SimpleMultimap<String, RemoteModRepository.Version>) result.get(1);
|
SimpleMultimap<String, RemoteMod.Version> versions = (SimpleMultimap<String, RemoteMod.Version>) result.get(1);
|
||||||
|
|
||||||
this.dependencies = dependencies;
|
this.dependencies = dependencies;
|
||||||
this.versions = versions;
|
this.versions = versions;
|
||||||
@@ -126,9 +126,9 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
this.state.set(State.fromTitle(addon.getTitle()));
|
this.state.set(State.fromTitle(addon.getTitle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SimpleMultimap<String, RemoteModRepository.Version> sortVersions(Stream<RemoteModRepository.Version> versions) {
|
private SimpleMultimap<String, RemoteMod.Version> sortVersions(Stream<RemoteMod.Version> versions) {
|
||||||
SimpleMultimap<String, RemoteModRepository.Version> classifiedVersions
|
SimpleMultimap<String, RemoteMod.Version> classifiedVersions
|
||||||
= new SimpleMultimap<String, RemoteModRepository.Version>(HashMap::new, ArrayList::new);
|
= new SimpleMultimap<String, RemoteMod.Version>(HashMap::new, ArrayList::new);
|
||||||
versions.forEach(version -> {
|
versions.forEach(version -> {
|
||||||
for (String gameVersion : version.getGameVersions()) {
|
for (String gameVersion : version.getGameVersions()) {
|
||||||
classifiedVersions.put(gameVersion, version);
|
classifiedVersions.put(gameVersion, version);
|
||||||
@@ -136,13 +136,13 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (String gameVersion : classifiedVersions.keys()) {
|
for (String gameVersion : classifiedVersions.keys()) {
|
||||||
List<RemoteModRepository.Version> versionList = (List<RemoteModRepository.Version>) classifiedVersions.get(gameVersion);
|
List<RemoteMod.Version> versionList = (List<RemoteMod.Version>) classifiedVersions.get(gameVersion);
|
||||||
versionList.sort(Comparator.comparing(RemoteModRepository.Version::getDatePublished).reversed());
|
versionList.sort(Comparator.comparing(RemoteMod.Version::getDatePublished).reversed());
|
||||||
}
|
}
|
||||||
return classifiedVersions;
|
return classifiedVersions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteModRepository.Mod getAddon() {
|
public RemoteMod getAddon() {
|
||||||
return addon;
|
return addon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
this.failed.set(failed);
|
this.failed.set(failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void download(RemoteModRepository.Version file) {
|
public void download(RemoteMod.Version file) {
|
||||||
if (this.callback == null) {
|
if (this.callback == null) {
|
||||||
saveAs(file);
|
saveAs(file);
|
||||||
} else {
|
} else {
|
||||||
@@ -182,7 +182,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveAs(RemoteModRepository.Version file) {
|
public void saveAs(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();
|
||||||
@@ -328,7 +328,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
|
|
||||||
private static final class DependencyModItem extends StackPane {
|
private static final class DependencyModItem extends StackPane {
|
||||||
|
|
||||||
DependencyModItem(DownloadListPage page, RemoteModRepository.Mod addon, Profile.ProfileVersion version, DownloadCallback callback) {
|
DependencyModItem(DownloadListPage page, RemoteMod addon, Profile.ProfileVersion version, DownloadCallback callback) {
|
||||||
HBox pane = new HBox(8);
|
HBox pane = new HBox(8);
|
||||||
pane.setPadding(new Insets(8));
|
pane.setPadding(new Insets(8));
|
||||||
pane.setAlignment(Pos.CENTER_LEFT);
|
pane.setAlignment(Pos.CENTER_LEFT);
|
||||||
@@ -355,7 +355,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class ModItem extends StackPane {
|
private static final class ModItem extends StackPane {
|
||||||
ModItem(RemoteModRepository.Version dataItem, DownloadPage selfPage) {
|
ModItem(RemoteMod.Version dataItem, DownloadPage selfPage) {
|
||||||
HBox pane = new HBox(8);
|
HBox pane = new HBox(8);
|
||||||
pane.setPadding(new Insets(8));
|
pane.setPadding(new Insets(8));
|
||||||
pane.setAlignment(Pos.CENTER_LEFT);
|
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());
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
public interface DownloadCallback {
|
public interface DownloadCallback {
|
||||||
void download(Profile profile, @Nullable String version, RemoteModRepository.Version file);
|
void download(Profile profile, @Nullable String version, RemoteMod.Version file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.versions;
|
package org.jackhuang.hmcl.ui.versions;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||||
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
|
||||||
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
|
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
|
||||||
@@ -46,7 +47,7 @@ public class ModDownloadListPage extends DownloadListPage {
|
|||||||
private class Repository implements RemoteModRepository {
|
private class Repository implements RemoteModRepository {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<Mod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
public Stream<RemoteMod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
||||||
String newSearchFilter;
|
String newSearchFilter;
|
||||||
if (StringUtils.CHINESE_PATTERN.matcher(searchFilter).find()) {
|
if (StringUtils.CHINESE_PATTERN.matcher(searchFilter).find()) {
|
||||||
List<ModTranslations.Mod> mods = ModTranslations.searchMod(searchFilter);
|
List<ModTranslations.Mod> mods = ModTranslations.searchMod(searchFilter);
|
||||||
@@ -76,7 +77,7 @@ public class ModDownloadListPage extends DownloadListPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Version> getRemoteVersionByLocalFile(Path file) {
|
public Optional<RemoteMod.Version> getRemoteVersionByLocalFile(Path file) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import javafx.collections.ObservableList;
|
|||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||||
import org.jackhuang.hmcl.mod.ModInfo;
|
import org.jackhuang.hmcl.mod.LocalMod;
|
||||||
import org.jackhuang.hmcl.mod.ModManager;
|
import org.jackhuang.hmcl.mod.ModManager;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
@@ -151,7 +151,7 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
|
|||||||
modManager.removeMods(selectedItems.stream()
|
modManager.removeMods(selectedItems.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(ModListPageSkin.ModInfoObject::getModInfo)
|
.map(ModListPageSkin.ModInfoObject::getModInfo)
|
||||||
.toArray(ModInfo[]::new));
|
.toArray(LocalMod[]::new));
|
||||||
loadMods(modManager);
|
loadMods(modManager);
|
||||||
} catch (IOException ignore) {
|
} catch (IOException ignore) {
|
||||||
// Fail to remove mods if the game is running or the mod is absent.
|
// Fail to remove mods if the game is running or the mod is absent.
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import org.jackhuang.hmcl.mod.ModInfo;
|
import org.jackhuang.hmcl.mod.LocalMod;
|
||||||
import org.jackhuang.hmcl.mod.ModManager;
|
import org.jackhuang.hmcl.mod.ModManager;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
@@ -124,34 +124,34 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
|||||||
|
|
||||||
static class ModInfoObject extends RecursiveTreeObject<ModInfoObject> implements Comparable<ModInfoObject> {
|
static class ModInfoObject extends RecursiveTreeObject<ModInfoObject> implements Comparable<ModInfoObject> {
|
||||||
private final BooleanProperty active;
|
private final BooleanProperty active;
|
||||||
private final ModInfo modInfo;
|
private final LocalMod localMod;
|
||||||
private final String message;
|
private final String message;
|
||||||
private final ModTranslations.Mod mod;
|
private final ModTranslations.Mod mod;
|
||||||
|
|
||||||
ModInfoObject(ModInfo modInfo) {
|
ModInfoObject(LocalMod localMod) {
|
||||||
this.modInfo = modInfo;
|
this.localMod = localMod;
|
||||||
this.active = modInfo.activeProperty();
|
this.active = localMod.activeProperty();
|
||||||
StringBuilder message = new StringBuilder(modInfo.getName());
|
StringBuilder message = new StringBuilder(localMod.getName());
|
||||||
if (isNotBlank(modInfo.getVersion()))
|
if (isNotBlank(localMod.getVersion()))
|
||||||
message.append(", ").append(i18n("archive.version")).append(": ").append(modInfo.getVersion());
|
message.append(", ").append(i18n("archive.version")).append(": ").append(localMod.getVersion());
|
||||||
if (isNotBlank(modInfo.getGameVersion()))
|
if (isNotBlank(localMod.getGameVersion()))
|
||||||
message.append(", ").append(i18n("archive.game_version")).append(": ").append(modInfo.getGameVersion());
|
message.append(", ").append(i18n("archive.game_version")).append(": ").append(localMod.getGameVersion());
|
||||||
if (isNotBlank(modInfo.getAuthors()))
|
if (isNotBlank(localMod.getAuthors()))
|
||||||
message.append(", ").append(i18n("archive.author")).append(": ").append(modInfo.getAuthors());
|
message.append(", ").append(i18n("archive.author")).append(": ").append(localMod.getAuthors());
|
||||||
this.message = message.toString();
|
this.message = message.toString();
|
||||||
this.mod = ModTranslations.getModById(modInfo.getId());
|
this.mod = ModTranslations.getModById(localMod.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTitle() {
|
String getTitle() {
|
||||||
return modInfo.getFileName();
|
return localMod.getFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSubtitle() {
|
String getSubtitle() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModInfo getModInfo() {
|
LocalMod getModInfo() {
|
||||||
return modInfo;
|
return localMod;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModTranslations.Mod getMod() {
|
public ModTranslations.Mod getMod() {
|
||||||
@@ -160,7 +160,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(@NotNull ModListPageSkin.ModInfoObject o) {
|
public int compareTo(@NotNull ModListPageSkin.ModInfoObject o) {
|
||||||
return modInfo.getFileName().toLowerCase().compareTo(o.modInfo.getFileName().toLowerCase());
|
return localMod.getFileName().toLowerCase().compareTo(o.localMod.getFileName().toLowerCase());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import org.jackhuang.hmcl.download.game.GameAssetDownloadTask;
|
|||||||
import org.jackhuang.hmcl.game.GameDirectoryType;
|
import org.jackhuang.hmcl.game.GameDirectoryType;
|
||||||
import org.jackhuang.hmcl.game.GameRepository;
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.game.LauncherHelper;
|
import org.jackhuang.hmcl.game.LauncherHelper;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.setting.Accounts;
|
import org.jackhuang.hmcl.setting.Accounts;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.Profiles;
|
import org.jackhuang.hmcl.setting.Profiles;
|
||||||
@@ -77,7 +77,7 @@ public final class Versions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void downloadModpackImpl(Profile profile, String version, RemoteModRepository.Version file) {
|
public static void downloadModpackImpl(Profile profile, String version, RemoteMod.Version file) {
|
||||||
Path modpack;
|
Path modpack;
|
||||||
URL downloadURL;
|
URL downloadURL;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -202,10 +202,10 @@ public class Datapack {
|
|||||||
private Path file;
|
private Path file;
|
||||||
private final BooleanProperty active;
|
private final BooleanProperty active;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final ModInfo.Description description;
|
private final LocalMod.Description description;
|
||||||
private final Datapack datapack;
|
private final Datapack datapack;
|
||||||
|
|
||||||
public Pack(Path file, String id, ModInfo.Description description, Datapack datapack) {
|
public Pack(Path file, String id, LocalMod.Description description, Datapack datapack) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
@@ -235,7 +235,7 @@ public class Datapack {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModInfo.Description getDescription() {
|
public LocalMod.Description getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,14 +64,14 @@ public final class FabricModMetadata {
|
|||||||
this.contact = contact;
|
this.contact = contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
public static LocalMod fromFile(File modFile) throws IOException, JsonParseException {
|
||||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||||
Path mcmod = fs.getPath("fabric.mod.json");
|
Path mcmod = fs.getPath("fabric.mod.json");
|
||||||
if (Files.notExists(mcmod))
|
if (Files.notExists(mcmod))
|
||||||
throw new IOException("File " + modFile + " is not a Fabric mod.");
|
throw new IOException("File " + modFile + " is not a Fabric mod.");
|
||||||
FabricModMetadata metadata = JsonUtils.fromNonNullJson(FileUtils.readText(mcmod), FabricModMetadata.class);
|
FabricModMetadata metadata = JsonUtils.fromNonNullJson(FileUtils.readText(mcmod), FabricModMetadata.class);
|
||||||
String authors = metadata.authors == null ? "" : metadata.authors.stream().map(author -> author.name).collect(Collectors.joining(", "));
|
String authors = metadata.authors == null ? "" : metadata.authors.stream().map(author -> author.name).collect(Collectors.joining(", "));
|
||||||
return new ModInfo(modFile, metadata.id, metadata.name, new ModInfo.Description(metadata.description),
|
return new LocalMod(modFile, ModLoaderType.FABRIC, metadata.id, metadata.name, new LocalMod.Description(metadata.description),
|
||||||
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "", metadata.icon);
|
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "", metadata.icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public final class ForgeNewModMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
public static LocalMod fromFile(File modFile) throws IOException, JsonParseException {
|
||||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||||
Path modstoml = fs.getPath("META-INF/mods.toml");
|
Path modstoml = fs.getPath("META-INF/mods.toml");
|
||||||
if (Files.notExists(modstoml))
|
if (Files.notExists(modstoml))
|
||||||
@@ -135,7 +135,7 @@ public final class ForgeNewModMetadata {
|
|||||||
LOG.log(Level.WARNING, "Failed to parse MANIFEST.MF in file " + modFile.getPath());
|
LOG.log(Level.WARNING, "Failed to parse MANIFEST.MF in file " + modFile.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ModInfo(modFile, mod.getModId(), mod.getDisplayName(), new ModInfo.Description(mod.getDescription()),
|
return new LocalMod(modFile, ModLoaderType.FORGE, mod.getModId(), mod.getDisplayName(), new LocalMod.Description(mod.getDescription()),
|
||||||
mod.getAuthors(), mod.getVersion().replace("${file.jarVersion}", jarVersion), "",
|
mod.getAuthors(), mod.getVersion().replace("${file.jarVersion}", jarVersion), "",
|
||||||
mod.getDisplayURL(),
|
mod.getDisplayURL(),
|
||||||
metadata.getLogoFile());
|
metadata.getLogoFile());
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public final class ForgeOldModMetadata {
|
|||||||
return authors;
|
return authors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
public static LocalMod fromFile(File modFile) throws IOException, JsonParseException {
|
||||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||||
Path mcmod = fs.getPath("mcmod.info");
|
Path mcmod = fs.getPath("mcmod.info");
|
||||||
if (Files.notExists(mcmod))
|
if (Files.notExists(mcmod))
|
||||||
@@ -138,7 +138,7 @@ public final class ForgeOldModMetadata {
|
|||||||
authors = String.join(", ", metadata.getAuthorList());
|
authors = String.join(", ", metadata.getAuthorList());
|
||||||
if (StringUtils.isBlank(authors))
|
if (StringUtils.isBlank(authors))
|
||||||
authors = metadata.getCredits();
|
authors = metadata.getCredits();
|
||||||
return new ModInfo(modFile, metadata.getModId(), metadata.getName(), new ModInfo.Description(metadata.getDescription()),
|
return new LocalMod(modFile, ModLoaderType.FORGE, metadata.getModId(), metadata.getName(), new LocalMod.Description(metadata.getDescription()),
|
||||||
authors, metadata.getVersion(), metadata.getGameVersion(),
|
authors, metadata.getVersion(), metadata.getGameVersion(),
|
||||||
StringUtils.isBlank(metadata.getUrl()) ? metadata.getUpdateUrl() : metadata.url,
|
StringUtils.isBlank(metadata.getUrl()) ? metadata.getUpdateUrl() : metadata.url,
|
||||||
metadata.getLogoFile());
|
metadata.getLogoFile());
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public final class LiteModMetadata {
|
|||||||
return updateURI;
|
return updateURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
public static LocalMod fromFile(File modFile) throws IOException, JsonParseException {
|
||||||
try (ZipFile zipFile = new ZipFile(modFile)) {
|
try (ZipFile zipFile = new ZipFile(modFile)) {
|
||||||
ZipEntry entry = zipFile.getEntry("litemod.json");
|
ZipEntry entry = zipFile.getEntry("litemod.json");
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
@@ -116,7 +116,7 @@ public final class LiteModMetadata {
|
|||||||
LiteModMetadata metadata = JsonUtils.GSON.fromJson(IOUtils.readFullyAsString(zipFile.getInputStream(entry)), LiteModMetadata.class);
|
LiteModMetadata metadata = JsonUtils.GSON.fromJson(IOUtils.readFullyAsString(zipFile.getInputStream(entry)), LiteModMetadata.class);
|
||||||
if (metadata == null)
|
if (metadata == null)
|
||||||
throw new IOException("Mod " + modFile + " `litemod.json` is malformed.");
|
throw new IOException("Mod " + modFile + " `litemod.json` is malformed.");
|
||||||
return new ModInfo(modFile, null, metadata.getName(), new ModInfo.Description(metadata.getDescription()), metadata.getAuthor(),
|
return new LocalMod(modFile, ModLoaderType.FORGE, null, metadata.getName(), new LocalMod.Description(metadata.getDescription()), metadata.getAuthor(),
|
||||||
metadata.getVersion(), metadata.getGameVersion(), metadata.getUpdateURI(), "");
|
metadata.getVersion(), metadata.getGameVersion(), metadata.getUpdateURI(), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ import java.util.logging.Level;
|
|||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public final class ModInfo implements Comparable<ModInfo> {
|
public final class LocalMod implements Comparable<LocalMod> {
|
||||||
|
|
||||||
private Path file;
|
private Path file;
|
||||||
|
private final ModLoaderType modLoaderType;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Description description;
|
private final Description description;
|
||||||
@@ -49,12 +50,13 @@ public final class ModInfo implements Comparable<ModInfo> {
|
|||||||
private final String logoPath;
|
private final String logoPath;
|
||||||
private final BooleanProperty activeProperty;
|
private final BooleanProperty activeProperty;
|
||||||
|
|
||||||
public ModInfo(File file, String id, String name, Description description) {
|
public LocalMod(File file, ModLoaderType modLoaderType, String id, String name, Description description) {
|
||||||
this(file, id, name, description, "", "", "", "", "");
|
this(file, modLoaderType, id, name, description, "", "", "", "", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModInfo(File file, String id, String name, Description description, String authors, String version, String gameVersion, String url, String logoPath) {
|
public LocalMod(File file, ModLoaderType modLoaderType, String id, String name, Description description, String authors, String version, String gameVersion, String url, String logoPath) {
|
||||||
this.file = file.toPath();
|
this.file = file.toPath();
|
||||||
|
this.modLoaderType = modLoaderType;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
@@ -67,13 +69,13 @@ public final class ModInfo implements Comparable<ModInfo> {
|
|||||||
activeProperty = new SimpleBooleanProperty(this, "active", !ModManager.isDisabled(file)) {
|
activeProperty = new SimpleBooleanProperty(this, "active", !ModManager.isDisabled(file)) {
|
||||||
@Override
|
@Override
|
||||||
protected void invalidated() {
|
protected void invalidated() {
|
||||||
Path path = ModInfo.this.file.toAbsolutePath();
|
Path path = LocalMod.this.file.toAbsolutePath();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (get())
|
if (get())
|
||||||
ModInfo.this.file = ModManager.enableMod(path);
|
LocalMod.this.file = ModManager.enableMod(path);
|
||||||
else
|
else
|
||||||
ModInfo.this.file = ModManager.disableMod(path);
|
LocalMod.this.file = ModManager.disableMod(path);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Logging.LOG.log(Level.SEVERE, "Unable to invert state of mod file " + path, e);
|
Logging.LOG.log(Level.SEVERE, "Unable to invert state of mod file " + path, e);
|
||||||
}
|
}
|
||||||
@@ -87,6 +89,10 @@ public final class ModInfo implements Comparable<ModInfo> {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModLoaderType getModLoaderType() {
|
||||||
|
return modLoaderType;
|
||||||
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -136,13 +142,13 @@ public final class ModInfo implements Comparable<ModInfo> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(ModInfo o) {
|
public int compareTo(LocalMod o) {
|
||||||
return getFileName().compareTo(o.getFileName());
|
return getFileName().compareTo(o.getFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return obj instanceof ModInfo && Objects.equals(getFileName(), ((ModInfo) obj).getFileName());
|
return obj instanceof LocalMod && Objects.equals(getFileName(), ((LocalMod) obj).getFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.mod;
|
||||||
|
|
||||||
|
public enum ModLoaderType {
|
||||||
|
UNKNOWN,
|
||||||
|
FORGE,
|
||||||
|
FABRIC,
|
||||||
|
LITE_LOADER,
|
||||||
|
PACK
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ import java.util.TreeSet;
|
|||||||
public final class ModManager {
|
public final class ModManager {
|
||||||
private final GameRepository repository;
|
private final GameRepository repository;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final TreeSet<ModInfo> modInfos = new TreeSet<>();
|
private final TreeSet<LocalMod> localMods = new TreeSet<>();
|
||||||
|
|
||||||
private boolean loaded = false;
|
private boolean loaded = false;
|
||||||
|
|
||||||
@@ -55,12 +55,12 @@ public final class ModManager {
|
|||||||
|
|
||||||
private void addModInfo(File file) {
|
private void addModInfo(File file) {
|
||||||
try {
|
try {
|
||||||
modInfos.add(getModInfo(file));
|
localMods.add(getModInfo(file));
|
||||||
} catch (IllegalArgumentException ignore) {
|
} catch (IllegalArgumentException ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModInfo getModInfo(File modFile) {
|
public static LocalMod getModInfo(File modFile) {
|
||||||
File file = isDisabled(modFile) ? new File(modFile.getAbsoluteFile().getParentFile(), FileUtils.getNameWithoutExtension(modFile)) : modFile;
|
File file = isDisabled(modFile) ? new File(modFile.getAbsoluteFile().getParentFile(), FileUtils.getNameWithoutExtension(modFile)) : modFile;
|
||||||
String description, extension = FileUtils.getExtension(file);
|
String description, extension = FileUtils.getExtension(file);
|
||||||
switch (extension) {
|
switch (extension) {
|
||||||
@@ -98,11 +98,11 @@ public final class ModManager {
|
|||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("File " + modFile + " is not a mod file.");
|
throw new IllegalArgumentException("File " + modFile + " is not a mod file.");
|
||||||
}
|
}
|
||||||
return new ModInfo(modFile, null, FileUtils.getNameWithoutExtension(modFile), new ModInfo.Description(description));
|
return new LocalMod(modFile, ModLoaderType.UNKNOWN, null, FileUtils.getNameWithoutExtension(modFile), new LocalMod.Description(description));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshMods() throws IOException {
|
public void refreshMods() throws IOException {
|
||||||
modInfos.clear();
|
localMods.clear();
|
||||||
if (Files.isDirectory(getModsDirectory())) {
|
if (Files.isDirectory(getModsDirectory())) {
|
||||||
try (DirectoryStream<Path> modsDirectoryStream = Files.newDirectoryStream(getModsDirectory())) {
|
try (DirectoryStream<Path> modsDirectoryStream = Files.newDirectoryStream(getModsDirectory())) {
|
||||||
for (Path subitem : modsDirectoryStream) {
|
for (Path subitem : modsDirectoryStream) {
|
||||||
@@ -122,10 +122,10 @@ public final class ModManager {
|
|||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ModInfo> getMods() throws IOException {
|
public Collection<LocalMod> getMods() throws IOException {
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
refreshMods();
|
refreshMods();
|
||||||
return modInfos;
|
return localMods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMod(File file) throws IOException {
|
public void addMod(File file) throws IOException {
|
||||||
@@ -145,9 +145,9 @@ public final class ModManager {
|
|||||||
addModInfo(newFile);
|
addModInfo(newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeMods(ModInfo... modInfos) throws IOException {
|
public void removeMods(LocalMod... localMods) throws IOException {
|
||||||
for (ModInfo modInfo : modInfos) {
|
for (LocalMod localMod : localMods) {
|
||||||
Files.deleteIfExists(modInfo.getFile());
|
Files.deleteIfExists(localMod.getFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ public class PackMcMeta implements Validation {
|
|||||||
private final int packFormat;
|
private final int packFormat;
|
||||||
|
|
||||||
@SerializedName("description")
|
@SerializedName("description")
|
||||||
private final ModInfo.Description description;
|
private final LocalMod.Description description;
|
||||||
|
|
||||||
public PackInfo() {
|
public PackInfo() {
|
||||||
this(0, new ModInfo.Description(Collections.emptyList()));
|
this(0, new LocalMod.Description(Collections.emptyList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PackInfo(int packFormat, ModInfo.Description description) {
|
public PackInfo(int packFormat, LocalMod.Description description) {
|
||||||
this.packFormat = packFormat;
|
this.packFormat = packFormat;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ public class PackMcMeta implements Validation {
|
|||||||
return packFormat;
|
return packFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModInfo.Description getDescription() {
|
public LocalMod.Description getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,13 +112,13 @@ public class PackMcMeta implements Validation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModInfo.Description.Part deserialize(JsonElement json, JsonDeserializationContext context) throws JsonParseException {
|
public LocalMod.Description.Part deserialize(JsonElement json, JsonDeserializationContext context) throws JsonParseException {
|
||||||
if (json.isJsonPrimitive()) {
|
if (json.isJsonPrimitive()) {
|
||||||
return new ModInfo.Description.Part(parseText(json));
|
return new LocalMod.Description.Part(parseText(json));
|
||||||
} else if (json.isJsonObject()) {
|
} else if (json.isJsonObject()) {
|
||||||
JsonObject obj = json.getAsJsonObject();
|
JsonObject obj = json.getAsJsonObject();
|
||||||
String text = parseText(obj.get("text"));
|
String text = parseText(obj.get("text"));
|
||||||
return new ModInfo.Description.Part(text);
|
return new LocalMod.Description.Part(text);
|
||||||
} else {
|
} else {
|
||||||
throw new JsonParseException("pack.mcmeta Raw JSON text should be string or an object");
|
throw new JsonParseException("pack.mcmeta Raw JSON text should be string or an object");
|
||||||
}
|
}
|
||||||
@@ -126,31 +126,31 @@ public class PackMcMeta implements Validation {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PackInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
public PackInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
List<ModInfo.Description.Part> parts = new ArrayList<>();
|
List<LocalMod.Description.Part> parts = new ArrayList<>();
|
||||||
JsonObject packInfo = json.getAsJsonObject();
|
JsonObject packInfo = json.getAsJsonObject();
|
||||||
int packFormat = packInfo.get("pack_format").getAsInt();
|
int packFormat = packInfo.get("pack_format").getAsInt();
|
||||||
JsonElement description = packInfo.get("description");
|
JsonElement description = packInfo.get("description");
|
||||||
if (description.isJsonPrimitive()) {
|
if (description.isJsonPrimitive()) {
|
||||||
parts.add(new ModInfo.Description.Part(parseText(description)));
|
parts.add(new LocalMod.Description.Part(parseText(description)));
|
||||||
} else if (description.isJsonArray()) {
|
} else if (description.isJsonArray()) {
|
||||||
for (JsonElement element : description.getAsJsonArray()) {
|
for (JsonElement element : description.getAsJsonArray()) {
|
||||||
JsonObject descriptionPart = element.getAsJsonObject();
|
JsonObject descriptionPart = element.getAsJsonObject();
|
||||||
parts.add(new ModInfo.Description.Part(descriptionPart.get("text").getAsString(), descriptionPart.get("color").getAsString()));
|
parts.add(new LocalMod.Description.Part(descriptionPart.get("text").getAsString(), descriptionPart.get("color").getAsString()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new JsonParseException("pack.mcmeta::pack::description should be String or array of text objects with text and color fields");
|
throw new JsonParseException("pack.mcmeta::pack::description should be String or array of text objects with text and color fields");
|
||||||
}
|
}
|
||||||
return new PackInfo(packFormat, new ModInfo.Description(parts));
|
return new PackInfo(packFormat, new LocalMod.Description(parts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModInfo fromFile(File modFile) throws IOException, JsonParseException {
|
public static LocalMod fromFile(File modFile) throws IOException, JsonParseException {
|
||||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(modFile.toPath())) {
|
||||||
Path mcmod = fs.getPath("pack.mcmeta");
|
Path mcmod = fs.getPath("pack.mcmeta");
|
||||||
if (Files.notExists(mcmod))
|
if (Files.notExists(mcmod))
|
||||||
throw new IOException("File " + modFile + " is not a resource pack.");
|
throw new IOException("File " + modFile + " is not a resource pack.");
|
||||||
PackMcMeta metadata = JsonUtils.fromNonNullJson(FileUtils.readText(mcmod), PackMcMeta.class);
|
PackMcMeta metadata = JsonUtils.fromNonNullJson(FileUtils.readText(mcmod), PackMcMeta.class);
|
||||||
return new ModInfo(modFile, null, FileUtils.getNameWithoutExtension(modFile), metadata.pack.description, "", "", "", "", "");
|
return new LocalMod(modFile, ModLoaderType.PACK, null, FileUtils.getNameWithoutExtension(modFile), metadata.pack.description, "", "", "", "", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
180
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RemoteMod.java
Normal file
180
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RemoteMod.java
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.mod;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class RemoteMod {
|
||||||
|
private final String slug;
|
||||||
|
private final String author;
|
||||||
|
private final String title;
|
||||||
|
private final String description;
|
||||||
|
private final List<String> categories;
|
||||||
|
private final String pageUrl;
|
||||||
|
private final String iconUrl;
|
||||||
|
private final IMod data;
|
||||||
|
|
||||||
|
public RemoteMod(String slug, String author, String title, String description, List<String> categories, String pageUrl, String iconUrl, IMod data) {
|
||||||
|
this.slug = slug;
|
||||||
|
this.author = author;
|
||||||
|
this.title = title;
|
||||||
|
this.description = description;
|
||||||
|
this.categories = categories;
|
||||||
|
this.pageUrl = pageUrl;
|
||||||
|
this.iconUrl = iconUrl;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSlug() {
|
||||||
|
return slug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCategories() {
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPageUrl() {
|
||||||
|
return pageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIconUrl() {
|
||||||
|
return iconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMod getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum VersionType {
|
||||||
|
Release,
|
||||||
|
Beta,
|
||||||
|
Alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IMod {
|
||||||
|
List<RemoteMod> loadDependencies() throws IOException;
|
||||||
|
|
||||||
|
Stream<Version> loadVersions() throws IOException;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Version {
|
||||||
|
private final Object self;
|
||||||
|
private final String name;
|
||||||
|
private final String version;
|
||||||
|
private final String changelog;
|
||||||
|
private final Instant datePublished;
|
||||||
|
private final VersionType versionType;
|
||||||
|
private final File file;
|
||||||
|
private final List<String> dependencies;
|
||||||
|
private final List<String> gameVersions;
|
||||||
|
private final List<String> loaders;
|
||||||
|
|
||||||
|
public Version(Object self, String name, String version, String changelog, Instant datePublished, VersionType versionType, File file, List<String> dependencies, List<String> gameVersions, List<String> loaders) {
|
||||||
|
this.self = self;
|
||||||
|
this.name = name;
|
||||||
|
this.version = version;
|
||||||
|
this.changelog = changelog;
|
||||||
|
this.datePublished = datePublished;
|
||||||
|
this.versionType = versionType;
|
||||||
|
this.file = file;
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
this.gameVersions = gameVersions;
|
||||||
|
this.loaders = loaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getSelf() {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChangelog() {
|
||||||
|
return changelog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getDatePublished() {
|
||||||
|
return datePublished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionType getVersionType() {
|
||||||
|
return versionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDependencies() {
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getGameVersions() {
|
||||||
|
return gameVersions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getLoaders() {
|
||||||
|
return loaders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class File {
|
||||||
|
private final Map<String, String> hashes;
|
||||||
|
private final String url;
|
||||||
|
private final String filename;
|
||||||
|
|
||||||
|
public File(Map<String, String> hashes, String url, String filename) {
|
||||||
|
this.hashes = hashes;
|
||||||
|
this.url = url;
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getHashes() {
|
||||||
|
return hashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,27 +19,19 @@ package org.jackhuang.hmcl.mod;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public interface RemoteModRepository {
|
public interface RemoteModRepository {
|
||||||
|
|
||||||
Stream<Mod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort)
|
Stream<RemoteMod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
Optional<Version> getRemoteVersionByLocalFile(Path file) throws IOException;
|
Optional<RemoteMod.Version> getRemoteVersionByLocalFile(Path file) throws IOException;
|
||||||
|
|
||||||
Stream<Category> getCategories() throws IOException;
|
Stream<Category> getCategories() throws IOException;
|
||||||
|
|
||||||
interface IMod {
|
|
||||||
List<Mod> loadDependencies() throws IOException;
|
|
||||||
|
|
||||||
Stream<Version> loadVersions() throws IOException;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Category {
|
class Category {
|
||||||
private final Object self;
|
private final Object self;
|
||||||
private final String id;
|
private final String id;
|
||||||
@@ -64,156 +56,6 @@ public interface RemoteModRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Mod {
|
|
||||||
private final String slug;
|
|
||||||
private final String author;
|
|
||||||
private final String title;
|
|
||||||
private final String description;
|
|
||||||
private final List<String> categories;
|
|
||||||
private final String pageUrl;
|
|
||||||
private final String iconUrl;
|
|
||||||
private final IMod data;
|
|
||||||
|
|
||||||
public Mod(String slug, String author, String title, String description, List<String> categories, String pageUrl, String iconUrl, IMod data) {
|
|
||||||
this.slug = slug;
|
|
||||||
this.author = author;
|
|
||||||
this.title = title;
|
|
||||||
this.description = description;
|
|
||||||
this.categories = categories;
|
|
||||||
this.pageUrl = pageUrl;
|
|
||||||
this.iconUrl = iconUrl;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSlug() {
|
|
||||||
return slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getCategories() {
|
|
||||||
return categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageUrl() {
|
|
||||||
return pageUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIconUrl() {
|
|
||||||
return iconUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMod getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum VersionType {
|
|
||||||
Release,
|
|
||||||
Beta,
|
|
||||||
Alpha
|
|
||||||
}
|
|
||||||
|
|
||||||
class Version {
|
|
||||||
private final Object self;
|
|
||||||
private final String name;
|
|
||||||
private final String version;
|
|
||||||
private final String changelog;
|
|
||||||
private final Instant datePublished;
|
|
||||||
private final VersionType versionType;
|
|
||||||
private final File file;
|
|
||||||
private final List<String> dependencies;
|
|
||||||
private final List<String> gameVersions;
|
|
||||||
private final List<String> loaders;
|
|
||||||
|
|
||||||
public Version(Object self, String name, String version, String changelog, Instant datePublished, VersionType versionType, File file, List<String> dependencies, List<String> gameVersions, List<String> loaders) {
|
|
||||||
this.self = self;
|
|
||||||
this.name = name;
|
|
||||||
this.version = version;
|
|
||||||
this.changelog = changelog;
|
|
||||||
this.datePublished = datePublished;
|
|
||||||
this.versionType = versionType;
|
|
||||||
this.file = file;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.gameVersions = gameVersions;
|
|
||||||
this.loaders = loaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getSelf() {
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getChangelog() {
|
|
||||||
return changelog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instant getDatePublished() {
|
|
||||||
return datePublished;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VersionType getVersionType() {
|
|
||||||
return versionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getDependencies() {
|
|
||||||
return dependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getGameVersions() {
|
|
||||||
return gameVersions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getLoaders() {
|
|
||||||
return loaders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class File {
|
|
||||||
private final Map<String, String> hashes;
|
|
||||||
private final String url;
|
|
||||||
private final String filename;
|
|
||||||
|
|
||||||
public File(Map<String, String> hashes, String url, String filename) {
|
|
||||||
this.hashes = hashes;
|
|
||||||
this.url = url;
|
|
||||||
this.filename = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getHashes() {
|
|
||||||
return hashes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilename() {
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] DEFAULT_GAME_VERSIONS = new String[]{
|
String[] DEFAULT_GAME_VERSIONS = new String[]{
|
||||||
"1.17.1", "1.17",
|
"1.17.1", "1.17",
|
||||||
"1.16.5", "1.16.4", "1.16.3", "1.16.2", "1.16.1", "1.16",
|
"1.16.5", "1.16.4", "1.16.3", "1.16.2", "1.16.1", "1.16",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.mod.curse;
|
package org.jackhuang.hmcl.mod.curse;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.util.Immutable;
|
import org.jackhuang.hmcl.util.Immutable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
public class CurseAddon implements RemoteModRepository.IMod {
|
public class CurseAddon implements RemoteMod.IMod {
|
||||||
private final int id;
|
private final int id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final List<Author> authors;
|
private final List<Author> authors;
|
||||||
@@ -168,13 +168,13 @@ public class CurseAddon implements RemoteModRepository.IMod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RemoteModRepository.Mod> loadDependencies() throws IOException {
|
public List<RemoteMod> loadDependencies() throws IOException {
|
||||||
Set<Integer> dependencies = latestFiles.stream()
|
Set<Integer> dependencies = latestFiles.stream()
|
||||||
.flatMap(latestFile -> latestFile.getDependencies().stream())
|
.flatMap(latestFile -> latestFile.getDependencies().stream())
|
||||||
.filter(dep -> dep.getType() == 3)
|
.filter(dep -> dep.getType() == 3)
|
||||||
.map(Dependency::getAddonId)
|
.map(Dependency::getAddonId)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
List<RemoteModRepository.Mod> mods = new ArrayList<>();
|
List<RemoteMod> mods = new ArrayList<>();
|
||||||
for (int dependencyId : dependencies) {
|
for (int dependencyId : dependencies) {
|
||||||
mods.add(CurseForgeRemoteModRepository.MODS.getAddon(dependencyId).toMod());
|
mods.add(CurseForgeRemoteModRepository.MODS.getAddon(dependencyId).toMod());
|
||||||
}
|
}
|
||||||
@@ -182,12 +182,12 @@ public class CurseAddon implements RemoteModRepository.IMod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<RemoteModRepository.Version> loadVersions() throws IOException {
|
public Stream<RemoteMod.Version> loadVersions() throws IOException {
|
||||||
return CurseForgeRemoteModRepository.MODS.getFiles(this).stream()
|
return CurseForgeRemoteModRepository.MODS.getFiles(this).stream()
|
||||||
.map(CurseAddon.LatestFile::toVersion);
|
.map(CurseAddon.LatestFile::toVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteModRepository.Mod toMod() {
|
public RemoteMod toMod() {
|
||||||
String iconUrl = null;
|
String iconUrl = null;
|
||||||
for (CurseAddon.Attachment attachment : attachments) {
|
for (CurseAddon.Attachment attachment : attachments) {
|
||||||
if (attachment.isDefault()) {
|
if (attachment.isDefault()) {
|
||||||
@@ -195,7 +195,7 @@ public class CurseAddon implements RemoteModRepository.IMod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RemoteModRepository.Mod(
|
return new RemoteMod(
|
||||||
slug,
|
slug,
|
||||||
"",
|
"",
|
||||||
name,
|
name,
|
||||||
@@ -481,31 +481,31 @@ public class CurseAddon implements RemoteModRepository.IMod {
|
|||||||
return fileDataInstant;
|
return fileDataInstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteModRepository.Version toVersion() {
|
public RemoteMod.Version toVersion() {
|
||||||
RemoteModRepository.VersionType versionType;
|
RemoteMod.VersionType versionType;
|
||||||
switch (getReleaseType()) {
|
switch (getReleaseType()) {
|
||||||
case 1:
|
case 1:
|
||||||
versionType = RemoteModRepository.VersionType.Release;
|
versionType = RemoteMod.VersionType.Release;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
versionType = RemoteModRepository.VersionType.Beta;
|
versionType = RemoteMod.VersionType.Beta;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
versionType = RemoteModRepository.VersionType.Alpha;
|
versionType = RemoteMod.VersionType.Alpha;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
versionType = RemoteModRepository.VersionType.Release;
|
versionType = RemoteMod.VersionType.Release;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RemoteModRepository.Version(
|
return new RemoteMod.Version(
|
||||||
this,
|
this,
|
||||||
getDisplayName(),
|
getDisplayName(),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
getParsedFileDate(),
|
getParsedFileDate(),
|
||||||
versionType,
|
versionType,
|
||||||
new RemoteModRepository.File(Collections.emptyMap(), getDownloadUrl(), getFileName()),
|
new RemoteMod.File(Collections.emptyMap(), getDownloadUrl(), getFileName()),
|
||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
gameVersion.stream().filter(ver -> ver.startsWith("1.") || ver.contains("w")).collect(Collectors.toList()),
|
gameVersion.stream().filter(ver -> ver.startsWith("1.") || ver.contains("w")).collect(Collectors.toList()),
|
||||||
Collections.emptyList()
|
Collections.emptyList()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hmcl.mod.curse;
|
package org.jackhuang.hmcl.mod.curse;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||||
import org.jackhuang.hmcl.util.MurmurHash;
|
import org.jackhuang.hmcl.util.MurmurHash;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
@@ -64,7 +65,7 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<RemoteModRepository.Mod> search(String gameVersion, RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
public Stream<RemoteMod> search(String gameVersion, RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
||||||
int categoryId = 0;
|
int categoryId = 0;
|
||||||
if (category != null) categoryId = ((Category) category.getSelf()).getId();
|
if (category != null) categoryId = ((Category) category.getSelf()).getId();
|
||||||
return searchPaginated(gameVersion, categoryId, pageOffset, pageSize, searchFilter, sort).stream()
|
return searchPaginated(gameVersion, categoryId, pageOffset, pageSize, searchFilter, sort).stream()
|
||||||
@@ -72,7 +73,7 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<RemoteModRepository.Version> getRemoteVersionByLocalFile(Path file) throws IOException {
|
public Optional<RemoteMod.Version> getRemoteVersionByLocalFile(Path file) throws IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(file)))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(file)))) {
|
||||||
int b;
|
int b;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.mod.modrinth;
|
|||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
import org.jackhuang.hmcl.util.DigestUtils;
|
||||||
import org.jackhuang.hmcl.util.Hex;
|
import org.jackhuang.hmcl.util.Hex;
|
||||||
@@ -64,13 +65,13 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<RemoteModRepository.Mod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
public Stream<RemoteMod> search(String gameVersion, Category category, int pageOffset, int pageSize, String searchFilter, int sort) throws IOException {
|
||||||
return searchPaginated(gameVersion, pageOffset, pageSize, searchFilter).stream()
|
return searchPaginated(gameVersion, pageOffset, pageSize, searchFilter).stream()
|
||||||
.map(ModResult::toMod);
|
.map(ModResult::toMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<RemoteModRepository.Version> getRemoteVersionByLocalFile(Path file) throws IOException {
|
public Optional<RemoteMod.Version> getRemoteVersionByLocalFile(Path file) throws IOException {
|
||||||
String sha1 = Hex.encodeHex(DigestUtils.digest("SHA-1", file));
|
String sha1 = Hex.encodeHex(DigestUtils.digest("SHA-1", file));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -288,23 +289,23 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
|
|||||||
return loaders;
|
return loaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<RemoteModRepository.Version> toVersion() {
|
public Optional<RemoteMod.Version> toVersion() {
|
||||||
RemoteModRepository.VersionType type;
|
RemoteMod.VersionType type;
|
||||||
if ("release".equals(versionType)) {
|
if ("release".equals(versionType)) {
|
||||||
type = RemoteModRepository.VersionType.Release;
|
type = RemoteMod.VersionType.Release;
|
||||||
} else if ("beta".equals(versionType)) {
|
} else if ("beta".equals(versionType)) {
|
||||||
type = RemoteModRepository.VersionType.Beta;
|
type = RemoteMod.VersionType.Beta;
|
||||||
} else if ("alpha".equals(versionType)) {
|
} else if ("alpha".equals(versionType)) {
|
||||||
type = RemoteModRepository.VersionType.Alpha;
|
type = RemoteMod.VersionType.Alpha;
|
||||||
} else {
|
} else {
|
||||||
type = RemoteModRepository.VersionType.Release;
|
type = RemoteMod.VersionType.Release;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (files.size() == 0) {
|
if (files.size() == 0) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.of(new RemoteModRepository.Version(
|
return Optional.of(new RemoteMod.Version(
|
||||||
this,
|
this,
|
||||||
name,
|
name,
|
||||||
versionNumber,
|
versionNumber,
|
||||||
@@ -342,12 +343,12 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteModRepository.File toFile() {
|
public RemoteMod.File toFile() {
|
||||||
return new RemoteModRepository.File(hashes, url, filename);
|
return new RemoteMod.File(hashes, url, filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ModResult implements RemoteModRepository.IMod {
|
public static class ModResult implements RemoteMod.IMod {
|
||||||
@SerializedName("mod_id")
|
@SerializedName("mod_id")
|
||||||
private final String modId;
|
private final String modId;
|
||||||
|
|
||||||
@@ -457,19 +458,19 @@ public final class ModrinthRemoteModRepository implements RemoteModRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RemoteModRepository.Mod> loadDependencies() throws IOException {
|
public List<RemoteMod> loadDependencies() throws IOException {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<RemoteModRepository.Version> loadVersions() throws IOException {
|
public Stream<RemoteMod.Version> loadVersions() throws IOException {
|
||||||
return ModrinthRemoteModRepository.INSTANCE.getFiles(this).stream()
|
return ModrinthRemoteModRepository.INSTANCE.getFiles(this).stream()
|
||||||
.map(ModVersion::toVersion)
|
.map(ModVersion::toVersion)
|
||||||
.flatMap(Lang::toStream);
|
.flatMap(Lang::toStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteModRepository.Mod toMod() {
|
public RemoteMod toMod() {
|
||||||
return new RemoteModRepository.Mod(
|
return new RemoteMod(
|
||||||
slug,
|
slug,
|
||||||
author,
|
author,
|
||||||
title,
|
title,
|
||||||
|
|||||||
Reference in New Issue
Block a user