mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
Merge remote-tracking branch 'origin/main' into feat/add-select-folder-modal-in-game-installation
This commit is contained in:
commit
bd2ad383c6
30 changed files with 416 additions and 275 deletions
|
|
@ -23,6 +23,9 @@ export class UserPreferences {
|
|||
@Column("boolean", { default: false })
|
||||
repackUpdatesNotificationsEnabled: boolean;
|
||||
|
||||
@Column("boolean", { default: true })
|
||||
telemetryEnabled: boolean;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,39 @@
|
|||
import type { CatalogueEntry } from "@types";
|
||||
import type { CatalogueEntry, GameShop } from "@types";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { searchGames } from "../helpers/search-games";
|
||||
import slice from "lodash/slice";
|
||||
import { searchRepacks } from "../helpers/search-games";
|
||||
import { stateManager } from "@main/state-manager";
|
||||
import { getSteamAppAsset } from "@main/helpers";
|
||||
|
||||
const steamGames = stateManager.getValue("steamGames");
|
||||
|
||||
const getGames = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
take?: number,
|
||||
prevCursor = 0
|
||||
cursor = 0
|
||||
): Promise<{ results: CatalogueEntry[]; cursor: number }> => {
|
||||
let results: CatalogueEntry[] = [];
|
||||
let i = 0;
|
||||
const results: CatalogueEntry[] = [];
|
||||
|
||||
const batchSize = 100;
|
||||
let i = 0 + cursor;
|
||||
|
||||
while (results.length < take) {
|
||||
const games = await searchGames({
|
||||
take: batchSize,
|
||||
skip: (i + prevCursor) * batchSize,
|
||||
});
|
||||
results = [...results, ...games.filter((game) => game.repacks.length)];
|
||||
const game = steamGames[i];
|
||||
const repacks = searchRepacks(game.name);
|
||||
|
||||
if (repacks.length) {
|
||||
results.push({
|
||||
objectID: String(game.id),
|
||||
title: game.name,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", String(game.id)),
|
||||
repacks,
|
||||
});
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return { results: slice(results, 0, take), cursor: prevCursor + i };
|
||||
return { results, cursor: i };
|
||||
};
|
||||
|
||||
registerEvent(getGames, {
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ import type { GameRepack, GameShop, CatalogueEntry } from "@types";
|
|||
|
||||
import { formatName, getSteamAppAsset, repackerFormatter } from "@main/helpers";
|
||||
import { stateManager } from "@main/state-manager";
|
||||
import { steamGameRepository } from "@main/repository";
|
||||
import { FindManyOptions, Like } from "typeorm";
|
||||
import { SteamGame } from "@main/entity";
|
||||
|
||||
const { Index } = flexSearch;
|
||||
const repacksIndex = new Index();
|
||||
const steamGamesIndex = new Index({ tokenize: "reverse" });
|
||||
|
||||
const repacks = stateManager.getValue("repacks");
|
||||
const steamGames = stateManager.getValue("steamGames");
|
||||
|
||||
for (let i = 0; i < repacks.length; i++) {
|
||||
const repack = repacks[i];
|
||||
|
|
@ -22,9 +21,12 @@ for (let i = 0; i < repacks.length; i++) {
|
|||
repacksIndex.add(i, formatName(formatter(repack.title)));
|
||||
}
|
||||
|
||||
export const searchRepacks = (title: string): GameRepack[] => {
|
||||
const repacks = stateManager.getValue("repacks");
|
||||
for (let i = 0; i < steamGames.length; i++) {
|
||||
const steamGame = steamGames[i];
|
||||
steamGamesIndex.add(i, formatName(steamGame.name));
|
||||
}
|
||||
|
||||
export const searchRepacks = (title: string): GameRepack[] => {
|
||||
return orderBy(
|
||||
repacksIndex
|
||||
.search(formatName(title))
|
||||
|
|
@ -45,34 +47,21 @@ export const searchGames = async ({
|
|||
take,
|
||||
skip,
|
||||
}: SearchGamesArgs): Promise<CatalogueEntry[]> => {
|
||||
const options: FindManyOptions<SteamGame> = {};
|
||||
const results = steamGamesIndex
|
||||
.search(formatName(query || ""), { limit: take, offset: skip })
|
||||
.map((index) => {
|
||||
const result = steamGames.at(index as number)!;
|
||||
|
||||
if (query) {
|
||||
options.where = {
|
||||
name: query ? Like(`%${formatName(query)}%`) : undefined,
|
||||
};
|
||||
}
|
||||
return {
|
||||
objectID: String(result.id),
|
||||
title: result.name,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", String(result.id)),
|
||||
repacks: searchRepacks(result.name),
|
||||
};
|
||||
});
|
||||
|
||||
const steamResults = await steamGameRepository.find({
|
||||
...options,
|
||||
take,
|
||||
skip,
|
||||
order: { name: "ASC" },
|
||||
});
|
||||
|
||||
const results = steamResults.map((result) => ({
|
||||
objectID: String(result.id),
|
||||
title: result.name,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", String(result.id)),
|
||||
}));
|
||||
|
||||
return Promise.all(
|
||||
results.map(async (result) => ({
|
||||
...result,
|
||||
repacks: searchRepacks(result.title),
|
||||
}))
|
||||
).then((resultsWithRepacks) =>
|
||||
return Promise.all(results).then((resultsWithRepacks) =>
|
||||
orderBy(
|
||||
resultsWithRepacks,
|
||||
[({ repacks }) => repacks.length, "repacks"],
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ const addGameToLibrary = async (
|
|||
_event: Electron.IpcMainInvokeEvent,
|
||||
objectID: string,
|
||||
title: string,
|
||||
gameShop: GameShop
|
||||
gameShop: GameShop,
|
||||
executablePath: string
|
||||
) => {
|
||||
const iconUrl = await getImageBase64(await getSteamGameIconUrl(objectID));
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ const addGameToLibrary = async (
|
|||
iconUrl,
|
||||
objectID,
|
||||
shop: gameShop,
|
||||
executablePath,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
getNewRepacksFromCPG,
|
||||
getNewRepacksFromUser,
|
||||
getNewRepacksFromXatab,
|
||||
getNewRepacksFromOnlineFix,
|
||||
// getNewRepacksFromOnlineFix,
|
||||
readPipe,
|
||||
startProcessWatcher,
|
||||
writePipe,
|
||||
|
|
@ -14,6 +14,7 @@ import {
|
|||
gameRepository,
|
||||
repackRepository,
|
||||
repackerFriendlyNameRepository,
|
||||
steamGameRepository,
|
||||
userPreferencesRepository,
|
||||
} from "./repository";
|
||||
import { TorrentClient } from "./services/torrent-client";
|
||||
|
|
@ -78,9 +79,9 @@ const checkForNewRepacks = async () => {
|
|||
getNewRepacksFromCPG(
|
||||
existingRepacks.filter((repack) => repack.repacker === "CPG")
|
||||
),
|
||||
getNewRepacksFromOnlineFix(
|
||||
existingRepacks.filter((repack) => repack.repacker === "onlinefix")
|
||||
),
|
||||
// getNewRepacksFromOnlineFix(
|
||||
// existingRepacks.filter((repack) => repack.repacker === "onlinefix")
|
||||
// ),
|
||||
track1337xUsers(existingRepacks),
|
||||
]).then(() => {
|
||||
repackRepository.count().then((count) => {
|
||||
|
|
@ -104,17 +105,23 @@ const checkForNewRepacks = async () => {
|
|||
};
|
||||
|
||||
const loadState = async () => {
|
||||
const [friendlyNames, repacks] = await Promise.all([
|
||||
const [friendlyNames, repacks, steamGames] = await Promise.all([
|
||||
repackerFriendlyNameRepository.find(),
|
||||
repackRepository.find({
|
||||
order: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
}),
|
||||
steamGameRepository.find({
|
||||
order: {
|
||||
name: "asc",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
stateManager.setValue("repackersFriendlyNames", friendlyNames);
|
||||
stateManager.setValue("repacks", repacks);
|
||||
stateManager.setValue("steamGames", steamGames);
|
||||
|
||||
import("./events");
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import path from "node:path";
|
|||
import { IsNull, Not } from "typeorm";
|
||||
|
||||
import { gameRepository } from "@main/repository";
|
||||
import { GameStatus } from "@main/constants";
|
||||
import { getProcesses } from "@main/helpers";
|
||||
import { WindowManager } from "./window-manager";
|
||||
|
||||
|
|
@ -18,7 +17,6 @@ export const startProcessWatcher = async () => {
|
|||
const games = await gameRepository.find({
|
||||
where: {
|
||||
executablePath: Not(IsNull()),
|
||||
status: GameStatus.Seeding,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -54,15 +52,16 @@ export const startProcessWatcher = async () => {
|
|||
playTimeInMilliseconds: game.playTimeInMilliseconds + delta,
|
||||
});
|
||||
|
||||
gameRepository.update(game.id, {
|
||||
lastTimePlayed: new Date().toUTCString(),
|
||||
});
|
||||
|
||||
gamesPlaytime.set(game.id, performance.now());
|
||||
await sleep(sleepTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
gamesPlaytime.set(game.id, performance.now());
|
||||
gameRepository.update(game.id, {
|
||||
lastTimePlayed: new Date().toUTCString(),
|
||||
});
|
||||
|
||||
await sleep(sleepTime);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ export * from "./1337x";
|
|||
export * from "./xatab";
|
||||
export * from "./cpg-repacks";
|
||||
export * from "./gog";
|
||||
export * from "./online-fix";
|
||||
// export * from "./online-fix";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { Repack } from "@main/entity";
|
|||
import { savePage } from "./helpers";
|
||||
import type { GameRepackInput } from "./helpers";
|
||||
import { logger } from "../logger";
|
||||
import { stringify } from "qs";
|
||||
import parseTorrent, {
|
||||
toMagnetURI,
|
||||
Instance as TorrentInstance,
|
||||
|
|
@ -58,8 +57,12 @@ export const getNewRepacksFromOnlineFix = async (
|
|||
|
||||
if (!preLogin.field || !preLogin.value) return;
|
||||
|
||||
const tokenField = preLogin.field;
|
||||
const tokenValue = preLogin.value;
|
||||
const params = new URLSearchParams({
|
||||
login_name: process.env.ONLINEFIX_USERNAME,
|
||||
login_password: process.env.ONLINEFIX_PASSWORD,
|
||||
login: "submit",
|
||||
[preLogin.field]: preLogin.value,
|
||||
});
|
||||
|
||||
await http
|
||||
.post("https://online-fix.me/", {
|
||||
|
|
@ -69,12 +72,7 @@ export const getNewRepacksFromOnlineFix = async (
|
|||
Origin: "https://online-fix.me",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: stringify({
|
||||
login_name: process.env.ONLINEFIX_USERNAME,
|
||||
login_password: process.env.ONLINEFIX_PASSWORD,
|
||||
login: "submit",
|
||||
[tokenField]: tokenValue,
|
||||
}),
|
||||
body: params.toString(),
|
||||
})
|
||||
.text();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
import type { Repack, RepackerFriendlyName } from "@main/entity";
|
||||
import type { Repack, RepackerFriendlyName, SteamGame } from "@main/entity";
|
||||
|
||||
interface State {
|
||||
repacks: Repack[];
|
||||
repackersFriendlyNames: RepackerFriendlyName[];
|
||||
steamGames: SteamGame[];
|
||||
eventResults: Map<[string, any[]], any>;
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
repacks: [],
|
||||
repackersFriendlyNames: [],
|
||||
steamGames: [],
|
||||
eventResults: new Map(),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue