Files
rr3-server/IMPLEMENTATION_GUIDE.md
Daniel Elliott 0a327f3a8b Initial commit: RR3 Community Server with web admin panel
- ASP.NET Core 8 REST API server
- 12 API endpoints matching EA Synergy protocol
- SQLite database with Entity Framework Core
- Web admin panel with Bootstrap 5
- User, Catalog, Session, Purchase management
- Comprehensive documentation

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

628 lines
15 KiB
Markdown

# Real Racing 3 Community Server - Implementation Guide
## 🎮 Overview
This is a fully functional, cross-platform .NET 8 community server for Real Racing 3 that emulates EA's Synergy backend infrastructure. This enables:
- **Private servers** for offline/LAN play
- **Game preservation** when official servers shut down
- **Custom content** and modifications
- **Educational purposes** for understanding client-server architecture
---
## ✅ What's Implemented
### Core Infrastructure
-**ASP.NET Core 8.0** Web API (cross-platform: Windows, Linux, macOS)
-**SQLite Database** for data persistence
-**Entity Framework Core** for ORM
-**Swagger UI** for API documentation and testing
### API Endpoints (100% Core Functionality)
#### 1. Director/Service Discovery
- `GET /director/api/android/getDirectionByPackage` - Service URLs routing
#### 2. User Management
- `GET /user/api/android/getDeviceID` - Device registration
- `GET /user/api/android/validateDeviceID` - Device validation
- `GET /user/api/android/getAnonUid` - Anonymous user ID generation
#### 3. Product Catalog
- `GET /product/api/core/getAvailableItems` - Item catalog
- `GET /product/api/core/getMTXGameCategories` - Categories
- `POST /product/api/core/getDownloadItemUrl` - Download URLs
#### 4. DRM & Purchases
- `GET /drm/api/core/getNonce` - DRM nonce generation
- `GET /drm/api/core/getPurchasedItems` - Purchase history
- `POST /drm/api/android/verifyAndRecordPurchase` - Purchase verification
#### 5. Analytics/Tracking
- `POST /tracking/api/core/logEvent` - Event logging
- `POST /tracking/api/core/logEvents` - Batch event logging
### Middleware
-**Synergy Headers Middleware** - Extracts and logs EA custom headers
-**Session Validation Middleware** - Validates sessions (lenient for community use)
### Services
-**Session Management** - UUID-based session tracking
-**User Service** - Device/user management
-**Catalog Service** - Product catalog management
-**DRM Service** - Nonce generation and purchase tracking
---
## 🚀 Quick Start
### Prerequisites
- **[.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)** or later
- **Port 443 or 5001** available for HTTPS
- **Administrative privileges** (for hosts file modification)
### Step 1: Build and Run
```bash
# Navigate to server directory
cd E:\rr3\RR3CommunityServer\RR3CommunityServer
# Restore dependencies
dotnet restore
# Build the project
dotnet build
# Run the server
dotnet run
```
You should see:
```
╔══════════════════════════════════════════════════════════╗
║ Real Racing 3 Community Server - RUNNING ║
╠══════════════════════════════════════════════════════════╣
║ Server is ready to accept connections ║
║ Ensure DNS/hosts file points EA servers to this IP ║
╚══════════════════════════════════════════════════════════╝
Listening on: https://localhost:5001
Director endpoint: /director/api/android/getDirectionByPackage
```
### Step 2: Redirect Game Traffic
The game needs to connect to **your server** instead of EA's servers.
#### Option A: Hosts File (Localhost Only)
**Windows:**
1. Open `C:\Windows\System32\drivers\etc\hosts` as Administrator
2. Add these lines:
```
127.0.0.1 syn-dir.sn.eamobile.com
127.0.0.1 director-stage.sn.eamobile.com
```
**Linux/macOS:**
1. Edit `/etc/hosts` with sudo:
```bash
sudo nano /etc/hosts
```
2. Add:
```
127.0.0.1 syn-dir.sn.eamobile.com
127.0.0.1 director-stage.sn.eamobile.com
```
#### Option B: Network-Wide Redirect (For LAN/Mobile Devices)
1. **DNS Override** - Configure your router/DNS server to point EA domains to your server IP
2. **Hosts file on mobile** (Android requires root):
```
<YOUR_SERVER_IP> syn-dir.sn.eamobile.com
```
#### Option C: SSL Interception (Advanced)
Use **mitmproxy** or similar tools for full HTTPS interception:
```bash
# Install mitmproxy
pip install mitmproxy
# Run proxy
mitmproxy --mode reverse:https://localhost:5001@*
# Install mitmproxy CA certificate on device
# Follow: https://docs.mitmproxy.org/stable/concepts-certificates/
```
### Step 3: Test the Server
#### Using Browser
Navigate to: `https://localhost:5001/director/api/android/getDirectionByPackage?packageName=com.ea.games.r3_row`
You should see JSON response:
```json
{
"resultCode": 0,
"message": "Success",
"data": {
"serverUrls": {
"synergy.product": "https://localhost:5001",
"synergy.drm": "https://localhost:5001",
...
}
}
}
```
#### Using curl
```bash
curl -k https://localhost:5001/user/api/android/getDeviceID?deviceId=test123&hardwareId=hw456
```
#### Using Swagger UI
Navigate to: `https://localhost:5001/swagger`
---
## 📁 Project Structure
```
RR3CommunityServer/
├── Controllers/ # API endpoints
│ ├── DirectorController.cs # Service discovery
│ ├── UserController.cs # User management
│ ├── ProductController.cs # Catalog
│ ├── DrmController.cs # Purchases
│ └── TrackingController.cs # Analytics
├── Models/
│ └── ApiModels.cs # DTOs for requests/responses
├── Services/
│ ├── IServices.cs # Service interfaces
│ └── ServiceImplementations.cs # Business logic
├── Data/
│ └── RR3DbContext.cs # Entity Framework context
├── Middleware/
│ └── SynergyMiddleware.cs # Request processing
├── Program.cs # App entry point
├── appsettings.json # Configuration
└── RR3CommunityServer.csproj # Project file
```
---
## 🗄️ Database
The server uses **SQLite** with Entity Framework Core.
### Location
`rr3community.db` (created automatically in project directory)
### Tables
- **Devices** - Registered devices
- **Users** - Synergy user accounts
- **Sessions** - Active sessions
- **Purchases** - Purchase records
- **CatalogItems** - Available items
### Viewing Database
```bash
# Install SQLite viewer
dotnet tool install -g dotnet-sqlite
# View database
dotnet sqlite rr3community.db
```
Or use GUI tools:
- [DB Browser for SQLite](https://sqlitebrowser.org/)
- [DBeaver](https://dbeaver.io/)
---
## ⚙️ Configuration
Edit `appsettings.json` to customize behavior:
```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Server": {
"Port": 5001,
"EnableSwagger": true
}
}
```
---
## 🔌 API Protocol
### Request Headers (Required)
```
Content-Type: application/json
SDK-VERSION: 1.63.0.2 # Nimble SDK version
SDK-TYPE: Nimble # EA framework identifier
EAM-SESSION: <session-uuid> # Session ID (auto-generated)
EAM-USER-ID: <synergy-id> # User identifier (optional)
EA-SELL-ID: <store-id> # Store ID (e.g., GOOGLE_PLAY)
```
### Response Format
All responses follow Synergy protocol:
```json
{
"resultCode": 0, // 0 = success, negative = error
"message": "Success", // Human-readable message
"data": { ... } // Response payload
}
```
### Error Codes
- `0` - Success
- `-1` - Generic error
- `-100` - Invalid device
- `-200` - Session expired
- `-300` - Purchase verification failed
---
## 🛠️ Development
### Running in Development Mode
```bash
# Watch mode (auto-reload on file changes)
dotnet watch run
```
### Adding New Endpoints
1. **Create Controller**:
```csharp
[ApiController]
[Route("myservice/api/core")]
public class MyController : ControllerBase
{
[HttpGet("myEndpoint")]
public ActionResult<SynergyResponse<object>> MyEndpoint()
{
return Ok(new SynergyResponse<object>
{
resultCode = 0,
data = new { hello = "world" }
});
}
}
```
2. **Add Service (if needed)**:
- Create interface in `IServices.cs`
- Implement in `ServiceImplementations.cs`
- Register in `Program.cs`: `builder.Services.AddScoped<IMyService, MyService>()`
3. **Update Database Model (if needed)**:
- Add entity to `RR3DbContext.cs`
- Run migration:
```bash
dotnet ef migrations add MyFeature
dotnet ef database update
```
### Debugging
```bash
# Enable detailed logging
export ASPNETCORE_ENVIRONMENT=Development
dotnet run
# View logs
tail -f <project-dir>/logs/app.log
```
---
## 🌐 Cross-Platform Deployment
### Windows (Standalone)
```bash
# Publish self-contained
dotnet publish -c Release -r win-x64 --self-contained
# Run
.\bin\Release\net8.0\win-x64\publish\RR3CommunityServer.exe
```
### Linux (Server)
```bash
# Publish for Linux
dotnet publish -c Release -r linux-x64 --self-contained
# Copy to server
scp -r bin/Release/net8.0/linux-x64/publish/ user@server:/opt/rr3server/
# Run as service
sudo systemctl enable rr3server
sudo systemctl start rr3server
```
**Service file** (`/etc/systemd/system/rr3server.service`):
```ini
[Unit]
Description=Real Racing 3 Community Server
[Service]
WorkingDirectory=/opt/rr3server
ExecStart=/opt/rr3server/RR3CommunityServer
Restart=always
User=www-data
[Install]
WantedBy=multi-user.target
```
### macOS
```bash
# Publish
dotnet publish -c Release -r osx-x64 --self-contained
# Run
./bin/Release/net8.0/osx-x64/publish/RR3CommunityServer
```
### Docker
```dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY RR3CommunityServer.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app .
EXPOSE 5001
ENTRYPOINT ["dotnet", "RR3CommunityServer.dll"]
```
```bash
# Build and run
docker build -t rr3-server .
docker run -p 5001:5001 rr3-server
```
---
## 🔒 SSL/HTTPS Setup
### Development (Self-Signed Certificate)
```bash
# Trust dev certificate
dotnet dev-certs https --trust
```
### Production (Let's Encrypt)
```bash
# Install certbot
sudo apt install certbot
# Get certificate
sudo certbot certonly --standalone -d yourdomain.com
# Configure in appsettings.json
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://*:443",
"Certificate": {
"Path": "/etc/letsencrypt/live/yourdomain.com/fullchain.pem",
"KeyPath": "/etc/letsencrypt/live/yourdomain.com/privkey.pem"
}
}
}
}
}
```
---
## 📊 Monitoring & Logging
### View Logs
```bash
# Real-time logs
dotnet run | tee server.log
# Filter errors only
dotnet run 2>&1 | grep "ERROR"
```
### Health Check Endpoint
Add to `Program.cs`:
```csharp
app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.UtcNow }));
```
---
## 🧪 Testing
### Manual Testing with curl
```bash
# Test director endpoint
curl -k https://localhost:5001/director/api/android/getDirectionByPackage?packageName=test
# Test device ID
curl -k -H "SDK-VERSION: 1.63.0.2" \
-H "SDK-TYPE: Nimble" \
https://localhost:5001/user/api/android/getDeviceID?deviceId=test123&hardwareId=hw456
# Test catalog
curl -k -H "EAM-SESSION: test-session" \
https://localhost:5001/product/api/core/getAvailableItems
```
### Automated Testing
Create `Tests/` directory with xUnit tests:
```csharp
public class DirectorControllerTests
{
[Fact]
public async Task GetDirection_ReturnsSuccess()
{
// Arrange
var controller = new DirectorController(logger, config);
// Act
var result = controller.GetDirection("com.ea.games.r3_row");
// Assert
Assert.Equal(0, result.Value.resultCode);
}
}
```
Run tests:
```bash
dotnet test
```
---
## 🎮 Using with Real Racing 3
### Step-by-Step Connection
1. **Start the server**:
```bash
dotnet run
```
2. **Modify hosts file** (see Step 2 above)
3. **Clear app data** (Android/iOS):
- Android: Settings > Apps > Real Racing 3 > Clear Data
- iOS: Delete and reinstall app
4. **Launch Real Racing 3** - it should now connect to your server!
5. **Verify connection** by watching server logs:
```
[INFO] Synergy Request: Path=/director/api/android/getDirectionByPackage
[INFO] GetDeviceID request: existing=null, hardware=abc123
```
---
## ⚠️ Security & Legal
### For Community Use Only
This server is intended for:
- ✅ Private/LAN gameplay
- ✅ Game preservation when official servers shut down
- ✅ Educational purposes
- ✅ Offline gameplay
**NOT for:**
- ❌ Piracy or bypassing purchases
- ❌ Cheating in official multiplayer
- ❌ Distributing EA's copyrighted content
- ❌ Commercial use
### Security Recommendations
- Use **strong SSL certificates** in production
- Implement **authentication** for public servers
- Enable **rate limiting** to prevent abuse
- **Disable Swagger UI** in production (`"EnableSwagger": false`)
---
## 🐛 Troubleshooting
### Issue: "Cannot connect to server"
**Solution:**
- Verify server is running: `curl -k https://localhost:5001/health`
- Check hosts file is correctly configured
- Ensure port 5001/443 is not blocked by firewall
- Check game logs for connection errors
### Issue: "SSL Certificate Error"
**Solution:**
- Trust development certificate: `dotnet dev-certs https --trust`
- Or use `mitmproxy` with custom CA certificate
### Issue: "Database error on startup"
**Solution:**
```bash
# Delete and recreate database
rm rr3community.db
dotnet run
```
### Issue: "Game doesn't recognize purchases"
**Solution:**
- For community servers, all purchases are automatically accepted
- Check DRM endpoint is responding correctly
- Verify purchase records in database
---
## 🔗 Resources
- **Protocol Documentation**: `E:\rr3\NETWORK_COMMUNICATION_ANALYSIS.md`
- **Decompiled APK**: `E:\rr3\decompiled\`
- **.NET Documentation**: https://docs.microsoft.com/dotnet/
- **Entity Framework Core**: https://docs.microsoft.com/ef/core/
- **ASP.NET Core**: https://docs.microsoft.com/aspnet/core/
---
## 👥 Contributing
Want to improve the server? Here's how:
1. **Fork the repository**
2. **Add features**:
- More robust purchase verification
- Multiplayer/leaderboard support
- Admin web UI
- Content modding tools
3. **Submit pull request**
---
## 📜 Changelog
### Version 1.0.0 (February 2026)
- ✅ Initial release
- ✅ All core Synergy API endpoints
- ✅ SQLite database persistence
- ✅ Cross-platform support (Windows/Linux/macOS)
- ✅ Swagger UI documentation
- ✅ Session management
- ✅ Device registration
- ✅ Catalog system
- ✅ DRM/Purchase tracking
---
## 🎉 Success!
You now have a fully functional Real Racing 3 community server! The game can connect, authenticate, retrieve catalogs, and track progress—all on your own infrastructure.
**Happy Racing! 🏁**