| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- const fs = require('fs-extra')
- const path = require('path')
- const { shell } = require('electron')
- // Group #1: File Name (without .disabled, if any)
- // Group #2: File Extension (jar, zip, or litemod)
- // Group #3: If it is disabled (if string 'disabled' is present)
- const MOD_REGEX = /^(.+(jar|zip|litemod))(?:\.(disabled))?$/
- const DISABLED_EXT = '.disabled'
- const SHADER_REGEX = /^(.+)\.zip$/
- const SHADER_OPTION = /shaderPack=(.+)/
- /**
- * Validate that the given directory exists. If not, it is
- * created.
- *
- * @param {string} modsDir The path to the mods directory.
- */
- exports.validateDir = function(dir) {
- fs.ensureDirSync(dir)
- }
- /**
- * Scan for drop-in mods in both the mods folder and version
- * safe mods folder.
- *
- * @param {string} modsDir The path to the mods directory.
- * @param {string} version The minecraft version of the server configuration.
- *
- * @returns {{fullName: string, name: string, ext: string, disabled: boolean}[]}
- * An array of objects storing metadata about each discovered mod.
- */
- exports.scanForDropinMods = function(modsDir, version) {
- const modsDiscovered = []
- if(fs.existsSync(modsDir)){
- let modCandidates = fs.readdirSync(modsDir)
- let verCandidates = []
- const versionDir = path.join(modsDir, version)
- if(fs.existsSync(versionDir)){
- verCandidates = fs.readdirSync(versionDir)
- }
- for(let file of modCandidates){
- const match = MOD_REGEX.exec(file)
- if(match != null){
- modsDiscovered.push({
- fullName: match[0],
- name: match[1],
- ext: match[2],
- disabled: match[3] != null
- })
- }
- }
- for(let file of verCandidates){
- const match = MOD_REGEX.exec(file)
- if(match != null){
- modsDiscovered.push({
- fullName: path.join(version, match[0]),
- name: match[1],
- ext: match[2],
- disabled: match[3] != null
- })
- }
- }
- }
- return modsDiscovered
- }
- /**
- * Add dropin mods.
- *
- * @param {FileList} files The files to add.
- * @param {string} modsDir The path to the mods directory.
- */
- exports.addDropinMods = function(files, modsdir) {
- exports.validateDir(modsdir)
- for(let f of files) {
- if(MOD_REGEX.exec(f.name) != null) {
- fs.moveSync(f.path, path.join(modsdir, f.name))
- }
- }
- }
- /**
- * Delete a drop-in mod from the file system.
- *
- * @param {string} modsDir The path to the mods directory.
- * @param {string} fullName The fullName of the discovered mod to delete.
- *
- * @returns {boolean} True if the mod was deleted, otherwise false.
- */
- exports.deleteDropinMod = function(modsDir, fullName){
- const res = shell.moveItemToTrash(path.join(modsDir, fullName))
- if(!res){
- shell.beep()
- }
- return res
- }
- /**
- * Toggle a discovered mod on or off. This is achieved by either
- * adding or disabling the .disabled extension to the local file.
- *
- * @param {string} modsDir The path to the mods directory.
- * @param {string} fullName The fullName of the discovered mod to toggle.
- * @param {boolean} enable Whether to toggle on or off the mod.
- *
- * @returns {Promise.<void>} A promise which resolves when the mod has
- * been toggled. If an IO error occurs the promise will be rejected.
- */
- exports.toggleDropinMod = function(modsDir, fullName, enable){
- return new Promise((resolve, reject) => {
- const oldPath = path.join(modsDir, fullName)
- const newPath = path.join(modsDir, enable ? fullName.substring(0, fullName.indexOf(DISABLED_EXT)) : fullName + DISABLED_EXT)
- fs.rename(oldPath, newPath, (err) => {
- if(err){
- reject(err)
- } else {
- resolve()
- }
- })
- })
- }
- /**
- * Check if a drop-in mod is enabled.
- *
- * @param {string} fullName The fullName of the discovered mod to toggle.
- * @returns {boolean} True if the mod is enabled, otherwise false.
- */
- exports.isDropinModEnabled = function(fullName){
- return !fullName.endsWith(DISABLED_EXT)
- }
- /**
- * Scan for shaderpacks inside the shaderpacks folder.
- *
- * @param {string} instanceDir The path to the server instance directory.
- *
- * @returns {{fullName: string, name: string}[]}
- * An array of objects storing metadata about each discovered shaderpack.
- */
- exports.scanForShaderpacks = function(instanceDir){
- const shaderDir = path.join(instanceDir, 'shaderpacks')
- const packsDiscovered = [{
- fullName: 'OFF',
- name: 'No Shaderpack'
- }]
- if(fs.existsSync(shaderDir)){
- let modCandidates = fs.readdirSync(shaderDir)
- for(let file of modCandidates){
- const match = SHADER_REGEX.exec(file)
- if(match != null){
- packsDiscovered.push({
- fullName: match[0],
- name: match[1]
- })
- }
- }
- }
- return packsDiscovered
- }
- /**
- * Read the optionsshaders.txt file to locate the current
- * enabled pack. If the file does not exist, OFF is returned.
- *
- * @param {string} instanceDir The path to the server instance directory.
- *
- * @returns {string} The file name of the enabled shaderpack.
- */
- exports.getEnabledShaderpack = function(instanceDir){
- exports.validateDir(instanceDir)
- const optionsShaders = path.join(instanceDir, 'optionsshaders.txt')
- if(fs.existsSync(optionsShaders)){
- const buf = fs.readFileSync(optionsShaders, {encoding: 'utf-8'})
- const match = SHADER_OPTION.exec(buf)
- if(match != null){
- return match[1]
- } else {
- console.warn('WARNING: Shaderpack regex failed.')
- }
- }
- return 'OFF'
- }
- /**
- * Set the enabled shaderpack.
- *
- * @param {string} instanceDir The path to the server instance directory.
- * @param {string} pack the file name of the shaderpack.
- */
- exports.setEnabledShaderpack = function(instanceDir, pack){
- exports.validateDir(instanceDir)
- const optionsShaders = path.join(instanceDir, 'optionsshaders.txt')
- let buf
- if(fs.existsSync(optionsShaders)){
- buf = fs.readFileSync(optionsShaders, {encoding: 'utf-8'})
- buf = buf.replace(SHADER_OPTION, `shaderPack=${pack}`)
- } else {
- buf = `shaderPack=${pack}`
- }
- fs.writeFileSync(optionsShaders, buf, {encoding: 'utf-8'})
- }
|