~ruther/NosSmooth

b73f81214e20e8d9cddccbb7a61539ccbe2bf608 — František Boháček 3 years ago 05c2624
fix(data): fix parsing file names and
M Data/NosSmooth.Data.NOSFiles/InfoService.cs => Data/NosSmooth.Data.NOSFiles/InfoService.cs +12 -12
@@ 27,46 27,46 @@ internal class InfoService : IInfoService
    }

    /// <inheritdoc />
    public Result<IItemInfo> GetItemInfo(int vnum)
    public Task<Result<IItemInfo>> GetItemInfoAsync(int vnum, CancellationToken ct = default)
    {
        if (!_nostaleData.Items.ContainsKey(vnum))
        {
            return new NotFoundError($"Couldn't find item {vnum}");
            return Task.FromResult(Result<IItemInfo>.FromError(new NotFoundError($"Couldn't find item {vnum}")));
        }

        return Result<IItemInfo>.FromSuccess(_nostaleData.Items[vnum]);
        return Task.FromResult(Result<IItemInfo>.FromSuccess(_nostaleData.Items[vnum]));
    }

    /// <inheritdoc />
    public Result<IMapInfo> GetMapInfo(int id)
    public Task<Result<IMapInfo>> GetMapInfoAsync(int id, CancellationToken ct = default)
    {
        if (!_nostaleData.Maps.ContainsKey(id))
        {
            return new NotFoundError($"Couldn't find item {id}");
            return Task.FromResult(Result<IMapInfo>.FromError(new NotFoundError($"Couldn't find map {id}")));
        }

        return Result<IMapInfo>.FromSuccess(_nostaleData.Maps[id]);
        return Task.FromResult(Result<IMapInfo>.FromSuccess(_nostaleData.Maps[id]));
    }

    /// <inheritdoc />
    public Result<IMonsterInfo> GetMonsterInfo(int vnum)
    public Task<Result<IMonsterInfo>> GetMonsterInfoAsync(int vnum, CancellationToken ct = default)
    {
        if (!_nostaleData.Monsters.ContainsKey(vnum))
        {
            return new NotFoundError($"Couldn't find item {vnum}");
            return Task.FromResult(Result<IMonsterInfo>.FromError(new NotFoundError($"Couldn't find monster {vnum}")));
        }

        return Result<IMonsterInfo>.FromSuccess(_nostaleData.Monsters[vnum]);
        return Task.FromResult(Result<IMonsterInfo>.FromSuccess(_nostaleData.Monsters[vnum]));
    }

    /// <inheritdoc />
    public Result<ISkillInfo> GetSkillInfo(int vnum)
    public Task<Result<ISkillInfo>> GetSkillInfoAsync(int vnum, CancellationToken ct = default)
    {
        if (!_nostaleData.Skills.ContainsKey(vnum))
        {
            return new NotFoundError($"Couldn't find item {vnum}");
            return Task.FromResult(Result<ISkillInfo>.FromError(new NotFoundError($"Couldn't find skill {vnum}")));
        }

        return Result<ISkillInfo>.FromSuccess(_nostaleData.Skills[vnum]);
        return Task.FromResult(Result<ISkillInfo>.FromSuccess(_nostaleData.Skills[vnum]));
    }
}
\ No newline at end of file

M Data/NosSmooth.Data.NOSFiles/LanguageService.cs => Data/NosSmooth.Data.NOSFiles/LanguageService.cs +32 -9
@@ 13,7 13,10 @@ namespace NosSmooth.Data.NOSFiles;
/// <inheritdoc />
internal class LanguageService : ILanguageService
{
    private readonly IReadOnlyDictionary<Language, IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>> _translations;
    private readonly
        IReadOnlyDictionary<Language, IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>>
        _translations;

    private readonly LanguageServiceOptions _options;

