mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 07:29:00 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RadicadeServer.API.Studio;
|
||||
|
||||
namespace RadicadeServer.CDN
|
||||
{
|
||||
/// <summary>
|
||||
/// Step one of the client's two-step bundle download. The client asks
|
||||
/// <c>/rooms/unity_assets/{assetId}/{target}/{version}</c> and is handed a file name, then
|
||||
/// ranges over that file at <c>/data/{Filename}</c> (and, for a subroom's bundle, under the
|
||||
/// CDN's own <c>/unity/{Filename}</c> alias).
|
||||
///
|
||||
/// The id arrives in two shapes and both have to be answered. A Studio manifest id is 40
|
||||
/// alphanumerics and its baked bundles are named in the manifest's own metadata. A legacy
|
||||
/// bundle is stored under its file name (or that name minus <c>.assetbundle</c>), and that
|
||||
/// name is what the subroom's <c>UnityAssetId</c> carries - every imported room, the built-in
|
||||
/// rooms and every room bound from the admin panel. Answering only the 40-character shape
|
||||
/// leaves every legacy bundle unresolvable, and the client reports one 400 as
|
||||
/// "Error downloading room assets" for the whole room.
|
||||
/// </summary>
|
||||
[Route("rooms/")]
|
||||
public class UnityAssetsCDN : Controller
|
||||
{
|
||||
[HttpGet("unity_assets/{assetId}/{target}/{version}")]
|
||||
public async Task<IActionResult> GetUnityAsset(string assetId, int target, int version)
|
||||
{
|
||||
return await ServeMetadataAsync(assetId, target, version);
|
||||
}
|
||||
|
||||
[HttpGet("unity_assets/{assetId}")]
|
||||
public async Task<IActionResult> GetUnityAsset(string assetId)
|
||||
{
|
||||
return await ServeMetadataAsync(assetId, 0, 1);
|
||||
}
|
||||
|
||||
private async Task<IActionResult> ServeMetadataAsync(string assetId, int target, int version)
|
||||
{
|
||||
if (!CdnStorageNames.IsServable(assetId) || target < 0 || target > byte.MaxValue || version < 0)
|
||||
return BadRequest();
|
||||
|
||||
string? filename = null;
|
||||
string? rejectedDependencies = null;
|
||||
|
||||
if (StudioUnityAssetRegistry.IsValidAssetId(assetId))
|
||||
{
|
||||
var asset = await StudioUnityAssetRegistry.ReadAsync(assetId, HttpContext.RequestAborted);
|
||||
var baked = asset?.BakedUnityAssets.FirstOrDefault(x => x.Target == target && x.Version == version);
|
||||
|
||||
if (baked != null)
|
||||
{
|
||||
filename = baked.Filename;
|
||||
rejectedDependencies = baked.RejectedDependenciesFilename;
|
||||
}
|
||||
else if (asset != null)
|
||||
{
|
||||
// The manifest exists, so the file on disk under this id is that JSON
|
||||
// manifest and not a bundle. A target/version it does not name is a 404:
|
||||
// handing the manifest over as the bundle would have the client parse
|
||||
// metadata as an asset bundle.
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
// Reached for every legacy id, and for a 40-character id with no manifest behind it:
|
||||
// the bundle is the file stored under the name the subroom points at, with or without
|
||||
// the .assetbundle suffix an import appends.
|
||||
filename ??= CdnStorageNames.Resolve(assetId);
|
||||
if (filename == null) return NotFound();
|
||||
|
||||
var body = JsonSerializer.Serialize(new
|
||||
{
|
||||
UnityAssetId = assetId,
|
||||
Target = target,
|
||||
Version = version,
|
||||
Filename = filename,
|
||||
RejectedDependenciesFilename = rejectedDependencies
|
||||
});
|
||||
return Content(body, "application/json");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user