Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions HMCL/src/main/java/org/jackhuang/hmcl/game/TexturesLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ public static ObjectBinding<LoadedTexture> skinBinding(YggdrasilService service,

public static ObservableValue<LoadedTexture> skinBinding(Account account) {
LoadedTexture uuidFallback = getDefaultSkin(account.getUUID());
if (account instanceof OfflineAccount) {
OfflineAccount offlineAccount = (OfflineAccount) account;
if (account instanceof OfflineAccount offlineAccount) {

SimpleObjectProperty<LoadedTexture> binding = new SimpleObjectProperty<>();
InvalidationListener listener = o -> {
Expand Down Expand Up @@ -251,6 +250,54 @@ public static ObservableValue<LoadedTexture> skinBinding(Account account) {
}
}

public static ObservableValue<LoadedTexture> capeBinding(Account account) {
if (account instanceof OfflineAccount offlineAccount) {

SimpleObjectProperty<LoadedTexture> binding = new SimpleObjectProperty<>();
InvalidationListener listener = o -> {
Skin skin = offlineAccount.getSkin();
String username = offlineAccount.getUsername();

binding.set(null);
if (skin != null) {
skin.load(username).setExecutor(POOL).whenComplete(Schedulers.javafx(), (result, exception) -> {
if (exception != null) {
LOG.warning("Failed to load texture", exception);
} else if (result != null && result.getCape() != null && result.getCape().getImage() != null) {
binding.set(new LoadedTexture(result.getCape().getImage(), emptyMap()));
}
}).start();
}
};

listener.invalidated(offlineAccount);

binding.addListener(new Holder<>(listener));
offlineAccount.addListener(new WeakInvalidationListener(listener));

return binding;
} else {
return BindingMapping.of(account.getTextures())
.asyncMap(textures -> {
if (textures.isPresent()) {
Texture texture = textures.get().get(TextureType.CAPE);
if (texture != null && StringUtils.isNotBlank(texture.getUrl())) {
return CompletableFuture.supplyAsync(() -> {
try {
return loadTexture(texture);
} catch (Throwable e) {
LOG.warning("Failed to load texture " + texture.getUrl() + ", using fallback texture", e);
return null;
}
}, POOL);
}
}

return CompletableFuture.completedFuture(null);
}, null);
}
}

// ====

// ==== Avatar ====
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ public AccountListItemSkin(AccountListItem skinnable) {
center.setAlignment(Pos.CENTER_LEFT);

Canvas canvas = new Canvas(32, 32);
canvas.setCursor(Cursor.HAND);
FXUtils.onClicked(canvas, () -> {
Controllers.dialog(new SkinPreviewDialog(skinnable.getAccount()));
});
TexturesLoader.bindAvatar(canvas, skinnable.getAccount());

Label title = new Label();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.jackhuang.hmcl.ui.account;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialogLayout;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.game.TexturesLoader;
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
import org.jackhuang.hmcl.ui.skin.SkinCanvas;
import org.jackhuang.hmcl.ui.skin.animation.SkinAniRunning;
import org.jackhuang.hmcl.ui.skin.animation.SkinAniWavingArms;
import org.jackhuang.hmcl.util.Lang;

import java.util.Objects;

import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;

public class SkinPreviewDialog extends JFXDialogLayout {
private final SkinCanvas canvas;
private final ObservableValue<TexturesLoader.LoadedTexture> skin;
private final ObservableValue<TexturesLoader.LoadedTexture> cape;

public SkinPreviewDialog(Account account) {
setHeading(new Label(i18n("account.character.preview")));


skin = TexturesLoader.skinBinding(account);
cape = TexturesLoader.capeBinding(account);

skin.addListener((observable, oldValue, newValue) -> refresh());

cape.addListener((observable, oldValue, newValue) -> refresh());

canvas = new SkinCanvas(TexturesLoader.getDefaultSkinImage(), 300, 300, true);

setBody(canvas);

onEscPressed(this, () -> fireEvent(new DialogCloseEvent()));
setActions(Lang.apply(new JFXButton(i18n("button.ok")), (jfxButton) -> {
jfxButton.setOnAction((event) -> fireEvent(new DialogCloseEvent()));
jfxButton.getStyleClass().add("dialog-accept");
}));
}

private void refresh() {
Image skinImg = skin.getValue().getImage();
boolean isSlim = Objects.equals(skin.getValue().getMetadata().get("model"), "slim");

Image capeImg = null;

if (cape != null && cape.getValue() != null) {
capeImg = cape.getValue().getImage();
}

canvas.getAnimationPlayer().addSkinAnimation(new SkinAniWavingArms(100, 2000, 7.5, canvas), new SkinAniRunning(100, 100, 30, canvas));
canvas.enableRotation(.5);
canvas.updateSkin(skinImg, isSlim, capeImg);
}
}
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ about.open_source.statement=GPL v3 (https://github.com/HMCL-dev/HMCL)
account=Accounts
account.cape=Cape
account.character=Player
account.character.preview=Skin preview
account.choose=Choose a Player
account.create=Add Account
account.create.microsoft=Add a Microsoft Account
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ about.open_source.statement=GPL v3 (https://github.com/HMCL-dev/HMCL/)
account=帳戶
account.cape=披風
account.character=角色
account.character.preview=外觀預覽
account.choose=請選取角色
account.create=建立帳戶
account.create.microsoft=新增 Microsoft 帳戶
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ about.open_source.statement=GPL v3 (https://github.com/HMCL-dev/HMCL)
account=账户
account.cape=披风
account.character=角色
account.character.preview=皮肤预览
account.choose=选择一个角色
account.create=添加账户
account.create.microsoft=添加微软账户
Expand Down