예제 #1
0
        /*
         * This doesn't really belong here...
         * changes all strings in an existing table definition to string_asci.
         */
        public void ConvertAllStringsToAscii(string packFile)
        {
            PackFile file = new PackFileCodec().Open(packFile);

            foreach (PackedFile packed in file)
            {
                if (packed.FullPath.StartsWith("db"))
                {
                    string       typename = DBFile.Typename(packed.FullPath);
                    DBFileHeader header   = PackedFileDbCodec.readHeader(packed);
                    if (!string.IsNullOrEmpty(header.GUID))
                    {
                        // List<FieldInfo> infos = DBTypeMap.Instance.GetInfoByGuid(header.GUID);
                        if (!CanDecode(packed))
                        {
                            // we don't have an entry for this yet; try out the ones we have
                            List <TypeInfo> allInfos = DBTypeMap.Instance.GetAllInfos(typename);
                            if (allInfos.Count > 0)
                            {
                                // TryDecode(packed, header, allInfos);
                            }
                            else
                            {
                                Console.WriteLine("no info at all for {0}", typename);
                            }
                        }
                        else
                        {
                            Console.WriteLine("already have info for {0}", header.GUID);
                        }
                    }
                }
            }
        }
예제 #2
0
 private void OptimizePack(object sender, EventArgs e)
 {
     if (!DBTypeMap.Instance.Initialized)
     {
         DBTypeMap.Instance.InitializeTypeMap(Path.GetDirectoryName(Application.ExecutablePath));
     }
     if (SelectedMod != null)
     {
         if (!File.Exists(SelectedMod.PackFilePath))
         {
             MessageBox.Show(string.Format("Pack file for mod \"{0}\" not found ", SelectedMod.Name));
             return;
         }
         else if (!QueryIgnoreEditedModPack())
         {
             return;
         }
         InputBox box = new InputBox {
             Text = "Enter prefix for rename"
         };
         PackFileCodec codec    = new PackFileCodec();
         PackFile      packFile = codec.Open(SelectedMod.PackFilePath);
         if (box.ShowDialog() == DialogResult.OK)
         {
             PackedFileRenamer renamer = new PackedFileRenamer(box.Input);
             renamer.Rename(packFile.Files);
         }
         statusLabel.Text = "Optimizing DB files...";
         Refresh();
         new DbFileOptimizer(Game.STW).CreateOptimizedFile(packFile);
         codec.Save(packFile);
         SetInstallDirectoryLabelText();
     }
 }
예제 #3
0
 public void Connect(PackFileCodec codec)
 {
     codec.HeaderLoaded     += HeaderLoaded;
     codec.PackedFileLoaded += PackedFileLoaded;
     codec.PackFileLoaded   += PackFileLoaded;
     currentCodec            = codec;
 }
