diff --git a/commands/debug.js b/commands/debug.js new file mode 100644 index 00000000..6169b28d --- /dev/null +++ b/commands/debug.js @@ -0,0 +1,34 @@ +const vscode = require('vscode'); +const fs = require('fs'); +const os = require('os'); + +const path = require('path'); + +const LSLIB_DLL = 'LSLib.dll'; +const TOOL_SUBDIR = 'Tools\\'; + +const { getConfig, loadConfigFile, setModName, setConfig } = require('../support_files/config'); +const { lslibPath, rootModPath, gameInstallLocation } = getConfig(); +const compatRootModPath = path.join(rootModPath + "\\"); +const lslibToolsPath = path.join(lslibPath, TOOL_SUBDIR); + +const { } = require('../support_files/helper_functions') + +const { CREATE_LOGGER, raiseError, raiseInfo } = require('../support_files/log_utils'); +var bg3mh_logger = CREATE_LOGGER(); + +const { FIND_FILES, getFormats, dirSeparator, LOAD_LSLIB } = require('../support_files/lslib_utils.js'); +const { pak } = getFormats(); +const { processPak } = require('../support_files/process_pak.js'); + +const { isMainThread, parentPort, Worker } = require('node:worker_threads'); + +const { jobs } = require('../support_files/conversion_junction'); + + +const debug = vscode.commands.registerCommand('bg3-mod-helper.debugCommand', async function () { + raiseInfo("hi dipshit! 💩"); +}); + + +module.exports = { debug } diff --git a/commands/packMod.js b/commands/packMod.js index 821a2a74..eb0b13c8 100644 --- a/commands/packMod.js +++ b/commands/packMod.js @@ -87,7 +87,7 @@ const packModCommand = vscode.commands.registerCommand('bg3-mod-helper.packMod', } // send the directory to the convert() function, and let it know it's a pak - await convert(rootModPath, pak, modName, getConfig().zipOnPack); + await convert(rootModPath, pak, modName); if (autoLaunchOnPack) { vscode.commands.executeCommand('bg3-mod-helper.launchGame'); diff --git a/extension.js b/extension.js index 632178b4..85e0e891 100644 --- a/extension.js +++ b/extension.js @@ -233,7 +233,7 @@ function aSimpleDataProvider() { return Promise.resolve([ { label: 'Reload Window', command: 'workbench.action.reloadWindow' }, { label: 'Extension Settings', command: 'workbench.action.openSettings', arguments: 'bg3ModHelper' }, - { label: 'Upate Settings File', command: 'bg3-mod-helper.saveConfigToFile' } + { label: 'Update Settings File', command: 'bg3-mod-helper.saveConfigToFile' } ]); } else if (element.id === 'conversion') { return Promise.resolve([ diff --git a/support_files/conversion_junction.js b/support_files/conversion_junction.js index 8793ae0e..6fce35d9 100644 --- a/support_files/conversion_junction.js +++ b/support_files/conversion_junction.js @@ -144,7 +144,7 @@ function getDynamicPath(filePath) { // at the moment this has all the functionality i planned for it, ie lsf, loca, and paks. for any other conversions we can make separate functions -async function convert(convertPath, targetExt = path.extname(getDynamicPath(convertPath)), modName = getConfig.getModName, zipCheck = getConfig.zipOnPack) { +async function convert(convertPath, targetExt = path.extname(getDynamicPath(convertPath)), modName = getConfig.getModName) { let rootModPath = getConfig.rootModPath; // checks if the convertPath was undefined and halts the function before it goes any further @@ -163,34 +163,31 @@ async function convert(convertPath, targetExt = path.extname(getDynamicPath(conv await convert(rootModPath, lsx) .then(() => bg3mh_logger.info(`lsx conversion done`, false)); - processPak(rootModPath, modName, '', zipCheck); + processPak(rootModPath); } // has a check for main thread here because when a worker thread calls this function, it's batch unpacking and has a specific place it needs the files inside to go, but can't rely on vscode module functions to get them else if (fs.statSync(convertPath).isFile()) { if (isMainThread) { - processPak(convertPath, modName); + processPak(convertPath); } else { - processPak(convertPath, modName, workerData.jobDestPath); + processPak(convertPath, workerData.jobDestPath); } } } // this function works best on single files, so we need to process that array and re-run this function with each of its elements else if (Array.isArray(convertPath)) { - // console.log('array1') for (let i = 0; i < convertPath.length; i++) { convert(convertPath[i], path.extname(convertPath[i])); } } // if this function is passsed a directory, parse it into an array of files of the specified type in targetExt, then send that back through else if (fs.statSync(convertPath).isDirectory()) { - // console.log('plz1') const filesToConvert = await FIND_FILES(targetExt); convert(filesToConvert); } // finally, if this function is handed a file, convert that bitch :catyes: else if (fs.statSync(convertPath).isFile()) { - // console.log('plz2') if (isLoca(targetExt)) { try { processLoca(convertPath, targetExt); diff --git a/support_files/loca_convert.js b/support_files/loca_convert.js index 8b26a51e..d01a1b0e 100644 --- a/support_files/loca_convert.js +++ b/support_files/loca_convert.js @@ -1,7 +1,9 @@ const path = require('path'); +const { isMainThread } = require('worker_threads'); + const { getFormats, baseNamePath, LOAD_LSLIB } = require('./lslib_utils'); -const { CREATE_LOGGER } = require('./log_utils'); +const { CREATE_LOGGER, raiseInfo } = require('./log_utils'); const bg3mh_logger = CREATE_LOGGER(); const { xml, loca } = getFormats(); @@ -54,7 +56,15 @@ async function processLoca(file, targetExt) { temp_loca = LocaUtils.Load(file); LocaUtils.Save(temp_loca, file_output); - bg3mh_logger.info(`Exported ${to_loca} file: ${file_output}`) + + if (isMainThread) { + const vscode = require('vscode'); + vscode.window.showInformationMessage(`Exported ${to_loca} file: ${file_output}`); + } else { + bg3mh_logger.info(`Exported ${to_loca} file: ${file_output}`); + } + + } catch (Error) { bg3mh_logger.error(Error); diff --git a/support_files/lsf_convert.js b/support_files/lsf_convert.js index c1442d56..86d0f36b 100644 --- a/support_files/lsf_convert.js +++ b/support_files/lsf_convert.js @@ -2,12 +2,12 @@ const path = require('path'); const fs = require('fs'); const { getFormats, baseNamePath, LOAD_LSLIB } = require('./lslib_utils'); - +const { isMainThread } = require('worker_threads'); const { lsb, lsf, lsj, lsfx, lsbc, lsbs, lsx } = getFormats(); const lsfFormats = [lsb, lsf, lsj, lsfx, lsbc, lsbs, lsx]; -const { CREATE_LOGGER } = require('./log_utils'); +const { CREATE_LOGGER, raiseInfo, raiseError } = require('./log_utils'); var bg3mh_logger = CREATE_LOGGER(); var to_lsf; @@ -110,11 +110,20 @@ async function processLsf(file, targetExt) { try { temp_lsf = ResourceUtils.LoadResource(file, load_params); ResourceUtils.SaveResource(temp_lsf, file_output, conversion_params); - - bg3mh_logger.info(`Exported ${to_lsf} file: ${file_output}`) + + if (isMainThread) { + const vscode = require('vscode'); + vscode.window.showInformationMessage(`Exported ${to_lsf} file: ${file_output}`); + } else { + bg3mh_logger.info(`Exported ${to_lsf} file: ${file_output}`); + } } - catch (Error) { - bg3mh_logger.error(Error); + catch (Error) { + if (isMainThread) { + vscode.window.showErrorMessage(Error); + } else { + bg3mh_logger.info(Error); + } } } diff --git a/support_files/lslib_utils.js b/support_files/lslib_utils.js index 9d38a590..dc2a608b 100644 --- a/support_files/lslib_utils.js +++ b/support_files/lslib_utils.js @@ -39,7 +39,6 @@ const hotfixPatchRegex = /Patch[\d]+_Hotfix[\d]+/; // tools to test where the process is const { isMainThread, workerData } = require('node:worker_threads'); -var DLLS = []; var DLL_PATHS, LSLIB, lslibPath, compatRootModPath, lslibToolsPath, vscode, findFiles, parse; var getConfig; @@ -174,20 +173,25 @@ function FIND_FILES_SYNC(filesPath, targetExt = getFormats().lsf, isRecursive = // beautiful. still needs dll handling in lslib_utils though, and some refactoring async function FIND_FILES(targetExt = getFormats().lsf, filesPath = '**/*') { let filesList; + // these don't do anything... yet + let globToSearch; let nonRecursiveGlob = '*'; let recursiveGlob = '**/*' + + // pak logic may not be needed here, will check at some point + if (targetExt === getFormats().dll || targetExt === getFormats().pak) { + // finding dlls needs to not be recursive so we don't accidentally load things twice + if (targetExt === getFormats().dll) { + globToSearch = nonRecursiveGlob; + } + // paks can be recursive, but we need to account for them not being in the workspace, like dlls + else if (targetExt === getFormats().pak) { + globToSearch = recursiveGlob; + } - // finding dlls needs to not be recursive so we don't accidentally load things twice - if (targetExt === getFormats().dll) { - let dllDir = new vscode.RelativePattern(filesPath, '*' + targetExt); - filesList = (await findFiles(dllDir)).map(file => dirSeparator(file.path)); - } - // paks can be recursive, but we need to account for them not being in the workspace, like dlls - else if (targetExt === getFormats().pak) { - let dllDir = new vscode.RelativePattern(filesPath, '**/*' + targetExt); - filesList = (await findFiles(dllDir)).map(file => dirSeparator(file.path)); - } - else { + let fileDir = new vscode.RelativePattern(filesPath, globToSearch + targetExt); + filesList = (await findFiles(fileDir)).map(file => dirSeparator(file.path)); + } else { filesList = (await findFiles(filesPath + targetExt)).map(file => dirSeparator(file.path)); } @@ -228,9 +232,12 @@ function FILTER_PATHS(filesPath) { return filesPath; } // if paks are being grabbed, it's for unpacking, so exclude the ones that throw errors - else if (temp_ext === getFormats().pak && !(virtualTextureRegex.test(temp_name) || hotfixPatchRegex.test(temp_name))) { + else if ( + temp_ext === getFormats().pak && + !(virtualTextureRegex.test(temp_name) || + hotfixPatchRegex.test(temp_name)) + ) { return filesPath; - } // check if an item is excluded by user, in a path that should be converted, or can be ignored else if ( @@ -248,23 +255,23 @@ function FILTER_PATHS(filesPath) { // here in case people (i'm people) have their working directory and their AppData on different hard drives. -function moveFileAcrossDevices(sourcePath, destPath, bg3mh_logger) { +function moveFileAcrossDevices(sourcePath, destPath, logger = bg3mh_logger) { let infoMsg = `${path.basename(sourcePath)} moved to ${destPath}.`; fs.readFile(sourcePath, (readErr, data) => { if (readErr) { - bg3mh_logger.error(readErr); + logger.error(readErr); return; } fs.writeFile(destPath, data, (writeErr) => { if (writeErr) { - bg3mh_logger.error(writeErr); + logger.error(writeErr); return; } fs.unlink(sourcePath, unlinkErr => { // added the check because it was raising an error every time the func was called if (unlinkErr) { - bg3mh_logger.error(unlinkErr); + logger.error(unlinkErr); return; } }); @@ -272,13 +279,14 @@ function moveFileAcrossDevices(sourcePath, destPath, bg3mh_logger) { }); if (isMainThread) { - bg3mh_logger.info(infoMsg, false); + logger.info(infoMsg, false); vscode.window.showInformationMessage(infoMsg); } else { - bg3mh_logger.info(infoMsg, false); + logger.info(infoMsg, false); } } +// probably not needed but i'll investigate later // i don't like putting this here but i need a worker_thread friendly version function getModNameSync() { let rootModPath; diff --git a/support_files/process_pak.js b/support_files/process_pak.js index 8078585f..8e307b43 100644 --- a/support_files/process_pak.js +++ b/support_files/process_pak.js @@ -1,21 +1,23 @@ const path = require('path'); const fs = require('fs'); -const { createGzip } = require('zlib'); -const { pipeline } = require('stream'); -const { promisify } = require('util'); -const streamPipeline = promisify(pipeline); const { getFormats, moveFileAcrossDevices, compatRootModPath, LOAD_LSLIB } = require('./lslib_utils'); const { pak } = getFormats(); +const { zipUpPak } = require('./zip_functions'); +const { xmlUpdate } = require('./xml_functions'); + const { isMainThread, workerData } = require('node:worker_threads'); const { CREATE_LOGGER } = require('./log_utils'); var bg3mh_logger = CREATE_LOGGER(); const temp_folder = "\\temp_folder"; -// const temp_path = path.join(rootParentPath, temp_folder); -var LSLIB, getConfig, vscode; + +let LSLIB, + getConfig, + vscode; + async function lslib_load() { if (LSLIB === undefined) { @@ -40,35 +42,25 @@ function prepareTempDir(movedPak = false) { } const rootParentPath = path.dirname(rootModPath); - const temp_path = path.join(rootParentPath, temp_folder); - // console.log('test11') + if (!(fs.existsSync(temp_path))) { console.log("making temp_path"); fs.mkdirSync(temp_path, { recursive: true}); return; } - // this is being finicky :starege: - /* - else if (movedPak) { - console.log("deleting temp_path %s", modTempDestPath); - console.log(fs.existsSync(modTempDestPath)) - fs.unlinkSync(modTempDestPath); - fs.rmSync(temp_path, { recursive: true, force: true }); - - return; - } - */ } // btw, sometimes this will log things before others because it's async. -async function processPak(modPath, modName, unpackLocation = path.join(path.dirname(modPath), path.basename(modPath, pak)), zipCheck = false) { +async function processPak(modPath, unpackLocation = path.join(path.dirname(modPath), path.basename(modPath, pak))) { await lslib_load(); var build = new LSLIB.PackageBuildData(); var Packager = new LSLIB.Packager(); - let rootModPath, modDestPath; + let rootModPath, + modDestPath, + zipOnPack; if (isMainThread) { vscode = require('vscode'); @@ -80,68 +72,40 @@ async function processPak(modPath, modName, unpackLocation = path.join(path.dirn rootModPath = getConfig.rootModPath; modDestPath = getConfig.modDestPath; - - console.log(rootModPath); - console.log(modDestPath); - - build.ExcludeHidden = getConfig.excludeHidden; - console.log(build.ExcludeHidden); + zipOnPack = getConfig.zipOnPack; const lastFolderName = path.basename(rootModPath); const rootParentPath = path.dirname(rootModPath); const temp_path = path.join(rootParentPath, temp_folder); const modFinalDestPath = path.join(modDestPath, lastFolderName + pak); const modTempDestPath = path.join(temp_path, lastFolderName + pak); - const metaPath = path.join(rootModPath, 'Mods', modName, 'meta.lsx'); try { if (path.extname(modPath) === pak && fs.statSync(modPath).isFile()) { try { - console.log(unpackLocation); await Packager.UncompressPackage(modPath, unpackLocation); } catch (Error) { bg3mh_logger.error(Error); } - bg3mh_logger.info(`Mod ${path.basename(modPath)} unpacked to ${unpackLocation}`) + bg3mh_logger.info(`Mod ${path.basename(modPath)} unpacked to ${unpackLocation}`); return; } - // i'd like to refactor xml code into its own file for next release - - // Read the XML content - let xmlContent = fs.readFileSync(metaPath, 'utf8'); - - // Modify the Name attribute in the XML - xmlContent = xmlContent.replace(/()/, `$1${lastFolderName}$3`); - - // Write the updated XML back to the file - fs.writeFileSync(metaPath, xmlContent, 'utf8'); - bg3mh_logger.info('meta.lsx updated successfully.'); + + xmlUpdate(); await Packager.CreatePackage(modTempDestPath, modPath, build); - bg3mh_logger.info(lastFolderName + pak + " packed", false); + bg3mh_logger.info(`${lastFolderName}${pak} packed`); if (isMainThread) { vscode.window.showInformationMessage(`${lastFolderName + pak} packed`); } - if (zipCheck == true) { - console.log('zipping'); - const zipPath = path.join(rootModPath, `${lastFolderName}.pak.gz`); - const gzip = createGzip(); - const source = fs.createReadStream(modTempDestPath); - const destination = fs.createWriteStream(zipPath); - - await streamPipeline(source, gzip, destination); - raiseInfo(`Gzip file has been created at ${zipPath}`, false); - if (isMainThread) { - vscode.window.showInformationMessage(`${lastFolderName}.pak.gz created`); - } - } else { - console.log('not zipping'); - moveFileAcrossDevices(modTempDestPath, modFinalDestPath); - prepareTempDir(true); - } + + zipUpPak(zipOnPack); + + moveFileAcrossDevices(modTempDestPath, modFinalDestPath); + prepareTempDir(true); } catch (Error) { bg3mh_logger.error(Error); diff --git a/support_files/xml_functions.js b/support_files/xml_functions.js new file mode 100644 index 00000000..cb0914f7 --- /dev/null +++ b/support_files/xml_functions.js @@ -0,0 +1,39 @@ +const fs = require('fs'); +const path = require('path'); + +const { isMainThread, workerData } = require('worker_threads'); + +const { CREATE_LOGGER } = require('./log_utils'); +const bg3mh_logger = CREATE_LOGGER(); + +let vscode, + getConfig; + + +if (isMainThread) { + vscode = require('vscode'); + getConfig = require('./config.js').getConfig(); + +} else { + getConfig = workerData.workerConfig; +} + + +function xmlUpdate(){ + // Read the XML content + let rootModPath = getConfig.rootModPath; + const lastFolderName = path.basename(rootModPath); + const metaPath = path.join(rootModPath, 'Mods', getConfig.modName, 'meta.lsx'); + let xmlContent = fs.readFileSync(metaPath, 'utf8'); + + + // Modify the Name attribute in the XML + xmlContent = xmlContent.replace(/()/, `$1${lastFolderName}$3`); + + // Write the updated XML back to the file + fs.writeFileSync(metaPath, xmlContent, 'utf8'); + bg3mh_logger.info('meta.lsx updated successfully.'); +} + + +module.exports = { xmlUpdate }; \ No newline at end of file diff --git a/support_files/zip_functions.js b/support_files/zip_functions.js new file mode 100644 index 00000000..1653fc1a --- /dev/null +++ b/support_files/zip_functions.js @@ -0,0 +1,59 @@ +const path = require('path'); +const fs = require('fs'); + +const { isMainThread, workerData } = require('worker_threads'); + +const { createGzip } = require('zlib'); +const { pipeline } = require('stream'); +const { promisify } = require('util'); +const streamPipeline = promisify(pipeline); + +const { pak } = require('./lslib_utils').getFormats(); + +const { CREATE_LOGGER } = require('./log_utils'); +const bg3mh_logger = CREATE_LOGGER(); + + +let vscode, + getConfig; + +if (isMainThread) { + vscode = require('vscode'); + getConfig = require('./config.js').getConfig(); + +} else { + getConfig = workerData.workerConfig; +} + +let zipOnPack = getConfig.zipOnPack; + +async function zipUpPak(zipPak = zipOnPack) { + let rootModPath = getConfig.rootModPath; + + const temp_folder = "\\temp_folder"; + const lastFolderName = path.basename(rootModPath); + const rootParentPath = path.dirname(rootModPath); + const temp_path = path.join(rootParentPath, temp_folder); + const modTempDestPath = path.join(temp_path, lastFolderName + pak); + + if (zipPak == true) { + console.log('zipping'); + const zipPath = path.join(rootModPath, `${lastFolderName}.pak.gz`); + const gzip = createGzip(); + const source = fs.createReadStream(modTempDestPath); + const destination = fs.createWriteStream(zipPath); + + await streamPipeline(source, gzip, destination); + bg3mh_logger.info(`Gzip file has been created at ${zipPath}`, false); + + if (isMainThread) { + vscode.window.showInformationMessage(`${lastFolderName}.pak.gz created`); + } + } else { + bg3mh_logger.info('not zipping'); + } +} + +module.exports = { zipUpPak } + +