diff --git a/src/main/constants.ts b/src/main/constants.ts index 243891e7..5625a53e 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -4,7 +4,8 @@ import { SystemPath } from "./services/system-path"; export const defaultDownloadsPath = SystemPath.getPath("downloads"); -export const isStaging = import.meta.env.MAIN_VITE_API_URL.includes("staging"); +export const isStaging = + true || import.meta.env.MAIN_VITE_API_URL.includes("staging"); export const windowsStartMenuPath = path.join( SystemPath.getPath("appData"), @@ -26,11 +27,10 @@ export const commonRedistPath = path.join( "CommonRedist" ); -export const logsPath = path.join(SystemPath.getPath("userData"), "logs"); - -export const seedsPath = app.isPackaged - ? path.join(process.resourcesPath, "seeds") - : path.join(__dirname, "..", "..", "seeds"); +export const logsPath = path.join( + SystemPath.getPath("userData"), + `logs${isStaging ? "-staging" : ""}` +); export const achievementSoundPath = app.isPackaged ? path.join(process.resourcesPath, "achievement.wav") diff --git a/src/main/index.ts b/src/main/index.ts index 5151b956..abe3b17a 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -4,7 +4,7 @@ import i18n from "i18next"; import path from "node:path"; import url from "node:url"; import { electronApp, optimizer } from "@electron-toolkit/utils"; -import { logger, WindowManager } from "@main/services"; +import { logger, clearGamesPlaytime, WindowManager } from "@main/services"; import resources from "@locales"; import { PythonRPC } from "./services/python-rpc"; import { db, levelKeys } from "./level"; diff --git a/src/main/services/process-watcher.ts b/src/main/services/process-watcher.ts index dd051760..cacc6734 100644 --- a/src/main/services/process-watcher.ts +++ b/src/main/services/process-watcher.ts @@ -225,7 +225,18 @@ function onOpenGame(game: Game) { }); if (game.remoteId) { - updateGamePlaytime(game, 0, new Date()).catch(() => {}); + updateGamePlaytime( + game, + game.unsyncedDeltaPlayTimeInMilliseconds ?? 0, + new Date() + ) + .then(() => { + gamesSublevel.put(levelKeys.game(game.shop, game.objectId), { + ...game, + unsyncedDeltaPlayTimeInMilliseconds: 0, + }); + }) + .catch(() => {}); if (game.automaticCloudSync) { CloudSync.uploadSaveGame( @@ -260,22 +271,34 @@ function onTickGame(game: Game) { }); if (currentTick % TICKS_TO_UPDATE_API === 0) { + const deltaToSync = + now - + gamePlaytime.lastSyncTick + + (game.unsyncedDeltaPlayTimeInMilliseconds ?? 0); + const gamePromise = game.remoteId - ? updateGamePlaytime( - game, - now - gamePlaytime.lastSyncTick, - game.lastTimePlayed! - ) + ? updateGamePlaytime(game, deltaToSync, game.lastTimePlayed!) : createGame(game); gamePromise .then(() => { + gamesSublevel.put(levelKeys.game(game.shop, game.objectId), { + ...game, + unsyncedDeltaPlayTimeInMilliseconds: 0, + }); + }) + .catch(() => { + gamesSublevel.put(levelKeys.game(game.shop, game.objectId), { + ...game, + unsyncedDeltaPlayTimeInMilliseconds: deltaToSync, + }); + }) + .finally(() => { gamesPlaytime.set(levelKeys.game(game.shop, game.objectId), { ...gamePlaytime, lastSyncTick: now, }); - }) - .catch(() => {}); + }); } } @@ -286,12 +309,6 @@ const onCloseGame = (game: Game) => { gamesPlaytime.delete(levelKeys.game(game.shop, game.objectId)); if (game.remoteId) { - updateGamePlaytime( - game, - performance.now() - gamePlaytime.lastSyncTick, - game.lastTimePlayed! - ).catch(() => {}); - if (game.automaticCloudSync) { CloudSync.uploadSaveGame( game.objectId, @@ -300,7 +317,26 @@ const onCloseGame = (game: Game) => { CloudSync.getBackupLabel(true) ); } + + const deltaToSync = + performance.now() - + gamePlaytime.lastSyncTick + + (game.unsyncedDeltaPlayTimeInMilliseconds ?? 0); + + return updateGamePlaytime(game, deltaToSync, game.lastTimePlayed!) + .then(() => { + return gamesSublevel.put(levelKeys.game(game.shop, game.objectId), { + ...game, + unsyncedDeltaPlayTimeInMilliseconds: 0, + }); + }) + .catch(() => { + return gamesSublevel.put(levelKeys.game(game.shop, game.objectId), { + ...game, + unsyncedDeltaPlayTimeInMilliseconds: deltaToSync, + }); + }); } else { - createGame(game).catch(() => {}); + return createGame(game).catch(() => {}); } }; diff --git a/src/types/level.types.ts b/src/types/level.types.ts index fd904ca5..6a729cc5 100644 --- a/src/types/level.types.ts +++ b/src/types/level.types.ts @@ -34,6 +34,7 @@ export interface Game { title: string; iconUrl: string | null; playTimeInMilliseconds: number; + unsyncedDeltaPlayTimeInMilliseconds?: number; lastTimePlayed: Date | null; objectId: string; shop: GameShop;