10 KiB
10 KiB
Real Racing 3 - Asset Import Quick Start Guide
FOR WHEN DISCORD SENDS YOU THE FILES
📥 Step 1: Receive the Assets
Discord will likely send you:
- A .zip/.7z/.tar.gz archive (2-5 GB)
- Or a Google Drive/Mega/Dropbox link
- Or multiple .pak/.pvr/.dat files
📦 Step 2: Extract & Organize
If it's an archive:
# Extract to temporary location
cd E:\rr3\
7z x assets-from-discord.zip -o"assets-temp"
Check what you got:
cd E:\rr3\assets-temp
Get-ChildItem -Recurse | Group-Object Extension | Sort-Object Count -Descending
You should see:
.pakfiles (main game assets).pvrfiles (textures - PowerVR format).datfiles (game data).atlasfiles (sprite sheets).zfiles (compressed data).fsh/.vshfiles (shaders)
✅ Step 3: Verify with Manifests (CRITICAL!)
Run the verification script:
cd E:\rr3\
# Create verification script
@'
$manifestPath = "E:\rr3\RR3CommunityServer\RR3CommunityServer\Assets\manifests\"
$assetsPath = "E:\rr3\assets-temp\"
Write-Host "Verifying assets against manifests..." -ForegroundColor Cyan
Write-Host ""
$verified = 0
$failed = 0
$missing = 0
# Read all manifests
Get-ChildItem $manifestPath -Filter "*.txt" | ForEach-Object {
$manifest = Get-Content $_.FullName
foreach ($line in $manifest) {
if ($line -match '^/') {
$parts = $line -split "`t"
$path = $parts[0]
$expectedMd5 = $parts[1]
$fileName = [System.IO.Path]::GetFileName($path)
# Find file
$file = Get-ChildItem $assetsPath -Recurse -Filter $fileName | Select-Object -First 1
if ($file) {
# Calculate MD5
$md5 = Get-FileHash $file.FullName -Algorithm MD5
$actualMd5 = $md5.Hash.ToLower()
if ($actualMd5 -eq $expectedMd5) {
$verified++
Write-Host "✅ $fileName" -ForegroundColor Green
} else {
$failed++
Write-Host "❌ $fileName - MD5 mismatch!" -ForegroundColor Red
Write-Host " Expected: $expectedMd5" -ForegroundColor Gray
Write-Host " Got: $actualMd5" -ForegroundColor Gray
}
} else {
$missing++
Write-Host "⚠️ $fileName - NOT FOUND" -ForegroundColor Yellow
}
}
}
}
Write-Host ""
Write-Host "═══════════════════════════════════════════" -ForegroundColor Cyan
Write-Host "VERIFICATION COMPLETE" -ForegroundColor Cyan
Write-Host "═══════════════════════════════════════════" -ForegroundColor Cyan
Write-Host "✅ Verified: $verified" -ForegroundColor Green
Write-Host "❌ Failed: $failed" -ForegroundColor Red
Write-Host "⚠️ Missing: $missing" -ForegroundColor Yellow
Write-Host ""
if ($failed -eq 0 -and $missing -lt 100) {
Write-Host "🎉 Assets are GOOD! Ready to deploy!" -ForegroundColor Green -BackgroundColor DarkGreen
} else {
Write-Host "⚠️ Some issues found - check with Discord" -ForegroundColor Yellow
}
'@ | Out-File verify-assets.ps1
# Run it
.\verify-assets.ps1
📂 Step 4: Copy to Server
Once verified, copy to the server:
# Copy all verified assets to server
$destination = "E:\rr3\RR3CommunityServer\RR3CommunityServer\Assets\downloaded\"
# Create directory structure
New-Item -ItemType Directory -Force -Path $destination
# Copy files (preserving structure if possible)
Copy-Item -Path "E:\rr3\assets-temp\*" -Destination $destination -Recurse -Force
Write-Host "✅ Assets copied to server!" -ForegroundColor Green
🗄️ Step 5: Import to Database
Create asset records in database:
cd E:\rr3\RR3CommunityServer
# Create import script
@'
using System;
using System.IO;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using RR3CommunityServer.Data;
var dbPath = "rr3community.db";
var assetsPath = "Assets/downloaded";
var manifestsPath = "Assets/manifests";
Console.WriteLine("Importing assets to database...");
using var db = new RR3DbContext(
new DbContextOptionsBuilder<RR3DbContext>()
.UseSqlite($"Data Source={dbPath}")
.Options
);
int imported = 0;
// Read manifests
foreach (var manifestFile in Directory.GetFiles(manifestsPath, "*.txt"))
{
var lines = File.ReadAllLines(manifestFile);
foreach (var line in lines)
{
if (line.StartsWith("/"))
{
var parts = line.Split('\t');
var path = parts[0];
var md5 = parts[1];
var compressedSize = long.Parse(parts[2]);
var uncompressedSize = long.Parse(parts[3]);
var fileName = Path.GetFileName(path);
// Check if asset exists
if (!db.GameAssets.Any(a => a.EaCdnPath == path))
{
// Find local file
var localFiles = Directory.GetFiles(assetsPath, fileName, SearchOption.AllDirectories);
var localPath = localFiles.FirstOrDefault();
var asset = new GameAsset
{
AssetType = DetermineAssetType(path),
FileName = fileName,
EaCdnPath = path,
LocalPath = localPath,
FileSize = uncompressedSize,
CompressedSize = compressedSize,
Md5Hash = md5,
ContentType = DetermineContentType(path),
Category = DetermineCategory(path),
DownloadedAt = localPath != null ? DateTime.UtcNow : null,
AccessCount = 0
};
db.GameAssets.Add(asset);
imported++;
if (imported % 100 == 0)
{
Console.WriteLine($"Imported {imported} assets...");
db.SaveChanges();
}
}
}
}
}
db.SaveChanges();
Console.WriteLine($"✅ Import complete! {imported} assets added to database.");
static string DetermineAssetType(string path)
{
if (path.Contains("car")) return "car";
if (path.Contains("track")) return "track";
if (path.Contains("audio")) return "audio";
if (path.Contains("gui")) return "ui";
return "other";
}
static string DetermineContentType(string path)
{
var ext = Path.GetExtension(path).ToLower();
return ext switch
{
".pak" => "application/octet-stream",
".pvr" => "image/pvr",
".dat" => "application/octet-stream",
".atlas" => "application/octet-stream",
".z" => "application/x-compress",
_ => "application/octet-stream"
};
}
static string DetermineCategory(string path)
{
if (path.Contains("/car")) return "cars";
if (path.Contains("/track")) return "tracks";
if (path.Contains("/audio")) return "audio";
if (path.Contains("/gui")) return "ui";
return "general";
}
'@ | Out-File -Encoding UTF8 import-assets.csx
# Run with dotnet-script (if installed) or manually add to server
Write-Host "⚠️ Import script created: import-assets.csx" -ForegroundColor Yellow
Write-Host "Run this inside your server project to populate the database" -ForegroundColor Gray
🚀 Step 6: Test Server
cd E:\rr3\RR3CommunityServer\RR3CommunityServer
# Start server
dotnet run
# In another terminal, test:
curl https://localhost:5001/content/api/status
# Should return JSON with:
# "availableAssets": (big number)
# "status": "ready"
📱 Step 7: Modify APK
Option A: APK Tool (Full Recompile)
# Decompile
apktool d realracing3.apk -o rr3-decompiled
# Edit smali or resources to change Director URL
# From: https://syn-dir.sn.eamobile.com
# To: https://YOUR_SERVER_IP:5001
# Recompile
apktool b rr3-decompiled -o rr3-modded.apk
# Sign
jarsigner -keystore my.keystore rr3-modded.apk my-key
# Install
adb install rr3-modded.apk
Option B: Hosts File (Easier but requires root)
On Android device:
# Root required
su
mount -o remount,rw /system
echo "YOUR_SERVER_IP syn-dir.sn.eamobile.com" >> /etc/hosts
echo "YOUR_SERVER_IP cloudcell.ea.com" >> /etc/hosts
On Windows (for emulator):
# Edit C:\Windows\System32\drivers\etc\hosts
# Add these lines:
192.168.1.100 syn-dir.sn.eamobile.com
192.168.1.100 cloudcell.ea.com
🎮 Step 8: LAUNCH THE GAME!
- Install modded APK or set up hosts file
- Launch Real Racing 3
- Game contacts your server (not EA!)
- Downloads assets from your server
- PROFIT! 🏎️💨
📊 Expected Results
First Launch:
Game → Director Service (your server) ✅
Game → Authentication (your server) ✅
Game → Asset manifest (your server) ✅
Game → Downloads .pak files (your server) ✅
Game → PLAYABLE! 🎮
What You'll See in Server Logs:
[INFO] Director request for package: com.ea.games.r3_row
[INFO] GetDeviceID request: hardware=abc123
[INFO] Asset download request: /gui_assets/sprites.atlas
[INFO] Serving asset: /gui_assets/sprites.atlas (3015 bytes)
[INFO] Asset download request: /cars/porsche_911_gt3.pak
[INFO] Serving asset: /cars/porsche_911_gt3.pak (5.2 MB)
🔥 Quick Checklist
When assets arrive:
- Download/extract files
- Run verification script (check MD5s)
- Copy to
Assets/downloaded/ - Import to database (optional but recommended)
- Test server:
curl https://localhost:5001/content/api/status - Modify APK or hosts file
- Install & launch game
- CELEBRATE! 🎉
🆘 Troubleshooting
Assets downloaded but game shows black screen?
- Check server logs for 404 errors
- Verify file paths match manifest paths
- Ensure file permissions are correct
Game can't connect to server?
- Check firewall allows port 5001
- Verify APK modification worked
- Try hosts file method instead
- Check server is running:
netstat -an | findstr 5001
MD5 verification failed?
- Files might be corrupted during transfer
- Ask Discord for re-upload
- Check if files were unzipped correctly
📞 Next Step
Just wait for Discord response now!
When they send files, follow this guide step-by-step and you'll have RR3 running in no time! 🏁