Skip to content

Commit

Permalink
small delay on opening bg3 when its open already. also dependencies i…
Browse files Browse the repository at this point in the history
…n last update. and handles fix. metadata.lsx creatikon added
  • Loading branch information
ghostboats committed Nov 4, 2024
1 parent bc32a85 commit 3579e13
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 14 deletions.
156 changes: 156 additions & 0 deletions commands/createAssetsMetadata.js
Original file line number Diff line number Diff line change
@@ -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 = `<?xml version="1.0" encoding="utf-8"?>
<save>
<version major="4" minor="7" revision="1" build="3" lslib_meta="v1,bswap_guids,lsf_keys_adjacency" />
<region id="config">
<node id="config">
<children>
<node id="entries">
<children>
`;

imagesData.forEach(image => {
xml += ` <node id="Object">
<attribute id="MapKey" type="FixedString" value="${image.MapKey}" />
<children>
<node id="entries">
<attribute id="h" type="int16" value="${image.height}" />
<attribute id="mipcount" type="int8" value="${image.mipMapCount}" />
<attribute id="w" type="int16" value="${image.width}" />
</node>
</children>
</node>
`;
});

xml += ` </children>
</node>
</children>
</node>
</region>
</save>
`;

return xml;
}
11 changes: 6 additions & 5 deletions commands/packMod.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down
5 changes: 4 additions & 1 deletion extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ let packModImport,
resizeImageController,
resizeImageHotbar,
resizeImageCustom,
saveConfigToFile;
saveConfigToFile,
createAssetsMetadataCommand;

const AutoCompleteProvider = require('./autocomplete/autoCompleteProvider');
const setupFunctionDescriptionHoverProvider = require('./hovers/functionDescriptions');
Expand All @@ -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')
Expand Down Expand Up @@ -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' },
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)"
},
{
Expand Down Expand Up @@ -322,7 +322,7 @@
"when": "editorTextFocus"
},
{
"command": "bg3-mod-helper.insertHandleDisposable",
"command": "bg3-mod-helper.insertHandle",
"key": "ctrl+shift+h",
"when": "editorTextFocus"
},
Expand Down
17 changes: 15 additions & 2 deletions support_files/release_notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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."
]
},
{
Expand Down

0 comments on commit 3579e13

Please sign in to comment.