mirror of
https://github.com/iTracerFacer/DCS_MissionDev.git
synced 2025-12-03 04:14:46 +00:00
Updated Moose
This commit is contained in:
269
Patch-MooseMissions/Patch-MooseMissions.ps1
Normal file
269
Patch-MooseMissions/Patch-MooseMissions.ps1
Normal file
@@ -0,0 +1,269 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Patches DCS mission files (.miz) with updated Lua scripts.
|
||||
|
||||
.DESCRIPTION
|
||||
This script extracts a DCS mission file (which is a ZIP archive), replaces or adds
|
||||
a Lua script file, and repackages the mission. This allows you to update scripts
|
||||
like Moose_.lua across multiple missions without opening the DCS Mission Editor.
|
||||
|
||||
.PARAMETER MissionPath
|
||||
Path to the .miz mission file to patch. Can be a single file or multiple files.
|
||||
|
||||
.PARAMETER LuaScriptPath
|
||||
Path to the Lua script file to insert/replace in the mission.
|
||||
|
||||
.PARAMETER ScriptName
|
||||
Optional. The name the script should have inside the mission file.
|
||||
If not specified, uses the filename from LuaScriptPath.
|
||||
|
||||
.PARAMETER OutputPath
|
||||
Optional. Directory where patched missions should be saved.
|
||||
If not specified, saves to the same directory as the input mission.
|
||||
|
||||
.PARAMETER NoVersionIncrement
|
||||
If specified, does not increment the version number in the filename.
|
||||
By default, the script automatically increments the patch version (e.g., 1.1.2 -> 1.1.3).
|
||||
WARNING: Using this flag will OVERWRITE the original mission file!
|
||||
|
||||
.EXAMPLE
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "C:\Missions\MyMission-1.2.3.miz" -LuaScriptPath "C:\Scripts\Moose_.lua"
|
||||
Creates: MyMission-1.2.4.miz (original 1.2.3 remains untouched)
|
||||
|
||||
.EXAMPLE
|
||||
Get-ChildItem "C:\Missions\*.miz" | .\Patch-MooseMissions.ps1 -LuaScriptPath "C:\Scripts\Moose_.lua"
|
||||
|
||||
.EXAMPLE
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "Mission-2.1.miz" -LuaScriptPath "MyScript.lua" -NoVersionIncrement
|
||||
WARNING: Overwrites Mission-2.1.miz
|
||||
|
||||
.NOTES
|
||||
Author: F99th-TracerFacer
|
||||
Version: 2.0
|
||||
DCS mission files are ZIP archives containing a 'l10n' folder with a 'DEFAULT' subfolder
|
||||
where Lua scripts are stored.
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
|
||||
[Alias("FullName", "Path")]
|
||||
[string[]]$MissionPath,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$LuaScriptPath,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$ScriptName,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$OutputPath,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]$NoVersionIncrement
|
||||
)
|
||||
|
||||
begin {
|
||||
# Verify Lua script exists
|
||||
if (-not (Test-Path $LuaScriptPath)) {
|
||||
throw "Lua script not found: $LuaScriptPath"
|
||||
}
|
||||
|
||||
# Determine script name to use inside mission
|
||||
if ([string]::IsNullOrWhiteSpace($ScriptName)) {
|
||||
$ScriptName = Split-Path $LuaScriptPath -Leaf
|
||||
}
|
||||
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "DCS Mission Patcher" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Lua Script: $ScriptName" -ForegroundColor Yellow
|
||||
Write-Host "Source: $LuaScriptPath" -ForegroundColor Gray
|
||||
Write-Host "Version Increment: $(if ($NoVersionIncrement) { 'Disabled (OVERWRITES ORIGINAL!)' } else { 'Enabled' })" -ForegroundColor $(if ($NoVersionIncrement) { 'Red' } else { 'Green' })
|
||||
Write-Host ""
|
||||
|
||||
# Validate output path if specified
|
||||
if ($OutputPath -and -not (Test-Path $OutputPath)) {
|
||||
Write-Host "Creating output directory: $OutputPath" -ForegroundColor Yellow
|
||||
New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
$successCount = 0
|
||||
$failCount = 0
|
||||
|
||||
# Function to increment version number in filename
|
||||
function Get-IncrementedFilename {
|
||||
param(
|
||||
[string]$FileName
|
||||
)
|
||||
|
||||
# Remove extension
|
||||
$nameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($FileName)
|
||||
$extension = [System.IO.Path]::GetExtension($FileName)
|
||||
|
||||
# Try to find version patterns: X.Y.Z or X.Y or just X at the end
|
||||
# Patterns to match (in order of specificity):
|
||||
# 1. Major.Minor.Patch (e.g., 1.2.3)
|
||||
# 2. Major.Minor (e.g., 1.2)
|
||||
# 3. Just version number at end (e.g., v5 or -5)
|
||||
|
||||
# Pattern 1: X.Y.Z (most common)
|
||||
if ($nameWithoutExt -match '^(.+?)[-_\s]?(\d+)\.(\d+)\.(\d+)$') {
|
||||
$baseName = $matches[1]
|
||||
$major = $matches[2]
|
||||
$minor = $matches[3]
|
||||
$patch = [int]$matches[4]
|
||||
$newPatch = $patch + 1
|
||||
$separator = if ($nameWithoutExt -match '[-_\s](\d+\.\d+\.\d+)$') { $matches[0][0] } else { '' }
|
||||
return "$baseName$separator$major.$minor.$newPatch$extension"
|
||||
}
|
||||
# Pattern 2: X.Y
|
||||
elseif ($nameWithoutExt -match '^(.+?)[-_\s]?(\d+)\.(\d+)$') {
|
||||
$baseName = $matches[1]
|
||||
$major = $matches[2]
|
||||
$minor = [int]$matches[3]
|
||||
$newMinor = $minor + 1
|
||||
$separator = if ($nameWithoutExt -match '[-_\s](\d+\.\d+)$') { $matches[0][0] } else { '' }
|
||||
return "$baseName$separator$major.$newMinor$extension"
|
||||
}
|
||||
# Pattern 3: Just a number at the end
|
||||
elseif ($nameWithoutExt -match '^(.+?)[-_\s]?(\d+)$') {
|
||||
$baseName = $matches[1]
|
||||
$version = [int]$matches[2]
|
||||
$newVersion = $version + 1
|
||||
$separator = if ($nameWithoutExt -match '[-_\s]\d+$') { $matches[0][0] } else { '' }
|
||||
return "$baseName$separator$newVersion$extension"
|
||||
}
|
||||
# No version found - append .1
|
||||
else {
|
||||
return "$nameWithoutExt-1.0.1$extension"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
foreach ($mission in $MissionPath) {
|
||||
try {
|
||||
# Resolve full path
|
||||
$missionFile = Resolve-Path $mission -ErrorAction Stop
|
||||
|
||||
Write-Host "Processing: " -NoNewline -ForegroundColor White
|
||||
Write-Host "$missionFile" -ForegroundColor Cyan
|
||||
|
||||
# Verify mission file exists and is a .miz file
|
||||
if (-not (Test-Path $missionFile)) {
|
||||
throw "Mission file not found: $missionFile"
|
||||
}
|
||||
|
||||
if ([System.IO.Path]::GetExtension($missionFile) -ne ".miz") {
|
||||
throw "File is not a .miz mission file: $missionFile"
|
||||
}
|
||||
|
||||
# Create temporary extraction directory
|
||||
$tempDir = Join-Path $env:TEMP ("DCS_Mission_Patch_" + [System.Guid]::NewGuid().ToString())
|
||||
New-Item -Path $tempDir -ItemType Directory -Force | Out-Null
|
||||
|
||||
try {
|
||||
# Extract mission file (it's a ZIP archive)
|
||||
# Use .NET classes instead of Expand-Archive for better .miz support
|
||||
Write-Host " Extracting mission..." -ForegroundColor Gray
|
||||
|
||||
Add-Type -Assembly System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($missionFile, $tempDir)
|
||||
|
||||
# Determine Lua script destination in mission structure
|
||||
# DCS stores Lua scripts in: l10n/DEFAULT/ folder
|
||||
$luaDestDir = Join-Path $tempDir "l10n\DEFAULT"
|
||||
|
||||
# Create directory if it doesn't exist
|
||||
if (-not (Test-Path $luaDestDir)) {
|
||||
Write-Host " Creating l10n/DEFAULT directory..." -ForegroundColor Yellow
|
||||
New-Item -Path $luaDestDir -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
$luaDestPath = Join-Path $luaDestDir $ScriptName
|
||||
|
||||
# Check if script already exists
|
||||
if (Test-Path $luaDestPath) {
|
||||
Write-Host " Replacing existing script: $ScriptName" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host " Adding new script: $ScriptName" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Copy Lua script to mission
|
||||
Copy-Item $LuaScriptPath $luaDestPath -Force
|
||||
|
||||
# Determine output filename and location
|
||||
$originalFileName = Split-Path $missionFile -Leaf
|
||||
|
||||
if ($NoVersionIncrement) {
|
||||
# Keep original filename
|
||||
$outputFileName = $originalFileName
|
||||
} else {
|
||||
# Increment version number
|
||||
$outputFileName = Get-IncrementedFilename -FileName $originalFileName
|
||||
Write-Host " Version increment: $originalFileName -> $outputFileName" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
# Determine output directory
|
||||
if ($OutputPath) {
|
||||
$outputDir = $OutputPath
|
||||
} else {
|
||||
$outputDir = Split-Path $missionFile -Parent
|
||||
}
|
||||
|
||||
$outputMission = Join-Path $outputDir $outputFileName
|
||||
|
||||
# Remove existing mission file if it exists
|
||||
if (Test-Path $outputMission) {
|
||||
Remove-Item $outputMission -Force
|
||||
}
|
||||
|
||||
# Repackage mission file
|
||||
Write-Host " Repackaging mission..." -ForegroundColor Gray
|
||||
|
||||
# Use .NET classes for better compatibility
|
||||
Add-Type -Assembly System.IO.Compression.FileSystem
|
||||
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
|
||||
|
||||
# Create ZIP from directory (will become .miz)
|
||||
[System.IO.Compression.ZipFile]::CreateFromDirectory($tempDir, $outputMission, $compressionLevel, $false)
|
||||
|
||||
Write-Host " SUCCESS: Mission patched successfully!" -ForegroundColor Green
|
||||
Write-Host " Output: $outputMission" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
$successCount++
|
||||
}
|
||||
finally {
|
||||
# Clean up temporary directory
|
||||
if (Test-Path $tempDir) {
|
||||
Remove-Item $tempDir -Recurse -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host " ERROR: $_" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
$failCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Patching Complete" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Successful: $successCount" -ForegroundColor Green
|
||||
Write-Host "Failed: $failCount" -ForegroundColor $(if ($failCount -gt 0) { "Red" } else { "Gray" })
|
||||
Write-Host ""
|
||||
|
||||
if ($successCount -gt 0) {
|
||||
if ($NoVersionIncrement) {
|
||||
Write-Host "WARNING: Original mission files were OVERWRITTEN!" -ForegroundColor Red
|
||||
} else {
|
||||
Write-Host "INFO: Original mission files remain untouched. New versioned files created." -ForegroundColor Green
|
||||
}
|
||||
Write-Host "TIP: Test your patched missions in DCS before using them!" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
283
Patch-MooseMissions/Patch-MyMooseMissions.ps1
Normal file
283
Patch-MooseMissions/Patch-MyMooseMissions.ps1
Normal file
@@ -0,0 +1,283 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Batch updates all DCS missions with the latest Moose framework.
|
||||
|
||||
.DESCRIPTION
|
||||
This script scans through the DCS mission development folder structure,
|
||||
finds the latest version of each mission (.miz files with version numbers),
|
||||
and patches them with the updated Moose_.lua script using Patch-MooseMissions.ps1.
|
||||
|
||||
It processes missions in the structure: C:\DCS_MissionDev\DCS_[Terrain]\[MissionFolder]\
|
||||
For each mission folder, it identifies the latest version (by version number or file date)
|
||||
and creates a new patched version.
|
||||
|
||||
.PARAMETER RootPath
|
||||
Root directory containing DCS terrain folders. Defaults to C:\DCS_MissionDev
|
||||
|
||||
.PARAMETER MooseLuaPath
|
||||
Path to the Moose_.lua file to patch into missions. Defaults to C:\DCS_MissionDev\Moose_.lua
|
||||
|
||||
.PARAMETER WhatIf
|
||||
Shows what would be processed without actually patching any files.
|
||||
|
||||
.PARAMETER ExcludeTerrain
|
||||
Array of terrain folder names to exclude from processing (e.g., @("DCS_Normandy", "DCS_Falklands"))
|
||||
|
||||
.EXAMPLE
|
||||
.\Patch-MyMooseMissions.ps1
|
||||
Processes all missions in C:\DCS_MissionDev using the default Moose_.lua
|
||||
|
||||
.EXAMPLE
|
||||
.\Patch-MyMooseMissions.ps1 -WhatIf
|
||||
Shows what missions would be processed without making any changes
|
||||
|
||||
.EXAMPLE
|
||||
.\Patch-MyMooseMissions.ps1 -ExcludeTerrain @("DCS_Normandy", "DCS_Falklands")
|
||||
Processes all missions except those in Normandy and Falklands terrains
|
||||
|
||||
.NOTES
|
||||
Author: F99th-TracerFacer
|
||||
Version: 1.0
|
||||
Requires: Patch-MooseMissions.ps1 in the same directory
|
||||
#>
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$RootPath = "C:\DCS_MissionDev",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$MooseLuaPath = "C:\DCS_MissionDev\Moose_.lua",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string[]]$ExcludeTerrain = @()
|
||||
)
|
||||
|
||||
# Verify paths exist
|
||||
if (-not (Test-Path $RootPath)) {
|
||||
Write-Error "Root path not found: $RootPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (-not (Test-Path $MooseLuaPath)) {
|
||||
Write-Error "Moose_.lua file not found: $MooseLuaPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Verify the Patch-MooseMissions.ps1 script exists
|
||||
$patchScriptPath = Join-Path $PSScriptRoot "Patch-MooseMissions.ps1"
|
||||
if (-not (Test-Path $patchScriptPath)) {
|
||||
Write-Error "Patch-MooseMissions.ps1 not found in: $PSScriptRoot"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Batch Moose Mission Patcher" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Root Path: $RootPath" -ForegroundColor Yellow
|
||||
Write-Host "Moose Script: $MooseLuaPath" -ForegroundColor Yellow
|
||||
Write-Host "Patch Script: $patchScriptPath" -ForegroundColor Yellow
|
||||
if ($ExcludeTerrain.Count -gt 0) {
|
||||
Write-Host "Excluded Terrains: $($ExcludeTerrain -join ', ')" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Function to parse version number from filename
|
||||
function Get-VersionNumber {
|
||||
param([string]$FileName)
|
||||
|
||||
$nameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($FileName)
|
||||
|
||||
# Try X.Y.Z pattern
|
||||
if ($nameWithoutExt -match '(\d+)\.(\d+)\.(\d+)') {
|
||||
$major = [int]$matches[1]
|
||||
$minor = [int]$matches[2]
|
||||
$patch = [int]$matches[3]
|
||||
return [PSCustomObject]@{
|
||||
Major = $major
|
||||
Minor = $minor
|
||||
Patch = $patch
|
||||
Value = ($major * 1000000) + ($minor * 1000) + $patch
|
||||
HasVersion = $true
|
||||
}
|
||||
}
|
||||
# Try X.Y pattern
|
||||
elseif ($nameWithoutExt -match '(\d+)\.(\d+)') {
|
||||
$major = [int]$matches[1]
|
||||
$minor = [int]$matches[2]
|
||||
return [PSCustomObject]@{
|
||||
Major = $major
|
||||
Minor = $minor
|
||||
Patch = 0
|
||||
Value = ($major * 1000000) + ($minor * 1000)
|
||||
HasVersion = $true
|
||||
}
|
||||
}
|
||||
# Try single version number
|
||||
elseif ($nameWithoutExt -match '(\d+)$') {
|
||||
$version = [int]$matches[1]
|
||||
return [PSCustomObject]@{
|
||||
Major = $version
|
||||
Minor = 0
|
||||
Patch = 0
|
||||
Value = $version * 1000000
|
||||
HasVersion = $true
|
||||
}
|
||||
}
|
||||
|
||||
# No version found
|
||||
return [PSCustomObject]@{
|
||||
Major = 0
|
||||
Minor = 0
|
||||
Patch = 0
|
||||
Value = 0
|
||||
HasVersion = $false
|
||||
}
|
||||
}
|
||||
|
||||
# Function to get the latest mission file from a directory
|
||||
function Get-LatestMission {
|
||||
param([string]$DirectoryPath)
|
||||
|
||||
# Get all .miz files in the directory (not subdirectories)
|
||||
$mizFiles = Get-ChildItem -Path $DirectoryPath -Filter "*.miz" -File -ErrorAction SilentlyContinue
|
||||
|
||||
if ($mizFiles.Count -eq 0) {
|
||||
return $null
|
||||
}
|
||||
|
||||
# Separate files with version numbers from those without
|
||||
$versionedFiles = @()
|
||||
$nonVersionedFiles = @()
|
||||
|
||||
foreach ($file in $mizFiles) {
|
||||
$version = Get-VersionNumber -FileName $file.Name
|
||||
if ($version.HasVersion) {
|
||||
$versionedFiles += [PSCustomObject]@{
|
||||
File = $file
|
||||
Version = $version
|
||||
}
|
||||
} else {
|
||||
$nonVersionedFiles += $file
|
||||
}
|
||||
}
|
||||
|
||||
# If we have versioned files, return the one with the highest version
|
||||
if ($versionedFiles.Count -gt 0) {
|
||||
$latest = $versionedFiles | Sort-Object -Property { $_.Version.Value } -Descending | Select-Object -First 1
|
||||
return $latest.File
|
||||
}
|
||||
|
||||
# If no versioned files, return the most recently modified file
|
||||
if ($nonVersionedFiles.Count -gt 0) {
|
||||
return $nonVersionedFiles | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
# Get all DCS terrain folders (folders starting with "DCS_")
|
||||
$terrainFolders = Get-ChildItem -Path $RootPath -Directory | Where-Object { $_.Name -match '^DCS_' }
|
||||
|
||||
if ($terrainFolders.Count -eq 0) {
|
||||
Write-Warning "No DCS terrain folders found in: $RootPath"
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host "Found $($terrainFolders.Count) terrain folder(s)" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Track statistics
|
||||
$totalMissionsFound = 0
|
||||
$totalMissionsPatched = 0
|
||||
$totalMissionsFailed = 0
|
||||
$skippedTerrains = 0
|
||||
|
||||
# Process each terrain folder
|
||||
foreach ($terrainFolder in $terrainFolders) {
|
||||
$terrainName = $terrainFolder.Name
|
||||
|
||||
# Check if this terrain should be excluded
|
||||
if ($ExcludeTerrain -contains $terrainName) {
|
||||
Write-Host "SKIPPING TERRAIN: $terrainName (excluded)" -ForegroundColor DarkGray
|
||||
$skippedTerrains++
|
||||
continue
|
||||
}
|
||||
|
||||
Write-Host "TERRAIN: $terrainName" -ForegroundColor Cyan
|
||||
|
||||
# Get all subdirectories (mission folders)
|
||||
$missionFolders = Get-ChildItem -Path $terrainFolder.FullName -Directory -ErrorAction SilentlyContinue
|
||||
|
||||
if ($missionFolders.Count -eq 0) {
|
||||
Write-Host " No mission folders found" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
continue
|
||||
}
|
||||
|
||||
Write-Host " Found $($missionFolders.Count) mission folder(s)" -ForegroundColor Gray
|
||||
|
||||
# Process each mission folder
|
||||
foreach ($missionFolder in $missionFolders) {
|
||||
$missionFolderName = $missionFolder.Name
|
||||
|
||||
# Get the latest mission file
|
||||
$latestMission = Get-LatestMission -DirectoryPath $missionFolder.FullName
|
||||
|
||||
if ($null -eq $latestMission) {
|
||||
Write-Host " [$missionFolderName] No .miz files found" -ForegroundColor DarkGray
|
||||
continue
|
||||
}
|
||||
|
||||
$totalMissionsFound++
|
||||
|
||||
Write-Host " [$missionFolderName] Latest: " -NoNewline -ForegroundColor White
|
||||
Write-Host "$($latestMission.Name)" -ForegroundColor Yellow
|
||||
|
||||
# Execute the patch script
|
||||
if ($PSCmdlet.ShouldProcess($latestMission.FullName, "Patch with Moose_.lua")) {
|
||||
try {
|
||||
# Call Patch-MooseMissions.ps1
|
||||
& $patchScriptPath -MissionPath $latestMission.FullName -LuaScriptPath $MooseLuaPath -ErrorAction Stop
|
||||
|
||||
# Check if it succeeded (the script will output its own messages)
|
||||
if ($LASTEXITCODE -eq 0 -or $null -eq $LASTEXITCODE) {
|
||||
$totalMissionsPatched++
|
||||
} else {
|
||||
$totalMissionsFailed++
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host " ERROR: Failed to patch mission - $_" -ForegroundColor Red
|
||||
$totalMissionsFailed++
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host " WHATIF: Would patch this mission" -ForegroundColor Magenta
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Final summary
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Batch Processing Complete" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Terrains Processed: $($terrainFolders.Count - $skippedTerrains)" -ForegroundColor White
|
||||
if ($skippedTerrains -gt 0) {
|
||||
Write-Host "Terrains Skipped: $skippedTerrains" -ForegroundColor DarkGray
|
||||
}
|
||||
Write-Host "Missions Found: $totalMissionsFound" -ForegroundColor White
|
||||
Write-Host "Missions Patched: $totalMissionsPatched" -ForegroundColor Green
|
||||
if ($totalMissionsFailed -gt 0) {
|
||||
Write-Host "Missions Failed: $totalMissionsFailed" -ForegroundColor Red
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
if ($WhatIfPreference) {
|
||||
Write-Host "INFO: This was a WhatIf run - no files were modified" -ForegroundColor Magenta
|
||||
} elseif ($totalMissionsPatched -gt 0) {
|
||||
Write-Host "SUCCESS: All missions have been patched with the latest Moose framework!" -ForegroundColor Green
|
||||
Write-Host "TIP: Test your patched missions in DCS before deployment!" -ForegroundColor Yellow
|
||||
}
|
||||
197
Patch-MooseMissions/README.md
Normal file
197
Patch-MooseMissions/README.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# DCS Mission Patcher
|
||||
|
||||
PowerShell script to automatically patch DCS mission files (.miz) with updated Lua scripts and increment version numbers.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ Updates Lua scripts in .miz files without opening DCS Mission Editor
|
||||
- ✅ **Automatically increments version numbers** in mission filenames (e.g., 1.2.3 → 1.2.4)
|
||||
- ✅ **Preserves original missions** - creates new versioned files instead of overwriting
|
||||
- ✅ Supports single or batch processing of multiple missions
|
||||
- ✅ Can output to a different directory
|
||||
- ✅ Handles both new script insertion and existing script replacement
|
||||
- ✅ Pipeline support for processing multiple missions
|
||||
- ✅ Smart version detection (supports X.Y.Z, X.Y, and X formats)
|
||||
|
||||
## Version Increment Examples
|
||||
|
||||
| Input Filename | Output Filename |
|
||||
|----------------|-----------------|
|
||||
| `Mission-1.2.3.miz` | `Mission-1.2.4.miz` |
|
||||
| `Operation Black Gold 2.8.miz` | `Operation Black Gold 2.9.miz` |
|
||||
| `F99th-Battle of Gori 1.3.miz` | `F99th-Battle of Gori 1.4.miz` |
|
||||
| `MyMission-5.miz` | `MyMission-6.miz` |
|
||||
| `Test.miz` | `Test-1.0.1.miz` |
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Update a mission with automatic version increment:
|
||||
|
||||
```powershell
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "MyMission-1.2.3.miz" -LuaScriptPath "Moose_.lua"
|
||||
# Original: MyMission-1.2.3.miz (untouched)
|
||||
# Creates: MyMission-1.2.4.miz
|
||||
```
|
||||
|
||||
### Batch Processing
|
||||
|
||||
Update all .miz files in a directory:
|
||||
|
||||
```powershell
|
||||
Get-ChildItem "C:\DCS_Missions\*.miz" | .\Patch-MooseMissions.ps1 -LuaScriptPath "C:\Scripts\Moose_.lua"
|
||||
# Each mission gets a new version
|
||||
```
|
||||
|
||||
### Output to Different Directory
|
||||
|
||||
Patch missions and save versioned outputs to a different folder:
|
||||
|
||||
```powershell
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "Mission-1.5.miz" -LuaScriptPath "Moose_.lua" -OutputPath "C:\PatchedMissions"
|
||||
# Creates: C:\PatchedMissions\Mission-1.6.miz
|
||||
```
|
||||
|
||||
### Disable Version Increment (CAUTION!)
|
||||
|
||||
⚠️ Overwrite the original mission file without creating a new version:
|
||||
|
||||
```powershell
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "Mission-1.2.3.miz" -LuaScriptPath "Moose_.lua" -NoVersionIncrement
|
||||
# WARNING: Overwrites Mission-1.2.3.miz (original is lost!)
|
||||
```
|
||||
|
||||
### Custom Script Name
|
||||
|
||||
Insert a script with a different name than the source file:
|
||||
|
||||
```powershell
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "Mission.miz" -LuaScriptPath "MyScript.lua" -ScriptName "CustomName.lua"
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Required | Description |
|
||||
|-----------|----------|-------------|
|
||||
| `-MissionPath` | Yes | Path to .miz mission file(s) to patch |
|
||||
| `-LuaScriptPath` | Yes | Path to the Lua script to insert/replace |
|
||||
| `-ScriptName` | No | Name for the script inside the mission (defaults to source filename) |
|
||||
| `-OutputPath` | No | Directory for patched missions (defaults to source directory) |
|
||||
| `-NoVersionIncrement` | No | **CAUTION:** Overwrites original instead of creating new version |
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Update All Caucasus Missions with Version Increment
|
||||
|
||||
```powershell
|
||||
Get-ChildItem "C:\DCS_MissionDev\DCS_Caucasus\*.miz" | .\Patch-MooseMissions.ps1 -LuaScriptPath "C:\Moose\Moose_.lua"
|
||||
# Each mission gets a new version: 1.2.miz -> 1.3.miz
|
||||
# Originals remain untouched
|
||||
```
|
||||
|
||||
### Example 2: Update Specific Missions to Output Folder
|
||||
|
||||
```powershell
|
||||
$missions = @(
|
||||
"F99th-Operation Black Gold 2.8.miz",
|
||||
"F99th-Operation Ronin 1.4.miz",
|
||||
"F99th-Battle of Gori 1.3.miz"
|
||||
)
|
||||
|
||||
$missions | .\Patch-MooseMissions.ps1 -LuaScriptPath "Moose_.lua" -OutputPath "C:\UpdatedMissions"
|
||||
# Creates: Operation Black Gold 2.9.miz, Operation Ronin 1.5.miz, Battle of Gori 1.4.miz in C:\UpdatedMissions
|
||||
```
|
||||
|
||||
### Example 3: Overwrite Original (Use with Caution)
|
||||
|
||||
```powershell
|
||||
.\Patch-MooseMissions.ps1 -MissionPath "TestMission-1.0.miz" -LuaScriptPath "Moose_.lua" -NoVersionIncrement
|
||||
# WARNING: Overwrites TestMission-1.0.miz (original is lost)
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Extraction**: The script treats .miz files as ZIP archives and extracts them to a temporary directory
|
||||
2. **Script Replacement**: Locates the Lua script in `l10n/DEFAULT/` folder and replaces/adds it
|
||||
3. **Version Increment**: Automatically detects version pattern and increments the patch number
|
||||
4. **Repackaging**: Compresses the modified mission into a new .miz file with incremented version
|
||||
5. **Cleanup**: Removes temporary files
|
||||
|
||||
## Version Detection Logic
|
||||
|
||||
The script intelligently detects and increments version numbers:
|
||||
|
||||
- **X.Y.Z format** (e.g., `Mission-1.2.3.miz`) → Increments Z: `Mission-1.2.4.miz`
|
||||
- **X.Y format** (e.g., `Mission-2.8.miz`) → Increments Y: `Mission-2.9.miz`
|
||||
- **X format** (e.g., `Mission-5.miz`) → Increments X: `Mission-6.miz`
|
||||
- **No version** (e.g., `Mission.miz`) → Adds version: `Mission-1.0.1.miz`
|
||||
|
||||
Supports various separators: `-`, `_`, or space
|
||||
|
||||
## Mission File Structure
|
||||
|
||||
DCS mission files (.miz) are ZIP archives with this structure:
|
||||
|
||||
```
|
||||
Mission.miz
|
||||
├── mission
|
||||
├── options
|
||||
├── warehouses
|
||||
├── l10n/
|
||||
│ └── DEFAULT/
|
||||
│ ├── dictionary
|
||||
│ ├── mapResource
|
||||
│ └── *.lua ← Scripts are stored here
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
⚠️ **Always test patched missions** before using them in production or multiplayer!
|
||||
|
||||
⚠️ **Originals are safe**: By default, the script creates NEW versioned files and never modifies originals
|
||||
|
||||
⚠️ **Script order matters**: If your mission has script load order dependencies, this tool only replaces the file content, not the trigger order
|
||||
|
||||
⚠️ **Version increment default**: By default, versions are incremented. Use `-NoVersionIncrement` to overwrite originals (NOT recommended)
|
||||
|
||||
✅ **Safe for**: Updating framework files like Moose_.lua, mist.lua, or any embedded Lua script
|
||||
|
||||
✅ **Preserves originals**: Original missions remain untouched (new versioned files are created)
|
||||
|
||||
✅ **No backups needed**: Since originals aren't modified, you always have your previous version
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "File is not a .miz mission file"
|
||||
- Ensure you're pointing to a valid .miz file, not a .lua or other file type
|
||||
|
||||
### "Lua script not found"
|
||||
- Verify the path to your Lua script is correct and the file exists
|
||||
|
||||
### Mission doesn't work after patching
|
||||
- Restore from backup
|
||||
- Verify the Lua script is valid
|
||||
- Check DCS.log for script errors
|
||||
- Ensure you updated the correct script name
|
||||
|
||||
### Permission errors
|
||||
- Run PowerShell as Administrator if modifying files in protected directories
|
||||
- Ensure mission files are not read-only
|
||||
|
||||
## Requirements
|
||||
|
||||
- Windows PowerShell 5.1 or later (or PowerShell Core 7+)
|
||||
- Write permissions to mission file locations
|
||||
- Valid .miz mission files
|
||||
- Valid Lua script to insert
|
||||
|
||||
## Author
|
||||
|
||||
**F99th-TracerFacer**
|
||||
|
||||
Discord: https://discord.gg/7wBVWKK3
|
||||
|
||||
## License
|
||||
|
||||
Free to use and modify for the DCS community.
|
||||
Reference in New Issue
Block a user