Far Cry Primal

Far Cry Primal

Not enough ratings
Менеджер сохранений для режима Окончательной Смерти(Permadeath)
By VaultBoee
Этот инструмент автоматически создает резервные копии ваших сохранений Far Cry Primal во время игры и позволяет восстанавливать предыдущие резервные копии.

Go to English Version
   
Award
Favorite
Favorited
Unfavorite
Возможности
  • Создает резервные копии каждую минуту (настраивается) или при нажатии Enter
  • Организует сохранения с метками времени для удобства
  • Нажмите R для просмотра и восстановления любой резервной копии (идеально для режима Permadeath!)
  • Сохраняет ваш прогресс в безопасности во время сложного геймплея
Отключение облачной синхронизации сохранений в Uplay
Прежде чем я начну объяснять, как работать с вашими файлами сохранений, я настоятельно рекомендую вам отключить облачную синхронизацию сохранений. Методы, которые я собираюсь предложить, могут работать неправильно при включенной облачной синхронизации. Кроме того, лучше делать собственные резервные копии сохранений, чем полагаться на облако Ubisoft – было множество случаев, когда облачные сохранения повреждались, и пользователи теряли весь свой прогресс.
Вы можете отключить облачную синхронизацию сохранений в общих настройках Uplay:
Код
$Source="2029"; $BackupRoot=$Source+"-backups"; $GameProcess="FCPrimal*" $TimeoutSeconds=60; $MaxBackups=100; $PageSize=10 if(-not(Test-Path $BackupRoot)){ New-Item -ItemType Directory -Path $BackupRoot -Force|Out-Null } function Update-StatusLine{ param([string]$Message,[System.ConsoleColor]$Color=[System.ConsoleColor]::White) Write-Host -NoNewline "`r$(' '*120)"; Write-Host -NoNewline "`r$Message" -ForegroundColor $Color } function Get-LastBackupInfo{ $backups=@(Get-ChildItem -Path $BackupRoot -Directory|Sort-Object CreationTime -Descending) if($backups.Count -eq 0){return "No backups found"} return "$($backups[0].Name) - Created: $($backups[0].CreationTime)" } function Reset-Screen{ Clear-Host; Write-Host "===== Far Cry Primal Save Backup System =====" -ForegroundColor Cyan Write-Host "Backup interval: $TimeoutSeconds seconds" -ForegroundColor Gray Write-Host "Maximum backups: $MaxBackups" -ForegroundColor Gray Write-Host "Last backup: $(Get-LastBackupInfo)" -ForegroundColor Yellow Write-Host "=============================================" -ForegroundColor Cyan Write-Host "Press [Enter] for manual backup, [R] to restore." -ForegroundColor Cyan; Write-Host } function List-Backups{ param([int]$Page=1,[switch]$CountOnly) $backups=@(Get-ChildItem -Path $BackupRoot -Directory|Sort-Object CreationTime -Descending) if($backups.Count -eq 0){ Update-StatusLine "No backups found." -Color Red; Write-Host; return $false } if($CountOnly){return $backups} $totalPages=[math]::Ceiling($backups.Count/$PageSize) if($Page -lt 1){$Page=1}; if($Page -gt $totalPages){$Page=$totalPages} $start=($Page-1)*$PageSize; $end=[math]::Min($start+$PageSize-1,$backups.Count-1) Write-Host; Write-Host "Available backups (Page $Page of $totalPages):" -ForegroundColor Cyan for($i=$start;$i -le $end;$i++){ Write-Host "[$(($i+1))] $($backups[$i].Name) - Created: $($backups[$i].CreationTime)" -ForegroundColor Green } Write-Host; Write-Host "Showing backups $($start+1)-$($end+1) of $($backups.Count)" -ForegroundColor Gray if($totalPages -gt 1){ Write-Host "Type 'N' for next page, 'P' for previous page, or a backup ID to restore." -ForegroundColor Cyan } return $backups } function Cleanup-OldBackups{ $backups=@(Get-ChildItem -Path $BackupRoot -Directory|Sort-Object CreationTime) $backupsToRemove=$backups.Count-$MaxBackups if($backupsToRemove -gt 0){ for($i=0;$i -lt $backupsToRemove;$i++){ Remove-Item -Path $backups[$i].FullName -Recurse -Force } } } function Create-Backup{ $saveFile=Join-Path $Source "1.save" if(-not(Test-Path $saveFile)){ Update-StatusLine "Save file does not exist!" -Color Red; Start-Sleep -Seconds 1; return } $fileAccessible=$false; $attempts=0 while(-not $fileAccessible -and $attempts -lt 5){ try{ $stream=[System.IO.File]::Open($saveFile,'Open','Read','ReadWrite'); $stream.Close(); $fileAccessible=$true } catch{ $attempts++; Update-StatusLine "Waiting for save file to be unlocked... (Attempt $attempts/5)" -Color Yellow; Start-Sleep -Seconds 1 } } if(-not $fileAccessible){ Update-StatusLine "Could not access save file after 5 attempts." -Color Red; Start-Sleep -Seconds 1; return } $now=Get-Date; $dest=Join-Path $BackupRoot ("backup-{0:yyyy-MM-dd_HH-mm-ss}\2029" -f $now) New-Item -ItemType Directory -Path $dest -Force|Out-Null Update-StatusLine "Backing up save files to $dest..." -Color Green Copy-Item -Path "$Source\*" -Destination $dest -Recurse -Force Update-StatusLine "Backup completed at $($now.ToString("HH:mm:ss"))" -Color Green Cleanup-OldBackups; Reset-Screen } function Restore-Backup{ $inRestoreMode=$true; Write-Host Write-Host "IMPORTANT: Make sure you're closed the game before restoring a save!" -ForegroundColor Yellow; Write-Host try{ $page=1; $backups=List-Backups -Page $page if(-not $backups){ Reset-Screen; return } $restored=$false while(-not $restored){ $input=Read-Host "Enter backup ID to restore, 'N' for next page, 'P' for previous page, or press Enter to cancel" if([string]::IsNullOrEmpty($input)){ Reset-Screen; return } if($input -eq "N" -or $input -eq "n"){ $page++; $backups=List-Backups -Page $page; continue } elseif($input -eq "P" -or $input -eq "p"){ $page--; $backups=List-Backups -Page $page; continue } $idNum=0 if(-not [int]::TryParse($input,[ref]$idNum)){ Update-StatusLine "Invalid input. Please enter a number or N/P for pagination." -Color Red; Start-Sleep -Seconds 1; continue } if($idNum -lt 1 -or $idNum -gt $backups.Count){ Update-StatusLine "ID out of range. Please enter a valid ID." -Color Red; Start-Sleep -Seconds 1; continue } $selectedBackup=$backups[$idNum-1]; $backupSourcePath=Join-Path $selectedBackup.FullName "2029" if(-not(Test-Path $backupSourcePath)){ Update-StatusLine "Backup files not found. The backup may be corrupted." -Color Red; Start-Sleep -Seconds 1; continue } Update-StatusLine "Restoring backup: $($selectedBackup.Name)" -Color Yellow if(-not(Test-Path $Source)){ New-Item -ItemType Directory -Path $Source -Force|Out-Null } Copy-Item -Path "$backupSourcePath\*" -Destination $Source -Recurse -Force Update-StatusLine "Backup restored successfully!" -Color Green; Start-Sleep -Seconds 1 $restored=$true; Reset-Screen Update-StatusLine "Backup $($selectedBackup.Name) restored. Next backup in $TimeoutSeconds seconds." -Color Green } }finally{ $inRestoreMode=$false } } Reset-Screen $lastBackupTime=Get-Date; $gameWasRunning=$false; $inRestoreMode=$false; $lastStatusMessage="" while($true){ $gameIsRunning=$null -ne (Get-Process|Where-Object{$_.ProcessName -like $GameProcess}|Select-Object -First 1) if($gameIsRunning -and -not $gameWasRunning){ Update-StatusLine "Game is running. Backup system active." -Color Green; Start-Sleep -Seconds 1 }elseif(-not $gameIsRunning -and $gameWasRunning){ Update-StatusLine "Game is not running. Waiting for game to start..." -Color Yellow } $gameWasRunning=$gameIsRunning if(-not $inRestoreMode -and [Console]::KeyAvailable){ $key=[Console]::ReadKey($true) if($key.Key -eq "Enter"){ Update-StatusLine "Manual backup requested" -Color Cyan if($gameIsRunning){ Create-Backup; $lastBackupTime=Get-Date } else{ Update-StatusLine "Game is not running, backup not created." -Color Yellow; Start-Sleep -Seconds 1 } }elseif($key.Key -eq "R"){ Update-StatusLine "Restore requested" -Color Cyan; Start-Sleep -Milliseconds 500 $inRestoreMode=$true; Restore-Backup; $inRestoreMode=$false; $lastBackupTime=Get-Date } } if(-not $inRestoreMode -and $gameIsRunning){ $currentTime=Get-Date; $timeDiff=($currentTime-$lastBackupTime).TotalSeconds if($timeDiff -ge $TimeoutSeconds){ Create-Backup; $lastBackupTime=Get-Date } $timeLeft=[Math]::Max(0,$TimeoutSeconds-$timeDiff) $statusMessage="Next backup in $([Math]::Ceiling($timeLeft)) seconds. Press [Enter] for manual backup, [R] to restore." if($statusMessage -ne $lastStatusMessage){ Update-StatusLine $statusMessage -Color Cyan; $lastStatusMessage=$statusMessage } }elseif(-not $inRestoreMode -and -not $gameIsRunning){ $statusMessage="Waiting for game to start. Press [Enter] to force backup, [R] to restore." if($statusMessage -ne $lastStatusMessage){ Update-StatusLine $statusMessage -Color Yellow; $lastStatusMessage=$statusMessage } } Start-Sleep -Milliseconds 100 }
Установка и использование
Создание файла скрипта:
  • Откройте Блокнот
  • Скопируйте и вставьте код, приведенный выше
  • Сохраните как "Save_backup.ps1" в следующем месте:
    C:\Program Files (x86)\Ubisoft\Ubisoft Game Launcher\savegames\ВАШ-УНИКАЛЬНЫЙ-ID\
  • Скрипт должен находиться в той же папке, что и папка игровых сохранений "2029"

