Page 1 of 1

Mod Download API with Powershell on Windows

Posted: Tue Nov 19, 2024 8:58 pm
by Kinson25
I have not found a good example to auto update mods on windows, so here is my powershell script. Just input the directory for your mods (usually in %appdata%/factorio/mods), your factorio username and the token from your profile here. Save it as FactorioModUpdates.ps1
I hope this helps someone.

Code: Select all

clear
# Define variables
$modsDir = "C:\factorio-server\mods"  # Path to your Factorio mods directory
$factorioUsername = ""      # Replace with your Factorio username
$apiKey = ""                   # Replace with your Factorio token

# Read mod-list.json
$modListPath = Join-Path $modsDir "mod-list.json"
if (!(Test-Path $modListPath)) {
    Write-Error "mod-list.json not found in $modsDir."
    exit
}

# Parse mod-list.json
$modList = Get-Content -Path $modListPath | ConvertFrom-Json
$enabledMods = $modList.mods | Where-Object { $_.name -ne "base" -and $_.enabled -eq $true }

# Function to download a mod
function Download-Mod {
    param (
        [string]$modName,
        [string]$downloadUrl,
        [string]$version
    )

    # Ensure the download URL starts with a slash
    if (-not $downloadUrl.StartsWith("/")) {
        $downloadUrl = "/$downloadUrl"
    }

    # Construct the full download URL
    #https://mods.factorio.com/{download_url}?username={username}&token={token}
    $fullDownloadUrl = "https://mods.factorio.com$($downloadUrl)?username=$factorioUsername&token=$apiKey"
    write-host $fullDownloadUrl
    $outputFile = Join-Path $modsDir "$($modName)_$version.zip"

    try {
        # Validate the constructed URI
        if (![System.Uri]::IsWellFormedUriString($fullDownloadUrl, [System.UriKind]::Absolute)) {
            throw "Invalid URI constructed: $fullDownloadUrl"
        }

        # Attempt to download the mod
        Invoke-WebRequest -Uri $fullDownloadUrl -OutFile $outputFile -ErrorAction Stop
        Write-Host "Downloaded $modName $version successfully."
    } catch {
        Write-Error "Failed to download $modName. $_"
    }
}


# Loop through enabled mods and update
foreach ($mod in $enabledMods) {
    $modName = $mod.name
    Write-Host "Checking updates for $modName..."
    if($modName -eq "elevated-rails" -or $modName -eq "space-age" -or $modName -eq "quality" ){write-host "skipping"
       }Else {
        # Get mod info
        try {
            $modInfo = Invoke-RestMethod -Uri "https://mods.factorio.com/api/mods/$modName" -ErrorAction Stop
            $latestRelease = $modInfo.releases | Sort-Object released_at -Descending | Select-Object -First 1
            $latestVersionNumber = $latestRelease.version
            $downloadUrl = $latestRelease.download_url

            # Check if mod needs updating
            $existingMod = Get-ChildItem -Path $modsDir -Filter "$modName*.zip"
            if ($existingMod.Name -notlike "*$latestVersionNumber*") {
                Write-Host "$modName needs update. Downloading version $latestVersionNumber..."
                Download-Mod -modName $modName -downloadUrl $downloadUrl -version $latestVersionNumber
                if($existingMod.Name -ne "" -and $existingMod.Name -ne $null){ Remove-Item "mods/$($existingMod.Name)" }
            } else {
                Write-Host "$modName is already up-to-date."
            }
        } catch {
            Write-Error "Error retrieving info for $modName. $_"
            continue
        }
    }
}

Write-Host "`tMod updates complete."