Example #1
0
        /// <summary>
        /// Load a BND4 file into the existing object, overwriting existing data.
        /// </summary>
        /// <param name="filePath"></param>
        public void LoadInPlace(string filePath)
        {
            Utils.Assert(File.Exists(filePath), "File does not exist");

            using (BinReader bin = new BinReader(File.OpenRead(filePath)))
            {
                if (DEBUG)
                {
                    Console.WriteLine("[DEBUG] READ BND4 HEADERS");
                }

                header = bin.ReadStruct <BND4Header>();
                header.AssertIntegrity();
                isUnicode = header.isUnicode;

                entries = new BND4Entry[header.fileCnt];

                for (int i = 0; i < header.fileCnt; i++)
                {
                    if (DEBUG)
                    {
                        Console.WriteLine(string.Format("[DEBUG] READ ENTRY HEADER {0}/{1}", i + 1, header.fileCnt));
                    }

                    entries[i]        = new BND4Entry();
                    entries[i].header = bin.ReadStruct <BND4EntryHeader>();
                    entries[i].header.AssertIntegrity();

                    if (DEBUG)
                    {
                        Console.WriteLine(string.Format("[DEBUG] READ ENTRY NAME {0}/{1}", i + 1, header.fileCnt));
                    }

                    bin.StepInto(entries[i].header.entryNameOffset);
                    entries[i].name = header.isUnicode ? bin.ReadWideString() : bin.ReadShiftJIS();
                    bin.StepOut();

                    if (DEBUG)
                    {
                        Console.WriteLine(string.Format("[DEBUG] READ ENTRY DATA {0}/{1}", i + 1, header.fileCnt));
                    }

                    bin.StepInto(entries[i].header.entryDataOffset);
                    entries[i].data = bin.ReadBytes((int)entries[i].header.entrySize);
                    bin.StepOut();
                }

                if (DEBUG)
                {
                    Console.WriteLine("[DEBUG] READ COMPLETE");
                }
            }
        }
Example #2
0
        /// <summary>
        /// Patch the DS3 account flag that controls if a save can be opened by a user.
        /// </summary>
        /// <param name="steamID"></param>
        public void PatchDS3AccountFlag(ulong steamID)
        {
            if (DEBUG)
            {
                Console.WriteLine("[DEBUG] PATCH MENU ACCOUNT FLAG...");
            }

            BND4Entry menuEntry = entries[10];

            // Overwrite account flag in menu file (Responsible for "Cannot load save" msg on startup)
            byte[] menuData = menuEntry.DecryptData();
            Array.Copy(BitConverter.GetBytes(steamID), 0, menuData, 0x8, 8);
            menuEntry.SetEncryptedData(menuData);
            // Get used save slots bool array to overwrite save-specific account flags
            byte[] usedCharSlots = new byte[10];
            Array.Copy(menuData, 0x1098, usedCharSlots, 0, 10);
            // For each used char. slot, patch its account flag
            for (int i = 0; i < 10; i++)
            {
                if (0 == usedCharSlots[i])
                {
                    continue;
                }
                if (DEBUG)
                {
                    Console.WriteLine("[DEBUG] PATCH ACCOUNT FLAG CHAR #" + i.ToString());
                }

                byte[] slotData = entries[i].DecryptData();
                // This offset always seems to go 0x6F under the account flag
                uint flagOffset = BitConverter.ToUInt32(slotData, 0x58) + 0x6F;
                Array.Copy(BitConverter.GetBytes(steamID), 0, slotData, flagOffset, 8);
                entries[i].SetEncryptedData(slotData);
            }

            if (DEBUG)
            {
                Console.WriteLine("[DEBUG] ACCOUNT FLAG PATCHED");
            }
        }