From 53cad0e56a9d564acb4ea7d201d94e105f458d48 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 20:09:19 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E5=9C=A8=E5=9B=A0=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E8=80=8C=E7=A7=BB=E9=99=A4=E8=B4=A6=E6=88=B7?= =?UTF-8?q?=E6=97=B6=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index 713ad792e..bf76b7ff5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -52,6 +52,7 @@ import java.util.logging.Level; import java.util.stream.Collectors; import static org.jackhuang.hmcl.util.Lang.tryCast; +import static org.jackhuang.hmcl.util.Logging.LOG; public class Settings { public static final Gson GSON = new GsonBuilder() @@ -84,7 +85,7 @@ public class Settings { Map settings = iterator.next(); AccountFactory factory = Accounts.ACCOUNT_FACTORY.get(tryCast(settings.get("type"), String.class).orElse("")); if (factory == null) { - // unrecognized account type, so remove it. + LOG.warning("Unrecognized account type, removing: " + settings); iterator.remove(); continue; } @@ -93,7 +94,7 @@ public class Settings { try { account = factory.fromStorage(settings, getProxy()); } catch (Exception e) { - // storage is malformed, delete. + LOG.log(Level.WARNING, "Malformed account storage, removing: " + settings, e); iterator.remove(); continue; } From 593159f4a688fcbc9c58b043469739689fc24e9e Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 18:15:30 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E5=B0=86DEFAULT=5FICON=E7=A7=BB=E8=87=B3?= =?UTF-8?q?Constants,=20=E5=B9=B6=E4=BD=BF=E7=94=A8=E6=87=92=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当类初始化时, JavaFX可能还未启动, 这将使图像加载失败 --- .../main/java/org/jackhuang/hmcl/ui/AddAccountPane.java | 9 +++++---- HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java | 3 --- .../org/jackhuang/hmcl/ui/VersionSettingsController.java | 2 +- .../src/main/java/org/jackhuang/hmcl/util/Constants.java | 8 ++++++++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java index 91e711129..49cbfb7d0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java @@ -46,6 +46,7 @@ import org.jackhuang.hmcl.ui.animation.TransitionHandler; import org.jackhuang.hmcl.ui.construct.AdvancedListBox; import org.jackhuang.hmcl.ui.construct.IconedItem; import org.jackhuang.hmcl.ui.construct.Validator; +import org.jackhuang.hmcl.util.Constants; import org.jackhuang.hmcl.util.Logging; import java.util.Collection; @@ -224,13 +225,13 @@ public class AddAccountPane extends StackPane { image = AccountHelper.getSkinImmediately(yggdrasilAccount, profile, 4, Settings.INSTANCE.getProxy()); } catch (Exception e) { Logging.LOG.log(Level.WARNING, "Failed to get skin for " + profile.getName(), e); - image = FXUtils.DEFAULT_ICON; + image = null; } ImageView portraitView = new ImageView(); portraitView.setSmooth(false); - if (image == FXUtils.DEFAULT_ICON) - portraitView.setImage(FXUtils.DEFAULT_ICON); - else { + if (image == null) { + portraitView.setImage(Constants.DEFAULT_ICON.get()); + } else { portraitView.setImage(image); portraitView.setViewport(AccountHelper.getViewport(4)); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index ef3659ab4..ef5b377af 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -34,7 +34,6 @@ import javafx.scene.control.ListView; import javafx.scene.control.ScrollBar; import javafx.scene.control.ScrollPane; import javafx.scene.control.Tooltip; -import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.input.ScrollEvent; @@ -402,8 +401,6 @@ public final class FXUtils { } } - public static final Image DEFAULT_ICON = new Image("/assets/img/icon.png"); - public static final Interpolator SINE = new Interpolator() { @Override protected double curve(double t) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java index 1a70f0853..162d30e5c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java @@ -264,7 +264,7 @@ public final class VersionSettingsController { if (iconFile.exists()) iconPickerItem.setImage(new Image("file:" + iconFile.getAbsolutePath())); else - iconPickerItem.setImage(FXUtils.DEFAULT_ICON); + iconPickerItem.setImage(Constants.DEFAULT_ICON.get()); FXUtils.limitSize(iconPickerItem.getImageView(), 32, 32); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Constants.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Constants.java index 76f684b54..8337473dd 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Constants.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Constants.java @@ -19,6 +19,11 @@ package org.jackhuang.hmcl.util; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + +import javafx.beans.binding.Bindings; +import javafx.beans.binding.ObjectBinding; +import javafx.scene.image.Image; + import org.jackhuang.hmcl.game.Argument; import org.jackhuang.hmcl.game.Library; import org.jackhuang.hmcl.game.RuledArgument; @@ -65,6 +70,9 @@ public final class Constants { javafx.application.Platform.runLater(s); }; + // lazy loading + public static final ObjectBinding DEFAULT_ICON = Bindings.createObjectBinding(() -> new Image("/assets/img/icon.png")); + public static final Gson GSON = new GsonBuilder() .enableComplexMapKeySerialization() .setPrettyPrinting() From 92e5eecaf268cb7396b2272654059427af8bd27c Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 20:30:14 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E5=B0=86Settings=E4=B8=ADDEFAULT=5FPROFI?= =?UTF-8?q?LE,=20HOME=5FPROFILE=E5=AD=97=E6=AE=B5=E7=A7=BB=E8=87=B3Profile?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/jackhuang/hmcl/setting/Profiles.java | 8 ++++++-- .../main/java/org/jackhuang/hmcl/setting/Settings.java | 7 ++----- 2 files changed, 8 insertions(+), 7 deletions(-) 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 eb22f9607..5582bb567 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java @@ -20,14 +20,18 @@ package org.jackhuang.hmcl.setting; import org.jackhuang.hmcl.Launcher; public final class Profiles { + + public static final String DEFAULT_PROFILE = "Default"; + public static final String HOME_PROFILE = "Home"; + private Profiles() { } public static String getProfileDisplayName(Profile profile) { switch (profile.getName()) { - case Settings.DEFAULT_PROFILE: + case Profiles.DEFAULT_PROFILE: return Launcher.i18n("profile.default"); - case Settings.HOME_PROFILE: + case Profiles.HOME_PROFILE: return Launcher.i18n("profile.home"); default: return profile.getName(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index bf76b7ff5..0f666bcae 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -66,9 +66,6 @@ public class Settings { .setPrettyPrinting() .create(); - public static final String DEFAULT_PROFILE = "Default"; - public static final String HOME_PROFILE = "Home"; - public static final String SETTINGS_FILE_NAME = "hmcl.json"; public static final File SETTINGS_FILE = new File(SETTINGS_FILE_NAME).getAbsoluteFile(); @@ -562,8 +559,8 @@ public class Settings { private void checkProfileMap() { if (getProfileMap().isEmpty()) { - getProfileMap().put(DEFAULT_PROFILE, new Profile(DEFAULT_PROFILE)); - getProfileMap().put(HOME_PROFILE, new Profile(HOME_PROFILE, Launcher.MINECRAFT_DIRECTORY)); + getProfileMap().put(Profiles.DEFAULT_PROFILE, new Profile(Profiles.DEFAULT_PROFILE)); + getProfileMap().put(Profiles.HOME_PROFILE, new Profile(Profiles.HOME_PROFILE, Launcher.MINECRAFT_DIRECTORY)); } } From bfbc4613b91929c503654f413a6f6e805a7cc5f8 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 19:01:23 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E5=9C=A8=E6=B7=BB=E5=8A=A0authlib-inject?= =?UTF-8?q?or=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=9A=84=E8=BF=87=E7=A8=8B?= =?UTF-8?q?=E4=B8=AD=EF=BC=8C=E4=BC=A0=E9=80=92AuthlibInjectorServerInfo?= =?UTF-8?q?=E8=80=8C=E4=B8=8D=E6=98=AFurl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmcl/ui/AuthlibInjectorServersPage.java | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java index dd5e20352..259635755 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java @@ -47,6 +47,8 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa private final TransitionHandler transitionHandler; + private AuthlibInjectorServerInfo serverBeingAdded; + { FXUtils.loadFXML(this, "/assets/fxml/authlib-injector-servers.fxml"); FXUtils.smoothScrolling(scrollPane); @@ -110,26 +112,28 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private void onAddNext() { - String serverIp = txtServerIp.getText(); + String url = fixInputUrl(txtServerIp.getText()); + progressBar.setVisible(true); addServerPane.setDisable(true); - Task.ofResult("serverName", () -> Accounts.getAuthlibInjectorServerName(serverIp)) - .finalized(Schedulers.javafx(), (variables, isDependentsSucceeded) -> { - progressBar.setVisible(false); - addServerPane.setDisable(false); + Task.of(() -> { + serverBeingAdded = new AuthlibInjectorServerInfo(url, Accounts.getAuthlibInjectorServerName(url)); + }).finalized(Schedulers.javafx(), (variables, isDependentsSucceeded) -> { + progressBar.setVisible(false); + addServerPane.setDisable(false); - if (isDependentsSucceeded) { - lblServerName.setText(variables.get("serverName")); - lblServerIp.setText(txtServerIp.getText()); + if (isDependentsSucceeded) { + lblServerName.setText(serverBeingAdded.getServerName()); + lblServerIp.setText(serverBeingAdded.getServerIp()); - lblServerWarning.setVisible("http".equals(NetworkUtils.toURL(serverIp).getProtocol())); - - transitionHandler.setContent(confirmServerPane, ContainerAnimations.SWIPE_LEFT.getAnimationProducer()); - } else - lblCreationWarning.setText(variables.get("lastException").getLocalizedMessage()); - }).start(); + lblServerWarning.setVisible("http".equals(NetworkUtils.toURL(serverBeingAdded.getServerIp()).getProtocol())); + transitionHandler.setContent(confirmServerPane, ContainerAnimations.SWIPE_LEFT.getAnimationProducer()); + } else { + lblCreationWarning.setText(variables.get("lastException").getLocalizedMessage()); + } + }).start(); } @@ -140,10 +144,7 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private void onAddFinish() { - String ip = txtServerIp.getText(); - if (!ip.endsWith("/")) - ip += "/"; - Settings.INSTANCE.addAuthlibInjectorServerURL(ip); + Settings.INSTANCE.addAuthlibInjectorServerURL(serverBeingAdded.getServerIp()); loading(); dialog.close(); } @@ -160,4 +161,11 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa public void setTitle(String title) { this.title.set(title); } + + private String fixInputUrl(String url) { + if (!url.endsWith("/")) { + url += "/"; + } + return url; + } } From 22732fee6a32d3f51f3d6fdebdc284bf5968fe28 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 19:15:16 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E5=AD=98=E5=82=A8AuthlibInjectorServerIn?= =?UTF-8?q?fo=E5=AF=B9=E8=B1=A1=E8=80=8C=E4=B8=8D=E6=98=AFurl=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jackhuang/hmcl/setting/Config.java | 7 +- .../org/jackhuang/hmcl/setting/Settings.java | 73 +++++++++++++------ .../org/jackhuang/hmcl/ui/AddAccountPane.java | 30 ++------ .../hmcl/ui/AuthlibInjectorServersPage.java | 36 ++++----- .../java/org/jackhuang/hmcl/ui/FXUtils.java | 5 ++ .../AuthlibInjectorServerInfo.java | 15 ++++ 6 files changed, 95 insertions(+), 71 deletions(-) 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 744815f7a..3673fb9ea 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -17,11 +17,12 @@ */ package org.jackhuang.hmcl.setting; -import java.util.HashSet; import java.util.Map; import java.util.TreeMap; import org.jackhuang.hmcl.Launcher; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerInfo; + import com.google.gson.annotations.SerializedName; import javafx.beans.property.BooleanProperty; @@ -35,7 +36,6 @@ import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; -import javafx.collections.ObservableSet; public final class Config implements Cloneable { @@ -99,8 +99,7 @@ public final class Config implements Cloneable { @SerializedName("logLines") public final IntegerProperty logLines = new SimpleIntegerProperty(100); - @SerializedName("authlibInjectorServerURLs") - public final ObservableSet authlibInjectorServerURLs = FXCollections.observableSet(new HashSet<>()); + public final ObservableList authlibInjectorServers = FXCollections.observableArrayList(); @Override public Config clone() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index 0f666bcae..51fa60681 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -19,6 +19,7 @@ package org.jackhuang.hmcl.setting; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + import javafx.beans.property.ObjectProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; @@ -35,6 +36,7 @@ import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.AccountFactory; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerInfo; import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.event.*; import org.jackhuang.hmcl.task.Schedulers; @@ -51,6 +53,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.stream.Collectors; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; +import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating; import static org.jackhuang.hmcl.util.Lang.tryCast; import static org.jackhuang.hmcl.util.Logging.LOG; @@ -71,7 +76,8 @@ public class Settings { public static final Settings INSTANCE = new Settings(); - private final Config SETTINGS = initSettings(); + // TODO: another way to access this property aside from Settings.INSTANCE.SETTINGS + public final Config SETTINGS = initSettings(); private final Map accounts = new ConcurrentHashMap<>(); @@ -99,7 +105,10 @@ public class Settings { accounts.put(Accounts.getAccountId(account), account); } - checkAuthlibInjectorAccounts(); + migrateAuthlibInjectorServers(); + + SETTINGS.authlibInjectorServers.addListener(onInvalidating(this::removeDanglingAuthlibInjectorAccounts)); + checkProfileMap(); save(); @@ -303,30 +312,50 @@ public class Settings { * AUTHLIB INJECTORS * ****************************************/ - public Set getAuthlibInjectorServerURLs() { - return SETTINGS.authlibInjectorServerURLs; + private Set getAuthlibInjectorServerUrls() { + return SETTINGS.authlibInjectorServers.stream() + .map(AuthlibInjectorServerInfo::getServerIp) + .collect(toSet()); } - public void removeAuthlibInjectorServerURL(String serverURL) { - SETTINGS.authlibInjectorServerURLs.remove(serverURL); - - checkAuthlibInjectorAccounts(); - save(); + /** + * The {@code serverBaseURL} specified in {@link AuthlibInjectorAccount} may not have an associated + * {@link AuthlibInjectorServerInfo} in {@link Config#authlibInjectorServers}, + * which usually happens when migrating data from an older version. + * This method adds the missing servers to {@link Config#authlibInjectorServers}. + */ + private void migrateAuthlibInjectorServers() { + Set existentServerUrls = getAuthlibInjectorServerUrls(); + accounts.values().stream() + .filter(AuthlibInjectorAccount.class::isInstance) + .map(it -> ((AuthlibInjectorAccount) it).getServerBaseURL()) + .distinct() + .filter(it -> !existentServerUrls.contains(it)) + .forEach(url -> { + String serverName; + try { + serverName = Accounts.getAuthlibInjectorServerName(url); + Logging.LOG.info("Migrated authlib injector server [" + url + "], name=[" + serverName + "]"); + } catch (Exception e) { + serverName = url; + Logging.LOG.log(Level.WARNING, "Failed to migrate authlib injector server [" + url + "]", e); + } + SETTINGS.authlibInjectorServers.add(new AuthlibInjectorServerInfo(url, serverName)); + }); } - public void addAuthlibInjectorServerURL(String serverURL) { - SETTINGS.authlibInjectorServerURLs.add(serverURL); - save(); - } - - private void checkAuthlibInjectorAccounts() { - for (Account account : getAccounts()) { - if (account instanceof AuthlibInjectorAccount) { - AuthlibInjectorAccount injectorAccount = (AuthlibInjectorAccount) account; - if (!SETTINGS.authlibInjectorServerURLs.contains(injectorAccount.getServerBaseURL())) - deleteAccount(account); - } - } + /** + * After an {@link AuthlibInjectorServerInfo} is removed, the associated accounts should also be removed. + * This method performs a check and removes the dangling accounts. + * Don't call this before {@link #migrateAuthlibInjectorServers()} is called, otherwise old data would be lost. + */ + private void removeDanglingAuthlibInjectorAccounts() { + Set currentServerUrls = getAuthlibInjectorServerUrls(); + accounts.values().stream() + .filter(AuthlibInjectorAccount.class::isInstance) + .filter(it -> !currentServerUrls.contains(((AuthlibInjectorAccount) it).getServerBaseURL())) + .collect(toList()) + .forEach(this::deleteAccount); } /**************************************** diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java index 49cbfb7d0..df51d7378 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java @@ -49,14 +49,13 @@ import org.jackhuang.hmcl.ui.construct.Validator; import org.jackhuang.hmcl.util.Constants; import org.jackhuang.hmcl.util.Logging; -import java.util.Collection; +import static java.util.stream.Collectors.toList; + import java.util.List; import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; import java.util.logging.Level; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class AddAccountPane extends StackPane { @@ -96,10 +95,6 @@ public class AddAccountPane extends StackPane { }); cboType.getSelectionModel().select(0); - // These two lines can eliminate black, don't know why. - cboServers.getItems().setAll(new TwoLineListItem("", "")); - cboServers.getSelectionModel().select(0); - txtPassword.setOnAction(e -> onCreationAccept()); txtUsername.setOnAction(e -> onCreationAccept()); txtUsername.getValidators().add(new Validator(Launcher.i18n("input.email"), str -> !txtPassword.isVisible() || str.contains("@"))); @@ -113,21 +108,12 @@ public class AddAccountPane extends StackPane { } private void loadServers() { - Task.ofResult("list", () -> Settings.INSTANCE.getAuthlibInjectorServerURLs().parallelStream() - .flatMap(serverURL -> { - try { - return Stream.of(new TwoLineListItem(Accounts.getAuthlibInjectorServerName(serverURL), serverURL)); - } catch (Exception e) { - Logging.LOG.log(Level.WARNING, "Authlib-injector server root " + serverURL + " cannot be recognized.", e); - return Stream.empty(); - } - }) - .collect(Collectors.toList())) - .subscribe(Task.of(Schedulers.javafx(), variables -> { - cboServers.getItems().setAll(variables.>get("list")); - if (!cboServers.getItems().isEmpty()) - cboServers.getSelectionModel().select(0); - })); + cboServers.getItems().setAll( + Settings.INSTANCE.SETTINGS.authlibInjectorServers.stream() + .map(server -> new TwoLineListItem(server.getServerName(), server.getServerIp())) + .collect(toList())); + if (!cboServers.getItems().isEmpty()) + cboServers.getSelectionModel().select(0); } private void showSpinner() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java index 259635755..efd058f27 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java @@ -4,7 +4,6 @@ import com.jfoenix.controls.*; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.fxml.FXML; -import javafx.scene.Node; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.layout.StackPane; @@ -18,13 +17,9 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionHandler; import org.jackhuang.hmcl.ui.wizard.DecoratorPage; -import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.NetworkUtils; -import java.util.Collection; -import java.util.logging.Level; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import static java.util.stream.Collectors.toList; public class AuthlibInjectorServersPage extends StackPane implements DecoratorPage { private final StringProperty title = new SimpleStringProperty(this, "title", Launcher.i18n("account.injector.server")); @@ -64,7 +59,7 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa } private void removeServer(AuthlibInjectorServerItem item) { - Settings.INSTANCE.removeAuthlibInjectorServerURL(item.getInfo().getServerIp()); + Settings.INSTANCE.SETTINGS.authlibInjectorServers.remove(item.getInfo()); loading(); } @@ -72,27 +67,20 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa getChildren().remove(contentPane); spinner.setVisible(true); - Task.ofResult("list", () -> Settings.INSTANCE.getAuthlibInjectorServerURLs().parallelStream() - .flatMap(serverURL -> { - try { - return Stream.of(new AuthlibInjectorServerItem(new AuthlibInjectorServerInfo(serverURL, Accounts.getAuthlibInjectorServerName(serverURL)), this::removeServer)); - } catch (Exception e) { - Logging.LOG.log(Level.WARNING, "Authlib-injector server root " + serverURL + " cannot be recognized.", e); - return Stream.empty(); - } - }) - .collect(Collectors.toList())) - .subscribe(Task.of(Schedulers.javafx(), variables -> { - listPane.getChildren().setAll(variables.>get("list")); - loadingCompleted(); - })); + listPane.getChildren().setAll( + Settings.INSTANCE.SETTINGS.authlibInjectorServers.stream() + .map(server -> new AuthlibInjectorServerItem(server, this::removeServer)) + .collect(toList())); + + // TODO: remove spinner + loadingCompleted(); } private void loadingCompleted() { getChildren().add(contentPane); spinner.setVisible(false); - if (Settings.INSTANCE.getAuthlibInjectorServerURLs().isEmpty()) + if (Settings.INSTANCE.SETTINGS.authlibInjectorServers.isEmpty()) onAdd(); } @@ -144,7 +132,9 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private void onAddFinish() { - Settings.INSTANCE.addAuthlibInjectorServerURL(serverBeingAdded.getServerIp()); + if (!Settings.INSTANCE.SETTINGS.authlibInjectorServers.contains(serverBeingAdded)) { + Settings.INSTANCE.SETTINGS.authlibInjectorServers.add(serverBeingAdded); + } loading(); dialog.close(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index ef5b377af..c5acdeaaa 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -23,6 +23,7 @@ import javafx.animation.Interpolator; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Platform; +import javafx.beans.InvalidationListener; import javafx.beans.property.Property; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -67,6 +68,10 @@ public final class FXUtils { } } + public static InvalidationListener onInvalidating(Runnable action) { + return arg -> action.run(); + } + public static void onChange(ObservableValue value, Consumer consumer) { value.addListener((a, b, c) -> consumer.accept(c)); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorServerInfo.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorServerInfo.java index 41b5f7dcb..369fc6f35 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorServerInfo.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorServerInfo.java @@ -33,4 +33,19 @@ public class AuthlibInjectorServerInfo { public String getServerName() { return serverName; } + + @Override + public int hashCode() { + return serverIp.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + if (!(obj instanceof AuthlibInjectorServerInfo)) + return false; + AuthlibInjectorServerInfo another = (AuthlibInjectorServerInfo) obj; + return this.serverIp.equals(another.serverIp); + } } From ba8cdb1b426ab09f8d1e3201de3954d26a9e4ae2 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 19:21:10 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E7=A7=BB=E9=99=A4AuthlibInjectorServersP?= =?UTF-8?q?age=E7=9A=84spinner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmcl/ui/AuthlibInjectorServersPage.java | 26 +++++-------------- .../assets/fxml/authlib-injector-servers.fxml | 1 - 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java index efd058f27..959429291 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java @@ -36,7 +36,6 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private JFXDialogLayout confirmServerPane; @FXML private JFXDialog dialog; @FXML private StackPane contentPane; - @FXML private JFXSpinner spinner; @FXML private JFXProgressBar progressBar; @FXML private JFXButton btnAddNext; @@ -55,33 +54,22 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa txtServerIp.textProperty().addListener((a, b, newValue) -> btnAddNext.setDisable(!txtServerIp.validate())); - loading(); + reload(); } private void removeServer(AuthlibInjectorServerItem item) { Settings.INSTANCE.SETTINGS.authlibInjectorServers.remove(item.getInfo()); - loading(); + reload(); } - private void loading() { - getChildren().remove(contentPane); - spinner.setVisible(true); - + private void reload() { listPane.getChildren().setAll( - Settings.INSTANCE.SETTINGS.authlibInjectorServers.stream() + Settings.INSTANCE.SETTINGS.authlibInjectorServers.stream() .map(server -> new AuthlibInjectorServerItem(server, this::removeServer)) .collect(toList())); - - // TODO: remove spinner - loadingCompleted(); - } - - private void loadingCompleted() { - getChildren().add(contentPane); - spinner.setVisible(false); - - if (Settings.INSTANCE.SETTINGS.authlibInjectorServers.isEmpty()) + if (Settings.INSTANCE.SETTINGS.authlibInjectorServers.isEmpty()) { onAdd(); + } } @FXML @@ -135,7 +123,7 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa if (!Settings.INSTANCE.SETTINGS.authlibInjectorServers.contains(serverBeingAdded)) { Settings.INSTANCE.SETTINGS.authlibInjectorServers.add(serverBeingAdded); } - loading(); + reload(); dialog.close(); } diff --git a/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml b/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml index e37c03188..cac3bee5d 100644 --- a/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml +++ b/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml @@ -8,7 +8,6 @@ - From 10d4084dde6eb2d74cf3ab8f3124a03038881301 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sat, 16 Jun 2018 19:31:23 +0800 Subject: [PATCH 07/14] =?UTF-8?q?AuthlibInjectorServerInfo=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=BAAuthlibInjectorServer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更正其它措辞:ip->url --- .../org/jackhuang/hmcl/setting/Config.java | 4 +-- .../org/jackhuang/hmcl/setting/Settings.java | 10 +++---- .../org/jackhuang/hmcl/ui/AddAccountPane.java | 2 +- .../hmcl/ui/AuthlibInjectorServerItem.java | 16 +++++------ .../hmcl/ui/AuthlibInjectorServersPage.java | 26 ++++++++--------- .../assets/fxml/authlib-injector-servers.fxml | 6 ++-- .../resources/assets/lang/I18N.properties | 2 +- .../assets/lang/I18N_zh_CN.properties | 2 +- ...erInfo.java => AuthlibInjectorServer.java} | 28 +++++++++---------- 9 files changed, 48 insertions(+), 48 deletions(-) rename HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/{AuthlibInjectorServerInfo.java => AuthlibInjectorServer.java} (62%) 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 3673fb9ea..d295404d3 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.TreeMap; import org.jackhuang.hmcl.Launcher; -import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerInfo; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import com.google.gson.annotations.SerializedName; @@ -99,7 +99,7 @@ public final class Config implements Cloneable { @SerializedName("logLines") public final IntegerProperty logLines = new SimpleIntegerProperty(100); - public final ObservableList authlibInjectorServers = FXCollections.observableArrayList(); + public final ObservableList authlibInjectorServers = FXCollections.observableArrayList(); @Override public Config clone() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index 51fa60681..b446ad3e2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -36,7 +36,7 @@ import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.AccountFactory; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount; -import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerInfo; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.event.*; import org.jackhuang.hmcl.task.Schedulers; @@ -314,13 +314,13 @@ public class Settings { private Set getAuthlibInjectorServerUrls() { return SETTINGS.authlibInjectorServers.stream() - .map(AuthlibInjectorServerInfo::getServerIp) + .map(AuthlibInjectorServer::getUrl) .collect(toSet()); } /** * The {@code serverBaseURL} specified in {@link AuthlibInjectorAccount} may not have an associated - * {@link AuthlibInjectorServerInfo} in {@link Config#authlibInjectorServers}, + * {@link AuthlibInjectorServer} in {@link Config#authlibInjectorServers}, * which usually happens when migrating data from an older version. * This method adds the missing servers to {@link Config#authlibInjectorServers}. */ @@ -340,12 +340,12 @@ public class Settings { serverName = url; Logging.LOG.log(Level.WARNING, "Failed to migrate authlib injector server [" + url + "]", e); } - SETTINGS.authlibInjectorServers.add(new AuthlibInjectorServerInfo(url, serverName)); + SETTINGS.authlibInjectorServers.add(new AuthlibInjectorServer(url, serverName)); }); } /** - * After an {@link AuthlibInjectorServerInfo} is removed, the associated accounts should also be removed. + * After an {@link AuthlibInjectorServer} is removed, the associated accounts should also be removed. * This method performs a check and removes the dangling accounts. * Don't call this before {@link #migrateAuthlibInjectorServers()} is called, otherwise old data would be lost. */ diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java index df51d7378..98e9b6e9b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java @@ -110,7 +110,7 @@ public class AddAccountPane extends StackPane { private void loadServers() { cboServers.getItems().setAll( Settings.INSTANCE.SETTINGS.authlibInjectorServers.stream() - .map(server -> new TwoLineListItem(server.getServerName(), server.getServerIp())) + .map(server -> new TwoLineListItem(server.getName(), server.getUrl())) .collect(toList())); if (!cboServers.getItems().isEmpty()) cboServers.getSelectionModel().select(0); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServerItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServerItem.java index 09df2e5fb..f5c874dfc 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServerItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServerItem.java @@ -23,19 +23,19 @@ import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; -import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerInfo; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.setting.Theme; import java.util.function.Consumer; public final class AuthlibInjectorServerItem extends BorderPane { - private final AuthlibInjectorServerInfo info; + private final AuthlibInjectorServer server; private final Label lblServerName = new Label(); private final Label lblServerIp = new Label(); - public AuthlibInjectorServerItem(AuthlibInjectorServerInfo info, Consumer deleteCallback) { - this.info = info; + public AuthlibInjectorServerItem(AuthlibInjectorServer server, Consumer deleteCallback) { + this.server = server; lblServerName.setStyle("-fx-font-size: 15;"); lblServerIp.setStyle("-fx-font-size: 10;"); @@ -54,11 +54,11 @@ public final class AuthlibInjectorServerItem extends BorderPane { setStyle("-fx-background-radius: 2; -fx-background-color: white; -fx-padding: 8;"); JFXDepthManager.setDepth(this, 1); - lblServerName.setText(info.getServerName()); - lblServerIp.setText(info.getServerIp()); + lblServerName.setText(server.getName()); + lblServerIp.setText(server.getUrl()); } - public AuthlibInjectorServerInfo getInfo() { - return info; + public AuthlibInjectorServer getServer() { + return server; } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java index 959429291..23ee6dc05 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java @@ -9,7 +9,7 @@ import javafx.scene.control.ScrollPane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import org.jackhuang.hmcl.Launcher; -import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerInfo; +import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.setting.Accounts; import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.task.Schedulers; @@ -26,12 +26,12 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private ScrollPane scrollPane; @FXML private StackPane addServerContainer; - @FXML private Label lblServerIp; + @FXML private Label lblServerUrl; @FXML private Label lblServerName; @FXML private Label lblCreationWarning; @FXML private Label lblServerWarning; @FXML private VBox listPane; - @FXML private JFXTextField txtServerIp; + @FXML private JFXTextField txtServerUrl; @FXML private JFXDialogLayout addServerPane; @FXML private JFXDialogLayout confirmServerPane; @FXML private JFXDialog dialog; @@ -41,7 +41,7 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa private final TransitionHandler transitionHandler; - private AuthlibInjectorServerInfo serverBeingAdded; + private AuthlibInjectorServer serverBeingAdded; { FXUtils.loadFXML(this, "/assets/fxml/authlib-injector-servers.fxml"); @@ -51,14 +51,14 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa getChildren().remove(dialog); dialog.setDialogContainer(this); - txtServerIp.textProperty().addListener((a, b, newValue) -> - btnAddNext.setDisable(!txtServerIp.validate())); + txtServerUrl.textProperty().addListener((a, b, newValue) -> + btnAddNext.setDisable(!txtServerUrl.validate())); reload(); } private void removeServer(AuthlibInjectorServerItem item) { - Settings.INSTANCE.SETTINGS.authlibInjectorServers.remove(item.getInfo()); + Settings.INSTANCE.SETTINGS.authlibInjectorServers.remove(item.getServer()); reload(); } @@ -75,7 +75,7 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private void onAdd() { transitionHandler.setContent(addServerPane, ContainerAnimations.NONE.getAnimationProducer()); - txtServerIp.setText(""); + txtServerUrl.setText(""); addServerPane.setDisable(false); progressBar.setVisible(false); dialog.show(); @@ -88,22 +88,22 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa @FXML private void onAddNext() { - String url = fixInputUrl(txtServerIp.getText()); + String url = fixInputUrl(txtServerUrl.getText()); progressBar.setVisible(true); addServerPane.setDisable(true); Task.of(() -> { - serverBeingAdded = new AuthlibInjectorServerInfo(url, Accounts.getAuthlibInjectorServerName(url)); + serverBeingAdded = new AuthlibInjectorServer(url, Accounts.getAuthlibInjectorServerName(url)); }).finalized(Schedulers.javafx(), (variables, isDependentsSucceeded) -> { progressBar.setVisible(false); addServerPane.setDisable(false); if (isDependentsSucceeded) { - lblServerName.setText(serverBeingAdded.getServerName()); - lblServerIp.setText(serverBeingAdded.getServerIp()); + lblServerName.setText(serverBeingAdded.getName()); + lblServerUrl.setText(serverBeingAdded.getUrl()); - lblServerWarning.setVisible("http".equals(NetworkUtils.toURL(serverBeingAdded.getServerIp()).getProtocol())); + lblServerWarning.setVisible("http".equals(NetworkUtils.toURL(serverBeingAdded.getUrl()).getProtocol())); transitionHandler.setContent(confirmServerPane, ContainerAnimations.SWIPE_LEFT.getAnimationProducer()); } else { diff --git a/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml b/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml index cac3bee5d..e5b4715bd 100644 --- a/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml +++ b/HMCL/src/main/resources/assets/fxml/authlib-injector-servers.fxml @@ -31,7 +31,7 @@