using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Security.Cryptography; using RadicadeServer.DB; using IOFile = System.IO.File; namespace RadicadeServer.Custom.API { [Route("custom/")] public class CCAPI(RecDBContext _db) : Controller { private static string GetHashAndCache(string hashName, string fileName) { if (!IOFile.Exists(hashName)) { string hash = CalculateMD5(fileName); IOFile.WriteAllText(hashName, hash); return hash; } return IOFile.ReadAllText(hashName); } private static string CalculateMD5(string filename) { using (var md5 = MD5.Create()) { using (var stream = IOFile.OpenRead(filename)) { var hash = md5.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } } } [HttpGet("all")] public async Task> GetAllContent() { return await _db.CustomContent.ToListAsync(); } [HttpGet("download/{modId}/{fileId}")] public async Task DownloadContent(long? modId, int? fileId) { if (modId == null || fileId == null) return BadRequest(); var mod = await _db.CustomContent.FirstOrDefaultAsync(x => x.Id == modId); if (mod == null) return NotFound(); var files = mod.Files.Split(";", StringSplitOptions.TrimEntries); if (fileId >= files.Length || fileId < 0) return BadRequest(); string path = Path.Join(DBConfig.CDNCustom, mod.Name, files[(int)fileId]); if (!System.IO.File.Exists(path)) return NotFound(); return PhysicalFile(path, "application/octet-stream", enableRangeProcessing: true); } [HttpGet("hash/{modId}/{file}")] public async Task GetHashForMod(string modId, string file) { if (modId == null || file == null) return BadRequest(); file = file.ToLower().Trim(); var mod = await _db.CustomContent.FirstOrDefaultAsync(x => x.Name == modId); if (mod == null) return NotFound(); var files = mod.Files.Split(";", StringSplitOptions.TrimEntries); var expectedFile = files.FirstOrDefault(x => x.ToLower().Trim().Contains(file)); string path = Path.Join(DBConfig.CDNCustom, mod.Name, file); string hashPath = Path.Join(DBConfig.CDNCustom, mod.Name, file + "-hash"); if (!IOFile.Exists(path)) return NotFound(); string hash = GetHashAndCache(hashPath, path); return Ok(hash); } } }