Files
rr3-apk/RR3-NETWORK-ANALYSIS-AND-CONFIG-SYSTEM.md
Daniel Elliott 61ad8db705 Eliminate EA URLs: Change config to CUSTOMIZED mode
- Changed com.ea.nimble.configuration from 'live' to 'customized'
- Added NimbleCustomizedSynergyServerEndpointUrl fallback (localhost:5001)
- EA production URLs no longer reachable in execution path

URL Priority System (enforced):
1. SharedPreferences (user config) - ALWAYS CHECKED FIRST 
2. AndroidManifest.xml (localhost fallback) 
3. EA Servers (unreachable with CUSTOMIZED mode) 

Security improvements:
- No automatic EA server connections
- User-controlled server selection enforced
- Triple-layer protection against EA fallback
- Safe localhost fallback for development

Files modified:
- AndroidManifest.xml (lines 126-128)

Documentation:
- EA-URL-ELIMINATION.md (complete analysis)
- RR3-NETWORK-ANALYSIS-AND-CONFIG-SYSTEM.md (updated)

Next: Rebuild APK to apply configuration changes

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

476 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# RR3 APK Network Analysis & Configuration System
**Analysis Date:** February 22, 2026
**APK Version:** Real Racing 3 v14.0.1
**Status:** Complete Network Stack Analyzed ✅
---
## 📡 Network Communication Architecture
### 1. Primary Network Stack
**Game-Specific HTTP Clients:**
1. **com.firemint.realracing.Http** (189 lines)
- Simple POST-only HTTP client
- Uses native `HttpURLConnection`
- **SSL Validation:** DISABLED (accepts all certificates) ⚠️
- Content-Type: `application/x-www-form-urlencoded`
- Timeout: 10,000ms
- Async callbacks to native JNI layer
- Methods: `completeCallback()`, `dataCallback()`, `errorCallback()`, `headerCallback()`
2. **com.firemonkeys.cloudcellapi.HttpRequest/HttpThread** (116 lines)
- More robust HTTP client with GET/POST support
- Configurable SSL validation (`m_bSSLCheck` flag)
- Custom headers support
- Streaming response (chunk-based callbacks)
- Configurable timeout per request
- Content-Type: `application/x-www-form-urlencoded` (default)
3. **EA Nimble SDK** (Synergy Backend)
- Primary authentication/configuration system
- Director API for service discovery
- Environment switching: INTEGRATION, STAGE, LIVE, CUSTOMIZED
- Base URLs:
- Integration: `https://director-int.sn.eamobile.com`
- Staging: `https://director-stage.sn.eamobile.com`
- Production: `https://syn-dir.sn.eamobile.com`
### 2. CloudCell API Services
**Core Services Integrated:**
- **Billing:** Google Play IAB, Amazon Appstore, Facebook payments
- **Authentication:** Google Play Games, Facebook Graph API
- **Notifications:** Local & push notification system
- **Store Integration:** GooglePlayWorker, FacebookWorker, AmazonStoreWorker
- **UI:** WebView dialogs, in-app prompts
**Key Classes:**
```
com.firemonkeys.cloudcellapi/
├── HttpRequest.java - Main HTTP client
├── HttpThread.java - Async execution
├── GooglePlayWorker.java - Play Store APIs
├── FacebookWorker.java - FB Graph API
├── NetworkStatusMonitor.java - Connectivity tracking
├── LocalNotificationsCenter - Scheduled notifications
├── Security.java - Signature verification
└── util/
├── Inventory.java - IAB inventory
├── Purchase.java - Purchase data
└── FacebookAccessToken - Token storage
```
### 3. Third-Party SDK Network Stack
**Analytics & Ads (20+ SDKs):**
- Firebase (Google backend infrastructure)
- Facebook SDK (Graph API)
- Google Play Services
- IronSource, Vungle, Fyber, mBridge
- Tapjoy (reward ads)
- Singular, AppsFlyer (analytics)
**HTTP Libraries Used:**
- `HttpURLConnection` - Native Java (game code)
- `OkHttp3` - Ad networks & modern SDKs
- `Apache HttpClient` - Legacy support
- `Retrofit` - Indirect via ad networks
- Firebase Performance Monitoring wraps all HTTP
---
## ⚙️ Current Configuration System
### Existing SharedPreferences Files
**1. rr3_community_server.xml** (Custom)
```xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="server_url">https://rr3.example.com:5001</string>
</map>
```
**Location:** `/data/data/com.ea.games.r3_row/shared_prefs/rr3_community_server.xml`
**Managed by:** `CommunityServerManager.java`
**Purpose:** Server URL storage for community servers
**2. rr3_offline_settings.xml** (Custom)
```xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="offline_mode_enabled" value="false" />
</map>
```
**Location:** `/data/data/com.ea.games.r3_row/shared_prefs/rr3_offline_settings.xml`
**Managed by:** `OfflineModeManager.java`
**Purpose:** Online/Offline mode toggle
**3. EA Nimble Persistence** (SDK)
- Cached Synergy environment configuration
- Session tokens & authentication data
- Various SDK-managed preferences
**4. Firebase/Google/Facebook** (Third-party)
- Remote config values
- Analytics settings
- Ad preferences
- OAuth tokens
### Current Configuration Flow
```
APK Startup
MainActivity.onCreate()
OfflineModeManager.init(context) ← Load offline_mode_enabled
CommunityServerManager.checkServerUrl() ← Check if server_url exists
├─ No URL? → ServerSetupActivity → User inputs URL → Save to SharedPrefs
└─ Has URL? → Continue boot
SynergyEnvironmentImpl.getSynergyDirectorServerUrl()
├─ 1. Check CommunityServerManager.getServerUrl() (SharedPreferences)
├─ 2. Check AndroidManifest.xml (NimbleCustomizedSynergyServerEndpointUrl)
└─ 3. Use EA default (LIVE/STAGE/INT based on build)
Director API Call → Service Discovery
Game Loads → Ready to play
```
---
## 🔍 Additional Endpoints Discovered
### Hardcoded URLs in APK
**1. Community Server Examples:**
```smali
# ServerSelectionActivity$1.smali:60
const-string v0, "https://rr3.barrer.net:8443"
# ServerSelectionActivity$1.smali:73
const-string p1, "http://localhost:3000"
```
**2. External Links:**
```smali
# Platform.smali:692
const-string v0, "https://play.google.com/store/apps/details?id=com.ea.game.nfs14_row&hl=en_IN"
```
**3. URL Format Validation:**
```smali
# ServerSetupActivity.smali:85
const-string v1, "❌ Invalid URL format. Example: https://rr3.example.com:5001"
# Checks for:
const-string v0, "http://" # Line 152
const-string v0, "https://" # Line 161
```
### No Additional Game-Specific Endpoints Found
**Key Finding:** The game **exclusively uses EA Nimble SDK's Synergy system** for all game-related network communication. No hardcoded game API endpoints exist outside of:
- EA Synergy Director URLs (environment-based)
- Third-party SDK endpoints (ads, analytics, social)
- Community server URL (user-configured)
This means our server **must implement the Synergy API format** that EA originally used. ✅ Already doing this!
---
## 🛠️ Enhanced Configuration System Design
### Current Limitations
1. **Only stores server URL** - No other settings persisted
2. **No SSL configuration** - Can't pin certificates or configure SSL
3. **No connection preferences** - Timeout, retry, etc. not configurable
4. **No server metadata** - Can't store server name, description, region
5. **No backup servers** - Single point of failure
6. **No validation** - URL format checked but no connectivity pre-validation
### Proposed Enhanced Configuration
**File:** `rr3_community_config.xml` (SharedPreferences)
```xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<!-- Server Configuration -->
<string name="server_url">https://rr3.example.com:5001</string>
<string name="server_name">Official Community Server</string>
<string name="server_region">US-East</string>
<string name="backup_server_url">https://rr3-backup.example.com:5001</string>
<!-- Connection Settings -->
<int name="connection_timeout_ms" value="10000" />
<int name="read_timeout_ms" value="15000" />
<int name="max_retries" value="3" />
<boolean name="auto_reconnect" value="true" />
<!-- SSL/TLS Configuration -->
<boolean name="ssl_validation_enabled" value="true" />
<boolean name="allow_self_signed" value="false" />
<string name="ssl_certificate_pin">sha256/ABCD1234...</string>
<!-- Mode Settings -->
<boolean name="offline_mode_enabled" value="false" />
<boolean name="auto_sync_enabled" value="true" />
<!-- Feature Flags (Server Override) -->
<boolean name="enable_multiplayer" value="false" />
<boolean name="enable_leaderboards" value="true" />
<boolean name="enable_time_trials" value="true" />
<boolean name="enable_custom_content" value="true" />
<!-- Cache Settings -->
<boolean name="cache_enabled" value="true" />
<int name="cache_size_mb" value="500" />
<long name="cache_expire_hours" value="24" />
<!-- Debug/Logging -->
<boolean name="debug_logging" value="false" />
<boolean name="log_network_requests" value="false" />
<!-- Last Update/Sync -->
<long name="last_sync_timestamp" value="1771746759000" />
<long name="config_version" value="1" />
</map>
```
### Implementation: CommunityConfigManager.java
```java
package com.firemint.realracing;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
public class CommunityConfigManager {
private static final String TAG = "RR3_ConfigManager";
private static final String PREFS_NAME = "rr3_community_config";
// Keys
public static final String KEY_SERVER_URL = "server_url";
public static final String KEY_SERVER_NAME = "server_name";
public static final String KEY_BACKUP_URL = "backup_server_url";
public static final String KEY_CONNECTION_TIMEOUT = "connection_timeout_ms";
public static final String KEY_SSL_VALIDATION = "ssl_validation_enabled";
public static final String KEY_OFFLINE_MODE = "offline_mode_enabled";
public static final String KEY_DEBUG_LOGGING = "debug_logging";
// Defaults
private static final int DEFAULT_TIMEOUT = 10000;
private static final boolean DEFAULT_SSL_VALIDATION = true;
private static SharedPreferences getPrefs(Context context) {
return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
// Server URL
public static String getServerUrl(Context context) {
return getPrefs(context).getString(KEY_SERVER_URL, null);
}
public static void setServerUrl(Context context, String url) {
getPrefs(context).edit().putString(KEY_SERVER_URL, url).apply();
Log.i(TAG, "Server URL updated: " + url);
}
// Connection Settings
public static int getConnectionTimeout(Context context) {
return getPrefs(context).getInt(KEY_CONNECTION_TIMEOUT, DEFAULT_TIMEOUT);
}
// SSL Configuration
public static boolean isSslValidationEnabled(Context context) {
return getPrefs(context).getBoolean(KEY_SSL_VALIDATION, DEFAULT_SSL_VALIDATION);
}
// Mode
public static boolean isOfflineMode(Context context) {
return getPrefs(context).getBoolean(KEY_OFFLINE_MODE, false);
}
public static void setOfflineMode(Context context, boolean enabled) {
getPrefs(context).edit().putBoolean(KEY_OFFLINE_MODE, enabled).apply();
Log.i(TAG, "Offline mode: " + (enabled ? "ENABLED" : "DISABLED"));
}
// Debug
public static boolean isDebugLoggingEnabled(Context context) {
return getPrefs(context).getBoolean(KEY_DEBUG_LOGGING, false);
}
// Validation
public static boolean hasValidConfiguration(Context context) {
String url = getServerUrl(context);
return url != null && !url.isEmpty() &&
(url.startsWith("http://") || url.startsWith("https://"));
}
// Reset to defaults
public static void resetToDefaults(Context context) {
getPrefs(context).edit().clear().apply();
Log.i(TAG, "Configuration reset to defaults");
}
// Export/Import for backup
public static String exportConfig(Context context) {
// Return JSON string of all settings
// For backup/restore functionality
return "{}"; // TODO: Implement
}
public static void importConfig(Context context, String json) {
// Import from JSON string
// TODO: Implement
}
}
```
### Smali Implementation Required
To add these features, we need to:
1. **Create CommunityConfigManager.smali** - Convert Java to Smali
2. **Update ServerSetupActivity** - Add advanced settings dialog
3. **Modify SynergyEnvironmentImpl** - Read timeout from config
4. **Update Http.java** - Use config for SSL validation toggle
5. **Create AdvancedSettingsActivity** - UI for all config options
---
## 🎯 Recommendations
### Immediate Actions
1.**Keep current system** - Server URL in SharedPreferences works well
2.**Maintain offline mode** - OfflineModeManager is solid
3. ⚠️ **Fix SSL validation** - Http.java currently accepts ALL certificates (security risk)
4. **Add backup server** - Failover if primary down
5. **Add connection timeout config** - Let users adjust for slow connections
### Phase 2 Enhancements
1. **Settings Menu** - In-game settings UI for:
- Server URL switching
- Offline mode toggle
- Connection preferences
- Debug logging toggle
2. **Server Discovery** - Auto-detect available community servers:
- Broadcast/multicast on LAN
- Public server directory
- QR code server setup
3. **Configuration Sync** - Server pushes config to APK:
- Feature flags from server
- Server MOTD
- Maintenance mode notification
4. **Certificate Pinning** - For production security:
- Pin Let's Encrypt certificates
- Validate server identity
- Prevent MITM attacks
### Security Improvements
**Critical Issue:** SSL validation is DISABLED in Http.java
```java
// CURRENT CODE (INSECURE):
HostnameVerifier allHostsValid = HttpsURLConnection.getDefaultHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier(
HttpsURLConnection.ALLOW_ALL_HOSTNAME_VERIFIER); // ⚠️ DANGER!
// RECOMMENDED FIX:
if (CommunityConfigManager.isSslValidationEnabled(context)) {
// Use default SSL validation
} else {
// Only allow in development builds
HttpsURLConnection.setDefaultHostnameVerifier(
HttpsURLConnection.ALLOW_ALL_HOSTNAME_VERIFIER);
}
```
---
## 📊 Network Communication Summary
| Component | Purpose | Protocol | Status |
|-----------|---------|----------|--------|
| EA Nimble SDK | Auth, config, services | HTTPS | ✅ Implemented |
| CloudCell API | Billing, social, UI | HTTPS | ✅ Integrated |
| Http.java | Game HTTP client | HTTP/HTTPS | ⚠️ No SSL validation |
| HttpRequest | CloudCell HTTP | HTTP/HTTPS | ✅ Configurable SSL |
| Firebase | Analytics, config | HTTPS | ✅ Third-party |
| Ad Networks | Monetization | HTTPS | ✅ Third-party |
---
## 🔧 Configuration File Locations
**APK Internal:**
- `assets/` - Could store default config.json (not currently used)
- `res/xml/` - Could store XML preferences (not currently used)
- `AndroidManifest.xml` - Has NimbleCustomizedSynergyServerEndpointUrl
**Device Storage (Runtime):**
- `/data/data/com.ea.games.r3_row/shared_prefs/rr3_community_server.xml` ✅ In use
- `/data/data/com.ea.games.r3_row/shared_prefs/rr3_offline_settings.xml` ✅ In use
- `/data/data/com.ea.games.r3_row/shared_prefs/rr3_community_config.xml` ⭐ Proposed
**External Storage (Optional):**
- `/sdcard/Android/data/com.ea.games.r3_row/files/config.json` - Backup/import
- `/sdcard/RealRacing3/community_settings.json` - User-accessible config
---
## ✅ Current Implementation Status
**What We Have:**
- ✅ Server URL storage (SharedPreferences)
- ✅ Offline mode toggle (SharedPreferences)
- ✅ Server URL validation (basic)
- ✅ First-launch server setup dialog
- ✅ Settings menu with mode switching
- ✅ Integration with Nimble SDK
**What We Need:**
- ⬜ Enhanced configuration options
- ⬜ SSL certificate validation
- ⬜ Connection timeout configuration
- ⬜ Backup server support
- ⬜ Server discovery mechanism
- ⬜ Configuration import/export
- ⬜ Advanced settings UI
---
## 📝 Next Steps
1. **Phase 1:** Keep current system, fix SSL validation ⚠️
2. **Phase 2:** Add enhanced config options (timeout, backup server)
3. **Phase 3:** Build advanced settings UI
4. **Phase 4:** Implement server discovery & auto-configuration
**Priority:** Fix SSL validation in Http.java immediately for security!
---
**Analysis Complete**
**Configuration System:** Currently functional, recommended enhancements documented
**Security Status:** ⚠️ SSL validation needs fixing
**Network Stack:** Fully mapped and understood