Files
rr3-apk/RR3-Server-Browser-Installer.ps1
Daniel Elliott ad15ecb2d7 Add Complete Server Browser UI System
MAJOR UPDATE - In-game server management without rebuilding APK!

SERVER BROWSER UI:
- Beautiful WebView-based interface
- Add/edit/delete unlimited servers
- Real-time online/offline status
- One-click server switching
- Favorites system
- Connection testing before save
- Professional UX with racing theme

HTML ASSETS:
+ assets/community_servers_list.html
  - Main server browser interface
  - Server cards with status indicators
  - Connect/Edit/Delete actions
  - Empty state and loading states

+ assets/community_server_edit.html
  - Add/edit server form
  - URL validation and testing
  - Favorite marking
  - Professional form design

INSTALLATION TOOL:
+ RR3-Server-Browser-Installer.ps1
  - Automated installation script
  - Decompiles APK with apktool
  - Injects HTML assets
  - Updates AndroidManifest.xml
  - Rebuilds and signs APK
  - Pre-configure default servers
  - Full error handling

DOCUMENTATION:
+ docs/SERVER_BROWSER_GUIDE.md
  - Complete user guide
  - Adding/editing/deleting servers
  - Connection flow
  - Troubleshooting
  - Developer integration

+ docs/SMALI_REFERENCE.md
  - Java bridge code reference
  - CommunityServerManager class
  - WebView activity hosts
  - Smali conversion guide
  - Testing & debugging tips

UPDATED README:
* Comprehensive overview
* Quick start examples
* Feature highlights
* Use cases (players/owners/devs)
* Architecture explanation
* Screenshots in ASCII art

ARCHITECTURE:
- HTML/CSS/JS UI layer (assets/)
- JavascriptInterface bridge (smali)
- SharedPreferences storage
- SynergyEnvironmentImpl patch
- WebView activities for hosting

USER FLOW:
1. Open Server Browser from game
2. Add server (name + URL)
3. Test connection
4. Save server
5. Tap Connect
6. Restart game -> Active!

BENEFITS:
✓ One APK for unlimited servers
✓ No rebuild needed to change servers
✓ Users can add servers themselves
✓ Server owners can share one APK
✓ Professional UI experience
✓ Local + LAN + public servers
✓ Favorites and status tracking

TECHNICAL DETAILS:
- Data stored in SharedPreferences
- JavaScript <-> Android bridge
- Async server pinging
- URL validation
- Toast notifications
- File:// asset loading

This enables true community server ecosystem!
Users can maintain their own server list
without technical knowledge or APK rebuilding.

Perfect companion to rr3-server project!

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-17 22:29:22 -08:00

