コード例 #1
0
ファイル: Racer.DC.cs プロジェクト: everalert/swe1r
 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);
 }
コード例 #2
0
ファイル: Racer.DC.cs プロジェクト: everalert/swe1r
        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));
            }
        }
コード例 #3
0
        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;
        }