在AuthlibInjectorAccountFactory中使用AuthlibInjectorServer而不是url

This commit is contained in:
yushijinhun
2018-06-16 20:39:04 +08:00
parent df29d47c0a
commit 5f40d01fb4
3 changed files with 43 additions and 37 deletions

View File

@@ -23,6 +23,7 @@ import org.jackhuang.hmcl.auth.AccountFactory;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccountFactory;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorBuildInfo;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServerResponse;
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory;
@@ -41,8 +42,10 @@ import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
/**
@@ -58,7 +61,7 @@ public final class Accounts {
public static final Map<String, AccountFactory<?>> ACCOUNT_FACTORY = mapOf(
pair(OFFLINE_ACCOUNT_KEY, OfflineAccountFactory.INSTANCE),
pair(YGGDRASIL_ACCOUNT_KEY, new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE)),
pair(AUTHLIB_INJECTOR_ACCOUNT_KEY, new AuthlibInjectorAccountFactory(Accounts::downloadAuthlibInjector))
pair(AUTHLIB_INJECTOR_ACCOUNT_KEY, new AuthlibInjectorAccountFactory(Accounts::downloadAuthlibInjector, Accounts::getOrCreateAuthlibInjectorServer))
);
private static final Map<String, String> AUTHLIB_INJECTOR_SERVER_NAMES = new HashMap<>();
@@ -104,7 +107,28 @@ public final class Accounts {
}
}
@Deprecated
public static TaskResult<String> getAuthlibInjectorServerNameAsync(AuthlibInjectorAccount account) {
return Task.ofResult("serverName", () -> Accounts.getAuthlibInjectorServerName(account.getServerBaseURL()));
}
private static AuthlibInjectorServer getOrCreateAuthlibInjectorServer(String url) {
return Settings.SETTINGS.authlibInjectorServers.stream()
.filter(server -> url.equals(server.getUrl()))
.findFirst()
.orElseGet(() -> {
// this usually happens when migrating data from an older version
String name;
try {
name = Accounts.getAuthlibInjectorServerName(url);
LOG.info("Migrated authlib injector server [" + url + "], name=[" + name + "]");
} catch (Exception e) {
name = url;
LOG.log(Level.WARNING, "Failed to migrate authlib injector server [" + url + "]", e);
}
AuthlibInjectorServer server = new AuthlibInjectorServer(url, name);
Settings.SETTINGS.authlibInjectorServers.add(server);
return server;
});
}
}

View File

@@ -104,8 +104,6 @@ public class Settings {
accounts.put(Accounts.getAccountId(account), account);
}
migrateAuthlibInjectorServers();
SETTINGS.authlibInjectorServers.addListener(onInvalidating(this::removeDanglingAuthlibInjectorAccounts));
checkProfileMap();
@@ -317,32 +315,6 @@ public class Settings {
.collect(toSet());
}
/**
* The {@code serverBaseURL} specified in {@link AuthlibInjectorAccount} may not have an associated
* {@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}.
*/
private void migrateAuthlibInjectorServers() {
Set<String> 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 AuthlibInjectorServer(url, serverName));
});
}
/**
* After an {@link AuthlibInjectorServer} is removed, the associated accounts should also be removed.
* This method performs a check and removes the dangling accounts.

View File

@@ -11,28 +11,36 @@ import org.jackhuang.hmcl.util.NetworkUtils;
import java.net.Proxy;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import static org.jackhuang.hmcl.util.Lang.tryCast;
public class AuthlibInjectorAccountFactory extends AccountFactory<AuthlibInjectorAccount> {
private final ExceptionalSupplier<String, ?> injectorJarPathSupplier;
private Function<String, AuthlibInjectorServer> serverLookup;
public AuthlibInjectorAccountFactory(ExceptionalSupplier<String, ?> injectorJarPathSupplier) {
/**
* @param serverLookup a function that looks up {@link AuthlibInjectorServer} by url
*/
public AuthlibInjectorAccountFactory(ExceptionalSupplier<String, ?> injectorJarPathSupplier, Function<String, AuthlibInjectorServer> serverLookup) {
this.injectorJarPathSupplier = injectorJarPathSupplier;
this.serverLookup = serverLookup;
}
@Override
public AuthlibInjectorAccount create(CharacterSelector selector, String username, String password, Object serverBaseURL, Proxy proxy) throws AuthenticationException {
public AuthlibInjectorAccount create(CharacterSelector selector, String username, String password, Object apiRoot, Proxy proxy) throws AuthenticationException {
Objects.requireNonNull(selector);
Objects.requireNonNull(username);
Objects.requireNonNull(password);
Objects.requireNonNull(proxy);
if (!(serverBaseURL instanceof String) || !NetworkUtils.isURL((String) serverBaseURL))
throw new IllegalArgumentException("Additional data should be server base url string for authlib injector accounts.");
if (!(apiRoot instanceof String) || !NetworkUtils.isURL((String) apiRoot))
throw new IllegalArgumentException("Additional data should be API root string for authlib injector accounts.");
AuthlibInjectorAccount account = new AuthlibInjectorAccount(new YggdrasilService(new AuthlibInjectorProvider((String) serverBaseURL), proxy),
(String) serverBaseURL, injectorJarPathSupplier, username, null, null);
AuthlibInjectorServer server = serverLookup.apply((String) apiRoot);
AuthlibInjectorAccount account = new AuthlibInjectorAccount(new YggdrasilService(new AuthlibInjectorProvider(server.getUrl()), proxy),
server.getUrl(), injectorJarPathSupplier, username, null, null);
account.logInWithPassword(password, selector);
return account;
}
@@ -49,7 +57,9 @@ public class AuthlibInjectorAccountFactory extends AccountFactory<AuthlibInjecto
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, session.getSelectedProfile().getId(), session);
AuthlibInjectorServer server = serverLookup.apply(apiRoot);
return new AuthlibInjectorAccount(new YggdrasilService(new AuthlibInjectorProvider(server.getUrl()), proxy),
server.getUrl(), injectorJarPathSupplier, username, session.getSelectedProfile().getId(), session);
}
}