This commit is contained in:
Haowei Wen 2020-10-14 14:36:17 +08:00 committed by Yuhui Huang
parent c191186023
commit 3f85ac208c
4 changed files with 57 additions and 21 deletions

View File

@ -18,8 +18,10 @@
package org.jackhuang.hmcl.ui.account; package org.jackhuang.hmcl.ui.account;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.binding.StringBinding; import javafx.beans.binding.StringBinding;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.beans.value.ObservableBooleanValue;
import javafx.scene.control.RadioButton; import javafx.scene.control.RadioButton;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.image.Image; 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.AuthlibInjectorAccount;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
import org.jackhuang.hmcl.auth.offline.OfflineAccount; 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.auth.yggdrasil.YggdrasilAccount;
import org.jackhuang.hmcl.game.TexturesLoader; import org.jackhuang.hmcl.game.TexturesLoader;
import org.jackhuang.hmcl.setting.Accounts; import org.jackhuang.hmcl.setting.Accounts;
@ -40,10 +44,13 @@ import org.jackhuang.hmcl.ui.DialogController;
import org.jackhuang.hmcl.ui.construct.PromptDialogPane; import org.jackhuang.hmcl.ui.construct.PromptDialogPane;
import java.io.File; import java.io.File;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.logging.Level; 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.Logging.LOG;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@ -111,8 +118,23 @@ public class AccountListItem extends RadioButton {
refreshAsync().whenComplete(e -> {}).start(); refreshAsync().whenComplete(e -> {}).start();
} }
public boolean canUploadSkin() { public ObservableBooleanValue canUploadSkin() {
return account instanceof YggdrasilAccount && !(account instanceof AuthlibInjectorAccount); if (account instanceof YggdrasilAccount) {
if (account instanceof AuthlibInjectorAccount) {
AuthlibInjectorAccount aiAccount = (AuthlibInjectorAccount) account;
ObjectBinding<Optional<CompleteGameProfile>> profile = aiAccount.getYggdrasilService().getProfileRepository().binding(aiAccount.getUUID());
return createBooleanBinding(() -> {
Set<TextureType> 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() { public void uploadSkin() {

View File

@ -92,14 +92,13 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
runInFX(() -> FXUtils.installFastTooltip(btnRefresh, i18n("button.refresh"))); runInFX(() -> FXUtils.installFastTooltip(btnRefresh, i18n("button.refresh")));
right.getChildren().add(btnRefresh); right.getChildren().add(btnRefresh);
if (skinnable.canUploadSkin()) { JFXButton btnUpload = new JFXButton();
JFXButton btnUpload = new JFXButton(); btnUpload.setOnMouseClicked(e -> skinnable.uploadSkin());
btnUpload.setOnMouseClicked(e -> skinnable.uploadSkin()); btnUpload.getStyleClass().add("toggle-icon4");
btnUpload.getStyleClass().add("toggle-icon4"); btnUpload.setGraphic(SVG.hanger(Theme.blackFillBinding(), -1, -1));
btnUpload.setGraphic(SVG.hanger(Theme.blackFillBinding(), -1, -1)); runInFX(() -> FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload")));
runInFX(() -> FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload"))); btnUpload.visibleProperty().bind(skinnable.canUploadSkin());
right.getChildren().add(btnUpload); right.getChildren().add(btnUpload);
}
JFXButton btnRemove = new JFXButton(); JFXButton btnRemove = new JFXButton();
btnRemove.setOnMouseClicked(e -> skinnable.remove()); btnRemove.setOnMouseClicked(e -> skinnable.remove());

View File

@ -21,6 +21,8 @@ import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.auth.AuthenticationException;
import org.jackhuang.hmcl.auth.CharacterSelector; import org.jackhuang.hmcl.auth.CharacterSelector;
import org.jackhuang.hmcl.auth.ServerDisconnectException; 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.YggdrasilAccount;
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession;
import org.jackhuang.hmcl.game.Arguments; import org.jackhuang.hmcl.game.Arguments;
@ -33,6 +35,8 @@ import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static java.nio.charset.StandardCharsets.UTF_8; 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 { public class AuthlibInjectorAccount extends YggdrasilAccount {
private final AuthlibInjectorServer server; private final AuthlibInjectorServer server;
@ -156,4 +160,22 @@ public class AuthlibInjectorAccount extends YggdrasilAccount {
.append("server", getServer().getUrl()) .append("server", getServer().getUrl())
.toString(); .toString();
} }
public static Set<TextureType> getUploadableTextures(CompleteGameProfile profile) {
String prop = profile.getProperties().get("uploadableTextures");
if (prop == null)
return emptySet();
Set<TextureType> 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);
}
} }

View File

@ -17,11 +17,12 @@
*/ */
package org.jackhuang.hmcl.auth.authlibinjector; 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.AuthenticationException;
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilProvider; import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilProvider;
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter; import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.UUID; import java.util.UUID;
@ -55,7 +56,7 @@ public class AuthlibInjectorProvider implements YggdrasilProvider {
@Override @Override
public URL getSkinUploadURL(UUID uuid) throws UnsupportedOperationException { public URL getSkinUploadURL(UUID uuid) throws UnsupportedOperationException {
throw new UnsupportedOperationException(); return toURL(apiRoot + "api/user/profile/" + UUIDTypeAdapter.fromUUID(uuid) + "/skin");
} }
@Override @Override
@ -67,12 +68,4 @@ public class AuthlibInjectorProvider implements YggdrasilProvider {
public String toString() { public String toString() {
return apiRoot; return apiRoot;
} }
private URL toURL(String url) throws AuthenticationException {
try {
return new URL(url);
} catch (MalformedURLException e) {
throw new AuthenticationException(e);
}
}
} }