Skip to content

[Feat] Add support for Amazon Games #2831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 49 commits into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
6f906f3
feat: initial skeleton for Amazon Games
Gustash Jun 30, 2023
2e60a4c
feat: added placeholder for amazon save location
Gustash Jun 30, 2023
3e797b2
chore: added EN Amazon Games translation
Gustash Jun 30, 2023
78060d3
feat: nile store boilerplate and rendering library
Gustash Jun 30, 2023
924fe92
chore: commented out non-finalized portions to satisfy eslint
Gustash Jun 30, 2023
163967d
refactor: better handling of installed games
Gustash Jul 1, 2023
8cf9430
feat: filled out game info in GameManager and using cache in library
Gustash Jul 1, 2023
b876085
feat: calling nile bin to sync library
Gustash Jul 1, 2023
f6437c2
fix: removed game logo from art
Gustash Jul 1, 2023
0962a20
feat: launching games
Gustash Jul 1, 2023
c6375eb
feat: implemented install and move installation folder
Gustash Jul 1, 2023
4d98978
feat: Implemented uninstall
Gustash Jul 1, 2023
8347f51
feat: implemented stopping game
Gustash Jul 1, 2023
52c20e8
feat: implemented isGameAvailable
Gustash Jul 1, 2023
1cb56cd
feat: using local nile config
Gustash Jul 2, 2023
1c921cc
feat: Implemented login
Gustash Jul 2, 2023
b537d13
feat: better handling of amazon session
Gustash Jul 2, 2023
9fdda27
feat: implemented logout
Gustash Jul 2, 2023
8b9cd28
feat: download progress
Gustash Jul 3, 2023
9c0d5c9
feat: added settings for nile version and alt nile bin
Gustash Jul 3, 2023
d6db528
feat: using JSON5 to parse fuel.json
Gustash Jul 3, 2023
a7f2397
fix: deadcode
Gustash Jul 3, 2023
e84019b
fix: process killing in Windows and macOS
Gustash Jul 3, 2023
2d1c1ec
feat: implemented game updates
Gustash Jul 3, 2023
255f1c5
fix: handle edge-case of games without title
Gustash Jul 4, 2023
a61870a
feat: implemented importing games
Gustash Jul 4, 2023
5d54870
feat: implemented repairing games
Gustash Jul 4, 2023
00d0d24
feat: saving import game log to file
Gustash Jul 4, 2023
7757b06
feat: added store page URLs
Gustash Jul 4, 2023
90396ca
feat: added Nile Linux binary
Gustash Jul 4, 2023
7ba0d9e
feat: added Nile Windows binary
Gustash Jul 4, 2023
b67a315
feat: added Nile macOS binary
Gustash Jul 4, 2023
2984a4d
feat: added nile binaries to asarUnpack
Gustash Jul 4, 2023
959d21f
chore: using binaries from nile build artifacts
Gustash Jul 4, 2023
5bb45f5
fix: added missing check for Amazon login
Gustash Jul 4, 2023
7931a32
feat: PostInstall implementation for Wine
Gustash Jul 5, 2023
c79e792
fix: runner name mapping in SearchBar
Gustash Jul 5, 2023
c0a2982
feat: implement PostInstall for Windows
Gustash Jul 5, 2023
10a38db
feat: implemented nile in protocol.ts
Gustash Jul 5, 2023
d0156ee
fix: user credentials not being loaded when copying config
Gustash Jul 5, 2023
846b7f4
chore: updated documentation
Gustash Jul 5, 2023
d9cc98d
fix: amazon logout not being handled async
Gustash Jul 11, 2023
e64ed11
refactor: changed default store_url to GOG
Gustash Jul 11, 2023
6e4ee06
feat: Prime Gaming added to stores
Gustash Jul 11, 2023
46be3cd
fix: nile library refresh
Gustash Jul 11, 2023
bd31985
refactor: disabled Amazon games Store Page link
Gustash Jul 12, 2023
f1714f4
chore: updated nile binaries
Gustash Jul 14, 2023
07a661e
refactor: simplify process killing with new nile version
Gustash Jul 14, 2023
819dbe2
fix: killing games in macOS
Gustash Jul 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![kofi](https://img.shields.io/badge/Ko--Fi-Donate-orange?style=for-the-badge&logo=ko-fi)](https://ko-fi.com/heroicgames)

Heroic is an Open Source Game Launcher for Linux, Windows and macOS.
Right now it supports launching games from the Epic Games Store using [Legendary](https://github.com/derrod/legendary) and GOG Games using our custom implementation with [gogdl](https://github.com/Heroic-Games-Launcher/heroic-gogdl).
Right now it supports launching games from the Epic Games Store using [Legendary](https://github.com/derrod/legendary), GOG Games using our custom implementation with [gogdl](https://github.com/Heroic-Games-Launcher/heroic-gogdl) and Amazon Games using [Nile](https://github.com/imLinguin/nile).

Heroic is built with Web Technologies:
[![Typescript](https://img.shields.io/badge/Typescript-3178c6?style=for-the-badge&logo=typescript&labelColor=gray)](https://www.typescriptlang.org/)
Expand Down Expand Up @@ -52,7 +52,7 @@ Heroic is built with Web Technologies:

## Features available right now

- Login with an existing Epic Games account or GOG account
- Login with an existing Epic Games, GOG or Amazon account
- Install, uninstall, update, repair and move Games
- Import an already installed game
- Play Epic games online [AntiCheat on macOS and on Linux depends on the game]
Expand All @@ -66,11 +66,11 @@ Heroic is built with Web Technologies:
- Sync saves with the cloud
- Custom Theming Support
- Download queue
- Add Games and Applications outside GOG and Epic Games
- Add Games and Applications outside GOG, Epic Games and Amazon Games

## Planned features

- Support Other Store (Amazon Gaming, IndieGala, etc)
- Support Other Store (IndieGala, etc)
- Play GOG games online

## Supported Operating Systems
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"icon": "build/win_icon.ico",
"asarUnpack": [
"build/bin/win32/legendary.exe",
"build/bin/win32/gogdl.exe"
"build/bin/win32/gogdl.exe",
"build/bin/win32/nile.exe"
],
"files": [
"build/bin/win32/*"
Expand All @@ -69,7 +70,8 @@
},
"asarUnpack": [
"build/bin/darwin/legendary",
"build/bin/darwin/gogdl"
"build/bin/darwin/gogdl",
"build/bin/darwin/nile"
],
"files": [
"build/bin/darwin/*"
Expand Down Expand Up @@ -106,6 +108,7 @@
"asarUnpack": [
"build/bin/linux/legendary",
"build/bin/linux/gogdl",
"build/bin/linux/nile",
"build/bin/linux/vulkan-helper"
],
"files": [
Expand Down Expand Up @@ -176,6 +179,7 @@
"i18next-fs-backend": "^2.1.1",
"i18next-http-backend": "^2.1.1",
"ini": "^3.0.0",
"json5": "^2.2.3",
"plist": "^3.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
Binary file added public/bin/darwin/nile
Binary file not shown.
Binary file added public/bin/linux/nile
Binary file not shown.
Binary file added public/bin/win32/nile.exe
Binary file not shown.
1 change: 1 addition & 0 deletions public/locales/en/gamepage.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"options": "Launch Options..."
},
"not_logged_in": {
"amazon": "You are not logged in with an Amazon account in Heroic. Don't use the store page to login, click the following button instead:",
"epic": "You are not logged in with an Epic account in Heroic. Don't use the store page to login, click the following button instead:",
"gog": "You are not logged in with a GOG account in Heroic. Don't use the store page to login, click the following button instead:",
"login": "Log in",
Expand Down
9 changes: 9 additions & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
},
"add_game": "Add Game",
"All": "All",
"amazon": "Amazon",
"Amazon Games": "Amazon Games",
"anticheat": {
"anticheats": "Anticheats",
"may_not_work": "It may not work due to denied or broken anticheat support.",
Expand All @@ -26,6 +28,7 @@
"choose-egs-prefix": "Choose Prefix where EGS is installed",
"choose-gogdl-binary": "Select GOGDL Binary (needs restart)",
"choose-legendary-binary": "Select Legendary binary",
"choose-nile-binary": "Select Nile binary",
"customWine": "Select the Wine or Proton binary",
"default-install-path": "Choose Default Install Path",
"default-steam-path": "Steam path.",
Expand Down Expand Up @@ -330,6 +333,7 @@
},
"login": {
"alternative_method": "Alternative Login Method",
"amazon": "Amazon Login",
"epic": "Epic Games Login",
"gog": "GOG Login",
"message": "Login with your platform. You can login to more than one platform at the same time."
Expand Down Expand Up @@ -426,12 +430,14 @@
"other": {
"gogdl-version": "GOGDL Version: ",
"legendary-version": "Legendary Version: ",
"nile-version": "Nile Version: ",
"weblate": "Help translate Heroic."
},
"Other": "Other",
"placeholder": {
"alt-gogdl-bin": "Using built-in GOGDL binary...",
"alt-legendary-bin": "Using built-in Legendary binary...",
"alt-nile-bin": "Using built-in Nile binary...",
"custom_themes_path": "Select the path to look for custom CSS files",
"dxvkfpsvalue": "Positive integer value (e.g. 30, 60, ...)",
"egs-prefix": "Prefix where EGS is installed",
Expand All @@ -444,6 +450,7 @@
"win": "Windows"
},
"please-wait": "Please wait...",
"prime-gaming": "Prime Gaming",
"progress": "Progress",
"queue": {
"label": {
Expand All @@ -467,6 +474,7 @@
"addgamestosteam": "Add games to Steam automatically",
"alt-gogdl-bin": "Choose an Alternative GOGDL Binary to use",
"alt-legendary-bin": "Choose an Alternative Legendary Binary",
"alt-nile-bin": "Choose an Alternative Nile Binary",
"autodxvk": "Auto Install/Update DXVK on Prefix",
"autosync": "Autosync Saves",
"autoUpdateGames": "Automatically update games",
Expand Down Expand Up @@ -614,6 +622,7 @@
"status": {
"installing": "Installing",
"logging": "Logging In...",
"preparing_login": "Preparing Login... ",
"processing": "Processing files, please wait"
},
"store": "Epic Store",
Expand Down
3 changes: 3 additions & 0 deletions src/backend/api/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export const abort = (id: string) => ipcRenderer.send('abort', id)

export const getUserInfo = async () => ipcRenderer.invoke('getUserInfo')

export const getAmazonUserInfo = async () =>
ipcRenderer.invoke('getAmazonUserInfo')

export const syncSaves = async (args: {
arg: string | undefined
path: string
Expand Down
6 changes: 6 additions & 0 deletions src/backend/api/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ButtonOptions,
GamepadActionArgs
} from 'common/types'
import { NileRegisterData } from 'common/types/nile'

export const clearCache = (showDialog?: boolean) =>
ipcRenderer.send('clearCache', showDialog)
Expand Down Expand Up @@ -43,6 +44,11 @@ export const logoutLegendary = async () => ipcRenderer.invoke('logoutLegendary')
export const authGOG = async (token: string) =>
ipcRenderer.invoke('authGOG', token)
export const logoutGOG = () => ipcRenderer.send('logoutGOG')
export const getAmazonLoginData = async () =>
ipcRenderer.invoke('getAmazonLoginData')
export const authAmazon = async (data: NileRegisterData) =>
ipcRenderer.invoke('authAmazon', data)
export const logoutAmazon = async () => ipcRenderer.invoke('logoutAmazon')
export const checkGameUpdates = async () =>
ipcRenderer.invoke('checkGameUpdates')
export const refreshLibrary = async (library?: Runner | 'all') =>
Expand Down
1 change: 1 addition & 0 deletions src/backend/api/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const setSetting = (args: {
export const getLegendaryVersion = async () =>
ipcRenderer.invoke('getLegendaryVersion')
export const getGogdlVersion = async () => ipcRenderer.invoke('getGogdlVersion')
export const getNileVersion = async () => ipcRenderer.invoke('getNileVersion')
export const getEosOverlayStatus = async () =>
ipcRenderer.invoke('getEosOverlayStatus')
export const getLatestEosOverlayVersion = async () =>
Expand Down
20 changes: 17 additions & 3 deletions src/backend/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const userHome = homedir()
const configFolder = app.getPath('appData')
const appFolder = join(configFolder, 'heroic')
const legendaryConfigPath = join(appFolder, 'legendaryConfig', 'legendary')
const nileConfigPath = join(appFolder, 'nile_config', 'nile')
const configPath = join(appFolder, 'config.json')
const gamesConfigPath = join(appFolder, 'GamesConfig')
const toolsPath = join(appFolder, 'tools')
Expand All @@ -58,8 +59,13 @@ const cachedUbisoftInstallerPath = join(
'UbisoftConnectInstaller.exe'
)

const { currentLogFile, lastLogFile, legendaryLogFile, gogdlLogFile } =
createNewLogFileAndClearOldOnes()
const {
currentLogFile,
lastLogFile,
legendaryLogFile,
gogdlLogFile,
nileLogFile
} = createNewLogFileAndClearOldOnes()

const publicDir = resolve(__dirname, '..', app.isPackaged ? '' : '../public')
const gogdlAuthConfig = join(app.getPath('userData'), 'gog_store', 'auth.json')
Expand All @@ -71,6 +77,9 @@ const iconDark = fixAsarPath(join(publicDir, 'icon-dark.png'))
const iconLight = fixAsarPath(join(publicDir, 'icon-light.png'))
const installed = join(legendaryConfigPath, 'installed.json')
const legendaryMetadata = join(legendaryConfigPath, 'metadata')
const nileInstalled = join(nileConfigPath, 'installed.json')
const nileLibrary = join(nileConfigPath, 'library.json')
const nileUserData = join(nileConfigPath, 'user.json')
const fallBackImage = 'fallback'
const epicLoginUrl = 'https://legendary.gl/epiclogin'
const sidInfoUrl =
Expand Down Expand Up @@ -205,6 +214,7 @@ export {
lastLogFile,
legendaryLogFile,
gogdlLogFile,
nileLogFile,
discordLink,
execOptions,
fixAsarPath,
Expand Down Expand Up @@ -252,5 +262,9 @@ export {
customThemesWikiLink,
cachedUbisoftInstallerPath,
gogdlAuthConfig,
vulkanHelperBin
vulkanHelperBin,
nileConfigPath,
nileInstalled,
nileLibrary,
nileUserData
}
4 changes: 4 additions & 0 deletions src/backend/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { GlobalConfig } from './config'
import { GameConfig } from './game_config'
import { DXVK } from './tools'
import setup from './storeManagers/gog/setup'
import nileSetup from './storeManagers/nile/setup'
import {
CallRunnerOptions,
GameInfo,
Expand Down Expand Up @@ -217,6 +218,9 @@ async function prepareWineLaunch(
if (runner === 'gog') {
await setup(appName)
}
if (runner === 'nile') {
await nileSetup(appName)
}
if (runner === 'legendary') {
await setupUbisoftConnect(appName)
}
Expand Down
6 changes: 4 additions & 2 deletions src/backend/logger/__tests__/logfile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ describeSkipOnWindows('logger/logfile.ts', () => {
currentLogFile: 'old/log/path/file.log',
lastLogFile: '',
legendaryLogFile: '',
gogdlLogFile: ''
gogdlLogFile: '',
nileLogFile: ''
})

const data = logfile.createNewLogFileAndClearOldOnes()
Expand All @@ -63,7 +64,8 @@ describeSkipOnWindows('logger/logfile.ts', () => {
currentLogFile: expect.any(String),
lastLogFile: 'old/log/path/file.log',
legendaryLogFile: expect.any(String),
gogdlLogFile: expect.any(String)
gogdlLogFile: expect.any(String),
nileLogFile: expect.any(String)
})
})

Expand Down
11 changes: 8 additions & 3 deletions src/backend/logger/logfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface createLogFileReturn {
lastLogFile: string
legendaryLogFile: string
gogdlLogFile: string
nileLogFile: string
}

let longestPrefix = 0
Expand Down Expand Up @@ -49,10 +50,12 @@ export function createNewLogFileAndClearOldOnes(): createLogFileReturn {
const newLogFile = join(logDir, `heroic-${fmtDate}.log`)
const newLegendaryLogFile = join(logDir, `legendary-${fmtDate}.log`)
const newGogdlLogFile = join(logDir, `gogdl-${fmtDate}.log`)
const newNileLogFile = join(logDir, `nile-${fmtDate}.log`)

createLogFile(newLogFile)
createLogFile(newLegendaryLogFile)
createLogFile(newGogdlLogFile)
createLogFile(newNileLogFile)

// Clean out logs that are more than a month old
if (existsSync(logDir)) {
Expand All @@ -67,9 +70,9 @@ export function createNewLogFileAndClearOldOnes(): createLogFileReturn {
.map((dirent) => dirent.name)

logs.forEach((log) => {
if (log.match(/(heroic|legendary|gogdl)-/)) {
if (log.match(/(heroic|legendary|gogdl|nile)-/)) {
const dateString = log
.replace(/(heroic|legendary|gogdl)-/, '')
.replace(/(heroic|legendary|gogdl|nile)-/, '')
.replace('.log', '')
.replaceAll('_', ':')
const logDate = new Date(dateString)
Expand All @@ -90,13 +93,15 @@ export function createNewLogFileAndClearOldOnes(): createLogFileReturn {
currentLogFile: '',
lastLogFile: '',
legendaryLogFile: '',
gogdlLogFile: ''
gogdlLogFile: '',
nileLogFile: ''
})

logs.lastLogFile = logs.currentLogFile
logs.currentLogFile = newLogFile
logs.legendaryLogFile = newLegendaryLogFile
logs.gogdlLogFile = newGogdlLogFile
logs.nileLogFile = newNileLogFile

configStore.set('general-logs', logs)

Expand Down
1 change: 1 addition & 0 deletions src/backend/logger/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export enum LogPrefix {
General = '',
Legendary = 'Legendary',
Gog = 'Gog',
Nile = 'Nile',
WineDownloader = 'WineDownloader',
DXVKInstaller = 'DXVKInstaller',
GlobalConfig = 'GlobalConfig',
Expand Down
15 changes: 14 additions & 1 deletion src/backend/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ import { GameConfig } from './game_config'
import { GlobalConfig } from './config'
import { LegendaryUser } from 'backend/storeManagers/legendary/user'
import { GOGUser } from './storeManagers/gog/user'
import { NileUser } from './storeManagers/nile/user'
import setup from './storeManagers/gog/setup'
import nileSetup from './storeManagers/nile/setup'
import {
clearCache,
execAsync,
Expand All @@ -70,7 +72,8 @@ import {
getCurrentChangelog,
checkWineBeforeLaunch,
removeFolder,
downloadDefaultWine
downloadDefaultWine,
getNileVersion
} from './utils'
import {
configStore,
Expand Down Expand Up @@ -643,6 +646,7 @@ ipcMain.handle('getMaxCpus', () => cpus().length)
ipcMain.handle('getHeroicVersion', app.getVersion)
ipcMain.handle('getLegendaryVersion', getLegendaryVersion)
ipcMain.handle('getGogdlVersion', getGogdlVersion)
ipcMain.handle('getNileVersion', getNileVersion)
ipcMain.handle('isFullscreen', () => isSteamDeckGameMode || isCLIFullscreen)
ipcMain.handle('isFlatpak', () => isFlatpak)
ipcMain.handle('getGameOverride', async () => getGameOverride())
Expand Down Expand Up @@ -752,6 +756,8 @@ ipcMain.handle('getUserInfo', async () => {
return LegendaryUser.getUserInfo()
})

ipcMain.handle('getAmazonUserInfo', async () => NileUser.getUserData())

// Checks if the user have logged in with Legendary already
ipcMain.handle('isLoggedIn', LegendaryUser.isLoggedIn)

Expand All @@ -763,6 +769,10 @@ ipcMain.handle('getLocalPeloadPath', async () => {
return fixAsarPath(join('file://', publicDir, 'webviewPreload.js'))
})

ipcMain.handle('getAmazonLoginData', NileUser.getLoginData)
ipcMain.handle('authAmazon', async (event, data) => NileUser.login(data))
ipcMain.handle('logoutAmazon', NileUser.logout)

ipcMain.handle('getAlternativeWine', async () =>
GlobalConfig.get().getAlternativeWine()
)
Expand Down Expand Up @@ -1585,6 +1595,9 @@ ipcMain.handle(
if (runner === 'gog' && updated) {
await setup(appName)
}
if (runner === 'nile' && updated) {
await nileSetup(appName)
}
if (runner === 'legendary' && updated) {
await setupUbisoftConnect(appName)
}
Expand Down
Loading