示例#1
0
        public List <Entry> ReadIndex()
        {
            if (!ArchiveFormat.IsSaneCount(Count))
            {
                return(null);
            }

            var sections = ReadSections(m_section_count);
            var list     = new List <Entry> (Count);

            foreach (var section in sections)
            {
                m_input.Position = section.IndexOffset;
                var dir_names = m_input.ReadBytes(section.DirNamesSize);
                if (section.DirNamesSize != dir_names.Length)
                {
                    return(null);
                }
                byte section_key = dir_names[section.DirNameLength - 1];
                DecryptNames(dir_names, section_key);

                var dirs = new TcdDirEntry[section.DirCount];
                for (int i = 0; i < dirs.Length; ++i)
                {
                    dirs[i].FileCount   = m_input.ReadInt32();
                    dirs[i].NamesOffset = m_input.ReadInt32();
                    dirs[i].FirstIndex  = m_input.ReadInt32();
                    m_input.ReadInt32();
                }
                var file_names = m_input.ReadBytes(section.FileNamesSize);
                if (file_names.Length != section.FileNamesSize)
                {
                    return(null);
                }
                DecryptNames(file_names, section_key);

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

                int dir_name_offset = 0;
                foreach (var dir in dirs)
                {
                    string dir_name    = GetName(dir_names, section.DirNameLength, ref dir_name_offset);
                    int    index       = dir.FirstIndex;
                    int    name_offset = dir.NamesOffset;
                    for (int i = 0; i < dir.FileCount; ++i)
                    {
                        string name = GetName(file_names, section.FileNameLength, ref name_offset);
                        name = Path.Combine(dir_name, name);
                        name = Path.ChangeExtension(name, section.Extension);
                        var entry = FormatCatalog.Instance.Create <TcdEntry> (name);
                        if (name.HasExtension(".SPD"))
                        {
                            entry.Type = "image";
                        }
                        entry.Offset = offsets[index];
                        entry.Size   = offsets[index + 1] - offsets[index];
                        entry.Index  = index;
                        ++index;
                        list.Add(entry);
                    }
                }
            }
            return(list);
        }
示例#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));
        }