// // NostaleDataParser.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Extensions.Options; using NosSmooth.Data.Abstractions; using NosSmooth.Data.Abstractions.Language; using NosSmooth.Data.NOSFiles.Files; using NosSmooth.Data.NOSFiles.Options; using NosSmooth.Data.NOSFiles.Parsers; using NosSmooth.Data.NOSFiles.Readers; using Remora.Results; namespace NosSmooth.Data.NOSFiles; /// /// Parser of NosTale .NOS files. /// public class NostaleDataParser { private readonly FileReader _fileReader; private readonly NostaleDataOptions _options; private readonly LanguageServiceOptions _languageOptions; private NostaleData? _parsed; /// /// Initializes a new instance of the class. /// /// The file reader. /// The options. /// The language options. public NostaleDataParser ( FileReader fileReader, IOptions options, IOptions languageOptions ) { _fileReader = fileReader; _options = options.Value; _languageOptions = languageOptions.Value; } /// /// Extract NosTale files from archives. /// /// The path to the nostale data files. /// The languages to include. /// The nostale files. public Result GetFiles(string? path = null, params Language[] languages) { string datFilesPath = Path.Combine(path ?? _options.NostaleDataPath, _options.InfosFileName); string mapGridsFilesPath = Path.Combine(path ?? _options.NostaleDataPath, _options.MapGridsFileName); string languageFilesPath = Path.Combine(path ?? _options.NostaleDataPath, _options.LanguageFileName); var datFile = _fileReader.ReadFileSystemFile(datFilesPath); if (!datFile.IsSuccess) { return Result.FromError(datFile); } var mapGridsFile = _fileReader.ReadFileSystemFile(mapGridsFilesPath); if (!mapGridsFile.IsSuccess) { return Result.FromError(mapGridsFile); } var languageFiles = new Dictionary(); foreach (var language in languages.Concat(_options.SupportedLanguages).Distinct()) { var langString = language.ToString().ToUpper(); var langPath = languageFilesPath.Replace("%lang%", langString); var languageFile = _fileReader.ReadFileSystemFile(langPath); if (!languageFile.IsSuccess) { return Result.FromError(languageFile); } languageFiles.Add(language, languageFile.Entity.Content); } return new NostaleFiles(languageFiles, datFile.Entity.Content, mapGridsFile.Entity.Content); } /// /// Parse the nostale files. /// /// The path to the files. /// The languages to parse. /// Parsed data or an error. public Result ParseFiles(string? path = null, params Language[] languages) { try { if (_parsed is not null) { return _parsed; } var filesResult = GetFiles(path, languages); if (!filesResult.IsSuccess) { return Result.FromError(filesResult); } var files = filesResult.Entity; var skillParser = new SkillParser(); var skillsResult = skillParser.Parse(files); if (!skillsResult.IsSuccess) { return Result.FromError(skillsResult); } var mapParser = new MapParser(); var mapsResult = mapParser.Parse(files); if (!mapsResult.IsSuccess) { return Result.FromError(mapsResult); } var itemParser = new ItemParser(); var itemsResult = itemParser.Parse(files); if (!itemsResult.IsSuccess) { return Result.FromError(itemsResult); } var monsterParser = new MonsterParser(); var monstersResult = monsterParser.Parse(files); if (!monstersResult.IsSuccess) { return Result.FromError(monstersResult); } var langParser = new LangParser(); var translations = new Dictionary>>(); foreach (var language in files.LanguageFiles.Keys) { var languageParseResult = langParser.Parse(files, language); if (!languageParseResult.IsSuccess) { return Result.FromError(languageParseResult); } translations.Add(language, languageParseResult.Entity); } return _parsed = new NostaleData ( translations, itemsResult.Entity, monstersResult.Entity, skillsResult.Entity, mapsResult.Entity ); } catch (Exception e) { return e; } } /// /// Create a language service from parsed files. /// /// A language service or an error. public Result CreateLanguageService() { var parsed = ParseFiles(); if (!parsed.IsSuccess) { return Result.FromError(parsed); } return new LanguageService(parsed.Entity.Translations, _languageOptions); } /// /// Create an info service from parsed files. /// /// An info service or an error. public Result CreateInfoService() { var parsed = ParseFiles(); if (!parsed.IsSuccess) { return Result.FromError(parsed); } return new InfoService(parsed.Entity); } }