Exemple #1
0
 public void Write(AssetsWriter writer)
 {
     writer.WriteBEInt64(Offset);
     writer.WriteBEInt64(Size);
     writer.WriteBEUInt32(_flags);
     writer.WriteCString(Filename);
 }
Exemple #2
0
 public void Write(AssetsWriter writer)
 {
     writer.Write(ObjectID);
     writer.Write(DataOffset);
     writer.Write(DataSize);
     writer.Write(TypeIndex);
 }
Exemple #3
0
 public void Write(AssetsWriter writer)
 {
     writer.WriteBEInt32(MetadataSize);
     writer.WriteBEInt32(FileSize);
     writer.WriteBEInt32(Version);
     writer.WriteBEInt32(ObjectDataOffset);
     writer.Write(IsBigEndian);
     writer.AlignTo(4);
     //writer.Write(new byte[3]);
 }
Exemple #4
0
 public void Write(AssetsWriter writer)
 {
     writer.Write(Entries.Count());
     writer.Write(StringBuffer.Length);
     foreach (var entry in Entries)
     {
         entry.Write(writer);
     }
     writer.WriteChars(StringBuffer);
 }
Exemple #5
0
 public void Write(AssetsWriter writer)
 {
     writer.Write(Version);
     writer.Write(Depth);
     writer.Write(IsArray);
     writer.Write(TypeOffset);
     writer.Write(NameOffset);
     writer.Write(Size);
     writer.Write(Index);
     writer.Write(Flags);
 }
Exemple #6
0
 public int GetSize()
 {
     using (MemoryStream ms = new MemoryStream())
     {
         using (AssetsWriter writer = new AssetsWriter(ms))
         {
             WriteObject(writer);
         }
         return((int)ms.Length);
     }
 }
Exemple #7
0
 public void WritePtr(AssetsWriter writer)
 {
     if (isNull)
     {
         byte[] buf = new byte[12];
         writer.Write(buf);
         return;
     }
     writer.Write(FileID);
     writer.AlignTo(4);
     writer.Write(Target.ObjectID);
 }
Exemple #8
0
        public void Write(AssetsWriter writer, byte[] compressedData)
        {
            if (fileVersion != 6)
            {
                throw new NotSupportedException("File version is not supported");
            }
            //basic header stuff
            writer.WriteCString(signature);
            writer.WriteBEInt32(fileVersion);
            // TODO ADD
            // WriteDirectory to a MemoryStream
            // Check length of the resultant byte array, should be = UncompressedLength
            // Compress it
            // Write compressed length
            MemoryStream s = new MemoryStream();

            using (AssetsWriter w = new AssetsWriter(s))
            {
                WriteDirectory(w);
            }
            int uncompressedLength = (int)s.Length;
            // todo
            var compressedMetadata = LZ4.LZ4Codec.EncodeHC(s.ToArray(), 0, uncompressedLength);

            BundleSize += compressedMetadata.Length;
            writer.WriteCString(PlayerVersion);
            writer.WriteCString(EngineVersion);
            writer.WriteBEInt64(BundleSize);

            // compressedSize is actually the size of the METADATA byte array
            // The one with the Entries and BlockInfos + unknown directory header
            writer.WriteBEInt32(compressedMetadata.Length);
            writer.WriteBEInt32(uncompressedLength);
            writer.WriteBEUInt32(flags);

            if (!IsDirectoryAtEnd(flags))
            {
                // Actually write the directory information to the file
                writer.Write(compressedMetadata);
            }
            // Now write the actual data the BlockInfos use
            writer.Write(compressedData);
            if (IsDirectoryAtEnd(flags))
            {
                // Actually write the directory information to the file
                writer.Write(compressedMetadata);
            }
        }
Exemple #9
0
        public void Write(AssetsWriter writer)
        {
            writer.Write(ClassID);
            writer.Write(Unknown1);
            writer.Write(Unknown2);
            if (IsScriptType)
            {
                writer.Write(ScriptHash);
            }
            writer.Write(TypeHash);

            if (TypeTree != null)
            {
                TypeTree.Write(writer);
            }
        }
