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>
This commit is contained in:
627
IMPLEMENTATION_GUIDE.md
Normal file
627
IMPLEMENTATION_GUIDE.md
Normal file
@@ -0,0 +1,627 @@
|
||||
# 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! 🏁**
|
||||
Reference in New Issue
Block a user