Example #1
0
 public PropertyFile(Gibbed.Spore.Package.DatabaseIndex index)
 {
     byte[] data = index.GetIndexData(true);
     using (Stream s = new MemoryStream(data, 0, data.Length))
     {
         this.Read(s);
     }
 }
Example #2
0
        public void Read(Stream stream)
        {
            bool big = false;
            Int64 indexCount;
            Int64 indexSize;
            Int64 indexOffset;

            uint magic = stream.ReadU32();
            if (magic != 0x46504244 && magic != 0x46424244) // DBPF & DBBF
            {
                throw new NotAPackageException();
            }

            if (magic == 0x46424244) // DBBF
            {
                big = true;

                DatabaseBigPackageFileHeader header;
                byte[] data = new byte[Marshal.SizeOf(typeof(DatabaseBigPackageFileHeader))];

                if (data.Length != (120 - 4))
                {
                    throw new Exception("DatabaseBigPackageFileHeader is wrong size (" + data.Length.ToString() + ")");
                }

                stream.Read(data, 0, data.Length);
                header = (DatabaseBigPackageFileHeader)data.BytesToStructure(typeof(DatabaseBigPackageFileHeader));

                if (header.Always3 != 3)
                {
                    throw new Exception("the value in the DBBF header that is always 3 was not 3");
                }

                // Nab useful stuff
                this.Version = new Version(header.MajorVersion, header.MinorVersion);
                indexCount = header.IndexCount;
                indexOffset = header.IndexOffset;
                indexSize = header.IndexSize;
            }
            else
            {
                big = false;

                DatabasePackedFileHeader header;
                byte[] data = new byte[Marshal.SizeOf(typeof(DatabasePackedFileHeader))];

                if (data.Length != (96 - 4))
                {
                    throw new Exception("DatabasePackageFileHeader is wrong size (" + data.Length.ToString() + ")");
                }

                stream.Read(data, 0, data.Length);
                header = (DatabasePackedFileHeader)data.BytesToStructure(typeof(DatabasePackedFileHeader));

                if (header.Always3 != 3)
                {
                    throw new Exception("the value in the DBPF header that is always 3 was not 3");
                }

                // Nab useful stuff
                this.Version = new Version(header.MajorVersion, header.MinorVersion);
                indexCount = header.IndexCount;
                indexOffset = header.IndexOffset;
                indexSize = header.IndexSize;
            }

            this.Indices = new List<DatabaseIndex>();

            if (indexCount > 0)
            {
                // Read index
                stream.Seek(indexOffset, SeekOrigin.Begin);

                int indexHeaderValues = stream.ReadS32();
                if (indexHeaderValues < 4 || indexHeaderValues > 7)
                {
                    throw new InvalidDataException("don't know how to handle this index data");
                }

                uint indexTypeId = 0xCAFEBABE;
                // type id
                if ((indexHeaderValues & (1 << 0)) == 1 << 0)
                {
                    indexTypeId = stream.ReadU32();
                }

                uint indexGroupId = 0xCAFEBABE;
                // group id
                if ((indexHeaderValues & (1 << 1)) == 1 << 1)
                {
                    indexGroupId = stream.ReadU32();
                }

                uint indexUnknown = 0xCAFEBABE;
                // unknown value
                if ((indexHeaderValues & (1 << 2)) == 1 << 2)
                {
                    indexUnknown = stream.ReadU32();
                }

                for (int i = 0; i < indexCount; i++)
                {
                    DatabaseIndex index = new DatabaseIndex();
                    #region index.TypeId
                    if ((indexHeaderValues & (1 << 0)) == 1 << 0)
                    {
                        index.TypeId = indexTypeId;
                    }
                    else
                    {
                        index.TypeId = stream.ReadU32();
                    }
                    #endregion
                    #region index.GroupId
                    if ((indexHeaderValues & (1 << 1)) == 1 << 1)
                    {
                        index.GroupId = indexGroupId;
                    }
                    else
                    {
                        index.GroupId = stream.ReadU32();
                    }
                    #endregion
                    #region index.Unknown
                    if ((indexHeaderValues & (1 << 2)) == 1 << 2)
                    {
                        index.Unknown = indexUnknown;
                    }
                    else
                    {
                        index.Unknown = stream.ReadU32();
                    }
                    #endregion
                    index.InstanceId = stream.ReadU32();

                    if (big == true)
                    {
                        index.Offset = stream.ReadS64();
                    }
                    else
                    {
                        index.Offset = stream.ReadS32();
                    }

                    index.CompressedSize = stream.ReadU32();
                    index.DecompressedSize = stream.ReadU32();
                    index.CompressedFlags = stream.ReadS16();
                    index.Flags = stream.ReadU16();
                    index.CheckCompressed();

                    this.Indices.Add(index);
                }
            }
        }
        public void Read(Stream stream)
        {
            bool  big = false;
            Int64 indexCount;
            Int64 indexSize;
            Int64 indexOffset;

            uint magic = stream.ReadU32();

            if (magic != 0x46504244 && magic != 0x46424244)             // DBPF & DBBF
            {
                throw new NotAPackageException();
            }

            if (magic == 0x46424244)             // DBBF
            {
                big = true;

                DatabaseBigPackageFileHeader header;
                byte[] data = new byte[Marshal.SizeOf(typeof(DatabaseBigPackageFileHeader))];

                if (data.Length != (120 - 4))
                {
                    throw new Exception("DatabaseBigPackageFileHeader is wrong size (" + data.Length.ToString() + ")");
                }

                stream.Read(data, 0, data.Length);
                header = (DatabaseBigPackageFileHeader)data.BytesToStructure(typeof(DatabaseBigPackageFileHeader));

                if (header.Always3 != 3)
                {
                    throw new Exception("the value in the DBBF header that is always 3 was not 3");
                }

                // Nab useful stuff
                this.Version = new Version(header.MajorVersion, header.MinorVersion);
                indexCount   = header.IndexCount;
                indexOffset  = header.IndexOffset;
                indexSize    = header.IndexSize;
            }
            else
            {
                big = false;

                DatabasePackedFileHeader header;
                byte[] data = new byte[Marshal.SizeOf(typeof(DatabasePackedFileHeader))];

                if (data.Length != (96 - 4))
                {
                    throw new Exception("DatabasePackageFileHeader is wrong size (" + data.Length.ToString() + ")");
                }

                stream.Read(data, 0, data.Length);
                header = (DatabasePackedFileHeader)data.BytesToStructure(typeof(DatabasePackedFileHeader));

                if (header.Always3 != 3)
                {
                    throw new Exception("the value in the DBPF header that is always 3 was not 3");
                }

                // Nab useful stuff
                this.Version = new Version(header.MajorVersion, header.MinorVersion);
                indexCount   = header.IndexCount;
                indexOffset  = header.IndexOffset;
                indexSize    = header.IndexSize;
            }

            this.Indices = new List <DatabaseIndex>();

            if (indexCount > 0)
            {
                // Read index
                stream.Seek(indexOffset, SeekOrigin.Begin);

                int indexHeaderValues = stream.ReadS32();
                if (indexHeaderValues < 4 || indexHeaderValues > 7)
                {
                    throw new InvalidDataException("don't know how to handle this index data");
                }

                uint indexTypeId = 0xCAFEBABE;
                // type id
                if ((indexHeaderValues & (1 << 0)) == 1 << 0)
                {
                    indexTypeId = stream.ReadU32();
                }

                uint indexGroupId = 0xCAFEBABE;
                // group id
                if ((indexHeaderValues & (1 << 1)) == 1 << 1)
                {
                    indexGroupId = stream.ReadU32();
                }

                uint indexUnknown = 0xCAFEBABE;
                // unknown value
                if ((indexHeaderValues & (1 << 2)) == 1 << 2)
                {
                    indexUnknown = stream.ReadU32();
                }

                for (int i = 0; i < indexCount; i++)
                {
                    DatabaseIndex index = new DatabaseIndex();
                    #region index.TypeId
                    if ((indexHeaderValues & (1 << 0)) == 1 << 0)
                    {
                        index.TypeId = indexTypeId;
                    }
                    else
                    {
                        index.TypeId = stream.ReadU32();
                    }
                    #endregion
                    #region index.GroupId
                    if ((indexHeaderValues & (1 << 1)) == 1 << 1)
                    {
                        index.GroupId = indexGroupId;
                    }
                    else
                    {
                        index.GroupId = stream.ReadU32();
                    }
                    #endregion
                    #region index.Unknown
                    if ((indexHeaderValues & (1 << 2)) == 1 << 2)
                    {
                        index.Unknown = indexUnknown;
                    }
                    else
                    {
                        index.Unknown = stream.ReadU32();
                    }
                    #endregion
                    index.InstanceId = stream.ReadU32();

                    if (big == true)
                    {
                        index.Offset = stream.ReadS64();
                    }
                    else
                    {
                        index.Offset = stream.ReadS32();
                    }

                    index.CompressedSize   = stream.ReadU32();
                    index.DecompressedSize = stream.ReadU32();
                    index.CompressedFlags  = stream.ReadS16();
                    index.Flags            = stream.ReadU16();
                    index.CheckCompressed();

                    this.Indices.Add(index);
                }
            }
        }
