silver-mc-java-core
Version:
A library starting minecraft game NW.js and Electron.js
163 lines (162 loc) • 8.45 kB
JavaScript
;
/**
* @author Luuxis
* @license CC-BY-NC 4.0 - https://creativecommons.org/licenses/by-nc/4.0/
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const os_1 = __importDefault(require("os"));
const node_fetch_1 = __importDefault(require("node-fetch"));
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const events_1 = __importDefault(require("events"));
const node_7z_1 = __importDefault(require("node-7z"));
const _7zip_bin_1 = __importDefault(require("7zip-bin"));
const Index_js_1 = require("../utils/Index.js");
const Downloader_js_1 = __importDefault(require("../utils/Downloader.js"));
class JavaDownloader extends events_1.default {
constructor(options) {
super();
this.options = options;
}
async getJavaFiles(jsonversion) {
if (this.options.java.version)
return await this.getJavaOther(jsonversion, this.options.java.version);
const archMapping = {
win32: { x64: 'windows-x64', ia32: 'windows-x86', arm64: 'windows-arm64' },
darwin: { x64: 'mac-os', arm64: this.options.intelEnabledMac ? "mac-os" : "mac-os-arm64" },
linux: { x64: 'linux', ia32: 'linux-i386' }
};
const osPlatform = os_1.default.platform();
const arch = os_1.default.arch();
const osArchMapping = archMapping[osPlatform];
const javaVersion = jsonversion.javaVersion?.component || 'jre-legacy';
let files = [];
if (!osArchMapping)
return await this.getJavaOther(jsonversion);
const archOs = osArchMapping[arch];
const javaVersionsJson = await (0, node_fetch_1.default)(`https://launchermeta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json`).then(res => res.json());
const versionName = javaVersionsJson[archOs]?.[javaVersion]?.[0]?.version?.name;
if (!versionName)
return await this.getJavaOther(jsonversion);
const manifestUrl = javaVersionsJson[archOs][javaVersion][0]?.manifest?.url;
const manifest = await (0, node_fetch_1.default)(manifestUrl).then(res => res.json());
const javaFiles = Object.entries(manifest.files);
const java = javaFiles.find(([path]) => path.endsWith(process.platform === 'win32' ? 'bin/javaw.exe' : 'bin/java'))[0];
const toDelete = java.replace(process.platform === 'win32' ? 'bin/javaw.exe' : 'bin/java', '');
for (let [path, info] of javaFiles) {
if (info.type == "directory")
continue;
if (!info.downloads)
continue;
let file = {};
file.path = `runtime/jre-${versionName}-${archOs}/${path.replace(toDelete, "")}`;
file.executable = info.executable;
file.sha1 = info.downloads.raw.sha1;
file.size = info.downloads.raw.size;
file.url = info.downloads.raw.url;
file.type = "Java";
files.push(file);
}
return {
files,
path: path_1.default.resolve(this.options.path, `runtime/jre-${versionName}-${archOs}/bin/java`),
};
}
async getJavaOther(jsonversion, versionDownload) {
const majorVersion = versionDownload || jsonversion.javaVersion?.majorVersion || 8;
const javaVersionURL = `https://api.adoptium.net/v3/assets/latest/${majorVersion}/hotspot`;
const javaVersions = await (0, node_fetch_1.default)(javaVersionURL).then(res => res.json());
const { platform, arch } = this.getPlatformArch();
const java = javaVersions.find(({ binary }) => binary.image_type === this.options.java.type &&
binary.architecture === arch &&
binary.os === platform);
if (!java)
return { error: true, message: "No Java found" };
const { checksum, link: url, name: fileName } = java.binary.package;
const pathFolder = path_1.default.resolve(this.options.path, `runtime/jre-${majorVersion}`);
const filePath = path_1.default.join(pathFolder, fileName);
await this.verifyAndDownloadFile({ filePath, pathFolder, fileName, url, checksum });
let javaPath = path_1.default.join(pathFolder, 'bin', 'java');
if (platform === 'mac')
javaPath = path_1.default.join(pathFolder, 'Contents', 'Home', 'bin', 'java');
if (!fs_1.default.existsSync(javaPath)) {
await this.extract(filePath, pathFolder);
fs_1.default.unlinkSync(filePath);
if (filePath.endsWith('.tar.gz')) {
const tarFilePath = filePath.replace('.gz', '');
await this.extract(tarFilePath, pathFolder);
if (fs_1.default.existsSync(tarFilePath))
fs_1.default.unlinkSync(tarFilePath);
}
const extractedItems = fs_1.default.readdirSync(pathFolder);
if (extractedItems.length === 1) {
const extractedFolder = path_1.default.join(pathFolder, extractedItems[0]);
const stat = fs_1.default.statSync(extractedFolder);
if (stat.isDirectory()) {
const subItems = fs_1.default.readdirSync(extractedFolder);
for (const item of subItems) {
const srcPath = path_1.default.join(extractedFolder, item);
const destPath = path_1.default.join(pathFolder, item);
fs_1.default.renameSync(srcPath, destPath);
}
fs_1.default.rmdirSync(extractedFolder);
}
}
if (platform !== 'windows')
fs_1.default.chmodSync(javaPath, 0o755);
}
return { files: [], path: javaPath };
}
getPlatformArch() {
const platformMap = { win32: 'windows', darwin: 'mac', linux: 'linux' };
const archMap = { x64: 'x64', ia32: 'x32', arm64: 'aarch64', arm: 'arm' };
const platform = platformMap[os_1.default.platform()] || os_1.default.platform();
let arch = archMap[os_1.default.arch()] || os_1.default.arch();
if (os_1.default.platform() === 'darwin' && os_1.default.arch() === 'arm64' && this.options.intelEnabledMac) {
arch = 'x64';
}
return { platform, arch };
}
async verifyAndDownloadFile({ filePath, pathFolder, fileName, url, checksum }) {
if (fs_1.default.existsSync(filePath)) {
const existingChecksum = await (0, Index_js_1.getFileHash)(filePath, 'sha256');
if (existingChecksum !== checksum) {
fs_1.default.unlinkSync(filePath);
fs_1.default.rmSync(pathFolder, { recursive: true, force: true });
}
}
if (!fs_1.default.existsSync(filePath)) {
fs_1.default.mkdirSync(pathFolder, { recursive: true });
const download = new Downloader_js_1.default();
download.on('progress', (downloaded, size) => {
this.emit('progress', downloaded, size, fileName);
});
await download.downloadFile(url, pathFolder, fileName);
}
const downloadedChecksum = await (0, Index_js_1.getFileHash)(filePath, 'sha256');
if (downloadedChecksum !== checksum) {
throw new Error("Java checksum failed");
}
}
async extract(filePath, destPath) {
if (os_1.default.platform() !== 'win32')
fs_1.default.chmodSync(_7zip_bin_1.default.path7za, 0o755);
await new Promise((resolve, reject) => {
const extract = node_7z_1.default.extractFull(filePath, destPath, {
$bin: _7zip_bin_1.default.path7za,
recursive: true,
$progress: true,
});
extract.on('end', () => resolve());
extract.on('error', (err) => reject(err));
extract.on('progress', (progress) => {
if (progress.percent > 0)
this.emit('extract', progress.percent);
});
});
}
}
exports.default = JavaDownloader;