154 lines
5.8 KiB
C#
154 lines
5.8 KiB
C#
namespace ALttPRandomizer.Service {
|
|
using ALttPRandomizer.Azure;
|
|
using ALttPRandomizer.Model;
|
|
using ALttPRandomizer.Randomizers;
|
|
using ALttPRandomizer.Settings;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
|
|
public class RandomizeService {
|
|
public RandomizeService(
|
|
IdGenerator idGenerator,
|
|
BaseRandomizer baseRandomizer,
|
|
MysteryRandomizer mysteryRandomizer,
|
|
AzureStorage azureStorage,
|
|
ILogger<RandomizeService> logger) {
|
|
this.IdGenerator = idGenerator;
|
|
this.BaseRandomizer = baseRandomizer;
|
|
this.MysteryRandomizer = mysteryRandomizer;
|
|
this.AzureStorage = azureStorage;
|
|
this.Logger = logger;
|
|
}
|
|
|
|
private ILogger<RandomizeService> Logger { get; }
|
|
|
|
private IdGenerator IdGenerator { get; }
|
|
private BaseRandomizer BaseRandomizer { get; }
|
|
private MysteryRandomizer MysteryRandomizer { get; }
|
|
private AzureStorage AzureStorage { get; }
|
|
|
|
public async Task<string> RandomizeSeed(SeedSettings settings, string? seedId = null) {
|
|
var id = seedId ?? this.IdGenerator.GenerateId();
|
|
this.Logger.LogInformation("Generating seed {seedId} with settings {@settings}", id, settings);
|
|
|
|
this.BaseRandomizer.Validate(settings);
|
|
|
|
await this.BaseRandomizer.Randomize(id, settings, seedId == null);
|
|
return id;
|
|
}
|
|
|
|
public async Task<string> RandomizeMystery(MysterySettings mysterySettings, SeedSettings baseSettings, string? seedId = null) {
|
|
var id = seedId ?? this.IdGenerator.GenerateId();
|
|
this.Logger.LogDebug("Rolling mystery seed {seedId} with mystery {@settings}", id, mysterySettings);
|
|
|
|
SeedSettings seedSettings;
|
|
|
|
for (var i = 0; i < 10; i++) {
|
|
seedSettings = baseSettings.Clone();
|
|
this.MysteryRandomizer.Roll(mysterySettings, seedSettings);
|
|
this.Logger.LogInformation("Mystery seed {seedId} rolled settings {@settings}", id, seedSettings);
|
|
|
|
try {
|
|
this.BaseRandomizer.Validate(seedSettings);
|
|
} catch (InvalidSettingsException) {
|
|
this.Logger.LogWarning("Mystery seed {seedId} settings {@settings} failed validation; retrying", id, seedSettings);
|
|
continue;
|
|
}
|
|
|
|
await this.BaseRandomizer.Randomize(id, seedSettings, true, seedId == null ? mysterySettings : null);
|
|
return id;
|
|
}
|
|
|
|
throw new InvalidSettingsException("Could not roll settings that pass validation");
|
|
}
|
|
|
|
public async Task<string> RandomizeMultiworld(IList<SeedSettings> settings, string? multiId = null) {
|
|
var id = multiId ?? this.IdGenerator.GenerateId();
|
|
this.Logger.LogInformation("Generating multiworld {seedId} with settings {@settings}", id, settings);
|
|
|
|
this.BaseRandomizer.ValidateAll(settings);
|
|
|
|
await this.BaseRandomizer.RandomizeMultiworld(id, settings, multiId == null);
|
|
return id;
|
|
}
|
|
|
|
public async Task<IDictionary<string, object>> RetrySeed(string seedId) {
|
|
var files = await this.AzureStorage.GetFiles(seedId);
|
|
|
|
this.Logger.LogDebug("Found files: {@files}", files.Keys);
|
|
|
|
var result = new Dictionary<string, object>();
|
|
|
|
if (!files.TryGetValue("settings.json", out var settingsData)) {
|
|
result["status"] = 404;
|
|
result["error"] = "seed not found";
|
|
return result;
|
|
}
|
|
|
|
var settingsJson = JsonDocument.Parse(settingsData.ToString());
|
|
|
|
var settings = settingsJson.Deserialize<SeedSettings>(JsonOptions.Default) ?? new SeedSettings();
|
|
|
|
if (files.TryGetValue("patch.bps", out var patchData)) {
|
|
result["status"] = 409;
|
|
result["error"] = "generation already successful";
|
|
return result;
|
|
}
|
|
|
|
if (files.ContainsKey("generating")) {
|
|
result["status"] = 409;
|
|
result["error"] = "generation still in progress";
|
|
return result;
|
|
}
|
|
|
|
await this.RandomizeSeed(settings, seedId);
|
|
|
|
result["status"] = 202;
|
|
return result;
|
|
}
|
|
|
|
public async Task<IDictionary<string, object>> RetryMulti(string multiId) {
|
|
var files = await this.AzureStorage.GetFiles(multiId);
|
|
|
|
this.Logger.LogDebug("Found files: {@files}", files.Keys);
|
|
|
|
var result = new Dictionary<string, object>();
|
|
|
|
if (!files.TryGetValue("settings.json", out var settingsData)) {
|
|
result["status"] = 404;
|
|
result["error"] = "multi settings not found";
|
|
return result;
|
|
}
|
|
|
|
var settingsJson = JsonDocument.Parse(settingsData.ToString());
|
|
|
|
var settings = settingsJson.Deserialize<IList<SeedSettings>>(JsonOptions.Default);
|
|
|
|
if (settings == null) {
|
|
result["status"] = 404;
|
|
result["error"] = "multi settings not found";
|
|
return result;
|
|
}
|
|
|
|
if (files.TryGetValue("patch.bps", out var patchData)) {
|
|
result["status"] = 409;
|
|
result["error"] = "generation already successful";
|
|
return result;
|
|
}
|
|
|
|
if (files.ContainsKey("generating")) {
|
|
result["status"] = 409;
|
|
result["error"] = "generation still in progress";
|
|
return result;
|
|
}
|
|
|
|
await this.RandomizeMultiworld(settings, multiId);
|
|
|
|
result["status"] = 202;
|
|
return result;
|
|
}
|
|
}
|
|
}
|