Files
rr3-apk/SERVER-URL-INPUT-IMPLEMENTATION.md
Daniel Elliott 51be1177df feat: Add first-launch server URL input dialog
Implements a setup dialog on first game launch that allows users to enter
their custom community server URL without rebuilding the APK.

Features:
- Server URL input dialog on first launch
- URL validation (format check)
- Connection test button
- SharedPreferences storage
- Priority: SharedPreferences > AndroidManifest.xml > EA defaults
- Activity restart flow for applying configuration

New files:
- CommunityServerManager.smali (URL management)
- ServerSetupActivity.smali + 4 inner classes (dialog UI)
- res/layout/activity_server_setup.xml (layout)
- SERVER-URL-INPUT-IMPLEMENTATION.md (docs)

Modified files:
- SynergyEnvironmentImpl.smali (SharedPreferences check priority)
- MainActivity.smali (first-launch check + onActivityResult)
- AndroidManifest.xml (declare ServerSetupActivity)

Benefits:
- One APK works with any server
- Easy server switching
- Lower barrier to entry for non-technical users
2026-02-21 23:33:14 -08:00

14 KiB

🖥️ RR3 Server URL Input System - Implementation Complete

Date: February 22, 2026
Status: IMPLEMENTED - APK builds successfully
Build: RR3-ServerInput-Test.apk


🎉 What's New

First-Launch Server Configuration Dialog

Users can now enter their custom server URL directly in the game on first launch - no APK rebuilding required!


Key Features

