瀏覽代碼

Add CSV to NEI converter

ghorsington 5 年之前
父節點
當前提交
42d68a449a
共有 2 個文件被更改,包括 72 次插入5 次删除
  1. 65 4
      ArcToolkitCLI/Commands/Converters/NeiConverter.cs
  2. 7 1
      ArcToolkitCLI/Util/Encryption.cs

+ 65 - 4
ArcToolkitCLI/Commands/Converters/NeiConverter.cs

@@ -51,6 +51,67 @@ namespace ArcToolkitCLI.Commands.Converters
 
         int ToNei(string filePath)
         {
+            string nameNoExt = Path.GetFileNameWithoutExtension(filePath);
+
+            List<string[]> values = new List<string[]>();
+
+            int cols = 0;
+            int rows = 0;
+
+            using (var tr = File.OpenText(filePath))
+            {
+                string line;
+
+                while ((line = tr.ReadLine()) != null)
+                {
+                    var colValues = line.Split(new []{ValueSeparator}, StringSplitOptions.None);
+                    if(colValues.Length == 0)
+                        continue;
+                    cols = Math.Max(cols, colValues.Length);
+                    values.Add(colValues);
+                    rows++;
+                }
+            }
+
+            using (var ms = new MemoryStream())
+            {
+                using (var bw = new BinaryWriter(ms))
+                {
+                    bw.Write(NEI_MAGIC);
+                    bw.Write(cols);
+                    bw.Write(rows);
+
+                    int totalLength = 0;
+                    foreach (var row in values)
+                    {
+                        for (int colIndex = 0; colIndex < cols; colIndex++)
+                        {
+                            bw.Write(totalLength);
+                            var strLen = colIndex < row.Length ? row[colIndex].Length : 0;
+                            bw.Write(strLen);
+                            totalLength += strLen;
+                        }
+                    }
+
+                    foreach (var row in values)
+                    {
+                        for (int colIndex = 0; colIndex < cols; colIndex++)
+                        {
+                            if(colIndex < row.Length)
+                                bw.Write(ShiftJisEncoding.GetBytes(row[colIndex]));
+                            bw.Write(0x00); // Add null terminator
+                        }
+                    }
+                }
+
+                var data = ms.ToArray();
+                byte[] extraData = null;
+                if ((data.Length & 0xf) == 0) // If the data size is padded to 16 bytes, add a bit of junk data at the end
+                    extraData = new []{ (byte)0x00 };
+
+                File.WriteAllBytes(Path.Combine(Output, $"{nameNoExt}.nei"), Encryption.EncryptBytes(data, NEI_KEY, extraData: extraData));
+            }
+
             return 0;
         }
 
@@ -89,17 +150,17 @@ namespace ArcToolkitCLI.Commands.Converters
                         values[cell] = ShiftJisEncoding.GetString(br.ReadBytes(len), 0, Math.Max(len - 1, 0));
                     }
 
-                    using (var sw = new StreamWriter(File.Create(Path.Combine(Output, $"{nameNoExt}.csv"))))
+                    using (var tw = File.CreateText(Path.Combine(Output, $"{nameNoExt}.csv")))
                     {
                         for (int row = 0; row < rows; row++)
                         {
                             for (int col = 0; col < cols; col++)
                             {
-                                sw.Write(values[row * cols + col]);
+                                tw.Write(values[row * cols + col]);
                                 if(col != cols - 1)
-                                    sw.Write(ValueSeparator);
+                                    tw.Write(ValueSeparator);
                             }
-                            sw.WriteLine();
+                            tw.WriteLine();
                         }
                     }
                 }

+ 7 - 1
ArcToolkitCLI/Util/Encryption.cs

@@ -8,6 +8,8 @@ namespace ArcToolkitCLI.Util
 {
     public static class Encryption
     {
+        private static Random Random = new Random();
+
         public static byte[] ReadKeyFromFile(string filename)
         {
             using (var br = new BinaryReader(File.OpenRead(filename)))
@@ -89,11 +91,15 @@ namespace ArcToolkitCLI.Util
             }
         }
 
-        public static byte[] EncryptBytes(byte[] data, byte[] key, byte[] ivSeed, byte[] extraData = null)
+        public static byte[] EncryptBytes(byte[] data, byte[] key, byte[] ivSeed = null, byte[] extraData = null)
         {
             if(extraData?.Length > 255)
                 throw new ArgumentException("Extra data cannot be larger than 255 bytes!", nameof(extraData));
 
+            if (ivSeed == null)
+                ivSeed = BitConverter.GetBytes(Random.Next());
+
+
             byte[] iv = GenerateIV(ivSeed);
 
             using (var rijndael = new RijndaelManaged())