Merge branch 'main' into build/win-portable-release

# Conflicts:
#	.github/workflows/build.yml
This commit is contained in:
Zamitto
2024-06-08 21:51:46 -03:00
121 changed files with 2883 additions and 2219 deletions

View File

@@ -1,95 +1,36 @@
import { formatName, getSteamAppAsset, repackerFormatter } from "@main/helpers";
import type { CatalogueCategory, CatalogueEntry, GameShop } from "@types";
import { getSteamAppAsset } from "@main/helpers";
import type { CatalogueEntry, GameShop } from "@types";
import { stateManager } from "@main/state-manager";
import { searchGames, searchRepacks } from "../helpers/search-games";
import { registerEvent } from "../register-event";
import { requestSteam250 } from "@main/services";
const repacks = stateManager.getValue("repacks");
const getStringForLookup = (index: number): string => {
const repack = repacks[index];
const formatter =
repackerFormatter[repack.repacker as keyof typeof repackerFormatter];
return formatName(formatter(repack.title));
};
import { RepacksManager, requestSteam250 } from "@main/services";
import { formatName } from "@shared";
const resultSize = 12;
const getCatalogue = async (
_event: Electron.IpcMainInvokeEvent,
category: CatalogueCategory
) => {
if (!repacks.length) return [];
if (category === "trending") {
return getTrendingCatalogue(resultSize);
}
return getRecentlyAddedCatalogue(resultSize);
};
const getTrendingCatalogue = async (
resultSize: number
): Promise<CatalogueEntry[]> => {
const results: CatalogueEntry[] = [];
const getCatalogue = async (_event: Electron.IpcMainInvokeEvent) => {
const trendingGames = await requestSteam250("/90day");
for (
let i = 0;
i < trendingGames.length && results.length < resultSize;
i++
) {
if (!trendingGames[i]) continue;
const { title, objectID } = trendingGames[i]!;
const repacks = searchRepacks(title);
if (title && repacks.length) {
const catalogueEntry = {
objectID,
title,
shop: "steam" as GameShop,
cover: getSteamAppAsset("library", objectID),
};
results.push({ ...catalogueEntry, repacks });
}
}
return results;
};
const getRecentlyAddedCatalogue = async (
resultSize: number
): Promise<CatalogueEntry[]> => {
const results: CatalogueEntry[] = [];
for (let i = 0; results.length < resultSize; i++) {
const stringForLookup = getStringForLookup(i);
if (!stringForLookup) {
for (let i = 0; i < resultSize; i++) {
if (!trendingGames[i]) {
i++;
continue;
}
const games = searchGames({ query: stringForLookup });
const { title, objectID } = trendingGames[i]!;
const repacks = RepacksManager.search({ query: formatName(title) });
for (const game of games) {
const isAlreadyIncluded = results.some(
(result) => result.objectID === game?.objectID
);
const catalogueEntry = {
objectID,
title,
shop: "steam" as GameShop,
cover: getSteamAppAsset("library", objectID),
};
if (!game || !game.repacks.length || isAlreadyIncluded) {
continue;
}
results.push(game);
}
results.push({ ...catalogueEntry, repacks });
}
return results.slice(0, resultSize);
return results;
};
registerEvent("getCatalogue", getCatalogue);

View File

@@ -4,9 +4,9 @@ import { getSteamAppDetails } from "@main/services";
import type { ShopDetails, GameShop, SteamAppDetails } from "@types";
import { registerEvent } from "../register-event";
import { stateManager } from "@main/state-manager";
import { steamGamesWorker } from "@main/workers";
const getLocalizedSteamAppDetails = (
const getLocalizedSteamAppDetails = async (
objectID: string,
language: string
): Promise<ShopDetails | null> => {
@@ -14,20 +14,22 @@ const getLocalizedSteamAppDetails = (
return getSteamAppDetails(objectID, language);
}
return getSteamAppDetails(objectID, language).then((localizedAppDetails) => {
const steamGame = stateManager
.getValue("steamGames")
.find((game) => game.id === Number(objectID));
return getSteamAppDetails(objectID, language).then(
async (localizedAppDetails) => {
const steamGame = await steamGamesWorker.run(Number(objectID), {
name: "getById",
});
if (steamGame && localizedAppDetails) {
return {
...localizedAppDetails,
name: steamGame.name,
};
if (steamGame && localizedAppDetails) {
return {
...localizedAppDetails,
name: steamGame.name,
};
}
return null;
}
return null;
});
);
};
const getGameShopDetails = async (

View File

@@ -1,39 +1,28 @@
import type { CatalogueEntry, GameShop } from "@types";
import type { CatalogueEntry } from "@types";
import { registerEvent } from "../register-event";
import { searchRepacks } from "../helpers/search-games";
import { stateManager } from "@main/state-manager";
import { getSteamAppAsset } from "@main/helpers";
const steamGames = stateManager.getValue("steamGames");
import { steamGamesWorker } from "@main/workers";
import { convertSteamGameToCatalogueEntry } from "../helpers/search-games";
import { RepacksManager } from "@main/services";
const getGames = async (
_event: Electron.IpcMainInvokeEvent,
take = 12,
cursor = 0
): Promise<{ results: CatalogueEntry[]; cursor: number }> => {
const results: CatalogueEntry[] = [];
const steamGames = await steamGamesWorker.run(
{ limit: take, offset: cursor },
{ name: "list" }
);
let i = 0 + cursor;
const entries = RepacksManager.findRepacksForCatalogueEntries(
steamGames.map((game) => convertSteamGameToCatalogueEntry(game))
);
while (results.length < take) {
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, cursor: i };
return {
results: entries,
cursor: cursor + entries.length,
};
};
registerEvent("getGames", getGames);

View File

@@ -3,21 +3,34 @@ import { shuffle } from "lodash-es";
import { getSteam250List } from "@main/services";
import { registerEvent } from "../register-event";
import { searchGames, searchRepacks } from "../helpers/search-games";
import { searchSteamGames } from "../helpers/search-games";
import type { Steam250Game } from "@types";
const state = { games: Array<Steam250Game>(), index: 0 };
const filterGames = async (games: Steam250Game[]) => {
const results: Steam250Game[] = [];
for (const game of games) {
const catalogue = await searchSteamGames({ query: game.title });
if (catalogue.length) {
const [steamGame] = catalogue;
if (steamGame.repacks.length) {
results.push(game);
}
}
}
return results;
};
const getRandomGame = async (_event: Electron.IpcMainInvokeEvent) => {
if (state.games.length == 0) {
const steam250List = await getSteam250List();
const filteredSteam250List = steam250List.filter((game) => {
const repacks = searchRepacks(game.title);
const catalogue = searchGames({ query: game.title });
return repacks.length && catalogue.length;
});
const filteredSteam250List = await filterGames(steam250List);
state.games = shuffle(filteredSteam250List);
}

View File

@@ -1,11 +1,9 @@
import { searchRepacks } from "../helpers/search-games";
import { RepacksManager } from "@main/services";
import { registerEvent } from "../register-event";
const searchGameRepacks = (
_event: Electron.IpcMainInvokeEvent,
query: string
) => {
return searchRepacks(query);
};
) => RepacksManager.search({ query });
registerEvent("searchGameRepacks", searchGameRepacks);

View File

@@ -1,12 +1,10 @@
import { registerEvent } from "../register-event";
import { searchGames } from "../helpers/search-games";
import { searchSteamGames } from "../helpers/search-games";
import { CatalogueEntry } from "@types";
const searchGamesEvent = async (
_event: Electron.IpcMainInvokeEvent,
query: string
): Promise<CatalogueEntry[]> => {
return searchGames({ query, take: 12 });
};
): Promise<CatalogueEntry[]> => searchSteamGames({ query, limit: 12 });
registerEvent("searchGames", searchGamesEvent);

View File

@@ -0,0 +1,42 @@
import { registerEvent } from "../register-event";
import { dataSource } from "@main/data-source";
import { DownloadSource } from "@main/entity";
import axios from "axios";
import { downloadSourceSchema } from "../helpers/validators";
import { insertDownloadsFromSource } from "@main/helpers";
import { RepacksManager } from "@main/services";
const addDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
url: string
) => {
const response = await axios.get(url);
const source = downloadSourceSchema.parse(response.data);
const downloadSource = await dataSource.transaction(
async (transactionalEntityManager) => {
const downloadSource = await transactionalEntityManager
.getRepository(DownloadSource)
.save({
url,
name: source.name,
downloadCount: source.downloads.length,
});
await insertDownloadsFromSource(
transactionalEntityManager,
downloadSource,
source.downloads
);
return downloadSource;
}
);
await RepacksManager.updateRepacks();
return downloadSource;
};
registerEvent("addDownloadSource", addDownloadSource);

View File

@@ -0,0 +1,16 @@
import { downloadSourceRepository } from "@main/repository";
import { registerEvent } from "../register-event";
const getDownloadSources = async (_event: Electron.IpcMainInvokeEvent) => {
return downloadSourceRepository
.createQueryBuilder("downloadSource")
.leftJoin("downloadSource.repacks", "repacks")
.orderBy("downloadSource.createdAt", "DESC")
.loadRelationCountAndMap(
"downloadSource.repackCount",
"downloadSource.repacks"
)
.getMany();
};
registerEvent("getDownloadSources", getDownloadSources);

View File

@@ -0,0 +1,13 @@
import { downloadSourceRepository } from "@main/repository";
import { registerEvent } from "../register-event";
import { RepacksManager } from "@main/services";
const removeDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
id: number
) => {
await downloadSourceRepository.delete(id);
await RepacksManager.updateRepacks();
};
registerEvent("removeDownloadSource", removeDownloadSource);

View File

@@ -0,0 +1,7 @@
import { registerEvent } from "../register-event";
import { fetchDownloadSourcesAndUpdate } from "@main/helpers";
const syncDownloadSources = async (_event: Electron.IpcMainInvokeEvent) =>
fetchDownloadSourcesAndUpdate();
registerEvent("syncDownloadSources", syncDownloadSources);

View File

@@ -0,0 +1,34 @@
import { registerEvent } from "../register-event";
import axios from "axios";
import { downloadSourceRepository } from "@main/repository";
import { downloadSourceSchema } from "../helpers/validators";
import { RepacksManager } from "@main/services";
const validateDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
url: string
) => {
const response = await axios.get(url);
const source = downloadSourceSchema.parse(response.data);
const existingSource = await downloadSourceRepository.findOne({
where: { url },
});
if (existingSource)
throw new Error("Source with the same url already exists");
const repacks = RepacksManager.repacks;
const existingUris = source.downloads
.flatMap((download) => download.uris)
.filter((uri) => repacks.some((repack) => repack.magnet === uri));
return {
name: source.name,
downloadCount: source.downloads.length - existingUris.length,
};
};
registerEvent("validateDownloadSource", validateDownloadSource);

View File

@@ -1,40 +1,11 @@
import flexSearch from "flexsearch";
import { orderBy } from "lodash-es";
import flexSearch from "flexsearch";
import type { GameRepack, GameShop, CatalogueEntry } from "@types";
import type { GameShop, CatalogueEntry, SteamGame } from "@types";
import { formatName, getSteamAppAsset, repackerFormatter } from "@main/helpers";
import { stateManager } from "@main/state-manager";
const { Index } = flexSearch;
const repacksIndex = new Index();
const steamGamesIndex = new Index({ tokenize: "forward" });
const repacks = stateManager.getValue("repacks");
const steamGames = stateManager.getValue("steamGames");
for (let i = 0; i < repacks.length; i++) {
const repack = repacks[i];
const formatter =
repackerFormatter[repack.repacker as keyof typeof repackerFormatter];
repacksIndex.add(i, formatName(formatter(repack.title)));
}
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))
.map((index) => repacks.at(index as number)!),
["uploadDate"],
"desc"
);
};
import { getSteamAppAsset } from "@main/helpers";
import { steamGamesWorker } from "@main/workers";
import { RepacksManager } from "@main/services";
export interface SearchGamesArgs {
query?: string;
@@ -42,27 +13,29 @@ export interface SearchGamesArgs {
skip?: number;
}
export const searchGames = ({
query,
take,
skip,
}: SearchGamesArgs): CatalogueEntry[] => {
const results = steamGamesIndex
.search(formatName(query || ""), { limit: take, offset: skip })
.map((index) => {
const result = steamGames.at(index as number)!;
export const convertSteamGameToCatalogueEntry = (
game: SteamGame
): CatalogueEntry => ({
objectID: String(game.id),
title: game.name,
shop: "steam" as GameShop,
cover: getSteamAppAsset("library", String(game.id)),
repacks: [],
});
return {
objectID: String(result.id),
title: result.name,
shop: "steam" as GameShop,
cover: getSteamAppAsset("library", String(result.id)),
repacks: searchRepacks(result.name),
};
});
export const searchSteamGames = async (
options: flexSearch.SearchOptions
): Promise<CatalogueEntry[]> => {
const steamGames = (await steamGamesWorker.run(options, {
name: "search",
})) as SteamGame[];
const result = RepacksManager.findRepacksForCatalogueEntries(
steamGames.map((game) => convertSteamGameToCatalogueEntry(game))
);
return orderBy(
results,
result,
[({ repacks }) => repacks.length, "repacks"],
["desc"]
);

View File

@@ -0,0 +1,14 @@
import { z } from "zod";
export const downloadSourceSchema = z.object({
name: z.string().max(255),
downloads: z.array(
z.object({
title: z.string().max(255),
downloaders: z.array(z.enum(["real_debrid", "torrent"])),
uris: z.array(z.string()),
uploadDate: z.string().max(255),
fileSize: z.string().max(255),
})
),
});

View File

@@ -10,12 +10,16 @@ import "./catalogue/search-games";
import "./catalogue/search-game-repacks";
import "./hardware/get-disk-free-space";
import "./library/add-game-to-library";
import "./library/create-game-shortcut";
import "./library/close-game";
import "./library/delete-game-folder";
import "./library/get-game-by-object-id";
import "./library/get-library";
import "./library/open-game";
import "./library/open-game-executable-path";
import "./library/open-game-installer";
import "./library/open-game-installer-path";
import "./library/update-executable-path";
import "./library/remove-game";
import "./library/remove-game-from-library";
import "./misc/open-external";
@@ -30,6 +34,11 @@ import "./user-preferences/auto-launch";
import "./autoupdater/check-for-updates";
import "./autoupdater/restart-and-install-update";
import "./user-preferences/authenticate-real-debrid";
import "./download-sources/get-download-sources";
import "./download-sources/validate-download-source";
import "./download-sources/add-download-source";
import "./download-sources/remove-download-source";
import "./download-sources/sync-download-sources";
ipcMain.handle("ping", () => "pong");
ipcMain.handle("getVersion", () => app.getVersion());

View File

@@ -4,14 +4,14 @@ import { registerEvent } from "../register-event";
import type { GameShop } from "@types";
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
import { stateManager } from "@main/state-manager";
import { steamGamesWorker } from "@main/workers";
const addGameToLibrary = async (
_event: Electron.IpcMainInvokeEvent,
objectID: string,
title: string,
shop: GameShop,
executablePath: string | null
shop: GameShop
) => {
return gameRepository
.update(
@@ -21,15 +21,14 @@ const addGameToLibrary = async (
{
shop,
status: null,
executablePath,
isDeleted: false,
}
)
.then(async ({ affected }) => {
if (!affected) {
const steamGame = stateManager
.getValue("steamGames")
.find((game) => game.id === Number(objectID));
const steamGame = await steamGamesWorker.run(Number(objectID), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
@@ -41,7 +40,6 @@ const addGameToLibrary = async (
iconUrl,
objectID,
shop,
executablePath,
})
.then(() => {
if (iconUrl) {

View File

@@ -0,0 +1,29 @@
import { gameRepository } from "@main/repository";
import { registerEvent } from "../register-event";
import { IsNull, Not } from "typeorm";
import createDesktopShortcut from "create-desktop-shortcuts";
const createGameShortcut = async (
_event: Electron.IpcMainInvokeEvent,
id: number
): Promise<boolean> => {
const game = await gameRepository.findOne({
where: { id, executablePath: Not(IsNull()) },
});
if (game) {
const filePath = game.executablePath;
const options = { filePath, name: game.title };
return createDesktopShortcut({
windows: options,
linux: options,
osx: options,
});
}
return false;
};
registerEvent("createGameShortcut", createGameShortcut);

View File

@@ -1,8 +1,6 @@
import path from "node:path";
import fs from "node:fs";
import { In } from "typeorm";
import { gameRepository } from "@main/repository";
import { getDownloadsPath } from "../helpers/get-downloads-path";
@@ -14,11 +12,18 @@ const deleteGameFolder = async (
gameId: number
): Promise<void> => {
const game = await gameRepository.findOne({
where: {
id: gameId,
status: In(["removed", "complete"]),
isDeleted: false,
},
where: [
{
id: gameId,
isDeleted: false,
status: "removed",
},
{
id: gameId,
progress: 1,
isDeleted: false,
},
],
});
if (!game) return;
@@ -30,7 +35,7 @@ const deleteGameFolder = async (
);
if (fs.existsSync(folderPath)) {
return new Promise((resolve, reject) => {
await new Promise<void>((resolve, reject) => {
fs.rm(
folderPath,
{ recursive: true, force: true, maxRetries: 5, retryDelay: 200 },
@@ -40,12 +45,21 @@ const deleteGameFolder = async (
reject();
}
const aria2ControlFilePath = `${folderPath}.aria2`;
if (fs.existsSync(aria2ControlFilePath))
fs.rmSync(aria2ControlFilePath);
resolve();
}
);
});
}
}
await gameRepository.update(
{ id: gameId },
{ downloadPath: null, folderName: null, status: null, progress: 0 }
);
};
registerEvent("deleteGameFolder", deleteGameFolder);

View File

@@ -11,9 +11,6 @@ const getGameByObjectID = async (
objectID,
isDeleted: false,
},
relations: {
repack: true,
},
});
registerEvent("getGameByObjectID", getGameByObjectID);

View File

@@ -1,30 +1,17 @@
import { gameRepository } from "@main/repository";
import { searchRepacks } from "../helpers/search-games";
import { registerEvent } from "../register-event";
import { sortBy } from "lodash-es";
const getLibrary = async () =>
gameRepository
.find({
where: {
isDeleted: false,
},
order: {
createdAt: "desc",
},
relations: {
repack: true,
},
})
.then((games) =>
sortBy(
games.map((game) => ({
...game,
repacks: searchRepacks(game.title),
})),
(game) => (game.status !== "removed" ? 0 : 1)
)
);
gameRepository.find({
where: {
isDeleted: false,
},
relations: {
downloadQueue: true,
},
order: {
createdAt: "desc",
},
});
registerEvent("getLibrary", getLibrary);

View File

@@ -0,0 +1,18 @@
import { shell } from "electron";
import { gameRepository } from "@main/repository";
import { registerEvent } from "../register-event";
const openGameExecutablePath = async (
_event: Electron.IpcMainInvokeEvent,
gameId: number
) => {
const game = await gameRepository.findOne({
where: { id: gameId, isDeleted: false },
});
if (!game || !game.executablePath) return;
shell.showItemInFolder(game.executablePath);
};
registerEvent("openGameExecutablePath", openGameExecutablePath);

View File

@@ -0,0 +1,27 @@
import { shell } from "electron";
import path from "node:path";
import { gameRepository } from "@main/repository";
import { getDownloadsPath } from "../helpers/get-downloads-path";
import { registerEvent } from "../register-event";
const openGameInstallerPath = async (
_event: Electron.IpcMainInvokeEvent,
gameId: number
) => {
const game = await gameRepository.findOne({
where: { id: gameId, isDeleted: false },
});
if (!game || !game.folderName || !game.downloadPath) return true;
const gamePath = path.join(
game.downloadPath ?? (await getDownloadsPath()),
game.folderName!
);
shell.showItemInFolder(gamePath);
return true;
};
registerEvent("openGameInstallerPath", openGameInstallerPath);

View File

@@ -5,7 +5,10 @@ const removeGameFromLibrary = async (
_event: Electron.IpcMainInvokeEvent,
gameId: number
) => {
gameRepository.update({ id: gameId }, { isDeleted: true });
gameRepository.update(
{ id: gameId },
{ isDeleted: true, executablePath: null }
);
};
registerEvent("removeGameFromLibrary", removeGameFromLibrary);

View File

@@ -0,0 +1,20 @@
import { gameRepository } from "@main/repository";
import { registerEvent } from "../register-event";
const updateExecutablePath = async (
_event: Electron.IpcMainInvokeEvent,
id: number,
executablePath: string
) => {
return gameRepository.update(
{
id,
},
{
executablePath,
}
);
};
registerEvent("updateExecutablePath", updateExecutablePath);

View File

@@ -1,25 +1,31 @@
import { gameRepository } from "@main/repository";
import { registerEvent } from "../register-event";
import { DownloadManager } from "@main/services";
import { dataSource } from "@main/data-source";
import { DownloadQueue, Game } from "@main/entity";
const cancelGameDownload = async (
_event: Electron.IpcMainInvokeEvent,
gameId: number
) => {
await DownloadManager.cancelDownload(gameId);
await dataSource.transaction(async (transactionalEntityManager) => {
await DownloadManager.cancelDownload(gameId);
await gameRepository.update(
{
id: gameId,
},
{
status: "removed",
bytesDownloaded: 0,
progress: 0,
}
);
await transactionalEntityManager.getRepository(DownloadQueue).delete({
game: { id: gameId },
});
await transactionalEntityManager.getRepository(Game).update(
{
id: gameId,
},
{
status: "removed",
bytesDownloaded: 0,
progress: 0,
}
);
});
};
registerEvent("cancelGameDownload", cancelGameDownload);

View File

@@ -1,13 +1,24 @@
import { registerEvent } from "../register-event";
import { gameRepository } from "../../repository";
import { DownloadManager } from "@main/services";
import { dataSource } from "@main/data-source";
import { DownloadQueue, Game } from "@main/entity";
const pauseGameDownload = async (
_event: Electron.IpcMainInvokeEvent,
gameId: number
) => {
await DownloadManager.pauseDownload();
await gameRepository.update({ id: gameId }, { status: "paused" });
await dataSource.transaction(async (transactionalEntityManager) => {
await DownloadManager.pauseDownload();
await transactionalEntityManager.getRepository(DownloadQueue).delete({
game: { id: gameId },
});
await transactionalEntityManager
.getRepository(Game)
.update({ id: gameId }, { status: "paused" });
});
};
registerEvent("pauseGameDownload", pauseGameDownload);

View File

@@ -5,7 +5,7 @@ import { gameRepository } from "../../repository";
import { DownloadManager } from "@main/services";
import { dataSource } from "@main/data-source";
import { Game } from "@main/entity";
import { DownloadQueue, Game } from "@main/entity";
const resumeGameDownload = async (
_event: Electron.IpcMainInvokeEvent,
@@ -16,7 +16,6 @@ const resumeGameDownload = async (
id: gameId,
isDeleted: false,
},
relations: { repack: true },
});
if (!game) return;
@@ -31,6 +30,14 @@ const resumeGameDownload = async (
await DownloadManager.resumeDownload(game);
await transactionalEntityManager
.getRepository(DownloadQueue)
.delete({ game: { id: gameId } });
await transactionalEntityManager
.getRepository(DownloadQueue)
.insert({ game: { id: gameId } });
await transactionalEntityManager
.getRepository(Game)
.update({ id: gameId }, { status: "active" });

View File

@@ -1,12 +1,17 @@
import { gameRepository, repackRepository } from "@main/repository";
import {
downloadQueueRepository,
gameRepository,
repackRepository,
} from "@main/repository";
import { registerEvent } from "../register-event";
import type { StartGameDownloadPayload } from "@types";
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
import { DownloadManager } from "@main/services";
import { stateManager } from "@main/state-manager";
import { Not } from "typeorm";
import { steamGamesWorker } from "@main/workers";
const startGameDownload = async (
_event: Electron.IpcMainInvokeEvent,
@@ -20,7 +25,6 @@ const startGameDownload = async (
objectID,
shop,
},
relations: { repack: true },
}),
repackRepository.findOne({
where: {
@@ -49,14 +53,14 @@ const startGameDownload = async (
bytesDownloaded: 0,
downloadPath,
downloader,
repack: { id: repackId },
uri: repack.magnet,
isDeleted: false,
}
);
} else {
const steamGame = stateManager
.getValue("steamGames")
.find((game) => game.id === Number(objectID));
const steamGame = await steamGamesWorker.run(Number(objectID), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
@@ -71,7 +75,7 @@ const startGameDownload = async (
shop,
status: "active",
downloadPath,
repack: { id: repackId },
uri: repack.magnet,
})
.then((result) => {
if (iconUrl) {
@@ -88,9 +92,11 @@ const startGameDownload = async (
where: {
objectID,
},
relations: { repack: true },
});
await downloadQueueRepository.delete({ game: { id: updatedGame!.id } });
await downloadQueueRepository.insert({ game: { id: updatedGame!.id } });
await DownloadManager.startDownload(updatedGame!);
};