minecraft-java-core
Version:
A library starting minecraft game NW.js and Electron.js
290 lines • 12.1 kB
JavaScript
/**
* This code is distributed under the CC-BY-NC 4.0 license:
* https://creativecommons.org/licenses/by-nc/4.0/
*
* Original author: Luuxis
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mirrors = void 0;
exports.getPathLibraries = getPathLibraries;
exports.getFileHash = getFileHash;
exports.isold = isold;
exports.loader = loader;
exports.getFileFromArchive = getFileFromArchive;
exports.createZIP = createZIP;
exports.skipLibrary = skipLibrary;
exports.fromAnyReadable = fromAnyReadable;
const crypto_1 = __importDefault(require("crypto"));
const fs_1 = __importDefault(require("fs"));
const adm_zip_1 = __importDefault(require("adm-zip"));
const node_stream_1 = require("node:stream");
/**
* Parses a Gradle/Maven identifier string (like "net.minecraftforge:forge:1.19-41.0.63")
* into a local file path (group/artifact/version) and final filename (artifact-version.jar).
* Optionally allows specifying a native string suffix or forcing an extension.
*
* @param main A Gradle-style coordinate (group:artifact:version[:classifier])
* @param nativeString A suffix for native libraries (e.g., "-natives-linux")
* @param forceExt A forced file extension (default is ".jar")
* @returns An object with `path` and `name`, where `path` is the directory path and `name` is the filename
*/
function getPathLibraries(main, nativeString, forceExt) {
// Example "net.minecraftforge:forge:1.19-41.0.63"
const libSplit = main.split(':');
// If there's a fourth element, it's typically a classifier appended to version
const fileName = libSplit[3] ? `${libSplit[2]}-${libSplit[3]}` : libSplit[2];
// Replace '@' in versions if present (e.g., "1.0@beta" => "1.0.beta")
let finalFileName = fileName.includes('@')
? fileName.replace('@', '.')
: `${fileName}${nativeString || ''}${forceExt || '.jar'}`;
// Construct the path: "net.minecraftforge" => "net/minecraftforge"
// artifact => "forge"
// version => "1.19-41.0.63"
const pathLib = `${libSplit[0].replace(/\./g, '/')}/${libSplit[1]}/${libSplit[2].split('@')[0]}`;
return {
path: pathLib,
name: `${libSplit[1]}-${finalFileName}`,
version: libSplit[2],
};
}
/**
* Computes a hash (default SHA-1) of the given file by streaming its contents.
*
* @param filePath Full path to the file on disk
* @param algorithm Hashing algorithm (default: "sha1")
* @returns A Promise resolving to the hex string of the file's hash
*/
async function getFileHash(filePath, algorithm = 'sha1') {
const shasum = crypto_1.default.createHash(algorithm);
const fileStream = fs_1.default.createReadStream(filePath);
return new Promise((resolve) => {
fileStream.on('data', (data) => {
shasum.update(data);
});
fileStream.on('end', () => {
resolve(shasum.digest('hex'));
});
});
}
/**
* Determines if a given Minecraft version JSON is considered "old"
* by checking its assets field (e.g., "legacy" or "pre-1.6").
*
* @param json The Minecraft version JSON
* @returns true if it's an older version, false otherwise
*/
function isold(json) {
return json.assets === 'legacy' || json.assets === 'pre-1.6';
}
/**
* Returns metadata necessary to download specific loaders (Forge, Fabric, etc.)
* based on a loader type string (e.g., "forge", "fabric").
* If the loader type is unrecognized, returns undefined.
*
* @param type A string representing the loader type
*/
function loader(type) {
if (type === 'forge') {
return {
metaData: 'https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json',
meta: 'https://files.minecraftforge.net/net/minecraftforge/forge/${build}/meta.json',
promotions: 'https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json',
install: 'https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-installer',
universal: 'https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-universal',
client: 'https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-client'
};
}
else if (type === 'neoforge') {
return {
legacyMetaData: 'https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/forge',
metaData: 'https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge',
legacyInstall: 'https://maven.neoforged.net/net/neoforged/forge/${version}/forge-${version}-installer.jar',
install: 'https://maven.neoforged.net/net/neoforged/neoforge/${version}/neoforge-${version}-installer.jar'
};
}
else if (type === 'fabric') {
return {
metaData: 'https://meta.fabricmc.net/v2/versions',
json: 'https://meta.fabricmc.net/v2/versions/loader/${version}/${build}/profile/json'
};
}
else if (type === 'legacyfabric') {
return {
metaData: 'https://meta.legacyfabric.net/v2/versions',
json: 'https://meta.legacyfabric.net/v2/versions/loader/${version}/${build}/profile/json'
};
}
else if (type === 'quilt') {
return {
metaData: 'https://meta.quiltmc.org/v3/versions',
json: 'https://meta.quiltmc.org/v3/versions/loader/${version}/${build}/profile/json'
};
}
// If none match, return undefined
}
/**
* A list of potential Maven mirrors for downloading libraries.
*/
const mirrors = [
'https://maven.minecraftforge.net',
'https://maven.neoforged.net/releases',
'https://maven.creeperhost.net',
'https://libraries.minecraft.net',
'https://repo1.maven.org/maven2'
];
exports.mirrors = mirrors;
/**
* Reads a .jar or .zip file, returning specific entries or listing file entries in the archive.
* Uses adm-zip under the hood.
*
* @param jar Full path to the jar/zip file
* @param file The file entry to extract data from (e.g., "install_profile.json"). If null, returns all entries or partial lists.
* @param prefix A path prefix filter (e.g., "maven/org/lwjgl/") if you want a list of matching files instead of direct extraction
* @returns A buffer or an array of { name, data }, or a list of filenames if prefix is given
*/
async function getFileFromArchive(jar, file = null, prefix = null) {
const result = [];
const zip = new adm_zip_1.default(jar);
const entries = zip.getEntries();
return new Promise((resolve) => {
for (const entry of entries) {
if (!entry.isDirectory && !prefix) {
// If no prefix is given, either return a specific file if 'file' is set,
// or accumulate all entries if 'file' is null
if (entry.entryName === file) {
return resolve(entry.getData());
}
else if (!file) {
result.push({ name: entry.entryName, data: entry.getData() });
}
}
// If a prefix is given, collect all entry names under that prefix
if (!entry.isDirectory && prefix && entry.entryName.includes(prefix)) {
result.push(entry.entryName);
}
}
if (file && !prefix) {
// If a specific file was requested but not found, return undefined or empty
return resolve(undefined);
}
// Otherwise, resolve the array of results
resolve(result);
});
}
/**
* Creates a new ZIP buffer by combining multiple file entries (name, data),
* optionally ignoring entries containing a certain string (e.g. "META-INF").
*
* @param files An array of { name, data } objects to include in the new zip
* @param ignored A substring to skip any matching files
* @returns A buffer containing the newly created ZIP
*/
async function createZIP(files, ignored = null) {
const zip = new adm_zip_1.default();
return new Promise((resolve) => {
for (const entry of files) {
if (ignored && entry.name.includes(ignored)) {
continue;
}
zip.addFile(entry.name, entry.data);
}
resolve(zip.toBuffer());
});
}
/**
* Determines if a library should be skipped based on its 'rules' property.
* For example, it might skip libraries if action='disallow' for the current OS,
* or if there are specific conditions not met.
*
* @param lib A library object (with optional 'rules' array)
* @returns true if the library should be skipped, false otherwise
*/
function skipLibrary(lib) {
// Map Node.js platform strings to Mojang's naming
const LibMap = {
win32: 'windows',
darwin: 'osx',
linux: 'linux'
};
// If no rules, it's not skipped
if (!lib.rules) {
return false;
}
let shouldSkip = true;
for (const rule of lib.rules) {
// If features exist, your logic can handle them here
if (rule.features) {
// Implementation is up to your usage
continue;
}
// "allow" means it can be used if OS matches (or no OS specified)
// "disallow" means skip if OS matches (or no OS specified)
if (rule.action === 'allow' &&
((rule.os && rule.os.name === LibMap[process.platform]) || !rule.os)) {
shouldSkip = false;
}
else if (rule.action === 'disallow' &&
((rule.os && rule.os.name === LibMap[process.platform]) || !rule.os)) {
shouldSkip = true;
}
}
return shouldSkip;
}
function fromAnyReadable(webStream) {
let NodeReadableStreamCtor;
if (!NodeReadableStreamCtor && typeof globalThis?.navigator === 'undefined') {
Promise.resolve().then(() => __importStar(require('node:stream/web'))).then((mod) => { NodeReadableStreamCtor = mod.ReadableStream; });
}
if (NodeReadableStreamCtor && webStream instanceof NodeReadableStreamCtor && typeof node_stream_1.Readable.fromWeb === 'function') {
return node_stream_1.Readable.fromWeb(webStream);
}
const nodeStream = new node_stream_1.Readable({ read() { } });
const reader = webStream.getReader();
(function pump() {
reader.read().then(({ done, value }) => {
if (done)
return nodeStream.push(null);
nodeStream.push(Buffer.from(value));
pump();
}).catch(err => nodeStream.destroy(err));
})();
return nodeStream;
}
//# sourceMappingURL=Index.js.map
;