task_processor.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { parentPort } from 'node:worker_threads';
  2. import fs from 'node:fs';
  3. import md5 from "./src/misc/md5.js";
  4. import path from "path";
  5. import defaultProcess from "./src/defaultProcess.js";
  6. import npcInit from "./src/npcInit.js";
  7. import skillDefinitions from "./src/skillDefinitions.js";
  8. //https://stackoverflow.com/a/25221100/7200161
  9. function baseFileName(fullpath){
  10. return fullpath.split('\\').pop().split('/').pop();
  11. }
  12. function convertFile(task){
  13. const VERSION = task.VERSION;
  14. const filePath = task.filePath;
  15. const outPath = task.outPath;
  16. const generatedFilesPrefix = task.generatedFilesPrefix;
  17. const options = task.options;
  18. try{
  19. const data = fs.readFileSync(filePath,{encoding: 'utf8'});
  20. const startTime = (new Date()).getTime();
  21. const baseFileNameStr = baseFileName(filePath);
  22. const outFilePath = path.join(outPath,generatedFilesPrefix,baseFileNameStr.split('.')[0]+'.tw');
  23. const outFilePathTS = path.join(outPath,generatedFilesPrefix,baseFileNameStr.split('.')[0]+'.ts');
  24. const qsp2twOptions = data.split('\n')?.[1];
  25. if(qsp2twOptions.startsWith("!! SKIP_QSRC2TW")){
  26. if(fs.existsSync(outFilePath))
  27. fs.unlink(outFilePath,(err) => {if (err) throw err;});
  28. if(fs.existsSync(outFilePathTS))
  29. fs.unlink(outFilePathTS,(err) => {if (err) throw err;});
  30. return [0,"SKIP"];
  31. }
  32. //#region Skip File Output if outfile exists, is based on the same codebase (determined by hash) and has used the same compier-version
  33. const codeHash = md5(data);
  34. if (fs.existsSync(outFilePath)) {
  35. try{
  36. const secondLineData = fs.readFileSync(outFilePath, "utf-8").split('\n')[1];
  37. const qsrc2twResultMatch = secondLineData.match(/<!--\s*qsrc2twResult=({.*})\s*-->/);
  38. if(qsrc2twResultMatch){
  39. const qsrc2twResult = JSON.parse(qsrc2twResultMatch[1]);
  40. if((qsrc2twResult.code && codeHash == qsrc2twResult.code) &&
  41. (qsrc2twResult.version && VERSION == qsrc2twResult.version)){
  42. return [0,"EXISTS"];
  43. }
  44. }
  45. }
  46. catch(e){
  47. //Something unexpected happens. No need to handle this, because we'll just run the default file-processing.
  48. }
  49. }
  50. //#endregion
  51. var convertMode = "default";
  52. if(qsp2twOptions.startsWith("!! QSRC2TW_module")){
  53. convertMode = qsp2twOptions.trim().split(" ").toReversed()[0];
  54. }
  55. /**
  56. * Return value is Array [TwineCode, TSCode]. TwineCode must not be null.
  57. */
  58. var convertFunction = (code)=>[null,null];
  59. switch (convertMode) {
  60. case "default": convertFunction = (code) => [defaultProcess(code),null]; break;
  61. case "npcInit": convertFunction = (code) => npcInit(code); break;
  62. case "stat_sklattrib_lvlset": convertFunction = (code) => skillDefinitions(code); break;
  63. default:
  64. console.warn("Unreckognized Convert Mode");
  65. break;
  66. }
  67. try{
  68. let twineCode = "";
  69. let twineCodeRaw = undefined;
  70. let tsCodeRaw = undefined;
  71. const defaultConsole = console;
  72. if(!options.verboseErrors)
  73. console = {log:(...args)=>{}, debug: (...args)=>{},warn:(...args)=>{}, error: (...args)=>{}};
  74. try{
  75. [twineCodeRaw,tsCodeRaw] = convertFunction(data);
  76. }
  77. catch(e){
  78. throw e;
  79. }
  80. finally{
  81. console = defaultConsole;
  82. }
  83. if(!twineCodeRaw){
  84. console.error("Twine Code must be generated by every converMode");
  85. return [2,"Invalid convertFunction"];
  86. }else{
  87. twineCode = twineCodeRaw.split('\n')
  88. .toSpliced(1,0,`<!--qsrc2twResult={"version":${VERSION},"code":"${codeHash}","time":"${(new Date().toISOString())}"}-->`)
  89. .join('\n');
  90. fs.writeFile(outFilePath, twineCode, err => {
  91. if (err) {
  92. console.error(err);
  93. } else {
  94. }
  95. });
  96. }
  97. if(!tsCodeRaw){
  98. if(fs.existsSync(outFilePathTS))
  99. fs.unlink(outFilePathTS,(err) => {if (err) throw err;});
  100. }else{
  101. fs.writeFile(outFilePathTS, tsCodeRaw, err => {
  102. if (err) {
  103. console.error(err);
  104. } else {
  105. }
  106. });
  107. }
  108. const executionTime = (new Date()).getTime() - startTime;
  109. console.log(`${baseFileNameStr.padEnd(30,'.')} ${executionTime} ms`);
  110. return [0,"SUCCESS"];
  111. }catch(e){
  112. //console.error(`Error in "${baseFileNameStr}". No output was generated`);
  113. return [1,`Error in "${baseFileNameStr}". No output was generated`,e];
  114. }
  115. }
  116. catch(e){
  117. //console.error();
  118. return [1,`Critical Error in "${filePath}". No output was generated`, e];
  119. }
  120. }
  121. parentPort.on('message', (task) => {
  122. parentPort.postMessage(convertFile(task));
  123. });