Поиск местоположения сохранений:
  • Найдите папку, содержащую директорию "2029"
  • Разместите скрипт рядом с папкой "2029", а не внутри нее

Запуск скрипта:
  • Щелкните правой кнопкой мыши на файле PS1
  • Выберите "Запустить с помощью PowerShell"
  • Если появится запрос о политике выполнения, введите "Y"

Использование:
  • Держите окно PowerShell открытым во время игры
  • Нажмите Enter в любое время для немедленного резервного копирования
  • Нажмите R для просмотра и восстановления резервных копий
  • ВАЖНО: Закройте игру перед восстановлением сохранения!
Примечания
  • Запустите скрипт перед запуском игры
  • Чтобы изменить частоту резервного копирования, отредактируйте значение $TimeoutSeconds (60 = 1 минута)
  • Чтобы изменить максимальное количество хранимых резервных копий, отредактируйте значение $MaxBackups (по умолчанию: 100)
  • Наслаждайтесь игрой без разочарования от постоянной смерти!

Параметры настройки:
Вы можете изменить эти параметры в начале скрипта:
  • $TimeoutSeconds - Время между автоматическими резервными копиями (в секундах)
  • $MaxBackups - Максимальное количество резервных копий, хранимых перед удалением старых
  • $PageSize - Количество резервных копий, отображаемых на странице при восстановлении
