Skip to content

[General] Restructure/Cleanup of runLegendaryOrGogdlCommand #1415

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 2 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
33 changes: 16 additions & 17 deletions electron/gog/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
} from '../launcher'
import { addShortcuts, removeShortcuts } from '../shortcuts'
import setup from './setup'
import { getGogdlCommand, runGogdlCommand } from './library'
import { runGogdlCommand } from './library'

function verifyProgress(stderr: string): boolean {
const text = stderr.split('\n').at(-1)
Expand Down Expand Up @@ -97,9 +97,8 @@ class GOGGame extends Game {

public async import(path: string): Promise<ExecResult> {
const commandParts = ['import', path]
const command = getGogdlCommand(commandParts)

logInfo([`Importing ${this.appName} with:`, command], LogPrefix.Gog)
logInfo(`Importing ${this.appName}.`, LogPrefix.Gog)

const res = await runGogdlCommand(commandParts)

Expand Down Expand Up @@ -138,7 +137,7 @@ class GOGGame extends Game {
`Progress for ${this.appName}:`,
`${percent}%/${bytes}MiB/${eta}`.trim()
],
LogPrefix.Backend
LogPrefix.Gog
)

this.window.webContents.send('setGameStatus', {
Expand Down Expand Up @@ -185,9 +184,8 @@ class GOGGame extends Game {
`--lang=${installLanguage}`,
...workers
]
const command = getGogdlCommand(commandParts)

logInfo([`Installing ${this.appName} with:`, command], LogPrefix.Gog)
logInfo(`Installing ${this.appName}.`, LogPrefix.Gog)

const onOutput = (data: string) => {
this.onInstallOrUpdateOutput('installing', data)
Expand Down Expand Up @@ -270,6 +268,7 @@ class GOGGame extends Game {
public async removeShortcuts() {
return removeShortcuts(this.appName, 'gog')
}

async launch(launchArguments?: string): Promise<LaunchResult> {
const gameSettings =
GameConfig.get(this.appName).config ||
Expand Down Expand Up @@ -395,14 +394,16 @@ class GOGGame extends Game {
launcherArgs
]
}
const command = getGogdlCommand(commandParts, commandEnv, wrappers)

logInfo([`Launching ${gameInfo.title}:`, command], LogPrefix.Gog)
logInfo(`Launching ${gameInfo.title}.`, LogPrefix.Gog)

const { error, stderr, stdout } = await runGogdlCommand(commandParts, {
env: commandEnv,
wrappers
})
const { error, stderr, stdout, fullCommand } = await runGogdlCommand(
commandParts,
{
env: commandEnv,
wrappers
}
)

if (error) {
logError(['Error launching game:', error], LogPrefix.Gog)
Expand All @@ -415,7 +416,7 @@ class GOGGame extends Game {
stdout,
stderr,
gameSettings,
command
command: fullCommand
}
}

Expand Down Expand Up @@ -467,9 +468,8 @@ class GOGGame extends Game {
'-b=' + gameData.install.buildId,
...workers
]
const command = getGogdlCommand(commandParts)

logInfo([`Repairing ${this.appName} with:`, command], LogPrefix.Gog)
logInfo(`Repairing ${this.appName}.`, LogPrefix.Gog)

const res = await runGogdlCommand(commandParts, { logFile: logPath })

Expand Down Expand Up @@ -578,9 +578,8 @@ class GOGGame extends Game {
`--lang=${gameData.install.language || 'en-US'}`,
...workers
]
const command = getGogdlCommand(commandParts)

logInfo([`Updating ${this.appName} with:`, command], LogPrefix.Gog)
logInfo(`Updating ${this.appName}.`, LogPrefix.Gog)

const onOutput = (data: string) => {
this.onInstallOrUpdateOutput('updating', data)
Expand Down
26 changes: 3 additions & 23 deletions electron/gog/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ import {
libraryStore,
installedGamesStore
} from './electronStores'
import {
getLegendaryOrGogdlCommand,
runLegendaryOrGogdlCommand
} from '../launcher'
import { runLegendaryOrGogdlCommand } from '../launcher'

export class GOGLibrary {
private static globalInstance: GOGLibrary = null
Expand Down Expand Up @@ -169,9 +166,8 @@ export class GOGLibrary {
'--os',
installPlatform
]
const command = getGogdlCommand(commandParts)

logInfo(['Getting game metadata:', command], LogPrefix.Gog)
logInfo('Getting game metadata.', LogPrefix.Gog)

const res = await runGogdlCommand(commandParts)
if (res.error) {
Expand Down Expand Up @@ -635,23 +631,7 @@ export async function runGogdlCommand(
const { dir, bin } = getGOGdlBin()
return runLegendaryOrGogdlCommand(
commandParts,
{ name: 'GOGDL', logPrefix: LogPrefix.Gog, bin, dir },
{ name: 'gog', logPrefix: LogPrefix.Gog, bin, dir },
options
)
}

/**
* Generates a "safe" GOGDL command **for formatting**.
* Command generated by this function are not meant to be ran directly, use runGogdlCommand for that.
* A "safe" command does not include the user's token
* @param commandParts The command to run, e. g. 'update', 'install'...
* @returns The full command as a string
*/
export function getGogdlCommand(
commandParts: string[],
env: Record<string, string> = {},
wrappers: string[] = []
): string {
const gogdlPath = join(...Object.values(getGOGdlBin()))
return getLegendaryOrGogdlCommand(commandParts, env, wrappers, gogdlPath)
}
56 changes: 28 additions & 28 deletions electron/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { DXVK } from './tools'
import setup from './gog/setup'
import { GOGGame } from 'gog/games'
import { LegendaryGame } from 'legendary/games'
import { GameInfo } from './types'
import { GameInfo, Runner } from './types'
import {
ExecResult,
GameSettings,
Expand Down Expand Up @@ -471,7 +471,7 @@ async function runWineCommand(
async function runLegendaryOrGogdlCommand(
commandParts: string[],
runner: {
name: 'GOGDL' | 'Legendary'
name: Runner
logPrefix: LogPrefix
bin: string
dir: string
Expand All @@ -485,20 +485,22 @@ async function runLegendaryOrGogdlCommand(
): Promise<ExecResult> {
const fullRunnerPath = join(runner.dir, runner.bin)
const appName = commandParts[commandParts.findIndex(() => 'launch') + 1]

// Necessary to get rid of undefined or null entries, else
// TypeError is triggered
commandParts = commandParts.filter(Boolean)
const safeCommand = getLegendaryOrGogdlCommand(
commandParts,
options?.env,
options?.wrappers,
fullRunnerPath
)
logDebug(['Running', runner.name, 'command:', safeCommand], runner.logPrefix)
if (options?.logFile) {
logDebug([`Logging to file "${options.logFile}"`], runner.logPrefix)
}

commandParts = commandParts.filter((n) => n)
logDebug(['Running', 'command:', safeCommand], runner.logPrefix)
logDebug(`Logging to file "${options?.logFile}"`, runner.logPrefix)

if (existsSync(options?.logFile)) {
writeFileSync(options.logFile, '')
writeFileSync(options?.logFile, '')
}

// If we have wrappers (things we want to run before the command), set bin to the first wrapper
Expand All @@ -521,28 +523,27 @@ async function runLegendaryOrGogdlCommand(
const stdout: string[] = []
const stderr: string[] = []

if (options?.logFile) {
child.stdout.on('data', (data: Buffer) => {
appendFileSync(options.logFile, data.toString())
})
child.stderr.on('data', (data: Buffer) => {
child.stdout.on('data', (data: Buffer) => {
if (options?.logFile) {
appendFileSync(options.logFile, data.toString())
})
}
}

if (options?.onOutput) {
child.stdout.on('data', (data: Buffer) => {
options.onOutput(data.toString())
})
child.stderr.on('data', (data: Buffer) => {
if (options?.onOutput) {
options.onOutput(data.toString())
})
}
}

child.stdout.on('data', (data: Buffer) => {
stdout.push(data.toString().trim())
})

child.stderr.on('data', (data: Buffer) => {
if (options?.logFile) {
appendFileSync(options.logFile, data.toString())
}

if (options?.onOutput) {
options.onOutput(data.toString())
}

stderr.push(data.toString().trim())
})

Expand All @@ -563,6 +564,7 @@ async function runLegendaryOrGogdlCommand(
stderr: stderr.join('\n')
})
})

child.on('error', (error) => {
rej(error)
})
Expand All @@ -583,10 +585,11 @@ async function runLegendaryOrGogdlCommand(
!`${error}`.includes('appears to be deleted')

logError(
['Error running', runner.name, 'command', `"${safeCommand}": ${error}`],
['Error running', 'command', `"${safeCommand}": ${error}`],
runner.logPrefix,
showDialog
)

return { stdout: '', stderr: `${error}`, fullCommand: safeCommand, error }
})
}
Expand All @@ -597,8 +600,6 @@ function getLegendaryOrGogdlCommand(
wrappers: string[] = [],
runnerPath: string
): string {
commandParts = commandParts.filter((n) => n)

// Redact sensitive arguments (SID for Legendary, token for GOGDL)
for (const sensitiveArg of ['--sid', '--token']) {
const sensitiveArgIndex = commandParts.indexOf(sensitiveArg)
Expand Down Expand Up @@ -636,6 +637,5 @@ export {
setupWineEnvVars,
setupWrappers,
runWineCommand,
runLegendaryOrGogdlCommand,
getLegendaryOrGogdlCommand
runLegendaryOrGogdlCommand
}
42 changes: 18 additions & 24 deletions electron/legendary/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ExecResult, ExtraInfo, InstallArgs, LaunchResult } from '../types'
import { Game } from '../games'
import { GameConfig } from '../game_config'
import { GlobalConfig } from '../config'
import { getLegendaryCommand, LegendaryLibrary } from './library'
import { LegendaryLibrary } from './library'
import { LegendaryUser } from './user'
import { execAsync, getSteamRuntime, isOnline } from '../utils'
import {
Expand Down Expand Up @@ -266,7 +266,7 @@ class LegendaryGame extends Game {
`Progress for ${this.appName}:`,
`${percent}%/${bytes}MiB/${eta}`.trim()
],
LogPrefix.Backend
LogPrefix.Legendary
)

this.window.webContents.send('setGameStatus', {
Expand Down Expand Up @@ -298,9 +298,8 @@ class LegendaryGame extends Game {
const logPath = join(heroicGamesConfigPath, this.appName + '.log')

const commandParts = ['update', this.appName, ...workers, '-y']
const command = getLegendaryCommand(commandParts)

logInfo([`Updating ${this.appName} with:`, command], LogPrefix.Legendary)
logInfo(`Updating ${this.appName}.`, LogPrefix.Legendary)

const onOutput = (data: string) => {
this.onInstallOrUpdateOutput(
Expand Down Expand Up @@ -393,8 +392,8 @@ class LegendaryGame extends Game {
...workers,
'-y'
]
const command = getLegendaryCommand(commandParts)
logInfo([`Installing ${this.appName} with:`, command], LogPrefix.Legendary)

logInfo(`Installing ${this.appName}.`, LogPrefix.Legendary)

const onOutput = (data: string) => {
this.onInstallOrUpdateOutput(
Expand Down Expand Up @@ -434,9 +433,8 @@ class LegendaryGame extends Game {

public async uninstall(): Promise<ExecResult> {
const commandParts = ['uninstall', this.appName, '-y']
const command = getLegendaryCommand(commandParts)

logInfo([`Uninstalling ${this.appName}:`, command], LogPrefix.Legendary)
logInfo(`Uninstalling ${this.appName}.`, LogPrefix.Legendary)

LegendaryLibrary.get().installState(this.appName, false)
const res = await runLegendaryCommand(commandParts)
Expand All @@ -463,9 +461,8 @@ class LegendaryGame extends Game {
const logPath = join(heroicGamesConfigPath, this.appName + '.log')

const commandParts = ['repair', this.appName, ...workers, '-y']
const command = getLegendaryCommand(commandParts)

logInfo([`Repairing ${this.appName}:`, command], LogPrefix.Legendary)
logInfo(`Repairing ${this.appName}.`, LogPrefix.Legendary)

const res = await runLegendaryCommand(commandParts, { logFile: logPath })

Expand All @@ -480,9 +477,8 @@ class LegendaryGame extends Game {

public async import(path: string): Promise<ExecResult> {
const commandParts = ['import', this.appName, path]
const command = getLegendaryCommand(commandParts)

logInfo([`Importing ${this.appName}:`, command], LogPrefix.Legendary)
logInfo(`Importing ${this.appName}.`, LogPrefix.Legendary)

const res = await runLegendaryCommand(commandParts)

Expand Down Expand Up @@ -517,12 +513,8 @@ class LegendaryGame extends Game {
this.appName,
'-y'
]
const command = getLegendaryCommand(commandParts)

logInfo(
[`Syncing saves for ${this.appName}:`, command],
LogPrefix.Legendary
)
logInfo(`Syncing saves for ${this.appName}.`, LogPrefix.Legendary)

const res = await runLegendaryCommand(commandParts)

Expand Down Expand Up @@ -659,13 +651,15 @@ class LegendaryGame extends Game {
launchArguments
]
}
const command = getLegendaryCommand(commandParts, commandEnv, wrappers)

logInfo([`Launching ${gameInfo.title}:`, command], LogPrefix.Legendary)
const { error, stderr, stdout } = await runLegendaryCommand(commandParts, {
env: commandEnv,
wrappers: wrappers
})
logInfo(`Launching ${gameInfo.title}.`, LogPrefix.Legendary)
const { error, stderr, stdout, fullCommand } = await runLegendaryCommand(
commandParts,
{
env: commandEnv,
wrappers: wrappers
}
)

if (error) {
const showDialog = !`${error}`.includes('appears to be deleted')
Expand All @@ -683,7 +677,7 @@ class LegendaryGame extends Game {
stdout,
stderr,
gameSettings,
command
command: fullCommand
}
}

Expand Down
Loading