Exemple #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0xC);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_offset = file.View.ReadUInt32(4);

            if (index_offset >= file.MaxOffset)
            {
                return(null);
            }
            var dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    UnpackedSize = file.View.ReadUInt32(index_offset),
                    Size         = file.View.ReadUInt32(index_offset + 4),
                    Offset       = file.View.ReadUInt32(index_offset + 8),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                uint name_length = file.View.ReadUInt32(index_offset + 0xC);
                if (0 == name_length || name_length > 0x100)
                {
                    return(null);
                }
                entry.Name     = file.View.ReadString(index_offset + 0x10, name_length);
                entry.Type     = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                entry.IsPacked = entry.UnpackedSize != entry.Size;
                dir.Add(entry);
                index_offset += 0x10 + name_length;
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

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

            uint index_offset = 0x20;
            long data_offset  = index_offset + count * 0x110;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString(index_offset, 0x100);
                if (string.IsNullOrWhiteSpace(name))
                {
                    return(null);
                }
                var entry = new PackedEntry();
                entry.IsPacked = name.HasExtension(".pr3");
                if (entry.IsPacked)
                {
                    name = name.Substring(0, name.Length - 4);
                }
                entry.Name         = name;
                entry.Type         = FormatCatalog.Instance.GetTypeFromName(name);
                entry.Size         = file.View.ReadUInt32(index_offset + 0x100);
                entry.Offset       = file.View.ReadUInt32(index_offset + 0x104);
                entry.UnpackedSize = entry.Size;
                if (entry.Offset < data_offset || entry.Offset > file.MaxOffset)
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x110;
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #3
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version = file.View.ReadByte(3) - '0';
            int count   = file.View.ReadInt32(4);

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

            var index = ReadIndex(file, 8, count);
            var dir   = new List <Entry>();

            foreach (var section in index)
            {
                int index_offset = section.Item1;
                for (int section_size = section.Item2; section_size > 0;)
                {
                    int entry_size = file.View.ReadByte(index_offset);
                    if (entry_size < 5)
                    {
                        break;
                    }
                    var entry = new PackedEntry {
                        Offset = Binary.BigEndian(file.View.ReadUInt32(index_offset + 1)),
                        Name   = file.View.ReadString(index_offset + 5, (uint)entry_size - 5),
                    };
                    if (entry.Offset > file.MaxOffset)
                    {
                        return(null);
                    }
                    index_offset += entry_size;
                    section_size -= entry_size;
                    dir.Add(entry);
                }
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
Exemple #4
0
        internal List <Entry> ReadIndex(ArcView file, uint index_offset, int count)
        {
            var  base_name = Path.GetFileNameWithoutExtension(file.Name);
            long offset    = index_offset + count * 4;

            if (offset >= file.MaxOffset)
            {
                return(null);
            }
            var dir = new List <Entry> (count / 2);

            for (int i = 0; i < count; ++i)
            {
                uint size = file.View.ReadUInt32(index_offset);
                if (size != 0 && size != uint.MaxValue)
                {
                    var entry = new PackedEntry
                    {
                        Name     = string.Format("{0}#{1:D5}", base_name, i),
                        Offset   = offset,
                        Size     = size,
                        IsPacked = false,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    offset += size;
                }
                index_offset += 4;
            }
            if (0 == dir.Count || (file.MaxOffset - offset) > 0x80000)
            {
                return(null);
            }
            DetectFileTypes(file, dir);
            return(dir);
        }
Exemple #5
0
        int UpdateFileTable(IDictionary <uint, PackedEntry> table, IEnumerable <Entry> list)
        {
            int update_count = 0;

            foreach (var entry in list)
            {
                if (entry.Type != "image" && !entry.Name.HasExtension(".scr"))
                {
                    continue;
                }
                uint id;
                if (!uint.TryParse(Path.GetFileNameWithoutExtension(entry.Name), NumberStyles.HexNumber,
                                   CultureInfo.InvariantCulture, out id))
                {
                    continue;
                }
                PackedEntry existing;
                if (table.TryGetValue(id, out existing) && !(existing is AmiEntry))
                {
                    var file_new = new FileInfo(entry.Name);
                    if (!file_new.Exists)
                    {
                        continue;
                    }
                    var file_old = new FileInfo(existing.Name);
                    if (file_new.LastWriteTime <= file_old.LastWriteTime)
                    {
                        continue;
                    }
                }
                table[id] = new PackedEntry
                {
                    Name = entry.Name,
                    Type = entry.Type
                };
                ++update_count;
            }
            return(update_count);
        }
Exemple #6
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count) || !file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            uint first_offset = file.View.ReadUInt32(0x14);

            if (first_offset != 4 + count * 0x14)
            {
                return(null);
            }
            uint index_offset = 4;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString(index_offset, 0xC);
                if (string.IsNullOrEmpty(name))
                {
                    return(null);
                }
                var entry = new PackedEntry {
                    Name   = name,
                    Size   = file.View.ReadUInt32(index_offset + 0xC),
                    Offset = file.View.ReadUInt32(index_offset + 0x10),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x14;
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
Exemple #7
0
        uint WriteAmiEntry(PackedEntry entry, Stream output)
        {
            uint packed_size = 0;

            using (var input = VFS.OpenBinaryStream(entry))
            {
                long file_size = input.Length;
                if (file_size > uint.MaxValue)
                {
                    throw new FileSizeException();
                }
                entry.UnpackedSize = (uint)file_size;
                if ("image" == entry.Type)
                {
                    packed_size = WriteImageEntry(entry, input, output);
                }
                else
                {
                    input.AsStream.CopyTo(output);
                }
            }
            return(packed_size);
        }
Exemple #8
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

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

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint index_offset = 0x20;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    Offset       = file.View.ReadUInt32(index_offset),
                    UnpackedSize = file.View.ReadUInt32(index_offset + 4),
                    Size         = file.View.ReadUInt32(index_offset + 8),
                    Name         = string.Format("{0}#{1:D5}", base_name, i),
                };
                entry.IsPacked = entry.Size != 0;
                if (!entry.IsPacked)
                {
                    entry.Size = entry.UnpackedSize;
                }
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                index_offset += 0x10;
                dir.Add(entry);
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
Exemple #9
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (0 != file.View.ReadInt32(4))
            {
                return(null);
            }
            long index_offset = file.View.ReadInt64(8);

            if (index_offset >= file.MaxOffset)
            {
                return(null);
            }
            if (!file.View.AsciiEqual(index_offset, "GCE3"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(index_offset + 0x18);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            bool index_packed = 0x11 == file.View.ReadInt32(index_offset + 4);
            uint index_size   = file.View.ReadUInt32(index_offset + 8);

            byte[] index = null;
            if (index_packed)
            {
                index_size -= 0x28;
                int unpacked_size = file.View.ReadInt32(index_offset + 0x20);
                using (var input = file.CreateStream(index_offset + 0x28, index_size))
                    using (var reader = new GceReader(input, unpacked_size))
                        index = reader.Data;
            }
            else
            {
                index_size -= 0x20;
                index       = new byte[index_size];
                if (index.Length != file.View.Read(index_offset + 0x20, index, 0, index_size))
                {
                    return(null);
                }
            }
            int  current_index    = 0;
            int  current_filename = 0x20 * count;
            long current_offset   = 0x10;
            var  dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                int name_length = LittleEndian.ToUInt16(index, current_filename);
                if (current_filename + 2 + name_length > index.Length)
                {
                    return(null);
                }
                uint size = LittleEndian.ToUInt32(index, current_index + 0x18);
                if (size != 0)
                {
                    string name  = Encodings.cp932.GetString(index, current_filename + 2, name_length);
                    var    entry = new PackedEntry
                    {
                        Name         = name,
                        Type         = FormatCatalog.Instance.GetTypeFromName(name),
                        Offset       = current_offset,
                        Size         = size,
                        UnpackedSize = LittleEndian.ToUInt32(index, current_index + 0x10),
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    entry.IsPacked  = entry.Size != entry.UnpackedSize;
                    current_offset += entry.Size;
                    dir.Add(entry);
                }
                current_index    += 0x20;
                current_filename += 2 + name_length;
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #10
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_size = (uint)count * 4 + 8;

            if (index_size > file.View.Reserve(0, index_size))
            {
                return(null);
            }
            uint index_offset = 4;
            uint offset       = file.View.ReadUInt32(index_offset);

            if (offset != index_size)
            {
                return(null);
            }
            uint last_offset = file.View.ReadUInt32(index_size - 4);

            if (last_offset != file.MaxOffset)
            {
                return(null);
            }
            string default_type = "";

            if (file.Name.HasExtension("fx"))
            {
                default_type = "audio";
            }
            else if (file.Name.HasExtension("gx"))
            {
                default_type = "image";
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name);
            var dir       = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry {
                    Name   = string.Format("{0}#{1:D4}", base_name, i),
                    Type   = default_type,
                    Offset = offset,
                };
                offset     = file.View.ReadUInt32(index_offset);
                entry.Size = (uint)(offset - entry.Offset);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            if (string.IsNullOrEmpty(default_type))
            {
                foreach (var entry in dir)
                {
                    uint signature = file.View.ReadUInt32(entry.Offset);
                    entry.ChangeType(AutoEntry.DetectFileType(signature));
                }
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #11
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version = file.View.ReadByte(3) - 0x30;
            int count   = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var  name_buf     = new byte[32];
            var  dir          = new List <Entry> (count);
            long index_offset = 8;
            uint next_offset  = file.View.ReadUInt32(index_offset);

            for (int i = 0; i < count; ++i)
            {
                uint offset      = next_offset;
                uint size        = file.View.ReadUInt32(index_offset + 4);
                int  name_length = file.View.ReadByte(index_offset + 8);
                if (name_length > name_buf.Length)
                {
                    name_buf = new byte[name_length];
                }
                file.View.Read(index_offset + 9, name_buf, 0, (uint)name_length);
                if (i + 1 == count)
                {
                    next_offset = (uint)file.MaxOffset;
                }
                else
                {
                    next_offset = file.View.ReadUInt32(index_offset + 9 + name_length);
                }
                if (0 != offset && offset != file.MaxOffset)
                {
                    if (2 == version)
                    {
                        for (int j = 0; j < name_length; ++j)
                        {
                            name_buf[j] ^= 0xff;
                        }
                    }
                    uint packed_size;
                    if (0 == next_offset)
                    {
                        packed_size = size;
                    }
                    else if (next_offset >= offset)
                    {
                        packed_size = next_offset - offset;
                    }
                    else
                    {
                        return(null);
                    }
                    string name  = Encodings.cp932.GetString(name_buf, 0, name_length);
                    var    entry = new PackedEntry
                    {
                        Name         = name,
                        Type         = FormatCatalog.Instance.GetTypeFromName(name),
                        Offset       = offset,
                        Size         = packed_size,
                        UnpackedSize = size,
                        IsPacked     = packed_size != size,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                index_offset += 9 + name_length;
            }
            if (2 == version)
            {
                return(new AstArchive(file, this, dir));
            }
            else
            {
                return(new ArcFile(file, this, dir));
            }
        }
Exemple #12
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint first_offset = file.View.ReadUInt32(0);

            if (first_offset < 8 || first_offset >= file.MaxOffset)
            {
                return(null);
            }
            int count = (int)(first_offset - 8) / 4;

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

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint index_offset = 0;
            uint next_offset  = first_offset;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    Offset = next_offset
                };
                index_offset += 4;
                next_offset   = file.View.ReadUInt32(index_offset);
                if (next_offset < entry.Offset)
                {
                    return(null);
                }
                entry.Size         = (uint)(next_offset - entry.Offset);
                entry.UnpackedSize = entry.Size;
                if (entry.Size != 0)
                {
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    entry.Name = string.Format("{0}#{1:D4}", base_name, i);
                    dir.Add(entry);
                }
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            foreach (PackedEntry entry in dir)
            {
                if (entry.Size < 4)
                {
                    continue;
                }
                uint unpacked_size = file.View.ReadUInt32(entry.Offset);
                if (entry.Size > 8 && file.View.AsciiEqual(entry.Offset + 4, "HDJ\0"))
                {
                    if (file.View.AsciiEqual(entry.Offset + 12, "BM"))
                    {
                        entry.Name = Path.ChangeExtension(entry.Name, "bmp");
                        entry.Type = "image";
                    }
                    entry.UnpackedSize = unpacked_size;
                    entry.IsPacked     = true;
                }
                else if (entry.Size > 12 && file.View.AsciiEqual(entry.Offset + 8, "RIFF"))
                {
                    entry.Name         = Path.ChangeExtension(entry.Name, "wav");
                    entry.Type         = "audio";
                    entry.UnpackedSize = unpacked_size;
                    entry.IsPacked     = true;
                }
                else if (0x4D42 == (unpacked_size & 0xFFFF))
                {
                    entry.Name = Path.ChangeExtension(entry.Name, "bmp");
                    entry.Type = "image";
                }
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #13
0
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (0);
     if (!IsSaneCount (count))
         return null;
     long offset = 4+count*4;
     if (offset >= file.MaxOffset)
         return null;
     uint index_offset = 4;
     var dir = new List<Entry>();
     for (int i = 0; i < count; ++i)
     {
         uint size = file.View.ReadUInt32 (index_offset);
         if (0 != size)
         {
             var entry = new PackedEntry
             {
                 Name = i.ToString ("D5"),
                 Offset = offset,
                 Size = size,
                 IsPacked = false,
             };
             if (!entry.CheckPlacement (file.MaxOffset))
                 return null;
             dir.Add (entry);
             offset += size;
         }
         index_offset += 4;
     }
     if (offset != file.MaxOffset || 0 == dir.Count)
         return null;
     byte[] preview = new byte[16];
     byte[] sign_buf = new byte[4];
     foreach (PackedEntry entry in dir)
     {
         uint extra = 6;
         if (extra > entry.Size)
             continue;
         int label = file.View.ReadUInt16 (entry.Offset);
         if (1 == label)
         {
             entry.IsPacked = true;
             entry.UnpackedSize = file.View.ReadUInt32 (entry.Offset+2);
         }
         entry.Offset += extra;
         entry.Size   -= extra;
         uint signature;
         if (entry.IsPacked)
         {
             file.View.Read (entry.Offset, preview, 0, (uint)preview.Length);
             using (var input = new MemoryStream (preview))
             {
                 LzssUnpack (input, sign_buf);
                 signature = LittleEndian.ToUInt32 (sign_buf, 0);
             }
         }
         else
         {
             signature = file.View.ReadUInt32 (entry.Offset);
         }
         if (0 != signature)
             SetEntryType (entry, signature);
     }
     return new ArcFile (file, this, dir);
 }
Exemple #14
0
 int UpdateFileTable(IDictionary<uint, PackedEntry> table, IEnumerable<Entry> list)
 {
     int update_count = 0;
     foreach (var entry in list)
     {
         if (entry.Type != "image" && !entry.Name.EndsWith (".scr", StringComparison.InvariantCultureIgnoreCase))
             continue;
         uint id;
         if (!uint.TryParse (Path.GetFileNameWithoutExtension (entry.Name), NumberStyles.HexNumber,
                             CultureInfo.InvariantCulture, out id))
             continue;
         PackedEntry existing;
         if (table.TryGetValue (id, out existing) && !(existing is AmiEntry))
         {
             var file_new = new FileInfo (entry.Name);
             if (!file_new.Exists)
                 continue;
             var file_old = new FileInfo (existing.Name);
             if (file_new.LastWriteTime <= file_old.LastWriteTime)
                 continue;
         }
         table[id] = new PackedEntry
         {
             Name = entry.Name,
             Type = entry.Type
         };
         ++update_count;
     }
     return update_count;
 }
Exemple #15
0
 uint WriteAmiEntry(PackedEntry entry, Stream output)
 {
     uint packed_size = 0;
     using (var input = File.OpenRead (entry.Name))
     {
         long file_size = input.Length;
         if (file_size > uint.MaxValue)
             throw new FileSizeException();
         entry.UnpackedSize = (uint)file_size;
         if ("image" == entry.Type)
         {
             packed_size = WriteImageEntry (entry, input, output);
         }
         else
         {
             input.CopyTo (output);
         }
     }
     return packed_size;
 }
Exemple #16
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32 (4);
            if (!IsSaneCount (count))
                return null;

            var base_name = Path.GetFileNameWithoutExtension (file.Name);
            var dir = new List<Entry> (count);
            int index_offset = 8;
            long data_offset = count * 4 + 8;
            uint next_offset = file.View.ReadUInt32 (index_offset);
            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry { Offset = next_offset };
                next_offset = i + 1 < count ? file.View.ReadUInt32 (index_offset) : (uint)file.MaxOffset;
                entry.Size = next_offset - (uint)entry.Offset;
                if (entry.Offset < data_offset || !entry.CheckPlacement (file.MaxOffset))
                    return null;
                entry.Name = string.Format ("{0}#{1:D4}", base_name, i);
                dir.Add (entry);
            }
            DetectFileTypes (file, dir);
            return new ArcFile (file, this, dir);
        }
Exemple #17
0
 public override ArcFile TryOpen(ArcView file)
 {
     if (!file.Name.EndsWith (".mgr", StringComparison.InvariantCultureIgnoreCase))
         return null;
     int count = file.View.ReadInt16 (0);
     if (count <= 0 || count >= 0x100)
         return null;
     uint current = 2;
     uint first_offset = current;
     if (count > 1)
     {
         first_offset = file.View.ReadUInt32 (current);
         if (first_offset != 2 + count * 4)
             return null;
     }
     if (!file.View.AsciiEqual (first_offset+9, "BM"))
         return null;
     string base_name = Path.GetFileNameWithoutExtension (file.Name);
     var dir = new List<Entry> (count);
     if (count > 1)
     {
         for (int i = 0; i < count; ++i)
         {
             var entry = new PackedEntry {
                 Name = string.Format ("{0}#{1:D4}.bmp", base_name, i),
                 Type = "image",
                 Offset = file.View.ReadUInt32 (current),
             };
             if (entry.Offset < first_offset || entry.Offset >= file.MaxOffset)
                 return null;
             dir.Add (entry);
             current += 4;
         }
     }
     else
     {
         dir.Add (new PackedEntry { Name = base_name+".bmp", Type = "image", Offset = current });
     }
     foreach (PackedEntry entry in dir)
     {
         entry.UnpackedSize  = file.View.ReadUInt32 (entry.Offset);
         entry.Size          = file.View.ReadUInt32 (entry.Offset+4);
         entry.IsPacked      = true;
         if (entry.UnpackedSize < 0x36 || entry.Size > file.MaxOffset-entry.Offset)
             return null;
         entry.Offset += 8;
     }
     return new ArcFile (file, this, dir);
 }
Exemple #18
0
        public List <Entry> ReadIndex()
        {
            uint section_size = ReadSectionSize("Fver");

            m_offset    += section_size;
            section_size = ReadSectionSize("Fcdr");

            /*
             * int Mcdr_size;
             * var Mcdr = ZlibUnpack (m_offset, section_size, out Mcdr_size);
             */
            m_offset += section_size;
            uint abmp_size   = ReadSectionSize("ABMP");
            int  max_count   = m_file.View.Read(m_offset, m_size_buffer, 0, Math.Min(10, abmp_size));
            int  size_offset = 0;

            ReadValue(m_size_buffer, ref size_offset, max_count);
            max_count -= size_offset;

            int bmp_unpacked_size = (int)ReadValue(m_size_buffer, ref size_offset, max_count);

            m_offset  += size_offset;
            abmp_size -= (uint)size_offset;
            int index_size;
            var index = ZlibUnpack(m_offset, abmp_size, out index_size, bmp_unpacked_size);

            m_offset    += abmp_size;
            section_size = ReadSectionSize("FGEI");
            if (0 != section_size)
            {
                throw new NotSupportedException();
            }

            int index_offset = 0;

            ReadValue(index, ref index_offset, index_size - index_offset);
            ReadValue(index, ref index_offset, index_size - index_offset);
            int entry_count = (int)ReadValue(index, ref index_offset, index_size - index_offset);

            if (entry_count <= 0 || entry_count > 0xfffff)
            {
                return(null);
            }

            var type_buf = new char[4];
            var dir      = new List <Entry> (entry_count);

            for (int i = 0; i < entry_count; ++i)
            {
                uint id            = ReadValue(index, ref index_offset, index_size - index_offset);
                uint offset        = ReadValue(index, ref index_offset, index_size - index_offset);
                uint size          = ReadValue(index, ref index_offset, index_size - index_offset);
                uint unpacked_size = ReadValue(index, ref index_offset, index_size - index_offset);
                uint flag          = ReadValue(index, ref index_offset, index_size - index_offset);

                if (index_size - index_offset < 4)
                {
                    return(null);
                }
                uint type_id = LittleEndian.ToUInt32(index, index_offset);
                index_offset += 4;
                if (0 == type_id || uint.MaxValue == offset)
                {
                    continue;
                }

                Encoding.ASCII.GetChars(index, index_offset - 4, 4, type_buf, 0);
                var entry = new PackedEntry
                {
                    Name         = CreateName(id, type_buf),
                    Offset       = (long)m_offset + offset,
                    Size         = size,
                    UnpackedSize = unpacked_size,
                    IsPacked     = 0 == flag,
                };
                if (entry.CheckPlacement(m_file.MaxOffset))
                {
                    dir.Add(entry);
                }
            }
            return(dir);
        }
Exemple #19
0
 public override ArcFile TryOpen(ArcView file)
 {
     if (!file.View.AsciiEqual (0, "KOTORI") || 0x1A1A00 != file.View.ReadInt32 (6))
         return null;
     int count = file.View.ReadUInt16 (0x14);
     if (0x0100A618 != file.View.ReadInt32 (0x10) || !IsSaneCount (count))
         return null;
     string base_name = Path.GetFileNameWithoutExtension (file.Name);
     uint current_offset = 0x18;
     long next_offset = file.View.ReadUInt32 (current_offset);
     var dir = new List<Entry> (count);
     for (int i = 0; i < count; ++i)
     {
         var entry = new PackedEntry {
             Name = string.Format ("{0}#{1:D4}.ogg", base_name, i),
             Type = "audio",
             Offset = next_offset,
         };
         if (i+1 != count)
         {
             current_offset += 6;
             next_offset = file.View.ReadUInt32 (current_offset);
         }
         else
             next_offset = file.MaxOffset;
         entry.Size = (uint)(next_offset - entry.Offset);
         if (entry.Size >= 0x32)
         {
             entry.IsPacked = true;
             entry.UnpackedSize = entry.Size - 0x32;
         }
         if (!entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
     }
     return new ArcFile (file, this, dir);
 }
Exemple #20
0
            bool ReadV1(Stream input)
            {
                // NOTE CryptoStream will close an input stream
                using (var xored = new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read))
                using (var lzss = new LzssStream (xored))
                    lzss.Read (m_index, 0, m_index.Length);

                int index_offset = Array.IndexOf (m_index, (byte)0);
                if (-1 == index_offset || 0 == index_offset)
                    return false;
                Password = m_index.Take (index_offset++).ToArray();
                long base_offset = 0x20 + m_packed_size;

                for (int i = 0; i < m_count; ++i)
                {
                    var entry = new PackedEntry();
                    entry.Offset = LittleEndian.ToUInt32 (m_index, index_offset) + base_offset;
                    entry.Size   = LittleEndian.ToUInt32 (m_index, index_offset + 4);
                    entry.UnpackedSize = LittleEndian.ToUInt32 (m_index, index_offset + 8);
                    entry.IsPacked = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement (m_file.MaxOffset))
                        return false;
                    int name_len = LittleEndian.ToInt32 (m_index, index_offset + 0xC);
                    entry.Name = Encodings.cp932.GetString (m_index, index_offset+0x18, name_len);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
                    m_dir.Value.Add (entry);
                    index_offset += 0x18 + name_len;
                }
                return true;
            }
Exemple #21
0
            bool ReadV0(Stream input)
            {
                long current_offset = 0x20 + m_packed_size;
                uint offset_table_size = (uint)m_count * 0x10;
                if (offset_table_size > m_file.View.Reserve (current_offset, offset_table_size))
                    return false;

                using (var lzss = new LzssStream (input, LzssMode.Decompress, true))
                    lzss.Read (m_index, 0, m_index.Length);

                for (int i = 0; i < m_index.Length; ++i)
                {
                    m_index[i] = (byte)(~m_index[i] - 5);
                }
                int index_offset = Array.IndexOf (m_index, (byte)0);
                if (-1 == index_offset || 0 == index_offset)
                    return false;
                index_offset++;
                //                Password = m_index.Take (index_offset++).ToArray();

                for (int i = 0; i < m_count && index_offset < m_index.Length; ++i)
                {
                    int name_end = Array.IndexOf (m_index, (byte)0, index_offset);
                    if (-1 == name_end)
                        name_end = m_index.Length;
                    if (index_offset == name_end)
                        return false;
                    var entry = new PackedEntry();
                    entry.Offset = m_file.View.ReadUInt32 (current_offset);
                    entry.Size   = m_file.View.ReadUInt32 (current_offset+4);
                    entry.UnpackedSize = m_file.View.ReadUInt32 (current_offset+8);
                    entry.IsPacked = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement (m_file.MaxOffset))
                        return false;
                    entry.Name = Encodings.cp932.GetString (m_index, index_offset, name_end-index_offset);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
                    m_dir.Value.Add (entry);
                    index_offset = name_end+1;
                    current_offset += 0x10;
                }
                return true;
            }
Exemple #22
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "OFST"))
            {
                return(null);
            }
            int index_size = file.View.ReadInt32(8);
            int count      = index_size / 4;

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var    base_name = Path.GetFileNameWithoutExtension(file.Name);
            string content_ext = "", content_type = "";

            if (base_name.EndsWith("flac", StringComparison.InvariantCultureIgnoreCase))
            {
                content_ext  = "flac";
                content_type = "audio";
                base_name    = base_name.Substring(0, base_name.Length - 4);
            }
            else if (base_name.EndsWith("ogg", StringComparison.InvariantCultureIgnoreCase))
            {
                content_ext  = "ogg";
                content_type = "audio";
                base_name    = base_name.Substring(0, base_name.Length - 3);
            }

            var filenames = GetFileNames(VFS.GetDirectoryName(file.Name), base_name);

            if (null == filenames)
            {
                filenames = new List <string> (count);
            }
            for (int i = filenames.Count; i < count; ++i)
            {
                filenames.Add(string.Format("{0}#{1:D5}", base_name, i));
            }

            uint index_offset = 0xC;
            var  dir          = new List <Entry> (count);
            uint next_offset  = file.View.ReadUInt32(index_offset);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry {
                    Name = filenames[i]
                };
                entry.Offset = next_offset;
                next_offset  = i + 1 < count?file.View.ReadUInt32(index_offset) : (uint)file.MaxOffset;

                entry.Size = next_offset - (uint)entry.Offset;
                if (entry.Size > 0 && !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                if (!string.IsNullOrEmpty(content_type))
                {
                    entry.Type = content_type;
                    entry.Name = Path.ChangeExtension(entry.Name, content_ext);
                }
                dir.Add(entry);
            }
            foreach (PackedEntry entry in dir.Where(e => e.Size > 4))
            {
                entry.IsPacked = file.View.AsciiEqual(entry.Offset, "DFLT");
                if (entry.IsPacked)
                {
                    entry.Size         = file.View.ReadUInt32(entry.Offset + 4);
                    entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 8);
                    entry.Offset      += 12;
                }
                else if (file.View.AsciiEqual(entry.Offset, "DATA"))
                {
                    entry.Size         = file.View.ReadUInt32(entry.Offset + 4);
                    entry.UnpackedSize = entry.Size;
                    entry.Offset      += 8;
                    if (string.IsNullOrEmpty(entry.Type))
                    {
                        uint signature = file.View.ReadUInt32(entry.Offset);
                        if (0x43614C66 == signature) // 'fLaC'
                        {
                            entry.Type = "audio";
                            entry.Name = Path.ChangeExtension(entry.Name, "flac");
                        }
                        else
                        {
                            var res = AutoEntry.DetectFileType(signature);
                            if (null != res)
                            {
                                entry.ChangeType(res);
                            }
                        }
                    }
                }
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #23
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint first_offset = file.View.ReadUInt32 (0);
            if (first_offset < 8 || first_offset >= file.MaxOffset)
                return null;
            int count = (int)(first_offset - 8) / 4;
            if (!IsSaneCount (count))
                return null;

            var base_name = Path.GetFileNameWithoutExtension (file.Name);
            uint index_offset = 0;
            uint next_offset = first_offset;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry { Offset = next_offset };
                index_offset += 4;
                next_offset = file.View.ReadUInt32 (index_offset);
                if (next_offset < entry.Offset)
                    return null;
                entry.Size = (uint)(next_offset - entry.Offset);
                entry.UnpackedSize = entry.Size;
                if (entry.Size != 0)
                {
                    if (!entry.CheckPlacement (file.MaxOffset))
                        return null;
                    entry.Name = string.Format ("{0}#{1:D4}", base_name, i);
                    dir.Add (entry);
                }
            }
            if (0 == dir.Count)
                return null;
            foreach (PackedEntry entry in dir)
            {
                if (entry.Size < 4)
                    continue;
                uint unpacked_size = file.View.ReadUInt32 (entry.Offset);
                if (entry.Size > 8 && file.View.AsciiEqual (entry.Offset+4, "HDJ\0"))
                {
                    if (file.View.AsciiEqual (entry.Offset+12, "BM"))
                    {
                        entry.Name = Path.ChangeExtension (entry.Name, "bmp");
                        entry.Type = "image";
                    }
                    entry.UnpackedSize = unpacked_size;
                    entry.IsPacked = true;
                }
                else if (entry.Size > 12 && file.View.AsciiEqual (entry.Offset+8, "RIFF"))
                {
                    entry.Name = Path.ChangeExtension (entry.Name, "wav");
                    entry.Type = "audio";
                    entry.UnpackedSize = unpacked_size;
                    entry.IsPacked = true;
                }
                else if (0x4D42 == (unpacked_size & 0xFFFF))
                {
                    entry.Name = Path.ChangeExtension (entry.Name, "bmp");
                    entry.Type = "image";
                }
            }
            return new ArcFile (file, this, dir);
        }
