~ruther/NosSmooth

344dc6da529c05ae0e25c753b99ae0dbd7d9cb1b — František Boháček 3 years ago 9f8812c
feat(samples): add data browser cli sample
M NosSmooth.sln => NosSmooth.sln +17 -0
@@ 38,6 38,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosSmooth.Data.NOSFiles", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosSmooth.Data.CLI", "Data\NosSmooth.Data.CLI\NosSmooth.Data.CLI.csproj", "{F1884ADF-6412-4E9B-81FD-357DC5761ADF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{99E72557-BCE9-496A-B49C-79537B0E6063}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataBrowser", "Samples\DataBrowser\DataBrowser.csproj", "{055C66A7-640C-49BB-81A7-28E630F51C37}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU


@@ 180,6 184,18 @@ Global
		{F1884ADF-6412-4E9B-81FD-357DC5761ADF}.Release|x64.Build.0 = Release|Any CPU
		{F1884ADF-6412-4E9B-81FD-357DC5761ADF}.Release|x86.ActiveCfg = Release|Any CPU
		{F1884ADF-6412-4E9B-81FD-357DC5761ADF}.Release|x86.Build.0 = Release|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Debug|x64.ActiveCfg = Debug|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Debug|x64.Build.0 = Debug|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Debug|x86.ActiveCfg = Debug|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Debug|x86.Build.0 = Debug|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Release|Any CPU.Build.0 = Release|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Release|x64.ActiveCfg = Release|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Release|x64.Build.0 = Release|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Release|x86.ActiveCfg = Release|Any CPU
		{055C66A7-640C-49BB-81A7-28E630F51C37}.Release|x86.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE


@@ 196,6 212,7 @@ Global
		{C4114AC1-72E8-46DA-9B4B-A4C942004492} = {1C785A74-19B9-42D2-93B1-F4EC9D6A8CFD}
		{4820B9B7-00E6-4E0C-B93A-83BB98C1EE99} = {1C785A74-19B9-42D2-93B1-F4EC9D6A8CFD}
		{F1884ADF-6412-4E9B-81FD-357DC5761ADF} = {1C785A74-19B9-42D2-93B1-F4EC9D6A8CFD}
		{055C66A7-640C-49BB-81A7-28E630F51C37} = {99E72557-BCE9-496A-B49C-79537B0E6063}
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {C5F46653-4DEC-429B-8580-4ED18ED9B4CA}

A Samples/DataBrowser/Commands/ItemInfoCommand.cs => Samples/DataBrowser/Commands/ItemInfoCommand.cs +65 -0
@@ 0,0 1,65 @@
//
//  ItemInfoCommand.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.Logging;
using NosSmooth.Data.Abstractions;
using NosSmooth.Data.Abstractions.Language;
using Remora.Commands.Attributes;
using Remora.Commands.Groups;
using Remora.Results;

namespace DataBrowser.Commands;

/// <summary>
/// Command for getting information about an item.
/// </summary>
public class ItemInfoCommand : CommandGroup
{
    private readonly IInfoService _infoService;
    private readonly ILanguageService _languageService;

    /// <summary>
    /// Initializes a new instance of the <see cref="ItemInfoCommand"/> class.
    /// </summary>
    /// <param name="infoService">The info service.</param>
    /// <param name="languageService">The language service.</param>
    public ItemInfoCommand(IInfoService infoService, ILanguageService languageService)
    {
        _infoService = infoService;
        _languageService = languageService;
    }

    /// <summary>
    /// Gets the info about the specified item.
    /// </summary>
    /// <param name="vnum">The vnum of the item.</param>
    /// <param name="language">The language.</param>
    /// <returns>A result that may or may not succeeded.</returns>
    [Command("item")]
    public async Task<Result> HandleItemInfo(int vnum, Language language = Language.Uk)
    {
        var itemResult = await _infoService.GetItemInfoAsync(vnum, CancellationToken);
        if (!itemResult.IsSuccess)
        {
            return Result.FromError(itemResult);
        }

        var translationResult = await _languageService.GetTranslationAsync
            (itemResult.Entity.Name, language, CancellationToken);
        if (!translationResult.IsSuccess)
        {
            return Result.FromError(translationResult);
        }

        Console.WriteLine("Found item {0}", translationResult.Entity);
        Console.WriteLine("  Type: {0}", itemResult.Entity.Type);
        Console.WriteLine("  SubType: {0}", itemResult.Entity.SubType);
        Console.WriteLine("  BagType: {0}", itemResult.Entity.BagType);
        Console.WriteLine("  Data: {0}", string.Join('|', itemResult.Entity.Data));

        return Result.FromSuccess();
    }
}
\ No newline at end of file

