From bed5bc353ad30858cc174467c59084f30e1f18ce Mon Sep 17 00:00:00 2001
From: Jozen
Date: Thu, 21 Nov 2019 19:09:02 +0800
Subject: [PATCH] Save grids, heroes when importing
---
package-lock.json | 27 ++++---
package.json | 3 +-
src/js/Components/Import/ImportList.jsx | 4 +-
src/js/Import.jsx | 102 ++++++++++++++++++++----
src/js/Search.jsx | 7 +-
src/js/Steam.js | 42 +++++-----
6 files changed, 131 insertions(+), 54 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index ea6a3dc..91caeab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7260,6 +7260,11 @@
"type-check": "~0.3.2"
}
},
+ "lnf": {
+ "version": "1.3.9",
+ "resolved": "https://registry.npmjs.org/lnf/-/lnf-1.3.9.tgz",
+ "integrity": "sha512-XKlRuyNZcWg7jmGaYzj1bfCs/PIgVyBB13YUnOZ/QKLzWdwKGsGx7kXO1PPymm/hijuNoi9bSSv/Oz6frh8DsA=="
+ },
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
@@ -9311,19 +9316,19 @@
}
},
"request-promise-core": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
- "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
+ "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
"requires": {
- "lodash": "^4.17.11"
+ "lodash": "^4.17.15"
}
},
"request-promise-native": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
- "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
+ "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
"requires": {
- "request-promise-core": "1.1.2",
+ "request-promise-core": "1.1.3",
"stealthy-require": "^1.1.1",
"tough-cookie": "^2.3.3"
}
@@ -9963,9 +9968,9 @@
}
},
"steamgriddb": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/steamgriddb/-/steamgriddb-1.3.0.tgz",
- "integrity": "sha512-i8IdqQOmA15hKXz76PKzuTdLBHxkrC9oEpURI2LBD0mqS5IBC2Jatv01dmCXWvZqkyhXODQZlmKGyDZaGZHxgg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/steamgriddb/-/steamgriddb-1.3.1.tgz",
+ "integrity": "sha512-+PTvAQhbK8BmamvggTrAi+Qm/L+x9m7hJv3+LWkKUI/GEqdzm4gom8nPKvg4ZH//LzrYWhoAJLqXA7mKwHGI5Q==",
"requires": {
"request": "^2.88.0",
"request-promise-native": "^1.0.7"
diff --git a/package.json b/package.json
index 5cb3a80..d7c6d89 100644
--- a/package.json
+++ b/package.json
@@ -95,6 +95,7 @@
"iconv-lite": "^0.5.0",
"js-yaml": "^3.13.1",
"jsonminify": "^0.4.1",
+ "lnf": "^1.3.9",
"lodash": "^4.17.15",
"metrohash": "^2.6.0",
"promise-reflect": "^1.1.0",
@@ -112,7 +113,7 @@
"react-uwp": "^1.2.31",
"steam-categories": "^1.1.0",
"steam-shortcut-editor": "^3.1.1",
- "steamgriddb": "^1.3.0",
+ "steamgriddb": "^1.3.1",
"steamid": "^1.1.3",
"winreg": "^1.2.4",
"xml-js": "^1.6.11"
diff --git a/src/js/Components/Import/ImportList.jsx b/src/js/Components/Import/ImportList.jsx
index bf1a903..28d11e8 100644
--- a/src/js/Components/Import/ImportList.jsx
+++ b/src/js/Components/Import/ImportList.jsx
@@ -37,8 +37,8 @@ class ImportList extends React.Component {
}
let thumb;
- if (this.grids[i].length > 0) {
- thumb = this.grids[i][0].thumb;
+ if (this.grids[i]) {
+ thumb = this.grids[i].thumb;
}
return (
diff --git a/src/js/Import.jsx b/src/js/Import.jsx
index ef403fd..8058ff0 100644
--- a/src/js/Import.jsx
+++ b/src/js/Import.jsx
@@ -12,6 +12,8 @@ const Store = window.require('electron-store');
const SGDB = window.require('steamgriddb');
const { metrohash64 } = window.require('metrohash');
const log = window.require('electron-log');
+const { join, extname, dirname } = window.require('path');
+const Lnf = window.require('lnf');
class Import extends React.Component {
constructor(props) {
@@ -28,6 +30,8 @@ class Import extends React.Component {
class: platformModules[key].default,
games: [],
grids: [],
+ posters: [],
+ heroes: [],
installed: false,
error: false,
}));
@@ -72,22 +76,7 @@ class Import extends React.Component {
// Get grids for each platform
const ids = platform.games.map((x) => encodeURIComponent(x.id));
const getGrids = this.SGDB.getGrids({ type: platform.id, id: ids.join(',') }).then((res) => {
- let formatted;
- // if only single id then return first grid
- if (ids.length === 1) {
- if (res.length > 0) {
- formatted = [[res[0]]];
- }
- } else {
- // if multiple ids treat each object as a request
- formatted = res.map((x) => {
- if (x.success) {
- return x.data;
- }
- return false;
- });
- }
- platform.grids = formatted;
+ platform.grids = this._formatResponse(ids, res);
}).catch(() => {
// show an error toast
});
@@ -115,6 +104,26 @@ class Import extends React.Component {
this.store.set('games', gamesStorage);
}
+ // @todo this is horrible but can't be arsed right now
+ _formatResponse(ids, res) {
+ let formatted = false;
+ // if only single id then return first grid
+ if (ids.length === 1) {
+ if (res.length > 0) {
+ formatted = [res[0]];
+ }
+ } else {
+ // if multiple ids treat each object as a request
+ formatted = res.map((x) => {
+ if (x.success) {
+ if (x.data[0]) return x.data[0];
+ }
+ return false;
+ });
+ }
+ return formatted;
+ }
+
addGames(games, platform) {
this.saveImportedGames(games);
@@ -142,6 +151,67 @@ class Import extends React.Component {
),
});
+ }).then(() => {
+ // Download images
+ PubSub.publish('toast', {
+ logoNode: 'Download',
+ title: 'Downloading Images...',
+ contents: (Downloading images for imported games...
),
+ });
+
+ const ids = games.map((x) => encodeURIComponent(x.id));
+ let posters = [];
+ let heroes = [];
+
+ // Get posters
+ const getPosters = this.SGDB.getGrids({ type: platform.id, id: ids.join(','), dimensions: ['600x900'] }).then((res) => {
+ posters = this._formatResponse(ids, res);
+ }).catch(() => {
+ // show an error toast
+ });
+
+ // Get heroes
+ const getHeroes = this.SGDB.getHeroes({ type: platform.id, id: ids.join(',') }).then((res) => {
+ heroes = this._formatResponse(ids, res);
+ }).catch(() => {
+ // show an error toast
+ });
+
+ Promise.all([getPosters, getHeroes]).then(() => {
+ const downloadPromises = [];
+ games.forEach((game, i) => {
+ const appId = Steam.generateNewAppId(game.exe, game.name);
+
+ // Take (legacy) grids from when we got them for the ImportList
+ const savedGrid = platform.grids[platform.games.indexOf(games[i])];
+ if (platform.grids[i] && savedGrid) {
+ const appIdOld = Steam.generateAppId(game.exe, game.name);
+ const saveGrids = Steam.addAsset('horizontalGrid', appId, savedGrid.url).then((dest) => {
+ // Symlink to old appid so it works in BPM
+ Lnf.sync(dest, join(dirname(dest), `${appIdOld}${extname(dest)}`));
+ });
+ downloadPromises.push(saveGrids);
+ }
+
+ // Download posters
+ if (posters[i]) {
+ downloadPromises.push(Steam.addAsset('verticalGrid', appId, posters[i].url));
+ }
+
+ // Download heroes
+ if (heroes[i]) {
+ downloadPromises.push(Steam.addAsset('hero', appId, heroes[i].url));
+ }
+ });
+
+ Promise.all(downloadPromises).then(() => {
+ PubSub.publish('toast', {
+ logoNode: 'Download',
+ title: 'Downloadeds Complete',
+ contents: (All Images Downloaded!
),
+ });
+ });
+ });
}).catch((err) => {
if (err.type === 'OpenError') {
PubSub.publish('toast', {
diff --git a/src/js/Search.jsx b/src/js/Search.jsx
index e20beef..033c96c 100644
--- a/src/js/Search.jsx
+++ b/src/js/Search.jsx
@@ -77,12 +77,7 @@ class Search extends React.Component {
}
this.setIsDownloading(true);
- const itemsClone = { ...this.state.items };
- Steam.addGrid(props.appid, props.image, (progress) => {
- this.setState({ downloadProgress: progress });
- itemsClone[props.index].progress = progress;
- this.setState({ itemsClone });
- }).then((dest) => {
+ Steam.addAsset('horizontalGrid', props.appid, props.image).then((dest) => {
this.setImageDownloaded(props.appid, props.name, dest);
}).catch(() => {
this.setIsDownloading(false);
diff --git a/src/js/Steam.js b/src/js/Steam.js
index 7fb5cd1..a3fe6f2 100644
--- a/src/js/Steam.js
+++ b/src/js/Steam.js
@@ -4,7 +4,7 @@ import { crc32 } from 'crc';
const Registry = window.require('winreg');
const Store = window.require('electron-store');
const fs = window.require('fs');
-const { join } = window.require('path');
+const { join, extname } = window.require('path');
const VDF = window.require('@node-steam/vdf');
const shortcut = window.require('steam-shortcut-editor');
const https = window.require('https');
@@ -265,13 +265,6 @@ class Steam {
return image;
}
- static deleteCustomGridImage(userdataGridPath, appid) {
- const imagePath = this.getCustomGridImage(userdataGridPath, appid);
- if (imagePath) {
- fs.unlinkSync(imagePath);
- }
- }
-
static getShortcutFile() {
return new Promise((resolve) => {
this.getSteamPath().then((steamPath) => {
@@ -284,12 +277,27 @@ class Steam {
});
}
- static addGrid(appId, url, onProgress = () => {}) {
+ static addAsset(type, appId, url) {
return new Promise((resolve, reject) => {
this.getCurrentUserGridPath().then((userGridPath) => {
const imageUrl = url;
- const imageExt = imageUrl.substr(imageUrl.lastIndexOf('.') + 1);
- const dest = join(userGridPath, `${appId}.${imageExt}`);
+ const imageExt = extname(imageUrl);
+
+ let dest;
+
+ switch (type) {
+ case 'horizontalGrid':
+ dest = join(userGridPath, `${appId}${imageExt}`);
+ break;
+ case 'verticalGrid':
+ dest = join(userGridPath, `${appId}p${imageExt}`);
+ break;
+ case 'hero':
+ dest = join(userGridPath, `${appId}_hero${imageExt}`);
+ break;
+ default:
+ reject();
+ }
let cur = 0;
const data = new Stream();
@@ -298,21 +306,19 @@ class Steam {
https.get(url, (response) => {
const len = parseInt(response.headers['content-length'], 10);
- response.on('end', () => {
- this.deleteCustomGridImage(userGridPath, appId);
- fs.writeFileSync(dest, data.read());
- resolve(dest);
- });
-
response.on('data', (chunk) => {
cur += chunk.length;
data.push(chunk);
progress = Math.round((cur / len) * 10) / 10;
if (progress !== lastProgress) {
lastProgress = progress;
- onProgress(progress);
}
});
+
+ response.on('end', () => {
+ fs.writeFileSync(dest, data.read());
+ resolve(dest);
+ });
}).on('error', (err) => {
fs.unlink(dest);
reject(err);