Exemple #24
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.EndsWith(".mgr", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            int count = file.View.ReadInt16(0);

            if (count <= 0 || count >= 0x100)
            {
                return(null);
            }
            uint current      = 2;
            uint first_offset = current;

            if (count > 1)
            {
                first_offset = file.View.ReadUInt32(current);
                if (first_offset != 2 + count * 4)
                {
                    return(null);
                }
            }
            if (!file.View.AsciiEqual(first_offset + 9, "BM"))
            {
                return(null);
            }
            string base_name = Path.GetFileNameWithoutExtension(file.Name);
            var    dir       = new List <Entry> (count);

            if (count > 1)
            {
                for (int i = 0; i < count; ++i)
                {
                    var entry = new PackedEntry {
                        Name   = string.Format("{0}#{1:D4}.bmp", base_name, i),
                        Type   = "image",
                        Offset = file.View.ReadUInt32(current),
                    };
                    if (entry.Offset < first_offset || entry.Offset >= file.MaxOffset)
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    current += 4;
                }
            }
            else
            {
                dir.Add(new PackedEntry {
                    Name = base_name + ".bmp", Type = "image", Offset = current
                });
            }
            foreach (PackedEntry entry in dir)
            {
                entry.UnpackedSize = file.View.ReadUInt32(entry.Offset);
                entry.Size         = file.View.ReadUInt32(entry.Offset + 4);
                entry.IsPacked     = true;
                if (entry.UnpackedSize < 0x36 || entry.Size > file.MaxOffset - entry.Offset)
                {
                    return(null);
                }
                entry.Offset += 8;
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #25
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint first_offset = file.View.ReadUInt32(4);

            if (4 + count * 8 != first_offset)
            {
                return(null);
            }

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            bool is_msg       = base_name == "msg";
            uint index_offset = 4;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint offset = file.View.ReadUInt32(index_offset);
                uint size   = file.View.ReadUInt32(index_offset + 4);
                var  entry  = new PackedEntry {
                    Name   = string.Format("{0}#{1:D5}", base_name, i),
                    Offset = offset,
                    Size   = size,
                };
                if (!is_msg && !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
            }
            foreach (PackedEntry entry in dir)
            {
                if (is_msg)
                {
                    uint size = file.View.ReadUInt32(entry.Offset);
                    entry.Offset      += 4;
                    entry.UnpackedSize = entry.Size;
                    entry.Size         = size;
                    entry.IsPacked     = true;
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    continue;
                }
                uint pos = file.View.ReadUInt32(entry.Offset + 4);
                if (pos > entry.Size)
                {
                    continue;
                }
                uint unpacked_size = file.View.ReadUInt32(entry.Offset + 8);
                uint flags         = unpacked_size >> 30;
                unpacked_size &= 0x3FFFFFFF;
                entry.IsPacked = 0 == flags;
                uint signature = 0;
                if (entry.IsPacked)
                {
                    entry.UnpackedSize = unpacked_size;
                    entry.Size         = file.View.ReadUInt32(entry.Offset + pos);
                    entry.Offset      += pos + 4;
                    if ((file.View.ReadByte(entry.Offset) & 0xF) == 0xF)
                    {
                        signature = file.View.ReadUInt32(entry.Offset + 1);
                    }
                }
                else
                {
                    entry.Size    = unpacked_size;
                    entry.Offset += pos;
                    signature     = file.View.ReadUInt32(entry.Offset);
                }
                var res = AutoEntry.DetectFileType(signature);
                if (res != null)
                {
                    entry.ChangeType(res);
                }
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #26
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.MaxOffset > uint.MaxValue ||
                !VFS.IsPathEqualsToFileName(file.Name, "ARCHPAC.DAT"))
            {
                return(null);
            }
            int file_count = file.View.ReadInt16(0);

            if (!IsSaneCount(file_count))
            {
                return(null);
            }
            uint index_pos  = 2;
            var  size_table = new uint[file_count];

            for (int i = 0; i < file_count; ++i)
            {
                size_table[i] = file.View.ReadUInt32(index_pos);
                index_pos    += 4;
            }
            var  section_table = new SortedDictionary <int, uint>();
            uint min_offset    = (uint)file.MaxOffset;

            while (index_pos + 6 <= min_offset)
            {
                uint offset = file.View.ReadUInt32(index_pos);
                int  index  = file.View.ReadInt16(index_pos + 4);
                if (index < 0 || index > file_count || offset > file.MaxOffset)
                {
                    return(null);
                }
                if (offset < min_offset)
                {
                    min_offset = offset;
                }
                section_table[index] = offset;
                index_pos           += 6;
            }
            var dir         = new List <Entry> (file_count);
            int section_num = 0;

            foreach (var section in section_table)
            {
                int  i           = section.Key;
                uint base_offset = section.Value;
                do
                {
                    uint size  = size_table[i];
                    var  entry = new PackedEntry {
                        Name   = string.Format("{0}-{1:D6}", section_num, i),
                        Offset = base_offset,
                        Size   = size,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    if (section_num < DefaultSections.Length && DefaultSections[section_num] != null)
                    {
                        entry.Type = DefaultSections[section_num];
                    }
                    if ("script" == entry.Type)
                    {
                        entry.IsPacked = true;
                    }
                    dir.Add(entry);
                    base_offset += size;
                    ++i;
                }while (i < file_count && !section_table.ContainsKey(i));
                ++section_num;
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #27
0
        public async Task <List <PackedEntry> > PackServerData(bool saveExecutable, ServerPresetPackMode mode, bool evbMode, CancellationToken cancellation)
        {
            var result = new List <PackedEntry>();

            // Wrapper
            if (ProvideDetails && DetailsMode == ServerPresetDetailsMode.ViaWrapper)
            {
                if (saveExecutable)
                {
                    string wrapper;
                    switch (mode)
                    {
                    case ServerPresetPackMode.Linux32:
                        wrapper = await LoadLinux32Wrapper(cancellation);

                        break;

                    case ServerPresetPackMode.Linux64:
                        wrapper = await LoadLinux64Wrapper(cancellation);

                        break;

                    case ServerPresetPackMode.Windows:
                        wrapper = await LoadWinWrapper(cancellation);

                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
                    }

                    if (cancellation.IsCancellationRequested)
                    {
                        return(null);
                    }

                    if (wrapper == null)
                    {
                        throw new InformativeException("Can’t pack server", "Can’t load server wrapper.");
                    }

                    // Actual wrapper, compiled to a single exe-file
                    result.Add(PackedEntry.FromFile(
                                   mode == ServerPresetPackMode.Windows ? @"acServerWrapper.exe" : @"acServerWrapper",
                                   wrapper));

                    // For EVB
                    if (evbMode)
                    {
                        result.Add(PackedEntry.FromContent("arguments.json", new JArray {
                            @"--copy-executable-to=acServer_tmp.exe",
                        }.ToString(Formatting.Indented)));
                    }
                }

                // Params
                var wrapperParams = _wrapperParamsJson?.DeepClone() as JObject;
                SetWrapperParams(ref wrapperParams);
                result.Add(PackedEntry.FromContent(@"cfg/cm_wrapper_params.json", wrapperParams.ToString(Formatting.Indented)));

                // Content
                if (DetailsContentJObject != null)
                {
                    void ProcessPiece(JObject piece)
                    {
                        var file = (string)piece?[@"file"];

                        if (piece == null || file == null)
                        {
                            return;
                        }

                        var filename = Path.IsPathRooted(file) ? file : Path.Combine(WrapperContentDirectory, file);

                        if (!FileUtils.ArePathsEqual(WrapperContentDirectory, Path.GetDirectoryName(filename)))
                        {
                            piece[@"file"] = Path.GetFileName(filename);
                        }

                        result.Add(PackedEntry.FromFile($"cfg/cm_content/{Path.GetFileName(filename)}", filename));
                    }

                    void ProcessPieces(JToken token, string childrenKey = null)
                    {
                        if (!(token is JObject o))
                        {
                            return;
                        }
                        foreach (var t in o)
                        {
                            var b = (JObject)t.Value;
                            if (b == null)
                            {
                                continue;
                            }
                            ProcessPiece(b);
                            if (childrenKey != null)
                            {
                                ProcessPieces(b[childrenKey]);
                            }
                        }
                    }

                    var content = DetailsContentJObject.DeepClone();
                    ProcessPieces(content[@"cars"], @"skins");
                    ProcessPiece(content[@"track"] as JObject);
                    ProcessPieces(content[@"weather"]);
                    result.Add(PackedEntry.FromContent("cfg/cm_content/content.json", content.ToString(Formatting.Indented)));
                }
                else
                {
                    result.Add(PackedEntry.FromContent("cfg/cm_content/content.json", @"{}"));
                }
            }

            // Executable
            if (saveExecutable)
            {
                var serverDirectory = ServerPresetsManager.ServerDirectory;
                result.Add(PackedEntry.FromFile(
                               mode == ServerPresetPackMode.Windows ? @"acServer.exe" : @"acServer",
                               Path.Combine(serverDirectory, mode == ServerPresetPackMode.Windows ? @"acServer.exe" : @"acServer")));
            }

            // Main config file
            var serverCfg   = IniObject?.Clone() ?? new IniFile(IniFileMode.ValuesWithSemicolons);
            var dataSection = serverCfg["DATA"];

            SaveData(serverCfg);

            if (ProvideDetails)
            {
                if (DetailsMode == ServerPresetDetailsMode.ViaWrapper)
                {
                    serverCfg["SERVER"].Set("NAME", $"{Name} {ServerEntry.ExtendedSeparator}{WrapperPort}");
                }
                else
                {
                    await EnsureDetailsNameIsActualAsync(serverCfg);
                }
            }

            // Welcome message
            if (!string.IsNullOrEmpty(WelcomeMessage))
            {
                result.Add(PackedEntry.FromContent("cfg/welcome.txt", WelcomeMessage));
                serverCfg["SERVER"].Set("WELCOME_MESSAGE", "cfg/welcome.txt");
                dataSection.Set("WELCOME_PATH", "cfg/welcome.txt");
            }

            // Setups
            var setupIndex = 0;

            foreach (var key in dataSection.Keys.Where(x => x.StartsWith(@"FIXED_SETUP_")).ToList())
            {
                dataSection.Remove(key);
            }
            foreach (var item in SetupItems)
            {
                if (!File.Exists(item.Filename))
                {
                    continue;
                }
                var name = $@"cfg/setup_{setupIndex}_{item.CarId}.ini";
                result.Add(PackedEntry.FromFile(name, item.Filename));
                dataSection[@"FIXED_SETUP_" + setupIndex] = $@"{(item.IsDefault ? @"1" : @"0")}|{name}";
                setupIndex++;
            }

            result.Add(PackedEntry.FromContent("cfg/server_cfg.ini", serverCfg.Stringify()));

            // Entry list
            var entryList = EntryListIniObject?.Clone() ?? new IniFile();

            entryList.SetSections("CAR", DriverEntries, (entry, section) => entry.SaveTo(section));
            result.Add(PackedEntry.FromContent("cfg/entry_list.ini", entryList.Stringify()));

            // Cars
            var root = AcRootDirectory.Instance.RequireValue;

            for (var i = 0; i < CarIds.Length; i++)
            {
                var carId      = CarIds[i];
                var packedData = Path.Combine(AcPaths.GetCarDirectory(root, carId), "data.acd");
                if (File.Exists(packedData))
                {
                    result.Add(PackedEntry.FromFile(Path.Combine(@"content", @"cars", carId, @"data.acd"), packedData));
                }
            }

            // Track
            var localPath = TrackLayoutId != null?Path.Combine(TrackId, TrackLayoutId) : TrackId;

            foreach (var file in TrackDataToKeep)
            {
                var actualData = Path.Combine(AcPaths.GetTracksDirectory(root), localPath, @"data", file);
                if (File.Exists(actualData))
                {
                    result.Add(PackedEntry.FromFile(Path.Combine(@"content", @"tracks", localPath, @"data", file), actualData));
                }
            }

            // System
            var systemSurfaces = Path.Combine(ServerPresetsManager.ServerDirectory, "system", "data", "surfaces.ini");

            if (File.Exists(systemSurfaces))
            {
                result.Add(PackedEntry.FromFile("system/data/surfaces.ini", systemSurfaces));
            }

            return(result);
        }
Exemple #28
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version = file.View.ReadByte (3) - '0';
            int count = file.View.ReadInt32 (4);
            if (!IsSaneCount (count))
                return null;

            int index_offset = 8;
            var index = new List<Tuple<int, int>> (count);
            for (int i = 0; i < count; ++i)
            {
                int size   = file.View.ReadInt32 (index_offset);
                int offset = file.View.ReadInt32 (index_offset+4);
                index_offset += 8;
                if (size != 0)
                    index.Add (Tuple.Create (offset, size));
            }
            var dir = new List<Entry>();
            foreach (var section in index)
            {
                index_offset = section.Item1;
                for (int section_size = section.Item2; section_size > 0; )
                {
                    int entry_size = file.View.ReadByte (index_offset);
                    if (entry_size < 5)
                        break;
                    var entry = new PackedEntry {
                        Offset = Binary.BigEndian (file.View.ReadUInt32 (index_offset+1)),
                        Name = file.View.ReadString (index_offset+5, (uint)entry_size-5),
                    };
                    if (entry.Offset > file.MaxOffset)
                        return null;
                    index_offset += entry_size;
                    section_size -= entry_size;
                    dir.Add (entry);
                }
            }
            DetectFileTypes (file, dir);
            return new ArcFile (file, this, dir);
        }
Exemple #29
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32 (4);
            if (!IsSaneCount (count))
                return null;

            long next_offset = file.View.ReadUInt32 (8);
            uint index_offset = 0xC;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                if (next_offset > file.MaxOffset)
                    return null;
                var entry = new PackedEntry {
                    Name = i.ToString ("D5"),
                    Offset = next_offset,
                };
                next_offset = i + 1 == count ? file.MaxOffset : file.View.ReadUInt32 (index_offset);
                index_offset += 4;
                entry.Size = (uint)(next_offset - entry.Offset);
                dir.Add (entry);
            }
            DetectFileTypes (file, dir);
            return new ArcFile (file, this, dir);
        }
Exemple #30
0
 uint WriteImageEntry(PackedEntry entry, Stream input, Stream output)
 {
     var grp = s_grp_format.Value;
     if (null == grp) // probably never happens
         throw new FileFormatException ("GRP image encoder not available");
     bool is_grp = grp.Signature == FormatCatalog.ReadSignature (input);
     input.Position = 0;
     var start = output.Position;
     using (var zstream = new ZLibStream (output, CompressionMode.Compress, CompressionLevel.Level9, true))
     {
         if (is_grp)
         {
             input.CopyTo (zstream);
         }
         else
         {
             var image = ImageFormat.Read (input);
             if (null == image)
                 throw new InvalidFormatException (string.Format (arcStrings.MsgInvalidImageFormat, entry.Name));
             grp.Write (zstream, image);
             entry.UnpackedSize = (uint)zstream.TotalIn;
         }
     }
     return (uint)(output.Position - start);
 }
Exemple #31
0
        Stream OpenTpw(ArcFile arc, PackedEntry entry)
        {
            var output = new byte[entry.UnpackedSize];

            using (var input = arc.File.CreateStream(entry.Offset, entry.Size))
            {
                input.Position = 8;
                var offsets = new int[4];
                offsets[0] = input.ReadUInt16();
                offsets[1] = offsets[0] * 2;
                offsets[2] = offsets[0] * 3;
                offsets[3] = offsets[0] * 4;
                int dst = 0;
                while (dst < output.Length)
                {
                    byte ctl = input.ReadUInt8();
                    if (0 == ctl)
                    {
                        break;
                    }
                    int count;
                    if (ctl < 0x40)
                    {
                        input.Read(output, dst, ctl);
                        dst += ctl;
                    }
                    else if (ctl <= 0x6F)
                    {
                        if (0x6F == ctl)
                        {
                            count = input.ReadUInt16();
                        }
                        else
                        {
                            count = (ctl + 0xC3) & 0xFF;
                        }
                        byte v = input.ReadUInt8();
                        while (count-- > 0)
                        {
                            output[dst++] = v;
                        }
                    }
                    else if (ctl <= 0x9F)
                    {
                        if (ctl == 0x9F)
                        {
                            count = input.ReadUInt16();
                        }
                        else
                        {
                            count = (ctl + 0x92) & 0xFF;
                        }
                        byte v1 = input.ReadUInt8();
                        byte v2 = input.ReadUInt8();
                        while (count-- > 0)
                        {
                            output[dst++] = v1;
                            output[dst++] = v2;
                        }
                    }
                    else if (ctl <= 0xBF)
                    {
                        if (ctl == 0xBF)
                        {
                            count = input.ReadUInt16();
                        }
                        else
                        {
                            count = ((ctl + 0x62) & 0xFF);
                        }
                        input.Read(output, dst, 3);
                        if (count > 0)
                        {
                            count *= 3;
                            Binary.CopyOverlapped(output, dst, dst + 3, count - 3);
                            dst += count;
                        }
                    }
                    else
                    {
                        count = (ctl & 0x3F) + 3;
                        int offset = input.ReadUInt8();
                        offset = (offset & 0x3F) - offsets[offset >> 6];
                        Binary.CopyOverlapped(output, dst + offset, dst, count);
                        dst += count;
                    }
                }
                return(new BinMemoryStream(output, entry.Name));
            }
        }
Exemple #32
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            long offset = 4 + count * 4;

            if (offset >= file.MaxOffset)
            {
                return(null);
            }
            uint index_offset = 4;
            var  dir          = new List <Entry>();

            for (int i = 0; i < count; ++i)
            {
                uint size = file.View.ReadUInt32(index_offset);
                if (0 != size)
                {
                    var entry = new PackedEntry
                    {
                        Name     = i.ToString("D5"),
                        Offset   = offset,
                        Size     = size,
                        IsPacked = false,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    offset += size;
                }
                index_offset += 4;
            }
            if (offset != file.MaxOffset || 0 == dir.Count)
            {
                return(null);
            }
            byte[] preview  = new byte[16];
            byte[] sign_buf = new byte[4];
            foreach (PackedEntry entry in dir)
            {
                uint extra = 6;
                if (extra > entry.Size)
                {
                    continue;
                }
                int label = file.View.ReadUInt16(entry.Offset);
                if (1 == label)
                {
                    entry.IsPacked     = true;
                    entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 2);
                }
                entry.Offset += extra;
                entry.Size   -= extra;
                uint signature;
                if (entry.IsPacked)
                {
                    file.View.Read(entry.Offset, preview, 0, (uint)preview.Length);
                    using (var input = new MemoryStream(preview))
                    {
                        LzssUnpack(input, sign_buf);
                        signature = LittleEndian.ToUInt32(sign_buf, 0);
                    }
                }
                else
                {
                    signature = file.View.ReadUInt32(entry.Offset);
                }
                if (0 != signature)
                {
                    SetEntryType(entry, signature);
                }
            }
            return(new ArcFile(file, this, dir));
        }