diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 568661832..2b42e859c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -78,6 +78,8 @@ + + diff --git a/SERVER-URL-INPUT-IMPLEMENTATION.md b/SERVER-URL-INPUT-IMPLEMENTATION.md new file mode 100644 index 000000000..77026674b --- /dev/null +++ b/SERVER-URL-INPUT-IMPLEMENTATION.md @@ -0,0 +1,478 @@ +# ๐Ÿ–ฅ๏ธ 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 + + + http://192.168.1.100:5001 + +``` + +### 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! ๐ŸŽ๏ธ๐Ÿ’จ diff --git a/build/apk/AndroidManifest.xml b/build/apk/AndroidManifest.xml index fca64444d..5185479d7 100644 Binary files a/build/apk/AndroidManifest.xml and b/build/apk/AndroidManifest.xml differ diff --git a/build/apk/classes2.dex b/build/apk/classes2.dex index d5a2af86f..097b35edf 100644 Binary files a/build/apk/classes2.dex and b/build/apk/classes2.dex differ diff --git a/build/apk/res/layout/activity_server_selection.xml b/build/apk/res/layout/activity_server_selection.xml index edef6b575..c21b1145e 100644 Binary files a/build/apk/res/layout/activity_server_selection.xml and b/build/apk/res/layout/activity_server_selection.xml differ diff --git a/build/apk/res/layout/activity_server_setup.xml b/build/apk/res/layout/activity_server_setup.xml new file mode 100644 index 000000000..0d0f3ba08 Binary files /dev/null and b/build/apk/res/layout/activity_server_setup.xml differ diff --git a/build/apk/res/layout/activity_settings.xml b/build/apk/res/layout/activity_settings.xml index 398a38c26..62cbe4b57 100644 Binary files a/build/apk/res/layout/activity_settings.xml and b/build/apk/res/layout/activity_settings.xml differ diff --git a/build/apk/res/layout/dialog_server_input.xml b/build/apk/res/layout/dialog_server_input.xml index 1a8f2abd0..c90f2acfc 100644 Binary files a/build/apk/res/layout/dialog_server_input.xml and b/build/apk/res/layout/dialog_server_input.xml differ diff --git a/build/apk/resources.arsc b/build/apk/resources.arsc index 9daaf03f3..9f4987988 100644 Binary files a/build/apk/resources.arsc and b/build/apk/resources.arsc differ diff --git a/build/resources.zip b/build/resources.zip index 054faf08b..ab954dcca 100644 Binary files a/build/resources.zip and b/build/resources.zip differ diff --git a/res/layout/activity_server_setup.xml b/res/layout/activity_server_setup.xml new file mode 100644 index 000000000..f88fc35bb --- /dev/null +++ b/res/layout/activity_server_setup.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + +