Skip to content

Instantly share code, notes, and snippets.

@leonard84
Last active November 1, 2023 12:16
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonard84/b31b3b9fb70fb737bb250bbf893a04d2 to your computer and use it in GitHub Desktop.
Save leonard84/b31b3b9fb70fb737bb250bbf893a04d2 to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link
Author

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

@shadoxxhd
Copy link

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
Copy link

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

@leonard84
Copy link
Author

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

@shadoxxhd
Copy link

shadoxxhd commented Oct 13, 2020 via email

@leonard84
Copy link
Author

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
Copy link

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
Copy link

Just FYI: I was using PS 4.0.

@leonard84
Copy link
Author

@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
Copy link

@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
Copy link
Author

@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