Skip to content

Instantly share code, notes, and snippets.

@jahands
Last active May 25, 2018 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jahands/ca33c914f5b3f1a27edf09585914254d to your computer and use it in GitHub Desktop.
Save jahands/ca33c914f5b3f1a27edf09585914254d to your computer and use it in GitHub Desktop.
Backup Factorio saves
<#
.SYNOPSIS
Backs up Factorio save / autosaves
.PARAMETER SaveName
The name of the save file (excluding the .zip extension)
.PARAMETER Auto
Auto backup new saves as you're playing
.PARAMETER SavesPath
Path to Factorio save files.
.PARAMETER RemoteBackupPath
Rclone path to remote
.PARAMETER Cache
Place to store saves during upload
.EXAMPLE
Backup all saves and autosaves for "MySpecialSave" as you're playing.
./Backup-FactorioSaves.ps1 -SaveName "MySpecialSave" -Auto
#>
Param(
[string]$SaveName = "Main",
[switch]$Auto,
[string]$SavesPath = "$env:APPDATA\Factorio\saves",
[string]$RemoteBackupPath = "gd:Gaming/Factorio/Saves/$SaveName",
[string]$Cache = "$env:USERPROFILE\Desktop\FactorioBackupTemp"
)
$gameRunning = $true # Backup at least once
do {
if ($gameRunning) {
Write-Verbose "Game running, doing backup"
$saveHashPath = "$RemoteBackupPath/savelist.txt"
$localSaves = (rclone lsjson --hash $SavesPath | ConvertFrom-Json)
$saves = $localSaves | Where-Object {$_.Name.StartsWith('_autosave') -or $_.Name.StartsWith($SaveName)} | ForEach-Object {$_ | ConvertTo-Json}
$remoteSaveHashes = (rclone cat $saveHashPath)
if ($remoteSaveHashes -eq $null -or $remoteSaveHashes.Count -eq 0) {
$remoteSaves = (rclone lsjson --hash $RemoteBackupPath -R --include '*.zip' | ConvertFrom-Json)
if ($remoteSaves.Hashes -ne $null -and $remoteSaves.Hashes.MD5 -ne $null) {
$remoteSaveHashes = $remoteSaves.Hashes.MD5
}
}
$transferred = $false
$itemsToTransfer = @()
foreach ($save in $saves) {
$s = $save | ConvertFrom-Json
if (-not $remoteSaveHashes.Contains($s.Hashes.MD5)) {
$itemsToTransfer += $s
$transferred = $true
}
}
if (-not (Test-Path $Cache)) {
New-Item -ItemType Directory -Path $Cache
}
foreach ($s in $itemsToTransfer) {
$date = $s.ModTime | Get-Date -Format 'yyyy-MM-dd_HH-mm-ss'
$dest = "$Cache/$($SaveName)_$($date)_main.zip"
if ($s.Name.StartsWith('_autosave')) {
$dest = "$Cache/$($SaveName)_$($date)_auto.zip"
}
$remoteSaveHashes += $s.Hashes.MD5
# copy to cache
rclone -v copyto "$SavesPath\$($s.Path)" $dest
}
# Upload all
if ((Get-ChildItem $Cache).Count -gt 0) {
$dest = "$RemoteBackupPath/$(Get-Date -Format 'yyyy/yyyy-MM/yyyy-MM-dd')"
rclone -v --bwlimit=1.5M copy $Cache $dest --ignore-existing --drive-chunk-size=128M
Get-ChildItem $Cache | Remove-Item
}
# Upload hash list
if ($transferred) {
$tempHashPath = (Get-Item ([System.IO.Path]::GetTempFileName()))
$remoteSaveHashes | Out-File $tempHashPath -Encoding utf8
rclone moveto $tempHashPath.FullName $saveHashPath
}
Write-Verbose "Backup done"
} else {
Write-Verbose "Game not running, skipping backup"
}
if ($Auto) {
Start-Sleep -Seconds (60 * 2)
$gameRunning = (Get-Process -Name factorio -ea:SilentlyContinue) -ne $null
}
}while ($Auto)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment