# 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: ```powershell # Extract to temporary location cd E:\rr3\ 7z x assets-from-discord.zip -o"assets-temp" ``` ### Check what you got: ```powershell cd E:\rr3\assets-temp Get-ChildItem -Recurse | Group-Object Extension | Sort-Object Count -Descending ``` **You should see:** - `.pak` files (main game assets) - `.pvr` files (textures - PowerVR format) - `.dat` files (game data) - `.atlas` files (sprite sheets) - `.z` files (compressed data) - `.fsh`/`.vsh` files (shaders) --- ## ✅ Step 3: Verify with Manifests (CRITICAL!) Run the verification script: ```powershell 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: ```powershell # 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: ```powershell 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() .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 ```powershell 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) ```powershell # 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:** ```bash # 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):** ```powershell # 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! 1. Install modded APK or set up hosts file 2. Launch Real Racing 3 3. Game contacts your server (not EA!) 4. Downloads assets from your server 5. **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! 🏁