Exemple #10
0
 public void Write(AssetsWriter writer)
 {
     Texture.Write(writer);
     AlphaTexture.Write(writer);
     writer.WriteArrayOf(SubMeshes, (o, w) => o.Write(w));
     writer.WriteArray(IndexBuffer);
     writer.AlignTo(4);
     VertexData.Write(writer);
     writer.WriteArrayOf(BindPose, (o, w) => w.Write(o));
     TextureRect.Write(writer);
     TextureRectOffset.Write(writer);
     AtlasRectOffset.Write(writer);
     writer.Write(SettingsRaw);
     UVTransform.Write(writer);
     writer.Write(DownscaleMultiplier);
 }
Exemple #11
0
        private void WriteDirectory(AssetsWriter writer)
        {
            //unknown?
            writer.Write(_directoryUnknown);
            writer.WriteBEInt32(BlockInfos.Count);

            for (int i = 0; i < BlockInfos.Count; i++)
            {
                BlockInfos[i].Write(writer);
            }

            writer.WriteBEInt32(Entries.Count);
            for (int i = 0; i < Entries.Count; i++)
            {
                Entries[i].Write(writer);
            }
        }
Exemple #12
0
 protected override void WriteBase(AssetsWriter writer)
 {
     base.WriteBase(writer);
     writer.Write(Name);
     Rect.Write(writer);
     Offset.Write(writer);
     Border.Write(writer);
     writer.Write(PixelsToUnits);
     Pivot.Write(writer);
     writer.Write(Extrude);
     writer.Write(IsPolygon);
     writer.AlignTo(4);
     writer.Write(RenderDataKey.First);
     writer.Write(RenderDataKey.Second);
     writer.WriteArrayOf(AtlasTags, (o, w) => w.Write(o));
     SpriteAtlas.Write(writer);
     RenderData.Write(writer);
     writer.WriteArrayOf(PhysicsShape, (o, w) => w.WriteArrayOf(o, (o2, w2) => o2.Write(w2)));
     writer.WriteArrayOf(Bones, (o, w) => o.Write(w));
 }
Exemple #13
0
 public void Write(AssetsWriter writer)
 {
     writer.WriteCString(Version);
     writer.Write(Platform);
     writer.Write(HasTypeTrees);
     writer.Write(Types.Count());
     Types.ForEach(x => x.Write(writer));
     writer.Write(ObjectInfos.Count());
     ObjectInfos.ForEach(x => {
         writer.AlignTo(4);
         x.Write(writer);
     });
     writer.Write(Adds.Count());
     Adds.ForEach(x => {
         writer.AlignTo(4);
         x.Write(writer);
     });
     writer.Write(ExternalFiles.Count());
     ExternalFiles.ForEach(x => x.Write(writer));
     writer.WriteCString("");
 }
Exemple #14
0
 public void Write(AssetsWriter writer)
 {
     writer.Write(FileID);
     writer.AlignTo(4);
     writer.Write(PathID);
 }
Exemple #15
0
 public void Write(AssetsWriter writer)
 {
     WriteBase(writer);
     WriteObject(writer);
 }
Exemple #16
0
 public void Write(AssetsWriter writer)
 {
     writer.WriteBEUInt32(UncompressedSize);
     writer.WriteBEUInt32(CompressedSize);
     writer.WriteBEUInt16(_flags);
 }
Exemple #17
0
 protected virtual void WriteObject(AssetsWriter writer)
 {
     writer.Write(Data);
 }
