minecraft-java-core
Version: 
A library starting minecraft game NW.js and Electron.js
131 lines • 6.46 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const zlib_1 = __importDefault(require("zlib"));
class Unzipper {
    constructor(zipFilePath) {
        this.entries = [];
        const fileBuffer = fs_1.default.readFileSync(zipFilePath);
        const eocdSig = Buffer.from([0x50, 0x4B, 0x05, 0x06]);
        const maxCommentLength = 0xFFFF;
        const scanStart = Math.max(0, fileBuffer.length - (maxCommentLength + 22));
        let eocdPos = -1;
        for (let i = fileBuffer.length - 22; i >= scanStart; i--) {
            if (fileBuffer[i] === 0x50 &&
                fileBuffer[i + 1] === 0x4B &&
                fileBuffer[i + 2] === 0x05 &&
                fileBuffer[i + 3] === 0x06) {
                eocdPos = i;
                break;
            }
        }
        if (eocdPos !== -1) {
            const cdOffset = fileBuffer.readUInt32LE(eocdPos + 16);
            const cdSize = fileBuffer.readUInt32LE(eocdPos + 12);
            const cdEnd = cdOffset + cdSize;
            let cdCursor = cdOffset;
            while (cdCursor < cdEnd) {
                if (cdCursor + 46 > fileBuffer.length)
                    break; // sécurité
                if (fileBuffer.readUInt32LE(cdCursor) !== 0x02014b50)
                    break;
                const compressionMethod = fileBuffer.readUInt16LE(cdCursor + 10);
                const compressedSize = fileBuffer.readUInt32LE(cdCursor + 20);
                const uncompressedSize = fileBuffer.readUInt32LE(cdCursor + 24);
                const fileNameLength = fileBuffer.readUInt16LE(cdCursor + 28);
                const extraFieldLength = fileBuffer.readUInt16LE(cdCursor + 30);
                const fileCommentLength = fileBuffer.readUInt16LE(cdCursor + 32);
                const relativeOffset = fileBuffer.readUInt32LE(cdCursor + 42);
                const fileName = fileBuffer.toString('utf-8', cdCursor + 46, cdCursor + 46 + fileNameLength);
                const headerOffset = relativeOffset;
                // Sécurité sur l'offset du header
                if (headerOffset + 30 > fileBuffer.length) {
                    cdCursor += 46 + fileNameLength + extraFieldLength + fileCommentLength;
                    continue;
                }
                if (fileBuffer.readUInt32LE(headerOffset) !== 0x04034b50) {
                    cdCursor += 46 + fileNameLength + extraFieldLength + fileCommentLength;
                    continue;
                }
                const lfFileNameLength = fileBuffer.readUInt16LE(headerOffset + 26);
                const lfExtraFieldLength = fileBuffer.readUInt16LE(headerOffset + 28);
                const dataStart = headerOffset + 30 + lfFileNameLength + lfExtraFieldLength;
                const dataEnd = dataStart + compressedSize;
                // Sécurité: ne pas dépasser la taille du buffer
                if (dataEnd > fileBuffer.length) {
                    cdCursor += 46 + fileNameLength + extraFieldLength + fileCommentLength;
                    continue;
                }
                const compressedData = fileBuffer.slice(dataStart, dataEnd);
                this.entries.push({
                    entryName: fileName,
                    isDirectory: fileName.endsWith('/'),
                    getData: () => {
                        if (compressionMethod === 8) {
                            return zlib_1.default.inflateRawSync(compressedData);
                        }
                        else if (compressionMethod === 0) {
                            return compressedData;
                        }
                        else {
                            throw new Error(`Unsupported compression method: ${compressionMethod}`);
                        }
                    }
                });
                cdCursor += 46 + fileNameLength + extraFieldLength + fileCommentLength;
            }
        }
        else {
            let currentOffset = 0;
            while (currentOffset < fileBuffer.length - 4) {
                const signaturePos = fileBuffer.indexOf(Buffer.from([0x50, 0x4B, 0x03, 0x04]), currentOffset);
                if (signaturePos === -1)
                    break;
                const headerOffset = signaturePos;
                if (headerOffset + 30 > fileBuffer.length)
                    break;
                const compressionMethod = fileBuffer.readUInt16LE(headerOffset + 8);
                const compressedSize = fileBuffer.readUInt32LE(headerOffset + 18);
                const uncompressedSize = fileBuffer.readUInt32LE(headerOffset + 22);
                const fileNameLength = fileBuffer.readUInt16LE(headerOffset + 26);
                const extraFieldLength = fileBuffer.readUInt16LE(headerOffset + 28);
                const fileNameStart = headerOffset + 30;
                const fileNameEnd = fileNameStart + fileNameLength;
                if (fileNameEnd > fileBuffer.length)
                    break;
                const fileName = fileBuffer.toString('utf-8', fileNameStart, fileNameEnd);
                const dataStart = fileNameEnd + extraFieldLength;
                const dataEnd = dataStart + compressedSize;
                if (dataEnd > fileBuffer.length) {
                    currentOffset = dataEnd;
                    continue;
                }
                const compressedData = fileBuffer.slice(dataStart, dataEnd);
                this.entries.push({
                    entryName: fileName,
                    isDirectory: fileName.endsWith('/'),
                    getData: () => {
                        if (compressionMethod === 8) {
                            return zlib_1.default.inflateRawSync(compressedData);
                        }
                        else if (compressionMethod === 0) {
                            return compressedData;
                        }
                        else {
                            throw new Error(`Unsupported compression method: ${compressionMethod}`);
                        }
                    }
                });
                currentOffset = dataEnd;
            }
        }
    }
    getEntries() {
        return this.entries;
    }
}
exports.default = Unzipper;
//# sourceMappingURL=unzipper.js.map