Пример #1
0
 private void buildButton_Click(object sender, EventArgs e)
 {
     using (var sfd = new SaveFileDialog()
     {
         FileName = contentIdTextBox.Text + ".pkg"
     })
     {
         if (sfd.ShowDialog() == DialogResult.OK)
         {
             Action <string> log = x => logBox.AppendText(x + Environment.NewLine);
             log("Converting DLC files...");
             var cons  = listBox1.Items.OfType <string>().Select(f => STFSPackage.OpenFile(GameArchives.Util.LocalFile(f))).ToList();
             var songs = new List <LibForge.DLCSong>();
             foreach (var con in cons)
             {
                 songs.AddRange(PkgCreator.ConvertDLCPackage(
                                    con.RootDirectory.GetDirectory("songs"),
                                    volumeAdjustCheckBox.Checked,
                                    s => log($"Warning ({con.FileName}): " + s)));
             }
             log("Building PKG...");
             PkgCreator.BuildPkg(songs, contentIdTextBox.Text, descriptionBox.Text, euCheckBox.Checked, sfd.FileName, log);
             foreach (var con in cons)
             {
                 con.Dispose();
             }
         }
     }
 }
Пример #2
0
 /// <summary>
 /// Genera los scripts de los archivos mencionados en el documento
 /// </summary>
 /// <param name="library">Lista que contiene los datos de archivos mencionados en el documento</param>
 /// <param name="place">Ubicación en donde se creará los archivos</param>
 internal void generateScripts(FileLibrary library, String place)
 {
     while (library != null)
     {
         Wrapper        file = this.serverExplorer(library.dbName, library.type, library.fileName);
         ScriptLocation sl   = new ScriptLocation(library.dbName, library.type, library.fileName, file.script(library.newStatus, alter));
         PkgCreator.createFile(sl, place);
         library = library.getNextInLine();
     }
 }
Пример #3
0
        private bool LoadCon(string filename)
        {
            con = STFSPackage.OpenFile(GameArchives.Util.LocalFile(filename));
            if (con.Type != STFSType.CON)
            {
                MessageBox.Show("Error: given file was not a CON file");
                return(false);
            }
            var songs = PkgCreator.ConvertDLCPackage(con.RootDirectory.GetDirectory("songs"));

            idBox.Text          = PkgCreator.GenId(songs[0]);
            descriptionBox.Text = $"Custom: \"{songs[0].SongData.Name} - {songs[0].SongData.Artist}\"";
            groupBox2.Enabled   = true;
            return(true);
        }
Пример #4
0
 private bool LoadCon(string filename)
 {
     using (var con = STFSPackage.OpenFile(GameArchives.Util.LocalFile(filename)))
     {
         if (con.Type != STFSType.CON)
         {
             throw new Exception($"File is not a CON file.");
         }
         var datas = PkgCreator.GetSongMetadatas(con.RootDirectory.GetDirectory("songs"));
         if (datas.Count > 0)
         {
             dtas[filename] = datas;
             listBox1.Items.Add(filename);
         }
     }
     return(true);
 }
Пример #5
0
        void UpdateState()
        {
            if (dtas.Count == 0)
            {
                groupBox2.Enabled   = false;
                groupBox3.Enabled   = false;
                idBox.Text          = "";
                descriptionBox.Text = "";
                return;
            }
            var dtaList = dtas.Values.SelectMany(x => x).ToList();

            dtaList.Sort((a, b) => a.Shortname.CompareTo(b.Shortname));
            groupBox2.Enabled   = true;
            idBox.Text          = PkgCreator.GenId(dtaList);
            descriptionBox.Text = PkgCreator.GenDesc(dtaList);
        }