Exemple #18
0
        // TODO BASICALLY FIX THIS ENTIRE FUNCTION
        public void Save(Stream stream)
        {
            // Fix parsing of DirectoryEntries
            long offset = 0;

            var oldBIs = new List <BlockInfo>();

            foreach (var bi in BlockInfos)
            {
                oldBIs.Add(bi);
            }

            uint blockLen = BlockInfos[0].UncompressedSize;

            long compsum   = 0;
            long uncompsum = 0;

            foreach (var bi in BlockInfos)
            {
                compsum   += bi.CompressedSize;
                uncompsum += bi.UncompressedSize;
            }
            var unknownDict = new Dictionary <int, BlockInfo>();

            for (int i = 0; i < BlockInfos.Count; i++)
            {
                if (BlockInfos[i].CompressionMode != UnityFSCompressionMode.LZ4HC)
                {
                    unknownDict.Add(i, BlockInfos[i]);
                }
            }

            List <byte> data             = new List <byte>();
            List <byte> compressed       = new List <byte>();
            long        uncompressedSize = 0;

            for (int i = 0; i < Entries.Count; i++)
            {
                Entries[i].Offset = offset;
                offset           += Entries[i].Size;
                uncompressedSize += Entries[i].Size;
                data.AddRange(Entries[i].Data);
            }
            // offset = length of stream
            // Fix parsing of all blocks
            UnityFSCompressionMode compMode = BlockInfos[0].CompressionMode;
            long blockCount = uncompressedSize / blockLen + 1;

            BlockInfos.Clear();
            BundleSize = 0;
            for (int i = 0; i < blockCount; i++)
            {
                long len = blockLen;
                if (uncompressedSize - i * blockLen < blockLen)
                {
                    // Not correct size!
                    len = uncompressedSize - i * blockLen;
                }
                var bts = data.GetRange((int)(i * blockLen), (int)len);
                if (unknownDict.ContainsKey(i))
                {
                    // This is actually a really poor way of doing it, I really need to clean all of this up
                    BlockInfos.Add(new BlockInfo()
                    {
                        UncompressedSize = (uint)len,
                        CompressionMode  = unknownDict[i].CompressionMode,
                        CompressedSize   = (uint)len
                    });
                    compressed.AddRange(bts.ToArray());
                }
                else
                {
                    //byte[] o = new byte[oldBIs[i].CompressedSize];
                    //var dat = LZ4.LZ4Codec.EncodeHC(bts.ToArray(), 0, bts.Count, o, 0, (int)oldBIs[i].CompressedSize);

                    var dat = LZ4.LZ4Codec.EncodeHC(bts.ToArray(), 0, bts.Count);

                    LZ4.LZ4Codec.Decode(dat, 0, dat.Length, bts.Count);
                    //var q = LZ4.LZ4Codec.Decode(dat, 0, dat, bts.Count);

                    //for (int l = 0; l < q.Length; l++)
                    //{
                    //    if (q[l] != bts[l])
                    //        Console.WriteLine("Byte does not match error");
                    //}

                    compressed.AddRange(dat);

                    BlockInfos.Add(new BlockInfo()
                    {
                        UncompressedSize = (uint)len,
                        CompressionMode  = compMode,
                        CompressedSize   = (uint)dat.Length
                    });
                }
            }
            BundleSize = compressed.Count;

            using (AssetsWriter writer = new AssetsWriter(stream))
            {
                Write(writer, compressed.ToArray());
            }
        }
