Last active
May 18, 2024 21:47
-
-
Save EntranceJew/fda074b3541a200477f4117ca2950e16 to your computer and use it in GitHub Desktop.
sort those archives
This file contains 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
param( | |
[string]$mo2MyGames = (Join-Path -Path ([environment]::GetFolderPath("MyDocuments")) -ChildPath "My Games\Fallout 76"), | |
[string]$targetIni = "Fallout76Custom.ini", | |
[string]$mo2Instance="$env:LOCALAPPDATA\ModOrganizer\Fallout 76", | |
[string]$mo2Profile="Default", | |
[string]$mo2GameFolder = "${env:ProgramFiles(x86)}\Bethesda.net Launcher\games\Fallout76" | |
) | |
<# | |
THE PROGRAM, BROKEN DOWN: | |
1) determine the load order for mods | |
2) determine associated archives for each mod | |
3) write to the Fallout76Custom ini | |
TODO: | |
1) if we ever get the ability to determine config information from $env then do that | |
#> | |
#region Function Definitions | |
function Test-Installed($cmdname) { | |
return [bool](Get-Module -ListAvailable -Name $cmdname -ErrorAction SilentlyContinue) | |
} | |
function Test-Imported($cmdname) { | |
return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue) | |
} | |
#endregion | |
#region Collect Dependencies | |
if (-Not (Test-Installed "PsGet")){ | |
Write-Host "PsGet was not installed, installing" | |
(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | Invoke-Expression | |
} | |
if (-Not (Test-Imported "Install-Module")) { | |
Write-Host "Install-Module was not imported, this may result in the script not executing correctly" | |
Import-Module -Name "PsGet" | |
} | |
if (-Not (Test-Installed "PsIni")) { | |
Write-Host "could not find PsIni, installing" | |
Install-Module -Name "PsIni" | |
} | |
if (-Not (Test-Imported "Get-IniContent")) { | |
Write-Host "Get-IniContent was not imported, this may result in the script not executing correctly" | |
Import-Module -Name "PsIni" | |
} | |
#endregion | |
<# get the loaded mod folder names, in order #> | |
$mods = @(Get-Content -Path "$mo2Instance\profiles\$mo2Profile\modlist.txt" | Where-Object {$_ -match '^\+.*'} | ForEach-Object {$_.substring(1)}) | |
[array]::Reverse($mods) | |
<# load the existing ini #> | |
$ini = Get-IniContent "$mo2Instance\profiles\$mo2Profile\$targetIni" | |
if ( -Not ($ini.Contains('Archive'))) { | |
$ini['Archive'] = @{}; | |
} | |
$arcs = @{ | |
"sResourceIndexFileList" = @(); | |
"sResourceStartUpArchiveList" = @(); | |
"SResourceArchiveMemoryCacheList" = @(); | |
"SResourceArchiveList" = @(); | |
"SResourceArchiveList2" = @(); | |
"sResourceArchive2List" = @(); | |
} | |
<# get the archives #> | |
$archives = @(Get-ChildItem -Path "$mo2GameFolder\Data\SeventySix - *.ba2" | Select-Object -ExpandProperty 'Name'); | |
foreach ($mod in $mods){ | |
$archives += @(Get-ChildItem -Path "$mo2Instance\mods\$mod" -Include "*.ba2" -Recurse | Select-Object -ExpandProperty 'Name'); | |
} | |
$ballpit = @(); | |
foreach ($file in $archives){ | |
Write-Output "sorting: $file" | |
if ($file -match " - Textures(\d{2})\.ba2$") { | |
$arcs['sResourceIndexFileList'] += $file; | |
} | |
if ($file -match " - (Interface|Localization|Shaders|Startup)\.ba2$") { | |
$arcs['sResourceStartUpArchiveList'] += $file; | |
} | |
if ($file -match " - (Interface|Materials|MiscClient|Shaders)\.ba2$") { | |
$arcs['SResourceArchiveMemoryCacheList'] += $file; | |
} | |
if ($file -match " - (GeneratedMeshes|Materials|Meshes(\d{2}|\w+)?|MiscClient|Sounds\d{2}|Startup|Voices)\.ba2$") { | |
$ballpit += $file; | |
} elseif ($file -match " - (Animations|Enlighten(Interiors|Exteriors\d{2})|GeneratedTextures)\.ba2$") { | |
$ballpit += $file; | |
} elseif ($file -match " - ATX_.*\.ba2$") { | |
# if it is named after DLC, it has to go here | |
$ballpit += $file; | |
} else { | |
# if it did not fit any description above, it gets tacked on at the end | |
$ballpit += $file; | |
} | |
} | |
<# smash a bunch of archives together in the 3 strings we have to do this with #> | |
$runsum = 0; | |
$maxLength = 1024; | |
$archiveKeys = @('SResourceArchiveList', 'SResourceArchiveList2', 'sResourceArchive2List') | |
$archiveIndex = 0; | |
foreach ($ball in $ballpit){ | |
if ($runsum+$ball.length+1 -le $maxLength) { | |
$runsum += $ball.length+1; | |
$arcs[$archiveKeys[$archiveIndex]] += $ball; | |
} else { | |
if($archiveIndex -lt $archiveKeys.Length-1) { | |
$archiveIndex += 1; | |
$runsum = 0; | |
continue; | |
} else { | |
$arcs[$archiveKeys[$archiveIndex]] += $ball; | |
} | |
} | |
} | |
<# write it out #> | |
foreach ($kvp in $arcs.GetEnumerator()) { | |
$ini['Archive'][$kvp.Key] = ($kvp.Value -join ','); | |
} | |
Remove-Item -Path "$mo2Instance\profiles\$mo2Profile\$targetIni" | |
Out-IniFile -InputObject $ini -FilePath "$mo2Instance\profiles\$mo2Profile\$targetIni" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment