Skip to content

Commit 6375558

Browse files
GlavoburningtntCopilot
authored
[release/3.7] 优化陶瓦联机 (#4751)
#4723 #4750 #4735 --------- Co-authored-by: Burning_TNT <pangyl08@163.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 12b525f commit 6375558

12 files changed

Lines changed: 709 additions & 85 deletions

File tree

HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaManager.java

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.net.URI;
4646
import java.nio.file.Files;
4747
import java.nio.file.Path;
48+
import java.util.concurrent.CancellationException;
4849
import java.util.concurrent.ThreadLocalRandom;
4950
import java.util.concurrent.atomic.AtomicReference;
5051
import java.util.concurrent.locks.LockSupport;
@@ -61,22 +62,20 @@ private TerracottaManager() {
6162
private static final InvocationDispatcher<TerracottaState> STATE_D = InvocationDispatcher.runOn(Platform::runLater, STATE::set);
6263

6364
static {
64-
Task.runAsync(() -> {
65-
if (TerracottaMetadata.PROVIDER == null) {
66-
setState(new TerracottaState.Fatal(TerracottaState.Fatal.Type.OS));
67-
LOG.warning("Terracotta hasn't support your OS: " + org.jackhuang.hmcl.util.platform.Platform.SYSTEM_PLATFORM);
68-
} else {
65+
Schedulers.io().execute(() -> {
66+
try {
67+
if (TerracottaMetadata.PROVIDER == null)
68+
throw new IOException("Unsupported platform: " + org.jackhuang.hmcl.util.platform.Platform.CURRENT_PLATFORM);
69+
6970
switch (TerracottaMetadata.PROVIDER.status()) {
7071
case NOT_EXIST -> setState(new TerracottaState.Uninitialized(false));
7172
case LEGACY_VERSION -> setState(new TerracottaState.Uninitialized(true));
7273
case READY -> launch(setState(new TerracottaState.Launching()));
7374
}
74-
}
75-
}).whenComplete(exception -> {
76-
if (exception != null) {
75+
} catch (Exception e) {
7776
compareAndSet(TerracottaState.Bootstrap.INSTANCE, new TerracottaState.Fatal(TerracottaState.Fatal.Type.UNKNOWN));
7877
}
79-
}).start();
78+
});
8079
}
8180

8281
public static ReadOnlyObjectProperty<TerracottaState> stateProperty() {
@@ -143,12 +142,7 @@ public static TerracottaState.Preparing install(@Nullable Path file) {
143142
return null;
144143
}
145144

146-
TerracottaState.Preparing preparing;
147-
if (state instanceof TerracottaState.Preparing it) {
148-
preparing = it;
149-
} else {
150-
preparing = new TerracottaState.Preparing(new ReadOnlyDoubleWrapper(-1));
151-
}
145+
TerracottaState.Preparing preparing = new TerracottaState.Preparing(new ReadOnlyDoubleWrapper(-1));
152146

153147
Task.supplyAsync(Schedulers.io(), () -> {
154148
return file != null ? TarFileTree.open(file) : null;
@@ -173,6 +167,7 @@ public static TerracottaState.Preparing install(@Nullable Path file) {
173167
if (compareAndSet(preparing, launching)) {
174168
launch(launching);
175169
}
170+
} else if (exception instanceof CancellationException) {
176171
} else if (exception instanceof ITerracottaProvider.ArchiveFileMissingException) {
177172
LOG.warning("Cannot install terracotta from local package.", exception);
178173
compareAndSet(preparing, new TerracottaState.Fatal(TerracottaState.Fatal.Type.INSTALL));
@@ -183,7 +178,7 @@ public static TerracottaState.Preparing install(@Nullable Path file) {
183178
}
184179
}).start();
185180

186-
return setState(preparing);
181+
return compareAndSet(state, preparing) ? preparing : null;
187182
}
188183

189184
private static ITerracottaProvider getProvider() {

HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ private static ProviderContext locateProvider(Config config) {
147147
String arch = Architecture.SYSTEM_ARCH.getCheckedName();
148148
return switch (OperatingSystem.CURRENT_OS) {
149149
case WINDOWS -> {
150-
if (!OperatingSystem.SYSTEM_VERSION.isAtLeast(OSVersion.WINDOWS_8_1))
150+
if (!OperatingSystem.SYSTEM_VERSION.isAtLeast(OSVersion.WINDOWS_10))
151151
yield null;
152152

153153
TerracottaNative target = config.of("windows-%s.exe".formatted(arch));

HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaState.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public Type getType() {
298298
}
299299

300300
public boolean isRecoverable() {
301-
return this.type != Type.OS && this.type != Type.UNKNOWN;
301+
return this.type != Type.UNKNOWN;
302302
}
303303
}
304304
}

HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
*/
1818
package org.jackhuang.hmcl.terracotta.provider;
1919

20+
import org.jackhuang.hmcl.Metadata;
2021
import org.jackhuang.hmcl.task.Task;
2122
import org.jackhuang.hmcl.terracotta.TerracottaNative;
23+
import org.jackhuang.hmcl.util.io.FileUtils;
2224
import org.jackhuang.hmcl.util.platform.ManagedProcess;
2325
import org.jackhuang.hmcl.util.platform.SystemUtils;
2426
import org.jackhuang.hmcl.util.tree.TarFileTree;
@@ -27,11 +29,13 @@
2729
import java.io.IOException;
2830
import java.nio.file.Files;
2931
import java.nio.file.Path;
32+
import java.nio.file.StandardCopyOption;
3033
import java.nio.file.attribute.PosixFilePermission;
3134
import java.util.List;
3235
import java.util.Set;
3336

3437
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
38+
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
3539

3640
public final class MacOSProvider implements ITerracottaProvider {
3741
public final TerracottaNative installer, binary;
@@ -62,19 +66,39 @@ public Task<?> install(Context context, @Nullable TarFileTree tree) throws IOExc
6266

6367
return Task.allOf(
6468
installerTask.thenComposeAsync(() -> {
69+
Path osascript = SystemUtils.which("osascript");
70+
if (osascript == null) {
71+
throw new IllegalStateException("Cannot locate 'osascript' system executable on MacOS for installing Terracotta.");
72+
}
73+
74+
Path pkg = Files.createTempDirectory(Metadata.HMCL_GLOBAL_DIRECTORY, "terracotta-pkg")
75+
.toRealPath()
76+
.resolve(FileUtils.getName(installer.getPath()));
77+
Files.copy(installer.getPath(), pkg, StandardCopyOption.REPLACE_EXISTING);
78+
6579
ManagedProcess process = new ManagedProcess(new ProcessBuilder(
66-
"osascript",
67-
"-e",
68-
String.format(
69-
"do shell script \"installer -pkg %s -target /\" with prompt \"%s\" with administrator privileges",
70-
installer.getPath(),
71-
i18n("terracotta.sudo_installing")
72-
)
73-
));
80+
osascript.toString(), "-e", String.format(
81+
"do shell script \"installer -pkg '%s' -target /\" with prompt \"%s\" with administrator privileges",
82+
pkg, i18n("terracotta.sudo_installing")
83+
)));
7484
process.pumpInputStream(SystemUtils::onLogLine);
7585
process.pumpErrorStream(SystemUtils::onLogLine);
7686

77-
return Task.fromCompletableFuture(process.getProcess().onExit());
87+
return Task.fromCompletableFuture(process.getProcess().onExit()).thenRunAsync(() -> {
88+
try {
89+
FileUtils.cleanDirectory(pkg.getParent());
90+
} catch (IOException e) {
91+
LOG.warning("Cannot remove temporary Terracotta package file.", e);
92+
}
93+
94+
if (process.getExitCode() != 0) {
95+
throw new IllegalStateException(String.format(
96+
"Cannot install Terracotta %s: system installer exited with code %d",
97+
pkg,
98+
process.getExitCode()
99+
));
100+
}
101+
});
78102
}),
79103
binaryTask.thenRunAsync(() -> Files.setPosixFilePermissions(binary.getPath(), Set.of(
80104
PosixFilePermission.OWNER_READ,

HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.jackhuang.hmcl.setting.Profiles;
3131
import org.jackhuang.hmcl.task.Schedulers;
3232
import org.jackhuang.hmcl.task.Task;
33+
import org.jackhuang.hmcl.terracotta.TerracottaMetadata;
3334
import org.jackhuang.hmcl.ui.Controllers;
3435
import org.jackhuang.hmcl.ui.FXUtils;
3536
import org.jackhuang.hmcl.ui.SVG;
@@ -49,6 +50,7 @@
4950
import org.jackhuang.hmcl.util.StringUtils;
5051
import org.jackhuang.hmcl.util.TaskCancellationAction;
5152
import org.jackhuang.hmcl.util.io.CompressingUtils;
53+
import org.jackhuang.hmcl.util.platform.*;
5254
import org.jackhuang.hmcl.util.versioning.VersionNumber;
5355

5456
import java.nio.file.Files;
@@ -186,7 +188,25 @@ protected Skin(RootPage control) {
186188
terracottaItem.setLeftGraphic(wrap(SVG.GRAPH2));
187189
terracottaItem.setActionButtonVisible(false);
188190
terracottaItem.setTitle(i18n("terracotta"));
189-
terracottaItem.setOnAction(e -> Controllers.navigate(Controllers.getTerracottaPage()));
191+
192+
terracottaItem.setOnAction(e -> {
193+
if (TerracottaMetadata.PROVIDER != null) {
194+
Controllers.navigate(Controllers.getTerracottaPage());
195+
} else {
196+
String message;
197+
if (Architecture.SYSTEM_ARCH.getBits() == Bits.BIT_32)
198+
message = i18n("terracotta.unsupported.arch.32bit");
199+
else if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS
200+
&& !OperatingSystem.SYSTEM_VERSION.isAtLeast(OSVersion.WINDOWS_10))
201+
message = i18n("terracotta.unsupported.os.windows.old");
202+
else if (Platform.SYSTEM_PLATFORM.equals(OperatingSystem.LINUX, Architecture.LOONGARCH64_OW))
203+
message = i18n("terracotta.unsupported.arch.loongarch64_ow");
204+
else
205+
message = i18n("terracotta.unsupported");
206+
207+
Controllers.dialog(message, null, MessageDialogPane.MessageType.WARNING);
208+
}
209+
});
190210

191211
// the left sidebar
192212
AdvancedListBox sideBar = new AdvancedListBox()

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,6 @@ terracotta.status.exception.desc.host_et_crash=Failed to create room: EasyTier c
14771477
terracotta.status.exception.desc.ping_server_rst=Room closed: You exited the game world, room closed automatically
14781478
terracotta.status.exception.desc.scaffolding_invalid_response=Invalid Protocol:Host has sent invalid response, please report this issue to developers
14791479
terracotta.status.fatal.retry=Retry
1480-
terracotta.status.fatal.os=Sorry, HMCL cannot enable Terracotta | Multiplayer on your operating system or architecture. Please use a more modern operating system.
14811480
terracotta.status.fatal.network=Failed to download Multiplayer Core. Please check your network connection and try again.
14821481
terracotta.status.fatal.install=Fatal Error: Unable to install Multiplayer Core.
14831482
terracotta.status.fatal.terracotta=Fatal Error: Unable to connect to Multiplayer Core.
@@ -1487,6 +1486,10 @@ terracotta.player_anonymous=Anonymous Player
14871486
terracotta.player_kind.host=Host
14881487
terracotta.player_kind.local=Yourself
14891488
terracotta.player_kind.guest=Guest
1489+
terracotta.unsupported=Multiplayer is not yet supported on the current platform.
1490+
terracotta.unsupported.os.windows.old=Multiplayer requires Windows 10 or later. Please update your system.
1491+
terracotta.unsupported.arch.32bit=Multiplayer is not supported on 32-bit systems. Please upgrade to a 64-bit system.
1492+
terracotta.unsupported.arch.loongarch64_ow=Multiplayer is not supported on Linux LoongArch64 Old World distributions. Please update to a New World distribution (such as AOSC OS).
14901493

14911494
unofficial.hint=You are using an unofficial build of HMCL. We cannot guarantee its security.
14921495

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,6 @@ terracotta.status.exception.desc.host_et_crash=建立房間失敗:EasyTier 已
12651265
terracotta.status.exception.desc.ping_server_rst=房間已關閉:您已退出遊戲存檔,房間已自動關閉
12661266
terracotta.status.exception.desc.scaffolding_invalid_response=協議錯誤:房主發送了錯誤的回應資料,請向開發者回報該問題
12671267
terracotta.status.fatal.retry=重試
1268-
terracotta.status.fatal.os=抱歉,HMCL 不能在您的作業系統或架構上啟用多人連線。請使用更主流的作業系統
12691268
terracotta.status.fatal.network=未能下載線上核心。請檢查網路連接,然後再試一次
12701269
terracotta.status.fatal.install=嚴重錯誤:無法安裝線上核心
12711270
terracotta.status.fatal.terracotta=嚴重錯誤:無法與線上核心通訊
@@ -1275,6 +1274,10 @@ terracotta.player_anonymous=匿名玩家
12751274
terracotta.player_kind.host=房主
12761275
terracotta.player_kind.local=
12771276
terracotta.player_kind.guest=房客
1277+
terracotta.unsupported=多人聯機功能尚未支援目前平台。
1278+
terracotta.unsupported.os.windows.old=多人聯機功能需要 Windows 10 或更高版本。請更新系統。
1279+
terracotta.unsupported.arch.32bit=多人聯機功能不支援 32 位元系統。請更新至 64 位元系統。
1280+
terracotta.unsupported.arch.loongarch64_ow=多人聯機功能不支援 Linux LoongArch64 舊世界發行版,請更新至新世界發行版 (如 AOSC OC)。
12781281

12791282
unofficial.hint=你正在使用第三方提供的 HMCL。我們無法保證其安全性,請注意甄別。
12801283

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,6 @@ terracotta.status.exception.desc.host_et_crash=创建房间失败:EasyTier 已
12751275
terracotta.status.exception.desc.ping_server_rst=房间已关闭:您已退出游戏存档,房间已自动关闭
12761276
terracotta.status.exception.desc.scaffolding_invalid_response=协议错误:房主发送了错误的响应数据,请向开发者反馈该问题
12771277
terracotta.status.fatal.retry=重试
1278-
terracotta.status.fatal.os=抱歉,HMCL 不能在您的操作系统或架构上启用多人联机。请使用更主流的操作系统
12791278
terracotta.status.fatal.network=未能下载联机核心。请检查网络连接,然后再试一次
12801279
terracotta.status.fatal.install=严重错误:无法安装联机核心
12811280
terracotta.status.fatal.terracotta=严重错误:无法与联机核心通讯
@@ -1285,6 +1284,10 @@ terracotta.player_anonymous=匿名玩家
12851284
terracotta.player_kind.host=房主
12861285
terracotta.player_kind.local=
12871286
terracotta.player_kind.guest=房客
1287+
terracotta.unsupported=多人联机功能尚不支持当前平台。
1288+
terracotta.unsupported.os.windows.old=多人联机功能需要 Windows 10 或更高版本。请更新系统。
1289+
terracotta.unsupported.arch.32bit=多人联机功能不支持 32 位系统。请更新至 64 位系统。
1290+
terracotta.unsupported.arch.loongarch64_ow=多人联机功能不支持 Linux LoongArch64 旧世界发行版,请更新至新世界发行版 (如 AOSC OC)。
12881291

12891292
unofficial.hint=你正在使用非官方构建的 HMCL。我们无法保证其安全性,请注意甄别。
12901293

HMCL/src/main/resources/assets/terracotta.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
{
2-
"version_legacy": "0\\.3\\.([89]-rc\\.([0-9]|10)|10|11)",
2+
"version_legacy": "0\\.3\\.([89]-rc\\.([0-9]|10)|10|11|12)",
33
"version_recent": [
4-
"0.3.11"
4+
"0.3.12"
55
],
6-
"version_latest": "0.3.12",
6+
"version_latest": "0.3.13",
77
"classifiers": {
8-
"linux-arm64": "sha256:cb88933f539d287419b9a83960bfdd8252dd2a850cbb39008491916c8a8ee25b",
9-
"linux-x86_64": "sha256:b329fed4157999f1be504a63ea2f5c95985d440435fba2f3b4604dced340572a",
10-
"linux-loongarch64": "sha256:9e6b1beb90817339ca8b40b3e26bd064505cc789d1c5f7df80659d91971042b6",
11-
"linux-riscv64": "sha256:58dde78047e3e0317cc935bfa6db0c2c3f6608fea15f545aa83d78a921805fc4",
12-
"macos-arm64": "sha256:282f47dd0e2667da44b0bef74a87d41d9e568c224515d2f230d2ef25edb1f628",
13-
"macos-arm64.pkg": "sha256:295974ec16d5a69006126d574efe16e7622ab67e85d35cd03020f38670cf3313",
14-
"macos-x86_64": "sha256:8cf097ae87b6f8fdb4a3543176ecc526922201446c18170e779ffff0cc62ec01",
15-
"macos-x86_64.pkg": "sha256:bfc1f4c121c107b3371b56e83cad80924be9016db3c3b39a9db7ae579dbaf1e2",
16-
"windows-arm64.exe": "sha256:cfa93fbc426002dbd25e376457db2a27be101907f568d91e1f92adfcf1b69cb8",
17-
"windows-x86_64.exe": "sha256:2153b676295cf059ca2ac08178e1d3754eb0007c947378cd1ae2ef2b9f7a2a4f"
8+
"freebsd-x86_64": "sha256:0713e54ee552496416bda9d9e814e33a8950ca8f321f5b3c6dd2e07e79b0e3af",
9+
"linux-arm64": "sha256:61affc46035337c182adeca3671b4cf4cc59c7b4e73039899f35416f7d00ad94",
10+
"linux-x86_64": "sha256:9399e1627b77d518950e66d944c9a4b70c20d2e13ca2c0e2fed0ded637e7ae06",
11+
"linux-loongarch64": "sha256:f3eb4c40dfccc25b5b355298c776abe3d399afb57a2af38803dd78089f0c182e",
12+
"linux-riscv64": "sha256:26f95f8b5f83746c9cf9a8362ce0ef793ede8515897a1ba15e5e6f93c3d39533",
13+
"macos-arm64": "sha256:35ba271c7dc924e91c2fdd8c1cabeff2ce3d060836748a7a07162b0a5900e8d5",
14+
"macos-arm64.pkg": "sha256:90a613ec69f28713fe06188247c57b7cc91743c95112de5aed85ea252103beaa",
15+
"macos-x86_64": "sha256:45b420b15a32d5450794a9776cf45a217871cf4333b29b65a35d7358c806b5b1",
16+
"macos-x86_64.pkg": "sha256:587623becb3593ccb5fe542a201a67ab3a4029dfa847fcef758faff7ba6d38d5",
17+
"windows-arm64.exe": "sha256:bd4e1acf2f304761cdabddd9ade94d046534f4c024bc3026ac98e6be58c2bc22",
18+
"windows-x86_64.exe": "sha256:b89599bbcc92b00222cfc6f2e5ef636b7daf192c96efba1049a892e6cb59ee70"
1819
},
1920
"downloads": [
2021
"https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}"

0 commit comments

Comments
 (0)