Skip to content

Commit 8e517e9

Browse files
authored
[General] Restructure/Cleanup of runLegendaryOrGogdlCommand (#1415)
* Restructured runLegendaryOrGogCommand - removed unessecary functions and logs - cleanup unessecary code * Review suggestions and cleanup
1 parent 4a0300b commit 8e517e9

File tree

8 files changed

+118
-168
lines changed

8 files changed

+118
-168
lines changed

electron/gog/games.ts

+23-28
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import {
4040
} from '../launcher'
4141
import { addShortcuts, removeShortcuts } from '../shortcuts'
4242
import setup from './setup'
43-
import { getGogdlCommand, runGogdlCommand } from './library'
43+
import { runGogdlCommand } from './library'
4444

4545
function verifyProgress(stderr: string): boolean {
4646
const text = stderr.split('\n').at(-1)
@@ -96,12 +96,9 @@ class GOGGame extends Game {
9696
}
9797

9898
public async import(path: string): Promise<ExecResult> {
99-
const commandParts = ['import', path]
100-
const command = getGogdlCommand(commandParts)
101-
102-
logInfo([`Importing ${this.appName} with:`, command], LogPrefix.Gog)
103-
104-
const res = await runGogdlCommand(commandParts)
99+
const res = await runGogdlCommand(['import', path], {
100+
logMessagePrefix: `Importing ${this.appName}`
101+
})
105102

106103
if (res.error) {
107104
logError(
@@ -138,7 +135,7 @@ class GOGGame extends Game {
138135
`Progress for ${this.appName}:`,
139136
`${percent}%/${bytes}MiB/${eta}`.trim()
140137
],
141-
LogPrefix.Backend
138+
LogPrefix.Gog
142139
)
143140

144141
this.window.webContents.send('setGameStatus', {
@@ -185,17 +182,15 @@ class GOGGame extends Game {
185182
`--lang=${installLanguage}`,
186183
...workers
187184
]
188-
const command = getGogdlCommand(commandParts)
189-
190-
logInfo([`Installing ${this.appName} with:`, command], LogPrefix.Gog)
191185

192186
const onOutput = (data: string) => {
193187
this.onInstallOrUpdateOutput('installing', data)
194188
}
195189

196190
const res = await runGogdlCommand(commandParts, {
197191
logFile: logPath,
198-
onOutput
192+
onOutput,
193+
logMessagePrefix: `Installing ${this.appName}`
199194
})
200195

201196
if (res.error) {
@@ -270,6 +265,7 @@ class GOGGame extends Game {
270265
public async removeShortcuts() {
271266
return removeShortcuts(this.appName, 'gog')
272267
}
268+
273269
async launch(launchArguments?: string): Promise<LaunchResult> {
274270
const gameSettings =
275271
GameConfig.get(this.appName).config ||
@@ -395,14 +391,15 @@ class GOGGame extends Game {
395391
launcherArgs
396392
]
397393
}
398-
const command = getGogdlCommand(commandParts, commandEnv, wrappers)
399394

400-
logInfo([`Launching ${gameInfo.title}:`, command], LogPrefix.Gog)
401-
402-
const { error, stderr, stdout } = await runGogdlCommand(commandParts, {
403-
env: commandEnv,
404-
wrappers
405-
})
395+
const { error, stderr, stdout, fullCommand } = await runGogdlCommand(
396+
commandParts,
397+
{
398+
env: commandEnv,
399+
wrappers,
400+
logMessagePrefix: `Launching ${gameInfo.title}`
401+
}
402+
)
406403

407404
if (error) {
408405
logError(['Error launching game:', error], LogPrefix.Gog)
@@ -415,7 +412,7 @@ class GOGGame extends Game {
415412
stdout,
416413
stderr,
417414
gameSettings,
418-
command
415+
command: fullCommand
419416
}
420417
}
421418

@@ -467,11 +464,11 @@ class GOGGame extends Game {
467464
'-b=' + gameData.install.buildId,
468465
...workers
469466
]
470-
const command = getGogdlCommand(commandParts)
471467

472-
logInfo([`Repairing ${this.appName} with:`, command], LogPrefix.Gog)
473-
474-
const res = await runGogdlCommand(commandParts, { logFile: logPath })
468+
const res = await runGogdlCommand(commandParts, {
469+
logFile: logPath,
470+
logMessagePrefix: `Repairing ${this.appName}`
471+
})
475472

476473
if (res.error) {
477474
logError(
@@ -578,17 +575,15 @@ class GOGGame extends Game {
578575
`--lang=${gameData.install.language || 'en-US'}`,
579576
...workers
580577
]
581-
const command = getGogdlCommand(commandParts)
582-
583-
logInfo([`Updating ${this.appName} with:`, command], LogPrefix.Gog)
584578

585579
const onOutput = (data: string) => {
586580
this.onInstallOrUpdateOutput('updating', data)
587581
}
588582

589583
const res = await runGogdlCommand(commandParts, {
590584
logFile: logPath,
591-
onOutput
585+
onOutput,
586+
logMessagePrefix: `Updating ${this.appName}`
592587
})
593588

594589
// This always has to be done, so we do it before checking for res.error

electron/gog/library.ts

+7-31
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
InstallInfo,
77
InstalledInfo,
88
GOGImportData,
9-
ExecResult
9+
ExecResult,
10+
CallRunnerOptions
1011
} from '../types'
1112
import { join } from 'node:path'
1213
import { existsSync, readFileSync } from 'graceful-fs'
@@ -19,10 +20,7 @@ import {
1920
libraryStore,
2021
installedGamesStore
2122
} from './electronStores'
22-
import {
23-
getLegendaryOrGogdlCommand,
24-
runLegendaryOrGogdlCommand
25-
} from '../launcher'
23+
import { callRunner } from '../launcher'
2624

2725
export class GOGLibrary {
2826
private static globalInstance: GOGLibrary = null
@@ -169,9 +167,8 @@ export class GOGLibrary {
169167
'--os',
170168
installPlatform
171169
]
172-
const command = getGogdlCommand(commandParts)
173170

174-
logInfo(['Getting game metadata:', command], LogPrefix.Gog)
171+
logInfo('Getting game metadata.', LogPrefix.Gog)
175172

176173
const res = await runGogdlCommand(commandParts)
177174
if (res.error) {
@@ -625,33 +622,12 @@ export class GOGLibrary {
625622
*/
626623
export async function runGogdlCommand(
627624
commandParts: string[],
628-
options?: {
629-
logFile?: string
630-
env?: Record<string, string>
631-
wrappers?: string[]
632-
onOutput?: (output: string) => void
633-
}
625+
options?: CallRunnerOptions
634626
): Promise<ExecResult> {
635627
const { dir, bin } = getGOGdlBin()
636-
return runLegendaryOrGogdlCommand(
628+
return callRunner(
637629
commandParts,
638-
{ name: 'GOGDL', logPrefix: LogPrefix.Gog, bin, dir },
630+
{ name: 'gog', logPrefix: LogPrefix.Gog, bin, dir },
639631
options
640632
)
641633
}
642-
643-
/**
644-
* Generates a "safe" GOGDL command **for formatting**.
645-
* Command generated by this function are not meant to be ran directly, use runGogdlCommand for that.
646-
* A "safe" command does not include the user's token
647-
* @param commandParts The command to run, e. g. 'update', 'install'...
648-
* @returns The full command as a string
649-
*/
650-
export function getGogdlCommand(
651-
commandParts: string[],
652-
env: Record<string, string> = {},
653-
wrappers: string[] = []
654-
): string {
655-
const gogdlPath = join(...Object.values(getGOGdlBin()))
656-
return getLegendaryOrGogdlCommand(commandParts, env, wrappers, gogdlPath)
657-
}

electron/launcher.ts

+42-39
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { DXVK } from './tools'
3434
import setup from './gog/setup'
3535
import { GOGGame } from 'gog/games'
3636
import { LegendaryGame } from 'legendary/games'
37-
import { GameInfo } from './types'
37+
import { CallRunnerOptions, GameInfo, Runner } from './types'
3838
import {
3939
ExecResult,
4040
GameSettings,
@@ -468,35 +468,40 @@ async function runWineCommand(
468468
})
469469
}
470470

471-
async function runLegendaryOrGogdlCommand(
471+
interface RunnerProps {
472+
name: Runner
473+
logPrefix: LogPrefix
474+
bin: string
475+
dir: string
476+
}
477+
478+
async function callRunner(
472479
commandParts: string[],
473-
runner: {
474-
name: 'GOGDL' | 'Legendary'
475-
logPrefix: LogPrefix
476-
bin: string
477-
dir: string
478-
},
479-
options?: {
480-
logFile?: string
481-
env?: Record<string, string>
482-
wrappers?: string[]
483-
onOutput?: (output: string) => void
484-
}
480+
runner: RunnerProps,
481+
options?: CallRunnerOptions
485482
): Promise<ExecResult> {
486483
const fullRunnerPath = join(runner.dir, runner.bin)
487484
const appName = commandParts[commandParts.findIndex(() => 'launch') + 1]
488-
const safeCommand = getLegendaryOrGogdlCommand(
485+
486+
// Necessary to get rid of possible undefined or null entries, else
487+
// TypeError is triggered
488+
commandParts = commandParts.filter(Boolean)
489+
const safeCommand = getRunnerCallWithoutCredentials(
489490
commandParts,
490491
options?.env,
491492
options?.wrappers,
492493
fullRunnerPath
493494
)
494-
logDebug(['Running', runner.name, 'command:', safeCommand], runner.logPrefix)
495+
496+
logInfo(
497+
[options?.logMessagePrefix ?? `Running command`, ':', safeCommand],
498+
runner.logPrefix
499+
)
500+
495501
if (options?.logFile) {
496-
logDebug([`Logging to file "${options.logFile}"`], runner.logPrefix)
502+
logDebug(`Logging to file "${options?.logFile}"`, runner.logPrefix)
497503
}
498504

499-
commandParts = commandParts.filter((n) => n)
500505
if (existsSync(options?.logFile)) {
501506
writeFileSync(options.logFile, '')
502507
}
@@ -521,28 +526,27 @@ async function runLegendaryOrGogdlCommand(
521526
const stdout: string[] = []
522527
const stderr: string[] = []
523528

524-
if (options?.logFile) {
525-
child.stdout.on('data', (data: Buffer) => {
526-
appendFileSync(options.logFile, data.toString())
527-
})
528-
child.stderr.on('data', (data: Buffer) => {
529+
child.stdout.on('data', (data: Buffer) => {
530+
if (options?.logFile) {
529531
appendFileSync(options.logFile, data.toString())
530-
})
531-
}
532+
}
532533

533-
if (options?.onOutput) {
534-
child.stdout.on('data', (data: Buffer) => {
535-
options.onOutput(data.toString())
536-
})
537-
child.stderr.on('data', (data: Buffer) => {
534+
if (options?.onOutput) {
538535
options.onOutput(data.toString())
539-
})
540-
}
536+
}
541537

542-
child.stdout.on('data', (data: Buffer) => {
543538
stdout.push(data.toString().trim())
544539
})
540+
545541
child.stderr.on('data', (data: Buffer) => {
542+
if (options?.logFile) {
543+
appendFileSync(options.logFile, data.toString())
544+
}
545+
546+
if (options?.onOutput) {
547+
options.onOutput(data.toString())
548+
}
549+
546550
stderr.push(data.toString().trim())
547551
})
548552

@@ -563,6 +567,7 @@ async function runLegendaryOrGogdlCommand(
563567
stderr: stderr.join('\n')
564568
})
565569
})
570+
566571
child.on('error', (error) => {
567572
rej(error)
568573
})
@@ -583,22 +588,21 @@ async function runLegendaryOrGogdlCommand(
583588
!`${error}`.includes('appears to be deleted')
584589

585590
logError(
586-
['Error running', runner.name, 'command', `"${safeCommand}": ${error}`],
591+
['Error running', 'command', `"${safeCommand}": ${error}`],
587592
runner.logPrefix,
588593
showDialog
589594
)
595+
590596
return { stdout: '', stderr: `${error}`, fullCommand: safeCommand, error }
591597
})
592598
}
593599

594-
function getLegendaryOrGogdlCommand(
600+
function getRunnerCallWithoutCredentials(
595601
commandParts: string[],
596602
env: Record<string, string> = {},
597603
wrappers: string[] = [],
598604
runnerPath: string
599605
): string {
600-
commandParts = commandParts.filter((n) => n)
601-
602606
// Redact sensitive arguments (SID for Legendary, token for GOGDL)
603607
for (const sensitiveArg of ['--sid', '--token']) {
604608
const sensitiveArgIndex = commandParts.indexOf(sensitiveArg)
@@ -636,6 +640,5 @@ export {
636640
setupWineEnvVars,
637641
setupWrappers,
638642
runWineCommand,
639-
runLegendaryOrGogdlCommand,
640-
getLegendaryOrGogdlCommand
643+
callRunner
641644
}

0 commit comments

Comments
 (0)