예제 #1
0
        public SAV4BR(byte[] data = null)
        {
            Data       = data ?? new byte[SaveUtil.SIZE_G4BR];
            BAK        = (byte[])Data.Clone();
            Exportable = !IsRangeEmpty(0, Data.Length);

            if (SaveUtil.GetIsG4BRSAV(Data) != GameVersion.BATREV)
            {
                return;
            }

            Data = DecryptPBRSaveData(data);

            // Detect active save
            SaveCount = Math.Max(BigEndian.ToUInt32(Data, 0x1C004C), BigEndian.ToUInt32(Data, 0x4C));
            if (BigEndian.ToUInt32(Data, 0x1C004C) > BigEndian.ToUInt32(Data, 0x4C))
            {
                byte[] tempData = new byte[0x1C0000];
                Array.Copy(Data, 0, tempData, 0, 0x1C0000);
                Array.Copy(Data, 0x1C0000, Data, 0, 0x1C0000);
                tempData.CopyTo(Data, 0x1C0000);
            }

            for (int i = 0; i < SAVE_COUNT; i++)
            {
                if (!IsOTNamePresent(i))
                {
                    continue;
                }
                SaveSlots.Add(i);
                SaveNames.Add(GetOTName(i).Trim());
            }

            CurrentSlot = SaveSlots[0];

            Personal  = PersonalTable.DP;
            HeldItems = Legal.HeldItems_DP;

            if (!Exportable)
            {
                ClearBoxes();
            }
        }
예제 #2
0
        private byte[] GetInnerData()
        {
            // Set Memo Back
            StrategyMemo.Write().CopyTo(Data, Memo);
            ShadowInfo.Write().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 = GCSaveUtil.Encrypt(Data, 0x10, 0x27FD8, keys);

            // Put save slot back in original save data
            byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[])BAK.Clone();
            Array.Copy(newSAV, 0, newFile, SLOT_START + (SaveIndex * SLOT_SIZE), newSAV.Length);
            return(newFile);
        }
예제 #3
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());
        }
예제 #4
0
파일: SAV4BR.cs 프로젝트: sutiam/PKHeX
        private void InitializeData(byte[] data)
        {
            Data = DecryptPBRSaveData(data);

            // Detect active save
            var first  = BigEndian.ToUInt32(Data, 0x00004C);
            var second = BigEndian.ToUInt32(Data, 0x1C004C);

            SaveCount = Math.Max(second, first);
            if (second > first)
            {
                // swap halves
                byte[] tempData = new byte[0x1C0000];
                Array.Copy(Data, 0, tempData, 0, 0x1C0000);
                Array.Copy(Data, 0x1C0000, Data, 0, 0x1C0000);
                tempData.CopyTo(Data, 0x1C0000);
            }

            var names = (string[])SaveNames;

            for (int i = 0; i < SAVE_COUNT; i++)
            {
                var name = GetOTName(i);
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = $"Empty {i + 1}";
                }
                else if (_currentSlot == -1)
                {
                    _currentSlot = i;
                }
                names[i] = name;
            }

            if (_currentSlot == -1)
            {
                _currentSlot = 0;
            }

            CurrentSlot = _currentSlot;
        }
예제 #5
0
        /// <summary>Checks to see if the data belongs to a Gen3 Box RS save</summary>
        /// <param name="data">Save data of which to determine the type</param>
        /// <returns>Version Identifier or Invalid if type cannot be determined.</returns>
        internal static GameVersion GetIsG3BOXSAV(byte[] data)
        {
            if (data.Length != SIZE_G3BOX && data.Length != SIZE_G3BOXGCI)
                return Invalid;

            byte[] sav = data;

            // Verify first checksum
            ushort chk = 0; // initial value
            var ofs = data.Length - SIZE_G3BOX + 0x2000;
            for (int i = 0x4; i < 0x1FFC; i += 2)
                chk += BigEndian.ToUInt16(sav, ofs + i);

            ushort chkA = chk;
            ushort chkB = (ushort)(0xF004 - chkA);

            ushort CHK_A = BigEndian.ToUInt16(sav, ofs + 0);
            ushort CHK_B = BigEndian.ToUInt16(sav, ofs + 2);

            return CHK_A == chkA && CHK_B == chkB ? RSBOX : Invalid;
        }
예제 #6
0
 private static bool GetIsRanchPlat(byte[] data) => data.Length == SIZE_G4RANCH_PLAT && BigEndian.ToUInt32(data, 0x268C) != 0;
예제 #7
0
 private static bool GetIsBank3(byte[] data) => data.Length == SIZE_G4BANK && BitConverter.ToUInt32(data, 0x3FC00) == 0; // size collision with ^
 private static bool GetIsRanchDP(byte[] data) => data.Length == SIZE_G4RANCH && BigEndian.ToUInt32(data, 0x22AC) != 0;
예제 #8
0
 private static bool GetIsBank3(byte[] data) => data.Length == SIZE_G4BANK && BitConverter.ToUInt32(data, 0x3FC00) == 0; // size collision with ^
 private static bool GetIsRanch4(byte[] data) => (data.Length == SIZE_G4RANCH && BigEndian.ToUInt32(data, 0x22AC) != 0) || (data.Length == SIZE_G4RANCH_PLAT && BigEndian.ToUInt32(data, 0x268C) != 0);