diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..289e7a42 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +postinstall.js diff --git a/package.json b/package.json index 84853898..b8396713 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "make": "electron-forge make", "publish": "electron-forge publish", "lint": "eslint .", - "format": "prettier . --write" + "format": "prettier . --write", + "postinstall": "node ./postinstall.js" }, "devDependencies": { "@electron-forge/cli": "^7.3.0", @@ -96,7 +97,6 @@ "react-redux": "^9.1.0", "react-router-dom": "^6.22.3", "sqlite3": "^5.1.7", - "tasklist": "^5.0.0", "tough-cookie": "^4.1.3", "typeorm": "^0.3.20", "update-electron-app": "^3.0.0", diff --git a/postinstall.js b/postinstall.js new file mode 100644 index 00000000..63b6399e --- /dev/null +++ b/postinstall.js @@ -0,0 +1,9 @@ +const fs = require("fs") + +if (process.platform === "win32"){ + if (!fs.existsSync("resources/dist")) { + fs.mkdirSync("resources/dist") + } + + fs.copyFileSync("node_modules/ps-list/vendor/fastlist-0.3.0-x64.exe", "resources/dist/fastlist.exe") +} diff --git a/src/declaration.d.ts b/src/declaration.d.ts deleted file mode 100644 index 26dfcc27..00000000 --- a/src/declaration.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -declare module "tasklist" { - interface Task { - imageName: string; - pid: number; - sessionName: string; - sessionNumber: number; - memUsage: number; - } - - function tasklist(): Promise; - - export { tasklist }; -} diff --git a/src/main/helpers/ps.ts b/src/main/helpers/ps.ts index f7ce3391..dbc11f09 100644 --- a/src/main/helpers/ps.ts +++ b/src/main/helpers/ps.ts @@ -1,12 +1,33 @@ import psList from "ps-list"; -import { tasklist } from "tasklist"; +import path from "node:path"; +import childProcess from "node:child_process"; +import { promisify } from "node:util"; +import { app } from "electron"; + +const TEN_MEGABYTES = 1000 * 1000 * 10; +const execFile = promisify(childProcess.execFile); export const getProcesses = async () => { - if (process.platform === "win32") { - return tasklist().then((tasks) => - tasks.map((task) => ({ ...task, name: task.imageName })) - ); - } + if (process.platform == "win32") { + const binaryPath = app.isPackaged + ? path.join(process.resourcesPath, "dist", "fastlist.exe") + : path.join(__dirname, "..", "..", "resources", "dist", "fastlist.exe"); - return psList(); + const { stdout } = await execFile(binaryPath, { + maxBuffer: TEN_MEGABYTES, + windowsHide: true, + }); + + return stdout + .trim() + .split("\r\n") + .map((line) => line.split("\t")) + .map(([pid, ppid, name]) => ({ + pid: Number.parseInt(pid, 10), + ppid: Number.parseInt(ppid, 10), + name, + })); + } else { + return psList(); + } }; diff --git a/src/main/services/process-watcher.ts b/src/main/services/process-watcher.ts index 96244a60..0d699165 100644 --- a/src/main/services/process-watcher.ts +++ b/src/main/services/process-watcher.ts @@ -1,7 +1,6 @@ import path from "node:path"; import { IsNull, Not } from "typeorm"; - import { gameRepository } from "@main/repository"; import { getProcesses } from "@main/helpers"; import { WindowManager } from "./window-manager"; @@ -9,27 +8,33 @@ import { WindowManager } from "./window-manager"; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export const startProcessWatcher = async () => { - const sleepTime = 100; + const sleepTime = 300; const gamesPlaytime = new Map(); // eslint-disable-next-line no-constant-condition while (true) { + await sleep(sleepTime); + const games = await gameRepository.find({ where: { executablePath: Not(IsNull()), }, }); + if (games.length == 0) { + continue; + } + const processes = await getProcesses(); for (const game of games) { - const gameProcess = processes.find((runningProcess) => { - const basename = path.win32.basename(game.executablePath); - const basenameWithoutExtension = path.win32.basename( - game.executablePath, - path.extname(game.executablePath) - ); + const basename = path.win32.basename(game.executablePath); + const basenameWithoutExtension = path.win32.basename( + game.executablePath, + path.extname(game.executablePath) + ); + const gameProcess = processes.find((runningProcess) => { if (process.platform === "win32") { return runningProcess.name === basename; } @@ -55,26 +60,15 @@ export const startProcessWatcher = async () => { gameRepository.update(game.id, { lastTimePlayed: new Date().toUTCString(), }); - - gamesPlaytime.set(game.id, performance.now()); - await sleep(sleepTime); - continue; } gamesPlaytime.set(game.id, performance.now()); - - await sleep(sleepTime); - continue; - } - - if (gamesPlaytime.has(game.id)) { + } else if (gamesPlaytime.has(game.id)) { gamesPlaytime.delete(game.id); if (WindowManager.mainWindow) { WindowManager.mainWindow.webContents.send("on-game-close", game.id); } } - - await sleep(sleepTime); } } }; diff --git a/yarn.lock b/yarn.lock index 8b36bcdb..78c336e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4611,31 +4611,6 @@ csstype@^3.0.2, csstype@^3.0.7: resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -csv-generate@^3.4.3: - version "3.4.3" - resolved "https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz" - integrity sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw== - -csv-parse@^4.16.3: - version "4.16.3" - resolved "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz" - integrity sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg== - -csv-stringify@^5.6.5: - version "5.6.5" - resolved "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz" - integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== - -csv@^5.5.0: - version "5.5.3" - resolved "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz" - integrity sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g== - dependencies: - csv-generate "^3.4.3" - csv-parse "^4.16.3" - csv-stringify "^5.6.5" - stream-transform "^2.1.3" - cycle@1.0.x: version "1.0.3" resolved "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz" @@ -7936,11 +7911,6 @@ minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" -mixme@^0.5.1: - version "0.5.10" - resolved "https://registry.npmjs.org/mixme/-/mixme-0.5.10.tgz" - integrity sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q== - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" @@ -8866,7 +8836,7 @@ proxy-from-env@^1.1.0: ps-list@^8.1.1: version "8.1.1" - resolved "https://registry.npmjs.org/ps-list/-/ps-list-8.1.1.tgz" + resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-8.1.1.tgz#9ff1952b26a9a07fcc05270407e60544237ae581" integrity sha512-OPS9kEJYVmiO48u/B9qneqhkMvgCxT+Tm28VCEJpheTpl8cJ0ffZRRNgS5mrQRTrX5yRTpaJ+hRDeefXYmmorQ== psl@^1.1.33: @@ -9463,11 +9433,6 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -sec@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/sec/-/sec-2.0.0.tgz" - integrity sha512-uq35HWa7mG6YyojrduMXjF8UhOySEf3X0V1uMpSOBYUF09xAMnJaKNSmWXeE3mN7NfJTpNUkmGa6nIpEBMN8Xw== - select-hose@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" @@ -9882,13 +9847,6 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-transform@^2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz" - integrity sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ== - dependencies: - mixme "^0.5.1" - "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -10144,14 +10102,6 @@ tar@^6.0.2, tar@^6.0.5, tar@^6.1.11, tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" -tasklist@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/tasklist/-/tasklist-5.0.0.tgz" - integrity sha512-qPB4J6pseXRqdxAFT1GhlvDPv4FHxWkXs8QVYQWIqusGwn7UXVKOoYu09DZuYWe1K7T5iusHfSoKrv8k9+RfxA== - dependencies: - csv "^5.5.0" - sec "^2.0.0" - temp-dir@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz"