namespace ALttPRandomizer { using ALttPRandomizer.Serialization; using ALttPRandomizer.Model; using ALttPRandomizer.Randomizers; using ALttPRandomizer.Service; using ALttPRandomizer.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Collections.Generic; using System.Threading.Tasks; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; public class SeedController : Controller { public SeedController( RandomizeService randomizeService, MysteryRandomizer mysteryRandomizer, SeedService seedService, ILogger logger) { this.RandomizeService = randomizeService; this.MysteryRandomizer = mysteryRandomizer; this.SeedService = seedService; this.Logger = logger; this.YamlSerializer = new SerializerBuilder() .WithNamingConvention(UnderscoredNamingConvention.Instance) .WithTypeConverter(new YamlStringEnumConverter()) .WithTypeConverter(new RandomizableWeightsYamlConverters()) .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull | DefaultValuesHandling.OmitEmptyCollections) .Build(); } private RandomizeService RandomizeService { get; } private MysteryRandomizer MysteryRandomizer { get; } private SeedService SeedService { get; } private ILogger Logger { get; } private ISerializer YamlSerializer { get; } [Route("/generate")] [HttpPost] public async Task Generate([FromBody] SeedSettings settings) { if (!ModelState.IsValid) { return BadRequest(ModelState); } try { var id = await this.RandomizeService.RandomizeSeed(settings); var url = string.Format("/seed/{0}", id); return Accepted(url, id); } catch (InvalidSettingsException ex) { return BadRequest(ex.Message); } } [Route("/mystery/{randomizer}")] [HttpPost] public ActionResult RollMystery([FromBody] MysterySettings mysterySettings, RandomizerInstance randomizer) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var seedSettings = new SeedSettings() { Randomizer = randomizer }; this.MysteryRandomizer.Roll(mysterySettings, seedSettings); return StatusCode(200, this.YamlSerializer.Serialize(mysterySettings)); } [Route("/multiworld")] [HttpPost] public async Task GenerateMultiworld([FromBody] IList settings) { if (!ModelState.IsValid) { return BadRequest(ModelState); } try { var id = await this.RandomizeService.RandomizeMultiworld(settings); var url = string.Format("/multi/{0}", id); return Accepted(url, id); } catch (InvalidSettingsException ex) { return BadRequest(ex.Message); } } [Route("/seed/{id}")] [HttpGet] public async Task GetSeed(string id) { return ResolveResult(await this.SeedService.GetSeed(id)); } [Route("/seed/{id}")] [HttpPost] public async Task RetrySeed(string id) { return ResolveResult(await this.RandomizeService.RetrySeed(id)); } [Route("/multi/{id}")] [HttpGet] public async Task GetMulti(string id) { return ResolveResult(await this.SeedService.GetMulti(id)); } [Route("/multi/{id}")] [HttpPost] public async Task RetryMulti(string id) { return ResolveResult(await this.RandomizeService.RetryMulti(id)); } [Route("/multidata/{id}")] [HttpGet] public async Task GetMultidata(string id) { var multidata = await this.SeedService.GetMultidata(id); if (multidata == null) { return NotFound("multidata not found"); } else { return new FileContentResult(multidata.ToArray(), "application/octet-stream") { FileDownloadName = $"{id}_multidata", }; } } private ObjectResult ResolveResult(IDictionary result) { if (result.TryGetValue("status", out var responseCode)) { if (responseCode is int code) { return StatusCode(code, result); } } this.Logger.LogWarning("Unexpected result from SeedService: {@result}", result); return StatusCode(500, result); } } }