public int ValueExists(DataBlock.Path path, uint offset, uint length) { for (int z = 0; z < data.Count; z++) { if (data[z].ContainsValue(path, offset, length)) { return(z); } } return(-1); }
public dynamic GetValue(Racer racer, DataBlock.Path path, uint offset, Core.DataType type, uint length) { int index = ValueExists(path, offset, length); if (index < 0) { data.Add(new DataBlock(racer, path, offset, type, length)); return(data.Last().GetValue(offset, type, length)); } else { return(data[index].GetValue(offset, type, length)); } }
public void Import(string filename) { //need to reimplement endianness converting, but low priority cuz there is probably not going to be variance from exporter across platforms //string filename = @"K:\Projects\swe1r\overlay\SWE1R Overlay\Format\Racer.State.WriteTest.e1rs"; FileStream file = File.OpenRead(filename); uint headerCRC32 = 0; uint dataCRC32 = 0; // READ HEADER // read data byte[] inMagicWord = FileIO.ReadChunk(file, fileMagicWord.Length, ref headerCRC32); if (!Win32.ByteArrayCompare(inMagicWord, fileMagicWord)) { throw new Exception("Read Savestate: Invalid filetype."); } byte inVerSrc = FileIO.ReadChunk(file, 0x1, ref headerCRC32)[0]; //ideal/generated-from version byte inVerRead = FileIO.ReadChunk(file, 0x1, ref headerCRC32)[0]; //readable version bool inBigEndian = Convert.ToBoolean(FileIO.ReadChunk(file, 0x1, ref headerCRC32)[0]); byte[] inDataLen = FileIO.ReadChunk(file, 0x4, ref headerCRC32); byte[] inDataOff = FileIO.ReadChunk(file, 0x2, ref headerCRC32); byte[] inHeaderCRC32 = FileIO.ReadChunk(file, 0x4); // convert to big endian if needed //if (inBigEndian) //{ // inDataLen = inDataLen.Reverse().ToArray(); // inDataOff = inDataOff.Reverse().ToArray(); // inHeaderCRC32 = inHeaderCRC32.Reverse().ToArray(); //} // check crc32 if (Crc32Algorithm.Append(headerCRC32, inHeaderCRC32, 0, 0x4) != 0x2144DF1C) { throw new Exception("Read Savestate: Header invalid."); } // check eof file.Seek(BitConverter.ToUInt16(inDataOff, 0) + BitConverter.ToUInt32(inDataLen, 0), SeekOrigin.Begin); byte[] inEOFCheck = FileIO.ReadChunk(file, fileEOFWord.Length); if (!Win32.ByteArrayCompare(inEOFCheck, fileEOFWord)) { throw new Exception("Read Savestate: File length invalid."); } // READ DATA file.Seek(BitConverter.ToUInt16(inDataOff, 0), SeekOrigin.Begin); List <DataBlock> inDataBlocks = new List <DataBlock>(); while (file.Position < BitConverter.ToUInt16(inDataOff, 0) + BitConverter.ToUInt32(inDataLen, 0) - 4) { uint blockCRC32 = 0; DataBlock.Path p = (DataBlock.Path)FileIO.ReadChunk(file, 0x1, ref blockCRC32, ref dataCRC32)[0]; uint o = BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref blockCRC32, ref dataCRC32), 0); int l = (int)BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref blockCRC32, ref dataCRC32), 0); //typecasted to preserve original encoding from uint //byte[] d = FileIO.ReadChunk(file, BitConverter.ToInt32((inBigEndian ? inDataBlocks.Last().length.Reverse().ToArray() : inDataBlocks.Last().length), 0), ref blockCRC32, ref dataCRC32); byte[] d = FileIO.ReadChunk(file, l, ref blockCRC32, ref dataCRC32); inDataBlocks.Add(new DataBlock(d, p, o, Core.DataType.None)); byte[] crc32 = FileIO.ReadChunk(file, 0x4, ref dataCRC32); //if (inBigEndian) // inDataBlocks.Last().ReverseArrays(); if (Crc32Algorithm.Append(blockCRC32, crc32) != 0x2144DF1C) { throw new Exception("Read Savestate: Data block " + inDataBlocks.Count + " invalid."); } } // check entire data set is valid byte[] inDataCRC32 = FileIO.ReadChunk(file, 0x4); //if (inBigEndian) // inDataCRC32 = inDataCRC32.Reverse().ToArray(); if (Crc32Algorithm.Append(dataCRC32, inDataCRC32, 0, 0x4) != 0x2144DF1C) { throw new Exception("Read Savestate: Data invalid."); } // check end of data is actually end of file inEOFCheck = FileIO.ReadChunk(file, fileEOFWord.Length); if (!Win32.ByteArrayCompare(inEOFCheck, fileEOFWord)) { throw new Exception("Read Savestate: File length invalid."); } //Savestate output = new Savestate(inDataBlocks.ToArray(), inDataPod, inDataTrack); //need to implement a way to update data blocks with data not sourced from the game directly in order to actually use the read data file.Dispose(); file.Close(); //return output; }