Created
April 24, 2021 11:49
-
-
Save foxfabi/08b00abf683f9e7bca409df9ce86e3b0 to your computer and use it in GitHub Desktop.
Return the CoordinateFrame (CFrame) elements extracted from a Roblox XML file (*.rbxmx) as JSON Array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Return the CoordinateFrame elements extracted | |
* from a Roblox XML file (*.rbxmx) as JSON Array. | |
* | |
* Models often consist of one part that is used several times | |
* and usually differ only in position and orientation. | |
* By extracting the CoordinateFrame from the model, it is now | |
* possible with a LUA script to clone the underlying part | |
* and place it dynamically at the desired location. | |
* | |
* @author Fabian Dennler <fd@fabforge.ch> | |
*/ | |
const fs = require('fs') | |
const glob = require('glob') | |
const XMLExtract = require('xml-extract') | |
const parseString = require('xml2js').parseString | |
// Folder containing the rbmxm files | |
const folder = './srv/Models/Tree/' | |
// Pattern to use to identify the same model/object | |
const pattern = '**/Part.rbxmx' | |
/** | |
* Reads the content of the given file | |
* @param {string} file - the file to read | |
**/ | |
const getFile = (file) => { | |
return new Promise((resolve, reject) => { | |
fs.readFile(file, 'utf8', (error, data) => { | |
if (error) { | |
reject(error) | |
} | |
resolve(data) | |
}) | |
}) | |
} | |
/** | |
* Parse the given xml, extract the CoordinateFrame | |
* and transform it into json format | |
* @param {string} data - the xml structure | |
**/ | |
const parseXML = (data) => { | |
return new Promise((resolve, reject) => { | |
XMLExtract(data, 'CoordinateFrame', true, function (error, element) { | |
if (error) { | |
reject(error) | |
} else { | |
parseString(element, function (error, result) { | |
if (error) { | |
reject(error) | |
} else { | |
resolve(JSON.stringify(result)) | |
} | |
}) | |
} | |
}) | |
}) | |
} | |
/** | |
* Read the | |
* @param {string} data - the xml structure | |
**/ | |
const parseFiles = (files) => { | |
return new Promise((resolve, reject) => { | |
const cframes = [] | |
let count = 0 | |
for (const file of files) { | |
getFile(file) | |
.then(data => parseXML(data) | |
.then(json => { | |
count++ | |
cframes.push(json) | |
if (count === files.length) { | |
resolve(cframes) | |
} | |
}) | |
.catch(err => console.error(err)) | |
).catch(err => console.error(err)) | |
} | |
}) | |
} | |
/** | |
* Search all files matching the given pattern in the given folder | |
* @param {string} folder - the folder to scan | |
* @param {string} pattern - the pattern to use for file matching | |
**/ | |
const extractFiles = function (folder, pattern) { | |
return new Promise((resolve, reject) => { | |
glob(folder + pattern, function (error, files) { | |
if (error) { | |
reject(error) | |
} else { | |
parseFiles(files) | |
.then(ok => { | |
console.log(ok) | |
resolve(ok) | |
}) | |
.catch(err => { | |
console.error(err) | |
}) | |
} | |
}) | |
}) | |
} | |
/** | |
* Main | |
* @param {string} folder - the folder to scan | |
* @param {string} pattern - the pattern to use for file matching | |
**/ | |
extractFiles(folder, pattern) | |
.then(cframes => console.log(cframes)) | |
.catch(err => console.error(err)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment