Created
December 26, 2025 08:54
-
-
Save grayfallstown/beecd34f46301551dfad03fd7db71eea to your computer and use it in GitHub Desktop.
Exports Space engineers mods of last saved game
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| ExportSpaceEngineersMods.ps1 | |
| - Findet neueste Space Engineers Welt (sandbox.sbc) | |
| - Extrahiert Mods (PublishedFileId, FriendlyName, Name) | |
| - Exportiert CSV + Markdown mit vollen Workshop-URLs neben der Welt | |
| Nutzung: | |
| Set-ExecutionPolicy -Scope Process RemoteSigned | |
| .\ExportSpaceEngineersMods.ps1 [-BasePath "D:\SE\Saves"] [-AlsoCheckDedicated] | |
| #> | |
| [CmdletBinding()] | |
| param( | |
| [string]$BasePath = (Join-Path $env:APPDATA "SpaceEngineers\Saves"), | |
| [switch]$AlsoCheckDedicated | |
| ) | |
| function Find-WorldFiles { | |
| param([string[]]$Roots) | |
| $files = @() | |
| foreach ($root in $Roots) { | |
| if (Test-Path $root) { | |
| $found = Get-ChildItem -Path $root -Filter "sandbox.sbc" -Recurse -File -ErrorAction SilentlyContinue | |
| if ($found) { $files += $found } | |
| } | |
| } | |
| return $files | |
| } | |
| function Select-LatestSandbox { | |
| param([System.IO.FileInfo[]]$SandboxFiles) | |
| if (-not $SandboxFiles -or $SandboxFiles.Count -eq 0) { return $null } | |
| $SandboxFiles | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | |
| } | |
| function Parse-ModsFromSandbox { | |
| param([string]$SandboxPath) | |
| try { | |
| [xml]$xml = Get-Content -Path $SandboxPath -Raw -ErrorAction Stop | |
| } catch { | |
| throw "Konnte XML nicht laden: $SandboxPath`n$($_.Exception.Message)" | |
| } | |
| $modsNode = $null | |
| foreach ($xp in @( | |
| "/MyObjectBuilder_Session/Mods", | |
| "/MyObjectBuilder_Checkpoint/Mods", | |
| "//Mods" | |
| )) { | |
| $node = $xml.SelectSingleNode($xp) | |
| if ($node -ne $null -and $node.ModItem) { $modsNode = $node; break } | |
| } | |
| $result = @() | |
| if ($modsNode -eq $null) { return ,@() } | |
| foreach ($modItem in $modsNode.ModItem) { | |
| $publishedId = $null | |
| $friendly = $null | |
| $name = $null | |
| if ($modItem.PublishedFileId) { | |
| $publishedId = [string]$modItem.PublishedFileId | |
| } elseif ($modItem.Attributes["PublishedFileId"]) { | |
| $publishedId = [string]$modItem.Attributes["PublishedFileId"].Value | |
| } | |
| if ($modItem.FriendlyName) { $friendly = [string]$modItem.FriendlyName } | |
| if ($modItem.Name) { $name = [string]$modItem.Name } | |
| $workshopUrl = $null | |
| if ($publishedId -and $publishedId -match '^\d+$') { | |
| $workshopUrl = "https://steamcommunity.com/sharedfiles/filedetails/?id=$publishedId" | |
| } | |
| $result += [pscustomobject]@{ | |
| PublishedFileId = $publishedId | |
| Name = $name | |
| FriendlyName = $friendly | |
| WorkshopURL = $workshopUrl | |
| } | |
| } | |
| return $result | |
| } | |
| # 1) Pfade sammeln | |
| $roots = @($BasePath) | |
| if ($AlsoCheckDedicated) { $roots += (Join-Path $env:APPDATA "SpaceEngineersDedicated") } | |
| # 2) sandbox.sbc suchen | |
| $allSandbox = Find-WorldFiles -Roots $roots | |
| if (-not $allSandbox -or $allSandbox.Count -eq 0) { | |
| Write-Error "Keine sandbox.sbc gefunden unter: $($roots -join ', ')" | |
| exit 2 | |
| } | |
| # 3) neueste Welt | |
| $latest = Select-LatestSandbox -SandboxFiles $allSandbox | |
| $worldDir = Split-Path -Path $latest.FullName -Parent | |
| $worldName = Split-Path -Path $worldDir -Leaf | |
| Write-Host "Neueste Welt: $worldName" | |
| Write-Host "Pfad : $worldDir" | |
| Write-Host "Stand : $($latest.LastWriteTime)" | |
| # 4) Mods parsen | |
| $mods = Parse-ModsFromSandbox -SandboxPath $latest.FullName | |
| # 5) Exportpfade | |
| $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" | |
| $csvPath = Join-Path $worldDir ("Mods-$worldName-$timestamp.csv") | |
| $mdPath = Join-Path $worldDir ("Mods-$worldName-$timestamp.md") | |
| # 6) CSV exportieren | |
| $mods | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8 | |
| # 7) Markdown bauen (keine Emojis, saubere Strings, kein Pipe am Zeilenanfang unquoted) | |
| $mdLines = @() | |
| $mdLines += "# Mods für Welt: $worldName" | |
| $mdLines += "" | |
| $mdLines += ('| # | PublishedFileId | FriendlyName | Name | WorkshopURL |') | |
| $mdLines += ('|---:|----------------|--------------|------|-------------|') | |
| # Helfer zum Sanitizen | |
| function _SanitizeMd([string]$s) { | |
| if ([string]::IsNullOrEmpty($s)) { return "" } | |
| return ($s -replace '\|','\|') # Pipes escapen | |
| } | |
| $idx = 0 | |
| foreach ($m in $mods) { | |
| $idx++ | |
| $pubId = _SanitizeMd $m.PublishedFileId | |
| $friendly = _SanitizeMd $m.FriendlyName | |
| $name = _SanitizeMd $m.Name | |
| $url = _SanitizeMd $m.WorkshopURL | |
| $line = ('| {0,3} | {1} | {2} | {3} | {4} |' -f $idx, $pubId, $friendly, $name, $url) | |
| $mdLines += $line | |
| } | |
| # 8) Markdown schreiben mit stabiler UTF-8 Kodierung | |
| $utf8NoBom = New-Object System.Text.UTF8Encoding($false) | |
| [System.IO.File]::WriteAllLines($mdPath, $mdLines, $utf8NoBom) | |
| # 9) Konsolenübersicht (ohne Emojis) | |
| Write-Host "" | |
| Write-Host "Export abgeschlossen:" | |
| Write-Host "CSV: $csvPath" | |
| Write-Host "MD : $mdPath" | |
| Write-Host "" | |
| if ($mods -and $mods.Count -gt 0) { | |
| $mods | Select-Object @{n="#";e={[array]::IndexOf($mods, $_)+1}}, | |
| PublishedFileId, FriendlyName, Name, WorkshopURL | | |
| Format-Table -AutoSize | |
| } else { | |
| Write-Host "(Keine Mods gefunden.)" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment