diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java index f22294d41..180505259 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java @@ -84,9 +84,11 @@ public final class AccountHelper { } public static Image getSkin(YggdrasilAccount account, double scaleRatio) { - if (account.getSelectedProfile() == null) return FXUtils.DEFAULT_ICON; + if (account.getSelectedProfile() == null) + return getDefaultSkin(account, scaleRatio); String name = account.getSelectedProfile().getName(); - if (name == null) return FXUtils.DEFAULT_ICON; + if (name == null) + return getDefaultSkin(account, scaleRatio); File file = getSkinFile(name); if (file.exists()) { Image original = new Image("file:" + file.getAbsolutePath()); @@ -95,7 +97,7 @@ public final class AccountHelper { original.getHeight() * scaleRatio, false, false); } - return FXUtils.DEFAULT_ICON; + return getDefaultSkin(account, scaleRatio); } public static Image getSkinImmediately(YggdrasilAccount account, GameProfile profile, double scaleRatio, Proxy proxy) throws Exception { @@ -103,13 +105,10 @@ public final class AccountHelper { File file = getSkinFile(name); downloadSkin(account, profile, true, proxy); if (!file.exists()) - return FXUtils.DEFAULT_ICON; + return getDefaultSkin(account, scaleRatio); - Image original = new Image("file:" + file.getAbsolutePath()); - return new Image("file:" + file.getAbsolutePath(), - original.getWidth() * scaleRatio, - original.getHeight() * scaleRatio, - false, false); + String url = "file:" + file.getAbsolutePath(); + return scale(url, scaleRatio); } public static Rectangle2D getViewport(double scaleRatio) { @@ -164,4 +163,31 @@ public final class AccountHelper { return; new FileDownloadTask(NetworkUtils.toURL(url), file, proxy).run(); } + + public static Image scale(String url, double scaleRatio) { + Image origin = new Image(url); + return new Image(url, + origin.getWidth() * scaleRatio, + origin.getHeight() * scaleRatio, + false, false); + } + + public static Image getSteveSkin(double scaleRatio) { + return scale("/assets/img/steve.png", 4); + } + + public static Image getAlexSkin(double scaleRatio) { + return scale("/assets/img/alex.png", 4); + } + + public static Image getDefaultSkin(Account account, double scaleRatio) { + if (account == null) + return getSteveSkin(scaleRatio); + + int type = account.getUUID().hashCode() & 1; + if (type == 1) + return getAlexSkin(scaleRatio); + else + return getSteveSkin(scaleRatio); + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Locales.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Locales.java index a42894ff8..17210c6b4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Locales.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Locales.java @@ -54,7 +54,7 @@ public final class Locales { */ public static final SupportedLocale RU = new SupportedLocale(new Locale("ru")); - public static final List LOCALES = Arrays.asList(DEFAULT, EN, ZH, ZH_CN, VI, RU); + public static final List LOCALES = Arrays.asList(DEFAULT, ZH_CN); public static SupportedLocale getLocale(int index) { return Lang.get(LOCALES, index).orElse(DEFAULT); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AccountItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AccountItem.java index c9a69add0..2c73a2543 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AccountItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AccountItem.java @@ -96,7 +96,8 @@ public final class AccountItem extends StackPane { }); AccountHelper.loadSkinAsync((YggdrasilAccount) account) .subscribe(Schedulers.javafx(), this::loadSkin); - } + } else + loadSkin(); if (account instanceof OfflineAccount) { // Offline Account cannot be refreshed, buttonPane.getChildren().remove(btnRefresh); @@ -104,12 +105,12 @@ public final class AccountItem extends StackPane { } private void loadSkin() { - if (!(account instanceof YggdrasilAccount)) - return; - pgsSkin.setVisible(false); portraitView.setViewport(AccountHelper.getViewport(4)); - portraitView.setImage(AccountHelper.getSkin((YggdrasilAccount) account, 4)); + if (account instanceof YggdrasilAccount) + portraitView.setImage(AccountHelper.getSkin((YggdrasilAccount) account, 4)); + else + portraitView.setImage(AccountHelper.getDefaultSkin(account, 4)); FXUtils.limitSize(portraitView, 32, 32); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index 0b436d871..63b803b0a 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -150,7 +150,10 @@ public final class Controllers { } public static void navigate(Node node) { - decorator.showPage(node); + if (decorator.getNowPage() == node) + decorator.showPage(null); + else + decorator.showPage(node); } public static void showUpdate() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java index c5e4f800f..a595acf76 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java @@ -418,6 +418,10 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza private String category; private Node nowPage; + public Node getNowPage() { + return nowPage; + } + public void showPage(Node content) { contentPlaceHolder.getStyleClass().removeAll("gray-background", "white-background"); if (content != null) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java index 17fa34f65..e36a62936 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java @@ -68,7 +68,7 @@ public final class LeftPaneController { iconedItem.prefWidthProperty().bind(leftPane.widthProperty()); iconedItem.setOnMouseClicked(e -> Controllers.navigate(Controllers.getSettingsPage())); })) - .startCategory(Main.i18n("profile").toUpperCase()) + .startCategory(Main.i18n("profile.title").toUpperCase()) .add(profilePane); EventBus.EVENT_BUS.channel(ProfileLoadingEvent.class).register(this::onProfilesLoading); @@ -90,23 +90,22 @@ public final class LeftPaneController { if (it instanceof YggdrasilAccount) { Image image = AccountHelper.getSkin((YggdrasilAccount) it, 4); - if (image == FXUtils.DEFAULT_ICON) - accountItem.setImage(FXUtils.DEFAULT_ICON, null); - else - accountItem.setImage(image, AccountHelper.getViewport(4)); + accountItem.setImage(image, AccountHelper.getViewport(4)); } else - accountItem.setImage(FXUtils.DEFAULT_ICON, null); + accountItem.setImage(AccountHelper.getDefaultSkin(it, 4), AccountHelper.getViewport(4)); }); } private void onProfileChanged(ProfileChangedEvent event) { Profile profile = event.getProfile(); - for (Node node : profilePane.getChildren()) { - if (node instanceof RipplerContainer && node.getProperties().get("profile") instanceof Pair) { - ((RipplerContainer) node).setSelected(Objects.equals(((Pair) node.getProperties().get("profile")).getKey(), profile.getName())); + Platform.runLater(() -> { + for (Node node : profilePane.getChildren()) { + if (node instanceof RipplerContainer && node.getProperties().get("profile") instanceof Pair) { + ((RipplerContainer) node).setSelected(Objects.equals(((Pair) node.getProperties().get("profile")).getKey(), profile.getName())); + } } - } + }); } private void onProfilesLoading() { diff --git a/HMCL/src/main/resources/assets/fxml/account-item.fxml b/HMCL/src/main/resources/assets/fxml/account-item.fxml index cd420287c..6465b0f0c 100644 --- a/HMCL/src/main/resources/assets/fxml/account-item.fxml +++ b/HMCL/src/main/resources/assets/fxml/account-item.fxml @@ -48,7 +48,6 @@ - diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 4e2b093f8..8fb5758bc 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -285,6 +285,7 @@ profile.instance_directory=Game Directory profile.new=New Config profile.new_name=New Profile Name: profile.remove=Sure to remove profile %s? +profile.title=Game Directories selector.choose=Choose selector.choose_file=Select a file diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 35b9f1677..d69d1d399 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -161,7 +161,7 @@ launch.unsupported_launcher_version=对不起,本启动器现在可能不能 launch.wrong_javadir=错误的Java路径,将自动重置为默认Java路径。 launcher=启动器 -launcher.about=默认背景图感谢gamerteam提供。\n关于作者:\n百度ID:huanghongxun20\nmcbbs:huanghongxun\nMinecraft Forum ID: klkl6523\n欢迎提交Bug哦\nCopyright (c) 2013-2017 huangyuhui.\n免责声明:Minecraft软件版权归Mojang AB所有,\n使用本软件产生的版权问题本软件制作方概不负责。\n本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,\n感谢issues和pull requests贡献者\n本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。 +launcher.about=默认背景图感谢gamerteam提供。\n关于作者:\n百度ID:huanghongxun20; mcbbs:huanghongxun; Minecraft Forum ID: klkl6523\nCopyright (c) 2018 huangyuhui.\n免责声明:Minecraft软件版权归Mojang AB所有,\n使用本软件产生的版权问题本软件制作方概不负责。\n本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,\n感谢issues和pull requests贡献者\n本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。 launcher.background_location=背景地址 launcher.background_tooltip=启动器默认使用自带的背景\n如果当前目录有background.png,则会使用该文件作为背景\n如果当前目录有bg子目录,则会随机使用里面的一张图作为背景\n如果该背景地址被修改,则会使用背景地址里的一张图作为背景\n背景地址允许有多个地址,使用半角分号";"(不包含双引号)分隔 launcher.choose_bgpath=选择背景路径 @@ -285,6 +285,7 @@ profile.instance_directory=游戏路径 profile.new=新建配置 profile.new_name=新配置名: profile.remove=真的要删除配置%s吗? +profile.title=游戏目录 selector.choose=选择 selector.choose_file=选择文件 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 323849fcf..7ea665ae4 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 java.net.Proxy; import java.util.HashMap; import java.util.Map; +import java.util.UUID; /** * @@ -32,6 +33,11 @@ public abstract class Account { */ public abstract String getUsername(); + /** + * @return the UUID + */ + public abstract UUID getUUID(); + /** * log in. * @param selector selects a character diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/OfflineAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/OfflineAccount.java index 69b229aef..e7c0ede0b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/OfflineAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/OfflineAccount.java @@ -20,10 +20,12 @@ package org.jackhuang.hmcl.auth; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.StringUtils; +import org.jackhuang.hmcl.util.UUIDTypeAdapter; import java.net.Proxy; import java.util.Map; import java.util.Objects; +import java.util.UUID; /** * @@ -45,8 +47,8 @@ public class OfflineAccount extends Account { throw new IllegalArgumentException("Username cannot be blank"); } - public String getUuid() { - return uuid; + public UUID getUUID() { + return UUIDTypeAdapter.fromString(uuid); } @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 ea87d16e2..b3e691932 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 @@ -244,6 +244,13 @@ public final class YggdrasilAccount extends Account { } } + public UUID getUUID() { + if (getSelectedProfile() == null) + return null; + else + return getSelectedProfile().getId(); + } + public Optional getSkin(GameProfile profile) throws IOException, JsonParseException { if (StringUtils.isBlank(userId)) throw new IllegalStateException("Not logged in");