diff --git a/SchemaValidator/SchemaValidator.cs b/SchemaValidator/SchemaValidator.cs index cf6d4d2..1499b6f 100644 --- a/SchemaValidator/SchemaValidator.cs +++ b/SchemaValidator/SchemaValidator.cs @@ -43,9 +43,11 @@ public class SchemaValidator new MultiLinkRefValidator(gameData, testDict), new ConditionValidator(gameData), new ConditionRefValidator(gameData, testDict), + new DuplicateFieldNameValidator(gameData), }; - // var exl = gameData.GetFile("exd/root.exl"); + var exl = gameData.GetFile("exd/root.exl"); + var existingSheets = exl.ExdMap.Select(s => s.Key).ToHashSet(); var results = new ValidationResults(); foreach (var schemaPath in Directory.GetFiles(schemaDir, "*.yml")) @@ -54,8 +56,7 @@ public class SchemaValidator var exh = gameData.GetFile($"exd/{sheetName}.exh"); if (exh == null) { - Console.Error.WriteLine($"Sheet {sheetName} does not exist!"); - continue; + results.Add(ValidationResult.Error(sheetName, "SheetExistsValidator", "Schema exists but sheet does not!")); } Sheet sheet; @@ -81,7 +82,16 @@ public class SchemaValidator foreach (var validator in validators) results.Add(validator.Validate(exh, sheet)); + existingSheets.Remove(sheetName); } + + foreach (var sheet in existingSheets) + { + if (sheet.Contains('/')) continue; + results.Add(ValidationResult.Error(sheet, "SchemaDefinedValidator", "Sheet exists but has no schema!")); + } + + // --- foreach (var result in results.Results.Where(r => r.Status == ValidationStatus.Warning)) { diff --git a/SchemaValidator/Util/SchemaUtil.cs b/SchemaValidator/Util/SchemaUtil.cs index 9c97773..c68bd8a 100644 --- a/SchemaValidator/Util/SchemaUtil.cs +++ b/SchemaValidator/Util/SchemaUtil.cs @@ -103,18 +103,4 @@ public static class SchemaUtil } return 1; } - - public static Field GetFieldByIndex(Sheet schema, int index) - { - foreach (var field in schema.Fields) - { - - } - return null; - } - - public static Field GetFieldByIndex(Field field, int index, int baseIndex) - { - return null; - } } \ No newline at end of file diff --git a/SchemaValidator/Util/SerializeUtil.cs b/SchemaValidator/Util/SerializeUtil.cs index f06fbc4..b0d45fa 100644 --- a/SchemaValidator/Util/SerializeUtil.cs +++ b/SchemaValidator/Util/SerializeUtil.cs @@ -23,8 +23,6 @@ public static class SerializeUtil NamingConvention = new CamelCaseNamingConvention(), IgnoreNulls = true, }; - settings.RegisterSerializer(typeof(Dictionary>), new CustomDictionarySerializer()); - settings.RegisterSerializer(typeof(FieldType), new CustomFieldTypeSerializer()); _serializer = new Serializer(settings); } @@ -43,51 +41,4 @@ public static class SerializeUtil { return _serializer.Deserialize(s); } - - public static EvaluationResults? EvaluateSchema(string filePath) - { - var yamlText = File.ReadAllText(filePath); - object? yamlObject; - try - { - yamlObject = _serializer.Deserialize(yamlText); - } - catch (Exception e) - { - Console.WriteLine(e); - return null; - } - if (yamlObject == null) return null; - - var json = JsonConvert.SerializeObject(yamlObject); - // Console.WriteLine(json); - // File.WriteAllText(@"C:\Users\Liam\Documents\repos\EXDSchema\SchemaValidator\test.json", json); - - var schemaText = File.ReadAllText(@"C:\Users\Liam\Documents\repos\EXDSchema\SchemaValidator\SchemaSchema.json"); - var schema = JsonSchema.FromText(schemaText); - var node = JsonNode.Parse(json); - return schema.Evaluate(node); - } } - -internal class CustomDictionarySerializer : DictionarySerializer -{ - protected override void WriteDictionaryItem(ref ObjectContext objectContext, KeyValuePair keyValue, KeyValuePair types) - { - objectContext.SerializerContext.WriteYaml(keyValue.Key, types.Key); - objectContext.SerializerContext.WriteYaml(keyValue.Value, types.Value, YamlStyle.Flow); - } -} - -internal class CustomFieldTypeSerializer : ScalarSerializerBase -{ - public override object? ConvertFrom(ref ObjectContext context, Scalar fromScalar) - { - return Enum.Parse(new PascalNamingConvention().Convert(fromScalar.Value)); - } - - public override string ConvertTo(ref ObjectContext objectContext) - { - return objectContext.Settings.NamingConvention.Convert(objectContext.Instance.ToString()); - } -} \ No newline at end of file diff --git a/SchemaValidator/Validation/Validators/DuplicateFieldNameValidator.cs b/SchemaValidator/Validation/Validators/DuplicateFieldNameValidator.cs new file mode 100644 index 0000000..a1f663e --- /dev/null +++ b/SchemaValidator/Validation/Validators/DuplicateFieldNameValidator.cs @@ -0,0 +1,53 @@ +using Lumina; +using Lumina.Data.Files.Excel; +using SchemaValidator.New; +using SchemaValidator.Util; + +namespace SchemaValidator.Validation.Validators; + +public class DuplicateFieldNameValidator : Validator +{ + public override string ValidatorName() => "DuplicateFieldNameValidator"; + + public DuplicateFieldNameValidator(GameData gameData) : base(gameData) { } + + private string _sheetName; + + public override ValidationResults Validate(ExcelHeaderFile exh, Sheet sheet) + { + _sheetName = sheet.Name; + + var fieldNames = new HashSet(); + var results = new ValidationResults(); + foreach (var field in sheet.Fields) + { + results.Add(Validate(field)); + if (fieldNames.Contains(field.Name)) + return ValidationResults.Error(sheet.Name, ValidatorName(), $"Duplicate field name {field.Name}"); + fieldNames.Add(field.Name); + } + + if (results.Results.Count == 0) + return ValidationResults.Success(sheet.Name, ValidatorName()); + return results; + } + + private ValidationResults Validate(Field field) + { + var results = new ValidationResults(); + var fieldNames = new HashSet(); + + if (field.Fields != null) + { + foreach (var subField in field.Fields) + { + Validate(subField); + if (fieldNames.Contains(subField.Name)) + results.Add(ValidationResult.Error(_sheetName, ValidatorName(), $"Duplicate field name {subField.Name}")); + fieldNames.Add(subField.Name); + } + } + + return results; + } +} \ No newline at end of file