# RR3-Community-Mod.ps1 # Real Racing 3 Community Server APK Modifier # Automatically modifies RR3 APK to use community servers param( [Parameter(Mandatory=$true, HelpMessage="Your community server URL (e.g., https://my-server.com)")] [string]$ServerUrl, [Parameter(HelpMessage="Path to original RR3 APK")] [string]$ApkPath = "realracing3.apk", [Parameter(HelpMessage="Output path for modified APK")] [string]$OutputPath = "realracing3-community.apk" ) # ASCII Art Banner $banner = @" ╔══════════════════════════════════════════════════════════════╗ ║ ║ ║ 🏎️ Real Racing 3 Community Server Modifier 🏎️ ║ ║ ║ ║ Modifies APK to connect to custom servers ║ ║ ║ ╚══════════════════════════════════════════════════════════════╝ "@ Write-Host $banner -ForegroundColor Cyan Write-Host "" # Validate inputs if (-not (Test-Path $ApkPath)) { Write-Host "❌ Error: APK file not found at '$ApkPath'" -ForegroundColor Red exit 1 } if ($ServerUrl -notmatch '^https?://') { Write-Host "❌ Error: Server URL must start with http:// or https://" -ForegroundColor Red exit 1 } # Check for required tools Write-Host "[✓] Checking for required tools..." -ForegroundColor Yellow $apktool = Get-Command apktool -ErrorAction SilentlyContinue if (-not $apktool) { Write-Host "❌ Error: APKTool not found. Install from: https://ibotpeaches.github.io/Apktool/" -ForegroundColor Red exit 1 } $java = Get-Command java -ErrorAction SilentlyContinue if (-not $java) { Write-Host "❌ Error: Java not found. Install JDK 8+ from: https://adoptium.net/" -ForegroundColor Red exit 1 } Write-Host " ✓ APKTool: $($apktool.Version)" -ForegroundColor Green Write-Host " ✓ Java: Found" -ForegroundColor Green Write-Host "" # Step 1: Decompile APK Write-Host "[1/5] 🔓 Decompiling APK..." -ForegroundColor Yellow $workDir = "rr3-modded-temp" if (Test-Path $workDir) { Remove-Item -Recurse -Force $workDir } $decompileResult = & apktool d $ApkPath -o $workDir -f 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "❌ Error decompiling APK: $decompileResult" -ForegroundColor Red exit 1 } Write-Host " ✓ APK decompiled successfully" -ForegroundColor Green Write-Host "" # Step 2: Modify AndroidManifest.xml Write-Host "[2/5] ✏️ Modifying configuration..." -ForegroundColor Yellow $manifestPath = Join-Path $workDir "AndroidManifest.xml" if (-not (Test-Path $manifestPath)) { Write-Host "❌ Error: AndroidManifest.xml not found!" -ForegroundColor Red exit 1 } $manifest = Get-Content $manifestPath -Raw # Check if already modified if ($manifest -match 'NimbleCustomizedSynergyServerEndpointUrl') { Write-Host " ⚠️ APK appears to be already modified. Updating server URL..." -ForegroundColor Yellow # Update existing server URL $manifest = $manifest -replace '(android:name="NimbleCustomizedSynergyServerEndpointUrl"\s+android:value=")[^"]*', "`$1$ServerUrl" } else { # Change configuration from 'live' to 'custom' $manifest = $manifest -replace '(android:name="com.ea.nimble.configuration"\s+android:value=")live(")', '$1custom$2' # Add custom server URL metadata $customServerMeta = @" "@ # Insert after nimble.configuration meta-data $manifest = $manifest -replace '(]*/>)', "`$1`n$customServerMeta" } # Save modified manifest Set-Content -Path $manifestPath -Value $manifest -Encoding UTF8 Write-Host " ✓ Configuration changed to 'custom'" -ForegroundColor Green Write-Host " ✓ Server URL set to: $ServerUrl" -ForegroundColor Green Write-Host "" # Step 3: Recompile APK Write-Host "[3/5] 🔨 Recompiling APK..." -ForegroundColor Yellow $recompileResult = & apktool b $workDir -o $OutputPath 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "❌ Error recompiling APK: $recompileResult" -ForegroundColor Red exit 1 } Write-Host " ✓ APK recompiled successfully" -ForegroundColor Green Write-Host "" # Step 4: Sign APK Write-Host "[4/5] ✍️ Signing APK..." -ForegroundColor Yellow # Check for Uber APK Signer $uberSigner = Get-ChildItem -Path . -Filter "uber-apk-signer*.jar" -ErrorAction SilentlyContinue | Select-Object -First 1 if ($uberSigner) { Write-Host " Using Uber APK Signer..." -ForegroundColor Cyan $signResult = & java -jar $uberSigner.FullName --apks $OutputPath 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "❌ Error signing APK: $signResult" -ForegroundColor Red exit 1 } # Uber signer creates a new file with -aligned-debugSigned suffix $signedApk = $OutputPath -replace '\.apk$', '-aligned-debugSigned.apk' if (Test-Path $signedApk) { Move-Item -Path $signedApk -Destination $OutputPath -Force } } else { Write-Host " ⚠️ Uber APK Signer not found. Using basic jarsigner..." -ForegroundColor Yellow # Create a debug keystore if it doesn't exist $keystorePath = "rr3-debug.keystore" if (-not (Test-Path $keystorePath)) { Write-Host " Creating debug keystore..." -ForegroundColor Cyan & keytool -genkey -v -keystore $keystorePath -alias rr3-key -keyalg RSA -keysize 2048 -validity 10000 -storepass android -keypass android -dname "CN=RR3 Community, OU=Dev, O=Community, L=City, ST=State, C=US" 2>&1 | Out-Null } # Sign with jarsigner & jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 -keystore $keystorePath -storepass android -keypass android $OutputPath rr3-key 2>&1 | Out-Null if ($LASTEXITCODE -ne 0) { Write-Host "❌ Error signing APK with jarsigner" -ForegroundColor Red exit 1 } # Zipalign with 16KB page alignment for Android 15+ (API 35+) $zipalign = Get-Command zipalign -ErrorAction SilentlyContinue if ($zipalign) { $alignedApk = $OutputPath -replace '\.apk$', '-aligned.apk' # Use -p flag for 16KB page alignment (required for Android 15+) & zipalign -p -f -v 16 $OutputPath $alignedApk 2>&1 | Out-Null Move-Item -Path $alignedApk -Destination $OutputPath -Force } } Write-Host " ✓ APK signed successfully" -ForegroundColor Green Write-Host "" # Step 5: Cleanup Write-Host "[5/5] 🧹 Cleaning up..." -ForegroundColor Yellow Remove-Item -Recurse -Force $workDir -ErrorAction SilentlyContinue Write-Host " ✓ Temporary files removed" -ForegroundColor Green Write-Host "" # Success! $successBanner = @" ╔══════════════════════════════════════════════════════════════╗ ║ ║ ║ ✅ SUCCESS! ✅ ║ ║ ║ ║ Your modified APK is ready: ║ ║ 📦 $OutputPath ║ ║ ║ Server URL: $ServerUrl ║ ║ ╚══════════════════════════════════════════════════════════════╝ "@ Write-Host $successBanner -ForegroundColor Green Write-Host "" # Installation instructions Write-Host "📱 Installation Instructions:" -ForegroundColor Cyan Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan Write-Host "" Write-Host "1️⃣ Uninstall the original Real Racing 3 (if installed):" -ForegroundColor Yellow Write-Host " adb uninstall com.ea.games.r3_row" -ForegroundColor White Write-Host "" Write-Host "2️⃣ Install the modified APK:" -ForegroundColor Yellow Write-Host " adb install $OutputPath" -ForegroundColor White Write-Host "" Write-Host "3️⃣ Launch Real Racing 3 - it will connect to your server!" -ForegroundColor Yellow Write-Host "" Write-Host "📝 Note: Make sure your community server is running at:" -ForegroundColor Cyan Write-Host " $ServerUrl" -ForegroundColor White Write-Host "" # Offer to install if ADB is available $adb = Get-Command adb -ErrorAction SilentlyContinue if ($adb) { Write-Host "❓ ADB detected. Would you like to install the APK now? (Y/N)" -ForegroundColor Cyan $install = Read-Host if ($install -eq 'Y' -or $install -eq 'y') { Write-Host "" Write-Host "📱 Checking for connected devices..." -ForegroundColor Yellow $devices = & adb devices if ($devices -match 'device$') { Write-Host " ✓ Device found!" -ForegroundColor Green Write-Host " Uninstalling original app..." -ForegroundColor Yellow & adb uninstall com.ea.games.r3_row 2>&1 | Out-Null Write-Host " Installing modified APK..." -ForegroundColor Yellow $installResult = & adb install -r $OutputPath 2>&1 if ($LASTEXITCODE -eq 0) { Write-Host " ✓ APK installed successfully!" -ForegroundColor Green Write-Host "" Write-Host "🏁 All done! Launch Real Racing 3 on your device." -ForegroundColor Green } else { Write-Host " ❌ Installation failed: $installResult" -ForegroundColor Red } } else { Write-Host " ⚠️ No device connected. Connect via USB and enable USB debugging." -ForegroundColor Yellow } } } Write-Host "" Write-Host "Happy racing! 🏎️💨" -ForegroundColor Magenta