Skip to content

Commit b98c1af

Browse files
committed
Merge commit 'refs/pull/3823/head' of https://github.com/HMCL-dev/HMCL into prs
2 parents 766c770 + 0f15d34 commit b98c1af

8 files changed

Lines changed: 123 additions & 21 deletions

File tree

HMCL/build.gradle.kts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ tasks.build {
190190
dependsOn(makeExecutables)
191191
}
192192

193-
fun parseToolOptions(options: String?): List<String> {
193+
fun parseToolOptions(options: String?): MutableList<String> {
194194
if (options == null)
195-
return listOf()
195+
return mutableListOf()
196196

197197
val builder = StringBuilder()
198198
val result = mutableListOf<String>()
@@ -249,6 +249,9 @@ tasks.create<JavaExec>("run") {
249249
workingDir = rootProject.rootDir
250250

251251
val vmOptions = parseToolOptions(System.getenv("HMCL_JAVA_OPTS"))
252+
if (vmOptions.none { it.startsWith("-Dhmcl.offline.auth.restricted=") })
253+
vmOptions += "-Dhmcl.offline.auth.restricted=false"
254+
252255
jvmArgs(vmOptions)
253256

254257
val hmclJavaHome = System.getenv("HMCL_JAVA_HOME")

HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import javafx.beans.property.ObjectProperty;
2323
import javafx.beans.property.SimpleObjectProperty;
2424
import javafx.collections.FXCollections;
25+
import javafx.collections.ListChangeListener;
2526
import javafx.collections.ObservableList;
2627
import org.jackhuang.hmcl.Metadata;
2728
import org.jackhuang.hmcl.auth.*;
@@ -50,6 +51,7 @@
5051
import static java.util.stream.Collectors.toList;
5152
import static javafx.collections.FXCollections.observableArrayList;
5253
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
54+
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
5355
import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating;
5456
import static org.jackhuang.hmcl.util.Lang.immutableListOf;
5557
import static org.jackhuang.hmcl.util.Lang.mapOf;
@@ -277,6 +279,30 @@ static void init() {
277279
selected = accounts.get(0);
278280
}
279281

282+
if (!globalConfig().isEnableOfflineAccount())
283+
for (Account account : accounts) {
284+
if (account instanceof MicrosoftAccount) {
285+
globalConfig().setEnableOfflineAccount(true);
286+
break;
287+
}
288+
}
289+
290+
if (!globalConfig().isEnableOfflineAccount())
291+
accounts.addListener(new ListChangeListener<Account>() {
292+
@Override
293+
public void onChanged(Change<? extends Account> change) {
294+
while (change.next()) {
295+
for (Account account : change.getAddedSubList()) {
296+
if (account instanceof MicrosoftAccount) {
297+
accounts.removeListener(this);
298+
globalConfig().setEnableOfflineAccount(true);
299+
return;
300+
}
301+
}
302+
}
303+
}
304+
});
305+
280306
selectedAccount.set(selected);
281307

282308
InvalidationListener listener = o -> {

HMCL/src/main/java/org/jackhuang/hmcl/setting/GlobalConfig.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import com.google.gson.annotations.JsonAdapter;
2222
import javafx.beans.InvalidationListener;
2323
import javafx.beans.Observable;
24+
import javafx.beans.property.BooleanProperty;
2425
import javafx.beans.property.IntegerProperty;
26+
import javafx.beans.property.SimpleBooleanProperty;
2527
import javafx.beans.property.SimpleIntegerProperty;
2628
import javafx.collections.FXCollections;
2729
import javafx.collections.ObservableSet;
@@ -53,6 +55,8 @@ public static GlobalConfig fromJson(String json) throws JsonParseException {
5355

5456
private final IntegerProperty logRetention = new SimpleIntegerProperty();
5557

58+
private final BooleanProperty enableOfflineAccount = new SimpleBooleanProperty(false);
59+
5660
private final ObservableSet<String> userJava = FXCollections.observableSet(new LinkedHashSet<>());
5761

5862
private final ObservableSet<String> disabledJava = FXCollections.observableSet(new LinkedHashSet<>());
@@ -115,6 +119,18 @@ public void setLogRetention(int logRetention) {
115119
this.logRetention.set(logRetention);
116120
}
117121

122+
public boolean isEnableOfflineAccount() {
123+
return enableOfflineAccount.get();
124+
}
125+
126+
public BooleanProperty enableOfflineAccountProperty() {
127+
return enableOfflineAccount;
128+
}
129+
130+
public void setEnableOfflineAccount(boolean value) {
131+
enableOfflineAccount.set(value);
132+
}
133+
118134
public ObservableSet<String> getUserJava() {
119135
return userJava;
120136
}
@@ -129,7 +145,8 @@ public static final class Serializer implements JsonSerializer<GlobalConfig>, Js
129145
"platformPromptVersion",
130146
"logRetention",
131147
"userJava",
132-
"disabledJava"
148+
"disabledJava",
149+
"enableOfflineAccount"
133150
));
134151

135152
@Override
@@ -142,6 +159,9 @@ public JsonElement serialize(GlobalConfig src, Type typeOfSrc, JsonSerialization
142159
jsonObject.add("agreementVersion", context.serialize(src.getAgreementVersion()));
143160
jsonObject.add("platformPromptVersion", context.serialize(src.getPlatformPromptVersion()));
144161
jsonObject.add("logRetention", context.serialize(src.getLogRetention()));
162+
if (src.enableOfflineAccount.get())
163+
jsonObject.addProperty("enableOfflineAccount", true);
164+
145165
if (!src.getUserJava().isEmpty())
146166
jsonObject.add("userJava", context.serialize(src.getUserJava()));
147167

@@ -165,6 +185,7 @@ public GlobalConfig deserialize(JsonElement json, Type typeOfT, JsonDeserializat
165185
config.setAgreementVersion(Optional.ofNullable(obj.get("agreementVersion")).map(JsonElement::getAsInt).orElse(0));
166186
config.setPlatformPromptVersion(Optional.ofNullable(obj.get("platformPromptVersion")).map(JsonElement::getAsInt).orElse(0));
167187
config.setLogRetention(Optional.ofNullable(obj.get("logRetention")).map(JsonElement::getAsInt).orElse(20));
188+
config.setEnableOfflineAccount(Optional.ofNullable(obj.get("enableOfflineAccount")).map(JsonElement::getAsBoolean).orElse(false));
168189

169190
JsonElement userJava = obj.get("userJava");
170191
if (userJava != null && userJava.isJsonArray()) {

HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.jfoenix.controls.JFXButton;
2121
import javafx.beans.binding.Bindings;
2222
import javafx.beans.property.*;
23+
import javafx.beans.value.ChangeListener;
2324
import javafx.beans.value.ObservableValue;
2425
import javafx.collections.FXCollections;
2526
import javafx.collections.ObservableList;
@@ -44,14 +45,37 @@
4445
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
4546

4647
import java.net.URI;
48+
import java.time.ZoneId;
4749
import java.util.Locale;
4850

51+
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
4952
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
5053
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
5154
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
5255
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor;
5356

54-
public class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage {
57+
public final class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage {
58+
static final BooleanProperty RESTRICTED = new SimpleBooleanProperty(true);
59+
60+
static {
61+
String property = System.getProperty("hmcl.offline.auth.restricted", "auto");
62+
63+
if ("false".equals(property)
64+
|| "auto".equals(property) && "Asia/Shanghai".equals(ZoneId.systemDefault().getId())
65+
|| globalConfig().isEnableOfflineAccount())
66+
RESTRICTED.set(false);
67+
else
68+
globalConfig().enableOfflineAccountProperty().addListener(new ChangeListener<Boolean>() {
69+
@Override
70+
public void changed(ObservableValue<? extends Boolean> o, Boolean oldValue, Boolean newValue) {
71+
if (newValue) {
72+
globalConfig().enableOfflineAccountProperty().removeListener(this);
73+
RESTRICTED.set(false);
74+
}
75+
}
76+
});
77+
}
78+
5579
private final ObservableList<AccountListItem> items;
5680
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("account.manage")));
5781
private final ListProperty<Account> accounts = new SimpleListProperty<>(this, "accounts", FXCollections.observableArrayList());
@@ -88,6 +112,7 @@ protected Skin<?> createDefaultSkin() {
88112
private static class AccountListPageSkin extends DecoratorAnimatedPageSkin<AccountListPage> {
89113

90114
private final ObservableList<AdvancedListItem> authServerItems;
115+
private ChangeListener<Boolean> holder;
91116

92117
public AccountListPageSkin(AccountListPage skinnable) {
93118
super(skinnable);
@@ -96,24 +121,21 @@ public AccountListPageSkin(AccountListPage skinnable) {
96121
VBox boxMethods = new VBox();
97122
{
98123
boxMethods.getStyleClass().add("advanced-list-box-content");
99-
boxMethods.getChildren().add(new ClassTitle(i18n("account.create").toUpperCase(Locale.ROOT)));
100124
FXUtils.setLimitWidth(boxMethods, 200);
101125

102-
AdvancedListItem offlineItem = new AdvancedListItem();
103-
offlineItem.getStyleClass().add("navigation-drawer-item");
104-
offlineItem.setActionButtonVisible(false);
105-
offlineItem.setTitle(i18n("account.methods.offline"));
106-
offlineItem.setLeftGraphic(wrap(SVG.PERSON));
107-
offlineItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_OFFLINE)));
108-
boxMethods.getChildren().add(offlineItem);
109-
110126
AdvancedListItem microsoftItem = new AdvancedListItem();
111127
microsoftItem.getStyleClass().add("navigation-drawer-item");
112128
microsoftItem.setActionButtonVisible(false);
113129
microsoftItem.setTitle(i18n("account.methods.microsoft"));
114130
microsoftItem.setLeftGraphic(wrap(SVG.MICROSOFT));
115131
microsoftItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_MICROSOFT)));
116-
boxMethods.getChildren().add(microsoftItem);
132+
133+
AdvancedListItem offlineItem = new AdvancedListItem();
134+
offlineItem.getStyleClass().add("navigation-drawer-item");
135+
offlineItem.setActionButtonVisible(false);
136+
offlineItem.setTitle(i18n("account.methods.offline"));
137+
offlineItem.setLeftGraphic(wrap(SVG.PERSON));
138+
offlineItem.setOnAction(e -> Controllers.dialog(new CreateAccountPane(Accounts.FACTORY_OFFLINE)));
117139

118140
VBox boxAuthServers = new VBox();
119141
authServerItems = MappedObservableList.create(skinnable.authServersProperty(), server -> {
@@ -149,7 +171,29 @@ public AccountListPageSkin(AccountListPage skinnable) {
149171
return item;
150172
});
151173
Bindings.bindContent(boxAuthServers.getChildren(), authServerItems);
152-
boxMethods.getChildren().add(boxAuthServers);
174+
175+
ClassTitle title = new ClassTitle(i18n("account.create").toUpperCase(Locale.ROOT));
176+
if (RESTRICTED.get()) {
177+
VBox wrapper = new VBox(offlineItem, boxAuthServers);
178+
wrapper.setPadding(Insets.EMPTY);
179+
FXUtils.installFastTooltip(wrapper, i18n("account.login.restricted"));
180+
181+
offlineItem.setDisable(true);
182+
boxAuthServers.setDisable(true);
183+
184+
boxMethods.getChildren().setAll(title, microsoftItem, wrapper);
185+
186+
holder = FXUtils.onWeakChange(RESTRICTED, value -> {
187+
if (!value) {
188+
holder = null;
189+
offlineItem.setDisable(false);
190+
boxAuthServers.setDisable(false);
191+
boxMethods.getChildren().setAll(title, microsoftItem, offlineItem, boxAuthServers);
192+
}
193+
});
194+
} else {
195+
boxMethods.getChildren().setAll(title, microsoftItem, offlineItem, boxAuthServers);
196+
}
153197
}
154198

155199
AdvancedListItem addAuthServerItem = new AdvancedListItem();

HMCL/src/main/java/org/jackhuang/hmcl/ui/account/CreateAccountPane.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,17 @@ public CreateAccountPane() {
108108

109109
public CreateAccountPane(AccountFactory<?> factory) {
110110
if (factory == null) {
111-
showMethodSwitcher = true;
112-
String preferred = config().getPreferredLoginType();
113-
try {
114-
factory = Accounts.getAccountFactory(preferred);
115-
} catch (IllegalArgumentException e) {
116-
factory = Accounts.FACTORY_OFFLINE;
111+
if (AccountListPage.RESTRICTED.get()) {
112+
showMethodSwitcher = false;
113+
factory = Accounts.FACTORY_MICROSOFT;
114+
} else {
115+
showMethodSwitcher = true;
116+
String preferred = config().getPreferredLoginType();
117+
try {
118+
factory = Accounts.getAccountFactory(preferred);
119+
} catch (IllegalArgumentException e) {
120+
factory = Accounts.FACTORY_OFFLINE;
121+
}
117122
}
118123
} else {
119124
showMethodSwitcher = false;

HMCL/src/main/resources/assets/lang/I18N.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ account.login.skip=Log in offline
8888
account.login.retry=Retry
8989
account.login.refresh=Log in again
9090
account.login.refresh.microsoft.hint=You need to log in to your Microsoft account again because the account authorization is invalid.
91+
account.login.restricted=Sign in to your Microsoft account to enable this feature
9192
account.logout=Logout
9293
account.register=Register
9394
account.manage=Account List

HMCL/src/main/resources/assets/lang/I18N_zh.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ account.login.skip=跳過重新整理帳戶
9191
account.login.retry=再次重新整理帳戶
9292
account.login.refresh=重新登入
9393
account.login.refresh.microsoft.hint=由於帳戶授權失效,你需要重新加入 Microsoft 帳戶
94+
account.login.restricted=登入微軟帳戶以啟用此功能
9495
account.logout=登出
9596
account.register=註冊
9697
account.manage=帳戶清單

HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ account.login.skip=跳过账户刷新
9292
account.login.retry=再次刷新账户
9393
account.login.refresh=重新登录
9494
account.login.refresh.microsoft.hint=由于账户授权失效,你需要重新添加微软账户。
95+
account.login.restricted=登录微软账户以启用此功能
9596
account.logout=登出
9697
account.register=注册
9798
account.manage=账户列表

0 commit comments

Comments
 (0)