From ddbf5e1435d0e64a42a8da704e8d57a7ba11d556 Mon Sep 17 00:00:00 2001 From: Ken Bynell Date: Thu, 30 May 2024 19:40:56 -0500 Subject: [PATCH] added some comments and signaling. more comments on the way. --- .../{worker_test.js => conversion_worker.js} | 9 +- commands/unpackGameData.js | 104 ++++++++++++++++++ extension.js | 8 +- package.json | 2 +- support_files/log_utils.js | 2 +- 5 files changed, 115 insertions(+), 10 deletions(-) rename commands/{worker_test.js => conversion_worker.js} (85%) create mode 100644 commands/unpackGameData.js diff --git a/commands/worker_test.js b/commands/conversion_worker.js similarity index 85% rename from commands/worker_test.js rename to commands/conversion_worker.js index 8781b951..146eef19 100644 --- a/commands/worker_test.js +++ b/commands/conversion_worker.js @@ -14,20 +14,21 @@ function taskIntake() { try { raiseInfo(`converting ${workerData.task[i]}`); - convert(workerData.task[i]); + // convert(workerData.task[i]); } catch (Error) { raiseError(`converting ${workerData.task[i]}\n failed with error ${Error}`); - } - + } } } else if (typeof(workerData.task) == 'string') { try { raiseInfo(`converting ${workerData.task}`); - convert(workerData.task); + // convert(workerData.task); } catch (Error) { raiseError(`converting ${workerData.task}\n failed with error ${Error}`); } } + + parentPort.postMessage(`worker ${workerData.workerId} done.`); } taskIntake(); \ No newline at end of file diff --git a/commands/unpackGameData.js b/commands/unpackGameData.js new file mode 100644 index 00000000..f24e0c87 --- /dev/null +++ b/commands/unpackGameData.js @@ -0,0 +1,104 @@ +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 } = require('../support_files/config'); +const { lslibPath, rootModPath, gameInstallLocation } = getConfig(); +const compatRootModPath = path.join(rootModPath + "\\"); +const lslibToolsPath = path.join(lslibPath, TOOL_SUBDIR); + +const { saveConfigFile, loadConfigFile } = 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, MessageChannel, Worker } = require('node:worker_threads'); +const comsPorts = new MessageChannel(); + +const { jobs, buildPathArrays } = require('../support_files/conversion_junction'); + +let temp_dir; + + +async function getTempDir() { + temp_dir = await vscode.window.showOpenDialog({ + canSelectFiles: false, + canSelectFolders: true, + canSelectMany: false, + title: 'Unpacked game data folder. Needs at least 160GB free space.' + }) + + if (!temp_dir || temp_dir.length === 0) { + vscode.window.showInformationMessage('No folder selected.'); + return false; + } else { + return true; + } +} + + +const unpackGameData = vscode.commands.registerCommand('bg3-mod-helper.unpackGameDataCommand', async function () { + // raiseInfo("hi dipshit! 💩"); + + let filesToConvert = await FIND_FILES(pak, path.join(gameInstallLocation, "Data")); + + // an array of workers + let workerArray = []; + let workerConfig = JSON.parse(loadConfigFile(true)); + + // the jobs function returns the lower of half the user's cpu cores or the number of things being unpacked + let jobsTotal = jobs(filesToConvert.length); + + let jobsFinished = 0; + + // made this a boolean so things don't get converted unless an unpack location is selected + if (isMainThread && await getTempDir()) { + // console.log(filesToConvert); + filesToConvert = buildPathArrays(filesToConvert); + raiseInfo(`Game data unpacking started. Please allow a few hours for this to complete, it's a big game.`); + + // nested .map() functionality :o + let convertFileNames = filesToConvert.map(fileArray => fileArray.map(file => path.basename(file))); + + // for each job, which is either a single file or an array of files sorted from smallest to largest file size, create a worker and give it the data it needs to unpack those files via workerData. + for (let i = 0; i < jobsTotal; i++) { + raiseInfo(`${convertFileNames[i]}\n`, false); + workerArray.push(new Worker(__dirname + "/conversion_worker.js", { + workerData: { + // passes the crystallized configuration settings to each of the workers + workerConfig, + // adding 2 to the workerId because 0 is the extension host and 1 is the main window + workerId: i + 2, + // passes the path of the file that needs to be converted + jobsTotal, + task: filesToConvert[i], + jobDestPath: temp_dir, + } + })); + + workerArray[i].on('message', (message) => { + if (message.includes("done.")) { + raiseInfo(message); + jobsFinished++; + } + + if (jobsFinished === jobsTotal) { + raiseInfo("All game data unpacked!") + } + }) + } + } +}); + + + +module.exports = { unpackGameData } diff --git a/extension.js b/extension.js index 967cb99c..40d01eaa 100644 --- a/extension.js +++ b/extension.js @@ -30,14 +30,14 @@ const { openModsFolderCommand, openGameFolderCommand, openLogsFolderCommand, ope const addDependenciesCommand = require('./commands/addDependencies') - const AutoCompleteProvider = require('./autocomplete/autoCompleteProvider'); const { CREATE_LOGGER, raiseInfo } = require('./support_files/log_utils'); var bg3mh_logger = CREATE_LOGGER(); const debugCommand = require('./commands/debug'); -const debug2Command = require('./commands/debug2'); +const unpackGameDataCommand = require('./commands/unpackGameData'); + const setupFunctionDescriptionHoverProvider = require('./hovers/functionDescriptions'); const setupUuidsHandlesHoverProvider = require('./hovers/uuidsHandlesCollector'); const { resizeImageTooltip, resizeImageController, resizeImageHotbar, resizeImageCustom } = require('./commands/resizeImage'); @@ -184,13 +184,13 @@ function aSimpleDataProvider() { { label: 'DDS Viewer (in development)', command: 'bg3-mod-helper.DDSViewer' }, { label: 'Add Dependencies to Meta via modsettings.lsx', command: 'bg3-mod-helper.addDependencies'}, { label: 'Debug Command', command: 'bg3-mod-helper.debugCommand' }, - { label: 'Debug2 Command', command: 'bg3-mod-helper.debug2Command' }, { label: 'Folder Shortcuts', id: 'folderShortcuts' } ]); } else if (element.id === 'packer') { return Promise.resolve([ { label: 'Pack Mod', command: 'bg3-mod-helper.packMod' }, - { label: 'Unpack Mod', command: 'bg3-mod-helper.unpackMod' } + { label: 'Unpack Mod', command: 'bg3-mod-helper.unpackMod' }, + { label: 'Unpack Game Data', command: 'bg3-mod-helper.unpackGameDataCommand' } ]); } else if (element.id === 'conversion') { return Promise.resolve([ diff --git a/package.json b/package.json index 00fca13d..be19be21 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "title": "For dev use, dont press the button" }, { - "command": "bg3-mod-helper.debug2Command", + "command": "bg3-mod-helper.unpackGameDataCommand", "title": "For dev use, do press the button ;)" }, { diff --git a/support_files/log_utils.js b/support_files/log_utils.js index a29218a2..214facb4 100644 --- a/support_files/log_utils.js +++ b/support_files/log_utils.js @@ -83,7 +83,7 @@ if (isMainThread) { if (popup) { vscode.window.showInformationMessage(`${info}`); } - console.info(info); + console.log(info); bg3mh_logger.info(info); } } else {