From 3579e1360d928d80da7ccf00449078f6000823dc Mon Sep 17 00:00:00 2001 From: ghostboats <106226990+ghostboats@users.noreply.github.com> Date: Mon, 4 Nov 2024 07:28:15 -0600 Subject: [PATCH] small delay on opening bg3 when its open already. also dependencies in last update. and handles fix. metadata.lsx creatikon added --- commands/createAssetsMetadata.js | 156 +++++++++++++++++++++++++++++++ commands/packMod.js | 11 ++- extension.js | 5 +- package-lock.json | 4 +- package.json | 8 +- support_files/release_notes.js | 17 +++- 6 files changed, 187 insertions(+), 14 deletions(-) create mode 100644 commands/createAssetsMetadata.js diff --git a/commands/createAssetsMetadata.js b/commands/createAssetsMetadata.js new file mode 100644 index 00000000..18d09355 --- /dev/null +++ b/commands/createAssetsMetadata.js @@ -0,0 +1,156 @@ +const vscode = require('vscode'); +const fs = require('fs'); +const path = require('path'); + +const { getConfig, getModName } = require('../support_files/config'); +const { rootModPath } = getConfig(); + +const createAssetsMetadataCommand = vscode.commands.registerCommand('bg3-mod-helper.createAssetsMetadata', async function () { + const modName = await getModName(); + const GUIPath = path.join(rootModPath, 'Mods', modName, 'GUI'); + const assetsPath = path.join(rootModPath, 'Mods', modName, 'GUI', 'Assets'); + const metadataPath = path.join(GUIPath, 'metadata.lsx'); + + // Check if the assetsPath exists + if (!fs.existsSync(assetsPath)) { + // Show options to create the directory or cancel + const choice = await vscode.window.showInformationMessage( + `The path ${assetsPath} does not exist. Do you want to create it?`, + 'Create', + 'Cancel' + ); + + if (choice === 'Create') { + // Create the directory + fs.mkdirSync(assetsPath, { recursive: true }); + vscode.window.showInformationMessage(`Created directory: ${assetsPath}`); + } else { + // User canceled the operation + return; + } + } + + // Check if metadata.lsx exists + if (fs.existsSync(metadataPath)) { + // Show options to overwrite or cancel + const overwrite = await vscode.window.showInformationMessage( + `The file ${metadataPath} already exists and will be overwritten. Do you want to proceed?`, + 'Overwrite', + 'Cancel' + ); + + if (overwrite !== 'Overwrite') { + // User chose not to overwrite the file + return; + } + } + + // Proceed with creating or overwriting the metadata.lsx file + + // Get all image files + const imageFiles = getAllDDSFiles(assetsPath, assetsPath); // baseDir is assetsPath + + const imagesData = []; + + imageFiles.forEach(({ fullPath, relativePath }) => { + let width, height, mipMapCount; + + try { + if (fullPath.toLowerCase().endsWith('.dds')) { + ({ width, height, mipMapCount } = readDDSHeader(fullPath)); + } else { + // Unsupported file type + return; + } + + // MapKey should be relative to 'Assets/' directory with forward slashes + const mapKey = 'Assets/' + relativePath.replace(/\\/g, '/').replace(/\.dds$/i, '.png'); + + imagesData.push({ MapKey: mapKey, width, height, mipMapCount }); + } catch (error) { + // Handle error, e.g., log or ignore + console.error(`Error processing file ${fullPath}: ${error.message}`); + } + }); + + // Build the metadata.lsx content + const metadataContent = buildMetadataLSX(imagesData); + + // Write the metadata.lsx file + fs.writeFileSync(metadataPath, metadataContent); + + vscode.window.showInformationMessage(`metadata.lsx has been created at ${metadataPath}`); +}); + +module.exports = { createAssetsMetadataCommand }; + +// Function to recursively get all .dds image files +function getAllDDSFiles(dir, baseDir, fileList = []) { + const files = fs.readdirSync(dir); + files.forEach(function(file) { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + if (stat.isDirectory()) { + getAllDDSFiles(filePath, baseDir, fileList); + } else if (stat.isFile() && file.toLowerCase().endsWith('.dds')) { + const relativePath = path.relative(baseDir, filePath); + fileList.push({ fullPath: filePath, relativePath }); + } + }); + return fileList; +} + +// Function to read DDS header and extract width, height, and mipMapCount +function readDDSHeader(filePath) { + const fd = fs.openSync(filePath, 'r'); + const buffer = Buffer.alloc(128); // DDS header is 128 bytes + fs.readSync(fd, buffer, 0, 128, 0); + fs.closeSync(fd); + + if (buffer.toString('ascii', 0, 4) !== 'DDS ') { + throw new Error('Not a DDS file'); + } + + const height = buffer.readUInt32LE(12); + const width = buffer.readUInt32LE(16); + const mipMapCount = buffer.readUInt32LE(28); + + return { width, height, mipMapCount }; +} + +// Function to build the metadata.lsx content +function buildMetadataLSX(imagesData) { + let xml = ` + + + + + + + +`; + + imagesData.forEach(image => { + xml += ` + + + + + + + + + +`; + }); + + xml += ` + + + + + +`; + + return xml; +} diff --git a/commands/packMod.js b/commands/packMod.js index 2e871d1b..2fa6fb47 100644 --- a/commands/packMod.js +++ b/commands/packMod.js @@ -29,7 +29,7 @@ const packModCommand = vscode.commands.registerCommand('bg3-mod-helper.packMod', if (gameRunning) { vscode.window.showErrorMessage('Baldur\'s Gate 3 is currently running. Please close the game before packing the mod or enable autoclose in settings.'); - return; // Stop further execution + return; } const workspaceState = vscode.workspace.getConfiguration('bg3ModHelper'); @@ -58,7 +58,6 @@ const packModCommand = vscode.commands.registerCommand('bg3-mod-helper.packMod', if (!fs.existsSync(metaPath)) { const shouldCreateMeta = await vscode.window.showInformationMessage('meta.lsx not found in ' + metaPath + '. Do you want to create one?', 'Create Meta', 'Close'); if (shouldCreateMeta === 'Create Meta') { - // Check if the directory exists, if not, create it const directoryPath = path.join(rootModPath, 'Mods', modName); if (!fs.existsSync(directoryPath)) { fs.mkdirSync(directoryPath, { recursive: true }); @@ -133,7 +132,7 @@ function handleGameRunning() { exec('tasklist', async (error, stdout, stderr) => { if (error || stderr) { bg3mh_logger.error("Error checking running processes: " + (error || stderr)); - resolve(false); // Assuming game is not running in case of error + resolve(false); return; } const { autoCloseBG3, laucherAPI } = getConfig(); @@ -147,13 +146,15 @@ function handleGameRunning() { exec(`taskkill /F /IM ${exeName}`, (killError, killStdout, killStderr) => { if (killError || killStderr) { bg3mh_logger.error("Error closing Baldur's Gate 3: " + (killError || killStderr)); - resolve(false); // Return false if there was an error closing the game + resolve(false); return; } vscode.window.showInformationMessage('Baldur\'s Gate 3 was closed to pack the mod.'); bg3mh_logger.info("Baldur's Gate 3 was successfully closed."); - resolve(false); + setTimeout(() => { + resolve(false); + }, 1000); }); } else { resolve(true); // Game is running, but user opted not to auto-close diff --git a/extension.js b/extension.js index 3743d679..b3f66d09 100644 --- a/extension.js +++ b/extension.js @@ -47,7 +47,8 @@ let packModImport, resizeImageController, resizeImageHotbar, resizeImageCustom, - saveConfigToFile; + saveConfigToFile, + createAssetsMetadataCommand; const AutoCompleteProvider = require('./autocomplete/autoCompleteProvider'); const setupFunctionDescriptionHoverProvider = require('./hovers/functionDescriptions'); @@ -70,6 +71,7 @@ function setCommands() { openConverterCommand = require('./commands/openConverter'); versionGeneratorCommand = require('./commands/versionGenerator'); textEditorCommand = require('./commands/textEditor'); + createAssetsMetadataCommand = require('./commands/createAssetsMetadata') // config commands saveConfigToFile = require('./commands/saveConfigToFile') @@ -228,6 +230,7 @@ function aSimpleDataProvider() { { label: 'Launch Game', command: 'bg3-mod-helper.launchGame' }, { label: 'Generate Folder Structure', command: 'bg3-mod-helper.createModTemplate' }, { label: 'Atlas Generator (Supply a folder of icons to make an atlas and its corresponding .dds with those icons, as well as its merged.lsx)', command: 'bg3-mod-helper.createAtlas' }, + { label: 'Assets MetaData.lsx Creation', command: 'bg3-mod-helper.createAssetsMetadata' }, { label: 'BBCode/Markdown Editor ', command: 'bg3-mod-helper.textEditorTool'}, { label: 'Convert Video to GIF', command: 'bg3-mod-helper.convertVideoToGif' }, { label: `Ver. Generator (${version})`, command: 'bg3-mod-helper.versionGenerator' }, diff --git a/package-lock.json b/package-lock.json index d866ca0a..cefe22b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bg3-mod-helper", - "version": "2.2.61", + "version": "2.2.63", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bg3-mod-helper", - "version": "2.2.61", + "version": "2.2.63", "license": "LGPL-3.0-or-later", "dependencies": { "ffmpeg-static": "^5.2.0", diff --git a/package.json b/package.json index 94e779c8..5da003bf 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "bg3_mod_helper", "publisher": "ghostboats", "description": "This extension is designed to help you make mods in Baldur's Gate 3 by creating UUIDs and handles for you, as well as updating your .loca.xml files as well should they exist. And more to come in the future.", - "version": "2.2.61", + "version": "2.2.63", "icon": "media/marketplace_icon.png", "engines": { "vscode": "^1.86.0" @@ -43,12 +43,12 @@ }, { "command": "bg3-mod-helper.insertHandle", - "title": "Generate Handle", + "title": "Generate Handle & Text", "iconPath": "$(chip)" }, { "command": "bg3-mod-helper.insertHandleDisposable", - "title": "Generate Handle Here", + "title": "Generate Handle", "iconPath": "$(chip)" }, { @@ -322,7 +322,7 @@ "when": "editorTextFocus" }, { - "command": "bg3-mod-helper.insertHandleDisposable", + "command": "bg3-mod-helper.insertHandle", "key": "ctrl+shift+h", "when": "editorTextFocus" }, diff --git a/support_files/release_notes.js b/support_files/release_notes.js index 09b17d0a..262aa1d7 100644 --- a/support_files/release_notes.js +++ b/support_files/release_notes.js @@ -56,16 +56,29 @@ function generateReleaseNotes(version) { { version: version, features: [ + { + title: "Assets Metadata.lsx button", + details: [ + "Added Assets Metadata.lsx Creation (I know my naming scheme sucks )button that will create a metadata.lsx \nfile based on your pngs/DDS files in your GUI/Assets folders and subfolders." + ] + }, + { + title: "Handle Entry Fixes", + details: [ + "Sorry i think I messed something up in a previous handle update. I have swapped around the \ncommands for insertHandle and insertHandleDisposable. Basically this should be that \n when you hit control shift h it will prompt for an intial handle. \nIf you right click you will see Generate Handle which will make a handle but not entry now." + ] + }, { title: "Dependencies Changes", details: [ - "Add Dependency button should now correctly check your modsettings list (for all profiles) and \ngive you quick access to add them in as dependencies to the mod you are working on" + "Add Dependency button should now correctly check your modsettings list (for all profiles) and \ngive you quick access to add them in as dependencies to the mod you are working on." ] }, { title: "Minor Changes", details: [ - "Your mod version now shows in the quick actions next to the version generator button(needs a \nreload of vscode if you update it to update the ui)." + "Your mod version now shows in the quick actions next to the version generator button(needs a \nreload of vscode if you update it to update the ui).", + "1 second delay if bg3 is open when reopening on pak and play to allow for proper closing and reopening of the game." ] }, {