Selaa lähdekoodia

Replace IConverterCommand.cs with BaseConverter.cs

ghorsington 4 vuotta sitten
vanhempi
commit
4ad0e10db2

+ 1 - 1
ArcToolkitCLI/ArcToolkitCLI.csproj

@@ -71,7 +71,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Commands\ConvertCommand.cs" />
-    <Compile Include="Commands\Converters\IConverterCommand.cs" />
+    <Compile Include="Commands\Converters\BaseConverter.cs" />
     <Compile Include="Commands\Converters\MenuConverter.cs" />
     <Compile Include="Commands\Converters\NeiConverter.cs" />
     <Compile Include="Commands\Converters\TexConverter.cs" />

+ 3 - 3
ArcToolkitCLI/Commands/ConvertCommand.cs

@@ -11,8 +11,8 @@ namespace ArcToolkitCLI.Commands
         public int Run()
         {
             var commandTypes = typeof(ConvertCommand).Assembly.GetTypes()
-                                                     .Where(t => !t.IsInterface && !t.IsAbstract &&
-                                                                 typeof(IConverterCommand).IsAssignableFrom(t))
+                                                     .Where(t => !t.IsInterface && !t.IsAbstract && t != typeof(BaseConverter) &&
+                                                                 typeof(BaseConverter).IsAssignableFrom(t))
                                                      .ToArray();
 
             return new Parser(with =>
@@ -20,7 +20,7 @@ namespace ArcToolkitCLI.Commands
                     with.IgnoreUnknownArguments = true;
                     with.HelpWriter = Parser.Default.Settings.HelpWriter;
                 }).ParseArguments(Environment.GetCommandLineArgs().Skip(2), commandTypes)
-                  .MapResult((object t) => ((IConverterCommand)t).Run(), errs => 1);
+                  .MapResult((object t) => ((BaseConverter)t).Run(), errs => 1);
         }
     }
 }

+ 54 - 0
ArcToolkitCLI/Commands/Converters/BaseConverter.cs

@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using ArcToolkitCLI.Commands.Options;
+using ArcToolkitCLI.Util;
+using CommandLine;
+
+namespace ArcToolkitCLI.Commands.Converters
+{
+    public class BaseConverter : IInputOptions, IOutputOptions
+    {
+        protected Dictionary<string, Func<string, int>> Converters { get; set; }
+
+        protected BaseConverter() { }
+        
+        public int Run()
+        {
+            var verb = GetType().GetCustomAttributes(typeof(VerbAttribute), true).Cast<VerbAttribute>().FirstOrDefault();
+            
+            if(verb == null)
+                throw new NotImplementedException("The converter is not properly implemented yet, sorry!");
+
+            var convertCommand = verb.Name;
+            
+            var files = Glob.EnumerateFiles(Input).ToArray();
+            Directory.CreateDirectory(Output);
+
+            if (files.Length == 0)
+            {
+                Console.WriteLine($"No files specified. Run `convert help {convertCommand}` for help.");
+                return 0;
+            }
+
+            foreach (var file in files)
+            {
+                if (Converters.TryGetValue(file.Extension.ToLowerInvariant(), out var converter))
+                {
+                    var result = 0;
+                    if ((result = converter(file.FullName)) != 0)
+                        return result;
+                }
+                else 
+                    Console.WriteLine($"File {file.FullName} is none of the supported file formats ({string.Join(", ", Converters.Keys)}). Skipping...");
+            }
+
+            return 0;
+        }
+
+        [Value(0, HelpText = "Input files to convert")]
+        public IEnumerable<string> Input { get; set; }
+        public string Output { get; set; }
+    }
+}

+ 0 - 7
ArcToolkitCLI/Commands/Converters/IConverterCommand.cs

@@ -1,7 +0,0 @@
-namespace ArcToolkitCLI.Commands.Converters
-{
-    internal interface IConverterCommand
-    {
-        int Run();
-    }
-}

+ 6 - 33
ArcToolkitCLI/Commands/Converters/MenuConverter.cs

