This commit is contained in:
Hachi-R 2024-12-22 06:58:20 -03:00
parent 1a286df3f7
commit fd5b2e08a5
14 changed files with 31 additions and 87 deletions

View File

@ -1,3 +1,2 @@
MAIN_VITE_API_URL=API_URL MAIN_VITE_API_URL=API_URL
MAIN_VITE_AUTH_URL=AUTH_URL MAIN_VITE_AUTH_URL=AUTH_URL
RENDERER_VITE_INTERCOM_APP_ID=YOUR_APP_ID

View File

@ -3,3 +3,4 @@ dist
out out
.gitignore .gitignore
migration.stub migration.stub
hydra-python-rpc/

View File

@ -31,7 +31,7 @@ jobs:
run: pip install -r requirements.txt run: pip install -r requirements.txt
- name: Build with cx_Freeze - name: Build with cx_Freeze
run: python torrent-client/setup.py build run: python python_rpc/setup.py build
- name: Build Linux - name: Build Linux
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'

5
.gitignore vendored
View File

@ -1,6 +1,5 @@
.vscode/ .vscode/
node_modules/ node_modules/
hydra-download-manager/
fastlist.exe fastlist.exe
__pycache__ __pycache__
dist dist
@ -9,4 +8,6 @@ out
*.log* *.log*
.env .env
.vite .vite
ludusavi/ ludusavi/
hydra-python-rpc/
aria2/

Binary file not shown.

View File

@ -3,8 +3,9 @@ productName: Hydra
directories: directories:
buildResources: build buildResources: build
extraResources: extraResources:
- aria2
- ludusavi - ludusavi
- hydra-download-manager - hydra-python-rpc
- seeds - seeds
- from: node_modules/create-desktop-shortcuts/src/windows.vbs - from: node_modules/create-desktop-shortcuts/src/windows.vbs
- from: resources/achievement.wav - from: resources/achievement.wav

View File

@ -68,7 +68,7 @@ def process_list():
if auth_error: if auth_error:
return auth_error return auth_error
process_list = [proc.info for proc in psutil.process_iter(['exe', 'pid', 'username'])] process_list = [proc.info for proc in psutil.process_iter(['exe', 'pid', 'name'])]
return jsonify(process_list), 200 return jsonify(process_list), 200
@app.route("/profile-image", methods=["POST"]) @app.route("/profile-image", methods=["POST"])

View File

@ -128,7 +128,7 @@ class TorrentDownloader:
self.torrent_handle = None self.torrent_handle = None
def get_download_status(self): def get_download_status(self):
if self.torrent_handle == None: if self.torrent_handle is None:
return None return None
status = self.torrent_handle.status() status = self.torrent_handle.status()

View File

