123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- import { parentPort } from 'node:worker_threads';
- import fs from 'node:fs';
- import md5 from "./src/misc/md5.js";
- import path from "path";
- import defaultProcess from "./src/defaultProcess.js";
- import npcInit from "./src/npcInit.js";
- import skillDefinitions from "./src/skillDefinitions.js";
- import wardrobeItems from "./src/wardrobeItems.js";
- import wardrobeItemsTypes from "./src/wardrobeItemsTypes.js";
- const thisFilesHash = md5(fs.readFileSync(__filename,{encoding: 'utf8'}));
- //https://stackoverflow.com/a/25221100/7200161
- function baseFileName(fullpath){
- return fullpath.split('\\').pop().split('/').pop();
- }
- function convertFile(task){
- const VERSION = task.VERSION;
- const filePath = task.filePath;
- const outPath = task.outPath;
- const generatedFilesPrefix = task.generatedFilesPrefix;
- const options = task.options;
- try{
- const data = fs.readFileSync(filePath,{encoding: 'utf8'});
- const startTime = (new Date()).getTime();
- const baseFileNameStr = baseFileName(filePath);
- const outFilePath = path.join(outPath,generatedFilesPrefix,baseFileNameStr.split('.')[0]+'.tw');
- const outFilePathTS = path.join(outPath,generatedFilesPrefix,baseFileNameStr.split('.')[0]+'.ts');
- const qsp2twOptions = data.split('\n')?.[1];
- if(qsp2twOptions.startsWith("!! SKIP_QSRC2TW")){
- if(fs.existsSync(outFilePath))
- fs.unlink(outFilePath,(err) => {if (err) throw err;});
- if(fs.existsSync(outFilePathTS))
- fs.unlink(outFilePathTS,(err) => {if (err) throw err;});
- return [0,"SKIP"];
- }
- //#region Skip File Output if outfile exists, is based on the same codebase (determined by hash) and has used the same compier-version
- const codeHash = md5(data);
- if (fs.existsSync(outFilePath)) {
- try{
- const secondLineData = fs.readFileSync(outFilePath, "utf-8").split('\n')[1];
- const qsrc2twResultMatch = secondLineData.match(/<!--\s*qsrc2twResult=({.*})\s*-->/);
- if(qsrc2twResultMatch){
- const qsrc2twResult = JSON.parse(qsrc2twResultMatch[1]);
- if((qsrc2twResult.code && codeHash == qsrc2twResult.code) &&
- (qsrc2twResult.version && thisFilesHash == qsrc2twResult.version)){
- return [0,"EXISTS"];
- }
- }
- }
- catch(e){
- //Something unexpected happens. No need to handle this, because we'll just run the default file-processing.
- }
- }
- //#endregion
- var convertMode = "default";
- var convertModeOptions = {};
- /*if(qsp2twOptions.startsWith("!! QSRC2TW_module")){
- convertMode = qsp2twOptions.trim().split(" ").toReversed()[0];
- }*/
- //const modeLookupRegex = /\s*!!\s*QSRC2TW_module\s+(\w+)(\s+{[^}]+})?/;
- const modeLookupRegex = /\s*!!\s*QSRC2TW_module\s+(\w+)(\s+.+)?/;
- let modeLookupResult;
- try{
- if(modeLookupResult = modeLookupRegex.exec(qsp2twOptions)){
- convertMode = modeLookupResult[1];
- if(modeLookupResult[2])
- convertModeOptions = JSON.parse(modeLookupResult[2]);
- }
- }
- catch(e){
- console.log(e.toString());
- }
- /**
- * Return value is Array [TwineCode, TSCode]. TwineCode must not be null.
- */
- var convertFunction = (code,options)=>[null,null];
- switch (convertMode) {
- case "default": convertFunction = (code,options) => [defaultProcess(code),null]; break;
- case "npcInit": convertFunction = (code,options) => npcInit(code); break;
- case "stat_sklattrib_lvlset": convertFunction = (code,options) => skillDefinitions(code); break;
- case "wardrobeItems": convertFunction = (code,options) => wardrobeItems(code,options); break;
- case "wardrobeItemsTypes": convertFunction = (code,options) => wardrobeItemsTypes(code,options); break;
- default:
- console.warn("Unreckognized Convert Mode");
- break;
- }
- try{
- let twineCode = "";
- let twineCodeRaw = undefined;
- let tsCodeRaw = undefined;
- const defaultConsole = console;
- if(!options.verboseErrors)
- console = {log:(...args)=>{}, debug: (...args)=>{},warn:(...args)=>{}, error: (...args)=>{}};
- try{
- [twineCodeRaw,tsCodeRaw] = convertFunction(data,convertModeOptions);
- }
- catch(e){
- throw e;
- }
- finally{
- console = defaultConsole;
- }
- if(!twineCodeRaw){
- console.error("Twine Code must be generated by every convertMode");
- return [2,"Invalid convertFunction"];
- }else{
- twineCode = twineCodeRaw.split('\n')
- .toSpliced(1,0,`<!--qsrc2twResult={"version":"${thisFilesHash}","code":"${codeHash}","time":"${(new Date().toISOString())}"}-->`)
- .join('\n');
- fs.writeFile(outFilePath, twineCode, err => {
- if (err) {
- console.error(err);
- } else {
- }
- });
- }
- if(!tsCodeRaw){
- if(fs.existsSync(outFilePathTS))
- fs.unlink(outFilePathTS,(err) => {if (err) throw err;});
- }else{
- fs.writeFile(outFilePathTS, tsCodeRaw, err => {
- if (err) {
- console.error(err);
- } else {
- }
- });
- }
- const executionTime = (new Date()).getTime() - startTime;
- console.log(`${baseFileNameStr.padEnd(30,'.')} ${executionTime} ms`);
- return [0,"SUCCESS"];
- }catch(e){
- //console.error(`Error in "${baseFileNameStr}". No output was generated`);
- return [1,`Error in "${baseFileNameStr}". No output was generated`,e];
- }
- }
- catch(e){
- //console.error();
- return [1,`Critical Error in "${filePath}". No output was generated`, e];
- }
- }
- parentPort.on('message', (task) => {
- parentPort.postMessage(convertFile(task));
- });
|