From 3f85ac208ce958ada1acfe97d08728d71505e79a Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Wed, 14 Oct 2020 14:36:17 +0800 Subject: [PATCH] impl yushijinhun/authlib-injector#90 --- .../hmcl/ui/account/AccountListItem.java | 28 +++++++++++++++++-- .../hmcl/ui/account/AccountListItemSkin.java | 15 +++++----- .../AuthlibInjectorAccount.java | 22 +++++++++++++++ .../AuthlibInjectorProvider.java | 13 ++------- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java index e0a03614b..deda746bb 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItem.java @@ -18,8 +18,10 @@ package org.jackhuang.hmcl.ui.account; import javafx.beans.binding.Bindings; +import javafx.beans.binding.ObjectBinding; import javafx.beans.binding.StringBinding; import javafx.beans.property.*; +import javafx.beans.value.ObservableBooleanValue; import javafx.scene.control.RadioButton; import javafx.scene.control.Skin; import javafx.scene.image.Image; @@ -30,6 +32,8 @@ import org.jackhuang.hmcl.auth.CredentialExpiredException; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.auth.offline.OfflineAccount; +import org.jackhuang.hmcl.auth.yggdrasil.CompleteGameProfile; +import org.jackhuang.hmcl.auth.yggdrasil.TextureType; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount; import org.jackhuang.hmcl.game.TexturesLoader; import org.jackhuang.hmcl.setting.Accounts; @@ -40,10 +44,13 @@ import org.jackhuang.hmcl.ui.DialogController; import org.jackhuang.hmcl.ui.construct.PromptDialogPane; import java.io.File; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.CancellationException; import java.util.logging.Level; -import static org.jackhuang.hmcl.util.Lang.thread; +import static java.util.Collections.emptySet; +import static javafx.beans.binding.Bindings.createBooleanBinding; import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -111,8 +118,23 @@ public class AccountListItem extends RadioButton { refreshAsync().whenComplete(e -> {}).start(); } - public boolean canUploadSkin() { - return account instanceof YggdrasilAccount && !(account instanceof AuthlibInjectorAccount); + public ObservableBooleanValue canUploadSkin() { + if (account instanceof YggdrasilAccount) { + if (account instanceof AuthlibInjectorAccount) { + AuthlibInjectorAccount aiAccount = (AuthlibInjectorAccount) account; + ObjectBinding> profile = aiAccount.getYggdrasilService().getProfileRepository().binding(aiAccount.getUUID()); + return createBooleanBinding(() -> { + Set uploadableTextures = profile.get() + .map(AuthlibInjectorAccount::getUploadableTextures) + .orElse(emptySet()); + return uploadableTextures.contains(TextureType.SKIN); + }, profile); + } else { + return createBooleanBinding(() -> true); + } + } else { + return createBooleanBinding(() -> false); + } } public void uploadSkin() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java index d56a670a9..dbf166b93 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java @@ -92,14 +92,13 @@ public class AccountListItemSkin extends SkinBase { runInFX(() -> FXUtils.installFastTooltip(btnRefresh, i18n("button.refresh"))); right.getChildren().add(btnRefresh); - if (skinnable.canUploadSkin()) { - JFXButton btnUpload = new JFXButton(); - btnUpload.setOnMouseClicked(e -> skinnable.uploadSkin()); - btnUpload.getStyleClass().add("toggle-icon4"); - btnUpload.setGraphic(SVG.hanger(Theme.blackFillBinding(), -1, -1)); - runInFX(() -> FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload"))); - right.getChildren().add(btnUpload); - } + JFXButton btnUpload = new JFXButton(); + btnUpload.setOnMouseClicked(e -> skinnable.uploadSkin()); + btnUpload.getStyleClass().add("toggle-icon4"); + btnUpload.setGraphic(SVG.hanger(Theme.blackFillBinding(), -1, -1)); + runInFX(() -> FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload"))); + btnUpload.visibleProperty().bind(skinnable.canUploadSkin()); + right.getChildren().add(btnUpload); JFXButton btnRemove = new JFXButton(); btnRemove.setOnMouseClicked(e -> skinnable.remove()); 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 14bc95f55..163bcf221 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 @@ -21,6 +21,8 @@ import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.auth.CharacterSelector; import org.jackhuang.hmcl.auth.ServerDisconnectException; +import org.jackhuang.hmcl.auth.yggdrasil.CompleteGameProfile; +import org.jackhuang.hmcl.auth.yggdrasil.TextureType; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession; import org.jackhuang.hmcl.game.Arguments; @@ -33,6 +35,8 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Collections.emptySet; +import static java.util.Collections.unmodifiableSet; public class AuthlibInjectorAccount extends YggdrasilAccount { private final AuthlibInjectorServer server; @@ -156,4 +160,22 @@ public class AuthlibInjectorAccount extends YggdrasilAccount { .append("server", getServer().getUrl()) .toString(); } + + public static Set getUploadableTextures(CompleteGameProfile profile) { + String prop = profile.getProperties().get("uploadableTextures"); + if (prop == null) + return emptySet(); + Set result = EnumSet.noneOf(TextureType.class); + for (String val : prop.split(",")) { + val = val.toUpperCase(); + TextureType parsed; + try { + parsed = TextureType.valueOf(val); + } catch (IllegalArgumentException e) { + continue; + } + result.add(parsed); + } + return unmodifiableSet(result); + } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorProvider.java index 6fcb53c09..871e667b9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorProvider.java @@ -17,11 +17,12 @@ */ package org.jackhuang.hmcl.auth.authlibinjector; +import static org.jackhuang.hmcl.util.io.NetworkUtils.toURL; + import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilProvider; import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter; -import java.net.MalformedURLException; import java.net.URL; import java.util.UUID; @@ -55,7 +56,7 @@ public class AuthlibInjectorProvider implements YggdrasilProvider { @Override public URL getSkinUploadURL(UUID uuid) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); + return toURL(apiRoot + "api/user/profile/" + UUIDTypeAdapter.fromUUID(uuid) + "/skin"); } @Override @@ -67,12 +68,4 @@ public class AuthlibInjectorProvider implements YggdrasilProvider { public String toString() { return apiRoot; } - - private URL toURL(String url) throws AuthenticationException { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new AuthenticationException(e); - } - } }