minecraft-server-dl-cli 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/README.md +147 -0
- package/README.zh-TW.md +147 -0
- package/bin/mc-server-dl.mjs +280 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# minecraft-server-dl-cli
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/minecraft-server-dl-cli)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
A simple CLI tool for downloading the official Minecraft Java `server.jar` by version.
|
|
8
|
+
|
|
9
|
+
This tool reads Mojang's official version manifest, resolves the requested Minecraft Java version, downloads the matching `server.jar`, and verifies the downloaded file using SHA1 when available.
|
|
10
|
+
|
|
11
|
+
## Languages
|
|
12
|
+
|
|
13
|
+
* [English](README.md)
|
|
14
|
+
* [繁體中文](README.zh-TW.md)
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
* Download official Minecraft Java `server.jar` by version
|
|
19
|
+
* Uses Mojang's official version manifest
|
|
20
|
+
* Automatically names files as `server_<version>.jar`
|
|
21
|
+
* Supports custom output paths
|
|
22
|
+
* Supports SHA1 and file size verification
|
|
23
|
+
* Can print the resolved download URL without downloading
|
|
24
|
+
* No runtime dependencies
|
|
25
|
+
|
|
26
|
+
## Official Data Sources
|
|
27
|
+
|
|
28
|
+
This tool uses Mojang/Minecraft official endpoints:
|
|
29
|
+
|
|
30
|
+
* [Minecraft Java version manifest](https://piston-meta.mojang.com/mc/game/version_manifest_v2.json)
|
|
31
|
+
* [Official Minecraft Java server download page](https://www.minecraft.net/en-us/download/server)
|
|
32
|
+
|
|
33
|
+
The resolved `server.jar` URL usually points to:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
https://piston-data.mojang.com/v1/objects/<sha1>/server.jar
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Requirements
|
|
40
|
+
|
|
41
|
+
* [Node.js](https://nodejs.org/) 18 or later
|
|
42
|
+
* npm, pnpm, or yarn
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
Install globally from npm:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install -g minecraft-server-dl-cli
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then run:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mc-server-dl 1.21.8
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or use it directly with `npx`:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx minecraft-server-dl-cli 1.21.8
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
mc-server-dl <version> [options]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Example:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
mc-server-dl 1.21.8
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This downloads:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
server_1.21.8.jar
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Options
|
|
83
|
+
|
|
84
|
+
| Option | Description |
|
|
85
|
+
| --------------------- | ------------------------------------------------------- |
|
|
86
|
+
| `-o, --output <path>` | Custom output path |
|
|
87
|
+
| `--no-verify` | Skip SHA1 and file size verification |
|
|
88
|
+
| `--url-only` | Print the resolved `server.jar` URL without downloading |
|
|
89
|
+
| `-h, --help` | Show help message |
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
Download a specific Minecraft Java server version:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
mc-server-dl 1.21.8
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Download and save to a custom path:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
mc-server-dl 1.21.8 -o ./servers/1.21.8/server.jar
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Print the official download URL only:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
mc-server-dl 1.21.8 --url-only
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Skip verification:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
mc-server-dl 1.21.8 --no-verify
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Exit Codes
|
|
118
|
+
|
|
119
|
+
| Code | Meaning |
|
|
120
|
+
| ---: | --------------------------------------------------------- |
|
|
121
|
+
| `0` | Success |
|
|
122
|
+
| `1` | Unexpected error |
|
|
123
|
+
| `2` | Invalid CLI arguments |
|
|
124
|
+
| `3` | Failed to fetch or parse metadata |
|
|
125
|
+
| `4` | Minecraft version not found |
|
|
126
|
+
| `5` | Version exists, but no official `server.jar` is available |
|
|
127
|
+
| `6` | Download failed |
|
|
128
|
+
| `7` | File size or SHA1 verification failed |
|
|
129
|
+
|
|
130
|
+
## How It Works
|
|
131
|
+
|
|
132
|
+
1. Fetches Mojang's version manifest.
|
|
133
|
+
2. Finds the requested Minecraft Java version.
|
|
134
|
+
3. Fetches that version's metadata JSON.
|
|
135
|
+
4. Reads `downloads.server.url`.
|
|
136
|
+
5. Downloads the official `server.jar`.
|
|
137
|
+
6. Verifies file size and SHA1 when metadata is available.
|
|
138
|
+
|
|
139
|
+
## Disclaimer
|
|
140
|
+
|
|
141
|
+
This project is not affiliated with Mojang Studios or Microsoft.
|
|
142
|
+
|
|
143
|
+
Minecraft is a trademark of Mojang Synergies AB. This tool only resolves and downloads files from official Mojang/Minecraft endpoints.
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
[MIT](LICENSE)
|
package/README.zh-TW.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# minecraft-server-dl-cli
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/minecraft-server-dl-cli)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
一個簡易的 CLI 工具,用來依照指定版本下載官方 Minecraft Java `server.jar`。
|
|
8
|
+
|
|
9
|
+
這個工具會讀取 Mojang 官方版本清單,解析指定的 Minecraft Java 版本,下載對應的 `server.jar`,並在 metadata 有提供時使用 SHA1 驗證下載結果。
|
|
10
|
+
|
|
11
|
+
## 語言
|
|
12
|
+
|
|
13
|
+
* [English](README.md)
|
|
14
|
+
* [繁體中文](README.zh-TW.md)
|
|
15
|
+
|
|
16
|
+
## 功能
|
|
17
|
+
|
|
18
|
+
* 依照版本下載官方 Minecraft Java `server.jar`
|
|
19
|
+
* 使用 Mojang 官方版本 manifest
|
|
20
|
+
* 預設輸出檔名為 `server_<version>.jar`
|
|
21
|
+
* 支援自訂輸出路徑
|
|
22
|
+
* 支援 SHA1 與檔案大小驗證
|
|
23
|
+
* 可只印出解析後的下載 URL,不下載檔案
|
|
24
|
+
* 不需要額外 runtime dependencies
|
|
25
|
+
|
|
26
|
+
## 官方資料來源
|
|
27
|
+
|
|
28
|
+
本工具使用 Mojang/Minecraft 官方端點:
|
|
29
|
+
|
|
30
|
+
* [Minecraft Java version manifest](https://piston-meta.mojang.com/mc/game/version_manifest_v2.json)
|
|
31
|
+
* [Minecraft Java 官方伺服器下載頁](https://www.minecraft.net/en-us/download/server)
|
|
32
|
+
|
|
33
|
+
解析後的 `server.jar` 下載 URL 通常會長這樣:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
https://piston-data.mojang.com/v1/objects/<sha1>/server.jar
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 系統需求
|
|
40
|
+
|
|
41
|
+
* [Node.js](https://nodejs.org/) 18 或更新版本
|
|
42
|
+
* npm、pnpm 或 yarn
|
|
43
|
+
|
|
44
|
+
## 安裝
|
|
45
|
+
|
|
46
|
+
從 npm 全域安裝:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install -g minecraft-server-dl-cli
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
執行:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mc-server-dl 1.21.8
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
或直接使用 `npx`:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx minecraft-server-dl-cli 1.21.8
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 使用方式
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
mc-server-dl <version> [options]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
範例:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
mc-server-dl 1.21.8
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
會下載成:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
server_1.21.8.jar
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 參數
|
|
83
|
+
|
|
84
|
+
| 參數 | 說明 |
|
|
85
|
+
| --------------------- | ------------------------------ |
|
|
86
|
+
| `-o, --output <path>` | 自訂輸出路徑 |
|
|
87
|
+
| `--no-verify` | 跳過 SHA1 與檔案大小驗證 |
|
|
88
|
+
| `--url-only` | 只印出解析後的 `server.jar` URL,不下載檔案 |
|
|
89
|
+
| `-h, --help` | 顯示說明 |
|
|
90
|
+
|
|
91
|
+
## 範例
|
|
92
|
+
|
|
93
|
+
下載指定 Minecraft Java server 版本:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
mc-server-dl 1.21.8
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
下載到指定路徑:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
mc-server-dl 1.21.8 -o ./servers/1.21.8/server.jar
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
只印出官方下載 URL:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
mc-server-dl 1.21.8 --url-only
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
跳過驗證:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
mc-server-dl 1.21.8 --no-verify
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Exit Codes
|
|
118
|
+
|
|
119
|
+
| Code | 意義 |
|
|
120
|
+
| ---: | --------------------------- |
|
|
121
|
+
| `0` | 成功 |
|
|
122
|
+
| `1` | 未預期錯誤 |
|
|
123
|
+
| `2` | CLI 參數錯誤 |
|
|
124
|
+
| `3` | metadata 取得或解析失敗 |
|
|
125
|
+
| `4` | 找不到指定 Minecraft 版本 |
|
|
126
|
+
| `5` | 版本存在,但沒有官方 `server.jar` 可下載 |
|
|
127
|
+
| `6` | 下載失敗 |
|
|
128
|
+
| `7` | 檔案大小或 SHA1 驗證失敗 |
|
|
129
|
+
|
|
130
|
+
## 運作方式
|
|
131
|
+
|
|
132
|
+
1. 取得 Mojang version manifest。
|
|
133
|
+
2. 找到使用者指定的 Minecraft Java 版本。
|
|
134
|
+
3. 取得該版本的 metadata JSON。
|
|
135
|
+
4. 讀取 `downloads.server.url`。
|
|
136
|
+
5. 下載官方 `server.jar`。
|
|
137
|
+
6. 若 metadata 有提供,驗證檔案大小與 SHA1。
|
|
138
|
+
|
|
139
|
+
## 免責聲明
|
|
140
|
+
|
|
141
|
+
本專案與 Mojang Studios 或 Microsoft 沒有關聯。
|
|
142
|
+
|
|
143
|
+
Minecraft 是 Mojang Synergies AB 的商標。本工具只會解析並下載 Mojang/Minecraft 官方端點提供的檔案。
|
|
144
|
+
|
|
145
|
+
## 授權
|
|
146
|
+
|
|
147
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { createWriteStream } from 'node:fs';
|
|
5
|
+
import { mkdir, rename, rm, stat } from 'node:fs/promises';
|
|
6
|
+
import { dirname, resolve } from 'node:path';
|
|
7
|
+
import { Readable } from 'node:stream';
|
|
8
|
+
import { pipeline } from 'node:stream/promises';
|
|
9
|
+
|
|
10
|
+
const MANIFEST_URL = 'https://piston-meta.mojang.com/mc/game/version_manifest_v2.json';
|
|
11
|
+
const USER_AGENT = 'mc-server-dl-cli/0.1.0';
|
|
12
|
+
|
|
13
|
+
class CliError extends Error {
|
|
14
|
+
constructor(message, exitCode = 1) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'CliError';
|
|
17
|
+
this.exitCode = exitCode;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function printHelp() {
|
|
22
|
+
console.log(`
|
|
23
|
+
Usage:
|
|
24
|
+
mc-server-dl <version> [options]
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
-o, --output <path> Output jar path. Default: server_<version>.jar
|
|
28
|
+
--no-verify Skip SHA1 verification
|
|
29
|
+
--url-only Print server.jar URL only, do not download
|
|
30
|
+
-h, --help Show help
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
mc-server-dl 1.21.8
|
|
34
|
+
mc-server-dl 1.21.8 -o ./servers/1.21.8/server.jar
|
|
35
|
+
mc-server-dl 1.21.8 --url-only
|
|
36
|
+
`.trim());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseArgs(argv) {
|
|
40
|
+
const args = {
|
|
41
|
+
version: null,
|
|
42
|
+
output: null,
|
|
43
|
+
verify: true,
|
|
44
|
+
urlOnly: false
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
48
|
+
const token = argv[i];
|
|
49
|
+
|
|
50
|
+
if (token === '-h' || token === '--help') {
|
|
51
|
+
printHelp();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (token === '-o' || token === '--output') {
|
|
56
|
+
const value = argv[i + 1];
|
|
57
|
+
|
|
58
|
+
if (!value || value.startsWith('-')) {
|
|
59
|
+
throw new CliError('Missing output path: -o <path>', 2);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
args.output = value;
|
|
63
|
+
i += 1;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (token === '--no-verify') {
|
|
68
|
+
args.verify = false;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (token === '--url-only') {
|
|
73
|
+
args.urlOnly = true;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (token.startsWith('-')) {
|
|
78
|
+
throw new CliError(`Unknown option: ${token}`, 2);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (args.version) {
|
|
82
|
+
throw new CliError(`Only one Minecraft version can be specified. Extra argument: ${token}`, 2);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
args.version = token;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!args.version) {
|
|
89
|
+
throw new CliError('Please specify a Minecraft version, for example: mc-server-dl 1.21.8', 2);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return args;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function getJson(url) {
|
|
96
|
+
const response = await fetch(url, {
|
|
97
|
+
headers: {
|
|
98
|
+
// Make requests identifiable in server logs for easier troubleshooting.
|
|
99
|
+
'User-Agent': USER_AGENT,
|
|
100
|
+
Accept: 'application/json'
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
throw new CliError(`HTTP ${response.status}: ${url}`, 3);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
return await response.json();
|
|
110
|
+
} catch (error) {
|
|
111
|
+
throw new CliError(`Failed to parse JSON response: ${url}`, 3);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function findVersion(manifest, version) {
|
|
116
|
+
const item = manifest.versions?.find((entry) => entry.id === version);
|
|
117
|
+
|
|
118
|
+
if (!item) {
|
|
119
|
+
const latestRelease = manifest.latest?.release ?? 'unknown';
|
|
120
|
+
const latestSnapshot = manifest.latest?.snapshot ?? 'unknown';
|
|
121
|
+
|
|
122
|
+
throw new CliError(
|
|
123
|
+
[
|
|
124
|
+
`Minecraft Java version not found: ${version}`,
|
|
125
|
+
`latest release: ${latestRelease}`,
|
|
126
|
+
`latest snapshot: ${latestSnapshot}`
|
|
127
|
+
].join('\n'),
|
|
128
|
+
4
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return item;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function resolveServerDownload(version) {
|
|
136
|
+
const manifest = await getJson(MANIFEST_URL);
|
|
137
|
+
const versionMeta = findVersion(manifest, version);
|
|
138
|
+
const versionJson = await getJson(versionMeta.url);
|
|
139
|
+
|
|
140
|
+
const server = versionJson.downloads?.server;
|
|
141
|
+
|
|
142
|
+
if (!server?.url) {
|
|
143
|
+
throw new CliError(`Version ${version} exists, but no official server.jar download is available.`, 5);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
version,
|
|
148
|
+
url: server.url,
|
|
149
|
+
sha1: server.sha1 ?? '',
|
|
150
|
+
size: Number(server.size ?? 0)
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function downloadFile(url, outputPath) {
|
|
155
|
+
const absoluteOutputPath = resolve(outputPath);
|
|
156
|
+
const tempPath = `${absoluteOutputPath}.tmp-${process.pid}`;
|
|
157
|
+
|
|
158
|
+
await mkdir(dirname(absoluteOutputPath), { recursive: true });
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const response = await fetch(url, {
|
|
162
|
+
headers: {
|
|
163
|
+
'User-Agent': USER_AGENT
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (!response.ok) {
|
|
168
|
+
throw new CliError(`Download failed, HTTP ${response.status}: ${url}`, 6);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!response.body) {
|
|
172
|
+
throw new CliError('Download failed: response body is empty', 6);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Write to a temporary file first to avoid replacing an existing valid server.jar on failure.
|
|
176
|
+
await pipeline(
|
|
177
|
+
Readable.fromWeb(response.body),
|
|
178
|
+
createWriteStream(tempPath)
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
await rename(tempPath, absoluteOutputPath);
|
|
182
|
+
|
|
183
|
+
return absoluteOutputPath;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
await rm(tempPath, { force: true });
|
|
186
|
+
|
|
187
|
+
if (error instanceof CliError) {
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
throw new CliError(`Download failed: ${error.message}`, 6);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function sha1OfFile(path) {
|
|
196
|
+
const hash = createHash('sha1');
|
|
197
|
+
const fileStream = Readable.toWeb(
|
|
198
|
+
await import('node:fs').then(({ createReadStream }) => createReadStream(path))
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const reader = fileStream.getReader();
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
while (true) {
|
|
205
|
+
const { done, value } = await reader.read();
|
|
206
|
+
|
|
207
|
+
if (done) {
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
hash.update(value);
|
|
212
|
+
}
|
|
213
|
+
} finally {
|
|
214
|
+
reader.releaseLock();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return hash.digest('hex');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function verifyFile(path, expectedSha1, expectedSize) {
|
|
221
|
+
if (expectedSize > 0) {
|
|
222
|
+
const fileStat = await stat(path);
|
|
223
|
+
|
|
224
|
+
if (fileStat.size !== expectedSize) {
|
|
225
|
+
throw new CliError(
|
|
226
|
+
`File size mismatch: expected=${expectedSize}, actual=${fileStat.size}`,
|
|
227
|
+
7
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!expectedSha1) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const actualSha1 = await sha1OfFile(path);
|
|
237
|
+
|
|
238
|
+
if (actualSha1.toLowerCase() !== expectedSha1.toLowerCase()) {
|
|
239
|
+
throw new CliError(
|
|
240
|
+
[
|
|
241
|
+
'SHA1 verification failed:',
|
|
242
|
+
`expected: ${expectedSha1}`,
|
|
243
|
+
`actual: ${actualSha1}`
|
|
244
|
+
].join('\n'),
|
|
245
|
+
7
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async function main() {
|
|
251
|
+
const args = parseArgs(process.argv.slice(2));
|
|
252
|
+
const server = await resolveServerDownload(args.version);
|
|
253
|
+
|
|
254
|
+
if (args.urlOnly) {
|
|
255
|
+
console.log(server.url);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
console.log(`Version: ${server.version}`);
|
|
260
|
+
console.log(`URL: ${server.url}`);
|
|
261
|
+
|
|
262
|
+
const output = args.output ?? `server_${server.version}.jar`;
|
|
263
|
+
const outputPath = await downloadFile(server.url, output);
|
|
264
|
+
|
|
265
|
+
if (args.verify) {
|
|
266
|
+
await verifyFile(outputPath, server.sha1, server.size);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
console.log(`Downloaded: ${outputPath}`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
main().catch((error) => {
|
|
273
|
+
if (error instanceof CliError) {
|
|
274
|
+
console.error(`Error: ${error.message}`);
|
|
275
|
+
process.exit(error.exitCode);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
console.error(error);
|
|
279
|
+
process.exit(1);
|
|
280
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "minecraft-server-dl-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Download official Minecraft Java server.jar by version.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mc-server-dl": "./bin/mc-server-dl.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "node ./bin/mc-server-dl.mjs",
|
|
19
|
+
"pack:check": "npm pack --dry-run"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"minecraft",
|
|
23
|
+
"server",
|
|
24
|
+
"cli",
|
|
25
|
+
"downloader",
|
|
26
|
+
"mojang"
|
|
27
|
+
],
|
|
28
|
+
"author": "DoSer ZBlock",
|
|
29
|
+
"license": "MIT"
|
|
30
|
+
}
|