From 13aabde5d9b700f0055f2e8815f195eb95b70fd3 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Fri, 8 Jun 2018 18:55:43 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=AE=8C=E5=96=84Account=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/jackhuang/hmcl/auth/Account.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) 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 708a523df..49391eb6c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java @@ -29,28 +29,31 @@ import java.util.UUID; public abstract class Account { /** - * @return the account name (mostly email) + * @return the name of the account who owns the character */ public abstract String getUsername(); /** - * * @return the character name */ public abstract String getCharacter(); /** - * @return the UUID + * @return the character UUID */ public abstract UUID getUUID(); /** - * log in. - * @return the specific player's info. - * @throws AuthenticationException if server error occurred. + * 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. */ - public abstract AuthInfo logIn() throws AuthenticationException; + public abstract AuthInfo logIn() throws ServerDisconnectException, AuthenticationException; + /** + * Login with specified password. + */ public abstract AuthInfo logInWithPassword(String password) throws AuthenticationException; public abstract boolean canPlayOffline(); From e71c06a0d0dc5f829f81d6bcf22c01186429f39a Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Fri, 8 Jun 2018 21:08:12 +0800 Subject: [PATCH 2/4] =?UTF-8?q?Arguments.addXXX=E6=94=B9=E4=B8=BA=E9=93=BE?= =?UTF-8?q?=E5=BC=8F=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuthlibInjectorAccount.java | 5 ++--- .../org/jackhuang/hmcl/game/Arguments.java | 22 +++++++------------ .../hmcl/mod/MultiMCModpackInstallTask.java | 2 +- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java index 9fda11c6d..6bd5422fd 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java @@ -66,11 +66,10 @@ public class AuthlibInjectorAccount extends YggdrasilAccount { try { thread.join(); - String arg = "-javaagent:" + injectorJarPath.get() + "=" + serverBaseURL; - Arguments arguments = Arguments.addJVMArguments(null, arg); + Arguments arguments = new Arguments().addJVMArguments("-javaagent:" + injectorJarPath.get() + "=" + serverBaseURL); if (flag.get()) - arguments = Arguments.addJVMArguments(arguments, "-Dorg.to2mbn.authlibinjector.config.prefetched=" + new String(Base64.getEncoder().encode(getTask.getResult().getBytes()), UTF_8)); + arguments = arguments.addJVMArguments("-Dorg.to2mbn.authlibinjector.config.prefetched=" + new String(Base64.getEncoder().encode(getTask.getResult().getBytes()), UTF_8)); return info.withArguments(arguments); } catch (Exception e) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Arguments.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Arguments.java index a2be04601..9222e2e58 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Arguments.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Arguments.java @@ -54,28 +54,22 @@ public final class Arguments { return jvm == null ? Collections.emptyList() : Collections.unmodifiableList(jvm); } - public static Arguments addGameArguments(Arguments arguments, String... gameArguments) { - return addGameArguments(arguments, Arrays.asList(gameArguments)); + public Arguments addGameArguments(String... gameArguments) { + return addGameArguments(Arrays.asList(gameArguments)); } - public static Arguments addGameArguments(Arguments arguments, List gameArguments) { + public Arguments addGameArguments(List gameArguments) { List list = gameArguments.stream().map(StringArgument::new).collect(Collectors.toList()); - if (arguments == null) - return new Arguments(list, null); - else - return new Arguments(Lang.merge(arguments.getGame(), list), arguments.getJvm()); + return new Arguments(Lang.merge(getGame(), list), getJvm()); } - public static Arguments addJVMArguments(Arguments arguments, String... jvmArguments) { - return addJVMArguments(arguments, Arrays.asList(jvmArguments)); + public Arguments addJVMArguments(String... jvmArguments) { + return addJVMArguments(Arrays.asList(jvmArguments)); } - public static Arguments addJVMArguments(Arguments arguments, List jvmArguments) { + public Arguments addJVMArguments(List jvmArguments) { List list = jvmArguments.stream().map(StringArgument::new).collect(Collectors.toList()); - if (arguments == null) - return new Arguments(null, list); - else - return new Arguments(arguments.getGame(), Lang.merge(arguments.getJvm(), list)); + return new Arguments(getGame(), Lang.merge(getJvm(), list)); } public static Arguments merge(Arguments a, Arguments b) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java index b796d1e9f..692390880 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java @@ -109,7 +109,7 @@ public final class MultiMCModpackInstallTask extends Task { version = version .setLibraries(Lang.merge(version.getLibraries(), patch.getLibraries())) .setMainClass(patch.getMainClass()) - .setArguments(Arguments.addGameArguments(version.getArguments().orElse(null), newArguments)); + .setArguments(version.getArguments().orElseGet(Arguments::new).addGameArguments(newArguments)); } } } From 4f51e377ae37d94057ea26db398ee70cd3fa71e3 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Fri, 8 Jun 2018 19:26:05 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E7=A7=BB=E9=99=A4canPlayOffline()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jackhuang/hmcl/game/LauncherHelper.java | 6 ++---- .../main/java/org/jackhuang/hmcl/auth/Account.java | 5 ++--- .../jackhuang/hmcl/auth/offline/OfflineAccount.java | 10 +++------- .../hmcl/auth/yggdrasil/YggdrasilAccount.java | 13 ++++--------- 4 files changed, 11 insertions(+), 23 deletions(-) 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 ef1ac22bb..7fff98200 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -97,10 +97,8 @@ public final class LauncherHelper { try { variables.set("account", account.logIn()); } catch (ServerDisconnectException e) { - if (account.canPlayOffline()) - variables.set("account", account.playOffline()); - else - throw e; + variables.set("account", + account.playOffline().orElseThrow(() -> e)); } } catch (AuthenticationException e) { variables.set("account", DialogController.logIn(account)); 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 49391eb6c..2fd2c7818 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/Account.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.auth; import org.jackhuang.hmcl.util.ToStringBuilder; import java.util.Map; +import java.util.Optional; import java.util.UUID; /** @@ -56,13 +57,11 @@ public abstract class Account { */ public abstract AuthInfo logInWithPassword(String password) throws AuthenticationException; - public abstract boolean canPlayOffline(); - /** * Play offline. * @return the specific offline player's info. */ - public abstract AuthInfo playOffline(); + public abstract Optional playOffline(); public abstract Map toStorage(); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java index aee8c60ed..f4925d9d5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java @@ -26,6 +26,7 @@ import org.jackhuang.hmcl.util.UUIDTypeAdapter; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.UUID; import static org.jackhuang.hmcl.util.Lang.mapOf; @@ -80,13 +81,8 @@ public class OfflineAccount extends Account { } @Override - public boolean canPlayOffline() { - return false; - } - - @Override - public AuthInfo playOffline() { - throw new IllegalStateException(); + public Optional playOffline() { + return Optional.empty(); } @Override 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 4b7fd3135..cb6d88022 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 @@ -103,16 +103,11 @@ public class YggdrasilAccount extends Account { } @Override - public boolean canPlayOffline() { - return isLoggedIn() && session.getSelectedProfile() != null && !canPlayOnline(); - } + public Optional playOffline() { + if (isLoggedIn() && session.getSelectedProfile() != null && !canPlayOnline()) + return Optional.of(session.toAuthInfo()); - @Override - public AuthInfo playOffline() { - if (!canPlayOffline()) - throw new IllegalStateException("Current account " + this + " cannot play offline."); - - return session.toAuthInfo(); + return Optional.empty(); } @Override From 631337c451e138bb186faa69d8e8c3cb10b80902 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Fri, 8 Jun 2018 18:27:07 +0800 Subject: [PATCH 4/4] =?UTF-8?q?YggdrasilAccount=E8=AE=B0=E5=BD=95=E8=A7=92?= =?UTF-8?q?=E8=89=B2uuid=E8=80=8C=E4=B8=8D=E6=98=AF=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 注:旧版本无法读取此版本配置(移除了character)。 --- .../hmcl/auth/SpecificCharacterSelector.java | 11 +++++----- .../AuthlibInjectorAccount.java | 5 +++-- .../AuthlibInjectorAccountFactory.java | 6 +++--- .../hmcl/auth/yggdrasil/YggdrasilAccount.java | 21 +++++++++---------- .../yggdrasil/YggdrasilAccountFactory.java | 6 +++--- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/SpecificCharacterSelector.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/SpecificCharacterSelector.java index dd75c6033..884a976ee 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/SpecificCharacterSelector.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/SpecificCharacterSelector.java @@ -20,23 +20,24 @@ package org.jackhuang.hmcl.auth; import org.jackhuang.hmcl.auth.yggdrasil.GameProfile; import java.util.List; +import java.util.UUID; /** * Select character by name. */ public class SpecificCharacterSelector implements CharacterSelector { - private final String id; + private UUID uuid; /** * Constructor. - * @param id character's name. + * @param uuid character's uuid. */ - public SpecificCharacterSelector(String id) { - this.id = id; + public SpecificCharacterSelector(UUID uuid) { + this.uuid = uuid; } @Override public GameProfile select(Account account, List names) throws NoSelectedCharacterException { - return names.stream().filter(profile -> profile.getName().equals(id)).findAny().orElseThrow(() -> new NoSelectedCharacterException(account)); + return names.stream().filter(profile -> profile.getId().equals(uuid)).findAny().orElseThrow(() -> new NoSelectedCharacterException(account)); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java index 6bd5422fd..0114bc804 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccount.java @@ -31,6 +31,7 @@ import org.jackhuang.hmcl.util.NetworkUtils; import java.util.Base64; import java.util.Map; +import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import static java.nio.charset.StandardCharsets.UTF_8; @@ -39,8 +40,8 @@ public class AuthlibInjectorAccount extends YggdrasilAccount { private final String serverBaseURL; private final ExceptionalSupplier injectorJarPath; - protected AuthlibInjectorAccount(YggdrasilService service, String serverBaseURL, ExceptionalSupplier injectorJarPath, String username, String character, YggdrasilSession session) { - super(service, username, character, session); + protected AuthlibInjectorAccount(YggdrasilService service, String serverBaseURL, ExceptionalSupplier injectorJarPath, String username, UUID characterUUID, YggdrasilSession session) { + super(service, username, characterUUID, session); this.injectorJarPath = injectorJarPath; this.serverBaseURL = serverBaseURL; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java index 2d6edd8f2..51d642f72 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorAccountFactory.java @@ -42,14 +42,14 @@ public class AuthlibInjectorAccountFactory extends AccountFactory new IllegalArgumentException("storage does not have username")); - String character = tryCast(storage.get("character"), String.class) - .orElseThrow(() -> new IllegalArgumentException("storage does not have selected character name.")); String apiRoot = tryCast(storage.get("serverBaseURL"), String.class) .orElseThrow(() -> new IllegalArgumentException("storage does not have API root.")); return new AuthlibInjectorAccount(new YggdrasilService(new AuthlibInjectorProvider(apiRoot), proxy), - apiRoot, injectorJarPathSupplier, username, character, YggdrasilSession.fromStorage(storage)); + apiRoot, injectorJarPathSupplier, username, session.getSelectedProfile().getId(), session); } } 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 cb6d88022..139d464d5 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 @@ -33,13 +33,13 @@ public class YggdrasilAccount extends Account { private final YggdrasilService service; private boolean isOnline = false; private YggdrasilSession session; - private String character; + private UUID characterUUID; - protected YggdrasilAccount(YggdrasilService service, String username, String character, YggdrasilSession session) { + protected YggdrasilAccount(YggdrasilService service, String username, UUID characterUUID, YggdrasilSession session) { this.service = service; this.username = username; this.session = session; - this.character = character; + this.characterUUID = characterUUID; if (session == null || session.getSelectedProfile() == null || StringUtils.isBlank(session.getAccessToken())) this.session = null; @@ -67,14 +67,14 @@ public class YggdrasilAccount extends Account { public AuthInfo logIn() throws AuthenticationException { if (!canPlayOnline()) { logInWithToken(); - selectProfile(new SpecificCharacterSelector(character)); + selectProfile(new SpecificCharacterSelector(characterUUID)); } return session.toAuthInfo(); } @Override public final AuthInfo logInWithPassword(String password) throws AuthenticationException { - return logInWithPassword(password, new SpecificCharacterSelector(character)); + return logInWithPassword(password, new SpecificCharacterSelector(characterUUID)); } protected AuthInfo logInWithPassword(String password, CharacterSelector selector) throws AuthenticationException { @@ -91,7 +91,7 @@ public class YggdrasilAccount extends Account { session = service.refresh(session.getAccessToken(), session.getClientToken(), selector.select(this, Arrays.asList(session.getAvailableProfiles()))); } - character = session.getSelectedProfile().getName(); + characterUUID = session.getSelectedProfile().getId(); } private void logInWithToken() throws AuthenticationException { @@ -112,13 +112,12 @@ public class YggdrasilAccount extends Account { @Override public Map toStorage() { + if (session == null) + throw new IllegalStateException("No session is specified"); + HashMap storage = new HashMap<>(); - storage.put("username", getUsername()); - storage.put("character", character); - if (session != null) - storage.putAll(session.toStorage()); - + storage.putAll(session.toStorage()); return storage; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccountFactory.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccountFactory.java index 03bbaf62d..3fb044793 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccountFactory.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccountFactory.java @@ -58,12 +58,12 @@ public class YggdrasilAccountFactory extends AccountFactory { Objects.requireNonNull(storage); Objects.requireNonNull(proxy); + YggdrasilSession session = YggdrasilSession.fromStorage(storage); + String username = tryCast(storage.get("username"), String.class) .orElseThrow(() -> new IllegalArgumentException("storage does not have username")); - String character = tryCast(storage.get("character"), String.class) - .orElseThrow(() -> new IllegalArgumentException("storage does not have selected character name.")); - return new YggdrasilAccount(new YggdrasilService(provider, proxy), username, character, YggdrasilSession.fromStorage(storage)); + return new YggdrasilAccount(new YggdrasilService(provider, proxy), username, session.getSelectedProfile().getId(), session); } public static String randomToken() {