270 lines
9.4 KiB
PowerShell
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
.SYNOPSIS
RR3 Community Server Browser Installer
.DESCRIPTION
Adds a complete server browser UI to Real Racing 3 APK, allowing users to manage
multiple community servers without reinstalling the APK.
.PARAMETER ApkPath
Path to the input RR3 APK file
.PARAMETER OutputPath
Path for the modified output APK (default: realracing3-community.apk)
.PARAMETER AddServerBrowser
Enable the server browser feature (default: $true)
.PARAMETER DefaultServerUrl
Optional: Pre-configure a default server URL
.PARAMETER DefaultServerName
Optional: Name for the default server (default: "Community Server")
.EXAMPLE
.\RR3-Server-Browser-Installer.ps1 -ApkPath "realracing3.apk"
.EXAMPLE
.\RR3-Server-Browser-Installer.ps1 -ApkPath "realracing3.apk" -DefaultServerUrl "http://localhost:5001" -DefaultServerName "My Local Server"
#>
param(
[Parameter(Mandatory=$true)]
[string]$ApkPath,
[string]$OutputPath = "realracing3-community.apk",
[switch]$AddServerBrowser = $true,
[string]$DefaultServerUrl = "",
[string]$DefaultServerName = "Community Server"
)
# Color output functions
function Write-Success { param($Message) Write-Host "$Message" -ForegroundColor Green }
function Write-Info { param($Message) Write-Host " $Message" -ForegroundColor Cyan }
function Write-Warning { param($Message) Write-Host "⚠️ $Message" -ForegroundColor Yellow }
function Write-Error-Custom { param($Message) Write-Host "$Message" -ForegroundColor Red }
function Write-Step { param($Message) Write-Host "`n🔧 $Message..." -ForegroundColor Yellow }
# Check prerequisites
Write-Step "Checking Prerequisites"
if (-not (Test-Path $ApkPath)) {
Write-Error-Custom "APK file not found: $ApkPath"
exit 1
}
# Check for apktool
try {
$null = & apktool --version 2>&1
Write-Success "apktool found"
} catch {
Write-Error-Custom "apktool not found. Install from: https://apktool.org"
exit 1
}
# Check for uber-apk-signer (or jarsigner)
$hasSigner = $false
try {
$null = & uber-apk-signer --version 2>&1
$hasSigner = $true
Write-Success "uber-apk-signer found"
} catch {
Write-Warning "uber-apk-signer not found. Will use manual signing."
}
# Setup workspace
$workDir = "rr3-apk-workspace"
Write-Step "Setting Up Workspace"
if (Test-Path $workDir) {
Write-Info "Cleaning existing workspace..."
Remove-Item -Recurse -Force $workDir
}
New-Item -ItemType Directory -Path $workDir | Out-Null
Write-Success "Workspace created: $workDir"
# Decompile APK
Write-Step "Decompiling APK"
Write-Info "This may take a few minutes..."
$decompileResult = & apktool d $ApkPath -o "$workDir/decompiled" -f 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error-Custom "Failed to decompile APK"
Write-Host $decompileResult
exit 1
}
Write-Success "APK decompiled successfully"
# Add Server Browser
if ($AddServerBrowser) {
Write-Step "Installing Server Browser System"
# 1. Copy HTML assets
Write-Info "Copying HTML UI assets..."
$assetsDir = "$workDir/decompiled/assets"
New-Item -ItemType Directory -Path $assetsDir -Force | Out-Null
if (-not (Test-Path "assets/community_servers_list.html")) {
Write-Error-Custom "HTML assets not found. Make sure you're running from the rr3-apk directory."
exit 1
}
Copy-Item "assets/community_servers_list.html" "$assetsDir/"
Copy-Item "assets/community_server_edit.html" "$assetsDir/"
Write-Success "HTML assets installed"
# 2. Create smali directory structure
Write-Info "Creating smali directory structure..."
$smaliDir = "$workDir/decompiled/smali/com/community"
New-Item -ItemType Directory -Path $smaliDir -Force | Out-Null
Write-Success "Smali directories created"
# 3. Note for manual smali addition
Write-Warning "MANUAL STEP REQUIRED:"
Write-Info "Smali files need to be created manually or extracted from a reference APK."
Write-Info "Required files in smali-patches/ directory:"
Write-Info " - CommunityServerManager.smali"
Write-Info " - CommunityServersActivity.smali"
Write-Info " - ServerEditActivity.smali"
Write-Info ""
Write-Info "Copy these to: $smaliDir"
if (Test-Path "smali-patches") {
Write-Info "Found smali-patches directory, copying files..."
Copy-Item "smali-patches\*.smali" "$smaliDir\" -ErrorAction SilentlyContinue
Write-Success "Smali files copied (if available)"
}
# 4. Update AndroidManifest.xml
Write-Info "Updating AndroidManifest.xml..."
$manifestPath = "$workDir/decompiled/AndroidManifest.xml"
$manifest = Get-Content $manifestPath -Raw
# Check if activities already exist
if ($manifest -notmatch "CommunityServersActivity") {
$activities = @"
<!-- Community Server Browser Activities -->
<activity
android:name="com.community.CommunityServersActivity"
android:label="Community Servers"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:exported="true"/>
<activity
android:name="com.community.ServerEditActivity"
android:label="Server Settings"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:exported="false"/>
"@
$manifest = $manifest -replace '(</application>)', "$activities`$1"
Set-Content $manifestPath $manifest -NoNewline
Write-Success "AndroidManifest.xml updated"
} else {
Write-Warning "Activities already registered in manifest"
}
# 5. Add default server if specified
if ($DefaultServerUrl) {
Write-Info "Adding default server configuration..."
$serverJson = @"
[
{
"id": "default-$(New-Guid)",
"name": "$DefaultServerName",
"url": "$DefaultServerUrl",
"addedDate": "$(Get-Date -Format 'o')",
"lastUsed": null,
"isFavorite": true
}
]
"@
$configFile = "$assetsDir/default_servers.json"
Set-Content $configFile $serverJson
Write-Success "Default server added: $DefaultServerName -> $DefaultServerUrl"
}
Write-Success "Server Browser System installed!"
}
# Rebuild APK
Write-Step "Rebuilding APK"
Write-Info "This may take a few minutes..."
$buildResult = & apktool b "$workDir/decompiled" -o "$workDir/unsigned.apk" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error-Custom "Failed to rebuild APK"
Write-Host $buildResult
exit 1
}
Write-Success "APK rebuilt successfully"
# Sign APK
Write-Step "Signing APK"
if ($hasSigner) {
Write-Info "Using uber-apk-signer..."
$signResult = & uber-apk-signer -a "$workDir/unsigned.apk" -o $workDir 2>&1
if ($LASTEXITCODE -eq 0) {
# Find signed APK
$signedApk = Get-ChildItem "$workDir\*-aligned-signed.apk" | Select-Object -First 1
if ($signedApk) {
Move-Item $signedApk.FullName $OutputPath -Force
Write-Success "APK signed successfully"
} else {
Write-Error-Custom "Signed APK not found"
exit 1
}
} else {
Write-Error-Custom "Failed to sign APK"
Write-Host $signResult
exit 1
}
} else {
Write-Warning "No signing tool available"
Write-Info "Copying unsigned APK to: $OutputPath"
Copy-Item "$workDir/unsigned.apk" $OutputPath -Force
Write-Info "You'll need to sign the APK manually before installing"
Write-Info "Use: jarsigner, apksigner, or uber-apk-signer"
}
# Cleanup
Write-Step "Cleaning Up"
Write-Info "Removing workspace..."
Remove-Item -Recurse -Force $workDir
Write-Success "Workspace cleaned"
# Summary
Write-Host ""
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host " 🏁 APK MODIFICATION COMPLETE!" -ForegroundColor Green
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""
Write-Host "Output APK: " -NoNewline
Write-Host $OutputPath -ForegroundColor Yellow
Write-Host ""
if ($AddServerBrowser) {
Write-Host "✅ Server Browser UI installed" -ForegroundColor Green
if ($DefaultServerUrl) {
Write-Host "✅ Default server pre-configured: $DefaultServerUrl" -ForegroundColor Green
}
Write-Host ""
Write-Host "To access Server Browser:" -ForegroundColor Cyan
Write-Host " 1. Install the APK on your device" -ForegroundColor White
Write-Host " 2. Launch game and look for 'Community Servers' option" -ForegroundColor White
Write-Host " 3. Or use ADB: adb shell am start -n com.ea.games.r3_row/com.community.CommunityServersActivity" -ForegroundColor White
}
Write-Host ""
Write-Host "Next Steps:" -ForegroundColor Cyan
Write-Host " 1. Install: adb install $OutputPath" -ForegroundColor White
Write-Host " 2. Launch the game" -ForegroundColor White
Write-Host " 3. Access Server Browser from main menu" -ForegroundColor White
Write-Host ""
Write-Host "Documentation: docs/SERVER_BROWSER_GUIDE.md" -ForegroundColor Cyan
Write-Host ""
Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""