Skip to content

[Log] Print installed winetricks packages in logs #3593

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 5 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
67 changes: 59 additions & 8 deletions src/backend/logger/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { appendFile, writeFile } from 'fs/promises'
import { gamesConfigPath, isWindows } from 'backend/constants'
import { gameManagerMap } from 'backend/storeManagers'
import { existsSync, mkdirSync, openSync } from 'graceful-fs'
import { Winetricks } from 'backend/tools'

export enum LogPrefix {
General = '',
Expand Down Expand Up @@ -361,43 +362,71 @@ const logsWriters: Record<string, LogWriter> = {}

// Base abstract class for all LogWriters
class LogWriter {
queue: string[]
queue: (string | Promise<string | string[]>)[]
initialized: boolean
filePath: string
timeoutId: NodeJS.Timeout | undefined
processing: boolean

constructor() {
this.initialized = false
this.queue = []
this.filePath = ''
this.processing = false

if (new.target === LogWriter) {
throw new Error('LogWriter is an abstract class')
}
}

logMessage(message: string) {
/**
* Append a message to the queue
* @param message string or promise that returns a string or string[]
*/
logMessage(message: string | Promise<string | string[]>) {
// push messages to append to the log
this.queue.push(message)

// if the logger is initialized and we don't have a timeout,
// append the message and start a timeout
// if the logger is initialized and we don't have a timeout
// and we are not proccesing the previous batch, write a new batch
//
// otherwise it means there's a timeout already running that will
// write the elements in the queue in a second
if (this.initialized && !this.timeoutId) this.appendMessages()
// write the elements in the queue in a second or that we are processing
// promises
if (this.initialized && !this.processing && !this.timeoutId)
this.appendMessages()
}

async appendMessages() {
const messagesToWrite = this.queue
const itemsInQueue = this.queue

// clear pending message if any
this.queue = []

// clear timeout if any
delete this.timeoutId

if (!messagesToWrite?.length) return
if (!itemsInQueue?.length) return

this.processing = true

// process items in queue, if they are promises we wait
// for them so we can write them in the right order
let messagesToWrite: string[] = []
for (const item of itemsInQueue) {
try {
let result = await item

// support promises returning a string or an array of strings
result = Array.isArray(result) ? result : [result]

messagesToWrite = messagesToWrite.concat(result)
} catch (error) {
logError(error, LogPrefix.Backend)
}
}

this.processing = false

// if we have messages, write them and check again in 1 second
// we start the timeout before writing so we don't wait until
Expand Down Expand Up @@ -504,6 +533,28 @@ export async function initGamePlayLog(gameInfo: GameInfo) {
return logsWriters[`${gameInfo.app_name}-lastPlay`].initLog()
}

export async function appendWinetricksGamePlayLog(gameInfo: GameInfo) {
const logWriter = logsWriters[`${gameInfo.app_name}-lastPlay`]
if (logWriter) {
// append a promise to the queue
logWriter.logMessage(
new Promise((resolve, reject) => {
Winetricks.listInstalled(gameInfo.runner, gameInfo.app_name)
.then((installedPackages) => {
const packagesString = installedPackages
? installedPackages.join(', ')
: 'none'

resolve(`Winetricks packages: ${packagesString}\n\n`)
})
.catch((error) => {
reject(error)
})
})
)
}
}

export function stopLogger(appName: string) {
logsWriters[`${appName}-lastPlay`]?.logMessage(
'============= End of log ============='
Expand Down
3 changes: 3 additions & 0 deletions src/backend/storeManagers/gog/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
} from './electronStores'
import {
appendGamePlayLog,
appendWinetricksGamePlayLog,
logDebug,
logError,
logFileLocation,
Expand Down Expand Up @@ -545,6 +546,8 @@ export async function launch(
return false
}

appendWinetricksGamePlayLog(gameInfo)

commandEnv = {
...commandEnv,
...wineEnvVars
Expand Down
3 changes: 3 additions & 0 deletions src/backend/storeManagers/legendary/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
} from '../../constants'
import {
appendGamePlayLog,
appendWinetricksGamePlayLog,
logError,
logFileLocation,
logInfo,
Expand Down Expand Up @@ -828,6 +829,8 @@ export async function launch(
return false
}

appendWinetricksGamePlayLog(gameInfo)

commandEnv = {
...commandEnv,
...wineEnvVars
Expand Down
3 changes: 3 additions & 0 deletions src/backend/storeManagers/nile/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import {
LogPrefix,
appendGamePlayLog,
appendWinetricksGamePlayLog,
logDebug,
logError,
logFileLocation,
Expand Down Expand Up @@ -371,6 +372,8 @@ export async function launch(
return false
}

appendWinetricksGamePlayLog(gameInfo)

commandEnv = {
...commandEnv,
...wineEnvVars
Expand Down
6 changes: 5 additions & 1 deletion src/backend/storeManagers/storeManagerCommon/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { GameConfig } from '../../game_config'
import { isMac, isLinux, icon } from '../../constants'
import {
appendGamePlayLog,
appendWinetricksGamePlayLog,
lastPlayLogFileLocation,
logInfo,
LogPrefix,
Expand Down Expand Up @@ -162,7 +163,10 @@ export async function launchGame(
steamRuntime
} = await prepareLaunch(gameSettings, gameInfo, isNative)

if (!isNative) await prepareWineLaunch(runner, appName)
if (!isNative) {
await prepareWineLaunch(runner, appName)
appendWinetricksGamePlayLog(gameInfo)
}

const wrappers = setupWrappers(
gameSettings,
Expand Down