@dimzxzzx07/mc-headless 1.7.0 → 1.9.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 +317 -703
- package/dist/core/JavaChecker.d.ts +16 -3
- package/dist/core/JavaChecker.d.ts.map +1 -1
- package/dist/core/JavaChecker.js +179 -31
- package/dist/core/JavaChecker.js.map +1 -1
- package/dist/core/MinecraftServer.d.ts +61 -0
- package/dist/core/MinecraftServer.d.ts.map +1 -1
- package/dist/core/MinecraftServer.js +742 -60
- package/dist/core/MinecraftServer.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -16
- package/dist/index.js.map +1 -1
- package/dist/platforms/BedrockServer.d.ts.map +1 -1
- package/dist/platforms/BedrockServer.js +2 -0
- package/dist/platforms/BedrockServer.js.map +1 -1
- package/dist/platforms/JavaServer.d.ts.map +1 -1
- package/dist/platforms/JavaServer.js +2 -0
- package/dist/platforms/JavaServer.js.map +1 -1
- package/dist/platforms/SkinRestorer.d.ts +14 -0
- package/dist/platforms/SkinRestorer.d.ts.map +1 -0
- package/dist/platforms/SkinRestorer.js +145 -0
- package/dist/platforms/SkinRestorer.js.map +1 -0
- package/dist/platforms/SkinsRestorer.d.ts +14 -0
- package/dist/platforms/SkinsRestorer.d.ts.map +1 -0
- package/dist/platforms/SkinsRestorer.js +145 -0
- package/dist/platforms/SkinsRestorer.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/JavaChecker.ts +170 -34
- package/src/core/MinecraftServer.ts +854 -64
- package/src/index.ts +33 -17
- package/src/platforms/BedrockServer.ts +2 -0
- package/src/platforms/JavaServer.ts +2 -0
- package/src/platforms/SkinRestorer.ts +127 -0
- package/src/scripts/install-java.sh +97 -32
- package/src/types/index.ts +2 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.SkinRestorerManager = void 0;
|
|
40
|
+
const FileUtils_1 = require("../utils/FileUtils");
|
|
41
|
+
const Logger_1 = require("../utils/Logger");
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const axios_1 = __importDefault(require("axios"));
|
|
44
|
+
const fs = __importStar(require("fs-extra"));
|
|
45
|
+
class SkinRestorerManager {
|
|
46
|
+
logger = Logger_1.Logger.getInstance();
|
|
47
|
+
SKINRESTORER_URL = 'https://github.com/SkinsRestorer/SkinsRestorerX/releases/latest/download/SkinsRestorer.jar';
|
|
48
|
+
async setup(config) {
|
|
49
|
+
const pluginsDir = config.folders.plugins;
|
|
50
|
+
await FileUtils_1.FileUtils.ensureDir(pluginsDir);
|
|
51
|
+
this.logger.info('Setting up SkinRestorer...');
|
|
52
|
+
await this.cleanupCorruptFiles(pluginsDir);
|
|
53
|
+
await this.downloadSkinRestorer(pluginsDir);
|
|
54
|
+
await this.verifyPlugin(pluginsDir);
|
|
55
|
+
this.logger.success('SkinRestorer installed successfully');
|
|
56
|
+
this.logger.info('Player skins will now be restored automatically');
|
|
57
|
+
}
|
|
58
|
+
async cleanupCorruptFiles(pluginsDir) {
|
|
59
|
+
const filePath = path.join(pluginsDir, 'SkinsRestorer.jar');
|
|
60
|
+
if (await FileUtils_1.FileUtils.fileExists(filePath)) {
|
|
61
|
+
try {
|
|
62
|
+
const stats = await fs.stat(filePath);
|
|
63
|
+
if (stats.size < 100000) {
|
|
64
|
+
this.logger.warning('Corrupt SkinRestorer detected, removing...');
|
|
65
|
+
await fs.remove(filePath);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const buffer = await fs.readFile(filePath);
|
|
69
|
+
if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
|
|
70
|
+
this.logger.warning('Invalid ZIP header in SkinRestorer, removing...');
|
|
71
|
+
await fs.remove(filePath);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.logger.info('SkinRestorer is valid, keeping it');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
this.logger.warning('Error checking SkinRestorer, removing...');
|
|
80
|
+
await fs.remove(filePath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async downloadSkinRestorer(pluginsDir) {
|
|
85
|
+
const destPath = path.join(pluginsDir, 'SkinsRestorer.jar');
|
|
86
|
+
if (await FileUtils_1.FileUtils.fileExists(destPath)) {
|
|
87
|
+
this.logger.info('SkinRestorer already exists, skipping download');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.logger.info('Downloading SkinRestorer...');
|
|
91
|
+
try {
|
|
92
|
+
const response = await (0, axios_1.default)({
|
|
93
|
+
method: 'GET',
|
|
94
|
+
url: this.SKINRESTORER_URL,
|
|
95
|
+
responseType: 'stream',
|
|
96
|
+
timeout: 60000,
|
|
97
|
+
headers: {
|
|
98
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
const writer = fs.createWriteStream(destPath);
|
|
102
|
+
response.data.pipe(writer);
|
|
103
|
+
await new Promise((resolve, reject) => {
|
|
104
|
+
writer.on('finish', () => resolve());
|
|
105
|
+
writer.on('error', (err) => reject(err));
|
|
106
|
+
});
|
|
107
|
+
const stats = await fs.stat(destPath);
|
|
108
|
+
if (stats.size < 100000) {
|
|
109
|
+
throw new Error(`Downloaded file too small: ${stats.size} bytes`);
|
|
110
|
+
}
|
|
111
|
+
const buffer = await fs.readFile(destPath);
|
|
112
|
+
if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
|
|
113
|
+
throw new Error('Invalid ZIP header');
|
|
114
|
+
}
|
|
115
|
+
this.logger.success(`Downloaded SkinRestorer (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
this.logger.error('Failed to download SkinRestorer:', error);
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async verifyPlugin(pluginsDir) {
|
|
123
|
+
const filePath = path.join(pluginsDir, 'SkinsRestorer.jar');
|
|
124
|
+
if (!await FileUtils_1.FileUtils.fileExists(filePath)) {
|
|
125
|
+
throw new Error('SkinRestorer plugin is missing');
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const stats = await fs.stat(filePath);
|
|
129
|
+
if (stats.size < 100000) {
|
|
130
|
+
throw new Error('SkinRestorer plugin is too small');
|
|
131
|
+
}
|
|
132
|
+
const buffer = await fs.readFile(filePath);
|
|
133
|
+
if (buffer[0] !== 0x50 || buffer[1] !== 0x4B) {
|
|
134
|
+
throw new Error('SkinRestorer plugin has invalid ZIP header');
|
|
135
|
+
}
|
|
136
|
+
this.logger.debug(`SkinRestorer verified OK (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
this.logger.error('Failed to verify SkinRestorer:', error);
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.SkinRestorerManager = SkinRestorerManager;
|
|
145
|
+
//# sourceMappingURL=SkinsRestorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkinsRestorer.js","sourceRoot":"","sources":["../../src/platforms/SkinsRestorer.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface MinecraftConfig {
|
|
|
26
26
|
seed?: string;
|
|
27
27
|
maxPlayers: number;
|
|
28
28
|
viewDistance: number;
|
|
29
|
+
simulationDistance?: number;
|
|
29
30
|
levelName: string;
|
|
30
31
|
};
|
|
31
32
|
folders: {
|
|
@@ -56,6 +57,7 @@ export interface ServerInfo {
|
|
|
56
57
|
used: number;
|
|
57
58
|
max: number;
|
|
58
59
|
};
|
|
60
|
+
cpu: number;
|
|
59
61
|
status: 'starting' | 'running' | 'stopping' | 'stopped' | 'crashed';
|
|
60
62
|
}
|
|
61
63
|
export interface DownloadInfo {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AACxF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AACjE,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IAExB,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,cAAc,EAAE,OAAO,CAAC;KAC3B,CAAC;IAEF,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,OAAO,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,KAAK,EAAE;QACH,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,OAAO,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE;QACJ,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;CACL;AAED,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;CACvE;AAED,MAAM,WAAW,YAAY;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,MAAM;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,IAAI,CAAC;CACrB"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/core/JavaChecker.ts
CHANGED
|
@@ -1,41 +1,55 @@
|
|
|
1
1
|
import { execSync, exec } from 'child_process';
|
|
2
|
+
import * as fs from 'fs-extra';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as https from 'https';
|
|
5
|
+
import * as tar from 'tar';
|
|
2
6
|
import { Logger } from '../utils/Logger';
|
|
3
|
-
|
|
7
|
+
|
|
8
|
+
export interface JavaInfo {
|
|
9
|
+
path: string;
|
|
10
|
+
version: string;
|
|
11
|
+
type: 'system' | 'portable';
|
|
12
|
+
}
|
|
4
13
|
|
|
5
14
|
export class JavaChecker {
|
|
6
15
|
private static logger = Logger.getInstance();
|
|
16
|
+
private static readonly JAVA_DIR = path.join('/tmp', '.mc-headless-java');
|
|
17
|
+
private static readonly JAVA_17_URL = 'https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.10%2B7/OpenJDK17U-jre_x64_linux_hotspot_17.0.10_7.tar.gz';
|
|
18
|
+
private static readonly JAVA_21_URL = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2%2B13/OpenJDK21U-jre_x64_linux_hotspot_21.0.2_13.tar.gz';
|
|
19
|
+
private static readonly JAVA_11_URL = 'https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.22%2B7/OpenJDK11U-jre_x64_linux_hotspot_11.0.22_7.tar.gz';
|
|
20
|
+
private static readonly JAVA_8_URL = 'https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u402-b06/OpenJDK8U-jre_x64_linux_hotspot_8u402b06.tar.gz';
|
|
7
21
|
|
|
8
|
-
public static checkJava(): Promise<boolean> {
|
|
22
|
+
public static async checkJava(): Promise<boolean> {
|
|
9
23
|
return new Promise((resolve) => {
|
|
10
|
-
exec('java
|
|
11
|
-
if (error) {
|
|
12
|
-
this.logger.warning('Java is not installed');
|
|
24
|
+
exec('which java', (error, stdout) => {
|
|
25
|
+
if (error || !stdout.trim()) {
|
|
26
|
+
this.logger.warning('Java is not installed in system');
|
|
13
27
|
resolve(false);
|
|
14
28
|
} else {
|
|
15
|
-
|
|
29
|
+
const javaPath = stdout.trim();
|
|
30
|
+
this.logger.success(`System Java found at: ${javaPath}`);
|
|
16
31
|
resolve(true);
|
|
17
32
|
}
|
|
18
33
|
});
|
|
19
34
|
});
|
|
20
35
|
}
|
|
21
36
|
|
|
22
|
-
public static
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const version = this.getJavaVersion();
|
|
31
|
-
if (version) {
|
|
32
|
-
this.logger.success(`Java version: ${version}`);
|
|
37
|
+
public static getSystemJavaPath(): string | null {
|
|
38
|
+
try {
|
|
39
|
+
const stdout = execSync('which java').toString().trim();
|
|
40
|
+
return stdout || null;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
33
43
|
}
|
|
34
44
|
}
|
|
35
45
|
|
|
36
|
-
public static
|
|
46
|
+
public static getSystemJavaVersion(): string | null {
|
|
37
47
|
try {
|
|
38
48
|
const output = execSync('java -version 2>&1').toString();
|
|
49
|
+
if (output.includes('version "21')) return '21';
|
|
50
|
+
if (output.includes('version "17')) return '17';
|
|
51
|
+
if (output.includes('version "11')) return '11';
|
|
52
|
+
if (output.includes('version "1.8')) return '8';
|
|
39
53
|
const match = output.match(/version "([^"]+)"/);
|
|
40
54
|
return match ? match[1] : null;
|
|
41
55
|
} catch {
|
|
@@ -43,29 +57,151 @@ export class JavaChecker {
|
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
59
|
|
|
46
|
-
public static async
|
|
47
|
-
|
|
60
|
+
public static async getOrDownloadPortableJava(version: '17' | '21' | '11' | '8' = '17'): Promise<JavaInfo> {
|
|
61
|
+
await fs.ensureDir(this.JAVA_DIR);
|
|
62
|
+
|
|
63
|
+
const javaHome = path.join(this.JAVA_DIR, `jre-${version}`);
|
|
64
|
+
const javaBin = path.join(javaHome, 'bin', 'java');
|
|
65
|
+
|
|
66
|
+
if (await fs.pathExists(javaBin)) {
|
|
67
|
+
this.logger.info(`Portable Java ${version} already exists at ${javaBin}`);
|
|
68
|
+
|
|
69
|
+
const versionOutput = execSync(`"${javaBin}" -version 2>&1`).toString();
|
|
70
|
+
this.logger.debug(`Portable Java version: ${versionOutput.split('\n')[0]}`);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
path: javaBin,
|
|
74
|
+
version: version,
|
|
75
|
+
type: 'portable'
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.logger.info(`Downloading portable Java ${version} JRE...`);
|
|
48
80
|
|
|
49
|
-
|
|
81
|
+
let downloadUrl = '';
|
|
82
|
+
switch (version) {
|
|
83
|
+
case '21':
|
|
84
|
+
downloadUrl = this.JAVA_21_URL;
|
|
85
|
+
break;
|
|
86
|
+
case '17':
|
|
87
|
+
downloadUrl = this.JAVA_17_URL;
|
|
88
|
+
break;
|
|
89
|
+
case '11':
|
|
90
|
+
downloadUrl = this.JAVA_11_URL;
|
|
91
|
+
break;
|
|
92
|
+
case '8':
|
|
93
|
+
downloadUrl = this.JAVA_8_URL;
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
downloadUrl = this.JAVA_17_URL;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const tarPath = path.join(this.JAVA_DIR, `jre-${version}.tar.gz`);
|
|
100
|
+
|
|
101
|
+
await this.downloadFile(downloadUrl, tarPath);
|
|
102
|
+
|
|
103
|
+
this.logger.info(`Extracting Java ${version}...`);
|
|
104
|
+
await fs.ensureDir(javaHome);
|
|
105
|
+
await tar.extract({
|
|
106
|
+
file: tarPath,
|
|
107
|
+
cwd: javaHome,
|
|
108
|
+
strip: 1
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await fs.remove(tarPath);
|
|
112
|
+
|
|
113
|
+
await fs.chmod(javaBin, 0o755);
|
|
114
|
+
|
|
115
|
+
this.logger.success(`Portable Java ${version} installed at ${javaBin}`);
|
|
116
|
+
|
|
117
|
+
const versionOutput = execSync(`"${javaBin}" -version 2>&1`).toString();
|
|
118
|
+
this.logger.debug(`Portable Java version: ${versionOutput.split('\n')[0]}`);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
path: javaBin,
|
|
122
|
+
version: version,
|
|
123
|
+
type: 'portable'
|
|
124
|
+
};
|
|
125
|
+
}
|
|
50
126
|
|
|
127
|
+
private static downloadFile(url: string, destPath: string): Promise<void> {
|
|
51
128
|
return new Promise((resolve, reject) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
129
|
+
this.logger.info(`Downloading from ${url}`);
|
|
130
|
+
|
|
131
|
+
const file = fs.createWriteStream(destPath);
|
|
132
|
+
https.get(url, (response) => {
|
|
133
|
+
if (response.statusCode !== 200) {
|
|
134
|
+
reject(new Error(`Download failed: ${response.statusCode}`));
|
|
135
|
+
return;
|
|
59
136
|
}
|
|
60
|
-
});
|
|
61
137
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
138
|
+
const totalSize = parseInt(response.headers['content-length'] || '0');
|
|
139
|
+
let downloadedSize = 0;
|
|
140
|
+
|
|
141
|
+
response.on('data', (chunk) => {
|
|
142
|
+
downloadedSize += chunk.length;
|
|
143
|
+
if (totalSize > 0) {
|
|
144
|
+
const percent = ((downloadedSize / totalSize) * 100).toFixed(1);
|
|
145
|
+
process.stdout.write(`\rDownloading Java: ${percent}% (${(downloadedSize / 1024 / 1024).toFixed(1)} MB / ${(totalSize / 1024 / 1024).toFixed(1)} MB)`);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
response.pipe(file);
|
|
65
150
|
|
|
66
|
-
|
|
67
|
-
|
|
151
|
+
file.on('finish', () => {
|
|
152
|
+
process.stdout.write('\n');
|
|
153
|
+
file.close();
|
|
154
|
+
resolve();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
file.on('error', (err) => {
|
|
158
|
+
fs.unlink(destPath).catch(() => {});
|
|
159
|
+
reject(err);
|
|
160
|
+
});
|
|
161
|
+
}).on('error', (err) => {
|
|
162
|
+
fs.unlink(destPath).catch(() => {});
|
|
163
|
+
reject(err);
|
|
68
164
|
});
|
|
69
165
|
});
|
|
70
166
|
}
|
|
167
|
+
|
|
168
|
+
public static async ensureJava(version: '17' | '21' | 'auto' = 'auto', usePortable: boolean = true): Promise<JavaInfo> {
|
|
169
|
+
const targetVersion = version === 'auto' ? '17' : version;
|
|
170
|
+
|
|
171
|
+
if (!usePortable) {
|
|
172
|
+
const systemJava = this.getSystemJavaPath();
|
|
173
|
+
if (systemJava) {
|
|
174
|
+
const systemVersion = this.getSystemJavaVersion();
|
|
175
|
+
if (systemVersion === targetVersion || (targetVersion === '17' && systemVersion === '21')) {
|
|
176
|
+
this.logger.success(`Using system Java ${systemVersion} at ${systemJava}`);
|
|
177
|
+
return {
|
|
178
|
+
path: systemJava,
|
|
179
|
+
version: systemVersion || targetVersion,
|
|
180
|
+
type: 'system'
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return this.getOrDownloadPortableJava(targetVersion as any);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
public static cleanupOldJava(): void {
|
|
190
|
+
try {
|
|
191
|
+
const files = fs.readdirSync(this.JAVA_DIR);
|
|
192
|
+
const now = Date.now();
|
|
193
|
+
const oneDay = 24 * 60 * 60 * 1000;
|
|
194
|
+
|
|
195
|
+
files.forEach(file => {
|
|
196
|
+
const filePath = path.join(this.JAVA_DIR, file);
|
|
197
|
+
const stats = fs.statSync(filePath);
|
|
198
|
+
if (now - stats.mtimeMs > oneDay) {
|
|
199
|
+
fs.removeSync(filePath);
|
|
200
|
+
this.logger.debug(`Cleaned up old Java: ${file}`);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
} catch (error) {
|
|
204
|
+
this.logger.debug('No old Java to cleanup');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
71
207
|
}
|