diff --git a/Source/AtlusScriptLibrary/Common/Libraries/LibraryLookup.cs b/Source/AtlusScriptLibrary/Common/Libraries/LibraryLookup.cs index f903d2b..7a7afa8 100644 --- a/Source/AtlusScriptLibrary/Common/Libraries/LibraryLookup.cs +++ b/Source/AtlusScriptLibrary/Common/Libraries/LibraryLookup.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using System.Text.Json; @@ -58,10 +59,76 @@ public static Library GetLibrary(string name) return null; } + private static bool ValidateLibrary(Library library, out List errors) + { + errors = new List(); + + // Validate the library's own name and short name + if (string.IsNullOrWhiteSpace(library.Name)) + errors.Add("Library name cannot be null or empty."); + + if (string.IsNullOrWhiteSpace(library.ShortName)) + errors.Add("Library short name cannot be null or empty."); + + // Track unique FlowScriptModule names + var flowModuleNameSet = new HashSet(); + if (library.FlowScriptModules != null) + { + foreach (var module in library.FlowScriptModules) + { + if (!flowModuleNameSet.Add(module.Name)) + errors.Add($"Duplicate FlowScriptModule name found: {module.Name}"); + + // Validate enum members within each FlowScriptModule, if applicable + foreach (var item in module.Enums) + { + var enumMemberNameSet = new HashSet(); + foreach (var enumMember in item.Members) + { + if (!enumMemberNameSet.Add(enumMember.Name)) + errors.Add($"Duplicate enum member name '{enumMember.Name}' in FlowScriptModule '{module.Name}'."); + } + } + } + } + + // Track unique MessageScriptLibrary names and indices + var messageLibraryNameSet = new HashSet(); + var messageLibraryIndexSet = new HashSet(); + if (library.MessageScriptLibraries != null) + { + foreach (var msgLibrary in library.MessageScriptLibraries) + { + if (!string.IsNullOrWhiteSpace(msgLibrary.Name) && !messageLibraryNameSet.Add(msgLibrary.Name)) + errors.Add($"Duplicate MessageScriptLibrary name found: {msgLibrary.Name}"); + + if (!messageLibraryIndexSet.Add(msgLibrary.Index)) + errors.Add($"Duplicate MessageScriptLibrary index found: {msgLibrary.Index}"); + + // Validate functions within each MessageScriptLibrary + var functionNameSet = new HashSet(); + var functionIndexSet = new HashSet(); + foreach (var function in msgLibrary.Functions ?? Enumerable.Empty()) + { + if (!string.IsNullOrWhiteSpace(function.Name) && !functionNameSet.Add(function.Name)) + errors.Add($"Duplicate function name '{function.Name}' in MessageScriptLibrary '{msgLibrary.Name}'."); + + if (!functionIndexSet.Add(function.Index)) + errors.Add($"Duplicate function index '{function.Index}' in MessageScriptLibrary '{msgLibrary.Name}'."); + } + } + } + + return errors.Count == 0; + } + private static Library ParseLibrary(string path) { EnsureInitialized(); string jsonText = File.ReadAllText(path); - return JsonSerializer.Deserialize(jsonText); + var lib = JsonSerializer.Deserialize(jsonText); + if (!ValidateLibrary(lib, out var errors)) + throw new Exception($"Failed to load library {path}:\n{string.Join("\n", errors)}"); + return lib; } } diff --git a/Source/AtlusScriptLibrary/Common/Libraries/Serialization/ExternalJsonPathConverter.cs b/Source/AtlusScriptLibrary/Common/Libraries/Serialization/ExternalJsonPathConverter.cs index f8c3e43..9b5e38a 100644 --- a/Source/AtlusScriptLibrary/Common/Libraries/Serialization/ExternalJsonPathConverter.cs +++ b/Source/AtlusScriptLibrary/Common/Libraries/Serialization/ExternalJsonPathConverter.cs @@ -39,7 +39,7 @@ public override List Read(ref Utf8JsonReader reader, Type typeToConvert, Json { var path = reader.GetString(); if (string.IsNullOrEmpty(path)) - return null; + return new List(); var fullPath = Path.Combine(LibraryLookup.LibraryBaseDirectoryPath, path); var jsonString = File.ReadAllText(fullPath); diff --git a/Source/AtlusScriptLibrary/Libraries/EO2/Modules/Common/Functions.json b/Source/AtlusScriptLibrary/Libraries/EO2/Modules/Common/Functions.json index b5b425f..c058013 100644 --- a/Source/AtlusScriptLibrary/Libraries/EO2/Modules/Common/Functions.json +++ b/Source/AtlusScriptLibrary/Libraries/EO2/Modules/Common/Functions.json @@ -540,7 +540,7 @@ { "Index": "0x0041", "ReturnType": "int", - "Name": "AI_CHK_MYHP", + "Name": "AI_CHK_MYHP_2", "Description": "", "Parameters": [ {