public SAV3RSBox(byte[] data = null) { Data = data == null ? new byte[SaveUtil.SIZE_G3BOX] : (byte[])data.Clone(); BAK = (byte[])Data.Clone(); Exportable = !Data.SequenceEqual(new byte[Data.Length]); if (SaveUtil.getIsG3BOXSAV(Data) != GameVersion.RSBOX) { return; } Blocks = new RSBOX_Block[2 * BLOCK_COUNT]; for (int i = 0; i < Blocks.Length; i++) { int offset = BLOCK_SIZE + i * BLOCK_SIZE; Blocks[i] = new RSBOX_Block(Data.Skip(offset).Take(BLOCK_SIZE).ToArray(), offset); } // Detect active save int[] SaveCounts = Blocks.Select(block => (int)block.SaveCount).ToArray(); SaveCount = SaveCounts.Max(); int ActiveSAV = Array.IndexOf(SaveCounts, SaveCount) / BLOCK_COUNT; Blocks = Blocks.Skip(ActiveSAV * BLOCK_COUNT).Take(BLOCK_COUNT).OrderBy(b => b.BlockNumber).ToArray(); // Set up PC data buffer beyond end of save file. Box = Data.Length; Array.Resize(ref Data, Data.Length + SIZE_RESERVED); // More than enough empty space. // Copy block to the allocated location foreach (RSBOX_Block b in Blocks) { Array.Copy(b.Data, 0xC, Data, Box + b.BlockNumber * (BLOCK_SIZE - 0x10), b.Data.Length - 0x10); } Personal = PersonalTable.RS; HeldItems = Legal.HeldItems_RS; if (!Exportable) { resetBoxes(); } }