예제 #1
0
        protected override TcdSection ReadSection(int number)
        {
            uint data_size = Input.ReadUInt32();

            if (0 == data_size)
            {
                return(null);
            }
            var section = new TcdSection {
                DataSize = data_size
            };

            section.Extension      = Extensions[number];
            section.FileCount      = Input.ReadInt32();
            section.DirCount       = Input.ReadInt32();
            section.IndexOffset    = Input.ReadUInt32();
            section.DirNameLength  = Input.ReadInt32();
            section.FileNameLength = Input.ReadInt32();
            section.DirNamesSize   = section.DirNameLength;
            section.FileNamesSize  = section.FileNameLength;
            return(section);
        }
예제 #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            uint current_offset = 8;
            var  sections       = new List <TcdSection> (5);

            for (int i = 0; i < 5; ++i, current_offset += 0x20)
            {
                uint index_offset = file.View.ReadUInt32(current_offset + 4);
                if (0 == index_offset)
                {
                    continue;
                }
                var section = new TcdSection
                {
                    IndexOffset    = index_offset,
                    DataSize       = file.View.ReadUInt32(current_offset),
                    DirCount       = file.View.ReadInt32(current_offset + 8),
                    DirNameLength  = file.View.ReadInt32(current_offset + 0x0C),
                    FileCount      = file.View.ReadInt32(current_offset + 0x10),
                    FileNameLength = file.View.ReadInt32(current_offset + 0x14),
                };
                sections.Add(section);
            }

            var list = new List <Entry> (count);

            foreach (var section in sections)
            {
                current_offset = section.IndexOffset;
                uint dir_size  = (uint)(section.DirCount * section.DirNameLength);
                var  dir_names = new byte[dir_size];
                if (dir_size != file.View.Read(current_offset, dir_names, 0, dir_size))
                {
                    return(null);
                }
                current_offset += dir_size;
                DecryptNames(dir_names, section.DirNameLength);

                var dirs = new TcdDirEntry[section.DirCount];
                for (int i = 0; i < dirs.Length; ++i)
                {
                    dirs[i].FileCount   = file.View.ReadInt32(current_offset);
                    dirs[i].NamesOffset = file.View.ReadInt32(current_offset + 4);
                    dirs[i].FirstIndex  = file.View.ReadInt32(current_offset + 8);
                    current_offset     += 0x10;
                }

                uint entries_size = (uint)(section.FileCount * section.FileNameLength);
                var  file_names   = new byte[entries_size];
                if (entries_size != file.View.Read(current_offset, file_names, 0, entries_size))
                {
                    return(null);
                }
                current_offset += entries_size;
                DecryptNames(file_names, section.FileNameLength);

                var offsets = new uint[section.FileCount + 1];
                for (int i = 0; i < offsets.Length; ++i)
                {
                    offsets[i]      = file.View.ReadUInt32(current_offset);
                    current_offset += 4;
                }

                int dir_name_offset = 0;
                foreach (var dir in dirs)
                {
                    string dir_name = Binary.GetCString(dir_names, dir_name_offset, section.DirNameLength);
                    dir_name_offset += section.DirNameLength;
                    int index       = dir.FirstIndex;
                    int name_offset = dir.NamesOffset;
                    for (int i = 0; i < dir.FileCount; ++i)
                    {
                        string name = Binary.GetCString(file_names, name_offset, section.FileNameLength);
                        name_offset += section.FileNameLength;
                        name         = dir_name + '\\' + name;
                        var entry = new TcdEntry(index, name, file, offsets[index]);
                        entry.Size = offsets[index + 1] - offsets[index];
                        ++index;
                        list.Add(entry);
                    }
                }
            }
            return(new TcdArchive(file, this, list));
        }