示例#1
0
文件: SAV4BR.cs 项目: wbsr9876/PKHeX
        public static void SetChecksum(byte[] input, int offset, int len, int checksum_offset)
        {
            uint[] storedChecksums = new uint[16];
            for (int i = 0; i < storedChecksums.Length; i++)
            {
                storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + i * 4);
                BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + i * 4);
            }

            uint[] checksums = new uint[16];

            for (int i = 0; i < len; i += 2)
            {
                ushort val = BigEndian.ToUInt16(input, offset + i);
                for (int j = 0; j < 16; j++)
                {
                    checksums[j] += (uint)((val >> j) & 1);
                }
            }

            for (int i = 0; i < checksums.Length; i++)
            {
                BigEndian.GetBytes(checksums[i]).CopyTo(input, checksum_offset + i * 4);
            }
        }
示例#2
0
文件: SAV4BR.cs 项目: wbsr9876/PKHeX
        private static byte[] EncryptPBRSaveData(byte[] input)
        {
            byte[] output = new byte[input.Length];
            for (int base_ofs = 0; base_ofs < SaveUtil.SIZE_G4BR; base_ofs += 0x1C0000)
            {
                Array.Copy(input, base_ofs, output, base_ofs, 8);

                ushort[] keys = new ushort[4];
                for (int i = 0; i < keys.Length; i++)
                {
                    keys[i] = BigEndian.ToUInt16(input, base_ofs + i * 2);
                }

                for (int ofs = base_ofs + 8; ofs < base_ofs + 0x1C0000; ofs += 8)
                {
                    for (int i = 0; i < keys.Length; i++)
                    {
                        ushort val = BigEndian.ToUInt16(input, ofs + i * 2);
                        val += keys[i];
                        BigEndian.GetBytes(val).CopyTo(output, ofs + i * 2);
                    }
                    keys = SaveUtil.AdvanceGCKeys(keys);
                }
            }
            return(output);
        }
示例#3
0
        protected override ushort CalculateChecksum()
        {
            ushort chk = 0;

            for (int i = 8; i < SIZE_STORED; i += 2)
            {
                chk += BigEndian.ToUInt16(Data, i);
            }
            return(chk);
        }
示例#4
0
 public void getPouchBigEndian(ref byte[] Data)
 {
     InventoryItem[] items = new InventoryItem[PouchDataSize];
     for (int i = 0; i < items.Length; i++)
     {
         items[i] = new InventoryItem
         {
             Index = BigEndian.ToUInt16(Data, Offset + i * 4),
             Count = BigEndian.ToUInt16(Data, Offset + i * 4 + 2) ^ (ushort)SecurityKey
         };
     }
     Items = items;
 }
示例#5
0
文件: SaveUtil.cs 项目: funagi/PKHeX
 internal static byte[] EncryptGC(byte[] input, int start, int end, ushort[] keys)
 {
     byte[] output = (byte[])input.Clone();
     for (int ofs = start; ofs < end; ofs += 8)
     {
         for (int i = 0; i < keys.Length; i++)
         {
             ushort val = BigEndian.ToUInt16(input, ofs + i * 2);
             val += keys[i];
             BigEndian.GetBytes(val).CopyTo(output, ofs + i * 2);
         }
         keys = AdvanceGCKeys(keys);
     }
     return(output);
 }
示例#6
0
        private static byte[] setXDChecksums(byte[] input, int subOffset0)
        {
            if (input.Length != 0x28000)
            {
                throw new ArgumentException("Input should be a slot, not the entire save binary.");
            }

            byte[]    data  = (byte[])input.Clone();
            const int start = 0xA8; // 0x88 + 0x20

            // Header Checksum
            int newHC = 0;

            for (int i = 0; i < 8; i++)
            {
                newHC += data[i];
            }

            BigEndian.GetBytes(newHC).CopyTo(data, start + subOffset0 + 0x38);

            // Body Checksum
            new byte[16].CopyTo(data, 0x10); // Clear old Checksum Data
            uint[] checksum = new uint[4];
            int    dt       = 8;

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 0x9FF4; j += 2, dt += 2)
                {
                    checksum[i] += BigEndian.ToUInt16(data, dt);
                }
            }

            ushort[] newchks = new ushort[8];
            for (int i = 0; i < 4; i++)
            {
                newchks[i * 2]     = (ushort)(checksum[i] >> 16);
                newchks[i * 2 + 1] = (ushort)checksum[i];
            }

            Array.Reverse(newchks);
            for (int i = 0; i < newchks.Length; i++)
            {
                BigEndian.GetBytes(newchks[i]).CopyTo(data, 0x10 + 2 * i);
            }

            return(data);
        }
示例#7
0
        public override byte[] Write(bool DSV)
        {
            // Set Memo Back
            StrategyMemo.FinalData.CopyTo(Data, Memo);
            ShadowInfo.FinalData.CopyTo(Data, Shadow);
            setChecksums();

            // Get updated save slot data
            ushort[] keys = new ushort[4];
            for (int i = 0; i < keys.Length; i++)
            {
                keys[i] = BigEndian.ToUInt16(Data, 8 + i * 2);
            }
            byte[] newSAV = SaveUtil.EncryptGC(Data, 0x10, 0x27FD8, keys);

            // Put save slot back in original save data
            byte[] newFile = (byte[])OriginalData.Clone();
            Array.Copy(newSAV, 0, newFile, SLOT_START + SaveIndex * SLOT_SIZE, newSAV.Length);
            return(Header.Concat(newFile).ToArray());
        }
示例#8
0
        public SAV3XD(byte[] data = null)
        {
            Data       = data == null ? new byte[SaveUtil.SIZE_G3XD] : (byte[])data.Clone();
            BAK        = (byte[])Data.Clone();
            Exportable = !Data.SequenceEqual(new byte[Data.Length]);

            if (SaveUtil.getIsG3XDSAV(Data) != GameVersion.XD)
            {
                return;
            }

            OriginalData = (byte[])Data.Clone();

            // Scan all 3 save slots for the highest counter
            for (int i = 0; i < SLOT_COUNT; i++)
            {
                int slotOffset  = SLOT_START + i * SLOT_SIZE;
                int SaveCounter = BigEndian.ToInt32(Data, slotOffset + 4);
                if (SaveCounter <= SaveCount)
                {
                    continue;
                }

                SaveCount = SaveCounter;
                SaveIndex = i;
            }

            // Decrypt most recent save slot
            {
                byte[] slot       = new byte[SLOT_SIZE];
                int    slotOffset = SLOT_START + SaveIndex * SLOT_SIZE;
                Array.Copy(Data, slotOffset, slot, 0, slot.Length);

                ushort[] keys = new ushort[4];
                for (int i = 0; i < keys.Length; i++)
                {
                    keys[i] = BigEndian.ToUInt16(slot, 8 + i * 2);
                }

                // Decrypt Slot
                Data = SaveUtil.DecryptGC(slot, 0x00010, 0x27FD8, keys);
            }

            // Get Offset Info
            ushort[] subLength = new ushort[16];
            for (int i = 0; i < 16; i++)
            {
                subLength[i]  = BigEndian.ToUInt16(Data, 0x20 + 2 * i);
                subOffsets[i] = BigEndian.ToUInt16(Data, 0x40 + 4 * i) | BigEndian.ToUInt16(Data, 0x40 + 4 * i + 2) << 16;
            }
            // Offsets are displaced by the 0xA8 savedata region
            Trainer1 = subOffsets[1] + 0xA8;
            Party    = Trainer1 + 0x30;
            Box      = subOffsets[2] + 0xA8;
            Daycare  = subOffsets[4] + 0xA8;
            Memo     = subOffsets[5] + 0xA8;
            Shadow   = subOffsets[7] + 0xA8;
            // Purifier = subOffsets[14] + 0xA8;

            StrategyMemo = new StrategyMemo(Data, Memo, xd: true);
            ShadowInfo   = new ShadowInfoTableXD(Data.Skip(Shadow).Take(subLength[7]).ToArray());

            OFS_PouchHeldItem = Trainer1 + 0x4C8;
            OFS_PouchKeyItem  = Trainer1 + 0x540;
            OFS_PouchBalls    = Trainer1 + 0x5EC;
            OFS_PouchTMHM     = Trainer1 + 0x62C;
            OFS_PouchBerry    = Trainer1 + 0x72C;
            OFS_PouchCologne  = Trainer1 + 0x7E4;
            OFS_PouchDisc     = Trainer1 + 0x7F0;

            LegalItems    = Legal.Pouch_Items_XD;
            LegalKeyItems = Legal.Pouch_Key_XD;
            LegalBalls    = Legal.Pouch_Ball_RS;
            LegalTMHMs    = Legal.Pouch_TM_RS; // not HMs
            LegalBerries  = Legal.Pouch_Berries_RS;
            LegalCologne  = Legal.Pouch_Cologne_CXD;
            LegalDisc     = Legal.Pouch_Disc_XD;

            Personal  = PersonalTable.RS;
            HeldItems = Legal.HeldItems_XD;

            if (!Exportable)
            {
                resetBoxes();
            }

            // Since PartyCount is not stored in the save file,
            // Count up how many party slots are active.
            for (int i = 0; i < 6; i++)
            {
                if (getPartySlot(getPartyOffset(i)).Species != 0)
                {
                    PartyCount++;
                }
            }
        }