Merge pull request #2195 from skyhancloud/fix-custom-game-shortcut-icons

fix(library): use custom game icons for generated shortcuts
This commit is contained in:
Zamitto
2026-05-05 06:35:09 -03:00
committed by GitHub
+32 -15
View File
@@ -14,8 +14,13 @@ import { ASSETS_PATH } from "@main/constants";
import { getGameAssets } from "../catalogue/get-game-assets";
import { logger } from "@main/services";
const isValidHttpUrl = (url: string | null | undefined): url is string => {
return !!url && (url.startsWith("http://") || url.startsWith("https://"));
const isValidUrl = (url: string | null | undefined): url is string => {
return (
!!url &&
(url.startsWith("http://") ||
url.startsWith("https://") ||
url.startsWith("local:"))
);
};
const isIcoUrl = (url: string): boolean => {
@@ -27,8 +32,19 @@ const downloadIcon = async (
objectId: string,
iconUrls: (string | null | undefined)[]
): Promise<string | null> => {
const validUrls = iconUrls.filter(isValidUrl);
if (validUrls.length === 0) {
logger.warn("No valid icon URLs found for game shortcut");
return null;
}
const urlHash = Buffer.from(validUrls[0])
.toString("base64")
.replace(/[^a-zA-Z0-9]/g, "")
.substring(0, 16);
const iconDir = path.join(ASSETS_PATH, `${shop}-${objectId}`);
const iconPath = path.join(iconDir, "icon.ico");
const iconPath = path.join(iconDir, `icon-${urlHash}.ico`);
try {
if (fs.existsSync(iconPath)) {
@@ -38,22 +54,22 @@ const downloadIcon = async (
// Ignore fs errors
}
const validUrls = iconUrls.filter(isValidHttpUrl);
if (validUrls.length === 0) {
logger.warn("No valid icon URLs found for game shortcut");
return null;
}
fs.mkdirSync(iconDir, { recursive: true });
for (const iconUrl of validUrls) {
try {
logger.log(`Trying to download icon from: ${iconUrl}`);
const response = await axios.get(iconUrl, {
responseType: "arraybuffer",
});
const imageBuffer = Buffer.from(response.data);
logger.log(`Trying to download/read icon from: ${iconUrl}`);
let imageBuffer: Buffer;
if (iconUrl.startsWith("local:")) {
const localPath = iconUrl.slice("local:".length);
imageBuffer = fs.readFileSync(localPath);
} else {
const response = await axios.get(iconUrl, {
responseType: "arraybuffer",
});
imageBuffer = Buffer.from(response.data);
}
// If source is already ICO, use it directly
if (isIcoUrl(iconUrl)) {
@@ -229,6 +245,7 @@ const createGameShortcut = async (
const assets = shop === "custom" ? null : await getGameAssets(objectId, shop);
const iconPath = await downloadIcon(shop, objectId, [
game.customIconUrl,
assets?.iconUrl,
game.iconUrl,
assets?.coverImageUrl,