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 4c810a573..612cbe046 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -158,6 +158,8 @@ public class HMCLGameRepository extends DefaultGameRepository { blackList.add("saves"); if (Files.exists(dstDir)) throw new IOException("Version exists"); + + Files.createDirectories(dstDir); FileUtils.copyDirectory(srcDir, dstDir, path -> Modpack.acceptFile(path, blackList, null)); Path fromJson = srcDir.resolve(srcId + ".json"); @@ -170,7 +172,7 @@ public class HMCLGameRepository extends DefaultGameRepository { } Files.copy(fromJson, toJson); - FileUtils.writeText(toJson, JsonUtils.GSON.toJson(fromVersion.setId(dstId))); + JsonUtils.writeToJsonFile(toJson, fromVersion.setId(dstId)); VersionSetting oldVersionSetting = getVersionSetting(srcId).clone(); GameDirectoryType originalGameDirType = oldVersionSetting.getGameDirType(); 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 86b75b9d8..a6f04fcd4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLModpackInstallTask.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLModpackInstallTask.java @@ -31,7 +31,6 @@ import org.jackhuang.hmcl.util.io.CompressingUtils; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -66,7 +65,7 @@ public final class HMCLModpackInstallTask extends Task { ModpackConfiguration config = null; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(Modpack.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(Modpack.class)); if (!HMCLModpackProvider.INSTANCE.getName().equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a HMCL modpack. Cannot update this version."); 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 5a7c01ae6..56ffd9ba2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java @@ -140,7 +140,7 @@ public final class ModpackHelper { throw new FileNotFoundException(file.getPath()); else try { - return JsonUtils.GSON.fromJson(Files.readString(file.toPath()), ModpackConfiguration.class); + return JsonUtils.fromJsonFile(file.toPath(), ModpackConfiguration.class); } catch (JsonParseException e) { throw new IOException("Malformed modpack configuration"); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/HMCLJavaRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/HMCLJavaRepository.java index 2f6a3915d..e1fa386a1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/HMCLJavaRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/HMCLJavaRepository.java @@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.platform.Platform; import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.io.InputStream; import java.nio.file.*; import java.util.*; @@ -116,11 +115,7 @@ public final class HMCLJavaRepository implements JavaRepository { } if (Files.isDirectory(javaDir)) { - JavaManifest manifest; - try (InputStream input = Files.newInputStream(file)) { - manifest = JsonUtils.fromJsonFully(input, JavaManifest.class); - } - + JavaManifest manifest = JsonUtils.fromJsonFile(file, JavaManifest.class); list.add(JavaRuntime.of(executable, manifest.getInfo(), isManaged)); } } @@ -191,7 +186,7 @@ public final class HMCLJavaRepository implements JavaRepository { }); JavaManifest manifest = new JavaManifest(info, update, files); - FileUtils.writeText(getManifestFile(platform, gameJavaVersion), JsonUtils.GSON.toJson(manifest)); + JsonUtils.writeToJsonFile(getManifestFile(platform, gameJavaVersion), manifest); return JavaRuntime.of(executable, info, true); }); } @@ -203,7 +198,7 @@ public final class HMCLJavaRepository implements JavaRepository { throw new IOException("Platform is mismatch: expected " + platform + " but got " + result.getInfo().getPlatform()); Path executable = javaDir.resolve("bin").resolve(platform.getOperatingSystem().getJavaExecutable()).toRealPath(); - FileUtils.writeText(getManifestFile(platform, name), JsonUtils.GSON.toJson(result)); + JsonUtils.writeToJsonFile(getManifestFile(platform, name), result); return JavaRuntime.of(executable, result.getInfo(), true); }); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/AuthlibInjectorServers.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/AuthlibInjectorServers.java index 82f3bc586..a68b9b836 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/AuthlibInjectorServers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/AuthlibInjectorServers.java @@ -72,8 +72,7 @@ public final class AuthlibInjectorServers implements Validation { if (ConfigHolder.isNewlyCreated() && Files.exists(configLocation)) { AuthlibInjectorServers configInstance; try { - String content = Files.readString(configLocation); - configInstance = JsonUtils.GSON.fromJson(content, AuthlibInjectorServers.class); + configInstance = JsonUtils.fromJsonFile(configLocation, AuthlibInjectorServers.class); } catch (IOException | JsonParseException e) { LOG.warning("Malformed authlib-injectors.json", e); return; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java index 618a72deb..a655ae4d8 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java @@ -34,9 +34,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.logging.Logger.LOG; @@ -117,8 +114,8 @@ public final class AboutPage extends StackPane { return componentList; } - try (Reader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) { - JsonArray array = JsonUtils.GSON.fromJson(reader, JsonArray.class); + try { + JsonArray array = JsonUtils.fromJsonFully(input, JsonArray.class); for (JsonElement element : array) { JsonObject obj = element.getAsJsonObject(); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java index 3cf901ca5..de9ffaffb 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java @@ -200,7 +200,8 @@ public class DefaultCacheRepository extends CacheRepository { private void saveIndex() { if (indexFile == null || index == null) return; try { - FileUtils.writeText(indexFile, JsonUtils.GSON.toJson(index)); + Files.createDirectories(indexFile.getParent()); + JsonUtils.writeToJsonFile(indexFile, index); } catch (IOException e) { LOG.error("Unable to save index.json", e); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java index b4965053a..a21dbc5f4 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/VersionJsonSaveTask.java @@ -21,9 +21,9 @@ import org.jackhuang.hmcl.game.DefaultGameRepository; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; -import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; /** * This task is to save the version json. @@ -51,7 +51,8 @@ public final class VersionJsonSaveTask extends Task { @Override public void execute() throws Exception { - File json = repository.getVersionJson(version.getId()).getAbsoluteFile(); - FileUtils.writeText(json, JsonUtils.GSON.toJson(version)); + Path json = repository.getVersionJson(version.getId()).toPath().toAbsolutePath(); + Files.createDirectories(json.getParent()); + JsonUtils.writeToJsonFile(json, version); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java index 048c8d692..57608468f 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java @@ -219,8 +219,9 @@ public class DefaultGameRepository implements GameRepository { // fix inheritsFrom of versions that inherits from version [from]. for (Version version : getVersions()) { if (from.equals(version.getInheritsFrom())) { - File json = getVersionJson(version.getId()).getAbsoluteFile(); - FileUtils.writeText(json, JsonUtils.GSON.toJson(version.setInheritsFrom(to))); + Path targetPath = getVersionJson(version.getId()).toPath(); + Files.createDirectories(targetPath.getParent()); + JsonUtils.writeToJsonFile(targetPath, version.setInheritsFrom(to)); } } return true; @@ -384,7 +385,7 @@ public class DefaultGameRepository implements GameRepository { @Override public AssetIndex getAssetIndex(String version, String assetId) throws IOException { try { - return Objects.requireNonNull(JsonUtils.GSON.fromJson(Files.readString(getIndexFile(version, assetId)), AssetIndex.class)); + return Objects.requireNonNull(JsonUtils.fromJsonFile(getIndexFile(version, assetId), AssetIndex.class)); } catch (JsonParseException | NullPointerException e) { throw new IOException("Asset index file malformed", e); } @@ -445,8 +446,7 @@ public class DefaultGameRepository implements GameRepository { if (!Files.isRegularFile(indexFile)) return assetsDir; - String assetIndexContent = Files.readString(indexFile); - AssetIndex index = JsonUtils.GSON.fromJson(assetIndexContent, AssetIndex.class); + AssetIndex index = JsonUtils.fromJsonFile(indexFile, AssetIndex.class); if (index == null) return assetsDir; @@ -455,7 +455,7 @@ public class DefaultGameRepository implements GameRepository { Path resourcesDir = getRunDirectory(version).toPath().resolve("resources"); int cnt = 0; - int tot = index.getObjects().entrySet().size(); + int tot = index.getObjects().size(); for (Map.Entry entry : index.getObjects().entrySet()) { Path target = virtualRoot.resolve(entry.getKey()); Path original = getAssetObject(version, assetsDir, entry.getValue()); @@ -512,7 +512,7 @@ public class DefaultGameRepository implements GameRepository { if (!hasVersion(version)) throw new VersionNotFoundException(version); File file = getModpackConfiguration(version); if (!file.exists()) return null; - return JsonUtils.GSON.fromJson(Files.readString(file.toPath()), ModpackConfiguration.class); + return JsonUtils.fromJsonFile(file.toPath(), ModpackConfiguration.class); } public boolean isModpack(String version) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java index 2aea03a3b..ab23d89a2 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java @@ -75,7 +75,9 @@ public final class MinecraftInstanceTask extends Task } ModpackConfiguration configuration = new ModpackConfiguration<>(manifest, type, name, version, overrides); - FileUtils.writeText(jsonFile, JsonUtils.GSON.toJson(configuration)); + Path jsonPath = jsonFile.toPath(); + Files.createDirectories(jsonPath.getParent()); + JsonUtils.writeToJsonFile(jsonPath, configuration); setResult(configuration); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseCompletionTask.java index 3358a06d1..3f0ebbc94 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseCompletionTask.java @@ -27,12 +27,10 @@ import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.file.Files; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -88,7 +86,7 @@ public final class CurseCompletionTask extends Task { try { File manifestFile = new File(repository.getVersionRoot(version), "manifest.json"); if (manifestFile.exists()) - this.manifest = JsonUtils.GSON.fromJson(Files.readString(manifestFile.toPath()), CurseManifest.class); + this.manifest = JsonUtils.fromJsonFile(manifestFile.toPath(), CurseManifest.class); } catch (Exception e) { LOG.warning("Unable to read CurseForge modpack manifest.json", e); } @@ -137,7 +135,7 @@ public final class CurseCompletionTask extends Task { } }) .collect(Collectors.toList())); - FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(newManifest)); + JsonUtils.writeToJsonFile(root.toPath().resolve("manifest.json"), newManifest); File versionRoot = repository.getVersionRoot(modManager.getVersion()); File resourcePacksRoot = new File(versionRoot, "resourcepacks"), shaderPacksRoot = new File(versionRoot, "shaderpacks"); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java index 7ddb25df1..7c5e4cee0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java @@ -25,11 +25,11 @@ import org.jackhuang.hmcl.mod.*; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -60,7 +60,6 @@ public final class CurseInstallTask extends Task { * @param zipFile the CurseForge modpack file. * @param manifest The manifest content of given CurseForge modpack. * @param name the new version name - * @see CurseManifest#readCurseForgeModpackManifest */ public CurseInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, CurseManifest manifest, String name) { this.dependencyManager = dependencyManager; @@ -99,7 +98,7 @@ public final class CurseInstallTask extends Task { ModpackConfiguration config = null; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(CurseManifest.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(CurseManifest.class)); if (!CurseModpackProvider.INSTANCE.getName().equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a Curse modpack. Cannot update this version."); @@ -137,7 +136,8 @@ public final class CurseInstallTask extends Task { } } - File root = repository.getVersionRoot(name); - FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(manifest)); + Path root = repository.getVersionRoot(name).toPath(); + Files.createDirectories(root); + JsonUtils.writeToJsonFile(root.resolve("manifest.json"), manifest); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackCompletionTask.java index a11697797..c3057cc5e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackCompletionTask.java @@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.*; import org.jackhuang.hmcl.util.DigestUtils; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -113,6 +112,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask { } Path rootPath = repository.getVersionRoot(version).toPath(); + Files.createDirectories(rootPath); Map localFiles = manifest.getFiles().stream().collect(Collectors.toMap(Function.identity(), Function.identity())); @@ -173,15 +173,15 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask { manifest = remoteManifest.setFiles(newFiles); return executor.all(tasks.stream().filter(Objects::nonNull).collect(Collectors.toList())); })).thenAcceptAsync(wrapConsumer(unused1 -> { - File manifestFile = repository.getModpackConfiguration(version); - FileUtils.writeText(manifestFile, JsonUtils.GSON.toJson( + Path manifestFile = repository.getModpackConfiguration(version).toPath(); + JsonUtils.writeToJsonFile(manifestFile, new ModpackConfiguration<>(manifest, this.configuration.getType(), this.manifest.getName(), this.manifest.getVersion(), this.manifest.getFiles().stream() .flatMap(file -> file instanceof McbbsModpackManifest.AddonFile ? Stream.of((McbbsModpackManifest.AddonFile) file) : Stream.empty()) .map(file -> new ModpackConfiguration.FileInformation(file.getPath(), file.getHash())) - .collect(Collectors.toList())))); + .collect(Collectors.toList()))); }))); }).thenComposeAsync(unused -> { AtomicBoolean allNameKnown = new AtomicBoolean(true); @@ -240,7 +240,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask { manifest = newManifest; configuration = configuration.setManifest(newManifest); - FileUtils.writeText(configurationFile, JsonUtils.GSON.toJson(configuration)); + JsonUtils.writeToJsonFile(configurationFile.toPath(), configuration); for (McbbsModpackManifest.File file : newManifest.getFiles()) if (file instanceof McbbsModpackManifest.CurseFile) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackLocalInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackLocalInstallTask.java index 8df6ae49b..70d51a976 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackLocalInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackLocalInstallTask.java @@ -31,7 +31,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -79,7 +78,7 @@ public class McbbsModpackLocalInstallTask extends Task { ModpackConfiguration config = null; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(McbbsModpackManifest.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(McbbsModpackManifest.class)); if (!McbbsModpackProvider.INSTANCE.getName().equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a Mcbbs modpack. Cannot update this version."); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackRemoteInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackRemoteInstallTask.java index 369d35687..491316c4e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackRemoteInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/mcbbs/McbbsModpackRemoteInstallTask.java @@ -27,7 +27,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -62,10 +61,10 @@ public class McbbsModpackRemoteInstallTask extends Task { repository.removeVersionFromDisk(name); }); - ModpackConfiguration config = null; + ModpackConfiguration config; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(McbbsModpackManifest.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(McbbsModpackManifest.class)); if (!MODPACK_TYPE.equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a Mcbbs modpack. Cannot update this version."); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modinfo/ForgeOldModMetadata.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modinfo/ForgeOldModMetadata.java index 9d916f182..bcce56fd7 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modinfo/ForgeOldModMetadata.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modinfo/ForgeOldModMetadata.java @@ -125,7 +125,7 @@ public final class ForgeOldModMetadata { Path mcmod = fs.getPath("mcmod.info"); if (Files.notExists(mcmod)) throw new IOException("File " + modFile + " is not a Forge mod."); - List modList = JsonUtils.GSON.fromJson(Files.readString(mcmod), listTypeOf(ForgeOldModMetadata.class)); + List modList = JsonUtils.fromJsonFile(mcmod, listTypeOf(ForgeOldModMetadata.class)); if (modList == null || modList.isEmpty()) throw new IOException("Mod " + modFile + " `mcmod.info` is malformed.."); ForgeOldModMetadata metadata = modList.get(0); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthCompletionTask.java index cf05a9b79..950218953 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthCompletionTask.java @@ -26,7 +26,6 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.FileUtils; -import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Files; @@ -78,9 +77,9 @@ public class ModrinthCompletionTask extends Task { if (manifest == null) try { - File manifestFile = new File(repository.getVersionRoot(version), "modrinth.index.json"); - if (manifestFile.exists()) - this.manifest = JsonUtils.GSON.fromJson(Files.readString(manifestFile.toPath()), ModrinthManifest.class); + Path manifestFile = repository.getVersionRoot(version).toPath().resolve("modrinth.index.json"); + if (Files.exists(manifestFile)) + this.manifest = JsonUtils.fromJsonFile(manifestFile, ModrinthManifest.class); } catch (Exception e) { LOG.warning("Unable to read Modrinth modpack manifest.json", e); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthInstallTask.java index 48d9a1059..ce406f4f2 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthInstallTask.java @@ -24,7 +24,6 @@ import org.jackhuang.hmcl.game.DefaultGameRepository; import org.jackhuang.hmcl.mod.*; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.io.IOException; @@ -93,7 +92,7 @@ public class ModrinthInstallTask extends Task { ModpackConfiguration config = null; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(ModrinthManifest.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(ModrinthManifest.class)); if (!ModrinthModpackProvider.INSTANCE.getName().equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a Modrinth modpack. Cannot update this version."); @@ -132,7 +131,8 @@ public class ModrinthInstallTask extends Task { } } - File root = repository.getVersionRoot(name); - FileUtils.writeText(new File(root, "modrinth.index.json"), JsonUtils.GSON.toJson(manifest)); + Path root = repository.getVersionRoot(name).toPath(); + Files.createDirectories(root); + JsonUtils.writeToJsonFile(root.resolve("modrinth.index.json"), manifest); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCModpackInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCModpackInstallTask.java index 7bb8908f4..de756c11a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCModpackInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/multimc/MultiMCModpackInstallTask.java @@ -110,7 +110,7 @@ public final class MultiMCModpackInstallTask extends Task config = null; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(MultiMCInstanceConfiguration.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(MultiMCInstanceConfiguration.class)); if (!MultiMCModpackProvider.INSTANCE.getName().equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a MultiMC modpack. Cannot update this version."); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackCompletionTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackCompletionTask.java index 7c26d2b2c..c07a14317 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackCompletionTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackCompletionTask.java @@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.DigestUtils; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.NetworkUtils; import java.io.File; @@ -65,7 +64,7 @@ public class ServerModpackCompletionTask extends Task { try { File manifestFile = repository.getModpackConfiguration(version); if (manifestFile.exists()) { - this.manifest = JsonUtils.GSON.fromJson(Files.readString(manifestFile.toPath()), ModpackConfiguration.typeOf(ServerModpackManifest.class)); + this.manifest = JsonUtils.fromJsonFile(manifestFile.toPath(), ModpackConfiguration.typeOf(ServerModpackManifest.class)); } } catch (Exception e) { LOG.warning("Unable to read Server modpack manifest.json", e); @@ -179,7 +178,8 @@ public class ServerModpackCompletionTask extends Task { @Override public void postExecute() throws Exception { if (manifest == null || StringUtils.isBlank(manifest.getManifest().getFileApi())) return; - File manifestFile = repository.getModpackConfiguration(version); - FileUtils.writeText(manifestFile, JsonUtils.GSON.toJson(new ModpackConfiguration<>(remoteManifest, this.manifest.getType(), this.manifest.getName(), this.manifest.getVersion(), remoteManifest.getFiles()))); + Path manifestFile = repository.getModpackConfiguration(version).toPath(); + Files.createDirectories(manifestFile.getParent()); + JsonUtils.writeToJsonFile(manifestFile, new ModpackConfiguration<>(remoteManifest, this.manifest.getType(), this.manifest.getName(), this.manifest.getVersion(), remoteManifest.getFiles())); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackLocalInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackLocalInstallTask.java index 6fe826287..e49a6c9c5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackLocalInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackLocalInstallTask.java @@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -71,7 +70,7 @@ public class ServerModpackLocalInstallTask extends Task { ModpackConfiguration config = null; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(ServerModpackManifest.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(ServerModpackManifest.class)); if (!ServerModpackProvider.INSTANCE.getName().equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a Server modpack. Cannot update this version."); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackRemoteInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackRemoteInstallTask.java index 893312b59..9282d5768 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackRemoteInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/server/ServerModpackRemoteInstallTask.java @@ -27,7 +27,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -65,7 +64,7 @@ public class ServerModpackRemoteInstallTask extends Task { ModpackConfiguration config; try { if (json.exists()) { - config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(ServerModpackManifest.class)); + config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(ServerModpackManifest.class)); if (!MODPACK_TYPE.equals(config.getType())) throw new IllegalArgumentException("Version " + name + " is not a Server modpack. Cannot update this version."); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java index 75a1fad2c..01da58ce7 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.util; import com.google.gson.JsonParseException; import com.google.gson.annotations.SerializedName; import org.jackhuang.hmcl.util.function.ExceptionalSupplier; +import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.FileUtils; import java.io.FileNotFoundException; @@ -44,7 +45,9 @@ import java.util.function.BiFunction; import java.util.stream.Stream; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.jackhuang.hmcl.util.gson.JsonUtils.*; +import static org.jackhuang.hmcl.util.gson.JsonUtils.fromMaybeMalformedJson; +import static org.jackhuang.hmcl.util.gson.JsonUtils.fromNonNullJson; +import static org.jackhuang.hmcl.util.gson.JsonUtils.mapTypeOf; import static org.jackhuang.hmcl.util.logging.Logger.LOG; public class CacheRepository { @@ -67,7 +70,7 @@ public class CacheRepository { } if (Files.isRegularFile(indexFile)) { - ETagIndex raw = GSON.fromJson(Files.readString(indexFile), ETagIndex.class); + ETagIndex raw = JsonUtils.fromJsonFile(indexFile, ETagIndex.class); if (raw == null) index = new HashMap<>(); else @@ -289,7 +292,7 @@ public class CacheRepository { ETagIndex indexOnDisk = fromMaybeMalformedJson(new String(Channels.newInputStream(channel).readAllBytes(), UTF_8), ETagIndex.class); Map newIndex = joinETagIndexes(indexOnDisk == null ? null : indexOnDisk.eTag, index.values()); channel.truncate(0); - ByteBuffer writeTo = ByteBuffer.wrap(GSON.toJson(new ETagIndex(newIndex.values())).getBytes(UTF_8)); + ByteBuffer writeTo = ByteBuffer.wrap(JsonUtils.GSON.toJson(new ETagIndex(newIndex.values())).getBytes(UTF_8)); while (writeTo.hasRemaining()) { if (channel.write(writeTo) == 0) { throw new IOException("No value is written"); @@ -427,7 +430,7 @@ public class CacheRepository { indexOnDisk.putAll(storage); channel.truncate(0); - ByteBuffer writeTo = ByteBuffer.wrap(GSON.toJson(storage).getBytes(UTF_8)); + ByteBuffer writeTo = ByteBuffer.wrap(JsonUtils.GSON.toJson(storage).getBytes(UTF_8)); while (writeTo.hasRemaining()) { if (channel.write(writeTo) == 0) { throw new IOException("No value is written"); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/JsonUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/JsonUtils.java index bfd07080a..be0f51e96 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/JsonUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/JsonUtils.java @@ -28,6 +28,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.time.Instant; import java.util.List; import java.util.Map; @@ -66,6 +68,16 @@ public final class JsonUtils { return (TypeToken>) TypeToken.getParameterized(Map.class, keyType, valueType.getType()); } + public static T fromJsonFile(Path file, Class classOfT) throws IOException { + return fromJsonFile(file, TypeToken.get(classOfT)); + } + + public static T fromJsonFile(Path file, TypeToken type) throws IOException { + try (var reader = Files.newBufferedReader(file)) { + return GSON.fromJson(reader, type.getType()); + } + } + public static T fromJsonFully(InputStream json, Class classOfT) throws IOException, JsonParseException { try (InputStreamReader reader = new InputStreamReader(json, StandardCharsets.UTF_8)) { return GSON.fromJson(reader, classOfT); @@ -126,6 +138,12 @@ public final class JsonUtils { } } + public static void writeToJsonFile(Path file, Object value) throws IOException { + try (var writer = Files.newBufferedWriter(file)) { + GSON.toJson(value, writer); + } + } + public static GsonBuilder defaultGsonBuilder() { return new GsonBuilder() .enableComplexMapKeySerialization()