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

479 lines
14 KiB
Markdown

# 🖥️ 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
<?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
```smali
# 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:**
```smali
# 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
```smali
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
```smali
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! 🏎️💨