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