#!/bin/bash # Bash script: Automatically update dependency paths in DevourClient.csproj (macOS) # Function: Automatically find Devour installation path in Steam libraries and replace hardcoded paths in csproj file CSPROJ_PATH="${1:-DevourClient/DevourClient.csproj}" echo "========================================" echo "DevourClient Dependency Path Update Script" echo "========================================" echo "" DEVOUR_APP_ID="1274570" find_steam_libraries() { local steam_libraries=() local default_steam_path="$HOME/Library/Application Support/Steam" if [ -d "$default_steam_path" ]; then steam_libraries+=("$default_steam_path") fi local library_folders_path="$default_steam_path/steamapps/libraryfolders.vdf" if [ -f "$library_folders_path" ]; then while IFS= read -r line; do if [[ $line =~ \"path\"[[:space:]]+\"([^\"]+)\" ]]; then local library_path="${BASH_REMATCH[1]}" library_path="${library_path//\\\\/\/}" if [ -d "$library_path" ]; then steam_libraries+=("$library_path") fi fi done < "$library_folders_path" fi printf '%s\n' "${steam_libraries[@]}" | sort -u } find_devour_path_from_manifest() { local steam_library_path="$1" local app_manifest_path="$steam_library_path/steamapps/appmanifest_${DEVOUR_APP_ID}.acf" if [ -f "$app_manifest_path" ]; then local install_dir=$(grep -o '"installdir"[[:space:]]*"[^"]*"' "$app_manifest_path" | sed 's/.*"\([^"]*\)".*/\1/') if [ -n "$install_dir" ]; then local devour_path="$steam_library_path/steamapps/common/$install_dir" if [ -d "$devour_path" ]; then echo "$devour_path" return 0 fi fi fi return 1 } declare -A REQUIRED_DEPENDENCIES=( ["0Harmony"]="steamapps/common/Devour/MelonLoader/net6/0Harmony.dll" ["Assembly-CSharp"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Assembly-CSharp.dll" ["Il2CppAstarPathfindingProject"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2CppAstarPathfindingProject.dll" ["Il2CppBehaviorDesigner.Runtime"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2CppBehaviorDesigner.Runtime.dll" ["Il2Cppbolt"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppbolt.dll" ["Il2Cppbolt.user"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppbolt.user.dll" ["Il2Cppcom.rlabrecque.steamworks.net"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppcom.rlabrecque.steamworks.net.dll" ["Il2CppInterop.Runtime"]="steamapps/common/Devour/MelonLoader/net6/Il2CppInterop.Runtime.dll" ["Il2Cppmscorlib"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppmscorlib.dll" ["Il2CppOpsive.UltimateCharacterController"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2CppOpsive.UltimateCharacterController.dll" ["Il2Cppudpkit"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppudpkit.dll" ["Il2Cppudpkit.common"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppudpkit.common.dll" ["Il2Cppudpkit.platform.photon"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppudpkit.platform.photon.dll" ["MelonLoader"]="steamapps/common/Devour/MelonLoader/net6/MelonLoader.dll" ["Unity.TextMeshPro"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Unity.TextMeshPro.dll" ["UnityEngine"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.dll" ["UnityEngine.AnimationModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.AnimationModule.dll" ["UnityEngine.CoreModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.CoreModule.dll" ["UnityEngine.HotReloadModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.HotReloadModule.dll" ["UnityEngine.IMGUIModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.IMGUIModule.dll" ["UnityEngine.InputLegacyModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.InputLegacyModule.dll" ["UnityEngine.PhysicsModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.PhysicsModule.dll" ["UnityEngine.TextRenderingModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.TextRenderingModule.dll" ["UnityEngine.UI"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.UI.dll" ["UnityEngine.UIModule"]="steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.UIModule.dll" ) find_devour_path() { echo "Searching for Devour installation path..." >&2 local steam_libraries steam_libraries=$(find_steam_libraries) if [ -z "$steam_libraries" ]; then echo "No Steam libraries found!" >&2 echo "Please check if Steam is installed." >&2 return 1 fi local devour_path="" while IFS= read -r library; do [ -z "$library" ] && continue local found_path=$(find_devour_path_from_manifest "$library") if [ -n "$found_path" ]; then local melon_loader_path="$found_path/MelonLoader" if [ -d "$melon_loader_path" ]; then devour_path="$found_path" echo "Found Devour: $devour_path" >&2 echo "$devour_path" return 0 fi fi done <<< "$steam_libraries" while IFS= read -r library; do [ -z "$library" ] && continue local possible_path="$library/steamapps/common/Devour" if [ -d "$possible_path" ]; then local melon_loader_path="$possible_path/MelonLoader" if [ -d "$melon_loader_path" ]; then devour_path="$possible_path" echo "Found Devour: $devour_path" >&2 echo "$devour_path" return 0 fi fi done <<< "$steam_libraries" echo "Devour installation path not found!" >&2 echo "Please ensure:" >&2 echo " 1. Devour is installed via Steam" >&2 echo " 2. MelonLoader is installed in the game" >&2 echo "" >&2 return 1 } update_csproj_dependencies() { local csproj_file="$1" local devour_path="$2" python3 << EOF import xml.etree.ElementTree as ET import sys import os required_deps = { "0Harmony": "steamapps/common/Devour/MelonLoader/net6/0Harmony.dll", "Assembly-CSharp": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Assembly-CSharp.dll", "Il2CppAstarPathfindingProject": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2CppAstarPathfindingProject.dll", "Il2CppBehaviorDesigner.Runtime": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2CppBehaviorDesigner.Runtime.dll", "Il2Cppbolt": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppbolt.dll", "Il2Cppbolt.user": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppbolt.user.dll", "Il2Cppcom.rlabrecque.steamworks.net": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppcom.rlabrecque.steamworks.net.dll", "Il2CppInterop.Runtime": "steamapps/common/Devour/MelonLoader/net6/Il2CppInterop.Runtime.dll", "Il2Cppmscorlib": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppmscorlib.dll", "Il2CppOpsive.UltimateCharacterController": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2CppOpsive.UltimateCharacterController.dll", "Il2Cppudpkit": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppudpkit.dll", "Il2Cppudpkit.common": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppudpkit.common.dll", "Il2Cppudpkit.platform.photon": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Il2Cppudpkit.platform.photon.dll", "MelonLoader": "steamapps/common/Devour/MelonLoader/net6/MelonLoader.dll", "Unity.TextMeshPro": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/Unity.TextMeshPro.dll", "UnityEngine": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.dll", "UnityEngine.AnimationModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.AnimationModule.dll", "UnityEngine.CoreModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.CoreModule.dll", "UnityEngine.HotReloadModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.HotReloadModule.dll", "UnityEngine.IMGUIModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.IMGUIModule.dll", "UnityEngine.InputLegacyModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.InputLegacyModule.dll", "UnityEngine.PhysicsModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.PhysicsModule.dll", "UnityEngine.TextRenderingModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.TextRenderingModule.dll", "UnityEngine.UI": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.UI.dll", "UnityEngine.UIModule": "steamapps/common/Devour/MelonLoader/Il2CppAssemblies/UnityEngine.UIModule.dll" } try: tree = ET.parse("$csproj_file") root = tree.getroot() item_group = None for ig in root.findall(".//ItemGroup"): if ig.find("Reference") is not None: item_group = ig break if item_group is None: item_group = ET.SubElement(root, "ItemGroup") added_count = 0 updated_count = 0 for dep_name, rel_path in required_deps.items(): relative_part = rel_path.replace("steamapps/common/Devour/", "") full_path = os.path.join("$devour_path", relative_part) existing_ref = None for ref in item_group.findall("Reference"): if ref.get("Include") == dep_name: existing_ref = ref break if existing_ref is not None: hint_path = existing_ref.find("HintPath") if hint_path is None: hint_path = ET.SubElement(existing_ref, "HintPath") hint_path.text = full_path updated_count += 1 else: new_ref = ET.SubElement(item_group, "Reference") new_ref.set("Include", dep_name) hint_path = ET.SubElement(new_ref, "HintPath") hint_path.text = full_path added_count += 1 try: ET.indent(tree, space=" ") except AttributeError: pass tree.write("$csproj_file", encoding="utf-8", xml_declaration=True) print(f"ADDED:{added_count}") print(f"UPDATED:{updated_count}") except Exception as e: print(f"ERROR:{str(e)}", file=sys.stderr) sys.exit(1) EOF } if [ ! -f "$CSPROJ_PATH" ]; then echo "Error: csproj file not found: $CSPROJ_PATH" >&2 exit 1 fi DEVOUR_PATH=$(find_devour_path) if [ $? -ne 0 ] || [ -z "$DEVOUR_PATH" ]; then exit 1 fi echo "" echo "Updating csproj file..." BACKUP_PATH="${CSPROJ_PATH}.backup" cp "$CSPROJ_PATH" "$BACKUP_PATH" echo "Backup created: $BACKUP_PATH" sed -i '' "s|[A-Z]:\\\\SteamLibrary\\\\steamapps\\\\common\\\\Devour|$DEVOUR_PATH|g" "$CSPROJ_PATH" 2>/dev/null || \ sed -i "s|[A-Z]:\\\\SteamLibrary\\\\steamapps\\\\common\\\\Devour|$DEVOUR_PATH|g" "$CSPROJ_PATH" RESULT=$(update_csproj_dependencies "$CSPROJ_PATH" "$DEVOUR_PATH") if [ $? -ne 0 ]; then echo "Error updating dependencies!" >&2 exit 1 fi ADDED=$(echo "$RESULT" | grep "ADDED:" | cut -d: -f2) UPDATED=$(echo "$RESULT" | grep "UPDATED:" | cut -d: -f2) if [ -z "$ADDED" ]; then ADDED=0 fi if [ -z "$UPDATED" ]; then UPDATED=0 fi if [ "$ADDED" -eq 0 ] && [ "$UPDATED" -eq 0 ]; then echo "Note: No changes needed (all dependencies are up to date)" else echo "Successfully updated csproj file!" if [ "$ADDED" -gt 0 ]; then echo "Added $ADDED new dependency reference(s)" fi if [ "$UPDATED" -gt 0 ]; then echo "Updated $UPDATED existing dependency reference(s)" fi fi echo "" echo "========================================" echo "Update completed!" echo "Devour path: $DEVOUR_PATH" echo "========================================"