mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-01-23 21:44:55 +03:00
feat: sync library
This commit is contained in:
parent
15176a12de
commit
ce13f6aa21
@ -22,6 +22,9 @@ export class Game {
|
||||
@Column("text", { unique: true })
|
||||
objectID: string;
|
||||
|
||||
@Column("text", { unique: true, nullable: true })
|
||||
remoteId: string;
|
||||
|
||||
@Column("text")
|
||||
title: string;
|
||||
|
||||
|
@ -6,6 +6,7 @@ import type { GameShop } from "@types";
|
||||
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
|
||||
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
import { HydraApi } from "@main/services/hydra-api";
|
||||
|
||||
const addGameToLibrary = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@ -49,6 +50,26 @@ const addGameToLibrary = async (
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const game = await gameRepository.findOne({ where: { objectID } });
|
||||
|
||||
HydraApi.post("/games", {
|
||||
objectId: objectID,
|
||||
playTimeInMilliseconds: game?.playTimeInMilliseconds,
|
||||
shop,
|
||||
lastTimePlayed: game?.lastTimePlayed,
|
||||
}).then((response) => {
|
||||
const {
|
||||
id: remoteId,
|
||||
playTimeInMilliseconds,
|
||||
lastTimePlayed,
|
||||
} = response.data;
|
||||
|
||||
gameRepository.update(
|
||||
{ objectID },
|
||||
{ remoteId, playTimeInMilliseconds, lastTimePlayed }
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gameRepository } from "../../repository";
|
||||
import { HydraApi } from "@main/services/hydra-api";
|
||||
|
||||
const removeGameFromLibrary = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@ -9,6 +10,12 @@ const removeGameFromLibrary = async (
|
||||
{ id: gameId },
|
||||
{ isDeleted: true, executablePath: null }
|
||||
);
|
||||
|
||||
const game = await gameRepository.findOne({ where: { id: gameId } });
|
||||
|
||||
if (game?.remoteId) {
|
||||
HydraApi.delete(`/games/${game.remoteId}`);
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("removeGameFromLibrary", removeGameFromLibrary);
|
||||
|
@ -1,15 +1,22 @@
|
||||
import { DownloadManager, RepacksManager, startMainLoop } from "./services";
|
||||
import {
|
||||
DownloadManager,
|
||||
RepacksManager,
|
||||
logger,
|
||||
startMainLoop,
|
||||
} from "./services";
|
||||
import {
|
||||
downloadQueueRepository,
|
||||
gameRepository,
|
||||
repackRepository,
|
||||
userPreferencesRepository,
|
||||
} from "./repository";
|
||||
import { UserPreferences } from "./entity";
|
||||
import { RealDebridClient } from "./services/real-debrid";
|
||||
import { fetchDownloadSourcesAndUpdate } from "./helpers";
|
||||
import { fetchDownloadSourcesAndUpdate, getSteamAppAsset } from "./helpers";
|
||||
import { publishNewRepacksNotifications } from "./services/notifications";
|
||||
import { MoreThan } from "typeorm";
|
||||
import { HydraApi } from "./services/hydra-api";
|
||||
import { steamGamesWorker } from "./workers";
|
||||
|
||||
startMainLoop();
|
||||
|
||||
@ -21,7 +28,69 @@ const loadState = async (userPreferences: UserPreferences | null) => {
|
||||
if (userPreferences?.realDebridApiToken)
|
||||
RealDebridClient.authorize(userPreferences?.realDebridApiToken);
|
||||
|
||||
HydraApi.setupApi();
|
||||
HydraApi.setupApi()
|
||||
.then(async () => {
|
||||
if (HydraApi.isLoggedIn()) {
|
||||
const games = await HydraApi.get("/games");
|
||||
|
||||
for (const game of games.data) {
|
||||
const localGame = await gameRepository.findOne({
|
||||
where: {
|
||||
objectID: game.objectId,
|
||||
},
|
||||
});
|
||||
|
||||
if (localGame) {
|
||||
const updatedLastTimePlayed =
|
||||
localGame.lastTimePlayed == null ||
|
||||
new Date(game.lastTimePlayed) > localGame.lastTimePlayed
|
||||
? new Date(game.lastTimePlayed)
|
||||
: localGame.lastTimePlayed;
|
||||
|
||||
const updatedPlayTime =
|
||||
localGame.playTimeInMilliseconds < game.playTimeInMilliseconds
|
||||
? game.playTimeInMilliseconds
|
||||
: localGame.playTimeInMilliseconds;
|
||||
|
||||
gameRepository.update(
|
||||
{
|
||||
objectID: game.objectId,
|
||||
shop: "steam",
|
||||
lastTimePlayed: updatedLastTimePlayed,
|
||||
playTimeInMilliseconds: updatedPlayTime,
|
||||
},
|
||||
{ remoteId: game.id }
|
||||
);
|
||||
} else {
|
||||
const steamGame = await steamGamesWorker.run(
|
||||
Number(game.objectId),
|
||||
{
|
||||
name: "getById",
|
||||
}
|
||||
);
|
||||
|
||||
if (steamGame) {
|
||||
const iconUrl = steamGame?.clientIcon
|
||||
? getSteamAppAsset("icon", game.objectId, steamGame.clientIcon)
|
||||
: null;
|
||||
|
||||
gameRepository.insert({
|
||||
objectID: game.objectId,
|
||||
title: steamGame?.name,
|
||||
remoteId: game.id,
|
||||
shop: game.shop,
|
||||
iconUrl,
|
||||
lastTimePlayed: game.lastTimePlayed,
|
||||
playTimeInMilliseconds: game.playTimeInMilliseconds,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error("erro api GET: /games", err);
|
||||
});
|
||||
|
||||
const [nextQueueItem] = await downloadQueueRepository.find({
|
||||
order: {
|
||||
|
@ -14,6 +14,10 @@ export class HydraApi {
|
||||
expirationTimestamp: 0,
|
||||
};
|
||||
|
||||
static isLoggedIn() {
|
||||
return this.userAuth.authToken !== "";
|
||||
}
|
||||
|
||||
static async handleExternalAuth(auth: string) {
|
||||
const { payload } = url.parse(auth, true).query;
|
||||
|
||||
@ -140,4 +144,9 @@ export class HydraApi {
|
||||
await this.revalidateAccessTokenIfExpired();
|
||||
return this.instance.patch(url, data, this.getAxiosConfig());
|
||||
}
|
||||
|
||||
static async delete(url: string) {
|
||||
await this.revalidateAccessTokenIfExpired();
|
||||
return this.instance.delete(url, this.getAxiosConfig());
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,12 @@ import { IsNull, Not } from "typeorm";
|
||||
import { gameRepository } from "@main/repository";
|
||||
import { getProcesses } from "@main/helpers";
|
||||
import { WindowManager } from "./window-manager";
|
||||
import { HydraApi } from "./hydra-api";
|
||||
|
||||
const gamesPlaytime = new Map<number, number>();
|
||||
const gamesPlaytime = new Map<
|
||||
number,
|
||||
{ lastTick: number; firstTick: number }
|
||||
>();
|
||||
|
||||
export const watchProcesses = async () => {
|
||||
const games = await gameRepository.find({
|
||||
@ -37,7 +41,9 @@ export const watchProcesses = async () => {
|
||||
|
||||
if (gameProcess) {
|
||||
if (gamesPlaytime.has(game.id)) {
|
||||
const zero = gamesPlaytime.get(game.id) ?? 0;
|
||||
const gamePlaytime = gamesPlaytime.get(game.id)!;
|
||||
|
||||
const zero = gamePlaytime.lastTick;
|
||||
const delta = performance.now() - zero;
|
||||
|
||||
if (WindowManager.mainWindow) {
|
||||
@ -48,12 +54,57 @@ export const watchProcesses = async () => {
|
||||
playTimeInMilliseconds: game.playTimeInMilliseconds + delta,
|
||||
lastTimePlayed: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
gamesPlaytime.set(game.id, performance.now());
|
||||
gamesPlaytime.set(game.id, {
|
||||
...gamePlaytime,
|
||||
lastTick: performance.now(),
|
||||
});
|
||||
} else {
|
||||
if (game.remoteId) {
|
||||
HydraApi.put(`/games/${game.remoteId}`, {
|
||||
playTimeDeltaInMilliseconds: 0,
|
||||
lastTimePlayed: new Date(),
|
||||
});
|
||||
} else {
|
||||
HydraApi.post("/games", {
|
||||
objectId: game.objectID,
|
||||
playTimeInMilliseconds: Math.round(game.playTimeInMilliseconds),
|
||||
shop: game.shop,
|
||||
lastTimePlayed: new Date(),
|
||||
}).then((response) => {
|
||||
const { id: remoteId } = response.data;
|
||||
gameRepository.update({ objectID: game.objectID }, { remoteId });
|
||||
});
|
||||
}
|
||||
|
||||
gamesPlaytime.set(game.id, {
|
||||
lastTick: performance.now(),
|
||||
firstTick: performance.now(),
|
||||
});
|
||||
}
|
||||
} else if (gamesPlaytime.has(game.id)) {
|
||||
const gamePlaytime = gamesPlaytime.get(game.id)!;
|
||||
gamesPlaytime.delete(game.id);
|
||||
|
||||
if (game.remoteId) {
|
||||
HydraApi.put(`/games/${game.remoteId}`, {
|
||||
playTimeInMilliseconds: Math.round(
|
||||
performance.now() - gamePlaytime.firstTick
|
||||
),
|
||||
lastTimePlayed: game.lastTimePlayed,
|
||||
});
|
||||
} else {
|
||||
HydraApi.post("/games", {
|
||||
objectId: game.objectID,
|
||||
playTimeInMilliseconds: Math.round(game.playTimeInMilliseconds),
|
||||
shop: game.shop,
|
||||
lastTimePlayed: game.lastTimePlayed,
|
||||
}).then((response) => {
|
||||
const { id: remoteId } = response.data;
|
||||
gameRepository.update({ objectID: game.objectID }, { remoteId });
|
||||
});
|
||||
}
|
||||
|
||||
if (WindowManager.mainWindow) {
|
||||
WindowManager.mainWindow.webContents.send("on-game-close", game.id);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user