Jump to content

Recommended Posts

Posted (edited)

Hello all,

I got very annoyed at losing progress in this game by seemingly stupid events (like running a horse into a tree and it finally falling over), or just generally making a mistake of some kind and not being able to roll back progress to a slightly earlier time.

This is one of the most unforgiving games I have every played in terms of being able to roll back progress to an earlier time, and also in terms of how limited the manual save is (it rarely lets you save manually). 

Therefore, I created this powershell script to back up the Profiles folder (which contains save data for the game).

Notes

  1. The script only backs up files when it has detected a change in any of the save files in the profile folder. So it will not be producing an enormous amount of duplicated files every time it runs. 
  2. Replace <your username> and <your profile folder name> in the script below accordingly depending on where the profile folder is for you.
  3. I make this run every 10 minutes using Windows Task Scheduler. The Task Scheduler setup can be seen here: https://imgur.com/a/Ho80oEZ
  4. Save the script below as a .ps1 file and store it in a completely different directory than the profile directory. 
  5. You can try using your own user account to run the task in Task Scheduler, but I had to use a local admin account I created for this purpose to run the task.

Restoring is easy - just delete everything out of the profile folder (<your profile folder name>), and copy the contents of one of the backup folders into the profile folder (<your profile folder name>).

Unsure how well this would work if you have cloud saves enabled. Feel free to try with cloud saves, but I had turned off cloud saves.

This works quite well for me.

Thanks,

Andrew

# Define paths
$sourceDir   = "C:\Users\<your username>\Documents\Rockstar Games\Red Dead Redemption 2\Profiles\<your profile folder name>"
$backupRoot  = "C:\Users\<your username>\Documents\Rockstar Games\Red Dead Redemption 2\Profiles\<your profile folder name>_BACKUPS"
$hashRecord  = "$backupRoot\last_hashes.txt"
$logFile     = "$backupRoot\backup_log.txt"

# Ensure backup root exists
if (-not (Test-Path $backupRoot)) {
    New-Item -ItemType Directory -Path $backupRoot | Out-Null
}

function Log($msg) {
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp - $msg" | Tee-Object -FilePath $logFile -Append
}

function Get-FileHashMap($basePath) {
    $map = @{}
    Get-ChildItem -Path $basePath -File -Recurse | ForEach-Object {
        $relative = $_.FullName.Substring($basePath.Length).TrimStart('\')
        $hash = Get-FileHash -Path $_.FullName -Algorithm SHA256
        $map[$relative] = $hash.Hash
    }
    return $map
}

function Load-PreviousHashes($path) {
    $map = @{}
    if (Test-Path $path) {
        foreach ($line in Get-Content $path) {
            if ($line -match "^([A-Fa-f0-9]{64})\s+(.+)$") {
                $map[$matches[2]] = $matches[1]
            }
        }
    }
    return $map
}

function Save-Hashes($map, $path) {
    $lines = $map.GetEnumerator() | ForEach-Object { "$($_.Value) $($_.Key)" }
    $lines | Set-Content $path
}

function HasChanges($current, $previous) {
    if ($current.Count -ne $previous.Count) { return $true }
    foreach ($key in $current.Keys) {
        if (-not $previous.ContainsKey($key)) { return $true }
        if ($current[$key] -ne $previous[$key]) { return $true }
    }
    return $false
}

Log "Starting backup check..."

$currentHashes = Get-FileHashMap $sourceDir
$previousHashes = Load-PreviousHashes $hashRecord

if (HasChanges $currentHashes $previousHashes) {
    Log "Change detected. Proceeding with backup."

    $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
    $backupDir = Join-Path $backupRoot $timestamp
    New-Item -ItemType Directory -Path $backupDir | Out-Null

    robocopy $sourceDir $backupDir /E /NFL /NDL /NJH /NJS /NC /NS | Out-Null
    Log "Files copied to $backupDir"

    Save-Hashes $currentHashes $hashRecord
    Log "Hash record updated."
} else {
    Log "No changes detected. Backup skipped."
}

 

Edited by AndrewTheArt

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...