예제 #4
0
 public void ExecuteLine(string line)
 {
     if (line.StartsWith("open"))
     {
         SourcePack = new PackFileCodec().Open(line.Substring(5));
         commands.ForEach(c => { c.PackedFiles = SourcePack; });
     }
     else if (line.StartsWith("schema"))
     {
         TypeMapFile = line.Substring(7);
     }
     else if (line.StartsWith("commit"))
     {
         Commit();
     }
     else if (line.StartsWith("save"))
     {
         string filename = line.Substring(5);
         if (File.Exists(filename))
         {
             TargetPack = new PackFileCodec().Open(filename);
         }
         else
         {
             TargetPack = new PackFile(filename, new PFHeader("PFH4")
             {
                 Type = PackType.Mod
             });
         }
     }
     else if (line.StartsWith("script"))
     {
         string filename = line.Substring(7);
         if (File.Exists(filename))
         {
             Script included = new Script {
                 SourcePack = this.SourcePack,
                 TargetPack = this.TargetPack
             };
             included.commands.AddRange(commands);
             foreach (string fileLine in File.ReadAllLines(filename))
             {
                 included.ExecuteLine(fileLine);
             }
             SourcePack = included.SourcePack;
             TargetPack = included.TargetPack;
             commands   = included.commands;
         }
     }
     else if (!line.StartsWith("#") && !string.IsNullOrEmpty(line.Trim()))
     {
         try {
             SqlCommand command = ParseCommand(line);
             command.Execute();
             commands.Add(command);
         } catch (Exception e) {
             Console.WriteLine("Failed to execute '{0}': {1}", line, e);
         }
     }
 }
        public FieldCorrespondencyFinder(string packFile, string xmlDir)
        {
            xmlDirectory = xmlDir;
            DBTypeMap.Instance.InitializeTypeMap(Directory.GetCurrentDirectory());
            // initialize patchFileValues from pack file
            PackFile pack = new PackFileCodec().Open(packFile);

            foreach (PackedFile contained in pack.Files)
            {
                if (contained.FullPath.StartsWith("db"))
                {
                    // no need to resolve if it's done already...
                    string tableName = DBFile.Typename(contained.FullPath).Replace("_tables", "");
                    try {
                        PackedFileDbCodec codec = PackedFileDbCodec.GetCodec(contained);
                        codec.AutoadjustGuid = false;
                        DBFile dbFile = codec.Decode(contained.Data);

                        MappedDataTable table = new MappedDataTable(tableName);
                        ValuesFromPack(table, dbFile);
                        ValuesFromXml(table);

                        mappedTables[tableName] = table;
#if DEBUG
                    } catch (Exception e) {
                        Console.Error.WriteLine(e.Message);
                    }
#else
                    } catch { }
예제 #6
0
 void CheckReferences()
 {
     foreach (Game game in games)
     {
         if (!game.IsInstalled)
         {
             continue;
         }
         List <ReferenceChecker> checkers = ReferenceChecker.CreateCheckers();
         foreach (string packPath in Directory.GetFiles(game.DataDirectory, "*pack"))
         {
             Console.WriteLine("adding {0}", packPath);
             PackFile packFile = new PackFileCodec().Open(packPath);
             foreach (ReferenceChecker checker in checkers)
             {
                 checker.PackFiles.Add(packFile);
             }
         }
         Console.WriteLine();
         Console.Out.Flush();
         foreach (ReferenceChecker checker in checkers)
         {
             checker.CheckReferences();
             Dictionary <PackFile, CheckResult> result = checker.FailedResults;
             foreach (PackFile pack in result.Keys)
             {
                 CheckResult r = result[pack];
                 Console.WriteLine("pack {0} failed reference from {1} to {2}",
                                   pack.Filepath, r.ReferencingString, r.ReferencedString, string.Join(",", r.UnfulfilledReferences));
             }
         }
     }
 }
예제 #7
0
        // tests all files in this test's pack
        public static void TestAllFiles(ICollection <PackedFileTest> tests, string packFilePath, bool verbose)
        {
            PackFile packFile = new PackFileCodec().Open(packFilePath);

            foreach (PackedFile packed in packFile.Files)
            {
                if (verbose)
                {
                    Console.WriteLine("Testing {0}", packed.FullPath);
                }
                foreach (PackedFileTest test in tests)
                {
                    try {
                        if (test.CanTest(packed))
                        {
                            test.TestFile(packed);
                        }
                    } catch (Exception x) {
                        using (var outstream = File.Create(string.Format("failed_{0}.packed", packed.Name))) {
                            using (var datastream = new MemoryStream(packed.Data)) {
                                datastream.CopyTo(outstream);
                            }
                        }
                        test.generalErrors.Add(string.Format("reading {0}: {1}", packed.FullPath, x.Message));
                    }
                }
            }
        }
예제 #8
0
        private void CleanUp(object sender, EventArgs e)
        {
            if (SelectedMod != null)
            {
                if (!QueryIgnoreEditedModPack())
                {
                    return;
                }

                if (MessageBox.Show("This will delete the directories 'battleterrain' and 'variantmodels' from your pack. " +
                                    "Do not do this if you changed anything there.\nContinue?", "Confirm cleanup",
                                    MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                {
                    return;
                }

                PackFileCodec codec   = new PackFileCodec();
                PackFile      modPack = codec.Open(SelectedMod.PackFilePath);
                foreach (VirtualDirectory dir in modPack.Root.Subdirectories)
                {
                    if (dir.Name.Equals("battleterrain") || dir.Name.Equals("variantmodels"))
                    {
                        dir.Deleted = true;
                    }
                }
                if (modPack.Root.Modified)
                {
                    string tempFilePath = Path.GetTempFileName();
                    codec.WriteToFile(tempFilePath, modPack);
                    File.Delete(SelectedMod.PackFilePath);
                    File.Move(tempFilePath, SelectedMod.PackFilePath);
                }
            }
        }
예제 #9
0
 void Connect(PackFileCodec codec, string f)
 {
     lock (this.codec)
         this.codec.Add(f, codec);
     codec.HeaderLoaded     += HeaderLoaded;
     codec.PackedFileLoaded += PackedFileLoaded;
     codec.PackFileLoaded   += PackFileLoaded;
 }
예제 #10
0
 public void ConnectPackCodec(PackFileCodec codec, string f)
 {
     progressReporter.ReportProgressAsync(() =>
     {
         progress.Minimum = 0;
         progress.Value   = 0;
     });
     Connect(codec, f);
 }
예제 #11
0
 public void Disconnect()
 {
     if (currentCodec != null)
     {
         currentCodec.HeaderLoaded     -= HeaderLoaded;
         currentCodec.PackedFileLoaded -= PackedFileLoaded;
         currentCodec.PackFileLoaded   -= PackFileLoaded;
         currentCodec = null;
     }
 }
예제 #12
0
 public LoadUpdater(PackFileCodec codec, string f, ToolStripLabel l, ToolStripProgressBar bar)
 {
     file        = Path.GetFileName(f);
     label       = l;
     progress    = bar;
     bar.Minimum = 0;
     bar.Value   = 0;
     bar.Step    = 10;
     Connect(codec);
 }
예제 #13
0
        public void InstallCurrentMod()
        {
            if (CurrentMod == null)
            {
                throw new InvalidOperationException("No mod set");
            }
            string targetDir = CurrentMod.Game.GameDirectory;

            if (targetDir == null)
            {
                throw new FileNotFoundException(string.Format("Game install directory not found"));
            }
            targetDir = Path.Combine(targetDir, "data");
            if (File.Exists(CurrentMod.FullModPath) && Directory.Exists(targetDir))
            {
                string installPackName = CurrentMod.PackName;
                if (installPackName.Contains(' ') && GameManager.Instance.CurrentGame == Game.R2TW)
                {
                    if (MessageBox.Show(MOD_SPACE_MESSAGE, "Invalid pack file name", MessageBoxButtons.YesNo)
                        == DialogResult.Yes)
                    {
                        installPackName = installPackName.Replace(' ', '_');
                    }
                }
                string targetFile = Path.Combine(targetDir, installPackName);

                // copy to data directory
                File.Copy(CurrentMod.FullModPath, targetFile, true);

                // add entry to user.script.txt if it's a mod file
                PFHeader header = PackFileCodec.ReadHeader(targetFile);
                if (header.Type == PackType.Mod)
                {
                    string        modEntry     = CurrentMod.ModScriptFileEntry;
                    string        scriptFile   = GameManager.Instance.CurrentGame.ScriptFile;
                    List <string> linesToWrite = new List <string>();
                    if (File.Exists(scriptFile))
                    {
                        // retain all other mods in the script file; will add our mod afterwards
                        foreach (string line in File.ReadAllLines(scriptFile, Encoding.Unicode))
                        {
                            if (!line.Contains(modEntry))
                            {
                                linesToWrite.Add(line);
                            }
                        }
                    }
                    if (!linesToWrite.Contains(modEntry))
                    {
                        linesToWrite.Add(modEntry);
                    }
                    File.WriteAllLines(scriptFile, linesToWrite, Encoding.Unicode);
                }
            }
        }
예제 #14
0
 /*
  * Lists the contents of the given pack file.
  * List parameter is ignored.
  */
 void ListPack(string packFileName, List <string> containedFiles)
 {
     try {
         PackFile pack = new PackFileCodec().Open(packFileName);
         foreach (PackedFile file in pack)
         {
             Console.WriteLine(file.FullPath);
         }
     } catch (Exception e) {
         Console.Error.WriteLine("Failed to list contents of {0}: {1}", packFileName, e.Message);
     }
 }
예제 #15
0
                PackFile getPackFile(ProgressUpdater pu, string gamedatapath, string packPath)
                {
                    string path = System.IO.Path.Combine(gamedatapath, packPath);

                    if (System.IO.File.Exists(path))
                    {
                        PackFileCodec codec = new PackFileCodec();
                        pu.ConnectPackCodec(codec, path.Replace('\\', System.IO.Path.DirectorySeparatorChar));
                        return(codec.Open(path));
                    }
                    else
                    {
                        return(null);
                    }
                }
예제 #16
0
        public void FilterExistingPacks()
        {
            if (Directory.Exists(PackDirectory))
            {
                DateTime start = DateTime.Now;
                Console.WriteLine("Retrieving from {0}, storing to {1}", PackDirectory, SchemaFilename);

                maxVersion.Clear();

                // all pack files in game directory
                List <string> files = new List <string>(Directory.EnumerateFiles(PackDirectory, "*.pack"));
                // all files called "*patch*" for backed up earlier packs
                // files.AddRange(Directory.EnumerateFiles(PackDirectory, "*.patch*"));

                foreach (string path in files)
                {
                    try {
                        PackFile pack = new PackFileCodec().Open(path);
                        // only use CA packs
                        if (pack.Type != PackType.Release && pack.Type != PackType.Patch)
                        {
                            Console.WriteLine("not handling {0}", path);
                            continue;
                        }
                        GetUsedTypes(pack);
                    } catch (Exception e) {
                        Console.WriteLine("Not able to include {0} into schema: {1}", path, e);
                    }
                }

                List <TypeVersionTuple> asTuples = new List <TypeVersionTuple>();
                foreach (string s in maxVersion.Keys)
                {
                    asTuples.Add(new TypeVersionTuple {
                        Type = s, MaxVersion = maxVersion[s]
                    });
                }
                using (var stream = File.Create(SchemaFilename)) {
                    XmlSerializer serializer = new XmlSerializer(asTuples.GetType());
                    serializer.Serialize(stream, asTuples);
                }

                DateTime end = DateTime.Now;
                Console.WriteLine("optimization took {0}", end.Subtract(start));
            }
        }
예제 #17
0
        public void ImportExistingPack(string packFileName)
        {
            string modName = PACK_FILE_RE.Replace(Path.GetFileName(packFileName), "");

            // trigger creation of backup folder
            new Mod(modName);
            MultiMods.Instance.AddMod(modName);

            PackFile pack = new PackFileCodec().Open(packFileName);

            foreach (PackedFile packed in pack)
            {
                // extract to working_data as binary
                List <string> extractPaths = new List <string>();
                byte[]        data         = null;
                if (DBTypeMap.Instance.IsSupported(DBFile.typename(packed.FullPath)))
                {
                    PackedFileDbCodec codec       = PackedFileDbCodec.GetCodec(packed);
                    Codec <DBFile>    writerCodec = new ModToolDBCodec(FieldMappingManager.Instance);
                    DBFile            dbFile      = codec.Decode(packed.Data);
                    using (var stream = new MemoryStream()) {
                        writerCodec.Encode(stream, dbFile);
                        data = stream.ToArray();
                    }
                    string extractFilename = string.Format("{0}.xml", packed.Name);
                    extractPaths.Add(Path.Combine(ModTools.Instance.InstallDirectory, "raw_data", "db", extractFilename));
                    extractPaths.Add(Path.Combine(ModTools.Instance.RawDataPath, "EmpireDesignData", "db", extractFilename));
                }
                else
                {
                    extractPaths.Add(Path.Combine(ModTools.Instance.WorkingDataPath, packed.FullPath));
                    data = packed.Data;
                }
                foreach (string path in extractPaths)
                {
                    string extractDir = Path.GetDirectoryName(path);
                    if (!Directory.Exists(extractDir))
                    {
                        Directory.CreateDirectory(extractDir);
                    }
                    File.WriteAllBytes(path, data);
                }
            }
        }
예제 #18
0
 private List <PackedFile> ReadPackageFile(string fileName)
 {
     try
     {
         if (File.Exists(fileName))
         {
             PackFileCodec codec = new PackFileCodec();
             return(codec.Open(fileName).Files);
         }
         else
         {
             return(new List <PackedFile>());
         }
     }
     catch (Exception exception1)
     {
         MessageBox.Show(exception1.ToString(), "读取文件[" + fileName + "]出错了", MessageBoxButtons.OK, MessageBoxIcon.Hand);
         return(new List <PackedFile>());
     }
 }
예제 #19
0
        void Disconnect(string f)
        {
            PackFileCodec codec = this.codec[f];

            codec.HeaderLoaded     -= HeaderLoaded;
            codec.PackedFileLoaded -= PackedFileLoaded;
            codec.PackFileLoaded   -= PackFileLoaded;
            lock (this.codec)
            {
                this.codec.Remove(f);
                if (this.codec.Count == 0)
                {
                    progressReporter.ReportProgressAsync(() =>
                    {
                        label.Text     = "Done loading all packs.";
                        progress.Value = progress.Maximum;
                    });
                }
            }
        }
예제 #20
0
 /*
  * Updates the given pack file, adding the files from the given list.
  * Will replace files already present in the pack when the replace parameter is true (default).
  */
 void UpdatePack(string packFileName, List <string> toAdd, bool replace)
 {
     try {
         PackFile toUpdate = new PackFileCodec().Open(packFileName);
         foreach (string file in toAdd)
         {
             try {
                 HandlingFile(file);
                 toUpdate.Add(new PackedFile(file), replace);
             } catch (Exception e) {
                 Console.Error.WriteLine("Failed to add {0}: {1}", file, e.Message);
             }
         }
         string tempFile = Path.GetTempFileName();
         new PackFileCodec().WriteToFile(tempFile, toUpdate);
         File.Delete(packFileName);
         File.Move(tempFile, packFileName);
     } catch (Exception e) {
         Console.Error.WriteLine("Failed to update {0}: {1}", packFileName, e.Message);
     }
 }
예제 #21
0
        /*
         * Unpacks the given files from the given pack file, or all if contained files list is empty.
         */
        void ExtractPack(string packFileName, List <string> containedFiles)
        {
            PackFile pack = new PackFileCodec().Open(packFileName);

            foreach (string entryPath in containedFiles)
            {
                try {
                    PackEntry entry = pack[entryPath];
                    if (entry is VirtualDirectory)
                    {
                        VirtualDirectory directory = entry as VirtualDirectory;
                        directory.AllFiles.ForEach(f => ExtractPackedFile(f));
                    }
                    else
                    {
                        ExtractPackedFile(entry as PackedFile);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("Failed to extract {0}: {1}", entryPath, e.Message);
                }
            }
        }
예제 #22
0
 /*
  * Add db files from given pack to the packedFiles dictionary.
  */
 private void LoadDbFiles()
 {
     if (VerifyAgainst != null)
     {
         Console.WriteLine("building pack file cache");
         foreach (string file in new PackLoadSequence().GetPacksLoadedFrom(VerifyAgainst.GameDirectory))
         {
             PackFile pack = new PackFileCodec().Open(file);
             foreach (PackedFile packed in pack)
             {
                 Console.WriteLine("loading {0}", packed.FullPath);
                 if (packed.FullPath.StartsWith("db"))
                 {
                     string typename = DBFile.Typename(packed.FullPath);
                     if (!packedFiles.ContainsKey(typename))
                     {
                         packedFiles[typename] = packed;
                     }
                 }
             }
         }
     }
 }
예제 #23
0
        public static void Main(string[] args)
        {
            PackFile exported    = null;
            bool     showManager = (args.Length > 0 && args[0].Equals("-g"));

            if (showManager)
            {
                DBTableDisplay display = new DBTableDisplay();
                display.ShowDialog();
            }
            else
            {
                bool export = (args.Length > 0 && args[0].Equals("-x"));
                Console.WriteLine("exporting undecoded to file");
                exported = new PackFile("undecoded.pack", new PFHeader("PFH4"));
                DBTypeMap.Instance.initializeFromFile("master_schema.xml");
                foreach (Game game in Game.Games)
                {
                    LoadGameLocationFromFile(game);
                    if (game.IsInstalled)
                    {
                        foreach (string packFileName in Directory.EnumerateFiles(game.DataDirectory, "*pack"))
                        {
                            Console.WriteLine("checking {0}", packFileName);
                            PackFile packFile = new PackFileCodec().Open(packFileName);
                            foreach (VirtualDirectory dir in packFile.Root.Subdirectories.Values)
                            {
                                if (dir.Name.Equals("db"))
                                {
                                    foreach (PackedFile dbFile in dir.AllFiles)
                                    {
                                        if (dbFile.Name.Contains("models_naval"))
                                        {
                                            continue;
                                        }
                                        // DBFileHeader header = PackedFileDbCodec.readHeader(dbFile);
                                        DBFile       decoded = PackedFileDbCodec.Decode(dbFile);
                                        DBFileHeader header  = PackedFileDbCodec.readHeader(dbFile);
                                        if (decoded == null && header.EntryCount != 0)
                                        {
                                            Console.WriteLine("failed to read {0} in {1}", dbFile.FullPath, packFile);
                                            if (export)
                                            {
                                                String     exportFileName = String.Format("db/{0}_{1}_{2}", game.Id, dbFile.Name, Path.GetFileName(packFileName)).ToLower();
                                                PackedFile exportedDbFile = new PackedFile(exportFileName, false)
                                                {
                                                    Data = dbFile.Data
                                                };
                                                exported.Add(exportedDbFile);
                                            }
                                            else
                                            {
                                                string key     = DBFile.Typename(dbFile.FullPath);
                                                bool   unicode = false;
                                                if (game == Game.ETW ||
                                                    game == Game.NTW ||
                                                    game == Game.STW)
                                                {
                                                    unicode = true;
                                                }
                                                DecodeTool.DecodeTool decoder = new DecodeTool.DecodeTool(unicode)
                                                {
                                                    TypeName = key,
                                                    Bytes    = dbFile.Data
                                                };
                                                decoder.ShowDialog();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (export)
                        {
                            new PackFileCodec().Save(exported);
                        }
                    }
                    else
                    {
                        Console.Error.WriteLine("Game {0} not installed in {1}", game, game.GameDirectory);
                    }
                }
            }
        }
예제 #24
0
        void TestAll(string[] args)
        {
            IEnumerable <string> arguments = args;

            if (args.Length == 0)
            {
                if (File.Exists(OPTIONS_FILENAME))
                {
                    arguments = File.ReadAllLines(OPTIONS_FILENAME);
                }
                else
                {
                    Console.Error.Write("Missing options; use file {0}", OPTIONS_FILENAME);
                    return;
                }
            }

            // make sure R2 knows its directory (no autodetect)
            if (File.Exists("gamedir_r2tw.txt"))
            {
                Game.R2TW.GameDirectory = File.ReadAllText("gamedir_r2tw.txt").Trim();
            }

            foreach (string dir in arguments)
            {
                if (dir.StartsWith("#") || dir.Trim().Equals(""))
                {
                    continue;
                }
                //CaFieldInfo inf;
                if (dir.StartsWith("-g"))
                {
                    games.Clear();
                    string gamesArg = dir.Substring(2);
                    if ("ALL".Equals(gamesArg))
                    {
                        games.AddRange(Game.Games);
                    }
                    else
                    {
                        string[] gameIds = gamesArg.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string gameId in gameIds)
                        {
                            games.Add(Game.ById(gameId));
                        }
                    }
                }
                else if (dir.Equals("-v"))
                {
                    Console.WriteLine("Running in verbose mode");
                    verbose = true;
                }
                else if (dir.Equals("-cr"))
                {
                    CheckReferences();
                }
                else if (dir.Equals("-x"))
                {
                    waitForKey = false;
                }
                else if (dir.StartsWith("-tm"))
                {
                    string typeMapFile = dir.Substring(3);
                    DBTypeMap.Instance.initializeFromFile(typeMapFile);
                }
                else if (dir.Equals("-t"))
                {
                    Console.WriteLine("TSV export/import enabled");
                    testTsvExport = true;
                }
                else if (dir.Equals("-db"))
                {
                    Console.WriteLine("Database Test enabled");
                    testFactories.Add(CreateDbTest);
                }
                else if (dir.Equals("-uv"))
                {
                    Console.WriteLine("Unit Variant Test enabled");
                    testFactories.Add(CreateUnitVariantTest);
                }
                else if (dir.StartsWith("-gf"))
                {
                    Console.WriteLine("Group formations test enabled");
                    GroupformationTest test = new GroupformationTest();
                    test.testFile(dir.Split(" ".ToCharArray())[1].Trim());
                }
                else if (dir.Equals("-ot"))
                {
                    outputTables = true;
                    Console.WriteLine("will output tables of db files");
                }
                else if (dir.StartsWith("-tg"))
                {
                    foreach (Game game in games)
                    {
                        Console.WriteLine("Testing game {0}", game.Id);
                        PackedFileTest.TestAllPacks(testFactories, Path.Combine(game.DataDirectory), verbose);
                    }
                }
                else if (dir.StartsWith("-dg"))
                {
                    string        file   = dir.Substring(3);
                    PackFile      pack   = null;
                    List <string> tables = new List <string>();
                    foreach (string line in File.ReadAllLines(file))
                    {
                        if (pack == null)
                        {
                            pack = new PackFileCodec().Open(line);
                        }
                        else
                        {
                            tables.Add(line);
                        }
                    }
                    DumpAllGuids(pack, tables);
                }
                else
                {
                    PackedFileTest.TestAllPacks(testFactories, dir, verbose);
                }
            }
            if (waitForKey)
            {
                Console.WriteLine("Test run finished, press any key");
                Console.ReadKey();
            }
        }
        public void Export(IList <GameVersion> versions)
        {
            // master_schema.xml is managed in the solution and copied to the bin root
            // so use "" as the basepath
            DBTypeMap.Instance.InitializeTypeMap("");

            var codec = new PackFileCodec();

            _dataPack     = new Dictionary <string, List <PackFile> >();
            _localPack    = new Dictionary <string, List <PackFile> >();
            _loadedTables = new Dictionary <string, DataTable>();

            foreach (var v in versions)
            {
                var exportDir = $"{Common.DataPath}/Export/{v.Id}";
                if (Directory.Exists(exportDir))
                {
                    Console.WriteLine($"[SKIP] Version {v.Name} already exists");
                    continue;
                }

                Console.WriteLine($"[EXPORT] Version {v.Name}");

                bool isTWW = (v.Game == Game.TWW || v.Game == Game.TWW2);

                // For Mods, first load the latest version packs
                if (!isTWW)
                {
                    var latestVersion = versions.First(ver => ver.Game == Game.TWW2);
                    foreach (var packFile in Directory.GetFiles(latestVersion.Data, "data*.pack"))
                    {
                        if (_dataPack.ContainsKey(v.Id))
                        {
                            _dataPack[v.Id].Add(codec.Open(packFile));
                        }
                        else
                        {
                            _dataPack[v.Id] = new List <PackFile> {
                                codec.Open(packFile)
                            }
                        };
                    }
                    foreach (var packFile in Directory.GetFiles(latestVersion.Data, "local*.pack"))
                    {
                        if (_localPack.ContainsKey(v.Id))
                        {
                            _localPack[v.Id].Add(codec.Open(packFile));
                        }
                        else
                        {
                            _localPack[v.Id] = new List <PackFile> {
                                codec.Open(packFile)
                            }
                        };
                    }
                }

                var dataPackPattern  = v.Game != Game.TWW2 ? "*.pack" : "data*.pack";
                var localPackPattern = v.Game != Game.TWW2 ? "*.pack" : "local*.pack";
                foreach (var packFile in Directory.GetFiles(v.Data, dataPackPattern))
                {
                    if (_dataPack.ContainsKey(v.Id))
                    {
                        _dataPack[v.Id].Add(codec.Open(packFile));
                    }
                    else
                    {
                        _dataPack[v.Id] = new List <PackFile> {
                            codec.Open(packFile)
                        }
                    };
                }
                foreach (var packFile in Directory.GetFiles(v.Data, localPackPattern))
                {
                    if (_localPack.ContainsKey(v.Id))
                    {
                        _localPack[v.Id].Add(codec.Open(packFile));
                    }
                    else
                    {
                        _localPack[v.Id] = new List <PackFile> {
                            codec.Open(packFile)
                        }
                    };
                }

                // DEBUGING PURPOSES
                //foreach (var p in _localPack[v.Id].Select(p => p.Root))
                //{
                //    foreach (var f in p.AllFiles)
                //    {
                //        byte[] data = f.Data;
                //        using (MemoryStream stream = new MemoryStream(data, 0, data.Length))
                //        {
                //            try
                //            {
                //                var locFile = LocCodec.Instance.Decode(stream);
                //                var found = locFile.Entries.FirstOrDefault(e => e.Localised.Contains("the minimum percentage of armour roll that can be applied"));
                //                if (found != null)
                //                {
                //                    Console.WriteLine($"FOUND IT: {p.Name} - {f.Name} - {found.Tag}");
                //                }
                //            }
                //            catch (Exception) { }
                //        }
                //    }
                //}


                Directory.CreateDirectory($"{exportDir}");

                // Export all xml files from the asssembly_kit if available
                var xmlFiles = Directory.GetFiles(v.Data, "*.xml", SearchOption.AllDirectories).ToList();
                xmlFiles.ForEach(f =>
                {
                    var xml = System.IO.File.ReadAllText(f);

                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xml);

                    var tableName = Path.GetFileNameWithoutExtension(f);
                    var entries   = doc.GetElementsByTagName(tableName).Cast <XmlNode>().Select(o =>
                    {
                        o.Attributes.RemoveAll();
                        foreach (XmlNode child in o.ChildNodes)
                        {
                            child.Attributes.RemoveAll();
                        }
                        return(JsonConvert.SerializeXmlNode(o, Newtonsoft.Json.Formatting.None, true));
                    });

                    string json = $"[{string.Join(',', entries)}]";

                    File.WriteAllText($"{exportDir}/{tableName}.json", json);
                });

                // Export ALL the tables of the db subdirectories
                // Only do this as a fallback if we don't have xml files present (i.e. no assembly kit data)
                if (!xmlFiles.Any())
                {
                    // Load all texts at once because Mods don't name their tables to match the original tables
                    var text = Text(v.Id);

                    _dataPack[v.Id].Select(dp => dp.Root.GetSubdirectory("db")).SelectMany(vd => vd.Subdirectories.Select(s => s.Name)).Distinct().ToList().ForEach(packTableName =>
                    {
                        var realTableName = packTableName.Replace("_tables", "");

                        // DEBUG
                        // if (realTableName != "battle_entities") { return; }

                        // Console.WriteLine($"=== {realTableName} ===");
                        try
                        {
                            var table = Table(v.Id, packTableName);

                            var result = ConvertDataToString(table, text, realTableName);

                            File.WriteAllText($"{exportDir}/{realTableName}.json", result);
                        }
                        catch (Exception e) {
                            Console.WriteLine($"ERROR: Could not process {realTableName}: {e}");
                        }
                    });
                }

                // Export ALL the images in the ui directory and its subdirectories
                _dataPack[v.Id].Select(dp => dp.Root.GetSubdirectory("ui")).ToList().ForEach(vd =>
                {
                    exportImages(vd, exportDir);
                });
            }
        }
예제 #26
0
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.Out.WriteLine("usage: dbcorrect [-cleanup] <packfile>");
                return;
            }
            bool   cleanup        = false;
            String inPackFileName = args[0];

            if (args.Length == 2)
            {
                cleanup = "-cleanup".Equals(args[0]);
                Console.WriteLine("Cleanup enabled (will not add empty db files)");
                inPackFileName = args[1];
            }
            Console.Out.WriteLine("opening {0}", inPackFileName);
            PackFile packFile = new PackFileCodec().Open(inPackFileName);

            String   correctedFileName = inPackFileName.Replace(".pack", "_corrected.pack");
            String   emptyFileName     = inPackFileName.Replace(".pack", "_empty.pack");
            String   missingFileName   = inPackFileName.Replace(".pack", "_unknown.pack");
            PackFile correctedPack     = new PackFile(correctedFileName, packFile.Header);
            PackFile emptyPack         = new PackFile(emptyFileName, packFile.Header);
            PackFile missingPack       = new PackFile(missingFileName, packFile.Header);

            DBTypeMap.Instance.InitializeTypeMap(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
            VirtualDirectory dbDir = packFile.Root.GetSubdirectory("db");

            foreach (PackedFile packedFile in dbDir.AllFiles)
            {
                PackFile targetPack = correctedPack;
                Console.Out.WriteLine(packedFile.FullPath);
                DBFileHeader header    = PackedFileDbCodec.readHeader(packedFile);
                DBFileHeader newHeader = new DBFileHeader(header);
                if (header.EntryCount == 0)
                {
                    emptyPack.Add(packedFile);
                    continue;
                }
                String typeName = DBFile.Typename(packedFile.FullPath);
                byte[] fileData = packedFile.Data;
                // we only accept the exact type/version combination here
                // and only if we don't have to go around trying which one it is (yet)
                var  infos = DBTypeMap.Instance.GetVersionedInfos(typeName, header.Version);
                bool added = false;
                foreach (Filetypes.TypeInfo typeInfo in infos)
                {
                    Console.Out.WriteLine("trying {0}", typeInfo);
                    DBFile newDbFile = new DBFile(newHeader, typeInfo);
                    try {
                        using (BinaryReader reader = new BinaryReader(new MemoryStream(fileData, 0, fileData.Length))) {
                            reader.BaseStream.Position = header.Length;
                            while (reader.BaseStream.Position != fileData.Length)
                            {
                                // try decoding a full row of fields and add it to the new file
                                DBRow newRow = new DBRow(typeInfo);
                                foreach (Filetypes.FieldInfo info in typeInfo.Fields)
                                {
                                    newRow[info.Name].Decode(reader);
                                    //FieldInstance instance = info.CreateInstance();
                                    //instance.Decode(reader);
                                    //newRow.Add(instance);
                                }
                                newDbFile.Entries.Add(newRow);
                            }
                            // all data read successfully!
                            if (newDbFile.Entries.Count == header.EntryCount)
                            {
                                Console.Out.WriteLine("{0}: entry count {1} is correct", packedFile.FullPath, newDbFile.Entries.Count);
#if DEBUG
//                                foreach(DBRow row in newDbFile.Entries) {
//                                    String line = "";
//                                    foreach(FieldInstance instance in row) {
//                                        line += String.Format("{0} - ", line);
//                                    }
//                                    Console.WriteLine(line);
//                                }
#endif
                            }
                            else
                            {
                                Console.Out.WriteLine("{0}: entry count {1} will be corrected to {2}",
                                                      packedFile.FullPath, header.EntryCount, newDbFile.Entries.Count);
                            }
                            if (newDbFile.Entries.Count == 0)
                            {
                                targetPack = emptyPack;
                            }
                            PackedFile        newPackedFile = new PackedFile(packedFile.FullPath, false);
                            PackedFileDbCodec codec         = PackedFileDbCodec.FromFilename(packedFile.FullPath);
                            newPackedFile.Data = codec.Encode(newDbFile);
                            targetPack.Add(newPackedFile);
                            added = true;
                            Console.Out.WriteLine("stored file with {0} entries", newDbFile.Entries.Count);
                            break;
                        }
                    } catch (Exception e) {
                        Console.Error.WriteLine("Will not add {0}: a problem occurred when reading it: {1} at entry {2}",
                                                packedFile.FullPath, e, newDbFile.Entries.Count);
                    }
                }
                if (!added)
                {
                    missingPack.Add(packedFile);
                }
            }
            Console.Out.WriteLine("saving {0}", correctedPack.Filepath);
            PackFileCodec packCodec = new PackFileCodec();
            packCodec.Save(correctedPack);
            packCodec.Save(emptyPack);
            packCodec.Save(missingPack);
        }
        public void Initialize(IList <GameVersion> versions, string typemappath)
        {
            _pks = new List <string> {
                "id", "key", "unit", "unit_key", "unit_class"
            };

            // For reference purposes
            _versions = versions;

            DBTypeMap.Instance.InitializeTypeMap(typemappath);

            var codec = new PackFileCodec();

            _dataPack       = new Dictionary <string, List <PackFile> >();
            _localPack      = new Dictionary <string, List <PackFile> >();
            _loadedTables   = new Dictionary <string, DataTable>();
            _loadedLocFiles = new Dictionary <string, Dictionary <string, string> >();
            foreach (var v in versions)
            {
                foreach (var packFile in Directory.GetFiles(v.Data, "data*.pack"))
                {
                    if (_dataPack.ContainsKey(v.Id))
                    {
                        _dataPack[v.Id].Add(codec.Open(packFile));
                    }
                    else
                    {
                        _dataPack[v.Id] = new List <PackFile> {
                            codec.Open(packFile)
                        }
                    };
                }
                foreach (var packFile in Directory.GetFiles(v.Data, "local*.pack"))
                {
                    if (_localPack.ContainsKey(v.Id))
                    {
                        _localPack[v.Id].Add(codec.Open(packFile));
                    }
                    else
                    {
                        _localPack[v.Id] = new List <PackFile> {
                            codec.Open(packFile)
                        }
                    };
                }

                var dir = $"{Common.DataPath}/Export/{v.Id}";
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);

                    // Export ALL the tables of the db subdirectories
                    var virtualDirectories = _dataPack[v.Id].Select(dp => dp.Root.GetSubdirectory("db"));
                    foreach (var tableName in virtualDirectories.SelectMany(vd => vd.Subdirectories.Select(s => s.Name)).Distinct())
                    {
                        try
                        {
                            var table = Table(v.Id, tableName);
                            var text  = Text(v.Id, tableName.Replace("_tables", ""));

                            var result = ConvertDataToString(GetPk(table), table, text);

                            File.WriteAllText($"{dir}/{tableName}.json", result);
                        } catch (Exception e)
                        {
                            Console.WriteLine($"Failed to export table {tableName}: {e.Message}");
                        }
                    }

                    // Export ALL the images in the ui directory and its subdirectories
                    virtualDirectories = _dataPack[v.Id].Select(dp => dp.Root.GetSubdirectory("ui"));
                    foreach (var vd in virtualDirectories)
                    {
                        exportImages(vd, dir);
                    }
                }
            }
        }