A Samples/DataBrowser/Commands/MonsterInfoCommand.cs => Samples/DataBrowser/Commands/MonsterInfoCommand.cs +62 -0
@@ 0,0 1,62 @@
//
//  MonsterInfoCommand.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.Logging;
using NosSmooth.Data.Abstractions;
using NosSmooth.Data.Abstractions.Language;
using Remora.Commands.Attributes;
using Remora.Commands.Groups;
using Remora.Results;

namespace DataBrowser.Commands;

/// <summary>
/// Command for getting information about a monster.
/// </summary>
public class MonsterInfoCommand : CommandGroup
{
    private readonly IInfoService _infoService;
    private readonly ILanguageService _languageService;

    /// <summary>
    /// Initializes a new instance of the <see cref="MonsterInfoCommand"/> class.
    /// </summary>
    /// <param name="infoService">The info service.</param>
    /// <param name="languageService">The language service.</param>
    public MonsterInfoCommand(IInfoService infoService, ILanguageService languageService)
    {
        _infoService = infoService;
        _languageService = languageService;
    }

    /// <summary>
    /// Gets the info about the specified monster.
    /// </summary>
    /// <param name="vnum">The vnum of the Monster.</param>
    /// <param name="language">The language.</param>
    /// <returns>A result that may or may not succeeded.</returns>
    [Command("monster")]
    public async Task<Result> HandleMonsterInfo(int vnum, Language language = Language.Uk)
    {
        var monsterResult = await _infoService.GetMonsterInfoAsync(vnum, CancellationToken);
        if (!monsterResult.IsSuccess)
        {
            return Result.FromError(monsterResult);
        }

        var translationResult = await _languageService.GetTranslationAsync
            (monsterResult.Entity.Name, language, CancellationToken);
        if (!translationResult.IsSuccess)
        {
            return Result.FromError(translationResult);
        }

        Console.WriteLine("Found Monster {0}", translationResult.Entity);
        Console.WriteLine("  Level: {0}", monsterResult.Entity.Level);

        return Result.FromSuccess();
    }
}
\ No newline at end of file

A Samples/DataBrowser/Commands/SkillInfoCommand.cs => Samples/DataBrowser/Commands/SkillInfoCommand.cs +69 -0
@@ 0,0 1,69 @@
//
//  SkillInfoCommand.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.Logging;
using NosSmooth.Data.Abstractions;
using NosSmooth.Data.Abstractions.Language;
using Remora.Commands.Attributes;
using Remora.Commands.Groups;
using Remora.Results;

namespace DataBrowser.Commands;

/// <summary>
/// Command for getting information about a Skill.
/// </summary>
public class SkillInfoCommand : CommandGroup
{
    private readonly IInfoService _infoService;
    private readonly ILanguageService _languageService;

    /// <summary>
    /// Initializes a new instance of the <see cref="SkillInfoCommand"/> class.
    /// </summary>
    /// <param name="infoService">The info service.</param>
    /// <param name="languageService">The language service.</param>
    public SkillInfoCommand(IInfoService infoService, ILanguageService languageService)
    {
        _infoService = infoService;
        _languageService = languageService;
    }

    /// <summary>
    /// Gets the info about the specified skill.
    /// </summary>
    /// <param name="vnum">The vnum of the Skill.</param>
    /// <param name="language">The language.</param>
    /// <returns>A result that may or may not succeeded.</returns>
    [Command("skill")]
    public async Task<Result> HandleSkillInfo(int vnum, Language language = Language.Uk)
    {
        var skillResult = await _infoService.GetSkillInfoAsync(vnum, CancellationToken);
        if (!skillResult.IsSuccess)
        {
            return Result.FromError(skillResult);
        }

        var translationResult = await _languageService.GetTranslationAsync
            (skillResult.Entity.Name, language, CancellationToken);
        if (!translationResult.IsSuccess)
        {
            return Result.FromError(translationResult);
        }

        Console.WriteLine("Found Skill {0}", translationResult.Entity);
        Console.WriteLine("  CastId: {0}", skillResult.Entity.CastId);
        Console.WriteLine("  MpCost: {0}", skillResult.Entity.MpCost);
        Console.WriteLine("  Cooldown: {0}", skillResult.Entity.Cooldown);
        Console.WriteLine("  Range: {0}", skillResult.Entity.Range);
        Console.WriteLine("  ZoneRange: {0}", skillResult.Entity.ZoneRange);
        Console.WriteLine("  HitType: {0}", skillResult.Entity.HitType);
        Console.WriteLine("  SkillType: {0}", skillResult.Entity.SkillType);
        Console.WriteLine("  TargetType: {0}", skillResult.Entity.TargetType);

        return Result.FromSuccess();
    }
}
\ No newline at end of file