Example #4
0
        public PackagePack(Stream output, string sourceFolder, PleaseWait progress)
        {
            NameRegistry.Files.UsedHashes = new List<UInt32>();

            var group_dirs = Directory.GetDirectories(sourceFolder);
            var file_query = from d in group_dirs
                                where d != sourceFolder + "\\sporemaster\\"
                                from f in Directory.GetFileSystemEntries(d)
                                where !f.EndsWith(".search_index")  // < these might appear in group directories if there are indexable files in subdirectories
                                select f;
            var files = file_query.ToList();
            files.Add(sourceFolder + "\\sporemaster\\names.txt");

            if (progress != null) progress.beginTask(1.0, files.Count);

            DatabasePackedFile dbf = new DatabasePackedFile();
            dbf.Version = new Version(2, 0);
            dbf.WriteHeader(output, 0, 0);

            var rw4_hash = NameRegistry.Types.toHash("rw4");

            uint size, start = (uint)output.Position;
            foreach( var f in files ) {
                string relativePath = f.Substring(sourceFolder.Length + 1);
                bool additionalOutputFiles;
                byte[] autoLocale = null;
                do
                {
                    additionalOutputFiles = false;

                    var parts = relativePath.Split(new char[] { '\\' });
                    if (parts.Length != 2) continue;
                    var group = parts[0];
                    parts = parts[1].Split(new char[] { '.' }, 2);
                    var instance = parts[0];
                    var extension = parts[1];
                    var index = new DatabaseIndex();
                    index.GroupId = NameRegistry.Groups.toHash(group);
                    index.InstanceId = NameRegistry.Files.toHash(instance);

                    try
                    {
                        if (relativePath == "sporemaster\\names.txt")
                        {
                            writeNamesFile(output);
                        }
                        else if (autoLocale != null)
                        {
                            output.Write(autoLocale, 0, autoLocale.Length);
                        }
                        else if (extension == "prop.xml")
                        {
                            extension = "prop";
                            writePropFile(group, instance, f, output, out autoLocale);
                            if (autoLocale.Length != 0)
                            {
                                additionalOutputFiles = true;
                                relativePath = "locale~\\auto_" + group + "_" + instance + ".locale";
                            }
                        }
                        else if (NameRegistry.Types.toHash(extension)==rw4_hash && Directory.Exists(f))
                        {
                            writeRW4File(f, output);
                        }
                        else
                            writeBinaryFile(f, output);
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Error packing file '" + relativePath + "'.", e);
                    }

                    size = (uint)output.Position - start;

                    index.TypeId = NameRegistry.Types.toHash(extension);
                    index.Compressed = false;
                    index.Flags = 1;
                    index.DecompressedSize = size;
                    index.CompressedSize = size | 0x80000000;
                    index.Offset = start;
                    dbf.Indices.Add(index);
                    start += size;
                } while (additionalOutputFiles);

                progress.addProgress(1.0);
            }

            dbf.WriteIndex(output);
            size = (uint)output.Position - start;
            output.Seek(0, SeekOrigin.Begin);
            dbf.WriteHeader(output, (int)start, (int)size);

            output.Close();

            if (progress != null) progress.endTask();
        }
Example #5
0
 private byte[] unpack(Stream archive, DatabaseIndex index)
 {
     if (index.Compressed)
     {
         archive.Seek(index.Offset, SeekOrigin.Begin);
         return archive.RefPackDecompress(index.CompressedSize, index.DecompressedSize);
     }
     else
     {
         archive.Seek(index.Offset, SeekOrigin.Begin);
         byte[] d = new byte[index.DecompressedSize];
         archive.Read(d, 0, d.Length);
         return d;
     }
 }