Radicade Public Code

This commit is contained in:
JogmansonReal
2026-10-16 23:33:13 -07:00
commit 55175acdf6
832 changed files with 363261 additions and 0 deletions
+184
View File
@@ -0,0 +1,184 @@
using System.Security.Cryptography;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using RadicadeServer;
using RadicadeServer.CDN;
using RadicadeServer.RecNet.CDN;
using RadicadeServer.Storage;
using RadicadeServer.API.Studio;
using RadicadeServer.RoomServer;
using RadicadeServer.DB;
using RadicadeServer.RecNet.Rooms;
using Xunit;
namespace RadicadeServer.Tests;
[Collection(DbFactoryCollection.Name)]
public class StudioUploadTests
{
[Fact]
public async Task BatchPreservesOrderAndStoresActualContentsIncludingEmptyFiles()
{
var previous = DBConfig.CDNStorage;
var directory = Path.Combine(Path.GetTempPath(), "studio-upload-" + Guid.NewGuid());
DBConfig.CDNStorage = directory;
try
{
var payloads = new[] { new byte[] { 1, 2, 3 }, Array.Empty<byte>() };
var boundary = "test";
var body = new MemoryStream();
foreach (var payload in payloads)
{
var header = System.Text.Encoding.ASCII.GetBytes(
$"--{boundary}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"asset.bin\"\r\nContent-Type: application/octet-stream\r\n\r\n");
body.Write(header);
body.Write(payload);
body.Write(System.Text.Encoding.ASCII.GetBytes("\r\n"));
}
body.Write(System.Text.Encoding.ASCII.GetBytes($"--{boundary}--\r\n"));
body.Position = 0;
var context = new DefaultHttpContext();
context.Request.ContentType = $"multipart/form-data; boundary={boundary}";
context.Request.Body = body;
context.Request.ContentLength = body.Length;
var controller = new StorageAPI { ControllerContext = new ControllerContext { HttpContext = context } };
var response = Assert.IsType<OkObjectResult>(await controller.UploadUnityAssets());
var json = System.Text.Json.JsonSerializer.SerializeToElement(response.Value);
Assert.Equal(2, json.GetArrayLength());
for (var i = 0; i < payloads.Length; i++)
{
var name = json[i].GetProperty("Filename").GetString()!;
Assert.Equal(40, name.Length);
Assert.Equal(payloads[i], await File.ReadAllBytesAsync(Path.Combine(directory, name)));
Assert.Equal(Convert.ToBase64String(SHA256.HashData(payloads[i])), json[i].GetProperty("Hash").GetString());
Assert.IsType<PhysicalFileResult>(new StudioAssetsCDN().Download(name));
}
Assert.Equal(2, Directory.GetFiles(directory).Length);
}
finally
{
DBConfig.CDNStorage = previous;
if (Directory.Exists(directory)) Directory.Delete(directory, true);
}
}
[Fact]
public async Task UploadParsesGzipCompressedMultipartFilesLargerThanDefault16KiBLimit()
{
var previous = DBConfig.CDNStorage;
var directory = Path.Combine(Path.GetTempPath(), "studio-upload-large-" + Guid.NewGuid());
DBConfig.CDNStorage = directory;
try
{
const string boundary = "studio-upload-boundary";
var payload = Enumerable.Range(0, 32 * 1024).Select(i => (byte)(i % 251)).ToArray();
var multipart = System.Text.Encoding.ASCII.GetBytes(
new string('p', 20 * 1024) + "\r\n" +
$"--{boundary}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"asset.bin\"\r\nContent-Type: application/octet-stream\r\n\r\n")
.Concat(payload)
.Concat(System.Text.Encoding.ASCII.GetBytes($"\r\n--{boundary}--\r\n"))
.ToArray();
var body = new MemoryStream();
await using (var gzip = new System.IO.Compression.GZipStream(body, System.IO.Compression.CompressionLevel.Optimal, leaveOpen: true))
await gzip.WriteAsync(multipart);
body.Position = 0;
var context = new DefaultHttpContext();
context.Request.ContentType = $"multipart/form-data; boundary=\"{boundary}\"";
context.Request.Headers["Content-Encoding"] = "gzip";
context.Request.Body = body;
context.Request.ContentLength = body.Length;
var controller = new StorageAPI { ControllerContext = new ControllerContext { HttpContext = context } };
var response = Assert.IsType<OkObjectResult>(await controller.UploadUnityAssets());
var json = System.Text.Json.JsonSerializer.SerializeToElement(response.Value);
var filename = json[0].GetProperty("Filename").GetString()!;
Assert.Equal(payload, await File.ReadAllBytesAsync(Path.Combine(directory, filename)));
}
finally
{
DBConfig.CDNStorage = previous;
if (Directory.Exists(directory)) Directory.Delete(directory, true);
}
}
[Fact]
public async Task CompressedSingleFileUploadReturnsLegacyFilenameResponse()
{
var previous = DBConfig.CDNStorage;
var directory = Path.Combine(Path.GetTempPath(), "studio-upload-single-" + Guid.NewGuid());
DBConfig.CDNStorage = directory;
try
{
const string boundary = "legacy-upload-boundary";
var payload = Enumerable.Range(0, 4096).Select(i => (byte)(i % 253)).ToArray();
var multipart = System.Text.Encoding.ASCII.GetBytes(
"--" + boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"asset.bin\"\r\nContent-Type: application/octet-stream\r\n\r\n")
.Concat(payload)
.Concat(System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"))
.ToArray();
var body = new MemoryStream();
await using (var gzip = new System.IO.Compression.GZipStream(body, System.IO.Compression.CompressionLevel.Optimal, leaveOpen: true))
await gzip.WriteAsync(multipart);
body.Position = 0;
var context = new DefaultHttpContext();
context.Request.ContentType = $"multipart/form-data; boundary=\"{boundary}\"";
context.Request.Headers["Content-Encoding"] = "gzip";
context.Request.Body = body;
context.Request.ContentLength = body.Length;
var controller = new StorageAPI { ControllerContext = new ControllerContext { HttpContext = context } };
var response = await controller.Upload();
var value = Assert.IsType<UploadResponse>(response.Value);
Assert.Equal(40, value.filename.Length);
Assert.Equal(payload, await File.ReadAllBytesAsync(Path.Combine(directory, value.filename)));
}
finally
{
DBConfig.CDNStorage = previous;
if (Directory.Exists(directory)) Directory.Delete(directory, true);
}
}
[Fact]
public async Task RegistryAndGameMetadataExposeBothWindowsBundlesAndRawAssetDownload()
{
var previous = DBConfig.CDNStorage;
var directory = Path.Combine(Path.GetTempPath(), "studio-baked-" + Guid.NewGuid());
DBConfig.CDNStorage = directory;
Directory.CreateDirectory(directory);
try
{
const string manifestId = "0123456789abcdef0123456789abcdef01234567";
await File.WriteAllTextAsync(Path.Combine(directory, manifestId), "{\"Version\":2,\"MainSceneProjectRelativePath\":\"Assets/Room.unity\",\"Files\":[]}");
await using var sceneBundle = new MemoryStream(new byte[] { 1, 2, 3, 4 });
var sceneUpload = await StudioAssetStorage.Save(sceneBundle, CancellationToken.None);
await using var rejectedBundle = new MemoryStream(new byte[] { 5, 6, 7 });
var rejectedUpload = await StudioAssetStorage.Save(rejectedBundle, CancellationToken.None);
await StudioUnityAssetRegistry.AddBakedAssetAsync(manifestId,
new StudioBakedUnityAsset(manifestId, 0, 1, sceneUpload.Filename, rejectedUpload.Filename));
var api = new UnityAssetsCDN { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() } };
var response = Assert.IsType<ContentResult>(await api.GetUnityAsset(manifestId, 0, 1));
using var metadata = System.Text.Json.JsonDocument.Parse(response.Content!);
Assert.Equal(sceneUpload.Filename, metadata.RootElement.GetProperty("Filename").GetString());
Assert.Equal(rejectedUpload.Filename, metadata.RootElement.GetProperty("RejectedDependenciesFilename").GetString());
Assert.IsType<PhysicalFileResult>(new DataCDN().GetDataBlob(sceneUpload.Filename));
Assert.IsType<PhysicalFileResult>(new DataCDN().GetDataBlob(rejectedUpload.Filename));
var studio = new StudioAssetsCDN { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() } };
Assert.IsType<PhysicalFileResult>(studio.Download(sceneUpload.Filename));
}
finally
{
DBConfig.CDNStorage = previous;
if (Directory.Exists(directory)) Directory.Delete(directory, true);
}
}
[Theory]
[InlineData("../secret")]
[InlineData("..\\secret")]
[InlineData("C:secret")]
public void DownloadRejectsPaths(string filename) =>
Assert.IsType<BadRequestResult>(new StudioAssetsCDN().Download(filename));
}