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 33504b62f..70e39e58b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -22,6 +22,7 @@ import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.auth.AuthenticationException; +import org.jackhuang.hmcl.auth.CredentialExpiredException; import org.jackhuang.hmcl.auth.ServerDisconnectException; import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.MaintainTask; @@ -106,14 +107,12 @@ public final class LauncherHelper { .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.LOGGING_IN))) .then(Task.of(Launcher.i18n("account.methods"), variables -> { try { - try { - variables.set("account", account.logIn()); - } catch (ServerDisconnectException e) { - variables.set("account", - account.playOffline().orElseThrow(() -> e)); - } - } catch (AuthenticationException e) { + variables.set("account", account.logIn()); + } catch (CredentialExpiredException e) { variables.set("account", DialogController.logIn(account)); + } catch (AuthenticationException e) { + variables.set("account", + account.playOffline().orElseThrow(() -> e)); } })) .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.LAUNCHING))) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java index 2fd2c7818..8eaf538cd 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java @@ -47,10 +47,9 @@ public abstract class Account { /** * Login with stored credentials. * - * @throws ServerDisconnectException if an network error has occurred, in which case password login won't be tried. - * @throws AuthenticationException if an error has occurred. If it's not a {@link ServerDisconnectException}, password login will be tried. + * @throws CredentialExpiredException when the stored credentials has expired, in which case a password login will be performed */ - public abstract AuthInfo logIn() throws ServerDisconnectException, AuthenticationException; + public abstract AuthInfo logIn() throws CredentialExpiredException, AuthenticationException; /** * Login with specified password. diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/CredentialExpiredException.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/CredentialExpiredException.java new file mode 100644 index 000000000..9461d5880 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/CredentialExpiredException.java @@ -0,0 +1,42 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2018 huangyuhui + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see {http://www.gnu.org/licenses/}. + */ +package org.jackhuang.hmcl.auth; + +/** + * Thrown when the stored credentials has expired. + * This exception indicates that a password login should be performed. + * + * @author yushijinhun + * @see Account#logIn() + */ +public class CredentialExpiredException extends AuthenticationException { + + public CredentialExpiredException() {} + + public CredentialExpiredException(String message, Throwable cause) { + super(message, cause); + } + + public CredentialExpiredException(String message) { + super(message); + } + + public CredentialExpiredException(Throwable cause) { + super(cause); + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccount.java index c903384da..112bdfc3c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccount.java @@ -69,7 +69,15 @@ public class YggdrasilAccount extends Account { if (service.validate(session.getAccessToken(), session.getClientToken())) { isOnline = true; } else { - updateSession(service.refresh(session.getAccessToken(), session.getClientToken(), null), new SpecificCharacterSelector(characterUUID)); + try { + updateSession(service.refresh(session.getAccessToken(), session.getClientToken(), null), new SpecificCharacterSelector(characterUUID)); + } catch (RemoteAuthenticationException e) { + if ("ForbiddenOperationException".equals(e.getRemoteName())) { + throw new CredentialExpiredException(e); + } else { + throw e; + } + } } } return session.toAuthInfo();