- Set extractNativeLibs=true to bypass 16KB alignment requirement - Lower targetSDK to 34 for compatibility mode - Update RR3-Community-Mod.ps1 with 16KB zipalign command - Tested on Android 16 (API 36) Issue: apksigner 0.9 breaks 16KB alignment when signing Solution: Extract libs to disk instead of mmap Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
248 lines
10 KiB
PowerShell
248 lines
10 KiB
PowerShell
# 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 = @"
|
||
<meta-data
|
||
android:name="NimbleCustomizedSynergyServerEndpointUrl"
|
||
android:value="$ServerUrl"/>
|
||
"@
|
||
|
||
# Insert after nimble.configuration meta-data
|
||
$manifest = $manifest -replace '(<meta-data\s+android:name="com.ea.nimble.configuration"[^>]*/>)', "`$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
|