command.helper.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { exec, spawn } from "child_process";
  2. import fs from "fs";
  3. const logsPath = `./scripts/logs`;
  4. const logPath = `${logsPath}/factorio-update.log`;
  5. if (!fs.existsSync(logsPath)) fs.mkdirSync(logsPath);
  6. if (fs.existsSync(logPath)) fs.rmSync(logPath);
  7. /** Log command output to separate log file to minimize console output */
  8. function logDebug(msg: string): void {
  9. fs.appendFileSync(logPath, msg);
  10. }
  11. async function runCommand(command: string, args?: string[]): Promise<number | null> {
  12. return new Promise((resolve, reject) => {
  13. const proc = spawn(command, args);
  14. proc.stdout.on("data", (data: string) => {
  15. logDebug(data);
  16. });
  17. proc.stderr.on("data", (data: string) => {
  18. logDebug(data);
  19. });
  20. proc.on("error", (code) => {
  21. reject(code);
  22. });
  23. proc.on("exit", (code) => {
  24. resolve(code);
  25. });
  26. });
  27. }
  28. //const FACTORIO_BIN_PATH = `C:\\Program Files\\Factorio\\bin\\x64\\factorio.exe`;
  29. const FACTORIO_BIN_PATH = `/opt/factorio/bin/x64/factorio`;
  30. /**
  31. * Dumps data.raw as JSON to the script output folder and exits.
  32. * the output are genereate in Factorio data folder under script-output/.
  33. * more at https://wiki.factorio.com/Command_line_parameters
  34. * @returns
  35. */
  36. export const dumpFactorioData = async () => {
  37. await runCommand(FACTORIO_BIN_PATH, ["--dump-data"]);
  38. await waitForFactorio(true, 10000);
  39. await waitForFactorio(false, 30000);
  40. };
  41. /**
  42. * Dumps all prototypes name and description (if they have a valid value) to the script output folder and exits.
  43. * the output are genereate in Factorio data folder under script-output.
  44. * more at https://wiki.factorio.com/Command_line_parameters
  45. * @returns
  46. */
  47. export const dumpFactorioLocale = async () => {
  48. await runCommand(FACTORIO_BIN_PATH, ["--dump-prototype-locale"]);
  49. await waitForFactorio(true, 10000);
  50. await waitForFactorio(false, 30000);
  51. };
  52. export const dumpFactorioIcon = async () => {
  53. await runCommand(FACTORIO_BIN_PATH, ["--dump-icon-sprites"]);
  54. await waitForFactorio(true, 10000);
  55. await waitForFactorio(false, 60000);
  56. };
  57. var isWin = process.platform === "win32";
  58. /** Check whether Factorio is running after a delay */
  59. export async function checkIfFactorioIsRunning(delayMs = 1000): Promise<boolean> {
  60. return new Promise((resolve, reject) => {
  61. setTimeout(() => {
  62. exec(isWin ? "tasklist" : "ps -A", (err, stdout, _) => {
  63. if (err != null) reject(err);
  64. resolve(stdout.toLowerCase().includes("factorio"));
  65. });
  66. }, delayMs);
  67. });
  68. }
  69. /**
  70. * Wait for factorio.exe to exit, since the image dump continues to run after
  71. * the batch script exits.
  72. */
  73. async function waitForFactorio(running: boolean, waitMs: number): Promise<void> {
  74. const start = Date.now();
  75. let result = false;
  76. let runtime = 0;
  77. do {
  78. result = await checkIfFactorioIsRunning();
  79. runtime = Date.now() - start;
  80. } while (result !== running && runtime < waitMs);
  81. logDebug(`Waited ${runtime.toString()} for Factorio to ${running ? "start" : "exit"}\n`);
  82. }