Add Apr2025 Randomizer
This commit is contained in:
@@ -1,21 +1,83 @@
|
||||
namespace ALttPRandomizer.Settings {
|
||||
using ALttPRandomizer.Model;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
internal class SettingNameAttribute : Attribute {
|
||||
public SettingNameAttribute(string name) {
|
||||
internal class RandomizerNameAttribute : Attribute {
|
||||
public RandomizerNameAttribute(string name) {
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
}
|
||||
|
||||
internal class NoSettingNameAttribute : Attribute { }
|
||||
internal abstract class RandomizerSpecificAttribute : Attribute {
|
||||
public RandomizerSpecificAttribute(RandomizerInstance[]? randomizers) {
|
||||
this.Randomizers = randomizers;
|
||||
}
|
||||
|
||||
internal class AdditionalSettingAttribute : Attribute {
|
||||
public AdditionalSettingAttribute(string setting) {
|
||||
protected RandomizerInstance[]? Randomizers { get; }
|
||||
|
||||
public bool HasRandomizer(RandomizerInstance name) {
|
||||
if (this.Randomizers == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.Randomizers.Contains(name);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SettingNameAttribute : RandomizerSpecificAttribute {
|
||||
public SettingNameAttribute(string name) : base(null) {
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
public SettingNameAttribute(RandomizerInstance[] randomizers, string name) : base(randomizers) {
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
}
|
||||
|
||||
internal class NoSettingNameAttribute : RandomizerSpecificAttribute {
|
||||
public NoSettingNameAttribute() : base(null) { }
|
||||
|
||||
public NoSettingNameAttribute(RandomizerInstance[] randomizers) : base(randomizers) { }
|
||||
}
|
||||
|
||||
internal class AdditionalSettingAttribute : RandomizerSpecificAttribute {
|
||||
public AdditionalSettingAttribute(string setting) : base(null) {
|
||||
this.Setting = setting;
|
||||
}
|
||||
|
||||
public AdditionalSettingAttribute(RandomizerInstance[] randomizers, string setting) : base(randomizers) {
|
||||
this.Setting = setting;
|
||||
}
|
||||
|
||||
public string Setting { get; }
|
||||
}
|
||||
|
||||
internal class RequiredSettingAttribute : RandomizerSpecificAttribute {
|
||||
public RequiredSettingAttribute(params object[] values) : base(null) {
|
||||
this.Values = values;
|
||||
}
|
||||
|
||||
public RequiredSettingAttribute(RandomizerInstance[] randomizers, params object[] values) : base(randomizers) {
|
||||
this.Values = values;
|
||||
}
|
||||
|
||||
public object[] Values { get; }
|
||||
}
|
||||
|
||||
internal class ForbiddenSettingAttribute : RandomizerSpecificAttribute {
|
||||
public ForbiddenSettingAttribute(params object[] values) : base(null) {
|
||||
this.Values = values;
|
||||
}
|
||||
|
||||
public ForbiddenSettingAttribute(RandomizerInstance[] randomizers, params object[] values) : base(randomizers) {
|
||||
this.Values = values;
|
||||
}
|
||||
|
||||
public object[] Values { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,61 @@
|
||||
using System;
|
||||
|
||||
namespace ALttPRandomizer.Settings {
|
||||
namespace ALttPRandomizer.Settings {
|
||||
using ALttPRandomizer.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
public class CommonSettingsProcessor {
|
||||
public IList<string> GetSettings(SeedSettings settings) {
|
||||
var args = new List<string>();
|
||||
|
||||
public IEnumerable<string> GetSettings(RandomizerInstance randomizer, SeedSettings settings) {
|
||||
var props = typeof(SeedSettings).GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
foreach (var prop in props) {
|
||||
var value = prop.GetValue(settings) ?? throw new SettingsLookupException("settings.{} not found", prop.Name);
|
||||
var valueFieldName = value.ToString() ?? throw new SettingsLookupException("settings.{}.ToString() returned null", prop.Name);
|
||||
var value = prop.GetValue(settings) ?? throw new SettingsLookupException("settings.{0} not found", prop.Name);
|
||||
var valueFieldName = value.ToString() ?? throw new SettingsLookupException("settings.{0}.ToString() returned null", prop.Name);
|
||||
var fi = prop.PropertyType.GetField(valueFieldName, BindingFlags.Static | BindingFlags.Public)
|
||||
?? throw new SettingsLookupException("Could not get field info for value {}.{}", prop.PropertyType, valueFieldName);
|
||||
?? throw new SettingsLookupException("Could not get field info for value {0}.{1}", prop.PropertyType, valueFieldName);
|
||||
|
||||
if (prop.GetCustomAttribute<NoSettingNameAttribute>() == null) {
|
||||
var settingName = prop.GetCustomAttribute<SettingNameAttribute>()?.Name ?? prop.Name.ToLower();
|
||||
var valueName = fi.GetCustomAttribute<SettingNameAttribute>()?.Name ?? valueFieldName.ToLower();
|
||||
if (!prop.GetCustomAttributes<NoSettingNameAttribute>().Any(att => att.HasRandomizer(randomizer))) {
|
||||
var settingName =
|
||||
prop.GetCustomAttributes<SettingNameAttribute>()
|
||||
.FirstOrDefault(att => att.HasRandomizer(randomizer))?.Name ?? prop.Name.ToLower();
|
||||
var valueName =
|
||||
fi.GetCustomAttributes<SettingNameAttribute>()
|
||||
.FirstOrDefault(att => att.HasRandomizer(randomizer))?.Name ?? valueFieldName.ToLower();
|
||||
|
||||
args.Add(string.Format("--{0}={1}", settingName, valueName));
|
||||
yield return string.Format("--{0}={1}", settingName, valueName);
|
||||
}
|
||||
|
||||
foreach (var att in fi.GetCustomAttributes<AdditionalSettingAttribute>()) {
|
||||
args.Add(att.Setting);
|
||||
foreach (var att in fi.GetCustomAttributes<AdditionalSettingAttribute>().Where(att => att.HasRandomizer(randomizer))) {
|
||||
yield return att.Setting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
public void ValidateSettings(RandomizerInstance randomizer, SeedSettings settings) {
|
||||
var props = typeof(SeedSettings).GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
foreach (var prop in props) {
|
||||
var value = prop.GetValue(settings) ?? throw new SettingsLookupException("settings.{0} not found", prop.Name);
|
||||
|
||||
foreach (var att in prop.GetCustomAttributes<RequiredSettingAttribute>().Where(att => att.HasRandomizer(randomizer))) {
|
||||
if (!att.Values.Contains(value)) {
|
||||
throw new InvalidSettingsException("{0} contains value {1} not in required set [{2}]", prop.Name, value, string.Join(", ", att.Values));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var att in prop.GetCustomAttributes<ForbiddenSettingAttribute>().Where(att => att.HasRandomizer(randomizer))) {
|
||||
if (att.Values.Contains(value)) {
|
||||
throw new InvalidSettingsException("{0} contains forbidden value {1}", prop.Name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SettingsLookupException : Exception {
|
||||
public SettingsLookupException(string message, params object?[] args) : base(string.Format(message, args)) { }
|
||||
}
|
||||
|
||||
public class InvalidSettingsException : Exception {
|
||||
public InvalidSettingsException(string message, params object?[] args) : base(string.Format(message, args)) { }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user