Skip to content

Commit

Permalink
[Improv]: Add opt out of playtime tracking (Heroic-Games-Launcher#3002)
Browse files Browse the repository at this point in the history
* improv: stop registering playtime on suspend, add option to disable playtime tracking

* generate i18n

* Update src/backend/main.ts

Co-authored-by: Ariel Juodziukynas <[email protected]>

* improv: add help, respect disable sync for pulling game time

* rollback suspend changes

* avoid confusing log messages for playtime sync

---------

Co-authored-by: Ariel Juodziukynas <[email protected]>
  • Loading branch information
imLinguin and arielj authored Oct 2, 2023
1 parent dac5965 commit 695f1c6
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 8 deletions.
2 changes: 2 additions & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
"custom_themes_path": "Do not use CSS files from untrusted sources. When in doubt, ask for a review in our Discord channel.",
"custom_themes_wiki": "Check the Wiki for more details on adding custom themes. Click here.",
"disable_logs": "Toggle this checkbox ON to disable most of the writes to log files (critical information is always logged). Make sure to turn OFF this setting before reporting any issue.",
"disablePlaytimeSync": "Disables playtime synchronization with given store's servers (currently only GOG is supported)",
"dxvk": "DXVK is a Vulkan-based translational layer for DirectX 9, 10 and 11 games. Enabling may improve compatibility. Might cause issues especially for older DirectX games.",
"dxvkfpslimit": "Sets a frame rate cap for DXVK games",
"dxvknvapi": "DXVK-NVAPI is an implementation of NVAPI built on top of DXVK and the linux native NVAPI, it allows for the usage of DLSS on Nvidia GPUs.",
Expand Down Expand Up @@ -500,6 +501,7 @@
"defaultWinePrefix": "Set Folder for new Wine Prefixes",
"disable_controller": "Disable Heroic navigation using controller",
"disable_logs": "Disable Logs",
"disablePlaytimeSync": "Disable playtime synchronization",
"discordRPC": "Enable Discord Rich Presence",
"download-no-https": "Download games without HTTPS (useful for CDNs e.g. LanCache)",
"dxvkfpslimit": "Limit FPS (DX9, 10 and 11)",
Expand Down
24 changes: 20 additions & 4 deletions src/backend/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,13 @@ if (!gotTheLock) {

// Make sure lock is not present when starting up
playtimeSyncQueue.delete('lock')
runOnceWhenOnline(syncQueuedPlaytimeGOG)

if (!settings.disablePlaytimeSync) {
runOnceWhenOnline(syncQueuedPlaytimeGOG)
} else {
logDebug('Skipping playtime sync queue upload - playtime sync disabled', {
prefix: LogPrefix.Backend
})
}
await i18next.use(Backend).init({
backend: {
addPath: path.join(publicDir, 'locales', '{{lng}}', '{{ns}}'),
Expand Down Expand Up @@ -1092,10 +1097,17 @@ ipcMain.handle(
sessionPlaytime + tsStore.get(`${appName}.totalPlayed`, 0)
tsStore.set(`${appName}.totalPlayed`, Math.floor(totalPlaytime))

const { disablePlaytimeSync } = GlobalConfig.get().getSettings()
if (runner === 'gog') {
await updateGOGPlaytime(appName, startPlayingDate, finishedPlayingDate)
if (!disablePlaytimeSync) {
await updateGOGPlaytime(appName, startPlayingDate, finishedPlayingDate)
} else {
logWarning(
'Posting playtime session to server skipped - playtime sync disabled',
{ prefix: LogPrefix.Backend }
)
}
}

await addRecentGame(game)

if (autoSyncSaves && isOnline()) {
Expand Down Expand Up @@ -1670,6 +1682,10 @@ ipcMain.on('processShortcut', async (e, combination: string) => {
ipcMain.handle(
'getPlaytimeFromRunner',
async (e, runner, appName): Promise<number | undefined> => {
const { disablePlaytimeSync } = GlobalConfig.get().getSettings()
if (disablePlaytimeSync) {
return
}
if (runner === 'gog') {
return getGOGPlaytime(appName)
}
Expand Down
4 changes: 3 additions & 1 deletion src/backend/storeManagers/gog/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,9 @@ export async function updateGOGPlaytime(
return
}

const response = await postPlaytimeSession({ ...data, appName })
const response = await postPlaytimeSession({ ...data, appName }).catch(
() => null
)

if (!response || response.status !== 201) {
logError('Failed to post session', { prefix: LogPrefix.Gog })
Expand Down
1 change: 1 addition & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export interface AppSettings extends GameSettings {
defaultSteamPath: string
defaultWinePrefix: string
disableController: boolean
disablePlaytimeSync: boolean
disableLogs: boolean
discordRPC: boolean
downloadNoHttps: boolean
Expand Down
44 changes: 44 additions & 0 deletions src/frontend/screens/Settings/components/PlaytimeSync.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { ToggleSwitch } from 'frontend/components/UI'
import useSetting from 'frontend/hooks/useSetting'
import SettingsContext from '../SettingsContext'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCircleInfo } from '@fortawesome/free-solid-svg-icons'

const PlaytimeSync = () => {
const { t } = useTranslation()
const { isDefault } = useContext(SettingsContext)
const [disablePlaytimeSync, setDisablePlaytimeSync] = useSetting(
'disablePlaytimeSync',
false
)

if (!isDefault) {
return <></>
}

return (
<div className="toggleRow">
<ToggleSwitch
htmlId="disablePlaytimeSync"
value={disablePlaytimeSync}
handleChange={() => setDisablePlaytimeSync(!disablePlaytimeSync)}
title={t(
'setting.disablePlaytimeSync',
'Disable playtime synchronization'
)}
/>
<FontAwesomeIcon
className="helpIcon"
icon={faCircleInfo}
title={t(
'help.disablePlaytimeSync',
"Disables playtime synchronization with given store's servers (currently only GOG is supported)"
)}
/>
</div>
)
}

export default PlaytimeSync
1 change: 1 addition & 0 deletions src/frontend/screens/Settings/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ export { default as WinePrefixesBasePath } from './WinePrefixesBasePath'
export { default as WineVersionSelector } from './WineVersionSelector'
export { default as WrappersTable } from './WrappersTable'
export { default as EnableDXVKFpsLimit } from './EnableDXVKFpsLimit'
export { default as PlaytimeSync } from './PlaytimeSync'
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import {
Shortcuts,
TraySettings,
UseDarkTrayIcon,
WinePrefixesBasePath
WinePrefixesBasePath,
PlaytimeSync
} from '../../components'

export default function GeneralSettings() {
const { t } = useTranslation()

return (
<>
<div>
<h3 className="settingSubheader">{t('settings.navbar.general')}</h3>

<LanguageSelector />
Expand Down Expand Up @@ -57,6 +58,8 @@ export default function GeneralSettings() {

<Shortcuts />

<PlaytimeSync />

<DiscordRPC />

<DisableController />
Expand All @@ -66,6 +69,6 @@ export default function GeneralSettings() {
<MaxRecentGames />

<MaxWorkers />
</>
</div>
)
}

0 comments on commit 695f1c6

Please sign in to comment.