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 04a600b18..e8c321b69 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -30,6 +30,7 @@ import org.jackhuang.hmcl.launch.*; import org.jackhuang.hmcl.mod.CurseCompletionException; import org.jackhuang.hmcl.mod.CurseCompletionTask; import org.jackhuang.hmcl.mod.ModpackConfiguration; +import org.jackhuang.hmcl.setting.Accounts; import org.jackhuang.hmcl.setting.LauncherVisibility; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.VersionSetting; @@ -141,7 +142,7 @@ public final class LauncherHelper { .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.LOGGING_IN))) .then(Task.of(i18n("account.methods"), variables -> { try { - variables.set("account", account.logIn()); + variables.set("account", Accounts.logIn(account)); } catch (CredentialExpiredException e) { variables.set("account", DialogController.logIn(account)); } catch (AuthenticationException e) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java index 23cdd0ef3..04f8ceca4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java @@ -26,6 +26,8 @@ import javafx.collections.ObservableList; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.AccountFactory; +import org.jackhuang.hmcl.auth.AuthInfo; +import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccountFactory; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDownloader; @@ -35,10 +37,14 @@ import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory; import org.jackhuang.hmcl.auth.yggdrasil.MojangYggdrasilProvider; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory; +import org.jackhuang.hmcl.task.Schedulers; import java.io.IOException; +import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.logging.Level; import static java.util.stream.Collectors.toList; @@ -159,6 +165,11 @@ public final class Accounts { if (initialized) throw new IllegalStateException("Already initialized"); + selectedAccount.addListener((a, b, newValue) -> { + if (newValue != null) + startLoggingIn(newValue); + }); + // load accounts config().getAccountStorages().forEach(storage -> { AccountFactory factory = type2factory.get(storage.get("type")); @@ -258,4 +269,34 @@ public final class Accounts { return getAccountTypeName(getAccountFactory(account)); } // ==== + + private static final Map> accountFutures = new HashMap<>(); + + public static void startLoggingIn(Account account) { + if (!accountFutures.containsKey(account)) { + Future future = Schedulers.computation().schedule(account::logIn); + accountFutures.put(account, future); + } + } + + public static AuthInfo logIn(Account account) throws AuthenticationException { + try { + if (!accountFutures.containsKey(account)) { + Future future = Schedulers.computation().schedule(account::logIn); + accountFutures.put(account, future); + future.get(); + } else { + accountFutures.get(account).get(); + } + } catch (ExecutionException e) { + if (e.getCause() instanceof AuthenticationException) + throw (AuthenticationException) e.getCause(); + else + LOG.log(Level.WARNING, "Unable to logIn", e); + } catch (InterruptedException e) { + // account.logIn() + } + + return account.logIn(); + } }