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(); } }
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); }
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()); }
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; }
/// <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; }
private static bool GetIsRanchPlat(byte[] data) => data.Length == SIZE_G4RANCH_PLAT && BigEndian.ToUInt32(data, 0x268C) != 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;
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);