Пример #6
0
 private void buildButton_Click(object sender, EventArgs e)
 {
     using (var sfd = new SaveFileDialog()
     {
         FileName = contentIdTextBox.Text + ".pkg"
     })
     {
         if (sfd.ShowDialog() == DialogResult.OK)
         {
             Action <string> log = x => logBox.AppendText(x + Environment.NewLine);
             log("Converting DLC files...");
             var songs = PkgCreator.ConvertDLCPackage(con.RootDirectory.GetDirectory("songs"), s => log("Warning: " + s));
             log("Building PKG...");
             PkgCreator.BuildPkg(songs, contentIdTextBox.Text, descriptionBox.Text, euCheckBox.Checked, sfd.FileName, log);
         }
     }
 }
Пример #7
0
        /// <summary>
        /// Función que sigue la lógica estándar para trabajar con el proyecto. Genera un zip con los scripts entregados
        /// </summary>
        /// <param name="pathToExcel">Ubicación del archivo a procesar</param>
        /// <param name="zipPath">Ubicación donde se depositará el comprimido</param>
        /// <param name="server">Nombre de servidor e instancia</param>
        /// <param name="user">Nombre de usuario</param>
        /// <param name="psw">Contraseña de usuario</param>
        public static void Process(String pathToExcel, String zipPath, String server, String user, String psw, bool altOption)
        {
            if (!Directory.Exists(zipPath))
            {
                Directory.CreateDirectory(zipPath);
            }

            String placeToCreateFiles = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\Data";

            Directory.CreateDirectory(placeToCreateFiles);

            SQLScripter.Parser.Parser p = new SQLScripter.Parser.Parser(pathToExcel);
            if (!p.docCheck())
            {
                return;
            }
            String pkgPath = zipPath + "//" + p.getDocName();

            FileLibrary f = p.createLibrary();

            try
            {
                Guionista g = new Guionista(server, user, psw);
                g.alter = altOption;
                g.generateScripts(f, placeToCreateFiles);
            }
            catch (Microsoft.SqlServer.Management.Common.ConnectionFailureException)
            {
                foreach (var subDir in new DirectoryInfo(placeToCreateFiles).GetDirectories())
                {
                    subDir.Delete(true);
                }
                File.Delete(placeToCreateFiles + @"\errors.txt");
            }

            PkgCreator.generatePkg("zip", pkgPath, placeToCreateFiles);
        }
