public SaveData(string path) : base(path) { Logger.Info($"Loading '{path}'"); byte[] bytes = File.ReadAllBytes(path); if (bytes.Length == 9438432) { throw new VanillaSaveGameException("This looks like pre-Iceborne SAVEDATA, which is not supported. Try using an older version of this tool."); } // 0x01 00 00 00 == decrypted, something else means that it's encrypted bool isUnencrypted = bytes[0] == 0x01 && bytes[1] == 0x00 && bytes[2] == 0x00 && bytes[3] == 0x00; if (!isUnencrypted) { var c = new TanukiSharpCrypto(); c.Decrypt(bytes); } using (MemoryStream ms = new MemoryStream(bytes)) using (BinaryReader br = new BinaryReader(ms)) { _header = br.ReadStruct <SaveData_Header>(); if (_header.Magic[0] != 0x01 || _header.Magic[1] != 0x00 || _header.Magic[2] != 0x00 || _header.Magic[3] != 0x00) { throw new Exception("Decryption failed or this isn't a valid SAVEDATA file."); } if (_header.DataSize == 9438368) { throw new VanillaSaveGameException("This looks like pre-Iceborne SAVEDATA, which is not supported. Try using an older version of this tool."); } else if (_header.DataSize != 11284640) { throw new Exception("Unexpected DataSize, meaning that this tool can't load this SAVEDATA."); } _sectionOffsets = new long[4]; _sectionOffsets[0] = br.ReadInt64(); _sectionOffsets[1] = br.ReadInt64(); _sectionOffsets[2] = br.ReadInt64(); _sectionOffsets[3] = br.ReadInt64(); // See misc/savedata_ib.bt _sections = br.ReadBytes(3149948); // Load SaveSlots SaveSlots = new SaveSlot[3]; for (int i = 0; i < 3; i++) { SaveSlots[i] = new SaveSlot(this, ms, i); } } Logger.Info($"Successfully loaded '{path}'"); }
public SaveData(string path) : base(path) { Logger.Info($"Loading '{path}'"); byte[] bytes = File.ReadAllBytes(path); // 0x01 00 00 00 == decrypted, something else means that it's encrypted bool isUnencrypted = bytes[0] == 0x01 && bytes[1] == 0x00 && bytes[2] == 0x00 && bytes[3] == 0x00; if (!isUnencrypted) { // BlowFish decryption is rather slow, maybe C would be faster (using P/Invoke)? bytes = SwapBytes(bytes); bytes = _blowfish.Decrypt_ECB(bytes); bytes = SwapBytes(bytes); } using (MemoryStream ms = new MemoryStream(bytes)) using (BinaryReader br = new BinaryReader(ms)) { _header = br.ReadStruct <SaveData_Header>(); if (_header.Magic[0] != 0x01 || _header.Magic[1] != 0x00 || _header.Magic[2] != 0x00 || _header.Magic[3] != 0x00) { throw new Exception("Decryption failed or this isn't a valid SAVEDATA1000 file."); } _sectionOffsets = new long[4]; _sectionOffsets[0] = br.ReadInt64(); _sectionOffsets[1] = br.ReadInt64(); _sectionOffsets[2] = br.ReadInt64(); _sectionOffsets[3] = br.ReadInt64(); // There are 3 unk blocks here, to keep things simple we combine it into one block for now _unk1 = br.ReadBytes((int)(_sectionOffsets[3] - _sectionOffsets[0])); _unk4 = br.ReadBytes(20); // Initialize SaveSlots SaveSlots = new List <SaveSlot>(3); // Read SaveSlots till the end of the file (max 3 ingame, but there is space for 7) //while (ms.Position < ms.Length) for (int i = 0; i < 3; i++) { SaveSlots.Add(new SaveSlot(ms)); } } }