@@ -44,6 +44,7 @@ const std::string StatsManager::FROM0_FILE_NAME = "general.dt";
4444const std::string StatsManager::SESSIONS_DIR_NAME = " sessions" ;
4545const std::string StatsManager::BACKUPS_DIR_NAME = " backups" ;
4646arc::TaskHandle<void > StatsManager::backupHandler{};
47+ bool StatsManager::isGameClosing = false ;
4748
4849std::filesystem::path StatsManager::getSavesFolderPath (){
4950 return Settings::getSavePath ();
@@ -337,127 +338,133 @@ Result<> StatsManager::setGeneral(const GeneralData& stats, const std::string& l
337338void StatsManager::addBackup (const std::string& levelKey, bool saveLevelStats, std::optional<int > sessionsToSave, bool showNotifications){
338339 // log::info("adding backup for level {} | {} | {}", levelKey, saveLevelStats, sessionsToSave);
339340
340- if (backupHandler.isValid ()){
341- backupHandler.abort ();
342- }
343-
344341 auto progressFunc = [](float progress01){
345342 // maybe ill use this later for somethn idk bruh
346343 };
347344
348- backupHandler = async::spawn (
349- [levelKey, saveLevelStats, sessionsToSave, progressFunc]() -> arc::Future<Result<>> {
350- std::error_code ec;
351- progressFunc (0 .0f );
352- auto metaRes = getMetadata (levelKey);
353- if (metaRes.isErr ()) co_return Err (" No level to back up! {}" , metaRes.unwrapErr ().error );
354- auto metadata = metaRes.unwrap ();
355-
356- createFilesIfNeeded (levelKey);
357- progressFunc (0 .1f );
358-
359- auto levelBackupsFilePath = getSavesFolderPath () / levelKey / StatsManager::BACKUPS_DIR_NAME;
345+ auto backupFunc = [levelKey, saveLevelStats, sessionsToSave, progressFunc]() -> arc::Future<Result<>> {
346+ std::error_code ec;
347+ progressFunc (0 .0f );
348+ auto metaRes = getMetadata (levelKey);
349+ if (metaRes.isErr ()) co_return Err (" No level to back up! {}" , metaRes.unwrapErr ().error );
350+ auto metadata = metaRes.unwrap ();
351+
352+ createFilesIfNeeded (levelKey);
353+ progressFunc (0 .1f );
360354
361- auto lvlBackupsDirRes = geode::utils::file::createDirectory (levelBackupsFilePath);
362- if (lvlBackupsDirRes.isErr ()) co_return Err (" failed to create backups folder! {}" , lvlBackupsDirRes.unwrapErr ());
355+ auto levelBackupsFilePath = getSavesFolderPath () / levelKey / StatsManager::BACKUPS_DIR_NAME;
363356
364- auto currBackupName = StatsManager::getNowSeconds ();
357+ auto lvlBackupsDirRes = geode::utils::file::createDirectory (levelBackupsFilePath);
358+ if (lvlBackupsDirRes.isErr ()) co_return Err (" failed to create backups folder! {}" , lvlBackupsDirRes.unwrapErr ());
365359
366- levelBackupsFilePath /= std::to_string (currBackupName );
360+ auto currBackupName = StatsManager::getNowSeconds ( );
367361
368- auto lvlBackupDirRes = geode::utils::file::createDirectory (levelBackupsFilePath);
369- if (lvlBackupDirRes.isErr ()) co_return Err (" failed to create backup folder! {}" , lvlBackupDirRes.unwrapErr ());
370- progressFunc (0 .2f );
362+ levelBackupsFilePath /= std::to_string (currBackupName);
371363
372- if (saveLevelStats){
364+ auto lvlBackupDirRes = geode::utils::file::createDirectory (levelBackupsFilePath);
365+ if (lvlBackupDirRes.isErr ()) co_return Err (" failed to create backup folder! {}" , lvlBackupDirRes.unwrapErr ());
366+ progressFunc (0 .2f );
373367
374- if (getGeneral (levelKey).isErr ()){
375- (void )deleteBackup (levelKey, currBackupName);
368+ if (saveLevelStats){
376369
377- co_return Err ( " backup failed! failed to read general stats " );
378- }
370+ if ( getGeneral (levelKey). isErr ()){
371+ ( void ) deleteBackup (levelKey, currBackupName);
379372
380- std::filesystem::copy_file (getSavesFolderPath () / levelKey / StatsManager::FROM0_FILE_NAME, levelBackupsFilePath / StatsManager::FROM0_FILE_NAME, std::filesystem::copy_options::overwrite_existing, ec);
381- if (ec) co_return Err (" Failed to backup level stats: {}" , ec.message ());
373+ co_return Err (" backup failed! failed to read general stats" );
382374 }
383- progressFunc (0 .35f );
384375
385- auto backupsAmount = Settings::getMaxBackupAmount ();
376+ std::filesystem::copy_file (getSavesFolderPath () / levelKey / StatsManager::FROM0_FILE_NAME, levelBackupsFilePath / StatsManager::FROM0_FILE_NAME, std::filesystem::copy_options::overwrite_existing, ec);
377+ if (ec) co_return Err (" Failed to backup level stats: {}" , ec.message ());
378+ }
379+ progressFunc (0 .35f );
386380
387- if (backupsAmount != std::nullopt ){
388- auto count = getBackupsCount (levelKey);
381+ auto backupsAmount = Settings::getMaxBackupAmount ();
389382
390- if (count.size () > backupsAmount.value ()){
391- int index = 0 ;
392- for (const auto & backupName : count)
393- {
394- if (index == count.size () - backupsAmount.value ()) break ;
383+ if (backupsAmount != std::nullopt ){
384+ auto count = getBackupsCount (levelKey);
395385
396- (void )deleteBackup (levelKey, backupName);
386+ if (count.size () > backupsAmount.value ()){
387+ int index = 0 ;
388+ for (const auto & backupName : count)
389+ {
390+ if (index == count.size () - backupsAmount.value ()) break ;
391+
392+ (void )deleteBackup (levelKey, backupName);
397393
398- index++;
399- }
394+ index++;
400395 }
401396 }
402- progressFunc (0 .5f );
397+ }
398+ progressFunc (0 .5f );
403399
404- std::filesystem::copy_file (getSavesFolderPath () / levelKey / StatsManager::METADATA_FILE_NAME, levelBackupsFilePath / StatsManager::METADATA_FILE_NAME, std::filesystem::copy_options::overwrite_existing, ec);
405- if (ec) co_return Err (" Failed to backup level metadata: {}" , ec.message ());
406- progressFunc (0 .7f );
400+ std::filesystem::copy_file (getSavesFolderPath () / levelKey / StatsManager::METADATA_FILE_NAME, levelBackupsFilePath / StatsManager::METADATA_FILE_NAME, std::filesystem::copy_options::overwrite_existing, ec);
401+ if (ec) co_return Err (" Failed to backup level metadata: {}" , ec.message ());
402+ progressFunc (0 .7f );
407403
408- if (sessionsToSave == std::nullopt ) {
409- progressFunc (1 .0f );
410- co_return Ok ();
411- }
404+ if (sessionsToSave == std::nullopt ) {
405+ progressFunc (1 .0f );
406+ co_return Ok ();
407+ }
412408
413- if (sessionsToSave.value () >= -1 ){
414- levelBackupsFilePath /= StatsManager::SESSIONS_DIR_NAME;
409+ if (sessionsToSave.value () >= -1 ){
410+ levelBackupsFilePath /= StatsManager::SESSIONS_DIR_NAME;
415411
416- auto lvlBackupsDirRes = geode::utils::file::createDirectory (levelBackupsFilePath);
417- if (lvlBackupsDirRes.isErr ()) co_return Err (" failed to create backup sessions folder! {}" , lvlBackupsDirRes.unwrapErr ());
412+ auto lvlBackupsDirRes = geode::utils::file::createDirectory (levelBackupsFilePath);
413+ if (lvlBackupsDirRes.isErr ()) co_return Err (" failed to create backup sessions folder! {}" , lvlBackupsDirRes.unwrapErr ());
418414
419- std::set<long long , std::greater<long long >> sessionTimes{};
420- auto nonSorted = getAllSessionTimesForLevel (levelKey);
421- sessionTimes.insert (nonSorted.begin (), nonSorted.end ());
415+ std::set<long long , std::greater<long long >> sessionTimes{};
416+ auto nonSorted = getAllSessionTimesForLevel (levelKey);
417+ sessionTimes.insert (nonSorted.begin (), nonSorted.end ());
422418
423- int numToSave = sessionsToSave.value ();
424- if (numToSave == -1 )
425- numToSave = sessionTimes.size ();
419+ int numToSave = sessionsToSave.value ();
420+ if (numToSave == -1 )
421+ numToSave = sessionTimes.size ();
426422
427- int index = 0 ;
428- for (const auto & sessionTime : sessionTimes)
429- {
430- if (index == numToSave) break ;
431-
432- if (getSession (levelKey, sessionTime).isErr ()){
433- log::error (" Failed to backup session {}" , sessionTime);
434- index++;
435- continue ;
436- }
437-
438- std::filesystem::copy_file (
439- getSavesFolderPath () / levelKey / StatsManager::SESSIONS_DIR_NAME / (std::to_string (sessionTime) + " .dt" ),
440- levelBackupsFilePath / (std::to_string (sessionTime) + " .dt" ),
441- std::filesystem::copy_options::overwrite_existing,
442- ec
443- );
444- if (ec) co_return Err (" Failed to backup session {}: {}" , sessionTime, ec.message ());
423+ int index = 0 ;
424+ for (const auto & sessionTime : sessionTimes)
425+ {
426+ if (index == numToSave) break ;
445427
428+ if (getSession (levelKey, sessionTime).isErr ()){
429+ log::error (" Failed to backup session {}" , sessionTime);
446430 index++;
447- if (numToSave > 0 ) {
448- float sessionProgress = 0 .7f + 0 .3f * (static_cast <float >(index) / static_cast <float >(numToSave));
449- if (sessionProgress > 1 .0f ) sessionProgress = 1 .0f ;
450- progressFunc (sessionProgress);
451- }
431+ continue ;
452432 }
453433
454- if (!sessionTimes.size ())
455- progressFunc (1 .0f );
434+ std::filesystem::copy_file (
435+ getSavesFolderPath () / levelKey / StatsManager::SESSIONS_DIR_NAME / (std::to_string (sessionTime) + " .dt" ),
436+ levelBackupsFilePath / (std::to_string (sessionTime) + " .dt" ),
437+ std::filesystem::copy_options::overwrite_existing,
438+ ec
439+ );
440+ if (ec) co_return Err (" Failed to backup session {}: {}" , sessionTime, ec.message ());
441+
442+ index++;
443+ if (numToSave > 0 ) {
444+ float sessionProgress = 0 .7f + 0 .3f * (static_cast <float >(index) / static_cast <float >(numToSave));
445+ if (sessionProgress > 1 .0f ) sessionProgress = 1 .0f ;
446+ progressFunc (sessionProgress);
447+ }
456448 }
457- else progressFunc (1 .0f );
458-
459- co_return Ok ();
460- },
449+
450+ if (!sessionTimes.size ())
451+ progressFunc (1 .0f );
452+ }
453+ else progressFunc (1 .0f );
454+
455+ co_return Ok ();
456+ };
457+
458+ if (StatsManager::isGameClosing){
459+ return ;
460+ }
461+
462+ if (backupHandler.isValid ()){
463+ backupHandler.abort ();
464+ }
465+
466+ backupHandler = async::spawn (
467+ backupFunc,
461468 [showNotifications](Result<> res){
462469 if (!showNotifications) return ;
463470
0 commit comments