mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 04:16:02 -04:00
默认限制离线账户功能 (#3823)
This commit is contained in:
parent
b4945a150e
commit
cc16f84992
@ -190,9 +190,9 @@ tasks.build {
|
|||||||
dependsOn(makeExecutables)
|
dependsOn(makeExecutables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseToolOptions(options: String?): List<String> {
|
fun parseToolOptions(options: String?): MutableList<String> {
|
||||||
if (options == null)
|
if (options == null)
|
||||||
return listOf()
|
return mutableListOf()
|
||||||
|
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
val result = mutableListOf<String>()
|
val result = mutableListOf<String>()
|
||||||
@ -249,6 +249,9 @@ tasks.create<JavaExec>("run") {
|
|||||||
workingDir = rootProject.rootDir
|
workingDir = rootProject.rootDir
|
||||||
|
|
||||||
val vmOptions = parseToolOptions(System.getenv("HMCL_JAVA_OPTS"))
|
val vmOptions = parseToolOptions(System.getenv("HMCL_JAVA_OPTS"))
|
||||||
|
if (vmOptions.none { it.startsWith("-Dhmcl.offline.auth.restricted=") })
|
||||||
|
vmOptions += "-Dhmcl.offline.auth.restricted=false"
|
||||||
|
|
||||||
jvmArgs(vmOptions)
|
jvmArgs(vmOptions)
|
||||||
|
|
||||||
val hmclJavaHome = System.getenv("HMCL_JAVA_HOME")
|
val hmclJavaHome = System.getenv("HMCL_JAVA_HOME")
|
||||||
|
@ -22,6 +22,7 @@ import javafx.beans.Observable;
|
|||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.auth.*;
|
import org.jackhuang.hmcl.auth.*;
|
||||||
@ -50,6 +51,7 @@ import java.util.*;
|
|||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static javafx.collections.FXCollections.observableArrayList;
|
import static javafx.collections.FXCollections.observableArrayList;
|
||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
|
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating;
|
import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating;
|
||||||
import static org.jackhuang.hmcl.util.Lang.immutableListOf;
|
import static org.jackhuang.hmcl.util.Lang.immutableListOf;
|
||||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||||
@ -277,6 +279,30 @@ public final class Accounts {
|
|||||||
selected = accounts.get(0);
|
selected = accounts.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!globalConfig().isEnableOfflineAccount())
|
||||||
|
for (Account account : accounts) {
|
||||||
|
if (account instanceof MicrosoftAccount) {
|
||||||
|
globalConfig().setEnableOfflineAccount(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalConfig().isEnableOfflineAccount())
|
||||||
|
accounts.addListener(new ListChangeListener<Account>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Change<? extends Account> change) {
|
||||||
|
while (change.next()) {
|
||||||
|
for (Account account : change.getAddedSubList()) {
|
||||||
|
if (account instanceof MicrosoftAccount) {
|
||||||
|
accounts.removeListener(this);
|
||||||
|
globalConfig().setEnableOfflineAccount(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
selectedAccount.set(selected);
|
selectedAccount.set(selected);
|
||||||
|
|
||||||
InvalidationListener listener = o -> {
|
InvalidationListener listener = o -> {
|
||||||
|
@ -21,7 +21,9 @@ import com.google.gson.*;
|
|||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableSet;
|
import javafx.collections.ObservableSet;
|
||||||
@ -53,6 +55,8 @@ public final class GlobalConfig implements Observable {
|
|||||||
|
|
||||||
private final IntegerProperty logRetention = new SimpleIntegerProperty();
|
private final IntegerProperty logRetention = new SimpleIntegerProperty();
|
||||||
|
|
||||||
|
private final BooleanProperty enableOfflineAccount = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
private final ObservableSet<String> userJava = FXCollections.observableSet(new LinkedHashSet<>());
|
private final ObservableSet<String> userJava = FXCollections.observableSet(new LinkedHashSet<>());
|
||||||
|
|
||||||
private final ObservableSet<String> disabledJava = FXCollections.observableSet(new LinkedHashSet<>());
|
private final ObservableSet<String> disabledJava = FXCollections.observableSet(new LinkedHashSet<>());
|
||||||
@ -115,6 +119,18 @@ public final class GlobalConfig implements Observable {
|
|||||||
this.logRetention.set(logRetention);
|
this.logRetention.set(logRetention);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEnableOfflineAccount() {
|
||||||
|
return enableOfflineAccount.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty enableOfflineAccountProperty() {
|
||||||
|
return enableOfflineAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableOfflineAccount(boolean value) {
|
||||||
|
enableOfflineAccount.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableSet<String> getUserJava() {
|
public ObservableSet<String> getUserJava() {
|
||||||
return userJava;
|
return userJava;
|
||||||
}
|
}
|
||||||
@ -129,7 +145,8 @@ public final class GlobalConfig implements Observable {
|
|||||||
"platformPromptVersion",
|
"platformPromptVersion",
|
||||||
"logRetention",
|
"logRetention",
|
||||||
"userJava",
|
"userJava",
|
||||||
"disabledJava"
|
"disabledJava",
|
||||||
|
"enableOfflineAccount"
|
||||||
));
|
));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -142,6 +159,9 @@ public final class GlobalConfig implements Observable {
|
|||||||
jsonObject.add("agreementVersion", context.serialize(src.getAgreementVersion()));
|
jsonObject.add("agreementVersion", context.serialize(src.getAgreementVersion()));
|
||||||
jsonObject.add("platformPromptVersion", context.serialize(src.getPlatformPromptVersion()));
|
jsonObject.add("platformPromptVersion", context.serialize(src.getPlatformPromptVersion()));
|
||||||
jsonObject.add("logRetention", context.serialize(src.getLogRetention()));
|
jsonObject.add("logRetention", context.serialize(src.getLogRetention()));
|
||||||
|
if (src.enableOfflineAccount.get())
|
||||||
|
jsonObject.addProperty("enableOfflineAccount", true);
|
||||||
|
|
||||||
if (!src.getUserJava().isEmpty())
|
if (!src.getUserJava().isEmpty())
|
||||||
jsonObject.add("userJava", context.serialize(src.getUserJava()));
|
jsonObject.add("userJava", context.serialize(src.getUserJava()));
|
||||||
|
|
||||||
@ -165,6 +185,7 @@ public final class GlobalConfig implements Observable {
|
|||||||
config.setAgreementVersion(Optional.ofNullable(obj.get("agreementVersion")).map(JsonElement::getAsInt).orElse(0));
|
config.setAgreementVersion(Optional.ofNullable(obj.get("agreementVersion")).map(JsonElement::getAsInt).orElse(0));
|
||||||
config.setPlatformPromptVersion(Optional.ofNullable(obj.get("platformPromptVersion")).map(JsonElement::getAsInt).orElse(0));
|
config.setPlatformPromptVersion(Optional.ofNullable(obj.get("platformPromptVersion")).map(JsonElement::getAsInt).orElse(0));
|
||||||
config.setLogRetention(Optional.ofNullable(obj.get("logRetention")).map(JsonElement::getAsInt).orElse(20));
|
config.setLogRetention(Optional.ofNullable(obj.get("logRetention")).map(JsonElement::getAsInt).orElse(20));
|
||||||
|
config.setEnableOfflineAccount(Optional.ofNullable(obj.get("enableOfflineAccount")).map(JsonElement::getAsBoolean).orElse(false));
|
||||||
|
|
||||||
JsonElement userJava = obj.get("userJava");
|
JsonElement userJava = obj.get("userJava");
|
||||||
if (userJava != null && userJava.isJsonArray()) {
|
if (userJava != null && userJava.isJsonArray()) {
|
||||||
|
@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui.account;
|
|||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
@ -44,14 +45,37 @@ import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
|||||||
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
|
||||||
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
|
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
|
||||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor;
|
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor;
|
||||||
|
|
||||||
public class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage {
|
public final class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||||
|
static final BooleanProperty RESTRICTED = new SimpleBooleanProperty(true);
|
||||||
|
|
||||||
|
static {
|
||||||
|
String property = System.getProperty("hmcl.offline.auth.restricted", "auto");
|
||||||
|
|
||||||
|
if ("false".equals(property)
|
||||||
|
|| "auto".equals(property) && "Asia/Shanghai".equals(ZoneId.systemDefault().getId())
|
||||||
|
|| globalConfig().isEnableOfflineAccount())
|
||||||
|
RESTRICTED.set(false);
|
||||||
|
else
|
||||||
|
globalConfig().enableOfflineAccountProperty().addListener(new ChangeListener<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Boolean> o, Boolean oldValue, Boolean newValue) {
|
||||||
|
if (newValue) {
|
||||||
|
globalConfig().enableOfflineAccountProperty().removeListener(this);
|
||||||
|
RESTRICTED.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private final ObservableList<AccountListItem> items;
|
private final ObservableList<AccountListItem> items;
|
||||||
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("account.manage")));
|
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("account.manage")));
|
||||||
private final ListProperty<Account> accounts = new SimpleListProperty<>(this, "accounts", FXCollections.observableArrayList());
|
private final ListProperty<Account> accounts = new SimpleListProperty<>(this, "accounts", FXCollections.observableArrayList());
|
||||||
@ -88,6 +112,7 @@ public class AccountListPage extends DecoratorAnimatedPage implements DecoratorP
|
|||||||
private static class AccountListPageSkin extends DecoratorAnimatedPageSkin<AccountListPage> {
|
private static class AccountListPageSkin extends DecoratorAnimatedPageSkin<AccountListPage> {
|
||||||
|
|
||||||
private final ObservableList<AdvancedListItem> authServerItems;
|
private final ObservableList<AdvancedListItem> authServerItems;
|
||||||
|
private ChangeListener<Boolean> holder;
|
||||||
|
|
||||||
public AccountListPageSkin(AccountListPage skinnable) {
|
public AccountListPageSkin(AccountListPage skinnable) {
|
||||||
super(skinnable);
|
super(skinnable);
|
||||||
@ -96,24 +121,21 @@ public class AccountListPage extends DecoratorAnimatedPage implements DecoratorP
|
|||||||
VBox boxMethods = new VBox();
|
VBox boxMethods = new VBox();
|
||||||
{
|
{
|
||||||
boxMethods.getStyleClass().add("advanced-list-box-content");
|
boxMethods.getStyleClass().add("advanced-list-box-content");
|
||||||
boxMethods.getChildren().add(new ClassTitle(i18n("account.create").toUpperCase(Locale.ROOT)));
|
|
||||||
FXUtils.setLimitWidth(boxMethods, 200);
|
FXUtils.setLimitWidth(boxMethods, 200);
|
||||||
|
|
||||||
AdvancedListItem offlineItem = new AdvancedListItem();
|
|
||||||
offlineItem.getStyleClass().add("navigation-drawer-item");
|
|
||||||
offlineItem.setActionButtonVisible(false);
|
|
||||||
offlineItem.setTitle(i18n("account.methods.offline"));
|
|
||||||
offlineItem.setLeftGraphic(wrap(SVG.PERSON));
|
|
||||||
offlineItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_OFFLINE)));
|
|
||||||
boxMethods.getChildren().add(offlineItem);
|
|
||||||
|
|
||||||
AdvancedListItem microsoftItem = new AdvancedListItem();
|
AdvancedListItem microsoftItem = new AdvancedListItem();
|
||||||
microsoftItem.getStyleClass().add("navigation-drawer-item");
|
microsoftItem.getStyleClass().add("navigation-drawer-item");
|
||||||
microsoftItem.setActionButtonVisible(false);
|
microsoftItem.setActionButtonVisible(false);
|
||||||
microsoftItem.setTitle(i18n("account.methods.microsoft"));
|
microsoftItem.setTitle(i18n("account.methods.microsoft"));
|
||||||
microsoftItem.setLeftGraphic(wrap(SVG.MICROSOFT));
|
microsoftItem.setLeftGraphic(wrap(SVG.MICROSOFT));
|
||||||
microsoftItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_MICROSOFT)));
|
microsoftItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_MICROSOFT)));
|
||||||
boxMethods.getChildren().add(microsoftItem);
|
|
||||||
|
AdvancedListItem offlineItem = new AdvancedListItem();
|
||||||
|
offlineItem.getStyleClass().add("navigation-drawer-item");
|
||||||
|
offlineItem.setActionButtonVisible(false);
|
||||||
|
offlineItem.setTitle(i18n("account.methods.offline"));
|
||||||
|
offlineItem.setLeftGraphic(wrap(SVG.PERSON));
|
||||||
|
offlineItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_OFFLINE)));
|
||||||
|
|
||||||
VBox boxAuthServers = new VBox();
|
VBox boxAuthServers = new VBox();
|
||||||
authServerItems = MappedObservableList.create(skinnable.authServersProperty(), server -> {
|
authServerItems = MappedObservableList.create(skinnable.authServersProperty(), server -> {
|
||||||
@ -149,7 +171,29 @@ public class AccountListPage extends DecoratorAnimatedPage implements DecoratorP
|
|||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
Bindings.bindContent(boxAuthServers.getChildren(), authServerItems);
|
Bindings.bindContent(boxAuthServers.getChildren(), authServerItems);
|
||||||
boxMethods.getChildren().add(boxAuthServers);
|
|
||||||
|
ClassTitle title = new ClassTitle(i18n("account.create").toUpperCase(Locale.ROOT));
|
||||||
|
if (RESTRICTED.get()) {
|
||||||
|
VBox wrapper = new VBox(offlineItem, boxAuthServers);
|
||||||
|
wrapper.setPadding(Insets.EMPTY);
|
||||||
|
FXUtils.installFastTooltip(wrapper, i18n("account.login.restricted"));
|
||||||
|
|
||||||
|
offlineItem.setDisable(true);
|
||||||
|
boxAuthServers.setDisable(true);
|
||||||
|
|
||||||
|
boxMethods.getChildren().setAll(title, microsoftItem, wrapper);
|
||||||
|
|
||||||
|
holder = FXUtils.onWeakChange(RESTRICTED, value -> {
|
||||||
|
if (!value) {
|
||||||
|
holder = null;
|
||||||
|
offlineItem.setDisable(false);
|
||||||
|
boxAuthServers.setDisable(false);
|
||||||
|
boxMethods.getChildren().setAll(title, microsoftItem, offlineItem, boxAuthServers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
boxMethods.getChildren().setAll(title, microsoftItem, offlineItem, boxAuthServers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvancedListItem addAuthServerItem = new AdvancedListItem();
|
AdvancedListItem addAuthServerItem = new AdvancedListItem();
|
||||||
|
@ -108,12 +108,17 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
|
|
||||||
public CreateAccountPane(AccountFactory<?> factory) {
|
public CreateAccountPane(AccountFactory<?> factory) {
|
||||||
if (factory == null) {
|
if (factory == null) {
|
||||||
showMethodSwitcher = true;
|
if (AccountListPage.RESTRICTED.get()) {
|
||||||
String preferred = config().getPreferredLoginType();
|
showMethodSwitcher = false;
|
||||||
try {
|
factory = Accounts.FACTORY_MICROSOFT;
|
||||||
factory = Accounts.getAccountFactory(preferred);
|
} else {
|
||||||
} catch (IllegalArgumentException e) {
|
showMethodSwitcher = true;
|
||||||
factory = Accounts.FACTORY_OFFLINE;
|
String preferred = config().getPreferredLoginType();
|
||||||
|
try {
|
||||||
|
factory = Accounts.getAccountFactory(preferred);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
factory = Accounts.FACTORY_OFFLINE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showMethodSwitcher = false;
|
showMethodSwitcher = false;
|
||||||
|
@ -88,6 +88,7 @@ account.login.skip=Log in offline
|
|||||||
account.login.retry=Retry
|
account.login.retry=Retry
|
||||||
account.login.refresh=Log in again
|
account.login.refresh=Log in again
|
||||||
account.login.refresh.microsoft.hint=You need to log in to your Microsoft account again because the account authorization is invalid.
|
account.login.refresh.microsoft.hint=You need to log in to your Microsoft account again because the account authorization is invalid.
|
||||||
|
account.login.restricted=Sign in to your Microsoft account to enable this feature
|
||||||
account.logout=Logout
|
account.logout=Logout
|
||||||
account.register=Register
|
account.register=Register
|
||||||
account.manage=Account List
|
account.manage=Account List
|
||||||
|
@ -91,6 +91,7 @@ account.login.skip=跳過重新整理帳戶
|
|||||||
account.login.retry=再次重新整理帳戶
|
account.login.retry=再次重新整理帳戶
|
||||||
account.login.refresh=重新登入
|
account.login.refresh=重新登入
|
||||||
account.login.refresh.microsoft.hint=由於帳戶授權失效,你需要重新加入 Microsoft 帳戶
|
account.login.refresh.microsoft.hint=由於帳戶授權失效,你需要重新加入 Microsoft 帳戶
|
||||||
|
account.login.restricted=登入微軟帳戶以啟用此功能
|
||||||
account.logout=登出
|
account.logout=登出
|
||||||
account.register=註冊
|
account.register=註冊
|
||||||
account.manage=帳戶清單
|
account.manage=帳戶清單
|
||||||
|
@ -92,6 +92,7 @@ account.login.skip=跳过账户刷新
|
|||||||
account.login.retry=再次刷新账户
|
account.login.retry=再次刷新账户
|
||||||
account.login.refresh=重新登录
|
account.login.refresh=重新登录
|
||||||
account.login.refresh.microsoft.hint=由于账户授权失效,你需要重新添加微软账户。
|
account.login.refresh.microsoft.hint=由于账户授权失效,你需要重新添加微软账户。
|
||||||
|
account.login.restricted=登录微软账户以启用此功能
|
||||||
account.logout=登出
|
account.logout=登出
|
||||||
account.register=注册
|
account.register=注册
|
||||||
account.manage=账户列表
|
account.manage=账户列表
|
||||||
|
Loading…
x
Reference in New Issue
Block a user