# PowerShell script: Automatically update dependency paths in DevourClient.csproj (Windows) # Function: Automatically find Devour installation path in Steam libraries and replace hardcoded paths in csproj file param( [string]$CsprojPath = "DevourClient\DevourClient.csproj" ) Write-Host "========================================" -ForegroundColor Cyan Write-Host "DevourClient Dependency Path Update Script" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" $DevourAppId = "1274570" function Find-SteamLibraries { $steamLibraries = @() $defaultSteamPath = "${env:ProgramFiles(x86)}\Steam" if (Test-Path $defaultSteamPath) { $steamLibraries += $defaultSteamPath } else { $alternativePaths = @( "${env:ProgramFiles}\Steam", "$env:LOCALAPPDATA\Steam", "C:\Steam", "D:\Steam" ) foreach ($altPath in $alternativePaths) { if (Test-Path $altPath) { $steamLibraries += $altPath $defaultSteamPath = $altPath break } } } $libraryFoldersPath = Join-Path $defaultSteamPath "steamapps\libraryfolders.vdf" if (Test-Path $libraryFoldersPath) { try { $content = Get-Content $libraryFoldersPath -Raw -ErrorAction Stop $pathPattern = '"path"\s+"([^"]+)"' $pathMatches = [regex]::Matches($content, $pathPattern) foreach ($match in $pathMatches) { $libraryPath = $match.Groups[1].Value -replace '\\\\', '\' if (Test-Path $libraryPath) { $steamLibraries += $libraryPath } } } catch { Write-Host "Error reading libraryfolders.vdf: $($_.Exception.Message)" -ForegroundColor Red } } else { $driveLetters = @("C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z") foreach ($drive in $driveLetters) { $pathsToCheck = @( "${drive}:\SteamLibrary", "${drive}:\Steam", "${drive}:\steam", "${drive}:\Steam\SteamLibrary", "${drive}:\Games\Steam" ) foreach ($checkPath in $pathsToCheck) { if (Test-Path $checkPath) { $steamappsPath = Join-Path $checkPath "steamapps" if (Test-Path $steamappsPath) { $steamLibraries += $checkPath } } } } } return $steamLibraries | Select-Object -Unique } function Find-DevourPathFromManifest { param([string]$SteamLibraryPath) $appManifestPath = Join-Path $SteamLibraryPath "steamapps\appmanifest_$DevourAppId.acf" if (Test-Path $appManifestPath) { $content = Get-Content $appManifestPath -Raw $installDirPattern = '"installdir"\s+"([^"]+)"' $installDirMatch = [regex]::Match($content, $installDirPattern) if ($installDirMatch.Success) { $installDir = $installDirMatch.Groups[1].Value $devourPath = Join-Path $SteamLibraryPath "steamapps\common\$installDir" if (Test-Path $devourPath) { return $devourPath } } } return $null } $RequiredDependencies = @( @{ Name = "0Harmony"; RelativePath = "steamapps\common\Devour\MelonLoader\net6\0Harmony.dll" }, @{ Name = "Assembly-CSharp"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll" }, @{ Name = "Il2CppAstarPathfindingProject"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2CppAstarPathfindingProject.dll" }, @{ Name = "Il2CppBehaviorDesigner.Runtime"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2CppBehaviorDesigner.Runtime.dll" }, @{ Name = "Il2Cppbolt"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppbolt.dll" }, @{ Name = "Il2Cppbolt.user"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppbolt.user.dll" }, @{ Name = "Il2Cppcom.rlabrecque.steamworks.net"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppcom.rlabrecque.steamworks.net.dll" }, @{ Name = "Il2CppInterop.Runtime"; RelativePath = "steamapps\common\Devour\MelonLoader\net6\Il2CppInterop.Runtime.dll" }, @{ Name = "Il2Cppmscorlib"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppmscorlib.dll" }, @{ Name = "Il2CppOpsive.UltimateCharacterController"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2CppOpsive.UltimateCharacterController.dll" }, @{ Name = "Il2Cppudpkit"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppudpkit.dll" }, @{ Name = "Il2Cppudpkit.common"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppudpkit.common.dll" }, @{ Name = "Il2Cppudpkit.platform.photon"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppudpkit.platform.photon.dll" }, @{ Name = "MelonLoader"; RelativePath = "steamapps\common\Devour\MelonLoader\net6\MelonLoader.dll" }, @{ Name = "Unity.TextMeshPro"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Unity.TextMeshPro.dll" }, @{ Name = "UnityEngine"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.dll" }, @{ Name = "UnityEngine.AnimationModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.AnimationModule.dll" }, @{ Name = "UnityEngine.CoreModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.CoreModule.dll" }, @{ Name = "UnityEngine.HotReloadModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.HotReloadModule.dll" }, @{ Name = "UnityEngine.IMGUIModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.IMGUIModule.dll" }, @{ Name = "UnityEngine.InputLegacyModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.InputLegacyModule.dll" }, @{ Name = "UnityEngine.PhysicsModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.PhysicsModule.dll" }, @{ Name = "UnityEngine.TextRenderingModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.TextRenderingModule.dll" }, @{ Name = "UnityEngine.UI"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.UI.dll" }, @{ Name = "UnityEngine.UIModule"; RelativePath = "steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.UIModule.dll" } ) function Find-DevourPath { Write-Host "Searching for Devour installation path..." -ForegroundColor Yellow $steamLibraries = Find-SteamLibraries if ($steamLibraries.Count -eq 0) { Write-Host "No Steam libraries found!" -ForegroundColor Red Write-Host "Please check if Steam is installed." -ForegroundColor Yellow return $null } $devourPath = $null foreach ($library in $steamLibraries) { $foundPath = Find-DevourPathFromManifest -SteamLibraryPath $library if ($foundPath) { $melonLoaderPath = Join-Path $foundPath "MelonLoader" if (Test-Path $melonLoaderPath) { $devourPath = $foundPath Write-Host "Found Devour: $devourPath" -ForegroundColor Green return $devourPath } } } foreach ($library in $steamLibraries) { $possiblePath = Join-Path $library "steamapps\common\Devour" if (Test-Path $possiblePath) { $melonLoaderPath = Join-Path $possiblePath "MelonLoader" if (Test-Path $melonLoaderPath) { $devourPath = $possiblePath Write-Host "Found Devour: $devourPath" -ForegroundColor Green break } } } if (-not $devourPath) { Write-Host "Devour installation path not found!" -ForegroundColor Red Write-Host "Please ensure:" -ForegroundColor Yellow Write-Host " 1. Devour is installed via Steam" -ForegroundColor Yellow Write-Host " 2. MelonLoader is installed in the game" -ForegroundColor Yellow Write-Host "" return $null } return $devourPath } function Update-CsprojDependencies { param( [string]$CsprojContent, [string]$DevourPath ) [xml]$xmlDoc = $CsprojContent $itemGroup = $xmlDoc.Project.ItemGroup | Where-Object { $null -ne $_.Reference } | Select-Object -First 1 if (-not $itemGroup) { $itemGroup = $xmlDoc.CreateElement("ItemGroup") $xmlDoc.Project.AppendChild($itemGroup) | Out-Null } $addedCount = 0 $updatedCount = 0 foreach ($dep in $RequiredDependencies) { $relativePart = $dep.RelativePath -replace '^steamapps\\common\\Devour\\', '' $fullPath = Join-Path $DevourPath $relativePart $existingRef = $itemGroup.Reference | Where-Object { $_.Include -eq $dep.Name } | Select-Object -First 1 if ($existingRef) { $hintPathNode = $existingRef.SelectSingleNode("HintPath") if (-not $hintPathNode) { $hintPathNode = $xmlDoc.CreateElement("HintPath") $existingRef.AppendChild($hintPathNode) | Out-Null } $hintPathNode.InnerText = $fullPath $updatedCount++ } else { $newRef = $xmlDoc.CreateElement("Reference") $newRef.SetAttribute("Include", $dep.Name) $hintPathNode = $xmlDoc.CreateElement("HintPath") $hintPathNode.InnerText = $fullPath $newRef.AppendChild($hintPathNode) | Out-Null $itemGroup.AppendChild($newRef) | Out-Null $addedCount++ } } $stringWriter = New-Object System.IO.StringWriter $xmlWriter = New-Object System.Xml.XmlTextWriter($stringWriter) $xmlWriter.Formatting = [System.Xml.Formatting]::Indented $xmlWriter.Indentation = 2 $xmlDoc.WriteContentTo($xmlWriter) $xmlWriter.Flush() $updatedContent = $stringWriter.ToString() return @{ Content = $updatedContent Added = $addedCount Updated = $updatedCount } } try { if (-not (Test-Path $CsprojPath)) { Write-Host "Error: csproj file not found: $CsprojPath" -ForegroundColor Red exit 1 } $devourPath = Find-DevourPath if (-not $devourPath) { exit 1 } Write-Host "" Write-Host "Updating csproj file..." -ForegroundColor Yellow $csprojContent = Get-Content $CsprojPath -Raw -Encoding UTF8 $originalContent = $csprojContent $oldPathPattern = '[A-Z]:\\SteamLibrary\\steamapps\\common\\Devour' $escapedNewPath = $devourPath -replace '\\', '\\' $csprojContent = $csprojContent -replace $oldPathPattern, $escapedNewPath $result = Update-CsprojDependencies -CsprojContent $csprojContent -DevourPath $devourPath $updatedContent = $result.Content if ($originalContent -eq $updatedContent -and $result.Added -eq 0 -and $result.Updated -eq 0) { Write-Host "Note: No changes needed (all dependencies are up to date)" -ForegroundColor Yellow } else { $backupPath = "$CsprojPath.backup" Copy-Item $CsprojPath $backupPath -Force Write-Host "Backup created: $backupPath" -ForegroundColor Gray $fullPath = (Resolve-Path $CsprojPath).Path [System.IO.File]::WriteAllText($fullPath, $updatedContent, [System.Text.Encoding]::UTF8) Write-Host "Successfully updated csproj file!" -ForegroundColor Green if ($result.Added -gt 0) { Write-Host "Added $($result.Added) new dependency reference(s)" -ForegroundColor Cyan } if ($result.Updated -gt 0) { Write-Host "Updated $($result.Updated) existing dependency reference(s)" -ForegroundColor Cyan } } Write-Host "" Write-Host "========================================" -ForegroundColor Cyan Write-Host "Update completed!" -ForegroundColor Green Write-Host "Devour path: $devourPath" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan } catch { Write-Host "" Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red Write-Host $_.ScriptStackTrace -ForegroundColor Red exit 1 }