Решение проблемы с политикой выполнения скриптов при запуске PS1 файла
Иногда при попытке запустить файл PowerShell с расширением
.ps1
вы можете столкнуться с ошибкой, связанной с политикой выполнения скриптов. Это руководство покажет вам, как решить эту проблему, не требуя прав администратора, используя команду
Set-ExecutionPolicy
. Если ваш файл запускается без проблем, то вам не потребуется выполнять эти шаги.

Пошаговая инструкция
    [] Откройте PowerShell: Найдите "PowerShell" в меню "Пуск" Windows и откройте его. Вам не нужно запускать его от имени администратора для этого метода.[] Измените политику выполнения: В окне PowerShell введите следующую команду:
    Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
    Эта команда устанавливает политику выполнения RemoteSigned только для текущего пользователя. Это означает, что скрипты, которые вы создали на своем компьютере, будут запускаться без проблем, а скрипты, загруженные из интернета, должны быть подписаны доверенным издателем, прежде чем они смогут быть выполнены. Это обеспечивает баланс между безопасностью и удобством.[] Подтвердите изменение: PowerShell может попросить вас подтвердить изменение политики выполнения. Нажмите
    Y
    и затем
    Enter
    , чтобы продолжить.[] Запустите ваш PS1 файл: Теперь вы можете запустить ваш
    .ps1
    файл, просто набрав его полный путь в PowerShell (например,
    C:\MyScripts\MyScript.ps1
    ) или перейдя в каталог, где находится файл, и набрав его имя (например,
    .\MyScript.ps1
    ).
3 Comments
Akunamatata 6 Oct @ 12:38am 
И, кстати, держи придуманный мной способ создания двуязычных гайдов ;)
https://github.com/IsThereAnyDeal/AugmentedSteam/issues/2126#issuecomment-2652652565
(Это чтобы можно было объединять английский и русский гайды в один, и в описании отображались оба языка.)
Akunamatata 6 Oct @ 12:32am 
Продолжение:
А что касается дополнительного автоматического ежеминутного бэкапа на случай смерти, достаточно одного "плывущего" сохранения, все предыдущие не нужны (если нужно откатиться к определённой точке, есть ручные сохранения, как я описал раньше, и их намного проще искать - их меньше, чем 100 штук как у тебя, и есть пояснения в названиях). Но тут важно, чтобы алгоритм перестал копировать папку, если случилась окончательная смерть. Для этого достаточно коротенького бат-файла, как у меня описано тут: steamproxy.net/sharedfiles/filedetails/?id=859358501
Akunamatata 6 Oct @ 12:21am 
Молодец, что проделал такую работу, но мне кажется, что это всё слишком сложно и алгоритм не продуман до конца, так что получилось не очень рационально... С одной стороны, если нужны точки отката к определённым моментам игры, достаточно просто держать папку с сохранениями открытой, переключаться на неё и нажимать Ctrl+C➔Ctrl+V, чтобы создавать пронумерованные копии папки 2029, и можно сразу дописывать краткие пояснения к именам папок, чтобы потом проще было искать. И тут совершенно не нужна функция очистки старых папок...