Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save grayfallstown/beecd34f46301551dfad03fd7db71eea to your computer and use it in GitHub Desktop.

Select an option

Save grayfallstown/beecd34f46301551dfad03fd7db71eea to your computer and use it in GitHub Desktop.
Exports Space engineers mods of last saved game
<#
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