1. First Launch Experience

  • Game detects no server URL configured
  • Shows dialog: "🏎️ Community Server Setup"
  • User enters server URL (e.g., http://192.168.1.100:5001)
  • Optional "Test Connection" button validates connectivity
  • URL saved to device (SharedPreferences)
  • Game continues normal boot with that server

2. Subsequent Launches

  • Game reads saved URL automatically
  • Direct boot to game - no dialog shown
  • URL persists until user changes it

3. Changing Servers

  • Can be implemented in Settings menu
  • Call CommunityServerManager.clearServerUrl(context)
  • Restart game → Setup dialog appears again

4. Priority System

1. 🥇 User input (SharedPreferences) - HIGHEST PRIORITY
2. 🥈 AndroidManifest.xml (fallback)
3. 🥉 EA default servers (last resort)

📁 Files Created/Modified

New Files Created

1. smali_classes2/com/firemint/realracing/CommunityServerManager.smali

  • Static utility class for URL management
  • checkServerUrl() - Returns true if URL configured
  • getServerUrl() - Retrieves saved URL
  • saveServerUrl() - Saves URL to SharedPreferences
  • clearServerUrl() - Clears saved URL (for "Change Server")

2. smali_classes2/com/firemint/realracing/ServerSetupActivity.smali

  • Dialog activity for URL input
  • Text input with validation
  • "Test Connection" button (pings /director/api/android/getDirectionByPackage)
  • "Continue" button saves URL and returns to game

3. smali_classes2/com/firemint/realracing/ServerSetupActivity$1.smali

  • Click listener for "Test Connection" button

4. smali_classes2/com/firemint/realracing/ServerSetupActivity$2.smali

  • Background thread for connection testing

5. smali_classes2/com/firemint/realracing/ServerSetupActivity$2$1.smali

  • UI update runnable for test results

6. smali_classes2/com/firemint/realracing/ServerSetupActivity$3.smali

  • Click listener for "Continue" button

7. res/layout/activity_server_setup.xml

  • Dark-themed dialog layout
  • Title, instructions, input field, examples, status text, buttons
  • Matches game aesthetic

Modified Files

1. smali_classes2/com/ea/nimble/SynergyEnvironmentImpl.smali

  • Line 956-980: Added SharedPreferences check BEFORE manifest check
  • Now reads user-configured URL first
  • Falls back to AndroidManifest.xml if no SharedPreferences URL
  • Logs: "🎯 Using community server from SharedPreferences"

2. smali_classes2/com/firemint/realracing/MainActivity.smali

  • Line 2307-2340: Added server URL check after super.onCreate()
  • If no URL → Launch ServerSetupActivity (blocks boot)
  • If URL exists → Continue normal boot
  • Line 2015-2050: Added onActivityResult() handler
    • REQUEST_CODE 0x1001 = ServerSetupActivity
    • RESULT_OK → Restart activity to continue boot
    • Cancelled → Exit app

3. AndroidManifest.xml

  • Line 81-82: Declared ServerSetupActivity
  • Theme: @android:style/Theme.Dialog
  • Landscape orientation to match game

🔧 Technical Implementation

Architecture Flow

Game Launch
  ↓
MainActivity.onCreate()
  ↓
Check SharedPreferences for "server_url"
  ↓
  ├─→ URL exists? → Continue boot → Use that server
  │
  └─→ No URL? → startActivityForResult(ServerSetupActivity, 0x1001)
        ↓
        [Server Setup Dialog Appears]
        ↓
        User enters URL → Test Connection (optional)
        ↓
        Tap "Continue" → saveServerUrl() → setResult(RESULT_OK)
        ↓
        MainActivity.onActivityResult()
        ↓
        RESULT_OK? → recreate() → Restart MainActivity
        ↓
        Now URL exists → Continue boot → Use custom server

SharedPreferences Storage

File: /data/data/com.ea.games.r3_row/shared_prefs/rr3_community_server.xml

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="server_url">http://192.168.1.100:5001</string>
</map>

URL Validation

Format check:

  • Must start with http:// or https://
  • Examples accepted:
    • http://localhost:5001
    • http://192.168.1.100:5001
    • https://rr3.example.com
    • https://rr3.example.com:8443

Connection test:

  • Creates HttpURLConnection to {URL}/director/api/android/getDirectionByPackage
  • 5-second timeout
  • Shows " Connection successful!" or " Could not connect"
  • User can continue even if test fails (for offline setup)

🎨 UI/UX Details

Dialog Appearance

┌────────────────────────────────────────┐
│  🏎️ Community Server Setup             │
│                                         │
│  Enter your community server URL:      │
│  ┌─────────────────────────────────┐  │
│  │ https://rr3.example.com:5001    │  │
│  └─────────────────────────────────┘  │
│                                         │
│  Examples:                              │
│  • http://192.168.1.100:5001           │
│  • https://rr3.yourserver.com          │
│  • https://rr3.example.com:8443        │
│                                         │
│  ✅ Connection successful!              │
│                                         │
│  [Test Connection] [Continue →]        │
└────────────────────────────────────────┘

Colors:

  • Background: #1a1a1a (dark black)
  • Text: #ffffff (white)
  • Hint text: #666666 (gray)
  • Input background: #2a2a2a (slightly lighter black)
  • Examples: #888888 (medium gray), monospace font
  • Test button: #3a3a3a (dark gray)
  • Continue button: #4CAF50 (green)
  • Success: #00CC66 (bright green)
  • Error: #ff6666 (red)

🧪 Testing Guide

Test Scenario 1: First Launch (Success)

  1. Install APK: adb install RR3-ServerInput-Test.apk
  2. Launch game
  3. Expected: Server setup dialog appears
  4. Enter: http://192.168.1.100:5001
  5. Tap "Test Connection"
  6. Expected: " Connection successful!"
  7. Tap "Continue"
  8. Expected: Dialog closes, game boots normally
  9. Check logcat: adb logcat -s SynergyEnvironmentImpl:I
  10. Expected: "🎯 Using community server from SharedPreferences"

Test Scenario 2: First Launch (Invalid URL)

  1. Install APK
  2. Launch game
  3. Dialog appears
  4. Enter: not-a-url
  5. Tap "Continue"
  6. Expected: " Invalid URL format. Example: https://rr3.example.com:5001"
  7. Cannot continue until valid URL entered

Test Scenario 3: Subsequent Launch

  1. Have already configured URL in Scenario 1
  2. Close and relaunch game
  3. Expected: No dialog - game boots directly with saved URL
  4. Check logcat: " Server URL configured - continuing boot"

Test Scenario 4: Change Server

# Add to SettingsActivity "Change Server" button:
invoke-static {p0}, Lcom/firemint/realracing/CommunityServerManager;->clearServerUrl(Landroid/content/Context;)V

# Then restart game
android.os.Process.killProcess(android.os.Process.myPid());
  1. In-game, go to Settings
  2. Tap "Change Server" (if implemented)
  3. Game restarts
  4. Expected: Server setup dialog appears again
  5. Enter new URL
  6. Game uses new server

Test Scenario 5: Connection Test Failure

  1. Install APK
  2. Launch game
  3. Enter: https://nonexistent-server-12345.com
  4. Tap "Test Connection"
  5. Expected: " Could not connect to server"
  6. Continue button still enabled
  7. User can proceed or fix URL

📱 User Instructions

For End Users

First Time Setup:

  1. Install RR3-ServerInput-Test.apk
  2. Launch the game
  3. You'll see a setup screen
  4. Enter your server URL (ask your server admin)
  5. Example: http://192.168.1.100:5001
  6. Tap "Test Connection" to verify it works
  7. Tap "Continue" when ready
  8. Game will start with your server!

Switching Servers:

  1. Clear app data: Settings → Apps → Real Racing 3 → Clear Data
  2. OR ask for "Change Server" feature in Settings menu
  3. Relaunch game → Setup screen appears again
  4. Enter new server URL

🔧 Developer Guide

Adding "Change Server" to Settings Menu

In SettingsActivity button handler:

# Clear saved URL
invoke-static {p0}, Lcom/firemint/realracing/CommunityServerManager;->clearServerUrl(Landroid/content/Context;)V

# Show confirmation toast
const-string v0, "Server cleared. Restart game to reconfigure."
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V

# Kill process to force restart
invoke-static {}, Landroid/os/Process;->myPid()I
move-result v0
invoke-static {v0}, Landroid/os/Process;->killProcess(I)V

Checking Current Server URL

invoke-static {p0}, Lcom/firemint/realracing/CommunityServerManager;->getServerUrl(Landroid/content/Context;)Ljava/lang/String;
move-result-object v0

# v0 now contains the URL or empty string

Programmatically Setting URL

const-string v0, "https://rr3.example.com:8443"
invoke-static {p0, v0}, Lcom/firemint/realracing/CommunityServerManager;->saveServerUrl(Landroid/content/Context;Ljava/lang/String;)V

🚀 Benefits

For Users

One APK = Unlimited Servers
Easy server switching
No APK building required
Clear setup process
Validation prevents mistakes
Works offline (can skip connection test)

For Community

Easier distribution (single APK for everyone)
Lower barrier to entry (non-technical users can play)
Server discovery (users can try different servers)
Reduced support burden (no "wrong URL" builds)

For Developers

Cleaner architecture (runtime config vs compile-time)
Easier testing (switch servers without rebuilding)
Extensible (can add server browser, QR scanning, etc.)
User-friendly (better UX = happier community)


🔮 Future Enhancements

Phase 2 Features (Not Yet Implemented)

  1. Server List/Favorites

    • Save multiple servers
    • Quick switch between favorites
    • Nickname servers ("My Server", "Official", etc.)
  2. QR Code Scanning

    • Server admin generates QR with URL
    • User scans → Auto-fills URL
    • Perfect for LAN parties
  3. Server Info Display

    • Show server name from Director API
    • Show player count
    • Show ping/latency
    • Show server version
  4. Recently Used Servers

    • Auto-save last 5 servers
    • Quick access dropdown
    • One-tap switching
  5. Settings Menu Integration

    • "Change Server" button
    • "Current Server" display
    • "Test Connection" without restart

📊 Build Information

Build Status: Success

I: Using Apktool 2.10.0 with 12 thread(s).
I: Building resources...
I: Smaling smali_classes2 folder into classes2.dex...
I: Building apk file...
I: Built apk into: RR3-ServerInput-Test.apk

Build Output: E:\rr3\rr3-apk\RR3-ServerInput-Test.apk

Next Steps:

  1. Sign APK with debug/release keystore
  2. Test on device/emulator
  3. Verify SharedPreferences creation
  4. Test URL validation
  5. Test connection test feature
  6. Commit to Git

🔐 Security Considerations

URL Validation

  • Only accepts http:// and https://
  • Rejects javascript:, file://, etc.
  • Input sanitization
  • Connection timeout (5 seconds)

Privacy

  • URLs stored locally only (SharedPreferences)
  • Not sent to analytics
  • Not logged to logcat (only masked logs)
  • User controls their own data

Security Notes

  • ⚠️ SSL validation disabled (by design for custom servers)
  • ⚠️ Connection test sends test request to user-provided URL
  • ⚠️ No protection against malicious servers (user trust model)

📝 Git Commit Message

feat: Add first-launch server URL input dialog

Implements a setup dialog on first game launch that allows users to enter
their custom community server URL. This eliminates the need for rebuilding
APKs with different server URLs.

Features:
- Server URL input dialog on first launch
- URL validation (format check)
- Connection test button
- SharedPreferences storage
- Priority: SharedPreferences > AndroidManifest.xml > EA defaults
- Activity restart flow for applying configuration

New files:
- CommunityServerManager.smali (URL management)
- ServerSetupActivity.smali + inner classes (dialog UI)
- activity_server_setup.xml (layout)

Modified files:
- SynergyEnvironmentImpl.smali (SharedPreferences check priority)
- MainActivity.smali (first-launch check + onActivityResult)
- AndroidManifest.xml (declare ServerSetupActivity)

Benefits:
- One APK works with any server
- Easy server switching
- Lower barrier to entry for non-technical users
- Cleaner distribution model

Closes: #XX (if you have an issue tracker)

🎉 Summary

The server URL input system is now fully implemented!

One APK. Unlimited servers. Zero rebuilds. 🚀

Users can now:

  1. Download one APK
  2. Enter their server URL on first launch
  3. Start playing immediately

This makes Real Racing 3 Community Servers accessible to everyone - not just developers who can rebuild APKs!


Next Step: Sign and test the APK! 🏎️💨