mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
chore: merge with main
This commit is contained in:
commit
4636571a25
16 changed files with 1567 additions and 1173 deletions
|
|
@ -21,6 +21,8 @@ const getRandomGame = async () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Promise.all([writePipe.createPipe(), readPipe.createPipe()]).then(async () => {
|
|||
});
|
||||
}
|
||||
|
||||
readPipe.socket.on("data", (data) => {
|
||||
readPipe.socket?.on("data", (data) => {
|
||||
TorrentClient.onSocketData(data);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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,34 @@ 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<number, number>();
|
||||
|
||||
// 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 executablePath = game.executablePath!;
|
||||
const basename = path.win32.basename(executablePath);
|
||||
const basenameWithoutExtension = path.win32.basename(
|
||||
executablePath,
|
||||
path.extname(executablePath)
|
||||
);
|
||||
|
||||
const gameProcess = processes.find((runningProcess) => {
|
||||
if (process.platform === "win32") {
|
||||
return runningProcess.name === basename;
|
||||
}
|
||||
|
|
@ -41,7 +47,7 @@ export const startProcessWatcher = async () => {
|
|||
|
||||
if (gameProcess) {
|
||||
if (gamesPlaytime.has(game.id)) {
|
||||
const zero = gamesPlaytime.get(game.id);
|
||||
const zero = gamesPlaytime.get(game.id) ?? 0;
|
||||
const delta = performance.now() - zero;
|
||||
|
||||
if (WindowManager.mainWindow) {
|
||||
|
|
@ -55,26 +61,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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
import type { Repack } from "@main/entity";
|
||||
import { repackRepository } from "@main/repository";
|
||||
|
||||
import type { GameRepack } from "@types";
|
||||
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||
|
||||
export type GameRepackInput = Omit<
|
||||
GameRepack,
|
||||
"id" | "repackerFriendlyName" | "createdAt" | "updatedAt"
|
||||
>;
|
||||
|
||||
export const savePage = async (repacks: GameRepackInput[]) =>
|
||||
export const savePage = async (repacks: QueryDeepPartialEntity<Repack>[]) =>
|
||||
Promise.all(
|
||||
repacks.map((repack) => repackRepository.insert(repack).catch(() => {}))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,11 +31,12 @@ const formatXatabDownloadSize = (str: string) =>
|
|||
const getXatabRepack = async (url: string) => {
|
||||
const data = await requestWebPage(url);
|
||||
const { window } = new JSDOM(data);
|
||||
const { document } = window;
|
||||
|
||||
const $uploadDate = window.document.querySelector(".entry__date");
|
||||
const $size = window.document.querySelector(".entry__info-size");
|
||||
const $uploadDate = document.querySelector(".entry__date");
|
||||
const $size = document.querySelector(".entry__info-size");
|
||||
|
||||
const $downloadButton = window.document.querySelector(
|
||||
const $downloadButton = document.querySelector(
|
||||
".download-torrent"
|
||||
) as HTMLAnchorElement;
|
||||
|
||||
|
|
@ -74,8 +75,10 @@ export const getNewRepacksFromXatab = async (
|
|||
...repack,
|
||||
page,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error(err.message, { method: "getNewRepacksFromXatab" });
|
||||
} catch (err: unknown) {
|
||||
logger.error((err as Error).message, {
|
||||
method: "getNewRepacksFromXatab",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ export const requestSteam250 = async (path: string) => {
|
|||
const steamGameUrl = ($title as HTMLAnchorElement).href;
|
||||
|
||||
return {
|
||||
title: $title.textContent,
|
||||
objectID: steamGameUrl.split("/").pop(),
|
||||
title: $title.textContent!,
|
||||
objectID: steamGameUrl.split("/").pop()!,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export class TorrentClient {
|
|||
const commonArgs = [BITTORRENT_PORT, writePipePath, readPipePath];
|
||||
|
||||
if (app.isPackaged) {
|
||||
const binaryName = binaryNameByPlatform[process.platform];
|
||||
const binaryName = binaryNameByPlatform[process.platform]!;
|
||||
const binaryPath = path.join(
|
||||
process.resourcesPath,
|
||||
"hydra-download-manager",
|
||||
|
|
@ -133,7 +133,7 @@ export class TorrentClient {
|
|||
relations: { repack: true },
|
||||
});
|
||||
|
||||
if (game.progress === 1) {
|
||||
if (game?.progress === 1) {
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
|
@ -153,7 +153,7 @@ export class TorrentClient {
|
|||
}
|
||||
}
|
||||
|
||||
if (WindowManager.mainWindow) {
|
||||
if (WindowManager.mainWindow && game) {
|
||||
const progress = this.getGameProgress(game);
|
||||
WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue