mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-12 19:22:28 +00:00
refactor: linux get game exe logic
This commit is contained in:
parent
64745b9147
commit
9f8269d9a9
1 changed files with 69 additions and 125 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue