diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java index 6ab9febd4..422033731 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -393,8 +393,8 @@ public final class Config implements Cloneable, Observable { return x; } - public void setX(double height) { - this.x.set(height); + public void setX(double x) { + this.x.set(x); } public double getY() { @@ -405,8 +405,8 @@ public final class Config implements Cloneable, Observable { return y; } - public void setY(double height) { - this.y.set(height); + public void setY(double y) { + this.y.set(y); } public double getWidth() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java index be202785f..1a034979c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java @@ -18,16 +18,11 @@ package org.jackhuang.hmcl.setting; import com.google.gson.Gson; -import org.jackhuang.hmcl.ui.Controllers; -import org.jackhuang.hmcl.util.Lang; -import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.StringUtils; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; import java.util.logging.Level; import static org.jackhuang.hmcl.util.Lang.tryCast; @@ -46,94 +41,66 @@ final class ConfigUpgrader { * @param rawContent raw json content of the config settings without modification */ static void upgradeConfig(Config deserialized, String rawContent) { - if (deserialized.getConfigVersion() == CURRENT_VERSION) { + int configVersion = deserialized.getConfigVersion(); + + if (configVersion == CURRENT_VERSION) { return; } - int configVersion = deserialized.getConfigVersion(); if (configVersion > CURRENT_VERSION) { LOG.log(Level.WARNING, String.format("Current HMCL only support the configuration version up to %d. However, the version now is %d.", CURRENT_VERSION, configVersion)); + deserialized.setConfigVersion(CURRENT_VERSION); return; } LOG.log(Level.INFO, String.format("Updating configuration from %d to %d.", configVersion, CURRENT_VERSION)); - Map unmodifiableRawJson = Collections.unmodifiableMap(new Gson().>fromJson(rawContent, Map.class)); - for (Map.Entry>> dfu : collectDFU()) { - if (configVersion < dfu.getKey()) { - dfu.getValue().accept(deserialized, unmodifiableRawJson); - configVersion = dfu.getKey(); + Map rawJson = Collections.unmodifiableMap(new Gson().>fromJson(rawContent, Map.class)); + + if (configVersion < 1) { + // Upgrade configuration of HMCL 2.x: Convert OfflineAccounts whose stored uuid is important. + tryCast(rawJson.get("auth"), Map.class).ifPresent(auth -> { + tryCast(auth.get("offline"), Map.class).ifPresent(offline -> { + String selected = rawJson.containsKey("selectedAccount") ? null + : tryCast(offline.get("IAuthenticator_UserName"), String.class).orElse(null); + + tryCast(offline.get("uuidMap"), Map.class).ifPresent(uuidMap -> { + ((Map) uuidMap).forEach((key, value) -> { + Map storage = new HashMap<>(); + storage.put("type", "offline"); + storage.put("username", key); + storage.put("uuid", value); + if (key.equals(selected)) { + storage.put("selected", true); + } + deserialized.getAccountStorages().add(storage); + }); + }); + }); + }); + + // Upgrade configuration of HMCL earlier than 3.1.70 + if (!rawJson.containsKey("commonDirType")) + deserialized.setCommonDirType(deserialized.getCommonDirectory().equals(Settings.getDefaultCommonDirectory()) ? EnumCommonDirectory.DEFAULT : EnumCommonDirectory.CUSTOM); + if (!rawJson.containsKey("backgroundType")) + deserialized.setBackgroundImageType(StringUtils.isNotBlank(deserialized.getBackgroundImage()) ? EnumBackgroundImage.CUSTOM : EnumBackgroundImage.DEFAULT); + if (!rawJson.containsKey("hasProxy")) + deserialized.setHasProxy(StringUtils.isNotBlank(deserialized.getProxyHost())); + if (!rawJson.containsKey("hasProxyAuth")) + deserialized.setHasProxyAuth(StringUtils.isNotBlank(deserialized.getProxyUser())); + + if (!rawJson.containsKey("downloadType")) { + tryCast(rawJson.get("downloadtype"), Number.class) + .map(Number::intValue) + .ifPresent(id -> { + if (id == 0) { + deserialized.setDownloadType("mojang"); + } else if (id == 1) { + deserialized.setDownloadType("bmclapi"); + } + }); } } deserialized.setConfigVersion(CURRENT_VERSION); } - - /** - *

Initialize the dfu of HMCL. Feel free to use lambda as all the lambda here would not be initialized unless HMCL needs to update the configuration. - * For each item in this list, it should be a Map.Entry.

- * - *

The key should be a version number. All the configuration with a version number which is less than the specific one will be applied to this upgrader.

- *

The value should be the upgrader. The configuration which is waited to being processed, and the raw unmodifiable value of the json from the configuration file.

- *

The return value should a target version number of this item.

- * - *

The last item must return CURRENT_VERSION, as the config file should always being updated to the latest version.

- */ - private static List>>> collectDFU() { - List>>> dfu = Lang.immutableListOf( - Pair.pair(1, (deserialized, rawJson) -> { - // Upgrade configuration of HMCL 2.x: Convert OfflineAccounts whose stored uuid is important. - tryCast(rawJson.get("auth"), Map.class).ifPresent(auth -> { - tryCast(auth.get("offline"), Map.class).ifPresent(offline -> { - String selected = rawJson.containsKey("selectedAccount") ? null - : tryCast(offline.get("IAuthenticator_UserName"), String.class).orElse(null); - - tryCast(offline.get("uuidMap"), Map.class).ifPresent(uuidMap -> { - ((Map) uuidMap).forEach((key, value) -> { - Map storage = new HashMap<>(); - storage.put("type", "offline"); - storage.put("username", key); - storage.put("uuid", value); - if (key.equals(selected)) { - storage.put("selected", true); - } - deserialized.getAccountStorages().add(storage); - }); - }); - }); - }); - - // Upgrade configuration of HMCL earlier than 3.1.70 - if (!rawJson.containsKey("commonDirType")) - deserialized.setCommonDirType(deserialized.getCommonDirectory().equals(Settings.getDefaultCommonDirectory()) ? EnumCommonDirectory.DEFAULT : EnumCommonDirectory.CUSTOM); - if (!rawJson.containsKey("backgroundType")) - deserialized.setBackgroundImageType(StringUtils.isNotBlank(deserialized.getBackgroundImage()) ? EnumBackgroundImage.CUSTOM : EnumBackgroundImage.DEFAULT); - if (!rawJson.containsKey("hasProxy")) - deserialized.setHasProxy(StringUtils.isNotBlank(deserialized.getProxyHost())); - if (!rawJson.containsKey("hasProxyAuth")) - deserialized.setHasProxyAuth(StringUtils.isNotBlank(deserialized.getProxyUser())); - - if (!rawJson.containsKey("downloadType")) { - tryCast(rawJson.get("downloadtype"), Number.class) - .map(Number::intValue) - .ifPresent(id -> { - if (id == 0) { - deserialized.setDownloadType("mojang"); - } else if (id == 1) { - deserialized.setDownloadType("bmclapi"); - } - }); - } - }), - Pair.pair(2, (deserialized, rawJson) -> { - deserialized.setX(0.5D - deserialized.getWidth() / Controllers.SCREEN.getBounds().getWidth() / 2); - deserialized.setY(0.5D - deserialized.getHeight() / Controllers.SCREEN.getBounds().getHeight() / 2); - }) - ); - - if (dfu.get(dfu.size() - 1).getKey() != CURRENT_VERSION) { - throw new IllegalStateException("The last dfu must adapt all the config version below CURRENT_VERSION"); - } - - return dfu; - } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index acedb629c..5a4fe371d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -37,10 +37,7 @@ import javafx.stage.StageStyle; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.game.ModpackHelper; -import org.jackhuang.hmcl.setting.Accounts; -import org.jackhuang.hmcl.setting.EnumCommonDirectory; -import org.jackhuang.hmcl.setting.Profiles; -import org.jackhuang.hmcl.setting.Theme; +import org.jackhuang.hmcl.setting.*; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.ui.account.AccountListPage; @@ -68,6 +65,8 @@ import static org.jackhuang.hmcl.ui.FXUtils.newBuiltinImage; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class Controllers { + public static final int MIN_WIDTH = 800 + 2 + 16; // bg width + border width*2 + shadow width*2 + public static final int MIN_HEIGHT = 450 + 2 + 40 + 16; // bg height + border width*2 + toolbar height + shadow width*2 public static final Screen SCREEN = Screen.getPrimary(); private static InvalidationListener stageSizeChangeListener; private static DoubleProperty stageX = new SimpleDoubleProperty(); @@ -205,35 +204,37 @@ public final class Controllers { WeakInvalidationListener weakListener = new WeakInvalidationListener(stageSizeChangeListener); - double initHeight = config().getHeight(); - double initWidth = config().getWidth(); - double initX = config().getX() * SCREEN.getBounds().getWidth(); - double initY = config().getY() * SCREEN.getBounds().getHeight(); + double initWidth = Math.max(MIN_WIDTH, config().getWidth()); + double initHeight = Math.max(MIN_HEIGHT, config().getHeight()); { + double initX = config().getX() * SCREEN.getBounds().getWidth(); + double initY = config().getY() * SCREEN.getBounds().getHeight(); + boolean invalid = true; double border = 20D; for (Screen screen : Screen.getScreens()) { Rectangle2D bound = screen.getBounds(); - if (bound.getMinX() + border <= initX + initWidth && initX <= bound.getMaxX() - border && bound.getMinY() + border <= initY + initHeight && initY <= bound.getMaxY() - border) { + if (bound.getMinX() + border <= initX + initWidth && initX <= bound.getMaxX() - border && bound.getMinY() + border <= initY && initY <= bound.getMaxY() - border) { invalid = false; break; } } if (invalid) { - initX = (0.5D - initWidth / Controllers.SCREEN.getBounds().getWidth() / 2) * SCREEN.getBounds().getWidth(); - initY = (0.5D - initHeight / Controllers.SCREEN.getBounds().getHeight() / 2) * SCREEN.getBounds().getHeight(); + initX = (0.5D - initWidth / SCREEN.getBounds().getWidth() / 2) * SCREEN.getBounds().getWidth(); + initY = (0.5D - initHeight / SCREEN.getBounds().getHeight() / 2) * SCREEN.getBounds().getHeight(); } + + stage.setX(initX); + stage.setY(initY); + stageX.set(initX); + stageY.set(initY); } - stage.setX(initX); - stage.setY(initY); stage.setHeight(initHeight); stage.setWidth(initWidth); - stageX.set(initX); - stageY.set(initY); stageHeight.set(initHeight); stageWidth.set(initWidth); stage.xProperty().addListener(weakListener); @@ -255,8 +256,8 @@ public final class Controllers { scene = new Scene(decorator.getDecorator()); scene.setFill(Color.TRANSPARENT); - stage.setMinHeight(450 + 2 + 40 + 16); // bg height + border width*2 + toolbar height + shadow width*2 - stage.setMinWidth(800 + 2 + 16); // bg width + border width*2 + shadow width*2 + stage.setMinWidth(MIN_WIDTH); + stage.setMinHeight(MIN_HEIGHT); decorator.getDecorator().prefWidthProperty().bind(scene.widthProperty()); decorator.getDecorator().prefHeightProperty().bind(scene.heightProperty()); scene.getStylesheets().setAll(Theme.getTheme().getStylesheets(config().getLauncherFontFamily()));