# 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
$zipalign = Get-Command zipalign -ErrorAction SilentlyContinue
if ($zipalign) {
$alignedApk = $OutputPath -replace '\.apk$', '-aligned.apk'
& zipalign -v 4 $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