Page 1 of 1
Factorio auto-update script
Posted: Mon May 20, 2019 6:49 pm
by Nidhoegger666
I have written a script to trigger an auto update on linux, if you are interested. You might need to adjust paths and stuff to fit your needs. To trigger the script, send SIGUSR1 to the bash that executes the script and it will check for updates (currently in the experimental branch), download, extract, stop the old server (with map save) and restart. Its pretty hacky. I created an URL to trigger the updatecheck via a set uid script in /usr/bin.
Have fun
Code: Select all
#!/bin/bash
NC="\033[0m"
RED="\033[0;31m"
GREEN="\033[0;32m"
WHITE="\033[1;37m"
function die
{
echo -e "${RED}$@${NC}"
exit 1
}
function update
{
wget -O "factorio_${release}.tar.xz" https://factorio.com/get-download/${release}/headless/linux64 || die "Error downloading new version"
mv "factorio" "factorio_${current}"
tar xvJf "factorio_${release}.tar.xz"
cp "factorio_${current}/data/server-settings.json" "factorio/data/"
echo "Update successful!"
}
function get_versions
{
release=$(curl https://factorio.com 2>&1 | grep -A1 Experimental | grep \<dd\> | cut -d'>' -f2 | cut -d'<' -f1)
current=$(cat ./factorio/data/base/info.json | grep version | cut -d'"' -f4)
}
function trigger_check
{
check=1
}
function do_update
{
echo "Released version: $release"
echo "Current version: $current"
if [ "${current}" != "${release}" ]; then
echo "Needing update"
update
else
echo "Factorio is up-to-date!"
fi
}
trap trigger_check SIGUSR1
get_versions
do_update
while true; do
# this is my script to launch factorio!
./start_mp17.sh &
update=0
while [ $update -eq 0 ]; do
check=0
while [ $check -eq 0 ]; do
sleep 5
done
get_versions
if [ "${current}" != "${release}" ]; then
update=1
else
echo "Factorio is up-to-date"
fi
done
pid=$(ps aux | sed 's/ */ /g' | grep "\./factorio/bin" | grep -v grep | cut -d' ' -f2)
if [ ! -z "${pid}" ]; then
echo "Sending SIGINT to $pid"
kill -SIGINT $pid
echo "Waiting for $pid"
tail --pid $pid -f /dev/null
echo "Updating"
do_update
fi
done
Factorio auto update script
Posted: Mon May 27, 2019 4:38 pm
by Takervat
If the user has adblock enabled the full page script doesnt work? anyone can fix this with a new code?
Re: Factorio auto-update script
Posted: Wed May 29, 2019 7:21 pm
by Orygeunik
Then I will allow myself to show my simplest PowerShell script
Code: Select all
#Factorio autoupdate powershell script
$useExperimentalVersion = 1; #0 - Stable; 1 - Experimental;
$baseTempFolderPath = "D:\Temp\";
$gameFolderPath = "D:\Temp\Game\";
$userLogin = "";
$userPassword = "";
$useSeparateGameFolder = $false; #true - create new folder with new game version; false - merge game folder (auto-backup)
$backupFolderPath = "D:\Temp\Backup\" #set if $useSeparateGameFolder = true
#
#
#
if([string]::IsNullOrWhiteSpace($baseTempFolderPath))
{
Write-Output "Base temp folder path - empty!";
Exit 1;
}
if([string]::IsNullOrWhiteSpace($gameFolderPath))
{
Write-Output "Game folder path - empty!";
Exit 2;
}
if([string]::IsNullOrWhiteSpace($userLogin))
{
Write-Output "User login - empty!";
Exit 3;
}
if([string]::IsNullOrWhiteSpace($userPassword))
{
Write-Output "User password - empty!";
Exit 4;
}
if((!$useSeparateGameFolder) -and [string]::IsNullOrWhiteSpace($backupFolderPath))
{
Write-Output "User password - empty!";
Exit 5;
}
$urlMain = "https://www.factorio.com/";
$urlLogin = "https://www.factorio.com/login";
$urlLogout = "https://www.factorio.com/logout";
$lastVersionFilePath = [IO.Path]::Combine($baseTempFolderPath, "lastVersionFilePath.txt");
$regexVersion = New-Object System.Text.RegularExpressions.Regex("<h3>\s+Latest releases\s+<\/h3>\s+<dl>\s+<dt>Stable:<\/dt>\s+<dd>(\d{0,2}\.\d{0,3}\.\d{0,4})<\/dd>\s+<dt>Experimental:<\/dt>\s+<dd>(\d{0,2}\.\d{0,3}\.\d{0,4})<\/dd>");
$regexToken = New-Object System.Text.RegularExpressions.Regex("<input id=""csrf_token"".+value=""(.{91})"">");
$start_time = Get-Date;
Add-Type -AssemblyName System.IO.Compression.FileSystem;
New-Item -ItemType Directory -Force -Path $baseTempFolderPath | Out-Null
New-Item -ItemType Directory -Force -Path $gameFolderPath | Out-Null
$cookieContainer = New-Object System.Net.CookieContainer;
#magic function for implement c# using {}
function Using-Object
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[AllowEmptyCollection()]
[AllowNull()]
[Object]
$InputObject,
[Parameter(Mandatory = $true)]
[scriptblock]
$ScriptBlock
)
try
{
. $ScriptBlock
}
finally
{
if ($null -ne $InputObject -and $InputObject -is [System.IDisposable])
{
$InputObject.Dispose()
}
}
}
function Get-DownloadPage
{
Param ([string]$url, [string]$outputPath)
Using-Object ([System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::Create($url)){
$req.method = "GET";
$req.Headers.Add("Accept-Charset: utf-8;");
$req.AllowAutoRedirect = $true;
$req.ContentType = "application/x-www-form-urlencoded";
$req.TimeOut = 50000;
$req.KeepAlive = $true;
$req.Headers.Add("Keep-Alive: 300");
$req.CookieContainer = $cookieContainer;
Using-Object ([System.Net.HttpWebResponse] $res = $req.GetResponse()){
Using-Object ($fs = [System.IO.File]::Open($outputPath, [System.IO.FileMode]::Create)){
$res.GetResponseStream().CopyTo($fs);
}
}
}
}
function Get-InternetPage
{
Param ([string]$url)
Using-Object ([System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::Create($url)){
$req.method = "GET";
$req.Headers.Add("Accept-Charset: utf-8;");
$req.AllowAutoRedirect = $true;
$req.ContentType = "application/x-www-form-urlencoded";
$req.TimeOut = 50000;
$req.KeepAlive = $true;
$req.Headers.Add("Keep-Alive: 300");
$req.CookieContainer = $cookieContainer;
Using-Object ([System.Net.HttpWebResponse] $res = $req.GetResponse()){
Using-Object ($reader = New-Object -TypeName System.IO.StreamReader -ArgumentList $res.GetResponseStream()){
return $reader.ReadToEnd();
}
}
}
}
function Send-Payload
{
Param ([string]$url, [string]$payload)
$buffer = [System.Text.Encoding]::UTF8.GetBytes($payload);
Using-Object ([System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::Create($url)){
$req.method = "POST";
$req.Headers.Add("Accept-Charset: utf-8;");
$req.AllowAutoRedirect = $true;
$req.ContentType = "application/x-www-form-urlencoded";
$req.TimeOut = 50000;
$req.KeepAlive = $true;
$req.Headers.Add("Keep-Alive: 300");
$req.CookieContainer = $cookieContainer;
Using-Object ($reqst = $req.GetRequestStream()){
$reqst.Write($buffer, 0, $buffer.Length);
$reqst.Flush()
$reqst.Close();
}
Using-Object ([System.Net.HttpWebResponse] $res = $req.GetResponse()){
Using-Object ($reader = New-Object -TypeName System.IO.StreamReader -ArgumentList $res.GetResponseStream()){
return $reader.ReadToEnd();
}
}
}
}
function Unzip
{
Param([string]$zipFile, [string]$outputPath, [string]$version)
Using-Object ($archive = [System.IO.Compression.ZipFile]::OpenRead($zipFile)){
foreach ($entry in $archive.Entries)
{
$entryTargetFilePath = [System.IO.Path]::Combine($outputPath, $entry.FullName);
if(!$useSeparateGameFolder)
{
$entryTargetFilePath = $entryTargetFilePath.Replace("Factorio_$($version)","");
}
$entryDir = [System.IO.Path]::GetDirectoryName($entryTargetFilePath);
if(!(Test-Path $entryDir ))
{
New-Item -ItemType Directory -Path $entryDir | Out-Null
}
if(!$entryTargetFilePath.EndsWith("\"))
{
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $entryTargetFilePath, $true);
}
}
$archive.Dispose();
}
}
function Zip
{
Param([string]$toZipDirectory)
$entryDir = [System.IO.Path]::GetDirectoryName($backupFolderPath);
if(!(Test-Path $entryDir ))
{
New-Item -ItemType Directory -Path $entryDir | Out-Null
}
$outputPath = [IO.Path]::Combine($backupFolderPath, (Get-Date -UFormat("{0:yyyy.MM.dd HH.mm}")) + "_backup.zip");
[System.IO.Compression.ZipFile]::CreateFromDirectory($toZipDirectory, $outputPath);
}
try
{
$lastVersion = "";
if(Test-Path -Path $lastVersionFilePath)
{
$lastVersion = Get-Content -Path $lastVersionFilePath;
}
$result = Get-InternetPage -url $urlMain
$mathes = $regexVersion.Match($result);
if(!$mathes.Success)
{
Write-Output "Get game version failed!";
Exit 6;
}
if ($lastVersion -eq $mathes.Groups[$useExperimentalVersion + 1].Value)
{
Write-Output "Time: $((Get-Date).Subtract($start_time))";
Exit 0;
}
$lastVersion = $mathes.Groups[$useExperimentalVersion + 1].Value;
$urlFile = "https://www.factorio.com/get-download/" + ($mathes.Groups[$useExperimentalVersion + 1].Value) + "/alpha/win64-manual";
$outputFilePath = [IO.Path]::Combine($baseTempFolderPath, "Factorio_" + ($mathes.Groups[$useExperimentalVersion + 1].Value) + ".zip");
$result = Get-InternetPage -url $urlLogin
$mathes = $regexToken.Match($result);
if(!$mathes.Success)
{
Write-Output "Get csrf_token failed!";
Exit 7;
}
$csrf_token = $mathes.Groups[1].Value;
$loginPayload = "csrf_token="+ $csrf_token + "&username_or_email=" + $userLogin + "&password=" + $userPassword + "&action=Login";
$result = Send-Payload -url $urlLogin -payload $loginPayload
#download game zip
Get-DownloadPage -url $urlFile -outputPath $outputFilePath
#logout.Because we good people :)
$result = Get-InternetPage -url $urlLogout
$lastVersion | Out-File $lastVersionFilePath;
if(!$useSeparateGameFolder)
{
Zip -toZipDirectory $gameFolderPath
}
#unzip arhive
Unzip -zipFile $outputFilePath -outputPath $gameFolderPath -version $lastVersion
}
catch [Exception]
{
Write-Output Get-Date + " Global Exception! Panic!";
Write-Output $error;
Exit -1;
}
Write-Output "Time: $((Get-Date).Subtract($start_time))";
Exit 0;
How to use:
- Open powershell script
- Find option "useExperimentalVersion"
- Select type of game (stable / experimental)
- Set 0 or 1 to set selected game type (0 - Stable; 1 - Experimental;)
- Find option "baseTempFolderPath"
- Set path to temporal folder (folder will be created automated). In this folder will be stored file with last downloaded version and archive of game
- Find option "gameFolderPath"
- Set path to game folder
- Find option "userLogin"
- Set your login from site https://factorio.com
- Find option "userPassword"
- Set your password from site https://factorio.com
- Find option "useSeparateGameFolder"
- Select how you store game, as separate folder or union folder. (true - create new folder with new game version; false - merge game folder (auto-backup))
- Find option "backupFolderPath"
- Set path to backup folder (folder will be created automated). Note. Relevant if you set "$false" in option "useSeparateGameFolder"
- And run script
---
Upd 2019.05.30 01:30
Also, just in case, the script to remove duplicate mods (Deleted earlier mods).
Code: Select all
#Factorio auto-trim duplicate mods powershell script
$modFolderPath = "";
#
#
#
if([string]::IsNullOrWhiteSpace($modFolderPath))
{
Write-Output "Mod folder path - empty!";
Exit 1;
}
$start_time = Get-Date;
$modNameList = New-Object 'System.Collections.Generic.Dictionary[string,string]';
$modNameDuplicateList = New-Object 'System.Collections.Generic.Dictionary[string,string]';
$modNames = Get-ChildItem -Path $modFolderPath -Name *.zip | Sort
$regexVersion = New-Object System.Text.RegularExpressions.Regex("(.+)_(\d{0,2}\.\d{0,3}\.\d{0,4})\.zip");
foreach ($name in $modNames)
{
$mathes = $regexVersion.Match($name);
if($mathes.Success)
{
if($modNameList.ContainsKey($mathes.Groups[1].Value))
{
$modNameDuplicateList.Add($mathes.Groups[1].Value, $modNameList[($mathes.Groups[1].Value)]);
}
else
{
$modNameList.Add($mathes.Groups[1].Value, $mathes.Groups[2].Value);
}
}
}
foreach ($name in $modNameDuplicateList.GetEnumerator())
{
$fullPath = [System.IO.Path]::Combine($modFolderPath, ($name.Key + "_" + $name.Value + ".zip"));
Write-Output "Trim mod: $($fullPath)";
Remove-Item -Path $fullPath
}
Write-Output "Time: $((Get-Date).Subtract($start_time))";
Exit 0;
How to use:
- Open powershell script
- Find option "modFolderPath"
- Set path to mods folder
- And run script