    /// <summary>


@@ 21,7 24,12 @@ internal class LanguageService : ILanguageService
    /// </summary>
    /// <param name="translations">The translations.</param>
    /// <param name="options">The options.</param>
    public LanguageService(IReadOnlyDictionary<Language, IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>> translations, LanguageServiceOptions options)
    public LanguageService
    (
        IReadOnlyDictionary<Language, IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>>
            translations,
        LanguageServiceOptions options
    )
    {
        CurrentLanguage = options.Language;
        _translations = translations;


@@ 32,32 40,47 @@ internal class LanguageService : ILanguageService
    public Language CurrentLanguage { get; set; }

    /// <inheritdoc/>
    public Result<string> GetTranslation(TranslationRoot root, string key, Language? language = default)
    public Task<Result<string>> GetTranslationAsync
    (
        TranslationRoot root,
        string key,
        Language? language = default,
        CancellationToken ct = default
    )
    {
        if (!_translations.ContainsKey(language ?? CurrentLanguage))
        {
            return new NotFoundError($"The requested language {language ?? CurrentLanguage} is not parsed.");
            return Task.FromResult
            (
                Result<string>.FromError
                    (new NotFoundError($"The requested language {language ?? CurrentLanguage} is not parsed."))
            );
        }

        var translations = _translations[language ?? CurrentLanguage];
        if (!translations.ContainsKey(root))
        {
            return key;
            return Task.FromResult(Result<string>.FromSuccess(key));
        }

        var keyTranslations = translations[root];
        if (!keyTranslations.ContainsKey(key))
        {
            return key;
            return Task.FromResult(Result<string>.FromSuccess(key));
        }

        return keyTranslations[key];
        return Task.FromResult(Result<string>.FromSuccess(keyTranslations[key]));
    }

    /// <inheritdoc/>
    public Result<string> GetTranslation(TranslatableString translatableString, Language? language = default)
    public async Task<Result<string>> GetTranslationAsync
    (
        TranslatableString translatableString,
        Language? language = default,
        CancellationToken ct = default
    )
    {
        var translation = GetTranslation(translatableString.Root, translatableString.Key, language);
        var translation = await GetTranslationAsync(translatableString.Root, translatableString.Key, language, ct);
        if (!translation.IsSuccess)
        {
            return translation;

M Data/NosSmooth.Data.NOSFiles/NostaleDataParser.cs => Data/NosSmooth.Data.NOSFiles/NostaleDataParser.cs +2 -2
@@ 68,9 68,9 @@ public class NostaleDataParser
        }

        var languageFiles = new Dictionary<Language, FileArchive>();
        foreach (var language in languages.Concat(_options.SupportedLanguages))
        foreach (var language in languages.Concat(_options.SupportedLanguages).Distinct())
        {
            var langString = language.ToString().ToLower();
            var langString = language.ToString().ToUpper();
            var langPath = languageFilesPath.Replace("%lang%", langString);
            var languageFile = _fileReader.ReadFileSystemFile<FileArchive>(langPath);


M Data/NosSmooth.Data.NOSFiles/Options/NostaleDataOptions.cs => Data/NosSmooth.Data.NOSFiles/Options/NostaleDataOptions.cs +1 -1
@@ 16,7 16,7 @@ public class NostaleDataOptions
    /// <summary>
    /// Gets or sets the supported languages that will be loaded into the memory..
    /// </summary>
    public Language[] SupportedLanguages { get; set; } = new Language[] { Language.En };
    public Language[] SupportedLanguages { get; set; } = new Language[] { Language.Uk };

    /// <summary>
    /// Gets or sets the path to .nos files.

M Data/NosSmooth.Data.NOSFiles/Parsers/Dat/DatReader.cs => Data/NosSmooth.Data.NOSFiles/Parsers/Dat/DatReader.cs +14 -6
@@ 27,7 27,7 @@ public class DatReader
    /// <param name="file">The file to read.</param>
    public DatReader(RawFile file)
    {
        _lines = Encoding.ASCII.GetString(file.Content).Split('\n').ToArray();
        _lines = Encoding.ASCII.GetString(file.Content).Split('\r', '\n').ToArray();
        _currentLine = 0;
        _file = file;
        _separator = "VNUM";


@@ 36,7 36,7 @@ public class DatReader
    /// <summary>
    /// Gets whether the reader has reached the end.
    /// </summary>
    public bool ReachedEnd => _currentLine + 1 >= _lines.Count;
    public bool ReachedEnd => _currentLine >= _lines.Count;

    /// <summary>
    /// Sets the separator of a new item.


@@ 54,30 54,38 @@ public class DatReader
    /// <returns>Whether an item was read.</returns>
    public bool ReadItem([NotNullWhen(true)] out DatItem? item)
    {
        return ReadItem(out item, _currentLine > 0);
    }

    private bool ReadItem([NotNullWhen(true)] out DatItem? item, bool readFirstItem)
    {
        if (ReachedEnd)
        {
            item = null;
            return false;
        }

        bool readFirstItem = _currentLine > 0;
        int startLine = _currentLine;
        if (readFirstItem && _lines[_currentLine].Trim().StartsWith(_separator))
        {
            _currentLine++;
        }

        while (!ReachedEnd && !_lines[_currentLine].StartsWith(_separator))
        while (!ReachedEnd && !_lines[_currentLine].Trim().StartsWith(_separator))
        {
            _currentLine++;
        }

        if (!readFirstItem)
        {
            return ReadItem(out item);
            return ReadItem(out item, true);
        }

        var dictionary = new Dictionary<string, IReadOnlyList<DatEntry>>();
        for (int i = startLine; i < _currentLine; i++)
        {
            var line = _lines[i];
            var splitted = line.Split('\t');
            var splitted = line.Trim().Split('\t');
            var key = splitted[0];
            var entry = new DatEntry(key, splitted);
            if (!dictionary.ContainsKey(key))

M Data/NosSmooth.Data.NOSFiles/Parsers/LangParser.cs => Data/NosSmooth.Data.NOSFiles/Parsers/LangParser.cs +5 -5
@@ 34,7 34,7 @@ public class LangParser
        var encoding = LanguageEncoding.GetEncoding(language);
        var dictionary = new Dictionary<TranslationRoot, IReadOnlyDictionary<string, string>>();

        var itemParsedResult = ParseFile(archive, encoding, $"code_{language.ToString().ToLower()}_Item.txt");
        var itemParsedResult = ParseFile(archive, encoding, $"_code_{language.ToString().ToLower()}_Item.txt");
        if (!itemParsedResult.IsSuccess)
        {
            return Result<IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>>.FromError


@@ 42,7 42,7 @@ public class LangParser
        }
        dictionary.Add(TranslationRoot.Item, itemParsedResult.Entity);

        var monsterParsedResult = ParseFile(archive, encoding, $"code_{language.ToString().ToLower()}_monster.txt");
        var monsterParsedResult = ParseFile(archive, encoding, $"_code_{language.ToString().ToLower()}_monster.txt");
        if (!monsterParsedResult.IsSuccess)
        {
            return Result<IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>>.FromError


@@ 50,7 50,7 @@ public class LangParser
        }
        dictionary.Add(TranslationRoot.Monster, itemParsedResult.Entity);

        var skillParsedResult = ParseFile(archive, encoding, $"code_{language.ToString().ToLower()}_Skill.txt");
        var skillParsedResult = ParseFile(archive, encoding, $"_code_{language.ToString().ToLower()}_Skill.txt");
        if (!skillParsedResult.IsSuccess)
        {
            return Result<IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>>.FromError


@@ 58,7 58,7 @@ public class LangParser
        }
        dictionary.Add(TranslationRoot.Skill, itemParsedResult.Entity);

        var mapParsedResult = ParseFile(archive, encoding, $"code_{language.ToString().ToLower()}_MapIDData.txt");
        var mapParsedResult = ParseFile(archive, encoding, $"_code_{language.ToString().ToLower()}_MapIDData.txt");
        if (!mapParsedResult.IsSuccess)
        {
            return Result<IReadOnlyDictionary<TranslationRoot, IReadOnlyDictionary<string, string>>>.FromError


@@ 79,7 79,7 @@ public class LangParser
        var fileContent = encoding.GetString(fileResult.Entity.Content);

        var dictionary = new Dictionary<string, string>();
        var lines = fileContent.Split('\n');
        var lines = fileContent.Split('\r', '\n');
        foreach (var line in lines)
        {
            var splitted = line.Split('\t');

M Data/NosSmooth.Data.NOSFiles/Parsers/MapParser.cs => Data/NosSmooth.Data.NOSFiles/Parsers/MapParser.cs +3 -3
@@ 24,12 24,12 @@ public class MapParser : IInfoParser<IMapInfo>
            return Result<Dictionary<int, IMapInfo>>.FromError(mapDatResult);
        }
        var mapGridsArchive = files.MapGridsFiles;
        var mapDatContent = Encoding.ASCII.GetString(mapDatResult.Entity.Content).Split('\n');
        var mapDatContent = Encoding.ASCII.GetString(mapDatResult.Entity.Content).Split('\r', '\n');

        var mapNames = new Dictionary<int, TranslatableString>();
        foreach (var line in mapDatContent)
        {
            var splitted = line.Split('\t');
            var splitted = line.Split(' ', '\t');
            if (splitted.Length != 5)
            {
                continue;


@@ 56,7 56,7 @@ public class MapParser : IInfoParser<IMapInfo>
            result[id] = new MapInfo
            (
                id,
                mapNames[id],
                mapNames.GetValueOrDefault(id, new TranslatableString(TranslationRoot.Map, "Map")),
                BitConverter.ToInt16(grid.Take(2).ToArray()),
                BitConverter.ToInt16(grid.Skip(2).Take(2).ToArray()),
                grid.Skip(4).ToArray()

M Data/NosSmooth.Data.NOSFiles/Parsers/MonsterParser.cs => Data/NosSmooth.Data.NOSFiles/Parsers/MonsterParser.cs +1 -1
@@ 18,7 18,7 @@ public class MonsterParser : IInfoParser<IMonsterInfo>
    /// <inheritdoc />
    public Result<Dictionary<int, IMonsterInfo>> Parse(NostaleFiles files)
    {
        var monsterDatResult = files.DatFiles.FindFile("Monster.dat");
        var monsterDatResult = files.DatFiles.FindFile("monster.dat");
        if (!monsterDatResult.IsSuccess)
        {
            return Result<Dictionary<int, IMonsterInfo>>.FromError(monsterDatResult);

Do not follow this link