Skip to content

Instantly share code, notes, and snippets.

@leonard84
Last active May 11, 2021
Embed
What would you like to do?
Prepare mods for factorio.zone
# What is this?
#
# This is a script I wrote to automate the process of removing images and soundfiles from mods,
# so that they can be uploaded to factorio.zone without taking forever or even exceed the max-upload size.
# It also creates a mod-settings.zip so that your mod-settings.dat (Startup Settings) are available on the server.
#
# How to use
#
# Download the script and put it somewhere on you harddrive, e.g., C:\temp\factorio
# Open a powershell prompt "Win+x, i" or just type powershell in the startmenu.
# Navigate to the script (e.g., "cd C:\temp\factorio") and call it like this ".\prepare-mods.ps1" alternatively you can double click on it.
#
# If you get a Warning regarding execution policy you can start it like this (without the quotes obviously):
#
# "Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned; .\prepare-mods.ps1"
#
# This will prompt you regarding the execution policy change, and you have to allow it.
#
[CmdletBinding()]
param(
[string]$FactorioDir = "$($env:APPDATA)\Factorio\mods",
[string]$OutputDir = "$($PWD)\out",
[boolean]$Overwrite = $false
)
Function Find7zExe {
$s7z = Get-Command 7z.exe -ErrorAction SilentlyContinue
if ($s7z -eq $null) {
$s7z = @($env:ProgramFiles,${env:ProgramFiles(x86)}) | ForEach-Object { Get-Item "$($_)\7-Zip\7z.exe" -ErrorAction SilentlyContinue } | Select-Object -First 1
if ($s7z -eq $null) {
$s7z = $s7z.FullName
}
} else {
$s7z = $s7z.Source
}
if ($s7z -eq $null) {
throw "7z.exe could not be found on the path"
}
Write-Host -ForegroundColor Green "Found 7z.exe"
Write-Debug "7z.exe Location: $($s7z)"
$s7z
}
Function Get-Active-Mods {
param(
[string]$FactorioDir
)
Get-Content -Raw "$($FactorioDir)\mod-list.json" | ConvertFrom-Json | Select-Object -ExpandProperty mods | Where {$_.enabled} | ForEach-Object { Get-Item "$($FactorioDir)\$($_.Name)_*.*.*.zip" }
}
Function Copy-Active-Mods {
param(
$Mods,
[string]$OutputDir
)
$Mods | ForEach-Object {
Write-Host "Copy $($_.Name)"
Write-Debug "From $($_.FullName) to $($OutputDir)"
Copy-Item -Path $_.FullName -Destination $OutputDir
}
}
Function Strip-Mods {
param(
[string]$ModFolder,
[string]$s7z
)
Write-Host $s7z
Get-ChildItem -Path $ModFolder | ForEach-Object {
$s7args = 'd', "$($_.FullName)", "*.png", "*.jpg", "*.jpeg", "*.wav", "*.ogg", "*/.git", "-r"
Write-Debug "Exec: $s7z $s7args"
Write-Host -NoNewline "Stripping $($_.Name)..."
& $s7z $s7args | Write-Debug
Write-Host -ForegroundColor Green "Done"
}
}
Function Create-Mod-Settings-Archive {
param(
[string]$FactorioDir,
[string]$OutputDir,
[string]$s7z
)
if (!(Test-Path -Path (Join-Path $FactorioDir "mod-settings.dat"))) {
Write-Host "No mod-settings.dat found, skipping mod-settings.zip creation"
}
Write-Host "Creating mod-settings.zip"
$tempDir = New-TemporaryDirectory
Write-Debug "Created tempDir $($tempDir)"
Copy-Item -Path (Join-Path $FactorioDir "mod-settings.dat") -Destination $tempDir
@"
{
"name": "mod-settings.dat",
"version": "3.14.15",
"title": "mod-settings.dat",
"description": "Mod settings for factorio.zone created with prepare-mods.ps1 script by leonard84."
}
"@ | Out-File -File (Join-Path $tempDir "info.json")
Push-Location $tempDir
$s7args = 'a', "mod-settings.zip", "mod-settings.dat", "info.json"
& $s7z $s7args | Write-Debug
Pop-Location
Move-Item -Path (Join-Path $tempDir "mod-settings.zip") -Destination $OutputDir
Remove-Item -Recurse -Force -Path $tempDir
}
function New-TemporaryDirectory {
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
New-Item -ItemType Directory -Path (Join-Path $parent $name)
}
Write-Host "Using FactorioDir: $($FactorioDir)"
Write-Host "Using OutputDir: $($OutputDir)"
if (Test-Path -Path "$($OutputDir)\*") {
if (!$Overwrite) {
Write-Warning "$($OutputDir) is not empty"
Get-ChildItem $OutputDir | Write-Host
Write-Warning "$($OutputDir) is not empty, see contents above."
$prompt = Read-Host "Do you want to overwrite that directory? [y/N]"
if ($prompt -ieq "y") {
$Overwrite = $True
} else {
throw "Please clean or select a diffent outputDir"
}
}
Remove-Item -Recurse -Force -Path $OutputDir
}
New-Item -Force -Type Directory -Path $OutputDir -ErrorAction SilentlyContinue
$s7z = Find7zExe
$activeMods = Get-Active-Mods -FactorioDir $FactorioDir
Copy-Active-Mods -Mods $activeMods -OutputDir $OutputDir
Strip-Mods -ModFolder $OutputDir -s7z $s7z
Create-Mod-Settings-Archive -FactorioDir $FactorioDir -OutputDir $OutputDir -s7z $s7z
Write-Host -ForegroundColor Green "All Done"
Read-Host "Press Enter to continue"
@icon256