Exemple #19
0
        public void Write()
        {
            try
            {
                using (Stream objectsMS = GetTempStream())
                {
                    using (Stream metaMS = GetTempStream())
                    {
                        using (AssetsWriter writer = new AssetsWriter(objectsMS))
                        {
                            int ctr = 0;
                            foreach (var obj in Metadata.ObjectInfos)
                            {
                                if (obj.IsNew)
                                {
                                    // Object is new here
                                    Console.WriteLine("Writing New object!");
                                }
                                ctr++;
                                var offset = (int)objectsMS.Position;
                                obj.GetObjectForWrite().Write(writer);
                                writer.Flush();
                                obj.DataOffset = offset;
                                var origSize = obj.DataSize;
                                obj.DataSize = (int)(objectsMS.Position - obj.DataOffset);
                                if (origSize != obj.DataSize)
                                {
                                    // TEMPORARY! MUST REMOVE!
                                    Console.WriteLine("MISMATCH!");
                                }
                                writer.AlignTo(8);
                            }
                        }
                        using (AssetsWriter writer = new AssetsWriter(metaMS))
                        {
                            // This is fine!
                            Metadata.Write(writer);
                        }
                        // objectMS is 8 bytes smaller than it should be here
                        Header.FileSize         = Header.HeaderSize + (int)objectsMS.Length + (int)metaMS.Length;
                        Header.ObjectDataOffset = Header.HeaderSize + (int)metaMS.Length;

                        int diff;
                        int alignment = 16; //or 32, I don't know which
                                            //data has to be at least 4096 inward from the start of the file
                        if (Header.ObjectDataOffset < 4096)
                        {
                            diff = 4096 - Header.ObjectDataOffset;
                        }
                        else
                        {
                            diff = alignment - (Header.ObjectDataOffset % alignment);
                            if (diff == alignment)
                            {
                                diff = 0;
                            }
                        }

                        if (diff > 0)
                        {
                            Header.ObjectDataOffset += diff;
                            Header.FileSize         += diff;
                        }
                        // According to parse, MetadataSize shrunk by 4
                        Header.MetadataSize = (int)metaMS.Length;
                        objectsMS.Seek(0, SeekOrigin.Begin);
                        metaMS.Seek(0, SeekOrigin.Begin);
                        lock (this)
                        {
                            try
                            {
                                CloseBaseStream();


                                FileProvider.DeleteFiles(AssetsRootPath.CombineFwdSlash(AssetsFilename + ".split*"));

                                using (Stream outputStream = GetTempStream())
                                {
                                    using (AssetsWriter writer = new AssetsWriter(outputStream))
                                    {
                                        Header.Write(writer);
                                    }
                                    metaMS.CopyTo(outputStream);
                                    metaMS.Close();


                                    if (diff > 0)
                                    {
                                        outputStream.Write(new byte[diff], 0, diff);
                                    }

                                    objectsMS.CopyTo(outputStream);
                                    objectsMS.Close();

                                    outputStream.Seek(0, SeekOrigin.Begin);
                                    if (FileWasSplit)
                                    {
                                        int    splitCtr = 0;
                                        byte[] buffer   = new byte[1024 * 1024];
                                        do
                                        {
                                            Stream outFile = FileProvider.GetWriteStream($"{AssetsRootPath.CombineFwdSlash(AssetsFilename)}.split{splitCtr}");
                                            var    readLen = (int)(outputStream.Length - outputStream.Position);
                                            if (readLen < buffer.Length)
                                            {
                                                outputStream.Read(buffer, 0, readLen);
                                                outFile.Write(buffer, 0, readLen);
                                                break;
                                            }
                                            outputStream.Read(buffer, 0, buffer.Length);
                                            outFile.Write(buffer, 0, buffer.Length);
                                            outFile.Close();
                                            splitCtr++;
                                        } while (true);
                                    }
                                    else
                                    {
                                        outputStream.Seek(0, SeekOrigin.Begin);
                                        var bts = outputStream.ReadBytes((int)outputStream.Length);
                                        FileProvider.Write(AssetsRootPath.CombineFwdSlash(AssetsFilename), bts);
                                    }
                                }
                                FileProvider.Save();
                                _hasChanges = false;
                                foreach (var ptr in _knownPointers.Where(x => x.Owner.ObjectInfo.ParentFile == this && x.IsNew))
                                {
                                    ptr.IsNew = false;
                                }
                                OpenBaseStream();
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("CRITICAL: writing and reopening the file failed, the file is possibly destroyed and this object is in an unknown state.", ex);
                            }
                        }
                    }
                }
            }
            finally
            {
                CleanupTempFiles();
            }
        }
Exemple #20
0
 public void Write(AssetsWriter writer)
 {
     writer.Write(PreloadIndex);
     writer.Write(PreloadSize);
     Asset.WritePtr(writer);
 }
Exemple #21
0
 protected virtual void WriteBase(AssetsWriter writer)
 {
 }