diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java index 43d1b3058..a63361608 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java @@ -27,7 +27,9 @@ import org.jackhuang.hmcl.Launcher; import java.io.File; import java.util.HashSet; +import java.util.stream.Collectors; +import static java.util.stream.Collectors.toList; import static javafx.collections.FXCollections.observableArrayList; import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating; @@ -95,8 +97,7 @@ public final class Profiles { private static boolean initialized = false; static { - profiles.addListener(onInvalidating(ConfigHolder::markConfigDirty)); - + profiles.addListener(onInvalidating(Profiles::updateProfileStorages)); profiles.addListener(onInvalidating(Profiles::checkProfiles)); selectedProfile.addListener((a, b, newValue) -> { @@ -105,6 +106,16 @@ public final class Profiles { }); } + private static void updateProfileStorages() { + // don't update the underlying storage before data loading is completed + // otherwise it might cause data loss + if (!initialized) + return; + // update storage + config().getConfigurations().clear(); + config().getConfigurations().putAll(profiles.stream().collect(Collectors.toMap(Profile::getName, it -> it))); + } + /** * Called when it's ready to load profiles from {@link ConfigHolder#config()}. */ diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java deleted file mode 100644 index bc8eedc11..000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.jackhuang.hmcl.game; - -import org.jackhuang.hmcl.util.CompressingUtils; -import org.jackhuang.hmcl.util.FileUtils; -import org.jackhuang.hmcl.util.Unzipper; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; - -public class World { - - private final Path file; - private final String name; - - public World(Path file) throws IOException { - this.file = file; - - if (Files.isDirectory(file)) - name = loadFromDirectory(); - else if (Files.isRegularFile(file)) - name = loadFromZip(); - else - throw new IOException("Path " + file + " cannot be recognized as a Minecraft world"); - } - - private String loadFromDirectory() { - return FileUtils.getName(file); - } - - private String loadFromZip() throws IOException { - try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(file)) { - Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() - .orElseThrow(() -> new IOException("Not a valid world zip file")); - - Path levelDat = root.resolve("level.dat"); - if (!Files.exists(levelDat)) - throw new FileNotFoundException("Not a valid world zip file since level.dat cannot be found."); - - return FileUtils.getName(root); - } - } - - public void install(Path savesDir) throws IOException { - Path worldDir = savesDir.resolve(name); - if (Files.isDirectory(worldDir)) { - throw new FileAlreadyExistsException("World already exists"); - } - - if (Files.isRegularFile(file)) { - new Unzipper(file, savesDir) - .setSubDirectory("/" + name + "/") - .unzip(); - } else if (Files.isDirectory(file)) { - FileUtils.copyDirectory(file, worldDir); - } - } -}