@ -76,7 +76,12 @@ const downloadAria2WindowsAndLinux = async () => {
await exec(`npx extract-zip ${file}`); await exec(`npx extract-zip ${file}`);
console.log("Extracted. Renaming folder..."); console.log("Extracted. Renaming folder...");
fs.renameSync(file.replace(".zip", ""), "aria2"); fs.mkdirSync("aria2");
fs.copyFileSync(
path.join(file.replace(".zip", ""), "aria2c.exe"),
"aria2/aria2c.exe"
);
fs.rmSync(file.replace(".zip", ""), { recursive: true });
} else { } else {
await exec(`tar --zstd -xvf ${file} usr/bin/aria2c`); await exec(`tar --zstd -xvf ${file} usr/bin/aria2c`);
console.log("Extracted. Copying binary file..."); console.log("Extracted. Copying binary file...");
@ -106,13 +111,6 @@ const copyAria2Macos = async () => {
await exec(`cp $(which aria2c) aria2/aria2c`); await exec(`cp $(which aria2c) aria2/aria2c`);
}; };
if (process.platform === "win32") {
fs.copyFileSync(
"node_modules/ps-list/vendor/fastlist-0.3.0-x64.exe",
"fastlist.exe"
);
}
if (process.platform == "darwin") { if (process.platform == "darwin") {
copyAria2Macos(); copyAria2Macos();
} else { } else {

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,8 @@ import { registerEvent } from "../register-event";
import { logger } from "@main/services"; import { logger } from "@main/services";
import sudo from "sudo-prompt"; import sudo from "sudo-prompt";
import { app } from "electron"; import { app } from "electron";
import { PythonRPC } from "@main/services/python-rpc";
import { ProcessPayload } from "@main/services/download/types";
const getKillCommand = (pid: number) => { const getKillCommand = (pid: number) => {
if (process.platform == "win32") { if (process.platform == "win32") {
@ -16,8 +18,10 @@ const closeGame = async (
_event: Electron.IpcMainInvokeEvent, _event: Electron.IpcMainInvokeEvent,
gameId: number gameId: number
) => { ) => {
// const processes = await PythonInstance.getProcessList(); const processes =
const processes = []; (await PythonRPC.rpc.get<ProcessPayload[] | null>("/process-list")).data ||
[];
const game = await gameRepository.findOne({ const game = await gameRepository.findOne({
where: { id: gameId, isDeleted: false }, where: { id: gameId, isDeleted: false },
}); });

View File

@ -20,7 +20,7 @@ export class Aria2 {
"--file-allocation=none", "--file-allocation=none",
"--allow-overwrite=true", "--allow-overwrite=true",
], ],
{ stdio: "inherit" } { stdio: "inherit", windowsHide: true }
); );
console.log(this.process); console.log(this.process);

View File

@ -28,7 +28,7 @@ export interface LibtorrentPayload {
} }
export interface ProcessPayload { export interface ProcessPayload {
exe: string; exe: string | null;
pid: number; pid: number;
name: string; name: string;
} }

View File

@ -2,10 +2,11 @@ import { gameRepository } from "@main/repository";
import { WindowManager } from "./window-manager"; import { WindowManager } from "./window-manager";
import { createGame, updateGamePlaytime } from "./library-sync"; import { createGame, updateGamePlaytime } from "./library-sync";
import type { GameRunning } from "@types"; import type { GameRunning } from "@types";
// import { PythonInstance } from "./download"; import { PythonRPC } from "./python-rpc";
import { Game } from "@main/entity"; import { Game } from "@main/entity";
import axios from "axios"; import axios from "axios";
import { exec } from "child_process"; import { exec } from "child_process";
import { ProcessPayload } from "./download/types";
const commands = { const commands = {
findWineDir: `lsof -c wine 2>/dev/null | grep '/drive_c/windows$' | head -n 1 | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`, findWineDir: `lsof -c wine 2>/dev/null | grep '/drive_c/windows$' | head -n 1 | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`,
@ -88,12 +89,14 @@ const findGamePathByProcess = (
}; };
const getSystemProcessMap = async () => { const getSystemProcessMap = async () => {
const processes = await PythonInstance.getProcessList(); const processes =
(await PythonRPC.rpc.get<ProcessPayload[] | null>("/process-list")).data ||
[];
const map = new Map<string, Set<string>>(); const map = new Map<string, Set<string>>();
processes.forEach((process) => { processes.forEach((process) => {
const key = process.name.toLowerCase(); const key = process.name?.toLowerCase();
const value = process.exe; const value = process.exe;
if (!key || !value) return; if (!key || !value) return;
@ -244,23 +247,7 @@ function onTickGame(game: Game) {
}) })
.catch(() => {}); .catch(() => {});
} }
}; }
const onOpenGame = (game: Game) => {
const now = performance.now();
gamesPlaytime.set(game.id, {
lastTick: now,
firstTick: now,
lastSyncTick: now,
});
if (game.remoteId) {
updateGamePlaytime(game, 0, new Date()).catch(() => {});
} else {
createGame({ ...game, lastTimePlayed: new Date() }).catch(() => {});
}
};
const onCloseGame = (game: Game) => { const onCloseGame = (game: Game) => {
const gamePlaytime = gamesPlaytime.get(game.id)!; const gamePlaytime = gamesPlaytime.get(game.id)!;
@ -276,50 +263,3 @@ const onCloseGame = (game: Game) => {
createGame(game).catch(() => {}); createGame(game).catch(() => {});
} }
}; };
export const watchProcesses = async () => {
const games = await gameRepository.find({
where: {
executablePath: Not(IsNull()),
isDeleted: false,
},
});
if (games.length === 0) return;
// const processes = await PythonInstance.getProcessList();
const processes = [];
const processSet = new Set(processes.map((process) => process.exe));
for (const game of games) {
const executablePath = game.executablePath!;
const gameProcess = processSet.has(executablePath);
if (gameProcess) {
if (gamesPlaytime.has(game.id)) {
onGameTick(game);
} else {
onOpenGame(game);
}
} else if (gamesPlaytime.has(game.id)) {
onCloseGame(game);
}
}
currentTick++;
if (WindowManager.mainWindow) {
const gamesRunning = Array.from(gamesPlaytime.entries()).map((entry) => {
return {
id: entry[0],
sessionDurationInMillis: performance.now() - entry[1].firstTick,
};
});
WindowManager.mainWindow.webContents.send(
"on-games-running",
gamesRunning as Pick<GameRunning, "id" | "sessionDurationInMillis">[]
);
}
};