UNPKG

resourcepacker

Version:

Package Minecraft resource packs easily and cleanly from a messy working directory

141 lines (140 loc) 6.2 kB
"use strict"; const fs = require('fs'); const copyfiles = require('copyfiles'); const movefiles = require('glob-move'); const archiver = require('archiver'); const packFormat = require('pack-format'); const log = (msg) => console.log('<resourcepacker> ' + msg); const CONFIG = { configver: 2, name: process.cwd().replace(/^.+[/\\]([^/\\]+)$/, '$1'), packver: 'v1', mcver: '1.16.5', mcsnap: null, description: 'Default resource pack configuration, which creates an automatic pack.mcmeta file when packing.', languages: null, files: [ "pack.png", "pack.mcmeta", "assets/**/*.png", "assets/**/*.mcmeta", "assets/**/*.json", "assets/**/lang/**/*.lang", "assets/**/texts/**/*.txt", "assets/**/sounds/**/*.ogg", "assets/**/shaders/**/*.fsh", "assets/**/shaders/**/*.bin", ], }; function init({ force } = { force: false }) { if (fs.existsSync('.rpkr.json') && !force) { log('Warning: This folder is already initialised with an .rpkr.json configuration file.'); log('Type `rpkr init force` to overwrite it with default settings.'); } else fs.writeFile('.rpkr.json', JSON.stringify(CONFIG, null, '\t'), (err) => { if (err) throw 'FSWriteError: Cannot write to .rpkr.json configuration file.'; else { if (force) log('Warning: Overwriting existing .rpkr.json configuration file.'); log(`Successfully created .rpkr.json configuration file with default settings.`); } }); } function pack(input = '.', output, { zipped } = { zipped: true }) { fs.readFile('.rpkr.json', 'utf8', (err, contents) => { if (err) init(); let config = err ? CONFIG : JSON.parse(contents); let { name, packver, mcver, mcsnap, description, languages, files = CONFIG.files } = config; // Create version label let versionLabel = mcver; if (mcsnap) { if (mcsnap.match(/\d\dw\d\d\w/)) versionLabel = mcsnap; // snapshot if (mcsnap.match(/\w+\d+/)) versionLabel = mcver + '-' + mcsnap; // short name of pre and rc else versionLabel = mcver + ' ' + mcsnap; // full name of pre and rc } output = output || `${name} ${packver} (${versionLabel})`; // Create automatic mcmeta file const mcmetaTemp = 'temp-pack.mcmeta'; if (description) { const mcmetaContent = { pack: { pack_format: 0, description: '' } }; mcmetaContent.pack.pack_format = packFormat(versionLabel, 'resource') || packFormat(mcver, 'resource') || 0; /// Compile description for (const item in config) { let escapedItem = item.replace(/[-\[\]{}().*+?^$\\\/|]/g, "\\$&"); description = description .replace(/&([0-9a-fk-or])/g, '§$1') // formatting codes .replace(RegExp(`<${escapedItem}>`, 'g'), config[item]); // custom parameters } mcmetaContent.pack.description = description; /// Parse languages if (languages) { mcmetaContent.language = {}; for (const lang in languages) { const matcher = /^\s*(.*?)\s*\((.*?)\)\s*/i; let [, name, region] = languages[lang].match(matcher); mcmetaContent.language[lang] = { name, region }; } } /// Write mcmeta to disc if (!zipped || output.includes('/')) fs.mkdirSync(output, { recursive: true }); fs.writeFileSync((zipped ? mcmetaTemp : output + '/pack.mcmeta'), JSON.stringify(mcmetaContent, null, '\t'), (err) => { if (err) log('FSWriteError: Could not create automatic pack.mcmeta file'); else log('Created automatic pack.mcmeta file'); }); } // Localise paths for (let i in files) { files[i] = input.replace(/\/$/, '') + '/' + files[i]; } // Write output to disk const success = function (s) { const outFile = output.replace(/\/$|\.zip$/, '') + (zipped ? '.zip' : '/'); log(`${s ? 'S' : 'Uns'}uccessfully packaged version ${packver} of '${name}' for Minecraft ${mcver} to '${outFile}'`); }; log(`Packaging version ${packver} of '${name}'...`); if (zipped) { const zipFilename = output + '.zip'; if (fs.existsSync(zipFilename)) log(`Warning: Overwriting existing file ${zipFilename}.`); const outFile = fs.createWriteStream(zipFilename); const zipFile = archiver('zip', { zlib: { level: 9 } }); outFile.on('close', function () { fs.unlink(mcmetaTemp, (err) => err ? log(`Error: ${err}`) : success(true)); }); zipFile.pipe(outFile); // Start writing to zip file zipFile.file(mcmetaTemp, { name: 'pack.mcmeta' }); for (let glob of [...files]) zipFile.glob(glob.replace(/^.\//, '')); zipFile.finalize(); // End writing to zip file } else { copyfiles([...files, output], {}, (err) => { if (err) { log(`Error: ${err}`); success(false); } else if (input !== '.') { const oldOutput = output + '/' + input; movefiles(oldOutput + '/*', output) .then(function () { fs.rmdirSync(oldOutput); success(true); }) .catch((err) => log(`Error: ${err}`)); } else success(true); }); } }); } module.exports = { init, pack };