예제 #1
0
        public void Import(string filename)
        {
            if (!File.Exists(filename))
            {
                throw new FileNotFoundException();
            }

            using (FileStream file = File.OpenRead(filename))
            {
                uint   hCRC32 = 0, fCRC32 = 0;
                byte[] CRC32_check;

                // header
                byte[] word_magic = FileIO.ReadChunk(file, file_word_magic.Length, ref hCRC32, ref fCRC32);
                if (!Win32.ByteArrayCompare(word_magic, file_word_magic))
                {
                    throw new InvalidDataException();
                }
                byte ver_write  = FileIO.ReadChunk(file, 0x1, ref hCRC32, ref fCRC32)[0];
                byte ver_read   = FileIO.ReadChunk(file, 0x1, ref hCRC32, ref fCRC32)[0];
                byte endianness = FileIO.ReadChunk(file, 0x1, ref hCRC32, ref fCRC32)[0];
                uint off_meta   = BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref hCRC32, ref fCRC32), 0);
                uint off_def    = BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref hCRC32, ref fCRC32), 0);
                uint off_body   = BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref hCRC32, ref fCRC32), 0);
                uint len_data   = BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref hCRC32, ref fCRC32), 0);
                CRC32_check = FileIO.ReadChunk(file, 0x4, ref fCRC32);
                if (Crc32Algorithm.Append(hCRC32, CRC32_check) != 0x2144DF1C)
                {
                    throw new InvalidDataException();
                }

                // meta
                byte[] in_meta_player         = FileIO.ReadChunk(file, 0x20, ref fCRC32);
                byte   in_meta_track          = FileIO.ReadChunk(file, 0x1, ref fCRC32)[0];
                byte   in_meta_vehicle        = FileIO.ReadChunk(file, 0x1, ref fCRC32)[0];
                byte[] in_meta_upgrade_level  = FileIO.ReadChunk(file, 0x7, ref fCRC32);
                byte[] in_meta_upgrade_health = FileIO.ReadChunk(file, 0x7, ref fCRC32);

                // def
                List <DataCollection.DataBlock.Path> in_path = new List <DataCollection.DataBlock.Path>();
                List <uint> in_offset = new List <uint>();
                List <uint> in_length = new List <uint>();
                while (file.Position < off_body)
                {
                    in_path.Add((DataCollection.DataBlock.Path)FileIO.ReadChunk(file, 0x1, ref fCRC32)[0]);
                    in_offset.Add(BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref fCRC32), 0));
                    in_length.Add(BitConverter.ToUInt32(FileIO.ReadChunk(file, 0x4, ref fCRC32), 0));
                }

                // body
                List <DataCollection> in_frame = new List <DataCollection>();
                while (file.Position < off_meta + len_data)
                {
                    DataCollection frame = new DataCollection();
                    for (int i = 0; i < in_path.Count; i++)
                    {
                        byte[] in_data = FileIO.ReadChunk(file, (int)in_length[i], ref fCRC32);
                        DataCollection.DataBlock block = new DataCollection.DataBlock(in_data, in_path[i], in_offset[i]);
                        frame.data.Add(block);
                    }
                    in_frame.Add(frame);
                }

                // footer
                CRC32_check = FileIO.ReadChunk(file, 0x4);
                if (Crc32Algorithm.Append(fCRC32, CRC32_check) != 0x2144DF1C)
                {
                    throw new InvalidDataException();
                }
                byte[] word_eof = FileIO.ReadChunk(file, file_word_eof.Length);
                if (!Win32.ByteArrayCompare(word_eof, file_word_eof))
                {
                    throw new InvalidDataException();
                }

                // output
                meta_track          = in_meta_track;
                meta_vehicle        = in_meta_vehicle;
                meta_player         = in_meta_player;
                meta_upgrade_level  = in_meta_upgrade_level;
                meta_upgrade_health = in_meta_upgrade_health;
                data.Clear();
                foreach (DataCollection frame in in_frame)
                {
                    data.Add(frame);
                }
                initialized = true;
            }
        }