using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
namespace RR3CommunityServer.Controllers;
[ApiController]
[Route("synergy/content")]
public class ContentController : ControllerBase
{
private readonly IWebHostEnvironment _env;
private readonly string _assetsPath;
public ContentController(IWebHostEnvironment env)
{
_env = env;
_assetsPath = Path.Combine(_env.ContentRootPath, "Assets");
// Create assets directory structure if not exists
Directory.CreateDirectory(Path.Combine(_assetsPath, "cars"));
Directory.CreateDirectory(Path.Combine(_assetsPath, "tracks"));
Directory.CreateDirectory(Path.Combine(_assetsPath, "textures"));
Directory.CreateDirectory(Path.Combine(_assetsPath, "audio"));
}
///
/// Get asset manifest - list of all available content
///
[HttpGet("manifest")]
public IActionResult GetManifest()
{
var assets = GetAssetList();
return Ok(new
{
version = "1.0.0",
assetCount = assets.Count,
totalSize = assets.Sum(a => ((dynamic)a).size),
assets = assets
});
}
///
/// Download specific asset file
///
[HttpGet("download/{assetType}/{assetId}")]
public IActionResult DownloadAsset(string assetType, string assetId)
{
var assetPath = Path.Combine(_assetsPath, assetType, $"{assetId}.pak");
if (!System.IO.File.Exists(assetPath))
{
return NotFound(new { error = $"Asset not found: {assetType}/{assetId}" });
}
var fileBytes = System.IO.File.ReadAllBytes(assetPath);
var fileName = $"{assetId}.pak";
return File(fileBytes, "application/octet-stream", fileName);
}
///
/// Get asset metadata and info
///
[HttpGet("info/{assetType}/{assetId}")]
public IActionResult GetAssetInfo(string assetType, string assetId)
{
var assetPath = Path.Combine(_assetsPath, assetType, $"{assetId}.pak");
if (!System.IO.File.Exists(assetPath))
{
return NotFound(new { error = $"Asset not found: {assetType}/{assetId}" });
}
var fileInfo = new FileInfo(assetPath);
return Ok(new
{
assetId = assetId,
assetType = assetType,
size = fileInfo.Length,
sizeFormatted = FormatBytes(fileInfo.Length),
checksum = CalculateMD5(assetPath),
version = "1.0.0",
downloadUrl = $"/synergy/content/download/{assetType}/{assetId}",
lastModified = fileInfo.LastWriteTimeUtc
});
}
///
/// Check if specific asset exists
///
[HttpHead("download/{assetType}/{assetId}")]
public IActionResult CheckAssetExists(string assetType, string assetId)
{
var assetPath = Path.Combine(_assetsPath, assetType, $"{assetId}.pak");
if (System.IO.File.Exists(assetPath))
{
var fileInfo = new FileInfo(assetPath);
Response.Headers["Content-Length"] = fileInfo.Length.ToString();
Response.Headers["X-Asset-Checksum"] = CalculateMD5(assetPath);
return Ok();
}
return NotFound();
}
///
/// Get assets by type
///
[HttpGet("list/{assetType}")]
public IActionResult GetAssetsByType(string assetType)
{
var typePath = Path.Combine(_assetsPath, assetType);
if (!Directory.Exists(typePath))
{
return Ok(new { assetType = assetType, assets = new List