diff --git a/.github/actions/install-deps/action.yml b/.github/actions/install-deps/action.yml index f4429294d6..c1e166d9bd 100644 --- a/.github/actions/install-deps/action.yml +++ b/.github/actions/install-deps/action.yml @@ -1,5 +1,5 @@ name: 'Prerequisite setup' -description: 'Installs dependencies (Node itself, node_modules, node-gyp)' +description: 'Installs dependencies (Node itself, node_modules, node-gyp, helper binaries)' runs: using: 'composite' steps: @@ -18,3 +18,6 @@ runs: shell: bash env: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' + - name: Download helper binaries + run: pnpm download-helper-binaries + shell: bash diff --git a/.husky/post-checkout b/.husky/post-checkout index ae2841da57..7d1e790d51 100755 --- a/.husky/post-checkout +++ b/.husky/post-checkout @@ -1,2 +1,3 @@ #!/bin/bash pnpm i +pnpm download-helper-binaries diff --git a/electron-builder.yml b/electron-builder.yml index 9183d3ff0b..3af81b61b8 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -15,6 +15,8 @@ asarUnpack: - build/icon-dark.png - build/icon-light.png - build/webviewPreload.js + - build/bin/**/* + - '!build/bin/legendary.LICENSE' electronDownload: mirror: https://github.com/castlabs/electron-releases/releases/download/v @@ -27,11 +29,7 @@ protocols: win: artifactName: ${productName}-${version}-Setup-${arch}.${ext} icon: build/win_icon.ico - asarUnpack: - - build/bin/win32/legendary.exe - - build/bin/win32/gogdl.exe - - build/bin/win32/nile.exe - files: build/bin/win32/* + files: build/bin/*/win32/* portable: artifactName: ${productName}-${version}-Portable-${arch}.${ext} @@ -46,12 +44,7 @@ mac: teamId: DLB2RYLUDX extendInfo: com.apple.security.cs.allow-jit: true - asarUnpack: - - build/bin/darwin/legendary - - build/bin/darwin/gogdl - - build/bin/darwin/nile - files: - - build/bin/darwin/* + files: build/bin/*/darwin/* dmg: background: public/dmg.png @@ -74,13 +67,7 @@ linux: desktop: Name: Heroic Games Launcher Comment[de]: Ein Open Source Spielelauncher for GOG und Epic Games - asarUnpack: - - build/bin/linux/legendary - - build/bin/linux/gogdl - - build/bin/linux/nile - - build/bin/linux/vulkan-helper - files: - - build/bin/linux/* + files: build/bin/*/linux/* snap: base: core20 diff --git a/meta/downloadHelperBinaries.ts b/meta/downloadHelperBinaries.ts new file mode 100644 index 0000000000..915c5ebcc6 --- /dev/null +++ b/meta/downloadHelperBinaries.ts @@ -0,0 +1,193 @@ +import { createWriteStream } from 'fs' +import { chmod, stat, mkdir, readFile, writeFile } from 'fs/promises' +import { dirname, join } from 'path' +import { Readable } from 'stream' +import { finished } from 'stream/promises' + +type SupportedPlatform = 'win32' | 'darwin' | 'linux' +type DownloadedBinary = 'legendary' | 'gogdl' | 'nile' + +const RELEASE_TAGS = { + legendary: '0.20.35', + gogdl: 'v1.1.1', + nile: 'v1.1.0' +} as const satisfies Record + +const pathExists = async (path: string): Promise => + stat(path).then( + () => true, + () => false + ) + +async function downloadFile(url: string, dst: string) { + const response = await fetch(url, { + headers: { + 'User-Agent': 'HeroicBinaryUpdater/1.0' + } + }) + await mkdir(dirname(dst), { recursive: true }) + const fileStream = createWriteStream(dst, { flags: 'w' }) + await finished(Readable.fromWeb(response.body).pipe(fileStream)) +} + +async function downloadAsset( + binaryName: string, + repo: string, + tag_name: string, + arch: string, + platform: SupportedPlatform, + filename: string +) { + const url = `https://github.com/${repo}/releases/download/${tag_name}/${filename}` + console.log('Downloading', binaryName, 'for', platform, arch, 'from', url) + + const exeFilename = binaryName + (platform === 'win32' ? '.exe' : '') + const exePath = join('public', 'bin', arch, platform, exeFilename) + await downloadFile(url, exePath) + + console.log('Done downloading', binaryName, 'for', platform, arch) + + if (platform !== 'win32') { + await chmod(exePath, '755') + } +} + +/** + * Downloads assets uploaded to a GitHub release + * @param binaryName The binary which was built & uploaded. Also used to get the final folder path + * @param repo The repo to download from + * @param tagName The GitHub Release tag which produced the binaries + * @param assetNames The name(s) of the assets which were uploaded, mapped to platforms + */ +async function downloadGithubAssets( + binaryName: string, + repo: string, + tagName: string, + assetNames: Record< + 'x64' | 'arm64', + Partial> + > +) { + const downloadPromises = Object.entries(assetNames).map( + async ([arch, platformFilenameMap]) => + Promise.all( + Object.entries(platformFilenameMap).map(([platform, filename]) => { + if (!filename) return + return downloadAsset( + binaryName, + repo, + tagName, + arch, + platform as keyof typeof platformFilenameMap, + filename + ) + }) + ) + ) + + return Promise.all(downloadPromises) +} + +async function downloadLegendary() { + return downloadGithubAssets( + 'legendary', + 'Heroic-Games-Launcher/legendary', + RELEASE_TAGS['legendary'], + { + x64: { + linux: 'legendary_linux_x86_64', + darwin: 'legendary_macOS_x86_64', + win32: 'legendary_windows_x86_64.exe' + }, + arm64: { + darwin: 'legendary_macOS_arm64' + } + } + ) +} + +async function downloadGogdl() { + return downloadGithubAssets( + 'gogdl', + 'Heroic-Games-Launcher/heroic-gogdl', + RELEASE_TAGS['gogdl'], + { + x64: { + linux: 'gogdl_linux_x86_64', + darwin: 'gogdl_macOS_x86_64', + win32: 'gogdl_windows_x86_64.exe' + }, + arm64: { + darwin: 'gogdl_macOS_arm64' + } + } + ) +} + +async function downloadNile() { + return downloadGithubAssets('nile', 'imLinguin/nile', RELEASE_TAGS['nile'], { + x64: { + linux: 'nile_linux_x86_64', + darwin: 'nile_macOS_x86_64', + win32: 'nile_windows_x86_64.exe' + }, + arm64: { + darwin: 'nile_macOS_arm64' + } + }) +} + +/** + * Finds out which binaries need to be downloaded by comparing + * `public/bin/.release_tags` to RELEASE_TAGS + */ +async function compareDownloadedTags(): Promise { + const storedTagsText = await readFile( + 'public/bin/.release_tags', + 'utf-8' + ).catch(() => '{}') + let storedTagsParsed: Partial> + try { + storedTagsParsed = JSON.parse(storedTagsText) + } catch { + return ['legendary', 'gogdl', 'nile'] + } + const binariesToDownload: DownloadedBinary[] = [] + for (const [runner, currentTag] of Object.entries(RELEASE_TAGS)) { + if (storedTagsParsed[runner] !== currentTag) + binariesToDownload.push(runner as keyof typeof RELEASE_TAGS) + } + return binariesToDownload +} + +async function storeDownloadedTags() { + await writeFile('public/bin/.release_tags', JSON.stringify(RELEASE_TAGS)) +} + +async function main() { + if (!(await pathExists('public/bin'))) { + console.error('public/bin not found, are you in the source root?') + return + } + + const binariesToDownload = await compareDownloadedTags() + if (!binariesToDownload.length) { + console.log('Nothing to download, binaries are up-to-date') + return + } + + console.log('Downloading:', binariesToDownload) + const promisesToAwait: Promise[] = [] + + if (binariesToDownload.includes('legendary')) + promisesToAwait.push(downloadLegendary()) + if (binariesToDownload.includes('gogdl')) + promisesToAwait.push(downloadGogdl()) + if (binariesToDownload.includes('nile')) promisesToAwait.push(downloadNile()) + + await Promise.all(promisesToAwait) + + await storeDownloadedTags() +} + +void main() diff --git a/package.json b/package.json index 0f1673e668..60665ebee2 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,8 @@ "i18n": "i18next --silent", "prepare": "husky install", "prettier": "prettier --check .", - "prettier-fix": "prettier --write ." + "prettier-fix": "prettier --write .", + "download-helper-binaries": "esbuild --bundle --platform=node --target=node21 meta/downloadHelperBinaries.ts | node" }, "dependencies": { "@emotion/react": "11.10.6", @@ -117,7 +118,7 @@ "@types/i18next-fs-backend": "1.1.4", "@types/ini": "1.3.31", "@types/jest": "29.4.0", - "@types/node": "18.15.0", + "@types/node": "20.14.9", "@types/plist": "3.0.2", "@types/react": "18.2.34", "@types/react-beautiful-dnd": "13.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a386678e04..524a9079a7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 29.4.0 version: 29.4.0 '@types/node': - specifier: 18.15.0 - version: 18.15.0 + specifier: 20.14.9 + version: 20.14.9 '@types/plist': specifier: 3.0.2 version: 3.0.2 @@ -245,7 +245,7 @@ importers: version: 5.47.1(eslint@8.36.0)(typescript@4.9.4) '@vitejs/plugin-react-swc': specifier: 3.6.0 - version: 3.6.0(vite@5.2.8(@types/node@18.15.0)(sass@1.59.2)) + version: 3.6.0(vite@5.2.8(@types/node@20.14.9)(sass@1.59.2)) cross-env: specifier: 7.0.3 version: 7.0.3 @@ -257,7 +257,7 @@ importers: version: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) electron-vite: specifier: ^2.0.0 - version: 2.2.0(@swc/core@1.4.11)(vite@5.2.8(@types/node@18.15.0)(sass@1.59.2)) + version: 2.2.0(@swc/core@1.4.11)(vite@5.2.8(@types/node@20.14.9)(sass@1.59.2)) eslint: specifier: 8.36.0 version: 8.36.0 @@ -281,7 +281,7 @@ importers: version: 7.7.0 jest: specifier: 29.5.0 - version: 29.5.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + version: 29.5.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) node-gyp: specifier: ^10.0.1 version: 10.1.0 @@ -302,7 +302,7 @@ importers: version: 0.2.1 ts-jest: specifier: 29.0.5 - version: 29.0.5(@babel/core@7.24.3)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.5.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0))(typescript@4.9.4) + version: 29.0.5(@babel/core@7.24.3)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.5.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0))(typescript@4.9.4) ts-prune: specifier: 0.10.3 version: 0.10.3 @@ -320,10 +320,10 @@ importers: version: 1.26.0(eslint@8.36.0) vite: specifier: 5.2.8 - version: 5.2.8(@types/node@18.15.0)(sass@1.59.2) + version: 5.2.8(@types/node@20.14.9)(sass@1.59.2) vite-plugin-svgr: specifier: 4.2.0 - version: 4.2.0(rollup@4.17.2)(typescript@4.9.4)(vite@5.2.8(@types/node@18.15.0)(sass@1.59.2)) + version: 4.2.0(rollup@4.17.2)(typescript@4.9.4)(vite@5.2.8(@types/node@20.14.9)(sass@1.59.2)) packages: @@ -1726,11 +1726,8 @@ packages: '@types/node@16.18.97': resolution: {integrity: sha512-4muilE1Lbfn57unR+/nT9AFjWk0MtWi5muwCEJqnOvfRQDbSfLCUdN7vCIg8TYuaANfhLOV85ve+FNpiUsbSRg==} - '@types/node@18.15.0': - resolution: {integrity: sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==} - - '@types/node@20.11.30': - resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} + '@types/node@20.14.9': + resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -6653,7 +6650,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -6666,14 +6663,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + jest-config: 29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -6698,7 +6695,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -6716,7 +6713,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.15.0 + '@types/node': 20.14.9 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -6738,7 +6735,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 18.15.0 + '@types/node': 20.14.9 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -6808,7 +6805,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/yargs': 17.0.32 chalk: 4.1.2 @@ -7257,7 +7254,7 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/responselike': 1.0.3 '@types/d3-array@3.2.1': {} @@ -7293,15 +7290,15 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/fs-extra@9.0.13': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/hast@2.3.10': dependencies: @@ -7343,11 +7340,11 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/keyv@3.1.4': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/mdast@3.0.15': dependencies: @@ -7359,9 +7356,7 @@ snapshots: '@types/node@16.18.97': {} - '@types/node@18.15.0': {} - - '@types/node@20.11.30': + '@types/node@20.14.9': dependencies: undici-types: 5.26.5 @@ -7371,7 +7366,7 @@ snapshots: '@types/plist@3.0.2': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 xmlbuilder: 15.1.1 '@types/prop-types@15.7.12': {} @@ -7414,7 +7409,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 '@types/sanitize-html@2.9.0': dependencies: @@ -7451,7 +7446,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 optional: true '@typescript-eslint/eslint-plugin@5.47.1(@typescript-eslint/parser@5.47.1(eslint@8.36.0)(typescript@4.9.4))(eslint@8.36.0)(typescript@4.9.4)': @@ -7558,10 +7553,10 @@ snapshots: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - '@vitejs/plugin-react-swc@3.6.0(vite@5.2.8(@types/node@18.15.0)(sass@1.59.2))': + '@vitejs/plugin-react-swc@3.6.0(vite@5.2.8(@types/node@20.14.9)(sass@1.59.2))': dependencies: '@swc/core': 1.4.11 - vite: 5.2.8(@types/node@18.15.0)(sass@1.59.2) + vite: 5.2.8(@types/node@20.14.9)(sass@1.59.2) transitivePeerDependencies: - '@swc/helpers' @@ -8350,13 +8345,13 @@ snapshots: dependencies: capture-stack-trace: 1.0.2 - create-jest@29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0): + create-jest@29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 - jest-config: 29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + jest-config: 29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -8732,7 +8727,7 @@ snapshots: transitivePeerDependencies: - supports-color - electron-vite@2.2.0(@swc/core@1.4.11)(vite@5.2.8(@types/node@18.15.0)(sass@1.59.2)): + electron-vite@2.2.0(@swc/core@1.4.11)(vite@5.2.8(@types/node@20.14.9)(sass@1.59.2)): dependencies: '@babel/core': 7.24.3 '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.24.3) @@ -8740,7 +8735,7 @@ snapshots: esbuild: 0.19.12 magic-string: 0.30.10 picocolors: 1.0.0 - vite: 5.2.8(@types/node@18.15.0)(sass@1.59.2) + vite: 5.2.8(@types/node@20.14.9)(sass@1.59.2) optionalDependencies: '@swc/core': 1.4.11 transitivePeerDependencies: @@ -8757,7 +8752,7 @@ snapshots: electron@https://codeload.github.com/castlabs/electron-releases/tar.gz/11c396ff7aa05e8fd8049193b58684f119cc0b8d: dependencies: '@electron/get': 2.0.3 - '@types/node': 20.11.30 + '@types/node': 20.14.9 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -9963,7 +9958,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1(babel-plugin-macros@3.1.0) @@ -9983,16 +9978,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0): + jest-cli@29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + create-jest: 29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + jest-config: 29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -10002,7 +9997,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0): + jest-config@29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0): dependencies: '@babel/core': 7.24.3 '@jest/test-sequencer': 29.7.0 @@ -10027,7 +10022,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -10056,7 +10051,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -10066,7 +10061,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 18.15.0 + '@types/node': 20.14.9 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -10105,7 +10100,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -10140,7 +10135,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -10168,7 +10163,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -10214,7 +10209,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.10 @@ -10233,7 +10228,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.15.0 + '@types/node': 20.14.9 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -10242,17 +10237,17 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.5.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0): + jest@29.5.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + jest-cli: 29.7.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -12015,11 +12010,11 @@ snapshots: dependencies: utf8-byte-length: 1.0.4 - ts-jest@29.0.5(@babel/core@7.24.3)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.5.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0))(typescript@4.9.4): + ts-jest@29.0.5(@babel/core@7.24.3)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.5.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0))(typescript@4.9.4): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.5.0(@types/node@18.15.0)(babel-plugin-macros@3.1.0) + jest: 29.5.0(@types/node@20.14.9)(babel-plugin-macros@3.1.0) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -12373,24 +12368,24 @@ snapshots: replace-ext: 2.0.0 teex: 1.0.1 - vite-plugin-svgr@4.2.0(rollup@4.17.2)(typescript@4.9.4)(vite@5.2.8(@types/node@18.15.0)(sass@1.59.2)): + vite-plugin-svgr@4.2.0(rollup@4.17.2)(typescript@4.9.4)(vite@5.2.8(@types/node@20.14.9)(sass@1.59.2)): dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.17.2) '@svgr/core': 8.1.0(typescript@4.9.4) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@4.9.4)) - vite: 5.2.8(@types/node@18.15.0)(sass@1.59.2) + vite: 5.2.8(@types/node@20.14.9)(sass@1.59.2) transitivePeerDependencies: - rollup - supports-color - typescript - vite@5.2.8(@types/node@18.15.0)(sass@1.59.2): + vite@5.2.8(@types/node@20.14.9)(sass@1.59.2): dependencies: esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.17.2 optionalDependencies: - '@types/node': 18.15.0 + '@types/node': 20.14.9 fsevents: 2.3.3 sass: 1.59.2 diff --git a/public/bin/.gitignore b/public/bin/.gitignore new file mode 100644 index 0000000000..4e897d46c0 --- /dev/null +++ b/public/bin/.gitignore @@ -0,0 +1,7 @@ +**/legendary +**/legendary.exe +**/gogdl +**/gogdl.exe +**/nile +**/nile.exe +.release_tags \ No newline at end of file diff --git a/public/bin/darwin/gogdl b/public/bin/darwin/gogdl deleted file mode 100755 index 763cf1f909..0000000000 Binary files a/public/bin/darwin/gogdl and /dev/null differ diff --git a/public/bin/darwin/legendary b/public/bin/darwin/legendary deleted file mode 100755 index fb74d79154..0000000000 Binary files a/public/bin/darwin/legendary and /dev/null differ diff --git a/public/bin/darwin/nile b/public/bin/darwin/nile deleted file mode 100755 index b1bf1c32d6..0000000000 Binary files a/public/bin/darwin/nile and /dev/null differ diff --git a/public/bin/linux/gogdl b/public/bin/linux/gogdl deleted file mode 100755 index d4125320f7..0000000000 Binary files a/public/bin/linux/gogdl and /dev/null differ diff --git a/public/bin/linux/legendary b/public/bin/linux/legendary deleted file mode 100755 index cc686fd033..0000000000 Binary files a/public/bin/linux/legendary and /dev/null differ diff --git a/public/bin/linux/nile b/public/bin/linux/nile deleted file mode 100755 index 812e48ff7e..0000000000 Binary files a/public/bin/linux/nile and /dev/null differ diff --git a/public/bin/win32/gogdl.exe b/public/bin/win32/gogdl.exe deleted file mode 100755 index 44b81729f2..0000000000 Binary files a/public/bin/win32/gogdl.exe and /dev/null differ diff --git a/public/bin/win32/legendary.exe b/public/bin/win32/legendary.exe deleted file mode 100755 index 7c84d54385..0000000000 Binary files a/public/bin/win32/legendary.exe and /dev/null differ diff --git a/public/bin/win32/nile.exe b/public/bin/win32/nile.exe deleted file mode 100644 index 9508522811..0000000000 Binary files a/public/bin/win32/nile.exe and /dev/null differ diff --git a/public/bin/linux/vulkan-helper b/public/bin/x64/linux/vulkan-helper similarity index 100% rename from public/bin/linux/vulkan-helper rename to public/bin/x64/linux/vulkan-helper diff --git a/src/backend/constants.ts b/src/backend/constants.ts index 9e4858c84f..c3a8ae9f5b 100644 --- a/src/backend/constants.ts +++ b/src/backend/constants.ts @@ -89,7 +89,7 @@ const publicDir = resolve( ) const gogdlAuthConfig = join(app.getPath('userData'), 'gog_store', 'auth.json') const vulkanHelperBin = fixAsarPath( - join(publicDir, 'bin', process.platform, 'vulkan-helper') + join(publicDir, 'bin', process.arch, process.platform, 'vulkan-helper') ) const icon = fixAsarPath(join(publicDir, 'icon.png')) const iconDark = fixAsarPath(join(publicDir, 'icon-dark.png')) diff --git a/src/backend/utils.ts b/src/backend/utils.ts index ada1d85594..8463e38e26 100644 --- a/src/backend/utils.ts +++ b/src/backend/utils.ts @@ -443,34 +443,55 @@ function splitPathAndName(fullPath: string): { dir: string; bin: string } { return { dir, bin } } +function archSpecificBinary(binaryName: string) { + // Try to use the arch-native binary first, if that doesn't exist fall back to + // the x64 version (assume a compatibility layer like box64 is installed) + const archSpecificPath = join( + publicDir, + 'bin', + process.arch, + process.platform, + binaryName + ) + if (existsSync(archSpecificPath)) return archSpecificPath + return join(publicDir, 'bin', 'x64', process.platform, binaryName) +} + +let defaultLegendaryPath: string | undefined = undefined function getLegendaryBin(): { dir: string; bin: string } { const settings = GlobalConfig.get().getSettings() if (settings?.altLegendaryBin) { return splitPathAndName(settings.altLegendaryBin) } - return splitPathAndName( - fixAsarPath(join(publicDir, 'bin', process.platform, 'legendary')) - ) + + if (!defaultLegendaryPath) + defaultLegendaryPath = archSpecificBinary('legendary') + + return splitPathAndName(fixAsarPath(defaultLegendaryPath)) } +let defaultGogdlPath: string | undefined = undefined function getGOGdlBin(): { dir: string; bin: string } { const settings = GlobalConfig.get().getSettings() if (settings?.altGogdlBin) { return splitPathAndName(settings.altGogdlBin) } - return splitPathAndName( - fixAsarPath(join(publicDir, 'bin', process.platform, 'gogdl')) - ) + + if (!defaultGogdlPath) defaultGogdlPath = archSpecificBinary('gogdl') + + return splitPathAndName(fixAsarPath(defaultGogdlPath)) } +let defaultNilePath: string | undefined = undefined function getNileBin(): { dir: string; bin: string } { const settings = GlobalConfig.get().getSettings() if (settings?.altNileBin) { return splitPathAndName(settings.altNileBin) } - return splitPathAndName( - fixAsarPath(join(publicDir, 'bin', process.platform, 'nile')) - ) + + if (!defaultNilePath) defaultNilePath = archSpecificBinary('nile') + + return splitPathAndName(fixAsarPath(defaultNilePath)) } function getFormattedOsName(): string { diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 54ecc0f563..cdca638e54 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -9,7 +9,8 @@ "e2e/**/*.js", "flathub/**/*.ts", "playwright.config.ts", - "electron.vite.config.ts" + "electron.vite.config.ts", + "meta/**/*.ts" ], "exclude": [] }