Example #1
0
 public MultiBNKEnumerator(BNKFile vanilla, BNKFile[] patches, string vanillaFilePath, string[] patchPaths)
 {
     VanillaFile = vanilla;
     Patches     = patches;
     VanillaPath = vanillaFilePath;
     PatchPaths  = patchPaths;
 }
Example #2
0
        /// <summary>
        /// Patches all bnk files into the vanilla bnk file.
        /// </summary>
        public void PatchEverything()
        {
            // Set up a list of conflicting WEM files + their corresponding BNK files.
            List <WEMFile> conflictingWEMs  = new List <WEMFile>();
            List <string>  conflictingPaths = new List <string>();
            List <WEMFile> vanillaWEMFiles  = VanillaFile.Marshaller.WEMFiles.ToList();
            int            currentFiles     = 0;

            for (int idx = 0; idx < vanillaWEMFiles.Count; idx++)
            {
                // Reset the conflicting lists since we're reviewing a new WEM file.
                conflictingWEMs.Clear();
                conflictingPaths.Clear();


                WEMFile vanillaWEM = vanillaWEMFiles[idx];
                for (int oidx = 0; oidx < Patches.Length; oidx++)
                {
                    BNKFile otherBnk = Patches[oidx];
                    WEMFile other    = GetWEMInOtherBNKFromID(vanillaWEM, otherBnk);
                    // conflictingWEMs will contain every wem file that isn't the same as the vanilla one.
                    // This means that if the list only has one element, there are no conflicts to resolve.


                    // Surprisingly, this is far faster than I thought it was going to be.
                    // I had initially anticipated it to take at least a minute to process all of this data, but my implementation proved sturdy.
                    // It can process multiple BNKs in a matter of about a second.
                    // I suppose this is the benefit of my storage method: Spend a lot of time constructing a representation once, Save time indexing the data later.
                    // Given how I overloaded (in)equality in WEMFile, this is alarmingly fast.
                    if (vanillaWEM != other)
                    {
                        conflictingWEMs.Add(other);
                        conflictingPaths.Add(PatchPaths[oidx]);
                    }
                }

                int targetReplacement = 0;
                if (conflictingPaths.Count > 1)
                {
                    Console.WriteLine();                     // Bump it down for the counter.
                    targetReplacement = ResolveFileConflict(vanillaWEM.ID, conflictingPaths.ToArray());
                }

                if (targetReplacement != -1 && conflictingWEMs.Count != 0)
                {
                    VanillaFile.Marshaller.OverwriteWEMFile(conflictingWEMs[targetReplacement]);
                }
                currentFiles++;
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.Write("Processed {0} files (of {1})", currentFiles, vanillaWEMFiles.Count);
                Console.CursorLeft = 0;
            }
            Console.WriteLine();
        }
Example #3
0
        /// <summary>
        /// Gets a WEM in another BNK archive via its ID.
        /// </summary>
        /// <param name="template">The template WEM file. This should have the ID you want to get inside of its data.</param>
        /// <param name="otherArchive">The other archive to search.</param>
        /// <returns></returns>
        private WEMFile GetWEMInOtherBNKFromID(WEMFile template, BNKFile otherArchive)
        {
            List <WEMFile> otherWemFiles = otherArchive.Marshaller.WEMFiles.ToList();

            for (int idx = 0; idx < otherWemFiles.Count; idx++)
            {
                WEMFile wemFile = otherWemFiles[idx];
                if (wemFile.ID == template.ID)
                {
                    return(wemFile);
                }
            }
            return(null);
        }
Example #4
0
 /// <summary>
 /// Construct a new BNKPatcher, loading an underlying BNK file to edit.
 /// </summary>
 /// <param name="bnkFile">The Stream of the BNK file being patched.</param>
 public BNKPatcher(Stream bnkFile)
 {
     BankFile = new BNKFile(bnkFile);
 }
Example #5
0
        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            string        vanillaBnkPath = null;
            List <string> patchFiles     = new List <string>();

            // [0] = vanilla file
            // [1] = custom file 1
            // [2] = custom file 2
            // [...] = ...
            if (args.Length < 3)
            {
                PopulateDirectoryInfo(out vanillaBnkPath, out patchFiles);
            }
            else
            {
                vanillaBnkPath = args[0];
                if (!File.Exists(vanillaBnkPath))
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("ERROR: The file you input does not exist!");
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.WriteLine("Failed to find: " + vanillaBnkPath);
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Press enter to quit...");
                    Console.ReadLine();
                    return;
                }
                foreach (string data in args.Skip(1))
                {
                    if (!File.Exists(data))
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("ERROR: The file you input does not exist!");
                        Console.ForegroundColor = ConsoleColor.DarkRed;
                        Console.WriteLine("Failed to find: " + data);
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Press enter to quit...");
                        Console.ReadLine();
                        return;
                    }
                    patchFiles.Add(data);
                }
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Loading up all of the BNK files. This might take a bit to complete. Lots of data to go through!");
            Console.WriteLine("Opening files...");


            FileStream vanillaBnk = File.OpenRead(vanillaBnkPath);

            FileStream[] otherBnks = new FileStream[patchFiles.Count];
            for (int idx = 0; idx < patchFiles.Count; idx++)
            {
                otherBnks[idx] = File.OpenRead(patchFiles[idx]);
            }

            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("Processing BNK File: {0}", vanillaBnkPath);

            BNKFile[] otherBnkObjects = new BNKFile[otherBnks.Length];
            BNKFile   vanillaFile     = new BNKFile(vanillaBnk);

            for (int idx = 0; idx < otherBnkObjects.Length; idx++)
            {
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine("Processing BNK File: {0}", patchFiles[idx]);
                otherBnkObjects[idx] = new BNKFile(otherBnks[idx]);
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Done populating BNK files! Enumerating... Please be present so that you may resolve any file conflicts.");

            MultiBNKEnumerator iterator = new MultiBNKEnumerator(vanillaFile, otherBnkObjects, vanillaBnkPath, patchFiles.ToArray());

            iterator.PatchEverything();

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Done enumerating BNK files! Saving in the same directory as the EXE...");


            string     name = "MergedBNK-" + DateTime.Now.ToFileTimeUtc().ToString() + ".BNK";
            FileStream save = File.OpenWrite(@".\" + name);

            iterator.VanillaFile.TranslateToBNKFile(save);
            save.Flush();
            save.Close();


            Console.Write("Saved as ");
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(name);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Press enter to quit.");
            Console.ReadLine();
        }