@@ -12,46 +12,19 @@ using YamlDotNet.Serialization;
 namespace ArcToolkitCLI.Commands.Converters
 {
     [Verb("menu", HelpText = "Convert MENU files into YAML and back")]
-    public class MenuConverter : IConverterCommand, IInputOptions, IOutputOptions
+    public class MenuConverter : BaseConverter
     {
         private const string MENU_TAG = "CM3D2_MENU";
 
-        public int Run()
+        public MenuConverter()
         {
-            var files = Glob.EnumerateFiles(Input);
-            Directory.CreateDirectory(Output);
-
-            if (!files.Any())
+            Converters = new Dictionary<string, Func<string, int>>
             {
-                Console.WriteLine("No files specified. Run `convert help tex` for help.");
-                return 0;
-            }
-
-            foreach (var file in files)
-            {
-                var result = 0;
-                switch (file.Extension.ToLowerInvariant())
-                {
-                    case ".menu":
-                        if ((result = MenuToYaml(file.FullName)) != 0)
-                            return result;
-                        break;
-                    case ".yaml":
-                        if ((result = YamlToMenu(file.FullName)) != 0)
-                            return result;
-                        break;
-                    default:
-                        Console.WriteLine($"File {file.FullName} is neither .png nor .tex file. Skipping...");
-                        break;
-                }
-            }
-
-            return 0;
+                [".menu"] = MenuToYaml,
+                [".yaml"] = YamlToMenu
+            };
         }
 
-        public IEnumerable<string> Input { get; set; }
-        public string Output { get; set; }
-
         private int YamlToMenu(string file)
         {
             var deserializer = new DeserializerBuilder().Build();

+ 6 - 35
ArcToolkitCLI/Commands/Converters/NeiConverter.cs

@@ -10,7 +10,7 @@ using CommandLine;
 namespace ArcToolkitCLI.Commands.Converters
 {
     [Verb("nei", HelpText = "Convert NEI files into CSV and back")]
-    internal class NeiConverter : IConverterCommand, IInputOptions, IOutputOptions
+    internal class NeiConverter : BaseConverter
     {
         private static readonly byte[] NEI_KEY =
         {
@@ -45,44 +45,15 @@ namespace ArcToolkitCLI.Commands.Converters
         [Option('s', "separator", Default = ';', HelpText = "Value separator of the CSV file")]
         public char ValueSeparator { get; set; }
 
-
-        public int Run()
+        public NeiConverter()
         {
-            var files = Glob.EnumerateFiles(Input);
-
-            if (!files.Any())
-            {
-                Console.WriteLine("No files specified. Run `convert help nei` for help.");
-                return 0;
-            }
-
-            foreach (var file in files)
+            Converters = new Dictionary<string, Func<string, int>>
             {
-                var result = 0;
-                switch (file.Extension.ToLowerInvariant())
-                {
-                    case ".nei":
-                        if ((result = ToCSV(file.FullName)) != 0)
-                            return result;
-                        break;
-                    case ".csv":
-                        if ((result = ToNei(file.FullName)) != 0)
-                            return result;
-                        break;
-                    default:
-                        Console.WriteLine($"File {file.FullName} is neither .nei nor .csv file. Skipping...");
-                        break;
-                }
-            }
-
-            return 0;
+                [".nei"] = ToCSV,
+                [".csv"] = ToNei
+            };
         }
 
-        [Value(0, HelpText = "Input NEI or CSV files")]
-        public IEnumerable<string> Input { get; set; }
-
-        public string Output { get; set; }
-
         private List<List<string>> ParseCSV(TextReader tr)
         {
             var buffer = new StringBuilder();

+ 31 - 61
ArcToolkitCLI/Commands/Converters/TexConverter.cs

@@ -13,12 +13,12 @@ using Squish;
 namespace ArcToolkitCLI.Commands.Converters
 {
     [Verb("tex", HelpText = "Convert TEX files into PNG and back")]
-    internal class TexConverter : IConverterCommand, IInputOptions, IOutputOptions
+    internal class TexConverter : BaseConverter
     {
         private const string TEX_TAG = "CM3D2_TEX";
         private const int TEX_VERSION = 1010;
 
-        private readonly byte[] PNG_HEADER =
+        private readonly byte[] pngHeader =
         {
             137,
             80,
@@ -34,58 +34,24 @@ namespace ArcToolkitCLI.Commands.Converters
 
         public TexConverter()
         {
-            textureLoaders = new Dictionary<TextureFormat, Action<string, byte[], int, int, TextureFormat>>
+            Converters = new Dictionary<string, Func<string, int>>
             {
-                [TextureFormat.ARGB32] = ConvertFromPng,
-                [TextureFormat.RGB24] = ConvertFromPng,
-                [TextureFormat.DXT1] = ConvertFromDxt,
-                [TextureFormat.DXT5] = ConvertFromDxt
+                [".tex"] = TexToPng,
+                [".png"] = PngToTex
             };
-        }
-
-        public int Run()
-        {
-            var files = Glob.EnumerateFiles(Input);
-            Directory.CreateDirectory(Output);
-
-            if (!files.Any())
-            {
-                Console.WriteLine("No files specified. Run `convert help tex` for help.");
-                return 0;
-            }
-
-            foreach (var file in files)
+            
+            textureLoaders = new Dictionary<TextureFormat, Action<string, byte[], int, int, TextureFormat>>
             {
-                var result = 0;
-                switch (file.Extension.ToLowerInvariant())
-                {
-                    case ".png":
-                        if ((result = PngToTex(file.FullName)) != 0)
-                            return result;
-                        break;
-                    case ".tex":
-                        if ((result = TexToPng(file.FullName)) != 0)
-                            return result;
-                        break;
-                    default:
-                        Console.WriteLine($"File {file.FullName} is neither .png nor .tex file. Skipping...");
-                        break;
-                }
-            }
-
-            return 0;
+                [TextureFormat.Argb32] = ConvertFromPng,
+                [TextureFormat.Rgb24] = ConvertFromPng,
+                [TextureFormat.Dxt1] = ConvertFromDxt,
+                [TextureFormat.Dxt5] = ConvertFromDxt
+            };
         }
 
-
-        [Value(0, HelpText = "Input PNG or TEX files")]
-        public IEnumerable<string> Input { get; set; }
-
-        public string Output { get; set; }
-
-
-        private bool ByteEquals(byte[] b1, byte[] b2)
+        private static bool ByteEquals(IReadOnlyList<byte> b1, IReadOnlyList<byte> b2)
         {
-            var len = Math.Min(b1.Length, b2.Length);
+            var len = Math.Min(b1.Count, b2.Count);
 
             for (var i = 0; i < len; i++)
                 if (b1[i] != b2[i])
@@ -97,14 +63,14 @@ namespace ArcToolkitCLI.Commands.Converters
         {
             var img = File.ReadAllBytes(file);
 
-            if (!ByteEquals(img, PNG_HEADER))
+            if (!ByteEquals(img, pngHeader))
             {
                 Console.WriteLine($"File {file} is not a PNG file!");
                 return 1;
             }
 
-            var w = BitConverter.ToInt32(img, PNG_HEADER.Length + 4 + 4);
-            var h = BitConverter.ToInt32(img, PNG_HEADER.Length + 4 + 4 + 4);
+            var w = BitConverter.ToInt32(img, pngHeader.Length + 4 + 4);
+            var h = BitConverter.ToInt32(img, pngHeader.Length + 4 + 4 + 4);
             using var bw =
                 new BinaryWriter(File.Create(Path.Combine(Output, $"{Path.GetFileNameWithoutExtension(file)}.tex")));
             bw.Write(TEX_TAG);
@@ -112,7 +78,7 @@ namespace ArcToolkitCLI.Commands.Converters
             bw.Write(string.Empty);
             bw.Write(w);
             bw.Write(h);
-            bw.Write((int)TextureFormat.ARGB32);
+            bw.Write((int)TextureFormat.Argb32);
             bw.Write(img.Length);
             bw.Write(img);
             return 0;
@@ -134,7 +100,7 @@ namespace ArcToolkitCLI.Commands.Converters
             var width = 0;
             var height = 0;
 
-            var format = TextureFormat.ARGB32;
+            var format = TextureFormat.Argb32;
 
             if (version >= 1010)
             {
@@ -155,8 +121,8 @@ namespace ArcToolkitCLI.Commands.Converters
 
             if (version == 1000)
             {
-                width = BitConverter.ToInt32(data, PNG_HEADER.Length + 4 + 4);
-                height = BitConverter.ToInt32(data, PNG_HEADER.Length + 4 + 4 + 4);
+                width = BitConverter.ToInt32(data, pngHeader.Length + 4 + 4);
+                height = BitConverter.ToInt32(data, pngHeader.Length + 4 + 4 + 4);
             }
 
             if (textureLoaders.TryGetValue(format, out var saveTex))
@@ -182,8 +148,12 @@ namespace ArcToolkitCLI.Commands.Converters
         private void ConvertFromDxt(string file, byte[] data, int width, int height, TextureFormat format)
         {
             var squishFlags =
-                format switch { TextureFormat.DXT1 => SquishFlags.kDxt1, TextureFormat.DXT5 => SquishFlags.kDxt5, _ =>
-                    throw new ArgumentException($"Invalid DXT texture format: {format}", nameof(format)) };
+                format switch 
+                { 
+                    TextureFormat.Dxt1 => SquishFlags.kDxt1, 
+                    TextureFormat.Dxt5 => SquishFlags.kDxt5,
+                    _ => throw new ArgumentException($"Invalid DXT texture format: {format}", nameof(format)) 
+                };
 
             var outData = new byte[width * height * 4];
             Squish.Squish.DecompressImage(outData, width, height, ref data, squishFlags);
@@ -207,10 +177,10 @@ namespace ArcToolkitCLI.Commands.Converters
 
         private enum TextureFormat
         {
-            ARGB32 = 5,
-            RGB24 = 3,
-            DXT1 = 10,
-            DXT5 = 12
+            Argb32 = 5,
+            Rgb24 = 3,
+            Dxt1 = 10,
+            Dxt5 = 12
         }
     }
 }