@opys/minecraft-vanilla 0.1.2

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/dist/index.cjs ADDED
@@ -0,0 +1,218 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let _opys_dev = require("@opys/dev");
3
+ let _opys_core = require("@opys/core");
4
+ let _opys_mojang = require("@opys/mojang");
5
+
6
+ //#region lib/mappers/libraries.ts
7
+ function libraryToArtifact(lib) {
8
+ const path = `\${library_directory}/${lib.artifact.path}`;
9
+ const extract = lib.native ? [(0, _opys_core.extractDump)("${natives_directory}", {
10
+ excludes: ["META-INF/"],
11
+ clean: true
12
+ })] : void 0;
13
+ return {
14
+ path,
15
+ source: (0, _opys_core.sourceUrl)(lib.artifact.url),
16
+ size: lib.artifact.size,
17
+ rules: lib.rules,
18
+ integrity: { sha1: lib.artifact.sha1 },
19
+ extract
20
+ };
21
+ }
22
+ function mapLibraries(libs) {
23
+ return libs.map((l) => libraryToArtifact(l));
24
+ }
25
+
26
+ //#endregion
27
+ //#region lib/mappers/assets.ts
28
+ function mapAssetIndex(index) {
29
+ return {
30
+ path: `\${assets_root}/indexes/${index.id}.json`,
31
+ source: (0, _opys_core.sourceUrl)(index.url),
32
+ size: index.size,
33
+ rules: [],
34
+ integrity: { sha1: index.sha1 }
35
+ };
36
+ }
37
+ function mapAssetObjects(manifest) {
38
+ return Object.entries(manifest.objects).map(([name, obj]) => ({
39
+ path: `\${assets_root}/objects/${(0, _opys_mojang.assetPath)(obj.hash)}`,
40
+ source: (0, _opys_core.sourceUrl)((0, _opys_mojang.assetUrl)(obj.hash)),
41
+ size: obj.size,
42
+ rules: [],
43
+ metadata: { name }
44
+ }));
45
+ }
46
+
47
+ //#endregion
48
+ //#region lib/mappers/client.ts
49
+ function mapClientJar(client) {
50
+ return {
51
+ path: `\${version_dir}/client.jar`,
52
+ source: (0, _opys_core.sourceUrl)(client.downloads.client.url),
53
+ size: client.downloads.client.size,
54
+ rules: [],
55
+ integrity: { sha1: client.downloads.client.sha1 }
56
+ };
57
+ }
58
+
59
+ //#endregion
60
+ //#region lib/mappers/launch.ts
61
+ /**
62
+ * Build the `${classpath}` arms — one per OS.
63
+ *
64
+ * Minecraft / forge / cleanroom library `rules` gate on OS only, never
65
+ * `arch` (verified across version JSONs 1.7.10–1.21.4 — the only arch
66
+ * dimension Mojang ever used is the legacy `natives`-map `${arch}`
67
+ * substitution, handled separately). So the classpath is computed once
68
+ * per OS; the `arch` below is a fixed placeholder, required solely
69
+ * because `OsOptions` mandates the field. If an `os.arch` rule ever
70
+ * appears in a version JSON, this must become per-(os, arch).
71
+ */
72
+ function buildClasspath(libs, clientJarPath) {
73
+ const oses = [
74
+ "linux",
75
+ "windows",
76
+ "osx"
77
+ ];
78
+ const arms = [];
79
+ for (const name of oses) {
80
+ const os = {
81
+ name,
82
+ version: "",
83
+ arch: "x86_64"
84
+ };
85
+ const value = [clientJarPath, ...libs.filter((l) => (0, _opys_core.satisfiesRuleset)(l.rules, os)).map((l) => l.artifactPath)].join("${classpath_separator}");
86
+ arms.push({
87
+ value,
88
+ rules: (0, _opys_core.allowOsRuleset)(name)
89
+ });
90
+ }
91
+ return arms;
92
+ }
93
+ function buildLaunch(mainClass, gameArgs, jvmArgs) {
94
+ const jvm = (0, _opys_core.parseValset)(jvmArgs);
95
+ const game = (0, _opys_core.parseValset)(gameArgs);
96
+ const main = {
97
+ rules: [],
98
+ value: [mainClass]
99
+ };
100
+ return {
101
+ launch: {
102
+ command: "${java_bin}",
103
+ workdir: "./",
104
+ args: [
105
+ ...jvm,
106
+ main,
107
+ ...game
108
+ ],
109
+ envs: {}
110
+ },
111
+ jvmArgs: jvm,
112
+ mainClass: main,
113
+ gameArgs: game
114
+ };
115
+ }
116
+
117
+ //#endregion
118
+ //#region lib/template.ts
119
+ async function resolveMinecraft(config) {
120
+ const { client } = await fetchClient(config?.version);
121
+ return clientToTemplate(client);
122
+ }
123
+ async function fetchClient(versionId) {
124
+ const manifest = await (0, _opys_mojang.fetchVersionManifest)();
125
+ const version = versionId ? (0, _opys_mojang.findVersion)(manifest, versionId) : (0, _opys_mojang.latestRelease)(manifest);
126
+ if (!version) throw new Error(`Version '${versionId ?? "latest"}' not found`);
127
+ const res = await (0, _opys_core.fetchWithRetry)(version.url);
128
+ if (!res.ok) throw new Error(`Failed to fetch version JSON: ${res.statusText}`);
129
+ const { parseClient } = await import("@opys/mojang");
130
+ return {
131
+ version,
132
+ client: parseClient(await res.json())
133
+ };
134
+ }
135
+ async function clientToTemplate(client) {
136
+ const manifest = await (0, _opys_mojang.fetchAssetManifest)(client.assetIndex.url);
137
+ const artifacts = [];
138
+ artifacts.push(mapClientJar(client));
139
+ artifacts.push(...mapLibraries(client.libraries));
140
+ artifacts.push(mapAssetIndex(client.assetIndex));
141
+ artifacts.push(...mapAssetObjects(manifest));
142
+ const classpath = buildClasspath(client.libraries.map((l) => ({
143
+ rules: l.rules,
144
+ artifactPath: `\${library_directory}/${l.artifact.path}`
145
+ })), "${version_dir}/client.jar");
146
+ return {
147
+ artifacts,
148
+ vars: {
149
+ root: ".",
150
+ launcher_name: "opys",
151
+ launcher_version: "0.1",
152
+ version_type: client.metadata.type,
153
+ version_name: client.id,
154
+ game_directory: "${root}/",
155
+ assets_root: "${root}/assets",
156
+ game_assets: "${assets_root}",
157
+ assets_index_name: client.assetIndex.id,
158
+ version_dir: "${root}/versions/${version_name}",
159
+ library_directory: "${root}/libraries",
160
+ natives_directory: "${version_dir}/natives",
161
+ auth_player_name: "${username}",
162
+ auth_uuid: "${uuid}",
163
+ auth_session: "${token}",
164
+ auth_access_token: "${token}",
165
+ user_type: "mojang",
166
+ user_properties: "{}",
167
+ clientid: "",
168
+ classpath_separator: [
169
+ {
170
+ value: ";",
171
+ rules: (0, _opys_core.allowOsRuleset)("windows")
172
+ },
173
+ {
174
+ value: ":",
175
+ rules: (0, _opys_core.allowOsRuleset)("linux")
176
+ },
177
+ {
178
+ value: ":",
179
+ rules: (0, _opys_core.allowOsRuleset)("osx")
180
+ }
181
+ ],
182
+ classpath
183
+ },
184
+ classpath,
185
+ ...buildLaunch(client.mainClass, client.args.game, client.args.jvm)
186
+ };
187
+ }
188
+
189
+ //#endregion
190
+ //#region lib/plugin.ts
191
+ /** Vanilla Minecraft client + libraries + assets. */
192
+ function minecraft(version) {
193
+ return (0, _opys_dev.definePlugin)({
194
+ name: "minecraft",
195
+ async build(ctx) {
196
+ const t = await resolveMinecraft(version ? { version } : {});
197
+ ctx.log("minecraft", `vanilla ${version ?? "latest"}`);
198
+ return {
199
+ artifacts: t.artifacts,
200
+ vars: t.vars,
201
+ launch: (0, _opys_dev.launchGroups)(t)
202
+ };
203
+ }
204
+ });
205
+ }
206
+
207
+ //#endregion
208
+ exports.buildClasspath = buildClasspath;
209
+ exports.buildLaunch = buildLaunch;
210
+ exports.clientToTemplate = clientToTemplate;
211
+ exports.fetchClient = fetchClient;
212
+ exports.libraryToArtifact = libraryToArtifact;
213
+ exports.mapAssetIndex = mapAssetIndex;
214
+ exports.mapAssetObjects = mapAssetObjects;
215
+ exports.mapClientJar = mapClientJar;
216
+ exports.mapLibraries = mapLibraries;
217
+ exports.minecraft = minecraft;
218
+ exports.resolveMinecraft = resolveMinecraft;
@@ -0,0 +1,80 @@
1
+ import { OpysPlugin } from "@opys/dev";
2
+ import { Artifact, ConditionalVal, Launch, Ruleset, Val, ValDefs, Valset } from "@opys/core";
3
+ import { AssetIndex, AssetManifest, Client, Library, MojangArgValue, Version } from "@opys/mojang";
4
+
5
+ //#region lib/plugin.d.ts
6
+ /** Vanilla Minecraft client + libraries + assets. */
7
+ declare function minecraft(version?: string): OpysPlugin;
8
+ //#endregion
9
+ //#region lib/template.d.ts
10
+ interface MinecraftTemplate {
11
+ artifacts: Artifact[];
12
+ vars: ValDefs;
13
+ /** Per-OS classpath arms (also baked into `vars.classpath`). */
14
+ classpath: ConditionalVal[];
15
+ /** Assembled Launch — drop straight into `manifest.launch`. */
16
+ launch: Launch;
17
+ /** JVM args alone, for composition (e.g. interleaving an auth `-javaagent`). */
18
+ jvmArgs: Valset;
19
+ /** Main class wrapped as a `Val` so it spreads into a `Valset`. Raw string at `mainClass.value[0]`. */
20
+ mainClass: Val;
21
+ /** Game args alone, for composition. */
22
+ gameArgs: Valset;
23
+ }
24
+ declare function resolveMinecraft(config?: {
25
+ version?: string;
26
+ }): Promise<MinecraftTemplate>;
27
+ declare function fetchClient(versionId?: string): Promise<{
28
+ version: Version;
29
+ client: Client;
30
+ }>;
31
+ declare function clientToTemplate(client: Client): Promise<MinecraftTemplate>;
32
+ //#endregion
33
+ //#region lib/mappers/libraries.d.ts
34
+ declare function libraryToArtifact(lib: Library): Artifact;
35
+ declare function mapLibraries(libs: readonly Library[]): Artifact[];
36
+ //#endregion
37
+ //#region lib/mappers/launch.d.ts
38
+ /**
39
+ * Decomposed parts of a Minecraft `Launch` config. `launch` is the
40
+ * assembled `Launch` (drop straight into `manifest.launch`); the
41
+ * remaining fields expose the JVM args, main class, and game args
42
+ * separately so callers can interleave their own JVM args (e.g. from
43
+ * `@opys/authliberty`) before the main class.
44
+ *
45
+ * `mainClass` is exposed as a `Val` so it slots directly into a
46
+ * `Valset` between `jvmArgs` and `gameArgs`. Use `mainClass.value[0]`
47
+ * for the raw class name.
48
+ */
49
+ interface LaunchParts {
50
+ launch: Launch;
51
+ jvmArgs: Valset;
52
+ mainClass: Val;
53
+ gameArgs: Valset;
54
+ }
55
+ /**
56
+ * Build the `${classpath}` arms — one per OS.
57
+ *
58
+ * Minecraft / forge / cleanroom library `rules` gate on OS only, never
59
+ * `arch` (verified across version JSONs 1.7.10–1.21.4 — the only arch
60
+ * dimension Mojang ever used is the legacy `natives`-map `${arch}`
61
+ * substitution, handled separately). So the classpath is computed once
62
+ * per OS; the `arch` below is a fixed placeholder, required solely
63
+ * because `OsOptions` mandates the field. If an `os.arch` rule ever
64
+ * appears in a version JSON, this must become per-(os, arch).
65
+ */
66
+ declare function buildClasspath(libs: {
67
+ rules: Ruleset;
68
+ artifactPath: string;
69
+ }[], clientJarPath: string): ConditionalVal[];
70
+ declare function buildLaunch(mainClass: string, gameArgs: MojangArgValue[], jvmArgs: MojangArgValue[]): LaunchParts;
71
+ //#endregion
72
+ //#region lib/mappers/assets.d.ts
73
+ declare function mapAssetIndex(index: AssetIndex): Artifact;
74
+ declare function mapAssetObjects(manifest: AssetManifest): Artifact[];
75
+ //#endregion
76
+ //#region lib/mappers/client.d.ts
77
+ declare function mapClientJar(client: Client): Artifact;
78
+ //#endregion
79
+ export { LaunchParts, MinecraftTemplate, buildClasspath, buildLaunch, clientToTemplate, fetchClient, libraryToArtifact, mapAssetIndex, mapAssetObjects, mapClientJar, mapLibraries, minecraft, resolveMinecraft };
80
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../lib/plugin.ts","../lib/template.ts","../lib/mappers/libraries.ts","../lib/mappers/launch.ts","../lib/mappers/assets.ts","../lib/mappers/client.ts"],"mappings":";;;;;;iBAIgB,SAAA,CAAU,OAAA,YAAmB,UAAA;;;UCmB5B,iBAAA;EACf,SAAA,EAAW,QAAA;EACX,IAAA,EAAM,OAAA;EDrBQ;ECuBd,SAAA,EAAW,cAAA;;EAEX,MAAA,EAAQ,MAAA;EDzB6C;EC2BrD,OAAA,EAAS,MAAA;;EAET,SAAA,EAAW,GAAA;EAVI;EAYf,QAAA,EAAU,MAAA;AAAA;AAAA,iBAGU,gBAAA,CAAiB,MAAA;EACrC,OAAA;AAAA,IACE,OAAA,CAAQ,iBAAA;AAAA,iBAKU,WAAA,CACpB,SAAA,YACC,OAAA;EAAU,OAAA,EAAS,OAAA;EAAS,MAAA,EAAQ,MAAA;AAAA;AAAA,iBAajB,gBAAA,CACpB,MAAA,EAAQ,MAAA,GACP,OAAA,CAAQ,iBAAA;;;iBC1DK,iBAAA,CAAkB,GAAA,EAAK,OAAA,GAAU,QAAA;AAAA,iBAqBjC,YAAA,CAAa,IAAA,WAAe,OAAA,KAAY,QAAA;;;;;AFrBxD;;;;;;;;ACmBA;UEPiB,WAAA;EACf,MAAA,EAAQ,MAAA;EACR,OAAA,EAAS,MAAA;EACT,SAAA,EAAW,GAAA;EACX,QAAA,EAAU,MAAA;AAAA;;;;;;;;;;;;iBAcI,cAAA,CACd,IAAA;EAAQ,KAAA,EAAO,OAAA;EAAS,YAAA;AAAA,KACxB,aAAA,WACC,cAAA;AAAA,iBAea,WAAA,CACd,SAAA,UACA,QAAA,EAAU,cAAA,IACV,OAAA,EAAS,cAAA,KACR,WAAA;;;iBCnDa,aAAA,CAAc,KAAA,EAAO,UAAA,GAAa,QAAA;AAAA,iBAUlC,eAAA,CAAgB,QAAA,EAAU,aAAA,GAAgB,QAAA;;;iBCX1C,YAAA,CAAa,MAAA,EAAQ,MAAA,GAAS,QAAA"}
@@ -0,0 +1,80 @@
1
+ import { OpysPlugin } from "@opys/dev";
2
+ import { Artifact, ConditionalVal, Launch, Ruleset, Val, ValDefs, Valset } from "@opys/core";
3
+ import { AssetIndex, AssetManifest, Client, Library, MojangArgValue, Version } from "@opys/mojang";
4
+
5
+ //#region lib/plugin.d.ts
6
+ /** Vanilla Minecraft client + libraries + assets. */
7
+ declare function minecraft(version?: string): OpysPlugin;
8
+ //#endregion
9
+ //#region lib/template.d.ts
10
+ interface MinecraftTemplate {
11
+ artifacts: Artifact[];
12
+ vars: ValDefs;
13
+ /** Per-OS classpath arms (also baked into `vars.classpath`). */
14
+ classpath: ConditionalVal[];
15
+ /** Assembled Launch — drop straight into `manifest.launch`. */
16
+ launch: Launch;
17
+ /** JVM args alone, for composition (e.g. interleaving an auth `-javaagent`). */
18
+ jvmArgs: Valset;
19
+ /** Main class wrapped as a `Val` so it spreads into a `Valset`. Raw string at `mainClass.value[0]`. */
20
+ mainClass: Val;
21
+ /** Game args alone, for composition. */
22
+ gameArgs: Valset;
23
+ }
24
+ declare function resolveMinecraft(config?: {
25
+ version?: string;
26
+ }): Promise<MinecraftTemplate>;
27
+ declare function fetchClient(versionId?: string): Promise<{
28
+ version: Version;
29
+ client: Client;
30
+ }>;
31
+ declare function clientToTemplate(client: Client): Promise<MinecraftTemplate>;
32
+ //#endregion
33
+ //#region lib/mappers/libraries.d.ts
34
+ declare function libraryToArtifact(lib: Library): Artifact;
35
+ declare function mapLibraries(libs: readonly Library[]): Artifact[];
36
+ //#endregion
37
+ //#region lib/mappers/launch.d.ts
38
+ /**
39
+ * Decomposed parts of a Minecraft `Launch` config. `launch` is the
40
+ * assembled `Launch` (drop straight into `manifest.launch`); the
41
+ * remaining fields expose the JVM args, main class, and game args
42
+ * separately so callers can interleave their own JVM args (e.g. from
43
+ * `@opys/authliberty`) before the main class.
44
+ *
45
+ * `mainClass` is exposed as a `Val` so it slots directly into a
46
+ * `Valset` between `jvmArgs` and `gameArgs`. Use `mainClass.value[0]`
47
+ * for the raw class name.
48
+ */
49
+ interface LaunchParts {
50
+ launch: Launch;
51
+ jvmArgs: Valset;
52
+ mainClass: Val;
53
+ gameArgs: Valset;
54
+ }
55
+ /**
56
+ * Build the `${classpath}` arms — one per OS.
57
+ *
58
+ * Minecraft / forge / cleanroom library `rules` gate on OS only, never
59
+ * `arch` (verified across version JSONs 1.7.10–1.21.4 — the only arch
60
+ * dimension Mojang ever used is the legacy `natives`-map `${arch}`
61
+ * substitution, handled separately). So the classpath is computed once
62
+ * per OS; the `arch` below is a fixed placeholder, required solely
63
+ * because `OsOptions` mandates the field. If an `os.arch` rule ever
64
+ * appears in a version JSON, this must become per-(os, arch).
65
+ */
66
+ declare function buildClasspath(libs: {
67
+ rules: Ruleset;
68
+ artifactPath: string;
69
+ }[], clientJarPath: string): ConditionalVal[];
70
+ declare function buildLaunch(mainClass: string, gameArgs: MojangArgValue[], jvmArgs: MojangArgValue[]): LaunchParts;
71
+ //#endregion
72
+ //#region lib/mappers/assets.d.ts
73
+ declare function mapAssetIndex(index: AssetIndex): Artifact;
74
+ declare function mapAssetObjects(manifest: AssetManifest): Artifact[];
75
+ //#endregion
76
+ //#region lib/mappers/client.d.ts
77
+ declare function mapClientJar(client: Client): Artifact;
78
+ //#endregion
79
+ export { LaunchParts, MinecraftTemplate, buildClasspath, buildLaunch, clientToTemplate, fetchClient, libraryToArtifact, mapAssetIndex, mapAssetObjects, mapClientJar, mapLibraries, minecraft, resolveMinecraft };
80
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../lib/plugin.ts","../lib/template.ts","../lib/mappers/libraries.ts","../lib/mappers/launch.ts","../lib/mappers/assets.ts","../lib/mappers/client.ts"],"mappings":";;;;;;iBAIgB,SAAA,CAAU,OAAA,YAAmB,UAAA;;;UCmB5B,iBAAA;EACf,SAAA,EAAW,QAAA;EACX,IAAA,EAAM,OAAA;EDrBQ;ECuBd,SAAA,EAAW,cAAA;;EAEX,MAAA,EAAQ,MAAA;EDzB6C;EC2BrD,OAAA,EAAS,MAAA;;EAET,SAAA,EAAW,GAAA;EAVI;EAYf,QAAA,EAAU,MAAA;AAAA;AAAA,iBAGU,gBAAA,CAAiB,MAAA;EACrC,OAAA;AAAA,IACE,OAAA,CAAQ,iBAAA;AAAA,iBAKU,WAAA,CACpB,SAAA,YACC,OAAA;EAAU,OAAA,EAAS,OAAA;EAAS,MAAA,EAAQ,MAAA;AAAA;AAAA,iBAajB,gBAAA,CACpB,MAAA,EAAQ,MAAA,GACP,OAAA,CAAQ,iBAAA;;;iBC1DK,iBAAA,CAAkB,GAAA,EAAK,OAAA,GAAU,QAAA;AAAA,iBAqBjC,YAAA,CAAa,IAAA,WAAe,OAAA,KAAY,QAAA;;;;;AFrBxD;;;;;;;;ACmBA;UEPiB,WAAA;EACf,MAAA,EAAQ,MAAA;EACR,OAAA,EAAS,MAAA;EACT,SAAA,EAAW,GAAA;EACX,QAAA,EAAU,MAAA;AAAA;;;;;;;;;;;;iBAcI,cAAA,CACd,IAAA;EAAQ,KAAA,EAAO,OAAA;EAAS,YAAA;AAAA,KACxB,aAAA,WACC,cAAA;AAAA,iBAea,WAAA,CACd,SAAA,UACA,QAAA,EAAU,cAAA,IACV,OAAA,EAAS,cAAA,KACR,WAAA;;;iBCnDa,aAAA,CAAc,KAAA,EAAO,UAAA,GAAa,QAAA;AAAA,iBAUlC,eAAA,CAAgB,QAAA,EAAU,aAAA,GAAgB,QAAA;;;iBCX1C,YAAA,CAAa,MAAA,EAAQ,MAAA,GAAS,QAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,208 @@
1
+ import { definePlugin, launchGroups } from "@opys/dev";
2
+ import { allowOsRuleset, extractDump, fetchWithRetry, parseValset, satisfiesRuleset, sourceUrl } from "@opys/core";
3
+ import { assetPath, assetUrl, fetchAssetManifest, fetchVersionManifest, findVersion, latestRelease } from "@opys/mojang";
4
+
5
+ //#region lib/mappers/libraries.ts
6
+ function libraryToArtifact(lib) {
7
+ const path = `\${library_directory}/${lib.artifact.path}`;
8
+ const extract = lib.native ? [extractDump("${natives_directory}", {
9
+ excludes: ["META-INF/"],
10
+ clean: true
11
+ })] : void 0;
12
+ return {
13
+ path,
14
+ source: sourceUrl(lib.artifact.url),
15
+ size: lib.artifact.size,
16
+ rules: lib.rules,
17
+ integrity: { sha1: lib.artifact.sha1 },
18
+ extract
19
+ };
20
+ }
21
+ function mapLibraries(libs) {
22
+ return libs.map((l) => libraryToArtifact(l));
23
+ }
24
+
25
+ //#endregion
26
+ //#region lib/mappers/assets.ts
27
+ function mapAssetIndex(index) {
28
+ return {
29
+ path: `\${assets_root}/indexes/${index.id}.json`,
30
+ source: sourceUrl(index.url),
31
+ size: index.size,
32
+ rules: [],
33
+ integrity: { sha1: index.sha1 }
34
+ };
35
+ }
36
+ function mapAssetObjects(manifest) {
37
+ return Object.entries(manifest.objects).map(([name, obj]) => ({
38
+ path: `\${assets_root}/objects/${assetPath(obj.hash)}`,
39
+ source: sourceUrl(assetUrl(obj.hash)),
40
+ size: obj.size,
41
+ rules: [],
42
+ metadata: { name }
43
+ }));
44
+ }
45
+
46
+ //#endregion
47
+ //#region lib/mappers/client.ts
48
+ function mapClientJar(client) {
49
+ return {
50
+ path: `\${version_dir}/client.jar`,
51
+ source: sourceUrl(client.downloads.client.url),
52
+ size: client.downloads.client.size,
53
+ rules: [],
54
+ integrity: { sha1: client.downloads.client.sha1 }
55
+ };
56
+ }
57
+
58
+ //#endregion
59
+ //#region lib/mappers/launch.ts
60
+ /**
61
+ * Build the `${classpath}` arms — one per OS.
62
+ *
63
+ * Minecraft / forge / cleanroom library `rules` gate on OS only, never
64
+ * `arch` (verified across version JSONs 1.7.10–1.21.4 — the only arch
65
+ * dimension Mojang ever used is the legacy `natives`-map `${arch}`
66
+ * substitution, handled separately). So the classpath is computed once
67
+ * per OS; the `arch` below is a fixed placeholder, required solely
68
+ * because `OsOptions` mandates the field. If an `os.arch` rule ever
69
+ * appears in a version JSON, this must become per-(os, arch).
70
+ */
71
+ function buildClasspath(libs, clientJarPath) {
72
+ const oses = [
73
+ "linux",
74
+ "windows",
75
+ "osx"
76
+ ];
77
+ const arms = [];
78
+ for (const name of oses) {
79
+ const os = {
80
+ name,
81
+ version: "",
82
+ arch: "x86_64"
83
+ };
84
+ const value = [clientJarPath, ...libs.filter((l) => satisfiesRuleset(l.rules, os)).map((l) => l.artifactPath)].join("${classpath_separator}");
85
+ arms.push({
86
+ value,
87
+ rules: allowOsRuleset(name)
88
+ });
89
+ }
90
+ return arms;
91
+ }
92
+ function buildLaunch(mainClass, gameArgs, jvmArgs) {
93
+ const jvm = parseValset(jvmArgs);
94
+ const game = parseValset(gameArgs);
95
+ const main = {
96
+ rules: [],
97
+ value: [mainClass]
98
+ };
99
+ return {
100
+ launch: {
101
+ command: "${java_bin}",
102
+ workdir: "./",
103
+ args: [
104
+ ...jvm,
105
+ main,
106
+ ...game
107
+ ],
108
+ envs: {}
109
+ },
110
+ jvmArgs: jvm,
111
+ mainClass: main,
112
+ gameArgs: game
113
+ };
114
+ }
115
+
116
+ //#endregion
117
+ //#region lib/template.ts
118
+ async function resolveMinecraft(config) {
119
+ const { client } = await fetchClient(config?.version);
120
+ return clientToTemplate(client);
121
+ }
122
+ async function fetchClient(versionId) {
123
+ const manifest = await fetchVersionManifest();
124
+ const version = versionId ? findVersion(manifest, versionId) : latestRelease(manifest);
125
+ if (!version) throw new Error(`Version '${versionId ?? "latest"}' not found`);
126
+ const res = await fetchWithRetry(version.url);
127
+ if (!res.ok) throw new Error(`Failed to fetch version JSON: ${res.statusText}`);
128
+ const { parseClient } = await import("@opys/mojang");
129
+ return {
130
+ version,
131
+ client: parseClient(await res.json())
132
+ };
133
+ }
134
+ async function clientToTemplate(client) {
135
+ const manifest = await fetchAssetManifest(client.assetIndex.url);
136
+ const artifacts = [];
137
+ artifacts.push(mapClientJar(client));
138
+ artifacts.push(...mapLibraries(client.libraries));
139
+ artifacts.push(mapAssetIndex(client.assetIndex));
140
+ artifacts.push(...mapAssetObjects(manifest));
141
+ const classpath = buildClasspath(client.libraries.map((l) => ({
142
+ rules: l.rules,
143
+ artifactPath: `\${library_directory}/${l.artifact.path}`
144
+ })), "${version_dir}/client.jar");
145
+ return {
146
+ artifacts,
147
+ vars: {
148
+ root: ".",
149
+ launcher_name: "opys",
150
+ launcher_version: "0.1",
151
+ version_type: client.metadata.type,
152
+ version_name: client.id,
153
+ game_directory: "${root}/",
154
+ assets_root: "${root}/assets",
155
+ game_assets: "${assets_root}",
156
+ assets_index_name: client.assetIndex.id,
157
+ version_dir: "${root}/versions/${version_name}",
158
+ library_directory: "${root}/libraries",
159
+ natives_directory: "${version_dir}/natives",
160
+ auth_player_name: "${username}",
161
+ auth_uuid: "${uuid}",
162
+ auth_session: "${token}",
163
+ auth_access_token: "${token}",
164
+ user_type: "mojang",
165
+ user_properties: "{}",
166
+ clientid: "",
167
+ classpath_separator: [
168
+ {
169
+ value: ";",
170
+ rules: allowOsRuleset("windows")
171
+ },
172
+ {
173
+ value: ":",
174
+ rules: allowOsRuleset("linux")
175
+ },
176
+ {
177
+ value: ":",
178
+ rules: allowOsRuleset("osx")
179
+ }
180
+ ],
181
+ classpath
182
+ },
183
+ classpath,
184
+ ...buildLaunch(client.mainClass, client.args.game, client.args.jvm)
185
+ };
186
+ }
187
+
188
+ //#endregion
189
+ //#region lib/plugin.ts
190
+ /** Vanilla Minecraft client + libraries + assets. */
191
+ function minecraft(version) {
192
+ return definePlugin({
193
+ name: "minecraft",
194
+ async build(ctx) {
195
+ const t = await resolveMinecraft(version ? { version } : {});
196
+ ctx.log("minecraft", `vanilla ${version ?? "latest"}`);
197
+ return {
198
+ artifacts: t.artifacts,
199
+ vars: t.vars,
200
+ launch: launchGroups(t)
201
+ };
202
+ }
203
+ });
204
+ }
205
+
206
+ //#endregion
207
+ export { buildClasspath, buildLaunch, clientToTemplate, fetchClient, libraryToArtifact, mapAssetIndex, mapAssetObjects, mapClientJar, mapLibraries, minecraft, resolveMinecraft };
208
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../lib/mappers/libraries.ts","../lib/mappers/assets.ts","../lib/mappers/client.ts","../lib/mappers/launch.ts","../lib/template.ts","../lib/plugin.ts"],"sourcesContent":["import type { Artifact } from '@opys/core';\nimport { sourceUrl, extractDump } from '@opys/core';\nimport type { Library } from '@opys/mojang';\n\nexport function libraryToArtifact(lib: Library): Artifact {\n const path = `\\${library_directory}/${lib.artifact.path}`;\n const extract = lib.native\n ? [\n extractDump('${natives_directory}', {\n excludes: ['META-INF/'],\n clean: true,\n }),\n ]\n : undefined;\n\n return {\n path,\n source: sourceUrl(lib.artifact.url),\n size: lib.artifact.size,\n rules: lib.rules,\n integrity: { sha1: lib.artifact.sha1 },\n extract,\n };\n}\n\nexport function mapLibraries(libs: readonly Library[]): Artifact[] {\n return libs.map((l) => libraryToArtifact(l));\n}\n","import type { Artifact } from '@opys/core';\nimport { sourceUrl } from '@opys/core';\nimport type { AssetManifest, AssetIndex } from '@opys/mojang';\nimport { assetUrl, assetPath } from '@opys/mojang';\n\nexport function mapAssetIndex(index: AssetIndex): Artifact {\n return {\n path: `\\${assets_root}/indexes/${index.id}.json`,\n source: sourceUrl(index.url),\n size: index.size,\n rules: [],\n integrity: { sha1: index.sha1 },\n };\n}\n\nexport function mapAssetObjects(manifest: AssetManifest): Artifact[] {\n return Object.entries(manifest.objects).map(([name, obj]) => ({\n path: `\\${assets_root}/objects/${assetPath(obj.hash)}`,\n source: sourceUrl(assetUrl(obj.hash)),\n size: obj.size,\n rules: [],\n metadata: { name },\n }));\n}\n","import type { Artifact } from '@opys/core';\nimport { sourceUrl } from '@opys/core';\nimport type { Client } from '@opys/mojang';\n\nexport function mapClientJar(client: Client): Artifact {\n return {\n path: `\\${version_dir}/client.jar`,\n source: sourceUrl(client.downloads.client.url),\n size: client.downloads.client.size,\n rules: [],\n integrity: { sha1: client.downloads.client.sha1 },\n };\n}\n","import type { Val, Valset, OsOptions, Ruleset } from '@opys/core';\nimport { parseValset, allowOsRuleset, satisfiesRuleset } from '@opys/core';\nimport type { MojangArgValue } from '@opys/mojang';\nimport type { Launch, ConditionalVal } from '@opys/core';\n\n/**\n * Decomposed parts of a Minecraft `Launch` config. `launch` is the\n * assembled `Launch` (drop straight into `manifest.launch`); the\n * remaining fields expose the JVM args, main class, and game args\n * separately so callers can interleave their own JVM args (e.g. from\n * `@opys/authliberty`) before the main class.\n *\n * `mainClass` is exposed as a `Val` so it slots directly into a\n * `Valset` between `jvmArgs` and `gameArgs`. Use `mainClass.value[0]`\n * for the raw class name.\n */\nexport interface LaunchParts {\n launch: Launch;\n jvmArgs: Valset;\n mainClass: Val;\n gameArgs: Valset;\n}\n\n/**\n * Build the `${classpath}` arms — one per OS.\n *\n * Minecraft / forge / cleanroom library `rules` gate on OS only, never\n * `arch` (verified across version JSONs 1.7.10–1.21.4 — the only arch\n * dimension Mojang ever used is the legacy `natives`-map `${arch}`\n * substitution, handled separately). So the classpath is computed once\n * per OS; the `arch` below is a fixed placeholder, required solely\n * because `OsOptions` mandates the field. If an `os.arch` rule ever\n * appears in a version JSON, this must become per-(os, arch).\n */\nexport function buildClasspath(\n libs: { rules: Ruleset; artifactPath: string }[],\n clientJarPath: string,\n): ConditionalVal[] {\n const oses: ('linux' | 'windows' | 'osx')[] = ['linux', 'windows', 'osx'];\n\n const arms: ConditionalVal[] = [];\n for (const name of oses) {\n const os: OsOptions = { name, version: '', arch: 'x86_64' };\n const applicable = libs\n .filter((l) => satisfiesRuleset(l.rules, os))\n .map((l) => l.artifactPath);\n const value = [clientJarPath, ...applicable].join('${classpath_separator}');\n arms.push({ value, rules: allowOsRuleset(name) });\n }\n return arms;\n}\n\nexport function buildLaunch(\n mainClass: string,\n gameArgs: MojangArgValue[],\n jvmArgs: MojangArgValue[],\n): LaunchParts {\n const jvm = parseValset(jvmArgs);\n const game = parseValset(gameArgs);\n const main: Val = { rules: [], value: [mainClass] };\n const launch: Launch = {\n command: '${java_bin}',\n workdir: './',\n args: [...jvm, main, ...game],\n envs: {},\n };\n return { launch, jvmArgs: jvm, mainClass: main, gameArgs: game };\n}\n","import {\n fetchWithRetry,\n allowOsRuleset,\n type Artifact,\n type ValDefs,\n type Launch,\n type Val,\n type Valset,\n type ConditionalVal,\n} from '@opys/core';\nimport {\n type Client,\n fetchAssetManifest,\n latestRelease,\n fetchVersionManifest,\n findVersion,\n type Version,\n} from '@opys/mojang';\nimport { mapLibraries } from './mappers/libraries';\nimport { mapAssetIndex, mapAssetObjects } from './mappers/assets';\nimport { mapClientJar } from './mappers/client';\nimport { buildClasspath, buildLaunch } from './mappers/launch';\n\nexport interface MinecraftTemplate {\n artifacts: Artifact[];\n vars: ValDefs;\n /** Per-OS classpath arms (also baked into `vars.classpath`). */\n classpath: ConditionalVal[];\n /** Assembled Launch — drop straight into `manifest.launch`. */\n launch: Launch;\n /** JVM args alone, for composition (e.g. interleaving an auth `-javaagent`). */\n jvmArgs: Valset;\n /** Main class wrapped as a `Val` so it spreads into a `Valset`. Raw string at `mainClass.value[0]`. */\n mainClass: Val;\n /** Game args alone, for composition. */\n gameArgs: Valset;\n}\n\nexport async function resolveMinecraft(config?: {\n version?: string;\n}): Promise<MinecraftTemplate> {\n const { client } = await fetchClient(config?.version);\n return clientToTemplate(client);\n}\n\nexport async function fetchClient(\n versionId?: string,\n): Promise<{ version: Version; client: Client }> {\n const manifest = await fetchVersionManifest();\n const version = versionId\n ? findVersion(manifest, versionId)\n : latestRelease(manifest);\n if (!version) throw new Error(`Version '${versionId ?? 'latest'}' not found`);\n const res = await fetchWithRetry(version.url);\n if (!res.ok)\n throw new Error(`Failed to fetch version JSON: ${res.statusText}`);\n const { parseClient } = await import('@opys/mojang');\n return { version, client: parseClient(await res.json()) };\n}\n\nexport async function clientToTemplate(\n client: Client,\n): Promise<MinecraftTemplate> {\n const manifest = await fetchAssetManifest(client.assetIndex.url);\n const artifacts: Artifact[] = [];\n\n artifacts.push(mapClientJar(client));\n artifacts.push(...mapLibraries(client.libraries));\n artifacts.push(mapAssetIndex(client.assetIndex));\n artifacts.push(...mapAssetObjects(manifest));\n\n const libPaths = client.libraries.map((l) => ({\n rules: l.rules,\n artifactPath: `\\${library_directory}/${l.artifact.path}`,\n }));\n\n const classpath = buildClasspath(libPaths, '\\${version_dir}/client.jar');\n\n const vars: ValDefs = {\n root: '.',\n launcher_name: 'opys',\n launcher_version: '0.1',\n version_type: client.metadata.type,\n version_name: client.id,\n game_directory: '\\${root}/',\n assets_root: '\\${root}/assets',\n game_assets: '\\${assets_root}',\n assets_index_name: client.assetIndex.id,\n version_dir: '\\${root}/versions/\\${version_name}',\n library_directory: '\\${root}/libraries',\n natives_directory: '\\${version_dir}/natives',\n auth_player_name: '\\${username}',\n auth_uuid: '\\${uuid}',\n auth_session: '\\${token}',\n auth_access_token: '\\${token}',\n user_type: 'mojang',\n user_properties: '{}',\n clientid: '',\n classpath_separator: [\n { value: ';', rules: allowOsRuleset('windows') },\n { value: ':', rules: allowOsRuleset('linux') },\n { value: ':', rules: allowOsRuleset('osx') },\n ],\n classpath,\n };\n\n const parts = buildLaunch(\n client.mainClass,\n client.args.game,\n client.args.jvm,\n );\n\n return { artifacts, vars, classpath, ...parts };\n}\n","import { definePlugin, launchGroups, type OpysPlugin } from '@opys/dev';\nimport { resolveMinecraft } from './template';\n\n/** Vanilla Minecraft client + libraries + assets. */\nexport function minecraft(version?: string): OpysPlugin {\n return definePlugin({\n name: 'minecraft',\n async build(ctx) {\n const t = await resolveMinecraft(version ? { version } : {});\n ctx.log('minecraft', `vanilla ${version ?? 'latest'}`);\n return { artifacts: t.artifacts, vars: t.vars, launch: launchGroups(t) };\n },\n });\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@opys/minecraft-vanilla",
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./dist/index.mjs",
9
+ "require": "./dist/index.cjs"
10
+ }
11
+ },
12
+ "scripts": {
13
+ "build": "tsdown lib/index.ts --format esm,cjs --dts --clean",
14
+ "typecheck": "tsc --noEmit -p tsconfig.json",
15
+ "test": "vitest run tests/unit --passWithNoTests"
16
+ },
17
+ "dependencies": {
18
+ "@opys/core": "^0.1.2",
19
+ "@opys/dev": "^0.1.2",
20
+ "@opys/mojang": "^0.1.2"
21
+ },
22
+ "devDependencies": {
23
+ "tsdown": "*",
24
+ "vitest": "*"
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "engines": {
30
+ "node": ">=20"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/harmoniya-net/opys.git",
35
+ "directory": "packages/minecraft-vanilla"
36
+ }
37
+ }