diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index b250406fa2d..c28968e5c8e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -755,7 +755,7 @@ public LaunchOptions.Builder getLaunchOptions(String version, JavaRuntime javaVe try { String jsonText = Files.readString(json); ModpackConfiguration modpackConfiguration = JsonUtils.GSON.fromJson(jsonText, ModpackConfiguration.class); - ModpackProvider provider = ModpackHelper.getProviderByType(modpackConfiguration.getType()); + ModpackProvider provider = ModpackHelper.getProviderByType(modpackConfiguration.type()); if (provider != null) provider.injectLaunchOptions(jsonText, builder); } catch (IOException | JsonParseException e) { LOG.warning("Failed to parse modpack configuration file " + json, e); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLModpackInstallTask.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLModpackInstallTask.java index e7de3f914c0..92f10760f2f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLModpackInstallTask.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLModpackInstallTask.java @@ -67,7 +67,7 @@ public HMCLModpackInstallTask(HMCLGameRepository repository, Path zipFile, Modpa if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(Modpack.class)); - if (!HMCLModpackProvider.INSTANCE.getName().equals(config.getType())) + if (!HMCLModpackProvider.INSTANCE.getName().equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a HMCL modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 3e7ef722194..b12fbb4a187 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -168,7 +168,7 @@ private void launch0() { Task.composeAsync(() -> { try { ModpackConfiguration configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion)); - ModpackProvider provider = ModpackHelper.getProviderByType(configuration.getType()); + ModpackProvider provider = ModpackHelper.getProviderByType(configuration.type()); if (provider == null) return null; else return provider.createCompletionTask(dependencyManager, selectedVersion); } catch (IOException e) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java index e84044e1b88..b8c01f7d54a 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java @@ -236,7 +236,7 @@ else if (modpack.getManifest() instanceof McbbsModpackManifest) } public static Task getUpdateTask(HMCLGameRepository repository, ServerModpackManifest manifest, Charset charset, String name, ModpackConfiguration configuration) throws UnsupportedModpackException { - switch (configuration.getType()) { + switch (configuration.type()) { case ServerModpackRemoteInstallTask.MODPACK_TYPE: return new ModpackUpdateTask(repository, name, new ServerModpackRemoteInstallTask(repository.getDependency(), manifest, name)) .thenComposeAsync(repository.refreshVersionsAsync()) @@ -248,7 +248,7 @@ public static Task getUpdateTask(HMCLGameRepository repository, ServerModp public static Task getUpdateTask(HMCLGameRepository repository, Path zipFile, Charset charset, String name, ModpackConfiguration configuration) throws UnsupportedModpackException, ManuallyCreatedModpackException, MismatchedModpackTypeException { Modpack modpack = ModpackHelper.readModpackManifest(zipFile, charset); - ModpackProvider provider = getProviderByType(configuration.getType()); + ModpackProvider provider = getProviderByType(configuration.type()); if (provider == null) { throw new UnsupportedModpackException(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/RemoteModpackPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/RemoteModpackPage.java index 3da22a67ac5..6270fbd3266 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/RemoteModpackPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/RemoteModpackPage.java @@ -52,9 +52,9 @@ public RemoteModpackPage(WizardController controller) { return; } - nameProperty.set(manifest.getName()); - versionProperty.set(manifest.getVersion()); - authorProperty.set(manifest.getAuthor()); + nameProperty.set(manifest.name()); + versionProperty.set(manifest.version()); + authorProperty.set(manifest.author()); HMCLGameRepository repository = controller.getSettings().get(ModpackPage.REPOSITORY); String name = controller.getSettings().get(MODPACK_NAME); @@ -63,14 +63,14 @@ public RemoteModpackPage(WizardController controller) { txtModpackName.setDisable(true); } else { // trim: https://github.com/HMCL-dev/HMCL/issues/962 - txtModpackName.setText(manifest.getName().trim()); + txtModpackName.setText(manifest.name().trim()); txtModpackName.getValidators().addAll( new RequiredValidator(), new Validator(i18n("install.new_game.already_exists"), str -> !repository.versionIdConflicts(str)), new Validator(i18n("install.new_game.malformed"), HMCLGameRepository::isValidVersionId)); } - btnDescription.setVisible(StringUtils.isNotBlank(manifest.getDescription())); + btnDescription.setVisible(StringUtils.isNotBlank(manifest.description())); } @Override @@ -85,7 +85,7 @@ protected void onInstall() { } protected void onDescribe() { - Controllers.navigate(new WebPage(i18n("modpack.description"), manifest.getDescription())); + Controllers.navigate(new WebPage(i18n("modpack.description"), manifest.description())); } public static final SettingsMap.Key MODPACK_SERVER_MANIFEST = new SettingsMap.Key<>("MODPACK_SERVER_MANIFEST"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java index a282be3d018..edfaefa9896 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameItem.java @@ -87,7 +87,7 @@ record Result(@Nullable String gameVersion, @Nullable String tag) { String modPackVersion = null; try { ModpackConfiguration config = repository.readModpackConfiguration(id); - modPackVersion = config != null ? config.getVersion() : null; + modPackVersion = config != null ? config.version() : null; } catch (IOException e) { LOG.warning("Failed to read modpack configuration from " + id, e); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackConfiguration.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackConfiguration.java index 41928323108..d3e6039d010 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackConfiguration.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackConfiguration.java @@ -23,69 +23,34 @@ import org.jackhuang.hmcl.util.gson.Validation; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; @Immutable -public final class ModpackConfiguration implements Validation { +public record ModpackConfiguration(T manifest, String type, String name, @Nullable String version, + List overrides) implements Validation { @SuppressWarnings("unchecked") public static TypeToken> typeOf(Class clazz) { return (TypeToken>) TypeToken.getParameterized(ModpackConfiguration.class, clazz); } - private final T manifest; - private final String type; - private final String name; - private final String version; - private final List overrides; - - public ModpackConfiguration() { - this(null, null, "", null, Collections.emptyList()); - } - - public ModpackConfiguration(T manifest, String type, String name, String version, List overrides) { - this.manifest = manifest; - this.type = type; - this.name = name; - this.version = version; - this.overrides = new ArrayList<>(overrides); - } - - public T getManifest() { - return manifest; - } - - public String getType() { - return type; - } - - public String getName() { - return name; + public ModpackConfiguration { + if (name == null) name = ""; + overrides = overrides == null ? List.of() : List.copyOf(overrides); } - @Nullable - public String getVersion() { - return version; - } - - public ModpackConfiguration setManifest(T manifest) { + public ModpackConfiguration withManifest(T manifest) { return new ModpackConfiguration<>(manifest, type, name, version, overrides); } - public ModpackConfiguration setOverrides(List overrides) { + public ModpackConfiguration withOverrides(List overrides) { return new ModpackConfiguration<>(manifest, type, name, version, overrides); } - public ModpackConfiguration setVersion(String version) { + public ModpackConfiguration withVersion(String version) { return new ModpackConfiguration<>(manifest, type, name, version, overrides); } - public List getOverrides() { - return Collections.unmodifiableList(overrides); - } - @Override public void validate() throws JsonParseException { if (manifest == null) @@ -94,43 +59,16 @@ public void validate() throws JsonParseException { throw new JsonParseException("MinecraftInstanceConfiguration missing `type`"); } + /** + * @param path the relative path to Minecraft run directory. + */ @Immutable - public static class FileInformation implements Validation { - private final String path; // relative - private final String hash; - private final String downloadURL; - - public FileInformation() { - this(null, null); - } + public record FileInformation(String path, String hash, @Nullable String downloadURL) implements Validation { public FileInformation(String path, String hash) { this(path, hash, null); } - public FileInformation(String path, String hash, String downloadURL) { - this.path = path; - this.hash = hash; - this.downloadURL = downloadURL; - } - - /** - * The relative path to Minecraft run directory - * - * @return the relative path to Minecraft run directory. - */ - public String getPath() { - return path; - } - - public String getDownloadURL() { - return downloadURL; - } - - public String getHash() { - return hash; - } - @Override public void validate() throws JsonParseException { if (path == null) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackInstallTask.java index e05bda259b9..44ff1c8d8d9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/ModpackInstallTask.java @@ -54,7 +54,7 @@ public ModpackInstallTask(Path modpackFile, Path dest, Charset charset, List files = new HashMap<>(); for (ModpackConfiguration.FileInformation file : overrides) - files.put(file.getPath(), file); + files.put(file.path(), file); for (String subDirectory : subDirectories) { @@ -88,7 +88,7 @@ public void execute() throws Exception { // If both old and new modpacks have this entry, and user has modified this file, // we will not replace it since this modified file is what user expects. String fileHash = DigestUtils.digestToString("SHA-1", destFile); - String oldHash = files.get(relativePath).getHash(); + String oldHash = files.get(relativePath).hash(); return Objects.equals(oldHash, fileHash); } }).unzip(); @@ -96,8 +96,8 @@ public void execute() throws Exception { // If old modpack have this entry, and new modpack deleted it. Delete this file. for (ModpackConfiguration.FileInformation file : overrides) { - Path original = dest.resolve(file.getPath()); - if (Files.exists(original) && !entries.contains(file.getPath())) + Path original = dest.resolve(file.path()); + if (Files.exists(original) && !entries.contains(file.path())) Files.deleteIfExists(original); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseInstallTask.java index b8cf50d8f2d..2611fb68ae5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseInstallTask.java @@ -107,7 +107,7 @@ public CurseInstallTask(DefaultDependencyManager dependencyManager, Path zipFile if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(CurseManifest.class)); - if (!CurseModpackProvider.INSTANCE.getName().equals(config.getType())) + if (!CurseModpackProvider.INSTANCE.getName().equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a Curse modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { @@ -172,7 +172,7 @@ public void execute() throws Exception { // resolves those file names and writes the enriched manifest to // manifest.json, so read from there when available. Path oldManifestFile = repository.getVersionRoot(name).resolve("manifest.json"); - List oldFiles = config.getManifest().files(); + List oldFiles = config.manifest().files(); if (Files.exists(oldManifestFile)) { try { CurseManifest oldManifest = JsonUtils.fromJsonFile(oldManifestFile, CurseManifest.class); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseMetaMod.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseMetaMod.java index 2a146188ce5..b01eda7597c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseMetaMod.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseMetaMod.java @@ -26,43 +26,14 @@ * https://addons-ecs.forgesvc.net/api/v2/addon/<projectID>/file/<fileID> */ @Immutable -public final class CurseMetaMod { - @SerializedName(value = "Id", alternate = "id") - private final int id; - - @SerializedName(value = "FileName", alternate = "fileName") - private final String fileName; - - @SerializedName(value = "FileNameOnDisk") - private final String fileNameOnDisk; - - @SerializedName(value = "DownloadURL", alternate = "downloadUrl") - private final String downloadURL; - - public CurseMetaMod() { - this(0, "", "", ""); - } - - public CurseMetaMod(int id, String fileName, String fileNameOnDisk, String downloadURL) { - this.id = id; - this.fileName = fileName; - this.fileNameOnDisk = fileNameOnDisk; - this.downloadURL = downloadURL; - } - - public int getId() { - return id; - } - - public String getFileName() { - return fileName; - } - - public String getFileNameOnDisk() { - return fileNameOnDisk; - } - - public String getDownloadURL() { - return downloadURL; +public record CurseMetaMod(@SerializedName(value = "Id", alternate = "id") int id, + @SerializedName(value = "FileName", alternate = "fileName") String fileName, + @SerializedName(value = "FileNameOnDisk") String fileNameOnDisk, + @SerializedName(value = "DownloadURL", alternate = "downloadUrl") String downloadURL) { + + public CurseMetaMod { + if (fileName == null) fileName = ""; + if (fileNameOnDisk == null) fileNameOnDisk = ""; + if (downloadURL == null) downloadURL = ""; } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackCompletionTask.java index 730acc2106b..859c46bc501 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackCompletionTask.java @@ -89,7 +89,7 @@ public CompletableFuture getFuture(TaskCompletableFuture executor) { throw new IOException("Malformed modpack configuration"); } } - manifest = configuration.getManifest(); + manifest = configuration.manifest(); if (manifest == null) throw new CustomException(); })).thenComposeAsync(unused -> { // we first download latest manifest @@ -173,7 +173,7 @@ public CompletableFuture getFuture(TaskCompletableFuture executor) { })).thenAcceptAsync(wrapConsumer(unused1 -> { Path manifestFile = repository.getModpackConfiguration(version); JsonUtils.writeToJsonFile(manifestFile, - new ModpackConfiguration<>(manifest, this.configuration.getType(), this.manifest.getName(), this.manifest.getVersion(), + new ModpackConfiguration<>(manifest, this.configuration.type(), this.manifest.getName(), this.manifest.getVersion(), this.manifest.getFiles().stream() .flatMap(file -> file instanceof McbbsModpackManifest.AddonFile ? Stream.of((McbbsModpackManifest.AddonFile) file) @@ -204,7 +204,7 @@ public CompletableFuture getFuture(TaskCompletableFuture executor) { try { String result = NetworkUtils.doGet(String.format("https://cursemeta.dries007.net/%d/%d.json", file.getProjectID(), file.getFileID())); CurseMetaMod mod = JsonUtils.fromNonNullJson(result, CurseMetaMod.class); - return file.withFileName(mod.getFileNameOnDisk()).withURL(mod.getDownloadURL()); + return file.withFileName(mod.fileNameOnDisk()).withURL(mod.downloadURL()); } catch (FileNotFoundException fof) { LOG.warning("Could not query cursemeta for deleted mods: " + file.getUrl(), fof); notFound.set(true); @@ -213,7 +213,7 @@ public CompletableFuture getFuture(TaskCompletableFuture executor) { try { String result = NetworkUtils.doGet(String.format("https://addons-ecs.forgesvc.net/api/v2/addon/%d/file/%d", file.getProjectID(), file.getFileID())); CurseMetaMod mod = JsonUtils.fromNonNullJson(result, CurseMetaMod.class); - return file.withFileName(mod.getFileName()).withURL(mod.getDownloadURL()); + return file.withFileName(mod.fileName()).withURL(mod.downloadURL()); } catch (FileNotFoundException fof) { LOG.warning("Could not query forgesvc for deleted mods: " + file.getUrl(), fof); notFound.set(true); @@ -237,7 +237,7 @@ public CompletableFuture getFuture(TaskCompletableFuture executor) { .collect(Collectors.toList())); manifest = newManifest; - configuration = configuration.setManifest(newManifest); + configuration = configuration.withManifest(newManifest); JsonUtils.writeToJsonFile(configurationFile, configuration); for (McbbsModpackManifest.File file : newManifest.getFiles()) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackLocalInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackLocalInstallTask.java index 9666b4c0b89..0755c5bc9ec 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackLocalInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackLocalInstallTask.java @@ -81,7 +81,7 @@ public McbbsModpackLocalInstallTask(DefaultDependencyManager dependencyManager, if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(McbbsModpackManifest.class)); - if (!McbbsModpackProvider.INSTANCE.getName().equals(config.getType())) + if (!McbbsModpackProvider.INSTANCE.getName().equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a Mcbbs modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackProvider.java index 966c08bfe15..8845ef0b18c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackProvider.java @@ -56,11 +56,11 @@ public Task createUpdateTask(DefaultDependencyManager dependencyManager, Stri public void injectLaunchOptions(String modpackConfigurationJson, LaunchOptions.Builder builder) { ModpackConfiguration config = JsonUtils.GSON.fromJson(modpackConfigurationJson, ModpackConfiguration.typeOf(McbbsModpackManifest.class)); - if (!getName().equals(config.getType())) { - throw new IllegalArgumentException("Incorrect manifest type, actual=" + config.getType() + ", expected=" + getName()); + if (!getName().equals(config.type())) { + throw new IllegalArgumentException("Incorrect manifest type, actual=" + config.type() + ", expected=" + getName()); } - config.getManifest().injectLaunchOptions(builder); + config.manifest().injectLaunchOptions(builder); } private static Modpack fromManifestFile(InputStream json, Charset encoding) throws IOException, JsonParseException { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackRemoteInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackRemoteInstallTask.java index bfd6ec23d9e..0d591d15e93 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackRemoteInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/mcbbs/McbbsModpackRemoteInstallTask.java @@ -67,7 +67,7 @@ public McbbsModpackRemoteInstallTask(DefaultDependencyManager dependencyManager, if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(McbbsModpackManifest.class)); - if (!MODPACK_TYPE.equals(config.getType())) + if (!MODPACK_TYPE.equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a Mcbbs modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthCompletionTask.java index 6794a52cf3b..efacb734a97 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthCompletionTask.java @@ -105,15 +105,15 @@ public void execute() throws Exception { Path runDirectory = FileUtils.toAbsolute(repository.getRunDirectory(version)); Path modsDirectory = runDirectory.resolve("mods"); - for (ModrinthManifest.File file : manifest.getFiles()) { - if (file.getEnv() != null && file.getEnv().getOrDefault("client", "required").equals("unsupported")) + for (ModrinthManifest.File file : manifest.files()) { + if (file.env() != null && file.env().getOrDefault("client", "required").equals("unsupported")) continue; - if (file.getDownloads().isEmpty()) + if (file.downloads().isEmpty()) continue; - Path filePath = runDirectory.resolve(file.getPath()).toAbsolutePath().normalize(); + Path filePath = runDirectory.resolve(file.path()).toAbsolutePath().normalize(); if (!filePath.startsWith(runDirectory)) - throw new IOException("Unsecure path: " + file.getPath()); + throw new IOException("Unsecure path: " + file.path()); if (Files.exists(filePath)) continue; @@ -121,7 +121,7 @@ public void execute() throws Exception { continue; var task = new FileDownloadTask( - dependency.getDownloadProvider().injectURLsWithCandidates(file.getDownloads()), + dependency.getDownloadProvider().injectURLsWithCandidates(file.downloads()), filePath); task.setCacheRepository(dependency.getCacheRepository()); task.setCaching(true); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthInstallTask.java index 00e9a0cc560..95488f81ecc 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthInstallTask.java @@ -68,7 +68,7 @@ public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipF throw new IllegalArgumentException("Version " + name + " already exists."); GameBuilder builder = dependencyManager.gameBuilder().name(name).gameVersion(manifest.getGameVersion()); - for (Map.Entry modLoader : manifest.getDependencies().entrySet()) { + for (Map.Entry modLoader : manifest.dependencies().entrySet()) { switch (modLoader.getKey()) { case "minecraft": break; @@ -106,7 +106,7 @@ public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipF if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(ModrinthManifest.class)); - if (!ModrinthModpackProvider.INSTANCE.getName().equals(config.getType())) + if (!ModrinthModpackProvider.INSTANCE.getName().equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a Modrinth modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { @@ -115,7 +115,7 @@ public ModrinthInstallTask(DefaultDependencyManager dependencyManager, Path zipF this.config = config; List subDirectories = Arrays.asList("/client-overrides", "/overrides"); dependents.add(new ModpackInstallTask<>(zipFile, run, modpack.getEncoding(), subDirectories, any -> true, config).withStage("hmcl.modpack")); - dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), subDirectories, manifest, ModrinthModpackProvider.INSTANCE, manifest.getName(), manifest.getVersionId(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack")); + dependents.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), subDirectories, manifest, ModrinthModpackProvider.INSTANCE, manifest.name(), manifest.versionId(), repository.getModpackConfiguration(name)).withStage("hmcl.modpack")); URI iconUri = NetworkUtils.toURIOrNull(iconUrl); if (iconUri != null) { @@ -143,10 +143,10 @@ public Collection> getDependencies() { public void execute() throws Exception { if (config != null) { // For update, remove mods not listed in new manifest - for (ModrinthManifest.File oldManifestFile : config.getManifest().getFiles()) { - Path oldFile = run.resolve(oldManifestFile.getPath()); + for (ModrinthManifest.File oldManifestFile : config.manifest().files()) { + Path oldFile = run.resolve(oldManifestFile.path()); if (!Files.exists(oldFile)) continue; - if (manifest.getFiles().stream().noneMatch(oldManifestFile::equals)) { + if (manifest.files().stream().noneMatch(oldManifestFile::equals)) { Files.deleteIfExists(oldFile); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthManifest.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthManifest.java index 12577c7899d..a77b0f317f9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthManifest.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthManifest.java @@ -26,54 +26,12 @@ import java.util.List; import java.util.Map; -import java.util.Objects; -public class ModrinthManifest implements ModpackManifest, Validation { +public record ModrinthManifest(String game, int formatVersion, String versionId, String name, @Nullable String summary, + List files, Map dependencies) implements ModpackManifest, Validation { - private final String game; - private final int formatVersion; - private final String versionId; - private final String name; - private final @Nullable String summary; - private final List files; - private final Map dependencies; - - public ModrinthManifest(String game, int formatVersion, String versionId, String name, @Nullable String summary, List files, Map dependencies) { - this.game = game; - this.formatVersion = formatVersion; - this.versionId = versionId; - this.name = name; - this.summary = summary; - this.files = files; - this.dependencies = dependencies; - } - - public String getGame() { - return game; - } - - public int getFormatVersion() { - return formatVersion; - } - - public String getVersionId() { - return versionId; - } - - public String getName() { - return name; - } - - public String getSummary() { - return summary == null ? "" : summary; - } - - public List getFiles() { - return files; - } - - public Map getDependencies() { - return dependencies; + public ModrinthManifest { + if (summary == null) summary = ""; } public String getGameVersion() { @@ -92,55 +50,7 @@ public void validate() throws JsonParseException, TolerableValidationException { } } - public static class File { - private final String path; - private final Map hashes; - @Nullable - private final Map env; - private final List downloads; - private final int fileSize; - - public File(String path, Map hashes, @Nullable Map env, List downloads, int fileSize) { - this.path = path; - this.hashes = hashes; - this.env = env; - this.downloads = downloads; - this.fileSize = fileSize; - } - - public String getPath() { - return path; - } - - public Map getHashes() { - return hashes; - } - - @Nullable - public Map getEnv() { - return env; - } - - public List getDownloads() { - return downloads; - } - - public int getFileSize() { - return fileSize; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - File file = (File) o; - return fileSize == file.fileSize && path.equals(file.path) && hashes.equals(file.hashes) && Objects.equals(this.env, file.env) && downloads.equals(file.downloads); - } - - @Override - public int hashCode() { - return Objects.hash(path, hashes, env, downloads, fileSize); - } + public record File(String path, Map hashes, @Nullable Map env, List downloads, int fileSize) { } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthModpackProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthModpackProvider.java index fdaa506c920..24753e4415d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthModpackProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/modrinth/ModrinthModpackProvider.java @@ -56,7 +56,7 @@ public Task createUpdateTask(DefaultDependencyManager dependencyManager, Stri @Override public Modpack readManifest(ZipArchiveReader zip, Path file, Charset encoding) throws IOException, JsonParseException { ModrinthManifest manifest = JsonUtils.fromNonNullJson(CompressingUtils.readTextZipEntry(zip, "modrinth.index.json"), ModrinthManifest.class); - return new Modpack(manifest.getName(), "", manifest.getVersionId(), manifest.getGameVersion(), manifest.getSummary(), encoding, manifest) { + return new Modpack(manifest.name(), "", manifest.versionId(), manifest.getGameVersion(), manifest.summary(), encoding, manifest) { @Override public Task getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) { return new ModrinthInstallTask(dependencyManager, zipFile, this, manifest, name, iconUrl); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstanceConfiguration.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstanceConfiguration.java index ff80cca6dc8..5305707f188 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstanceConfiguration.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstanceConfiguration.java @@ -72,8 +72,8 @@ public final class MultiMCInstanceConfiguration implements ModpackManifest { instanceType = readValue(p, "InstanceType"); autoCloseConsole = Boolean.parseBoolean(readValue(p, "AutoCloseConsole")); - gameVersion = mmcPack != null ? mmcPack.getComponents().stream().filter(e -> "net.minecraft".equals(e.getUid())).findAny() - .orElseThrow(() -> new IOException("Malformed mmc-pack.json")).getVersion() : readValue(p, "IntendedVersion"); + gameVersion = mmcPack != null ? mmcPack.components().stream().filter(e -> "net.minecraft".equals(e.uid())).findAny() + .orElseThrow(() -> new IOException("Malformed mmc-pack.json")).version() : readValue(p, "IntendedVersion"); javaPath = readValue(p, "JavaPath"); jvmArgs = readValue(p, "JvmArgs"); fullscreen = Boolean.parseBoolean(readValue(p, "LaunchMaximized")); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstancePatch.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstancePatch.java index 452faace338..6398251725d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstancePatch.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCInstancePatch.java @@ -199,43 +199,8 @@ public static MultiMCInstancePatch read(String componentID, String text) { } } - public static final class ResolvedInstance { - private final Version version; - - private final String gameVersion; - - private final Library mainJar; - - private final List jarModFileNames; - private final List mavenOnlyFiles; - - public ResolvedInstance(Version version, String gameVersion, Library mainJar, List jarModFileNames, List mavenOnlyFiles) { - this.version = version; - this.gameVersion = gameVersion; - this.mainJar = mainJar; - this.jarModFileNames = jarModFileNames; - this.mavenOnlyFiles = mavenOnlyFiles; - } - - public Version getVersion() { - return version; - } - - public String getGameVersion() { - return gameVersion; - } - - public Library getMainJar() { - return mainJar; - } - - public List getJarModFileNames() { - return jarModFileNames; - } - - public List getMavenOnlyFiles() { - return mavenOnlyFiles; - } + public record ResolvedInstance(Version version, String gameVersion, Library mainJar, + List jarModFileNames, List mavenOnlyFiles) { } /** diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCManifest.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCManifest.java index 66f15c02ed7..7f700723b19 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCManifest.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCManifest.java @@ -17,6 +17,7 @@ */ package org.jackhuang.hmcl.modpack.multimc; +import com.google.gson.JsonParseException; import com.google.gson.annotations.SerializedName; import kala.compress.archivers.zip.ZipArchiveEntry; import kala.compress.archivers.zip.ZipArchiveReader; @@ -27,136 +28,43 @@ import java.util.List; @Immutable -public final class MultiMCManifest { - - @SerializedName("formatVersion") - private final int formatVersion; - - @SerializedName("components") - private final List components; - - public MultiMCManifest(int formatVersion, List components) { - this.formatVersion = formatVersion; - this.components = components; - } - - public int getFormatVersion() { - return formatVersion; - } - - public List getComponents() { - return components; - } +public record MultiMCManifest(@SerializedName("formatVersion") int formatVersion, + @SerializedName("components") List components) { /** * Read MultiMC modpack manifest from zip file + * * @param zipFile the zip file * @return the MultiMC modpack manifest. - * @throws IOException if zip file is malformed - * @throws com.google.gson.JsonParseException if manifest is malformed. + * @throws IOException if zip file is malformed + * @throws JsonParseException if manifest is malformed. */ public static MultiMCManifest readMultiMCModpackManifest(ZipArchiveReader zipFile, String rootEntryName) throws IOException { ZipArchiveEntry mmcPack = zipFile.getEntry(rootEntryName + "mmc-pack.json"); if (mmcPack == null) return null; MultiMCManifest manifest = JsonUtils.fromNonNullJsonFully(zipFile.getInputStream(mmcPack), MultiMCManifest.class); - if (manifest.getComponents() == null) + if (manifest.components() == null) throw new IOException("mmc-pack.json malformed."); return manifest; } - public static final class MultiMCManifestCachedRequires { - @SerializedName("equals") - private final String equalsVersion; - - @SerializedName("uid") - private final String uid; - - @SerializedName("suggests") - private final String suggests; - - public MultiMCManifestCachedRequires(String equalsVersion, String uid, String suggests) { - this.equalsVersion = equalsVersion; - this.uid = uid; - this.suggests = suggests; - } - - public String getEqualsVersion() { - return equalsVersion; - } - - public String getID() { - return uid; - } - - public String getSuggests() { - return suggests; - } + public record MultiMCManifestCachedRequires(@SerializedName("equals") String equalsVersion, + @SerializedName("uid") String uid, + @SerializedName("suggests") String suggests) { } - public static final class MultiMCManifestComponent { - @SerializedName("cachedName") - private final String cachedName; - - @SerializedName("cachedRequires") - private final List cachedRequires; - - @SerializedName("cachedVersion") - private final String cachedVersion; - - @SerializedName("important") - private final boolean important; - - @SerializedName("dependencyOnly") - private final boolean dependencyOnly; - - @SerializedName("uid") - private final String uid; - - @SerializedName("version") - private final String version; + public record MultiMCManifestComponent(@SerializedName("cachedName") String cachedName, + @SerializedName("cachedRequires") List cachedRequires, + @SerializedName("cachedVersion") String cachedVersion, + @SerializedName("important") boolean important, + @SerializedName("dependencyOnly") boolean dependencyOnly, + @SerializedName("uid") String uid, + @SerializedName("version") String version) { public MultiMCManifestComponent(boolean important, boolean dependencyOnly, String uid, String version) { this(null, null, null, important, dependencyOnly, uid, version); } - - public MultiMCManifestComponent(String cachedName, List cachedRequires, String cachedVersion, boolean important, boolean dependencyOnly, String uid, String version) { - this.cachedName = cachedName; - this.cachedRequires = cachedRequires; - this.cachedVersion = cachedVersion; - this.important = important; - this.dependencyOnly = dependencyOnly; - this.uid = uid; - this.version = version; - } - - public String getCachedName() { - return cachedName; - } - - public List getCachedRequires() { - return cachedRequires; - } - - public String getCachedVersion() { - return cachedVersion; - } - - public boolean isImportant() { - return important; - } - - public boolean isDependencyOnly() { - return dependencyOnly; - } - - public String getUid() { - return uid; - } - - public String getVersion() { - return version; - } } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackInstallTask.java index a028e6200d8..2369eacad97 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackInstallTask.java @@ -120,7 +120,7 @@ public void preExecute() throws Exception { if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(MultiMCInstanceConfiguration.class)); - if (!MultiMCModpackProvider.INSTANCE.getName().equals(config.getType())) + if (!MultiMCModpackProvider.INSTANCE.getName().equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a MultiMC modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { @@ -142,14 +142,14 @@ public void preExecute() throws Exception { Path root = getRootPath(fs); List components = Objects.requireNonNull( - Objects.requireNonNull(manifest.getMmcPack(), "mmc-pack.json").getComponents(), "components" + Objects.requireNonNull(manifest.getMmcPack(), "mmc-pack.json").components(), "components" ); List> patches = new ArrayList<>(); String mcVersion = null; for (MultiMCManifest.MultiMCManifestComponent component : components) { - if (MultiMCComponents.getComponent(component.getUid()) == LibraryAnalyzer.LibraryType.MINECRAFT) { - mcVersion = component.getVersion(); + if (MultiMCComponents.getComponent(component.uid()) == LibraryAnalyzer.LibraryType.MINECRAFT) { + mcVersion = component.version(); break; } } @@ -158,7 +158,7 @@ public void preExecute() throws Exception { } for (MultiMCManifest.MultiMCManifestComponent component : components) { - String componentID = Objects.requireNonNull(component.getUid(), "Component ID"); + String componentID = Objects.requireNonNull(component.uid(), "Component ID"); Path patchPath = root.resolve(String.format("patches/%s.json", componentID)); if (Files.exists(patchPath)) { @@ -170,7 +170,7 @@ public void preExecute() throws Exception { patches.add(Task.supplyAsync(() -> patch)); // TODO: Task.completed has unclear compatibility issue. } else { patches.add( - new GetTask(MultiMCComponents.getMetaURL(componentID, component.getVersion(), mcVersion)) + new GetTask(MultiMCComponents.getMetaURL(componentID, component.version(), mcVersion)) .thenApplyAsync(s -> MultiMCInstancePatch.read(componentID, s)) ); } @@ -206,10 +206,10 @@ public void execute() throws Exception { while (true) { for (MultiMCInstancePatch patch : existed.values()) { for (MultiMCManifest.MultiMCManifestCachedRequires require : patch.getRequires()) { - String componentID = require.getID(); + String componentID = require.uid(); if (!existed.containsKey(componentID)) { Task task = new GetTask(MultiMCComponents.getMetaURL( - componentID, Lang.requireNonNullElse(require.getEqualsVersion(), require.getSuggests()), mcVersion + componentID, Lang.requireNonNullElse(require.equalsVersion(), require.suggests()), mcVersion )).thenApplyAsync(s -> MultiMCInstancePatch.read(componentID, s)); task.run(); @@ -254,21 +254,21 @@ public void execute() throws Exception { if (Files.exists(libraries)) FileUtils.copyDirectory(libraries, repository.getVersionRoot(name).resolve("libraries")); - for (Library library : artifact.getVersion().getLibraries()) { + for (Library library : artifact.version().getLibraries()) { if ("local".equals(library.getHint())) { /* TODO: Determine whether we should erase community fields, like 'hint' and 'filename' from version json. Retain them will facilitate compatibility, as some embedded libraries may check where their JAR is. Meanwhile, potential compatibility issue with other launcher which never supports these fields might occur. Here, we make the file stored twice, to keep maximum compatibility. */ - Path from = repository.getLibraryFile(artifact.getVersion(), library); - Path target = repository.getLibraryFile(artifact.getVersion(), library.withoutCommunityFields()); + Path from = repository.getLibraryFile(artifact.version(), library); + Path target = repository.getLibraryFile(artifact.version(), library.withoutCommunityFields()); Files.createDirectories(target.getParent()); Files.copy(from, target, StandardCopyOption.REPLACE_EXISTING); } } try (InputStream input = MaintainTask.class.getResourceAsStream("/assets/game/HMCLMultiMCBootstrap-1.0.jar")) { - Path libraryPath = repository.getLibraryFile(artifact.getVersion(), MultiMCInstancePatch.BOOTSTRAP_LIBRARY); + Path libraryPath = repository.getLibraryFile(artifact.version(), MultiMCInstancePatch.BOOTSTRAP_LIBRARY); Files.createDirectories(libraryPath.getParent()); Files.copy(Objects.requireNonNull(input, "Bundled HMCLMultiMCBootstrap is missing."), libraryPath, StandardCopyOption.REPLACE_EXISTING); @@ -285,19 +285,19 @@ public void execute() throws Exception { // Stage #5: Assemble game files. { - Version version = artifact.getVersion(); + Version version = artifact.version(); - dependencies.add(repository.saveAsync(artifact.getVersion())); + dependencies.add(repository.saveAsync(artifact.version())); dependencies.add(new GameAssetDownloadTask(dependencyManager, version, GameAssetDownloadTask.DOWNLOAD_INDEX_FORCIBLY, true)); dependencies.add(new GameLibrariesTask( dependencyManager, // TODO: check integrity of maven-only files when launching games? - version.setLibraries(Lang.merge(version.getLibraries(), artifact.getMavenOnlyFiles())), + version.setLibraries(Lang.merge(version.getLibraries(), artifact.mavenOnlyFiles())), true )); - Artifact mainJarArtifact = artifact.getMainJar().getArtifact(); - String gameVersion = artifact.getGameVersion(); + Artifact mainJarArtifact = artifact.mainJar().getArtifact(); + String gameVersion = artifact.gameVersion(); if (gameVersion != null && "com.mojang".equals(mainJarArtifact.getGroup()) && "minecraft".equals(mainJarArtifact.getName()) && @@ -328,7 +328,7 @@ public boolean doPostExecute() { public void postExecute() throws Exception { MultiMCInstancePatch.ResolvedInstance artifact = Objects.requireNonNull(getResult(), "ResolvedInstance"); - List files = artifact.getJarModFileNames(); + List files = artifact.jarModFileNames(); if (!isDependenciesSucceeded() || files.isEmpty()) { return; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackCompletionTask.java index ab06e48e380..6da1f2009fc 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackCompletionTask.java @@ -81,8 +81,8 @@ public boolean doPreExecute() { @Override public void preExecute() throws Exception { - if (manifest == null || StringUtils.isBlank(manifest.getManifest().getFileApi())) return; - dependent = new GetTask(manifest.getManifest().getFileApi() + "/server-manifest.json"); + if (manifest == null || StringUtils.isBlank(manifest.manifest().fileApi())) return; + dependent = new GetTask(manifest.manifest().fileApi() + "/server-manifest.json"); } @Override @@ -96,12 +96,12 @@ public Collection> getDependents() { } private Map toMap(Collection addons) { - return addons.stream().collect(Collectors.toMap(ServerModpackManifest.Addon::getId, ServerModpackManifest.Addon::getVersion)); + return addons.stream().collect(Collectors.toMap(ServerModpackManifest.Addon::id, ServerModpackManifest.Addon::version)); } @Override public void execute() throws Exception { - if (manifest == null || StringUtils.isBlank(manifest.getManifest().getFileApi())) return; + if (manifest == null || StringUtils.isBlank(manifest.manifest().fileApi())) return; try { remoteManifest = JsonUtils.fromNonNullJson(dependent.getResult(), ServerModpackManifest.class); @@ -109,23 +109,23 @@ public void execute() throws Exception { throw new IOException(e); } - Map oldAddons = toMap(manifest.getManifest().getAddons()); - Map newAddons = toMap(remoteManifest.getAddons()); + Map oldAddons = toMap(manifest.manifest().addons()); + Map newAddons = toMap(remoteManifest.addons()); if (!Objects.equals(oldAddons, newAddons)) { GameBuilder builder = dependencyManager.gameBuilder().name(version); - for (ServerModpackManifest.Addon addon : remoteManifest.getAddons()) { - builder.version(addon.getId(), addon.getVersion()); + for (ServerModpackManifest.Addon addon : remoteManifest.addons()) { + builder.version(addon.id(), addon.version()); } dependencies.add(builder.buildAsync()); } Path rootPath = repository.getVersionRoot(version).toAbsolutePath().normalize(); - Map files = manifest.getManifest().getFiles().stream() - .collect(Collectors.toMap(ModpackConfiguration.FileInformation::getPath, + Map files = manifest.manifest().files().stream() + .collect(Collectors.toMap(ModpackConfiguration.FileInformation::path, Function.identity())); - Set remoteFiles = remoteManifest.getFiles().stream().map(ModpackConfiguration.FileInformation::getPath) + Set remoteFiles = remoteManifest.files().stream().map(ModpackConfiguration.FileInformation::path) .collect(Collectors.toSet()); Path runDirectory = repository.getRunDirectory(version).toAbsolutePath().normalize(); @@ -133,12 +133,12 @@ public void execute() throws Exception { int total = 0; // for files in new modpack - for (ModpackConfiguration.FileInformation file : remoteManifest.getFiles()) { - Path actualPath = rootPath.resolve(file.getPath()).toAbsolutePath().normalize(); + for (ModpackConfiguration.FileInformation file : remoteManifest.files()) { + Path actualPath = rootPath.resolve(file.path()).toAbsolutePath().normalize(); String fileName = actualPath.getFileName().toString(); if (!actualPath.startsWith(rootPath)) { - throw new IOException("Unsecure path: " + file.getPath()); + throw new IOException("Unsecure path: " + file.path()); } boolean download; @@ -149,7 +149,7 @@ public void execute() throws Exception { if (isModDisabled) { download = false; - } else if (!files.containsKey(file.getPath())) { + } else if (!files.containsKey(file.path())) { // If old modpack does not have this entry, download it download = true; } else if (!Files.exists(actualPath)) { @@ -159,24 +159,24 @@ public void execute() throws Exception { } else { // If user modified this entry file, we will not replace this file since this modified file is that user expects. String fileHash = DigestUtils.digestToString("SHA-1", actualPath); - String oldHash = files.get(file.getPath()).getHash(); - download = !Objects.equals(oldHash, file.getHash()) && Objects.equals(oldHash, fileHash); + String oldHash = files.get(file.path()).hash(); + download = !Objects.equals(oldHash, file.hash()) && Objects.equals(oldHash, fileHash); } if (download) { total++; dependencies.add(new FileDownloadTask( - remoteManifest.getFileApi() + "/overrides/" + file.getPath(), + remoteManifest.fileApi() + "/overrides/" + file.path(), actualPath, - new FileDownloadTask.IntegrityCheck("SHA-1", file.getHash())) + new FileDownloadTask.IntegrityCheck("SHA-1", file.hash())) .withCounter("hmcl.modpack.download")); } } // If old modpack have this entry, and new modpack deleted it. Delete this file. - for (ModpackConfiguration.FileInformation file : manifest.getManifest().getFiles()) { - Path actualPath = rootPath.resolve(file.getPath()); - if (Files.exists(actualPath) && !remoteFiles.contains(file.getPath())) + for (ModpackConfiguration.FileInformation file : manifest.manifest().files()) { + Path actualPath = rootPath.resolve(file.path()); + if (Files.exists(actualPath) && !remoteFiles.contains(file.path())) Files.deleteIfExists(actualPath); } @@ -191,9 +191,9 @@ public boolean doPostExecute() { @Override public void postExecute() throws Exception { - if (manifest == null || StringUtils.isBlank(manifest.getManifest().getFileApi())) return; + if (manifest == null || StringUtils.isBlank(manifest.manifest().fileApi())) return; Path manifestFile = repository.getModpackConfiguration(version); Files.createDirectories(manifestFile.getParent()); - JsonUtils.writeToJsonFile(manifestFile, new ModpackConfiguration<>(remoteManifest, this.manifest.getType(), this.manifest.getName(), this.manifest.getVersion(), remoteManifest.getFiles())); + JsonUtils.writeToJsonFile(manifestFile, new ModpackConfiguration<>(remoteManifest, this.manifest.type(), this.manifest.name(), this.manifest.version(), remoteManifest.files())); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackLocalInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackLocalInstallTask.java index 5a1d382a685..b5764e27a4b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackLocalInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackLocalInstallTask.java @@ -58,8 +58,8 @@ public ServerModpackLocalInstallTask(DefaultDependencyManager dependencyManager, throw new IllegalArgumentException("Version " + name + " already exists."); GameBuilder builder = dependencyManager.gameBuilder().name(name); - for (ServerModpackManifest.Addon addon : manifest.getAddons()) { - builder.version(addon.getId(), addon.getVersion()); + for (ServerModpackManifest.Addon addon : manifest.addons()) { + builder.version(addon.id(), addon.version()); } dependents.add(builder.buildAsync()); @@ -73,7 +73,7 @@ public ServerModpackLocalInstallTask(DefaultDependencyManager dependencyManager, if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(ServerModpackManifest.class)); - if (!ServerModpackProvider.INSTANCE.getName().equals(config.getType())) + if (!ServerModpackProvider.INSTANCE.getName().equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a Server modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackManifest.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackManifest.java index f706b0add45..f0abb076db6 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackManifest.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackManifest.java @@ -35,55 +35,18 @@ import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.MINECRAFT; -public class ServerModpackManifest implements ModpackManifest, Validation { - private final String name; - private final String author; - private final String version; - private final String description; - private final String fileApi; - private final List files; - private final List addons; - - public ServerModpackManifest() { - this("", "", "", "", "", Collections.emptyList(), Collections.emptyList()); - } - - public ServerModpackManifest(String name, String author, String version, String description, String fileApi, List files, List addons) { - this.name = name; - this.author = author; - this.version = version; - this.description = description; - this.fileApi = fileApi; - this.files = files; - this.addons = addons; - } - - public String getName() { - return name; - } - - public String getAuthor() { - return author; - } - - public String getVersion() { - return version; - } - - public String getDescription() { - return description; - } - - public String getFileApi() { - return fileApi; - } - - public List getFiles() { - return files; - } - - public List getAddons() { - return addons; +public record ServerModpackManifest(String name, String author, String version, String description, String fileApi, + List files, + List addons) implements ModpackManifest, Validation { + + public ServerModpackManifest { + if (name == null) name = ""; + if (author == null) author = ""; + if (version == null) version = ""; + if (description == null) description = ""; + if (fileApi == null) fileApi = ""; + if (files == null) files = Collections.emptyList(); + if (addons == null) addons = Collections.emptyList(); } @Override @@ -99,31 +62,17 @@ public void validate() throws JsonParseException, TolerableValidationException { throw new JsonParseException("ServerModpackManifest.files cannot be null"); } - public static final class Addon { - private final String id; - private final String version; - - public Addon() { - this("", ""); - } - - public Addon(String id, String version) { - this.id = id; - this.version = version; - } - - public String getId() { - return id; - } + public record Addon(String id, String version) { - public String getVersion() { - return version; + public Addon { + if (id == null) id = ""; + if (version == null) version = ""; } } public Modpack toModpack(Charset encoding) throws IOException { String gameVersion = addons.stream().filter(x -> MINECRAFT.getPatchId().equals(x.id)).findAny() - .orElseThrow(() -> new IOException("Cannot find game version")).getVersion(); + .orElseThrow(() -> new IOException("Cannot find game version")).version(); return new Modpack(name, author, version, gameVersion, description, encoding, this) { @Override public Task getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackRemoteInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackRemoteInstallTask.java index ecff6c17ac6..854b3ae2e95 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackRemoteInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/server/ServerModpackRemoteInstallTask.java @@ -52,8 +52,8 @@ public ServerModpackRemoteInstallTask(DefaultDependencyManager dependencyManager throw new IllegalArgumentException("Version " + name + " already exists."); GameBuilder builder = dependencyManager.gameBuilder().name(name); - for (ServerModpackManifest.Addon addon : manifest.getAddons()) { - builder.version(addon.getId(), addon.getVersion()); + for (ServerModpackManifest.Addon addon : manifest.addons()) { + builder.version(addon.id(), addon.version()); } dependents.add(builder.buildAsync()); @@ -67,7 +67,7 @@ public ServerModpackRemoteInstallTask(DefaultDependencyManager dependencyManager if (Files.exists(json)) { config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(ServerModpackManifest.class)); - if (!MODPACK_TYPE.equals(config.getType())) + if (!MODPACK_TYPE.equals(config.type())) throw new IllegalArgumentException("Version " + name + " is not a Server modpack. Cannot update this version."); } } catch (JsonParseException | IOException ignore) { @@ -86,7 +86,7 @@ public List> getDependencies() { @Override public void execute() throws Exception { - dependencies.add(new ServerModpackCompletionTask(dependency, name, new ModpackConfiguration<>(manifest, MODPACK_TYPE, manifest.getName(), manifest.getVersion(), Collections.emptyList()))); + dependencies.add(new ServerModpackCompletionTask(dependency, name, new ModpackConfiguration<>(manifest, MODPACK_TYPE, manifest.name(), manifest.version(), Collections.emptyList()))); } public static final String MODPACK_TYPE = "Server";