@kzheart_/mc-pilot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mct +2 -0
- package/data/variants.json +139 -0
- package/dist/client/ClientManager.d.ts +82 -0
- package/dist/client/ClientManager.js +213 -0
- package/dist/client/WebSocketClient.d.ts +15 -0
- package/dist/client/WebSocketClient.js +76 -0
- package/dist/commands/block.d.ts +2 -0
- package/dist/commands/block.js +52 -0
- package/dist/commands/book.d.ts +2 -0
- package/dist/commands/book.js +21 -0
- package/dist/commands/channel.d.ts +2 -0
- package/dist/commands/channel.js +24 -0
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +31 -0
- package/dist/commands/client.d.ts +2 -0
- package/dist/commands/client.js +87 -0
- package/dist/commands/combat.d.ts +2 -0
- package/dist/commands/combat.js +46 -0
- package/dist/commands/craft.d.ts +5 -0
- package/dist/commands/craft.js +45 -0
- package/dist/commands/effects.d.ts +2 -0
- package/dist/commands/effects.js +16 -0
- package/dist/commands/entity.d.ts +2 -0
- package/dist/commands/entity.js +53 -0
- package/dist/commands/gui.d.ts +2 -0
- package/dist/commands/gui.js +49 -0
- package/dist/commands/hud.d.ts +2 -0
- package/dist/commands/hud.js +16 -0
- package/dist/commands/input.d.ts +2 -0
- package/dist/commands/input.js +124 -0
- package/dist/commands/inventory.d.ts +2 -0
- package/dist/commands/inventory.js +28 -0
- package/dist/commands/look.d.ts +2 -0
- package/dist/commands/look.js +37 -0
- package/dist/commands/move.d.ts +2 -0
- package/dist/commands/move.js +50 -0
- package/dist/commands/position.d.ts +2 -0
- package/dist/commands/position.js +7 -0
- package/dist/commands/request-helpers.d.ts +26 -0
- package/dist/commands/request-helpers.js +58 -0
- package/dist/commands/resourcepack.d.ts +2 -0
- package/dist/commands/resourcepack.js +9 -0
- package/dist/commands/rotation.d.ts +2 -0
- package/dist/commands/rotation.js +7 -0
- package/dist/commands/screen.d.ts +2 -0
- package/dist/commands/screen.js +7 -0
- package/dist/commands/screenshot.d.ts +2 -0
- package/dist/commands/screenshot.js +14 -0
- package/dist/commands/server.d.ts +2 -0
- package/dist/commands/server.js +66 -0
- package/dist/commands/sign.d.ts +2 -0
- package/dist/commands/sign.js +30 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +17 -0
- package/dist/commands/wait.d.ts +2 -0
- package/dist/commands/wait.js +23 -0
- package/dist/download/CacheManager.d.ts +20 -0
- package/dist/download/CacheManager.js +50 -0
- package/dist/download/DownloadUtils.d.ts +2 -0
- package/dist/download/DownloadUtils.js +23 -0
- package/dist/download/JavaDetector.d.ts +7 -0
- package/dist/download/JavaDetector.js +31 -0
- package/dist/download/ModVariantCatalog.d.ts +10 -0
- package/dist/download/ModVariantCatalog.js +52 -0
- package/dist/download/SearchCommand.d.ts +29 -0
- package/dist/download/SearchCommand.js +37 -0
- package/dist/download/VersionMatrix.d.ts +72 -0
- package/dist/download/VersionMatrix.js +227 -0
- package/dist/download/client/Arm64LwjglPatcher.d.ts +5 -0
- package/dist/download/client/Arm64LwjglPatcher.js +153 -0
- package/dist/download/client/ClientDownloader.d.ts +42 -0
- package/dist/download/client/ClientDownloader.js +233 -0
- package/dist/download/client/FabricRuntimeDownloader.d.ts +10 -0
- package/dist/download/client/FabricRuntimeDownloader.js +91 -0
- package/dist/download/server/ServerDownloader.d.ts +51 -0
- package/dist/download/server/ServerDownloader.js +196 -0
- package/dist/download/types.d.ts +37 -0
- package/dist/download/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +89 -0
- package/dist/server/ServerManager.d.ts +63 -0
- package/dist/server/ServerManager.js +114 -0
- package/dist/util/command.d.ts +10 -0
- package/dist/util/command.js +35 -0
- package/dist/util/config.d.ts +30 -0
- package/dist/util/config.js +59 -0
- package/dist/util/context.d.ts +17 -0
- package/dist/util/context.js +16 -0
- package/dist/util/errors.d.ts +20 -0
- package/dist/util/errors.js +37 -0
- package/dist/util/net.d.ts +5 -0
- package/dist/util/net.js +35 -0
- package/dist/util/output.d.ts +4 -0
- package/dist/util/output.js +23 -0
- package/dist/util/process.d.ts +3 -0
- package/dist/util/process.js +32 -0
- package/dist/util/state.d.ts +10 -0
- package/dist/util/state.js +40 -0
- package/package.json +54 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { loadModVariantCatalogSync } from "./ModVariantCatalog.js";
|
|
2
|
+
const VERSION_MATRIX = [
|
|
3
|
+
{
|
|
4
|
+
minecraftVersion: "1.21.4",
|
|
5
|
+
javaVersion: "21+",
|
|
6
|
+
servers: {
|
|
7
|
+
vanilla: { supported: true },
|
|
8
|
+
paper: { supported: true, latestBuild: 170 },
|
|
9
|
+
purpur: { supported: true, latestBuild: 2406 },
|
|
10
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
11
|
+
},
|
|
12
|
+
clients: {
|
|
13
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0", validation: "verified" },
|
|
14
|
+
forge: { supported: false, notes: "不支持此版本" },
|
|
15
|
+
neoforge: { supported: true, loaderVersion: "21.4.x", modVersion: "0.1.0" }
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
minecraftVersion: "1.21.1",
|
|
20
|
+
javaVersion: "21+",
|
|
21
|
+
servers: {
|
|
22
|
+
vanilla: { supported: true },
|
|
23
|
+
paper: { supported: true, latestBuild: 119 },
|
|
24
|
+
purpur: { supported: true, latestBuild: 2324 },
|
|
25
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
26
|
+
},
|
|
27
|
+
clients: {
|
|
28
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0", validation: "verified" },
|
|
29
|
+
forge: { supported: false, notes: "不支持此版本" },
|
|
30
|
+
neoforge: { supported: true, loaderVersion: "21.1.x", modVersion: "0.1.0" }
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
minecraftVersion: "1.20.4",
|
|
35
|
+
javaVersion: "17+",
|
|
36
|
+
servers: {
|
|
37
|
+
vanilla: { supported: true },
|
|
38
|
+
paper: { supported: true, latestBuild: 496 },
|
|
39
|
+
purpur: { supported: true, latestBuild: 2176 },
|
|
40
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
41
|
+
},
|
|
42
|
+
clients: {
|
|
43
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0" },
|
|
44
|
+
forge: { supported: true, loaderVersion: "49.0.49", modVersion: "0.1.0" },
|
|
45
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
minecraftVersion: "1.20.3",
|
|
50
|
+
javaVersion: "17+",
|
|
51
|
+
servers: {
|
|
52
|
+
vanilla: { supported: true },
|
|
53
|
+
paper: { supported: false },
|
|
54
|
+
purpur: { supported: false },
|
|
55
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
56
|
+
},
|
|
57
|
+
clients: {
|
|
58
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0", validation: "verified" },
|
|
59
|
+
forge: { supported: false, notes: "当前未接入此 loader" },
|
|
60
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
minecraftVersion: "1.20.2",
|
|
65
|
+
javaVersion: "17+",
|
|
66
|
+
servers: {
|
|
67
|
+
vanilla: { supported: true },
|
|
68
|
+
paper: { supported: true, latestBuild: 318 },
|
|
69
|
+
purpur: { supported: true, latestBuild: 2095 },
|
|
70
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
71
|
+
},
|
|
72
|
+
clients: {
|
|
73
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0" },
|
|
74
|
+
forge: { supported: false, notes: "当前未接入此 loader" },
|
|
75
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
minecraftVersion: "1.20.1",
|
|
80
|
+
javaVersion: "17+",
|
|
81
|
+
servers: {
|
|
82
|
+
vanilla: { supported: true },
|
|
83
|
+
paper: { supported: true, latestBuild: 196 },
|
|
84
|
+
purpur: { supported: true, latestBuild: 2062 },
|
|
85
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
86
|
+
},
|
|
87
|
+
clients: {
|
|
88
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0" },
|
|
89
|
+
forge: { supported: true, loaderVersion: "47.x", modVersion: "0.1.0" },
|
|
90
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
minecraftVersion: "1.18.2",
|
|
95
|
+
javaVersion: "17+",
|
|
96
|
+
servers: {
|
|
97
|
+
vanilla: { supported: true },
|
|
98
|
+
paper: { supported: true, latestBuild: 388 },
|
|
99
|
+
purpur: { supported: false },
|
|
100
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
101
|
+
},
|
|
102
|
+
clients: {
|
|
103
|
+
fabric: { supported: true, loaderVersion: "0.16.10", modVersion: "0.1.0", validation: "verified" },
|
|
104
|
+
forge: { supported: true, loaderVersion: "40.x", modVersion: "0.1.0" },
|
|
105
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
minecraftVersion: "1.16.5",
|
|
110
|
+
javaVersion: "8+",
|
|
111
|
+
servers: {
|
|
112
|
+
vanilla: { supported: true },
|
|
113
|
+
paper: { supported: true, latestBuild: 794 },
|
|
114
|
+
purpur: { supported: false },
|
|
115
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
116
|
+
},
|
|
117
|
+
clients: {
|
|
118
|
+
fabric: { supported: false, notes: "当前未接入此版本 mod" },
|
|
119
|
+
forge: { supported: true, loaderVersion: "36.x", modVersion: "0.1.0" },
|
|
120
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
minecraftVersion: "1.12.2",
|
|
125
|
+
javaVersion: "8+",
|
|
126
|
+
servers: {
|
|
127
|
+
vanilla: { supported: true },
|
|
128
|
+
paper: { supported: true, latestBuild: 1620 },
|
|
129
|
+
purpur: { supported: false },
|
|
130
|
+
spigot: { supported: true, requiresBuildTools: true }
|
|
131
|
+
},
|
|
132
|
+
clients: {
|
|
133
|
+
fabric: { supported: false, notes: "不支持此版本" },
|
|
134
|
+
forge: { supported: true, loaderVersion: "14.23.x", modVersion: "0.1.0" },
|
|
135
|
+
neoforge: { supported: false, notes: "不支持此版本" }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
];
|
|
139
|
+
function overlayClientSupport(entry, loader) {
|
|
140
|
+
const catalog = loadModVariantCatalogSync();
|
|
141
|
+
const variant = catalog.variants.find((candidate) => candidate.minecraftVersion === entry.minecraftVersion && candidate.loader === loader);
|
|
142
|
+
if (!variant) {
|
|
143
|
+
return { ...entry.clients[loader] };
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
supported: variant.support === "ready" || variant.support === "configured",
|
|
147
|
+
loaderVersion: variant.fabricLoaderVersion ?? variant.forgeVersion ?? variant.neoforgeVersion,
|
|
148
|
+
modVersion: variant.modVersion,
|
|
149
|
+
validation: variant.validation,
|
|
150
|
+
notes: variant.notes
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export function getVersionMatrix() {
|
|
154
|
+
return VERSION_MATRIX.map((entry) => ({
|
|
155
|
+
minecraftVersion: entry.minecraftVersion,
|
|
156
|
+
javaVersion: entry.javaVersion,
|
|
157
|
+
servers: { ...entry.servers },
|
|
158
|
+
clients: {
|
|
159
|
+
fabric: overlayClientSupport(entry, "fabric"),
|
|
160
|
+
forge: overlayClientSupport(entry, "forge"),
|
|
161
|
+
neoforge: overlayClientSupport(entry, "neoforge")
|
|
162
|
+
}
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
export function getSupportedMinecraftVersions() {
|
|
166
|
+
return VERSION_MATRIX.map((entry) => entry.minecraftVersion);
|
|
167
|
+
}
|
|
168
|
+
export function getMinecraftSupport(version) {
|
|
169
|
+
return VERSION_MATRIX.find((entry) => entry.minecraftVersion === version);
|
|
170
|
+
}
|
|
171
|
+
export function searchServerVersions(filter) {
|
|
172
|
+
const types = filter?.type ? [filter.type] : getServerTypes();
|
|
173
|
+
const entries = filter?.version ? VERSION_MATRIX.filter((entry) => entry.minecraftVersion === filter.version) : VERSION_MATRIX;
|
|
174
|
+
return types.flatMap((type) => entries.map((entry) => ({
|
|
175
|
+
type,
|
|
176
|
+
minecraftVersion: entry.minecraftVersion,
|
|
177
|
+
supported: entry.servers[type].supported,
|
|
178
|
+
latestBuild: entry.servers[type].latestBuild,
|
|
179
|
+
requiresBuildTools: entry.servers[type].requiresBuildTools
|
|
180
|
+
})));
|
|
181
|
+
}
|
|
182
|
+
export function searchClientVersions(filter) {
|
|
183
|
+
const loaders = filter?.loader ? [filter.loader] : getClientLoaders();
|
|
184
|
+
const entries = filter?.version ? VERSION_MATRIX.filter((entry) => entry.minecraftVersion === filter.version) : VERSION_MATRIX;
|
|
185
|
+
return loaders.flatMap((loader) => entries.map((entry) => {
|
|
186
|
+
const support = overlayClientSupport(entry, loader);
|
|
187
|
+
return {
|
|
188
|
+
loader,
|
|
189
|
+
minecraftVersion: entry.minecraftVersion,
|
|
190
|
+
supported: support.supported,
|
|
191
|
+
...(support.loaderVersion ? { loaderVersion: support.loaderVersion } : {}),
|
|
192
|
+
...(support.modVersion ? { modVersion: support.modVersion } : {}),
|
|
193
|
+
...(support.validation ? { validation: support.validation } : {}),
|
|
194
|
+
...(support.notes ? { notes: support.notes } : {}),
|
|
195
|
+
javaVersion: entry.javaVersion
|
|
196
|
+
};
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
export function getServerVersionMatrix() {
|
|
200
|
+
return searchServerVersions();
|
|
201
|
+
}
|
|
202
|
+
export function getClientVersionMatrix() {
|
|
203
|
+
return searchClientVersions();
|
|
204
|
+
}
|
|
205
|
+
export function getServerVersionCatalog() {
|
|
206
|
+
return getServerTypes().reduce((catalog, type) => {
|
|
207
|
+
catalog[type] = VERSION_MATRIX
|
|
208
|
+
.filter((entry) => entry.servers[type].supported)
|
|
209
|
+
.map((entry) => ({
|
|
210
|
+
version: entry.minecraftVersion,
|
|
211
|
+
build: entry.servers[type].latestBuild != null ? String(entry.servers[type].latestBuild) : undefined,
|
|
212
|
+
requiresBuildTools: entry.servers[type].requiresBuildTools
|
|
213
|
+
}));
|
|
214
|
+
return catalog;
|
|
215
|
+
}, {
|
|
216
|
+
vanilla: [],
|
|
217
|
+
paper: [],
|
|
218
|
+
purpur: [],
|
|
219
|
+
spigot: []
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
export function getServerTypes() {
|
|
223
|
+
return ["vanilla", "paper", "purpur", "spigot"];
|
|
224
|
+
}
|
|
225
|
+
export function getClientLoaders() {
|
|
226
|
+
return ["fabric", "forge", "neoforge"];
|
|
227
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export interface Arm64PatchDependencies {
|
|
2
|
+
fetchImpl?: typeof fetch;
|
|
3
|
+
}
|
|
4
|
+
export declare function needsArm64Patch(): boolean;
|
|
5
|
+
export declare function applyArm64LwjglPatch(runtimeRoot: string, versionId: string, dependencies?: Arm64PatchDependencies): Promise<string | null>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { MinecraftFolder } from "@xmcl/core";
|
|
5
|
+
const LWJGL_ARM64_PATCH = {
|
|
6
|
+
patchVersion: "3.3.1",
|
|
7
|
+
jars: {
|
|
8
|
+
"org.lwjgl:lwjgl": { path: "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar", url: "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar", sha1: "ae58664f88e18a9bb2c77b063833ca7aaec484cb", size: 0 },
|
|
9
|
+
"org.lwjgl:lwjgl-jemalloc": { path: "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar", url: "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1.jar", sha1: "a817bcf213db49f710603677457567c37d53e103", size: 0 },
|
|
10
|
+
"org.lwjgl:lwjgl-openal": { path: "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar", url: "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1.jar", sha1: "2623a6b8ae1dfcd880738656a9f0243d2e6840bd", size: 0 },
|
|
11
|
+
"org.lwjgl:lwjgl-opengl": { path: "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar", url: "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1.jar", sha1: "831a5533a21a5f4f81bbc51bb13e9899319b5411", size: 0 },
|
|
12
|
+
"org.lwjgl:lwjgl-stb": { path: "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar", url: "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1.jar", sha1: "b119297cf8ed01f247abe8685857f8e7fcf5980f", size: 0 },
|
|
13
|
+
"org.lwjgl:lwjgl-tinyfd": { path: "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar", url: "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1.jar", sha1: "0ff1914111ef2e3e0110ef2dabc8d8cdaad82347", size: 0 },
|
|
14
|
+
"org.lwjgl:lwjgl-glfw": { path: "org/glavo/hmcl/mmachina/lwjgl-glfw/3.3.1-mmachina.1/lwjgl-glfw-3.3.1-mmachina.1.jar", url: "https://repo1.maven.org/maven2/org/glavo/hmcl/mmachina/lwjgl-glfw/3.3.1-mmachina.1/lwjgl-glfw-3.3.1-mmachina.1.jar", sha1: "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", size: 0 }
|
|
15
|
+
},
|
|
16
|
+
natives: {
|
|
17
|
+
"org.lwjgl:lwjgl": { path: "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar", sha1: "71d0d5e469c9c95351eb949064497e3391616ac9", size: 0 },
|
|
18
|
+
"org.lwjgl:lwjgl-jemalloc": { path: "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar", sha1: "e577b87d8ad2ade361aaea2fcf226c660b15dee8", size: 0 },
|
|
19
|
+
"org.lwjgl:lwjgl-openal": { path: "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar", sha1: "23d55e7490b57495320f6c9e1936d78fd72c4ef8", size: 0 },
|
|
20
|
+
"org.lwjgl:lwjgl-opengl": { path: "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar", sha1: "eafe34b871d966292e8db0f1f3d6b8b110d4e91d", size: 0 },
|
|
21
|
+
"org.lwjgl:lwjgl-stb": { path: "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar", sha1: "fcf073ed911752abdca5f0b00a53cfdf17ff8e8b", size: 0 },
|
|
22
|
+
"org.lwjgl:lwjgl-tinyfd": { path: "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar", sha1: "972ecc17bad3571e81162153077b4d47b7b9eaa9", size: 0 },
|
|
23
|
+
"org.lwjgl:lwjgl-glfw": { path: "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar", url: "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar", sha1: "cac0d3f712a3da7641fa174735a5f315de7ffe0a", size: 0 }
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export function needsArm64Patch() {
|
|
27
|
+
return os.arch() === "arm64" && os.platform() === "darwin";
|
|
28
|
+
}
|
|
29
|
+
async function downloadJar(entry, minecraft, fetchImpl) {
|
|
30
|
+
const localPath = minecraft.getLibraryByPath(entry.path);
|
|
31
|
+
try {
|
|
32
|
+
await access(localPath);
|
|
33
|
+
return localPath;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
console.error(`[MCT] Downloading ${path.basename(entry.path)}...`);
|
|
37
|
+
const response = await fetchImpl(entry.url);
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
throw new Error(`HTTP ${response.status}: ${entry.url}`);
|
|
40
|
+
}
|
|
41
|
+
await mkdir(path.dirname(localPath), { recursive: true });
|
|
42
|
+
await writeFile(localPath, Buffer.from(await response.arrayBuffer()));
|
|
43
|
+
return localPath;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export async function applyArm64LwjglPatch(runtimeRoot, versionId, dependencies = {}) {
|
|
47
|
+
if (!needsArm64Patch()) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
51
|
+
const minecraft = MinecraftFolder.from(runtimeRoot);
|
|
52
|
+
const nativesDir = minecraft.getNativesRoot(versionId);
|
|
53
|
+
// Walk version JSON chain to detect old LWJGL 3.2.x
|
|
54
|
+
let targetJsonPath = minecraft.getVersionJson(versionId);
|
|
55
|
+
let needsJsonPatch = false;
|
|
56
|
+
for (let depth = 0; depth < 5; depth++) {
|
|
57
|
+
const raw = await readFile(targetJsonPath, "utf-8").catch(() => null);
|
|
58
|
+
if (!raw) {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
const json = JSON.parse(raw);
|
|
62
|
+
if ((json.libraries || []).some((lib) => lib.name?.startsWith("org.lwjgl:lwjgl:3.2"))) {
|
|
63
|
+
needsJsonPatch = true;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
if ((json.libraries || []).some((lib) => lib.name?.startsWith("org.lwjgl:lwjgl:3.3"))) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
if (!json.inheritsFrom) {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
targetJsonPath = minecraft.getVersionJson(json.inheritsFrom);
|
|
73
|
+
}
|
|
74
|
+
if (!needsJsonPatch) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
console.error("[MCT] Applying LWJGL 3.3.1 arm64 patch (based on HMCL NativePatcher)...");
|
|
78
|
+
const { open, walkEntriesGenerator, openEntryReadStream } = await import("@xmcl/unzip");
|
|
79
|
+
const { createWriteStream } = await import("node:fs");
|
|
80
|
+
const { pipeline } = await import("node:stream");
|
|
81
|
+
const { promisify } = await import("node:util");
|
|
82
|
+
const pipelineAsync = promisify(pipeline);
|
|
83
|
+
// 1. Download and extract arm64 natives
|
|
84
|
+
await mkdir(nativesDir, { recursive: true });
|
|
85
|
+
for (const [libKey, entry] of Object.entries(LWJGL_ARM64_PATCH.natives)) {
|
|
86
|
+
const localJar = await downloadJar(entry, minecraft, fetchImpl).catch((e) => { console.error(`[MCT] Skip ${libKey}: ${e.message}`); return null; });
|
|
87
|
+
if (!localJar) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const zip = await open(localJar, { lazyEntries: true, autoClose: false });
|
|
91
|
+
for await (const zipEntry of walkEntriesGenerator(zip)) {
|
|
92
|
+
const name = zipEntry.fileName;
|
|
93
|
+
if (!name.endsWith(".dylib") || name.endsWith("/")) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const dest = path.join(nativesDir, path.basename(name));
|
|
97
|
+
await pipelineAsync(await openEntryReadStream(zip, zipEntry), createWriteStream(dest));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// 2. Download Java JARs
|
|
101
|
+
for (const [libKey, entry] of Object.entries(LWJGL_ARM64_PATCH.jars)) {
|
|
102
|
+
await downloadJar(entry, minecraft, fetchImpl).catch((e) => console.error(`[MCT] Skip ${libKey}: ${e.message}`));
|
|
103
|
+
}
|
|
104
|
+
// 3. Patch vanilla version JSON to swap LWJGL 3.2.x -> 3.3.1
|
|
105
|
+
let curJsonPath = minecraft.getVersionJson(versionId);
|
|
106
|
+
for (let depth = 0; depth < 5; depth++) {
|
|
107
|
+
const raw = await readFile(curJsonPath, "utf-8").catch(() => null);
|
|
108
|
+
if (!raw) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
const json = JSON.parse(raw);
|
|
112
|
+
const hasOldLwjgl = (json.libraries || []).some((lib) => lib.name?.startsWith("org.lwjgl:lwjgl:3.2"));
|
|
113
|
+
if (hasOldLwjgl) {
|
|
114
|
+
const newLibraries = [];
|
|
115
|
+
for (const lib of json.libraries) {
|
|
116
|
+
const name = lib.name || "";
|
|
117
|
+
const parts = name.split(":");
|
|
118
|
+
const baseKey = parts.slice(0, 2).join(":");
|
|
119
|
+
if (!(baseKey in LWJGL_ARM64_PATCH.jars) && !(baseKey in LWJGL_ARM64_PATCH.natives)) {
|
|
120
|
+
newLibraries.push(lib);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const newLib = { ...lib };
|
|
124
|
+
if ((baseKey in LWJGL_ARM64_PATCH.jars) && lib.downloads?.artifact) {
|
|
125
|
+
const jarEntry = LWJGL_ARM64_PATCH.jars[baseKey];
|
|
126
|
+
const newName = baseKey === "org.lwjgl:lwjgl-glfw"
|
|
127
|
+
? "org.glavo.hmcl.mmachina:lwjgl-glfw:3.3.1-mmachina.1"
|
|
128
|
+
: `${baseKey}:3.3.1`;
|
|
129
|
+
newLib.name = newName;
|
|
130
|
+
newLib.downloads = { ...lib.downloads, artifact: { path: jarEntry.path, sha1: jarEntry.sha1, size: jarEntry.size, url: jarEntry.url } };
|
|
131
|
+
}
|
|
132
|
+
if ((baseKey in LWJGL_ARM64_PATCH.natives) && lib.downloads?.classifiers?.["natives-macos"]) {
|
|
133
|
+
const nativeEntry = LWJGL_ARM64_PATCH.natives[baseKey];
|
|
134
|
+
newLib.downloads = {
|
|
135
|
+
...newLib.downloads,
|
|
136
|
+
classifiers: { "natives-macos": { path: nativeEntry.path, sha1: nativeEntry.sha1, size: nativeEntry.size, url: nativeEntry.url } }
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
newLibraries.push(newLib);
|
|
140
|
+
}
|
|
141
|
+
json.libraries = newLibraries;
|
|
142
|
+
await writeFile(curJsonPath, JSON.stringify(json, null, 2), "utf-8");
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
if (!json.inheritsFrom) {
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
curJsonPath = minecraft.getVersionJson(json.inheritsFrom);
|
|
149
|
+
}
|
|
150
|
+
await writeFile(path.join(nativesDir, ".arm64-patched"), "3.3.1");
|
|
151
|
+
console.error("[MCT] arm64 LWJGL 3.3.1 patch applied");
|
|
152
|
+
return nativesDir;
|
|
153
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CommandContext } from "../../util/context.js";
|
|
2
|
+
import { CacheManager } from "../CacheManager.js";
|
|
3
|
+
import { detectJava } from "../JavaDetector.js";
|
|
4
|
+
import type { LoaderType } from "../types.js";
|
|
5
|
+
import { prepareManagedFabricRuntime } from "./FabricRuntimeDownloader.js";
|
|
6
|
+
export interface DownloadClientOptions {
|
|
7
|
+
loader?: LoaderType;
|
|
8
|
+
version?: string;
|
|
9
|
+
dir?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
wsPort?: number;
|
|
12
|
+
server?: string;
|
|
13
|
+
instanceDir?: string;
|
|
14
|
+
metaDir?: string;
|
|
15
|
+
librariesDir?: string;
|
|
16
|
+
assetsDir?: string;
|
|
17
|
+
nativesDir?: string;
|
|
18
|
+
java?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DownloadClientDependencies {
|
|
21
|
+
cacheManager?: CacheManager;
|
|
22
|
+
detectJavaImpl?: typeof detectJava;
|
|
23
|
+
fetchImpl?: typeof fetch;
|
|
24
|
+
prepareManagedRuntimeImpl?: typeof prepareManagedFabricRuntime;
|
|
25
|
+
}
|
|
26
|
+
export declare function downloadClientMod(context: CommandContext, options: DownloadClientOptions, dependencies?: DownloadClientDependencies): Promise<{
|
|
27
|
+
downloaded: boolean;
|
|
28
|
+
variantId: string;
|
|
29
|
+
minecraftVersion: string;
|
|
30
|
+
loader: LoaderType;
|
|
31
|
+
javaCommand: string;
|
|
32
|
+
javaVersion: number | undefined;
|
|
33
|
+
clientRootDir: string;
|
|
34
|
+
minecraftDir: string;
|
|
35
|
+
modsDir: string;
|
|
36
|
+
jar: string;
|
|
37
|
+
cachePath: string;
|
|
38
|
+
clientName: string;
|
|
39
|
+
launchCommandConfigured: boolean;
|
|
40
|
+
runtimeRootDir: string | undefined;
|
|
41
|
+
runtimeVersionId: string | undefined;
|
|
42
|
+
}>;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { access, mkdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { DEFAULT_WS_PORT_BASE, loadConfig, writeConfig } from "../../util/config.js";
|
|
5
|
+
import { MctError } from "../../util/errors.js";
|
|
6
|
+
import { CacheManager } from "../CacheManager.js";
|
|
7
|
+
import { copyFileIfMissing, downloadFile } from "../DownloadUtils.js";
|
|
8
|
+
import { detectJava } from "../JavaDetector.js";
|
|
9
|
+
import { findVariantByVersionAndLoader, getDefaultVariant, getModArtifactFileName, loadModVariantCatalog } from "../ModVariantCatalog.js";
|
|
10
|
+
import { prepareManagedFabricRuntime } from "./FabricRuntimeDownloader.js";
|
|
11
|
+
const GITHUB_RELEASE_BASE_URL = process.env.MCT_MOD_DOWNLOAD_BASE_URL || "https://github.com/kzheart/mc-pilot/releases/download";
|
|
12
|
+
function ensureSupportedVariant(variant) {
|
|
13
|
+
if (variant.loader !== "fabric") {
|
|
14
|
+
throw new MctError({
|
|
15
|
+
code: "UNSUPPORTED_LOADER",
|
|
16
|
+
message: `Loader ${variant.loader} is not implemented yet`
|
|
17
|
+
}, 4);
|
|
18
|
+
}
|
|
19
|
+
if (!variant.fabricLoaderVersion || !variant.yarnMappings) {
|
|
20
|
+
throw new MctError({
|
|
21
|
+
code: "VARIANT_NOT_BUILDABLE",
|
|
22
|
+
message: `Variant ${variant.id} is not buildable yet`,
|
|
23
|
+
details: {
|
|
24
|
+
support: variant.support,
|
|
25
|
+
validation: variant.validation
|
|
26
|
+
}
|
|
27
|
+
}, 4);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function resolveArtifact(context, variant, cacheManager, fetchImpl = fetch) {
|
|
31
|
+
const artifactFileName = getModArtifactFileName(variant);
|
|
32
|
+
const gradleModule = variant.gradleModule ?? `version-${variant.minecraftVersion}`;
|
|
33
|
+
const buildArtifactPath = path.join(context.cwd, "client-mod", gradleModule, "build", "libs", artifactFileName);
|
|
34
|
+
const cacheArtifactPath = cacheManager.getModFile(artifactFileName);
|
|
35
|
+
// 1. Check local build artifact
|
|
36
|
+
try {
|
|
37
|
+
await access(buildArtifactPath);
|
|
38
|
+
await copyFileIfMissing(buildArtifactPath, cacheArtifactPath);
|
|
39
|
+
return { sourcePath: buildArtifactPath, cachePath: cacheArtifactPath, artifactFileName, source: "local-build" };
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
// 2. Check cache
|
|
43
|
+
try {
|
|
44
|
+
await access(cacheArtifactPath);
|
|
45
|
+
return { sourcePath: cacheArtifactPath, cachePath: cacheArtifactPath, artifactFileName, source: "cache" };
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
// 3. Download from GitHub Releases
|
|
49
|
+
const modVersion = variant.modVersion ?? "0.1.0";
|
|
50
|
+
const releaseTag = `v${modVersion}`;
|
|
51
|
+
const downloadUrl = `${GITHUB_RELEASE_BASE_URL}/${releaseTag}/${artifactFileName}`;
|
|
52
|
+
try {
|
|
53
|
+
await downloadFile(downloadUrl, cacheArtifactPath, fetchImpl);
|
|
54
|
+
return { sourcePath: cacheArtifactPath, cachePath: cacheArtifactPath, artifactFileName, source: "github-release" };
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new MctError({
|
|
58
|
+
code: "ARTIFACT_NOT_FOUND",
|
|
59
|
+
message: `Could not find mod artifact for ${variant.id}. Tried local build, cache, and GitHub Releases.`,
|
|
60
|
+
details: {
|
|
61
|
+
localBuild: buildArtifactPath,
|
|
62
|
+
cache: cacheArtifactPath,
|
|
63
|
+
downloadUrl,
|
|
64
|
+
downloadError: error instanceof Error ? error.message : String(error)
|
|
65
|
+
}
|
|
66
|
+
}, 4);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function resolveLaunchRuntimePaths(context, options) {
|
|
70
|
+
const runtimePaths = {
|
|
71
|
+
instanceDir: options.instanceDir,
|
|
72
|
+
metaDir: options.metaDir,
|
|
73
|
+
librariesDir: options.librariesDir,
|
|
74
|
+
assetsDir: options.assetsDir,
|
|
75
|
+
nativesDir: options.nativesDir
|
|
76
|
+
};
|
|
77
|
+
const requiredEntries = Object.entries({
|
|
78
|
+
instanceDir: runtimePaths.instanceDir,
|
|
79
|
+
metaDir: runtimePaths.metaDir,
|
|
80
|
+
librariesDir: runtimePaths.librariesDir,
|
|
81
|
+
assetsDir: runtimePaths.assetsDir
|
|
82
|
+
});
|
|
83
|
+
const providedRequired = requiredEntries.filter(([, value]) => Boolean(value));
|
|
84
|
+
if (providedRequired.length === 0) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
const missing = requiredEntries
|
|
88
|
+
.filter(([, value]) => !value)
|
|
89
|
+
.map(([key]) => key);
|
|
90
|
+
if (missing.length > 0) {
|
|
91
|
+
throw new MctError({
|
|
92
|
+
code: "INVALID_PARAMS",
|
|
93
|
+
message: "Client runtime directories must be configured together",
|
|
94
|
+
details: {
|
|
95
|
+
missing
|
|
96
|
+
}
|
|
97
|
+
}, 4);
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
instanceDir: path.resolve(context.cwd, runtimePaths.instanceDir),
|
|
101
|
+
metaDir: path.resolve(context.cwd, runtimePaths.metaDir),
|
|
102
|
+
librariesDir: path.resolve(context.cwd, runtimePaths.librariesDir),
|
|
103
|
+
assetsDir: path.resolve(context.cwd, runtimePaths.assetsDir),
|
|
104
|
+
...(runtimePaths.nativesDir
|
|
105
|
+
? {
|
|
106
|
+
nativesDir: path.resolve(context.cwd, runtimePaths.nativesDir)
|
|
107
|
+
}
|
|
108
|
+
: {})
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function buildLaunchCommand(context, runtimePaths, variant) {
|
|
112
|
+
return [
|
|
113
|
+
process.execPath,
|
|
114
|
+
path.join(context.cwd, "scripts", "launch-fabric-client.mjs"),
|
|
115
|
+
"--instance-dir",
|
|
116
|
+
runtimePaths.instanceDir,
|
|
117
|
+
"--meta-dir",
|
|
118
|
+
runtimePaths.metaDir,
|
|
119
|
+
"--libraries-dir",
|
|
120
|
+
runtimePaths.librariesDir,
|
|
121
|
+
"--assets-dir",
|
|
122
|
+
runtimePaths.assetsDir,
|
|
123
|
+
...(runtimePaths.nativesDir ? ["--natives-dir", runtimePaths.nativesDir] : []),
|
|
124
|
+
"--minecraft-version",
|
|
125
|
+
variant.minecraftVersion,
|
|
126
|
+
"--fabric-loader-version",
|
|
127
|
+
variant.fabricLoaderVersion ?? "0.16.10"
|
|
128
|
+
];
|
|
129
|
+
}
|
|
130
|
+
function buildManagedLaunchCommand(context, runtimeRootDir, versionId, gameDir) {
|
|
131
|
+
return [
|
|
132
|
+
process.execPath,
|
|
133
|
+
path.join(context.cwd, "scripts", "launch-fabric-client.mjs"),
|
|
134
|
+
"--runtime-root",
|
|
135
|
+
runtimeRootDir,
|
|
136
|
+
"--version-id",
|
|
137
|
+
versionId,
|
|
138
|
+
"--game-dir",
|
|
139
|
+
gameDir
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
async function ensureJavaReady(variant, detectJavaImpl, command) {
|
|
143
|
+
const result = await detectJavaImpl(command ?? "java");
|
|
144
|
+
const requiredVersion = variant.javaVersion ?? 17;
|
|
145
|
+
if (!result.available) {
|
|
146
|
+
throw new MctError({
|
|
147
|
+
code: "JAVA_NOT_FOUND",
|
|
148
|
+
message: `Java ${requiredVersion}+ is required for ${variant.id}`,
|
|
149
|
+
details: {
|
|
150
|
+
command: result.command
|
|
151
|
+
}
|
|
152
|
+
}, 4);
|
|
153
|
+
}
|
|
154
|
+
if ((result.majorVersion ?? 0) < requiredVersion) {
|
|
155
|
+
throw new MctError({
|
|
156
|
+
code: "JAVA_VERSION_TOO_LOW",
|
|
157
|
+
message: `Java ${requiredVersion}+ is required for ${variant.id}`,
|
|
158
|
+
details: {
|
|
159
|
+
detected: result.majorVersion,
|
|
160
|
+
command: result.command
|
|
161
|
+
}
|
|
162
|
+
}, 4);
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
export async function downloadClientMod(context, options, dependencies = {}) {
|
|
167
|
+
const loader = options.loader ?? "fabric";
|
|
168
|
+
const cacheManager = dependencies.cacheManager ?? new CacheManager();
|
|
169
|
+
const detectJavaImpl = dependencies.detectJavaImpl ?? detectJava;
|
|
170
|
+
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
171
|
+
const prepareManagedRuntimeImpl = dependencies.prepareManagedRuntimeImpl ?? prepareManagedFabricRuntime;
|
|
172
|
+
const catalog = await loadModVariantCatalog();
|
|
173
|
+
const variant = options.version
|
|
174
|
+
? findVariantByVersionAndLoader(catalog, options.version, loader)
|
|
175
|
+
: getDefaultVariant(catalog);
|
|
176
|
+
if (!variant) {
|
|
177
|
+
throw new MctError({
|
|
178
|
+
code: "VARIANT_NOT_FOUND",
|
|
179
|
+
message: `No mod variant found for ${options.version ?? "default"} / ${loader}`
|
|
180
|
+
}, 4);
|
|
181
|
+
}
|
|
182
|
+
ensureSupportedVariant(variant);
|
|
183
|
+
const java = await ensureJavaReady(variant, detectJavaImpl, options.java);
|
|
184
|
+
const artifact = await resolveArtifact(context, variant, cacheManager, fetchImpl);
|
|
185
|
+
const clientRootDir = path.resolve(context.cwd, options.dir ?? "./client");
|
|
186
|
+
const minecraftDir = path.join(clientRootDir, "minecraft");
|
|
187
|
+
const modsDir = path.join(minecraftDir, "mods");
|
|
188
|
+
await mkdir(minecraftDir, { recursive: true });
|
|
189
|
+
await mkdir(modsDir, { recursive: true });
|
|
190
|
+
const targetJarPath = path.join(modsDir, artifact.artifactFileName);
|
|
191
|
+
await copyFileIfMissing(artifact.sourcePath, targetJarPath);
|
|
192
|
+
const clientName = options.name ?? "default";
|
|
193
|
+
const latestConfig = await loadConfig(context.configPath, context.cwd);
|
|
194
|
+
const configuredClient = latestConfig.clients[clientName] ?? {};
|
|
195
|
+
const runtimePaths = resolveLaunchRuntimePaths(context, options);
|
|
196
|
+
const managedRuntime = runtimePaths
|
|
197
|
+
? undefined
|
|
198
|
+
: await prepareManagedRuntimeImpl(variant, clientRootDir, { fetchImpl });
|
|
199
|
+
const generatedLaunchCommand = runtimePaths
|
|
200
|
+
? buildLaunchCommand(context, runtimePaths, variant)
|
|
201
|
+
: buildManagedLaunchCommand(context, managedRuntime.runtimeRootDir, managedRuntime.versionId, managedRuntime.gameDir);
|
|
202
|
+
latestConfig.clients[clientName] = {
|
|
203
|
+
...configuredClient,
|
|
204
|
+
version: variant.minecraftVersion,
|
|
205
|
+
wsPort: options.wsPort ?? configuredClient.wsPort ?? DEFAULT_WS_PORT_BASE,
|
|
206
|
+
server: options.server ?? configuredClient.server ?? "localhost:25565",
|
|
207
|
+
workingDir: path.relative(context.cwd, minecraftDir) || ".",
|
|
208
|
+
env: {
|
|
209
|
+
...configuredClient.env,
|
|
210
|
+
MCT_CLIENT_MOD_VARIANT: variant.id,
|
|
211
|
+
MCT_CLIENT_MOD_JAR: path.relative(context.cwd, targetJarPath)
|
|
212
|
+
},
|
|
213
|
+
...(generatedLaunchCommand ? { launchCommand: generatedLaunchCommand } : {})
|
|
214
|
+
};
|
|
215
|
+
await writeConfig(context.configPath, context.cwd, latestConfig);
|
|
216
|
+
return {
|
|
217
|
+
downloaded: true,
|
|
218
|
+
variantId: variant.id,
|
|
219
|
+
minecraftVersion: variant.minecraftVersion,
|
|
220
|
+
loader: variant.loader,
|
|
221
|
+
javaCommand: java.command,
|
|
222
|
+
javaVersion: java.majorVersion,
|
|
223
|
+
clientRootDir,
|
|
224
|
+
minecraftDir,
|
|
225
|
+
modsDir,
|
|
226
|
+
jar: targetJarPath,
|
|
227
|
+
cachePath: artifact.cachePath,
|
|
228
|
+
clientName,
|
|
229
|
+
launchCommandConfigured: Boolean(generatedLaunchCommand),
|
|
230
|
+
runtimeRootDir: managedRuntime?.runtimeRootDir,
|
|
231
|
+
runtimeVersionId: managedRuntime?.versionId
|
|
232
|
+
};
|
|
233
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ModVariant } from "../types.js";
|
|
2
|
+
export interface PrepareFabricRuntimeDependencies {
|
|
3
|
+
fetchImpl?: typeof fetch;
|
|
4
|
+
}
|
|
5
|
+
export interface PreparedFabricRuntime {
|
|
6
|
+
runtimeRootDir: string;
|
|
7
|
+
gameDir: string;
|
|
8
|
+
versionId: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function prepareManagedFabricRuntime(variant: ModVariant, clientRootDir: string, dependencies?: PrepareFabricRuntimeDependencies): Promise<PreparedFabricRuntime>;
|