Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Specified variable values
- $SourceFolder = "C:\Program Files (x86)\Steam\steamapps\common\Red Dead Redemption 2\lml\CharactersOverhaul" # Folder with source files
- $TextFilePath = "C:\Program Files (x86)\Steam\steamapps\common\Red Dead Redemption 2\lml\CharactersOverhaul\source_paths.txt" # Path to the text file with paths
- # Define path to the log file and XML file in the same folder as the text file
- $LogFolder = Split-Path $TextFilePath
- $LogFile = Join-Path $LogFolder "log.log" # Use .log extension
- $XmlFileName = Join-Path $LogFolder "EasyInstall.xml"
- # Clear old log (ignore errors if the file doesn't exist)
- if (Test-Path $LogFile) {
- Clear-Content $LogFile -ErrorAction SilentlyContinue
- }
- # Read content of the text file into an array of strings
- $TextFileContent = Get-Content $TextFilePath
- # Get a list of all files in the folder and subfolders
- $FilesInFolder = Get-ChildItem -Path $SourceFolder -File -Recurse
- # Create XML file
- $XmlDocument = New-Object System.Xml.XmlDocument
- # Create root element
- $RootElement = $XmlDocument.CreateElement("EasyInstall")
- $XmlDocument.AppendChild($RootElement)
- # Add Name element (folder name)
- $NameElement = $XmlDocument.CreateElement("Name")
- $NameElement.InnerText = (Get-Item $SourceFolder).Name
- $RootElement.AppendChild($NameElement)
- # Add Author element
- $AuthorElement = $XmlDocument.CreateElement("Author")
- $AuthorElement.InnerText = "werwolf969"
- $RootElement.AppendChild($AuthorElement)
- # Add Version element
- $VersionElement = $XmlDocument.CreateElement("Version")
- $VersionElement.InnerText = "1.0"
- $RootElement.AppendChild($VersionElement)
- # Create Resources section
- $ResourcesElement = $XmlDocument.CreateElement("Resources")
- $RootElement.AppendChild($ResourcesElement)
- # Create Resource section
- $ResourceElement = $XmlDocument.CreateElement("Resource")
- $ResourcesElement.AppendChild($ResourceElement)
- function Convert-FilePath {
- param ([string]$FilePath)
- # Archive and mount point mappings
- $Mapping = @{
- "common_0.rpf" = "common:/"
- "movies_0.rpf" = "common:/"
- "anim_0.rpf" = "platform:/"
- "data_0.rpf" = "platform:/"
- "rowpack_0.rpf" = "platform:/"
- "hd_0.rpf" = "platform:/"
- "levels_0.rpf" = "platform:/"
- "levels_1.rpf" = "platform:/"
- "levels_2.rpf" = "platform:/"
- "levels_3.rpf" = "platform:/"
- "levels_4.rpf" = "platform:/"
- "levels_5.rpf" = "platform:/"
- "levels_6.rpf" = "platform:/"
- "levels_7.rpf" = "platform:/"
- "packs_0.rpf" = "platform:/"
- "packs_1.rpf" = "platform:/"
- "textures_0.rpf" = "platform:/"
- "textures_1.rpf" = "platform:/"
- "shaders_x64.rpf" = "common:/"
- "update_2.rpf" = "update:/"
- "update_3.rpf" = "update:/"
- "update_4.rpf" = "update:/"
- "update_1.rpf" = "update:/"
- "audio_rel.rpf" = "audio:/"
- "dlc_content_extra\dlc.rpf" = "dlc_content_extra:/"
- "mp001\dlc.rpf" = "dlc_mp001:/"
- "mp003\dlc.rpf" = "dlc_mp003:/"
- "mp004\dlc.rpf" = "dlc_mp004:/"
- "mp005\dlc.rpf" = "dlc_mp005:/"
- "mp006\dlc.rpf" = "dlc_mp006:/"
- "mp007\dlc.rpf" = "dlc_mp007:/"
- "mp008\dlc.rpf" = "dlc_mp008:/"
- "mp009\dlc.rpf" = "dlc_mp009:/"
- "opt001\dlc.rpf" = "dlc_opt001:/"
- "patchpack_mp001\dlc.rpf" = "dlc_patchpack_mp001:/"
- "patchpack_mp003\dlc.rpf" = "dlc_patchpack_mp003:/"
- "patchpack_mp006\dlc.rpf" = "dlc_patchpack_mp006:/"
- "patchpack001\dlc.rpf" = "dlc_patchPack001:/"
- "patchpack002\dlc.rpf" = "dlc_patchPack002:/"
- "patchpack003\dlc.rpf" = "dlc_patchPack003:/"
- "patchpack004\dlc.rpf" = "dlc_patchPack004:/"
- "patchpack005\dlc.rpf" = "dlc_patchPack005:/"
- "patchpack006\dlc.rpf" = "dlc_patchPack006:/"
- "patchpack007\dlc.rpf" = "dlc_patchPack007:/"
- "patchpack008\dlc.rpf" = "dlc_patchPack008:/"
- "patchpack009\dlc.rpf" = "dlc_patchPack009:/"
- "row_patchpack002\dlc.rpf" = "dlc_row_patchpack002:/"
- "row_patchpack005\dlc.rpf" = "dlc_row_patchpack005:/"
- "row_patchpack008\dlc.rpf" = "dlc_row_patchpack008:/"
- }
- # Search for the longest matching key in the path
- foreach ($key in $Mapping.Keys | Sort-Object Length -Descending) {
- if ($FilePath -like "*$key*") {
- $MountPoint = $Mapping[$key]
- $RemainingPath = $FilePath -replace ".*$([regex]::Escape($key))", ""
- $RemainingPath = $RemainingPath -replace '\\', '/' # Convert to forward slashes
- if ($MountPoint -like "*/" -and $RemainingPath -like "/*") {
- $RemainingPath = $RemainingPath.TrimStart('/')
- }
- # Remove .rpf from the remaining path
- $RemainingPath = $RemainingPath -replace '\.rpf', ''
- return "$MountPoint$RemainingPath"
- }
- }
- return $FilePath # If no mapping is found, return the original path
- }
- # Convert paths and add unique FileReplacement elements
- $FileReplacementMap = @{}
- foreach ($line in $TextFileContent) {
- $FileName = [System.IO.Path]::GetFileName($line)
- if (!$FileName) { continue }
- $MatchingFile = $FilesInFolder | Where-Object { $_.Name -eq $FileName } | Select-Object -First 1
- if ($MatchingFile) {
- $TransformedPath = Convert-FilePath -FilePath $line
- $RelativeFilePath = ($MatchingFile.FullName.Substring($SourceFolder.Length + 1) -replace '\\', '/').TrimStart('/')
- # Check if a FileReplacement already exists for this FilePath
- if ($FileReplacementMap.ContainsKey($RelativeFilePath)) {
- # Add a new GamePath to the existing FileReplacement if it's unique
- $ExistingFileReplacement = $FileReplacementMap[$RelativeFilePath]
- if (-not ($ExistingFileReplacement.ChildNodes | Where-Object { $_.InnerText -eq $TransformedPath })) {
- $NewGamePathElement = $XmlDocument.CreateElement("GamePath")
- $NewGamePathElement.InnerText = $TransformedPath
- $ExistingFileReplacement.InsertBefore($NewGamePathElement, $ExistingFileReplacement.LastChild)
- }
- # Remove duplicate GamePath nodes
- $GamePaths = $ExistingFileReplacement.SelectNodes("GamePath")
- $UniqueGamePaths = $GamePaths | Sort-Object -Unique { $_.InnerText }
- foreach ($GamePath in $GamePaths) {
- if (-not ($UniqueGamePaths -contains $GamePath)) {
- $ExistingFileReplacement.RemoveChild($GamePath)
- }
- }
- # Set allowDuplicate="true" if there are multiple unique GamePaths
- if ($UniqueGamePaths.Count -gt 1) {
- $ExistingFileReplacement.SetAttribute("allowDuplicate", "true")
- } else {
- $ExistingFileReplacement.Attributes.RemoveNamedItem("allowDuplicate")
- }
- } else {
- # Create a new FileReplacement element if none exists for this FilePath
- $FileReplacementElement = $XmlDocument.CreateElement("FileReplacement")
- $GamePathElement = $XmlDocument.CreateElement("GamePath")
- $GamePathElement.InnerText = $TransformedPath
- $FileReplacementElement.AppendChild($GamePathElement)
- $FilePathElement = $XmlDocument.CreateElement("FilePath")
- $FilePathElement.InnerText = $RelativeFilePath
- $FileReplacementElement.AppendChild($FilePathElement)
- # Add the new FileReplacement element to the Resource
- $ResourceElement.AppendChild($FileReplacementElement)
- $FileReplacementMap[$RelativeFilePath] = $FileReplacementElement
- }
- } else {
- # Log missing files
- Add-Content -Path $LogFile -Value "Missing file: $FileName"
- }
- }
- # Save the XML document
- $XmlDocument.Save($XmlFileName)
- Write-Output "XML document saved to $XmlFileName"
Advertisement
Add Comment
Please, Sign In to add comment