This comment has been minimized.

Copy link

@icon256 icon256 commented Apr 25, 2020

Hi there, It's icon256 from discord.

Some issues as follows: I'm not seeing it output to a different directory but outputs to the same directory of the script it's placed of the mod directory as I attempted to run this on two different computers to make sure it was not out of fault of a particular computer. It looks like it copies the file and outputs to the same directory with no modification as the file name "out.zip".

For the slightly less included person to run this script. When, where should this script be placed, and where should the output file be? Hoping this can be of great use for Factorio-Zone users. Thx.

@leonard84

This comment has been minimized.

Copy link
Owner Author

@leonard84 leonard84 commented Apr 26, 2020

I've update the script a bit and included a header that describes how this works.

@shadoxxhd

This comment has been minimized.

Copy link

@shadoxxhd shadoxxhd commented Oct 5, 2020

ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At C:\Users\sh4dow\Downloads\prepare-mods.ps1:57 char:51
+     Get-Content "$($FactorioDir)\mod-list.json" | ConvertFrom-Json | Select-Obje ...
+                                                   ~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

My mod-list.json is valid json, according to jsonlint.com , so I have no idea what causes this error.

@shadoxxhd

This comment has been minimized.

Copy link

@shadoxxhd shadoxxhd commented Oct 5, 2020

Apparently Get-Content needs to be called with the -Raw option to be readable by ConvertFrom-Json.

@leonard84

This comment has been minimized.

Copy link
Owner Author

@leonard84 leonard84 commented Oct 12, 2020

@shadoxxhd what version of powershell are you using, it works for me without -Raw?

@shadoxxhd

This comment has been minimized.

Copy link

@shadoxxhd shadoxxhd commented Oct 13, 2020

@leonard84

This comment has been minimized.

Copy link
Owner Author

@leonard84 leonard84 commented Oct 15, 2020

I just checked again and it works for me in both the standard windows powershell (5.1) and the new one (7.0.3) you can check with $PSVersionTable.

However, since it also works with -Raw I've updated the script, so that it works for more people.

@Kurochi51

This comment has been minimized.

Copy link

@Kurochi51 Kurochi51 commented Oct 21, 2020

 Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
 At D:\prepare-mods.ps1:44 char:25
          Copy-Item -Path $_.FullName -Destination $OutputDir
                          ~~~~~~~~~~~
  CategoryInfo          : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
  FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand

Not quite sure what's causing this error, it still outputs the folder with the mod-settings.zip

@shadoxxhd

This comment has been minimized.

Copy link

@shadoxxhd shadoxxhd commented Nov 17, 2020

Just FYI: I was using PS 4.0.

@leonard84

This comment has been minimized.

Copy link
Owner Author

@leonard84 leonard84 commented Nov 17, 2020

@Kurochi51 which PS version are you using? You can check with $PSVersionTable if you also have something < 5.1 then I might have to add a version check.

@Kurochi51

This comment has been minimized.

Copy link

@Kurochi51 Kurochi51 commented Nov 17, 2020

@Kurochi51 which PS version are you using? You can check with $PSVersionTable if you also have something < 5.1 then I might have to add a version check.

I have 5.1

@leonard84

This comment has been minimized.

Copy link
Owner Author

@leonard84 leonard84 commented Nov 17, 2020

@Kurochi51 I'd suggest to run the script with -Debug maybe you have some invalid data in your mod-list.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment