Skip to content

Commit 3a30e5b

Browse files
burningtntGlavoCopilot
authored
修复 Terracotta 在 macOS 上的兼容性问题 (#4723)
Co-authored-by: Glavo <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 49b0a99 commit 3a30e5b

File tree

3 files changed

+51
-29
lines changed

3 files changed

+51
-29
lines changed

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

Lines changed: 4 additions & 7 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;
@@ -141,12 +142,7 @@ public static TerracottaState.Preparing install(@Nullable Path file) {
141142
return null;
142143
}
143144

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

151147
Task.supplyAsync(Schedulers.io(), () -> {
152148
return file != null ? TarFileTree.open(file) : null;
@@ -171,6 +167,7 @@ public static TerracottaState.Preparing install(@Nullable Path file) {
171167
if (compareAndSet(preparing, launching)) {
172168
launch(launching);
173169
}
170+
} else if (exception instanceof CancellationException) {
174171
} else if (exception instanceof ITerracottaProvider.ArchiveFileMissingException) {
175172
LOG.warning("Cannot install terracotta from local package.", exception);
176173
compareAndSet(preparing, new TerracottaState.Fatal(TerracottaState.Fatal.Type.INSTALL));
@@ -181,7 +178,7 @@ public static TerracottaState.Preparing install(@Nullable Path file) {
181178
}
182179
}).start();
183180

184-
return setState(preparing);
181+
return compareAndSet(state, preparing) ? preparing : null;
185182
}
186183

187184
private static ITerracottaProvider getProvider() {

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/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)