A Samples/DataBrowser/DataBrowser.csproj => Samples/DataBrowser/DataBrowser.csproj +22 -0
@@ 0,0 1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <IsPackable>false</IsPackable>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
      <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
      <PackageReference Include="Remora.Commands" Version="9.0.0" />
    </ItemGroup>

    <ItemGroup>
      <ProjectReference Include="..\..\Core\NosSmooth.Core\NosSmooth.Core.csproj" />
      <ProjectReference Include="..\..\Data\NosSmooth.Data.NOSFiles\NosSmooth.Data.NOSFiles.csproj" />
    </ItemGroup>

</Project>

A Samples/DataBrowser/Program.cs => Samples/DataBrowser/Program.cs +102 -0
@@ 0,0 1,102 @@
//
//  Program.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 DataBrowser.Commands;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NosSmooth.Core.Extensions;
using NosSmooth.Data.Abstractions.Language;
using NosSmooth.Data.NOSFiles;
using NosSmooth.Data.NOSFiles.Extensions;
using NosSmooth.Data.NOSFiles.Options;
using Remora.Commands.Extensions;
using Remora.Commands.Services;

namespace DataBrowser;

/// <summary>
/// Entrypoint class.
/// </summary>
public class Program
{
    /// <summary>
    /// Entrypoint method.
    /// </summary>
    /// <param name="arguments">The arguments.</param>
    /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
    public static async Task Main(string[] arguments)
    {
        var services = CreateServices();

        // Initialize the file manager that will parse the files and register the
        // ILanguageService and IInfoService into the provider.
        var fileManager = services.GetRequiredService<NostaleDataFilesManager>();
        var initializationResult = fileManager.Initialize();
        if (!initializationResult.IsSuccess)
        {
            Console.Error.WriteLine($"There was an error, {initializationResult.ToFullString()}");
            return;
        }

        // Handle the command
        var commandService = services.GetRequiredService<CommandService>();
        var preparedCommandResult = await commandService.TryPrepareCommandAsync(string.Join(' ', arguments), services);
        if (!preparedCommandResult.IsSuccess)
        {
            Console.Error.WriteLine($"There was an error, {preparedCommandResult.ToFullString()}");
            return;
        }

        if (preparedCommandResult.Entity is null)
        {
            Console.Error.WriteLine("You must enter a command such ast list or inject.");
            return;
        }

        var executionResult = await commandService.TryExecuteAsync(preparedCommandResult.Entity, services);
        if (!executionResult.IsSuccess)
        {
            Console.Error.WriteLine($"There was an error\n, {executionResult.ToFullString()}");
        }
        else if (!executionResult.Entity.IsSuccess)
        {
            Console.Error.WriteLine($"There was an error\n, {executionResult.Entity.ToFullString()}");
        }
    }

    private static IServiceProvider CreateServices()
    {
        var collection = new ServiceCollection();

        collection

            // Adds provider using .NOS files that have to be located in NostaleData folder in the starup directory.
            // Use AddNostaleDataDatabase for using the database, you have to generate it using NosSmooth.Data.CLI
            // with migrate command. It's generated from the .NOS files.
            .AddNostaleDataFiles()
            .Configure<NostaleDataOptions>
            (
                o =>
                {
                    o.SupportedLanguages = new[]
                    {
                        // These languages will be loaded into the memory from the files.
                        Language.Cz, Language.Uk
                    };

                    // The path to the data folder.
                    o.NostaleDataPath = "NostaleData";
                }
            )
            .AddCommands()
            .AddCommandTree()
            .WithCommandGroup<ItemInfoCommand>()
            .WithCommandGroup<MonsterInfoCommand>()
            .WithCommandGroup<SkillInfoCommand>();

        return collection.BuildServiceProvider();
    }
}
\ No newline at end of file

Do not follow this link