Пример #8
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Usage();
                return;
            }
            void WithIO(Action <Stream, Stream> action)
            {
                using (var fi = File.OpenRead(args[1]))
                    using (var fo = File.OpenWrite(args[2]))
                        action(fi, fo);
            }

            var makepkg = true;

            switch (args[0])
            {
            case "rbmid2mid":
                WithIO((fi, fo) =>
                {
                    var rbmid = RBMidReader.ReadStream(fi);
                    var midi  = RBMidConverter.ToMid(rbmid);
                    MidiCS.MidiFileWriter.WriteSMF(midi, fo);
                });
                break;

            case "mid2rbmid":
                WithIO((fi, fo) =>
                {
                    var mid   = MidiCS.MidiFileReader.FromStream(fi);
                    var rbmid = RBMidConverter.ToRBMid(mid);
                    RBMidWriter.WriteStream(rbmid, fo);
                });
                break;

            case "reprocess":
                WithIO((fi, fo) =>
                {
                    var rbmid     = RBMidReader.ReadStream(fi);
                    var processed = RBMidConverter.ToRBMid(RBMidConverter.ToMid(rbmid), rbmid.HopoThreshold);
                    RBMidWriter.WriteStream(processed, fo);
                });
                break;

            case "tex2png":
                WithIO((fi, fo) =>
                {
                    var tex    = TextureReader.ReadStream(fi);
                    var bitmap = TextureConverter.ToBitmap(tex, 0);
                    bitmap.Save(fo, System.Drawing.Imaging.ImageFormat.Png);
                });
                break;

            case "png2tex":
                WithIO((fi, fo) =>
                {
                    var img = System.Drawing.Image.FromStream(fi);
                    var tex = TextureConverter.ToTexture(img);
                    TextureWriter.WriteStream(tex, fo);
                });
                break;

            case "milopng2tex":
                WithIO((fi, fo) =>
                {
                    var tex = TextureConverter.MiloPngToTexture(fi);
                    TextureWriter.WriteStream(tex, fo);
                });
                break;

            case "mesh2obj":
            {
                var input  = args[1];
                var output = args[2];
                using (var fi = File.OpenRead(input))
                {
                    var mesh = HxMeshReader.ReadStream(fi);
                    var obj  = HxMeshConverter.ToObj(mesh);
                    File.WriteAllText(output, obj);
                }
                break;
            }

            case "milo2lip":
            case "milo2lips":
            case "milo2lipsync":
                WithIO((fi, fo) =>
                {
                    var milo    = MiloFile.ReadFromStream(fi);
                    var lipsync = LipsyncConverter.FromMilo(milo);
                    new LipsyncWriter(fo).WriteStream(lipsync);
                });
                break;

            case "version":
                var assembly    = System.Reflection.Assembly.GetExecutingAssembly();
                var version     = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
                var libAssembly = System.Reflection.Assembly.GetAssembly(typeof(RBMid));
                var libVersion  = FileVersionInfo.GetVersionInfo(libAssembly.Location).FileVersion;
                Console.WriteLine($"ForgeTool v{version}");
                Console.WriteLine($"LibForge v{libVersion}");
                break;

            case "test":
            {
                var dir = args[1];
                int succ = 0, warn = 0, fail = 0;
                var files = dir.EndsWith(".rbmid_ps4") || dir.EndsWith(".rbmid_pc") ?
                            new[] { dir } : Directory.EnumerateFiles(dir, "*.rbmid_*");
                foreach (var f in files)
                {
                    var info = new FileInfo(f);
                    var name = info.Name;
                    using (var fi = File.OpenRead(f))
                    {
                        try
                        {
                            var rbmid  = RBMidReader.ReadStream(fi);
                            var midi   = RBMidConverter.ToMid(rbmid);
                            var rbmid2 = RBMidConverter.ToRBMid(midi, rbmid.HopoThreshold);
                            using (var ms = new MemoryStream((int)fi.Length))
                            {
                                // TODO: Switch this to rbmid2 once we are generating all events
                                //       (regardless of whether the event data are all correct)
                                RBMidWriter.WriteStream(rbmid, ms);
                                ms.Position = 0;
                                if (ms.Length == fi.Length)
                                {
                                    var comparison = rbmid.Compare(rbmid2);
                                    if (comparison != null)
                                    {
                                        throw new CompareException("File comparison failed at field: " + comparison);
                                    }
                                    Console.WriteLine($"[OK] {name}");
                                    succ++;
                                }
                                else
                                {
                                    Console.Write($"[WARN] {name}:");
                                    Console.WriteLine($" Processed file had different length ({fi.Length} orig, {ms.Length} processed)");
                                    warn++;
                                }
                            }
                        } catch (CompareException e)
                        {
                            Console.WriteLine($"[WARN] {name}: {e.Message}");
                            warn++;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[ERROR] {name}: {e.Message}");
                            Console.WriteLine(e.StackTrace);
                            fail++;
                        }
                    }
                }
                Console.WriteLine($"Summary: {succ} OK, {warn} WARN, {fail} ERROR");
                if (warn > 0)
                {
                    Console.WriteLine("(a = converted file, b = original)");
                }
            }
            break;

            case "simpletest":
            {
                var dir = args[1];
                int succ = 0, warn = 0, fail = 0;
                foreach (var f in Directory.EnumerateFiles(dir, "*.rbmid_*"))
                {
                    var info = new FileInfo(f);
                    var name = info.Name;
                    using (var fi = File.OpenRead(f))
                    {
                        try
                        {
                            var rbmid = RBMidReader.ReadStream(fi);
                            using (var ms = new MemoryStream((int)fi.Length))
                            {
                                RBMidWriter.WriteStream(rbmid, ms);
                                ms.Position = 0;
                                if (ms.Length == fi.Length)
                                {
                                    succ++;
                                }
                                else
                                {
                                    Console.WriteLine($"[WARN] {name}:");
                                    Console.WriteLine($"  Processed file had different length ({fi.Length} orig, {ms.Length} processed)");
                                    warn++;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[ERROR] {name}:");
                            Console.WriteLine("  " + e.Message);
                            fail++;
                        }
                    }
                }
                Console.WriteLine($"Summary: {succ} OK, {warn} WARN, {fail} ERROR");
            }
            break;

            case "testrbsong":
            {
                var dir = args[1];
                int succ = 0, warn = 0, fail = 0;
                var files = dir.EndsWith(".rbsong") ?
                            new[] { dir } : Directory.EnumerateFiles(dir, "*.rbsong");
                foreach (var f in files)
                {
                    var info = new FileInfo(f);
                    var name = info.Name;
                    using (var fi = File.OpenRead(f))
                    {
                        try
                        {
                            var rbsong = new RBSongReader(fi).Read();
                            using (var ms = new MemoryStream((int)fi.Length))
                            {
                                new RBSongWriter(ms).WriteStream(rbsong);
                                ms.Position = 0;
                                if (ms.Length == fi.Length)
                                {
                                    succ++;
                                }
                                else
                                {
                                    Console.WriteLine($"[WARN] {name}:");
                                    Console.WriteLine($"  Processed file had different length ({fi.Length} orig, {ms.Length} processed)");
                                    warn++;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[ERROR] {name}:");
                            Console.WriteLine("  " + e.Message);
                            fail++;
                        }
                    }
                }
                Console.WriteLine($"Summary: {succ} OK, {warn} WARN, {fail} ERROR");
                if (fail > 0)
                {
                    Console.WriteLine("(a = converted file, b = original)");
                }
            }
            break;

            case "rbsong2rbsong":
                WithIO((i, o) => new RBSongWriter(o).WriteStream(new RBSongReader(i).Read()));
                break;

            case "con2gp4":
                makepkg = false;
                goto case "con2pkg";

            case "con2pkg":
            {
                var    i = 0;
                bool   eu = false;
                string pkgId = null, pkgDesc = null;
                while (++i < args.Length - 4)
                {
                    switch (args[i])
                    {
                    case "--scee":
                        eu = true;
                        continue;

                    case "--id":
                        pkgId = args[++i];
                        continue;

                    case "--desc":
                        pkgDesc = args[++i];
                        continue;
                    }
                    break;
                }
                if (makepkg)
                {
                    var cmd    = args[i++];
                    var con    = args[i++];
                    var dest   = args[i++];
                    var tmpDir = Path.Combine(Path.GetTempPath(), "forgetool_tmp_build");
                    if (!Directory.Exists(con))
                    {
                        var conFilename = Path.GetFileName(con);
                        PkgCreator.ConToGp4(con, tmpDir, eu, pkgId, pkgDesc);
                    }
                    else
                    {
                        PkgCreator.ConsToGp4(con, tmpDir, eu, pkgId, pkgDesc);
                    }
                    PkgCreator.BuildPkg(cmd, Path.Combine(tmpDir, "project.gp4"), dest);
                    Directory.Delete(tmpDir, true);
                }
                else
                {
                    var con  = args[i++];
                    var dest = args[i++];
                    PkgCreator.ConToGp4(con, dest, eu, pkgId, pkgDesc);
                }
            }
            break;

            default:
                Usage();
                break;
            }
        }
Пример #9
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Usage();
                return;
            }
            void WithIO(Action <Stream, Stream> action)
            {
                using (var fi = File.OpenRead(args[1]))
                    using (var fo = File.OpenWrite(args[2]))
                        action(fi, fo);
            }

            var makepkg = true;

            switch (args[0])
            {
            case "rbmid2mid":
                WithIO((fi, fo) =>
                {
                    var rbmid = RBMidReader.ReadStream(fi);
                    var midi  = RBMidConverter.ToMid(rbmid);
                    MidiCS.MidiFileWriter.WriteSMF(midi, fo);
                });
                break;

            case "mid2rbmid":
                WithIO((fi, fo) =>
                {
                    var mid   = MidiCS.MidiFileReader.FromStream(fi);
                    var rbmid = RBMidConverter.ToRBMid(mid);
                    RBMidWriter.WriteStream(rbmid, fo);
                });
                break;

            case "reprocess":
                WithIO((fi, fo) =>
                {
                    var rbmid     = RBMidReader.ReadStream(fi);
                    var processed = RBMidConverter.ToRBMid(RBMidConverter.ToMid(rbmid), rbmid.HopoThreshold);
                    RBMidWriter.WriteStream(processed, fo);
                });
                break;

            case "tex2png":
                WithIO((fi, fo) =>
                {
                    var tex    = TextureReader.ReadStream(fi);
                    var bitmap = TextureConverter.ToBitmap(tex, 0);
                    bitmap.Save(fo, System.Drawing.Imaging.ImageFormat.Png);
                });
                break;

            case "png2tex":
                WithIO((fi, fo) =>
                {
                    var img = System.Drawing.Image.FromStream(fi);
                    var tex = TextureConverter.ToTexture(img);
                    TextureWriter.WriteStream(tex, fo);
                });
                break;

            case "milopng2tex":
                WithIO((fi, fo) =>
                {
                    var tex = TextureConverter.MiloPngToTexture(fi);
                    TextureWriter.WriteStream(tex, fo);
                });
                break;

            case "mesh2obj":
            {
                var input  = args[1];
                var output = args[2];
                using (var fi = File.OpenRead(input))
                {
                    var mesh = HxMeshReader.ReadStream(fi);
                    var obj  = HxMeshConverter.ToObj(mesh);
                    File.WriteAllText(output, obj);
                }
                break;
            }

            case "milo2lip":
            case "milo2lips":
            case "milo2lipsync":
                WithIO((fi, fo) =>
                {
                    var milo    = MiloFile.ReadFromStream(fi);
                    var lipsync = LipsyncConverter.FromMilo(milo);
                    new LipsyncWriter(fo).WriteStream(lipsync);
                });
                break;

            case "version":
                var assembly    = System.Reflection.Assembly.GetExecutingAssembly();
                var version     = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
                var libAssembly = System.Reflection.Assembly.GetAssembly(typeof(RBMid));
                var libVersion  = FileVersionInfo.GetVersionInfo(libAssembly.Location).FileVersion;
                Console.WriteLine($"ForgeTool v{version}");
                Console.WriteLine($"LibForge v{libVersion}");
                break;

            case "test":
            {
                var dir = args[1];
                int succ = 0, warn = 0, fail = 0;
                var files = dir.EndsWith(".rbmid_ps4") || dir.EndsWith(".rbmid_pc") ?
                            new[] { dir } : Directory.EnumerateFiles(dir, "*.rbmid_*");
                foreach (var f in files)
                {
                    var info = new FileInfo(f);
                    var name = info.Name;
                    using (var fi = File.OpenRead(f))
                    {
                        try
                        {
                            var rbmid  = RBMidReader.ReadStream(fi);
                            var midi   = RBMidConverter.ToMid(rbmid);
                            var rbmid2 = RBMidConverter.ToRBMid(midi, rbmid.HopoThreshold);
                            using (var ms = new MemoryStream((int)fi.Length))
                            {
                                // TODO: Switch this to rbmid2 once we are generating all events
                                //       (regardless of whether the event data are all correct)
                                RBMidWriter.WriteStream(rbmid, ms);
                                ms.Position = 0;
                                if (ms.Length == fi.Length)
                                {
                                    var comparison = rbmid.Compare(rbmid2);
                                    if (comparison != null)
                                    {
                                        throw new CompareException("File comparison failed at field: " + comparison);
                                    }
                                    Console.WriteLine($"[OK] {name}");
                                    succ++;
                                }
                                else
                                {
                                    Console.Write($"[WARN] {name}:");
                                    Console.WriteLine($" Processed file had different length ({fi.Length} orig, {ms.Length} processed)");
                                    warn++;
                                }
                            }
                        } catch (CompareException e)
                        {
                            Console.WriteLine($"[WARN] {name}: {e.Message}");
                            warn++;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[ERROR] {name}: {e.Message}");
                            Console.WriteLine(e.StackTrace);
                            fail++;
                        }
                    }
                }
                Console.WriteLine($"Summary: {succ} OK, {warn} WARN, {fail} ERROR");
                if (warn > 0)
                {
                    Console.WriteLine("(a = converted file, b = original)");
                }
                if (warn > 0 || fail > 0)
                {
                    Environment.Exit(1);
                }
            }
            break;

            case "simpletest":
            {
                var dir = args[1];
                int succ = 0, warn = 0, fail = 0;
                foreach (var f in Directory.EnumerateFiles(dir, "*.rbmid_*"))
                {
                    var info = new FileInfo(f);
                    var name = info.Name;
                    using (var fi = File.OpenRead(f))
                    {
                        try
                        {
                            var rbmid = RBMidReader.ReadStream(fi);
                            using (var ms = new MemoryStream((int)fi.Length))
                            {
                                RBMidWriter.WriteStream(rbmid, ms);
                                ms.Position = 0;
                                if (ms.Length == fi.Length)
                                {
                                    succ++;
                                }
                                else
                                {
                                    Console.WriteLine($"[WARN] {name}:");
                                    Console.WriteLine($"  Processed file had different length ({fi.Length} orig, {ms.Length} processed)");
                                    warn++;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[ERROR] {name}:");
                            Console.WriteLine("  " + e.Message);
                            fail++;
                        }
                    }
                }
                Console.WriteLine($"Summary: {succ} OK, {warn} WARN, {fail} ERROR");
            }
            break;

            case "testrbsong":
            {
                var dir = args[1];
                int succ = 0, warn = 0, fail = 0;
                var files = dir.EndsWith(".rbsong") ?
                            new[] { dir } : Directory.EnumerateFiles(dir, "*.rbsong");
                foreach (var f in files)
                {
                    var info = new FileInfo(f);
                    var name = info.Name;
                    using (var fi = File.OpenRead(f))
                    {
                        try
                        {
                            var rbsong = new RBSongResource();
                            rbsong.Load(fi);
                            using (var ms = new MemoryStream((int)fi.Length))
                            {
                                new RBSongResourceWriter(ms).WriteStream(rbsong);
                                ms.Position = 0;
                                if (ms.Length == fi.Length)
                                {
                                    succ++;
                                }
                                else
                                {
                                    Console.WriteLine($"[WARN] {name}:");
                                    Console.WriteLine($"  Processed file had different length ({fi.Length} orig, {ms.Length} processed)");
                                    warn++;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"[ERROR] {name}:");
                            Console.WriteLine("  " + e.Message);
                            fail++;
                        }
                    }
                }
                Console.WriteLine($"Summary: {succ} OK, {warn} WARN, {fail} ERROR");
                if (fail > 0)
                {
                    Console.WriteLine("(a = converted file, b = original)");
                }
            }
            break;

            case "rbsong2rbsong":
                WithIO((i, o) => {
                    var rbsong = new RBSongResource();
                    rbsong.Load(i);
                    new RBSongResourceWriter(o).WriteStream(rbsong);
                });
                break;

            case "con2gp4":
                makepkg = false;
                goto case "con2pkg";

            case "con2pkg":
            {
                var    i = 0;
                bool   eu = false;
                string pkgId = null, pkgDesc = null;
                while (++i < args.Length - 3)
                {
                    switch (args[i])
                    {
                    case "--scee":
                        eu = true;
                        continue;

                    case "--id":
                        pkgId = args[++i];
                        continue;

                    case "--desc":
                        pkgDesc = args[++i];
                        continue;
                    }
                    break;
                }
                if (makepkg)
                {
                    var con    = args[i++];
                    var dest   = args[i++];
                    var tmpDir = Path.Combine(Path.GetTempPath(), "forgetool_tmp_build");
                    if (!Directory.Exists(con))
                    {
                        var conFilename = Path.GetFileName(con);
                        PkgCreator.ConToGp4(con, tmpDir, eu, pkgId, pkgDesc);
                    }
                    else
                    {
                        PkgCreator.ConsToGp4(con, tmpDir, eu, pkgId, pkgDesc);
                    }
                    PkgCreator.BuildPkg(Path.Combine(tmpDir, "project.gp4"), dest);
                    Directory.Delete(tmpDir, true);
                }
                else
                {
                    var con  = args[i++];
                    var dest = args[i++];
                    PkgCreator.ConToGp4(con, dest, eu, pkgId, pkgDesc);
                }
            }
            break;

            case "csv2txt":
            {
                var input  = args[1];
                var output = args[2];
                using (var fi = File.OpenRead(input))
                {
                    var csv = CsvData.LoadFile(fi);
                    File.WriteAllText(output, csv.ToString());
                }
            }
            break;

            case "arkorder":
            {
                var input   = args[1];
                var output  = args[2];
                var sb      = new StringBuilder();
                var archive = new Archive(input);
                using (var o = File.OpenWrite(output))
                    using (var sw = new StreamWriter(o))
                    {
                        archive.WriteArkorder(sw);
                    }
            }
            break;

            case "arkbuild":
            {
                var filedir  = args[1];
                var arkorder = args[2];
                var outdir   = args[3];
                var name     = args[4];
                if (!Directory.Exists(filedir))
                {
                    Console.WriteLine($"Error: {filedir} does not exist.");
                    return;
                }
                if (!Directory.Exists(outdir))
                {
                    Console.WriteLine($"Error: {outdir} does not exist.");
                    return;
                }
                if (!File.Exists(arkorder))
                {
                    Console.WriteLine($"Error: {arkorder} not found.");
                    return;
                }
                var       arks = new List <List <Tuple <string, IFile> > >();
                DataArray arkOrder;
                using (var order = File.OpenRead(arkorder))
                    using (var reader = new StreamReader(order))
                    {
                        arkOrder = DtxCS.DTX.FromDtaStream(order);
                    }
                int arkIndex = 0;
                arks.Add(new List <Tuple <string, IFile> >());
                foreach (var x in arkOrder.Children)
                {
                    if (x is DataSymbol s)
                    {
                        var fullPath = Path.Combine(filedir, s.Name.Replace('/', Path.DirectorySeparatorChar));
                        if (!File.Exists(fullPath))
                        {
                            Console.WriteLine($"Error: {fullPath} could not be found.");
                            return;
                        }
                        IFile f = Util.LocalFile(fullPath);
                        arks[arkIndex].Add(Tuple.Create(s.Name, f));
                    }
                    else if (x is DataCommand c && c.Symbol(0).Name == "split_ark")
                    {
                        arkIndex++;
                        arks[arkIndex] = new List <Tuple <string, IFile> >();
                    }
                }
                var builder = new ArkBuilder(name, arks);
                Console.Write($"Writing {name}.hdr and ark files to {outdir}...");
                builder.Save(outdir);
            }
            break;

            default:
                Usage();
                break;
            }
        }