A Data/NosSmooth.Data.CLI/Commands/ExtractNosFileCommand.cs => Data/NosSmooth.Data.CLI/Commands/ExtractNosFileCommand.cs +63 -0
@@ 0,0 1,63 @@
+//
+// ExtractNosFileCommand.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 System.Net;
+using System.Text;
+using NosSmooth.Data.NOSFiles.Files;
+using NosSmooth.Data.NOSFiles.Readers;
+using Remora.Commands.Attributes;
+using Remora.Commands.Groups;
+using Remora.Results;
+
+namespace NosSmooth.Data.CLI.Commands;
+
+/// <summary>
+/// A command to extract files from a NosTale archive.
+/// </summary>
+public class ExtractNosFileCommand : CommandGroup
+{
+ private readonly FileReader _reader;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExtractNosFileCommand"/> class.
+ /// </summary>
+ /// <param name="reader">The file reader.</param>
+ public ExtractNosFileCommand(FileReader reader)
+ {
+ _reader = reader;
+ }
+
+ /// <summary>
+ /// Handles extract command.
+ /// </summary>
+ /// <param name="inputFile">The input nos archive.</param>
+ /// <param name="outputDirectory">The output directory to put the extracted files to.</param>
+ /// <returns>A result that may or may not have succeeded..</returns>
+ [Command("extract")]
+ public async Task<Result> HandleExtract
+ (
+ string inputFile,
+ [Option('o', "option")]
+ string outputDirectory = "out"
+ )
+ {
+ Directory.CreateDirectory(outputDirectory);
+
+ var readResult = _reader.ReadFileSystemFile<FileArchive>(inputFile);
+ if (!readResult.IsSuccess)
+ {
+ return Result.FromError(readResult);
+ }
+
+ foreach (var file in readResult.Entity.Content.Files)
+ {
+ var outputPath = Path.Combine(outputDirectory, file.Path);
+ await File.WriteAllBytesAsync(outputPath, file.Content, CancellationToken);
+ }
+
+ return Result.FromSuccess();
+ }
+}<
\ No newline at end of file
A Data/NosSmooth.Data.CLI/Commands/MigrateDatabaseCommand.cs => Data/NosSmooth.Data.CLI/Commands/MigrateDatabaseCommand.cs +63 -0
@@ 0,0 1,63 @@
+//
+// MigrateDatabaseCommand.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 NosSmooth.Data.Abstractions.Language;
+using NosSmooth.Data.Database;
+using NosSmooth.Data.NOSFiles;
+using Remora.Commands.Attributes;
+using Remora.Commands.Groups;
+using Remora.Results;
+
+namespace NosSmooth.Data.CLI.Commands;
+
+/// <summary>
+/// Create a database from nos files.
+/// </summary>
+public class MigrateDatabaseCommand : CommandGroup
+{
+ private readonly DatabaseMigrator _migrator;
+ private readonly NostaleDataParser _parser;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MigrateDatabaseCommand"/> class.
+ /// </summary>
+ /// <param name="migrator">The database migrator.</param>
+ /// <param name="parser">The data parser.</param>
+ public MigrateDatabaseCommand(DatabaseMigrator migrator, NostaleDataParser parser)
+ {
+ _migrator = migrator;
+ _parser = parser;
+ }
+
+ /// <summary>
+ /// Migrate the database using nos files.
+ /// </summary>
+ /// <param name="nostaleDataPath">The directory with nostale data files.</param>
+ /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
+ [Command("migrate")]
+ public async Task<Result> HandleMigrate(string nostaleDataPath)
+ {
+ var parsingResult = _parser.ParseFiles
+ (
+ nostaleDataPath,
+ Language.Cz,
+ Language.De,
+ Language.Uk,
+ Language.Es,
+ Language.Fr,
+ Language.It,
+ Language.Pl,
+ Language.Ru,
+ Language.Tr
+ );
+ if (!parsingResult.IsSuccess)
+ {
+ return Result.FromError(parsingResult);
+ }
+
+ return await _migrator.Migrate(parsingResult.Entity);
+ }
+}<
\ No newline at end of file
M Data/NosSmooth.Data.CLI/NosSmooth.Data.CLI.csproj => Data/NosSmooth.Data.CLI/NosSmooth.Data.CLI.csproj +11 -0
@@ 7,4 7,15 @@
<OutputType>Exe</OutputType>
</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="..\NosSmooth.Data.Database\NosSmooth.Data.Database.csproj" />
+ <ProjectReference Include="..\NosSmooth.Data.NOSFiles\NosSmooth.Data.NOSFiles.csproj" />
+ </ItemGroup>
+
</Project>
A Data/NosSmooth.Data.CLI/Program.cs => Data/NosSmooth.Data.CLI/Program.cs +76 -0
@@ 0,0 1,76 @@
+//
+// 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 Microsoft.Extensions.DependencyInjection;
+using NosSmooth.Data.CLI.Commands;
+using NosSmooth.Data.Database.Extensions;
+using NosSmooth.Data.NOSFiles.Extensions;
+using NosSmooth.Data.NOSFiles.Files;
+using NosSmooth.Data.NOSFiles.Readers;
+using NosSmooth.Data.NOSFiles.Readers.Types;
+using Remora.Commands.Extensions;
+using Remora.Commands.Services;
+using Remora.Results;
+
+namespace NosSmooth.Data.CLI;
+
+/// <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();
+ 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.Error.Message}");
+ 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.Entity.IsSuccess)
+ {
+ switch (executionResult.Entity.Error)
+ {
+ case ExceptionError exc:
+ Console.Error.WriteLine($"There was an exception, {exc.Exception.Message}");
+ break;
+ default:
+ Console.Error.WriteLine($"There was an error, {executionResult.Entity.Error!.Message}");
+ break;
+ }
+ }
+ }
+
+ private static IServiceProvider CreateServices()
+ {
+ var collection = new ServiceCollection();
+
+ collection
+ .AddNostaleDataParsing()
+ .AddNostaleDatabaseMigrator()
+ .AddCommands()
+ .AddCommandTree()
+ .WithCommandGroup<MigrateDatabaseCommand>()
+ .WithCommandGroup<ExtractNosFileCommand>();
+
+ return collection.BuildServiceProvider();
+ }
+}<
\ No newline at end of file