refactor: linux get game exe logic

This commit is contained in:
JackEnx 2024-12-16 21:31:39 -03:00
parent 64745b9147
commit 9f8269d9a9

View file

@ -8,10 +8,10 @@ import axios from "axios";
import { exec } from "child_process"; import { exec } from "child_process";
const commands = { const commands = {
findGameExecutableWithWineProcess: (executable: string) =>
`lsof -c wine 2>/dev/null | grep -i ${executable} | awk \'{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}\'`,
findWineDir: () => findWineDir: () =>
`lsof -c wine 2>/dev/null | grep -i drive_c/windows | head -n 1 | awk \'{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}\'`, `lsof -c wine 2>/dev/null | grep '/drive_c/windows$' | head -n 1 | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`,
findWineExecutables: () =>
`lsof -c wine 2>/dev/null | grep '\.exe$' | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`,
}; };
export const gamesPlaytime = new Map< export const gamesPlaytime = new Map<
@ -43,10 +43,10 @@ const findGamePathByProcess = (
processMap: Map<string, Set<string>>, processMap: Map<string, Set<string>>,
gameId: string gameId: string
) => { ) => {
if (process.platform === "win32") { const executables = gameExecutables[gameId].filter((info) => {
const executables = gameExecutables[gameId].filter( if (process.platform === "linux" && info.os === "linux") return true;
(info) => info.os === "win32" return info.os === "win32";
); });
for (const executable of executables) { for (const executable of executables) {
const exe = executable.name.slice(executable.name.lastIndexOf("/") + 1); const exe = executable.name.slice(executable.name.lastIndexOf("/") + 1);
@ -56,7 +56,10 @@ const findGamePathByProcess = (
const pathSet = processMap.get(exe); const pathSet = processMap.get(exe);
if (pathSet) { if (pathSet) {
const executableName = executable.name.replace(/\//g, "\\"); const executableName =
process.platform === "win32"
? executable.name.replace(/\//g, "\\")
: executable.name;
pathSet.forEach((path) => { pathSet.forEach((path) => {
if (path.toLowerCase().endsWith(executableName)) { if (path.toLowerCase().endsWith(executableName)) {
@ -64,62 +67,8 @@ const findGamePathByProcess = (
{ objectID: gameId, shop: "steam" }, { objectID: gameId, shop: "steam" },
{ executablePath: path } { executablePath: path }
); );
}
});
}
}
}
if (process.platform === "linux") { if (process.platform === "linux") {
const executables = gameExecutables[gameId].filter((info) => {
if (info.os === "win32") return true;
if (info.os === "linux") return true;
return false;
});
for (const executable of executables) {
if (executable.os === "win32") {
const exe = executable.name.slice(executable.name.lastIndexOf("/") + 1);
if (!exe) return;
const hasProcess = processMap.get(exe);
if (hasProcess) {
new Promise((res) => {
exec(
commands.findGameExecutableWithWineProcess(exe),
(err, out) => {
if (err) {
res(false);
return;
}
const paths = [
...new Set(
out
.trim()
.split("\n")
.map((path) => path.trim())
),
];
for (const path of paths) {
if (path.toLocaleLowerCase().endsWith(executable.name)) {
gameRepository.update(
{ objectID: gameId, shop: "steam" },
{ executablePath: path }
);
res(true);
return;
}
}
res(false);
}
);
}).then((res) => {
if (res) {
exec(commands.findWineDir(), (err, out) => { exec(commands.findWineDir(), (err, out) => {
if (err) return; if (err) return;
@ -131,12 +80,9 @@ const findGamePathByProcess = (
); );
}); });
} }
}
}); });
} }
} else {
//TODO: linux case
}
}
} }
}; };
@ -155,19 +101,35 @@ const getSystemProcessMap = async () => {
map.set(key, currentSet.add(value)); map.set(key, currentSet.add(value));
}); });
return map; if (process.platform === "linux") {
}; await new Promise((res) => {
exec(commands.findWineExecutables(), (err, out) => {
if (err) res(null);
const observeGameProcess = (hasProcess: boolean, game: Game) => { const pathSet = new Set(
if (hasProcess) { out
if (gamesPlaytime.has(game.id)) { .trim()
onTickGame(game); .split("\n")
} else { .map((path) => path.trim())
onOpenGame(game); );
}
} else if (gamesPlaytime.has(game.id)) { pathSet.forEach((path) => {
onCloseGame(game); if (path.startsWith("/usr")) return;
const key = path.slice(path.lastIndexOf("/") + 1).toLowerCase();
if (!key || !path) return;
const currentSet = map.get(key) ?? new Set();
map.set(key, currentSet.add(path));
});
res(null);
});
});
} }
return map;
}; };
export const watchProcesses = async () => { export const watchProcesses = async () => {
@ -202,34 +164,16 @@ export const watchProcesses = async () => {
if (!processSet) continue; if (!processSet) continue;
if (process.platform === "win32") {
const hasProcess = processSet.has(executablePath); const hasProcess = processSet.has(executablePath);
observeGameProcess(hasProcess, game); if (hasProcess) {
} if (gamesPlaytime.has(game.id)) {
onTickGame(game);
if (process.platform === "linux") {
if (executable.endsWith(".exe")) {
exec(
commands.findGameExecutableWithWineProcess(executable),
(err, out) => {
if (err) return;
const pathSet = new Set(
out
.trim()
.split("\n")
.map((path) => path.trim())
);
const hasProcess = pathSet.has(executablePath!);
observeGameProcess(hasProcess, game);
}
);
} else { } else {
//TODO: linux case onOpenGame(game);
} }
} else if (gamesPlaytime.has(game.id)) {
onCloseGame(game);
} }
} }