Exemple #1
0
        private void LoadAssetsFromMemory(string fullName, EndianBinaryStream stream, string originalPath, string unityVersion = null)
        {
            var fileName = Path.GetFileName(fullName);

            if (!assetsFileListHash.Contains(fileName))
            {
                try
                {
                    var assetsFile = new SerializedFile(this, fullName, stream)
                    {
                        originalPath = originalPath
                    };
                    if (assetsFile.header.m_Version < 7)
                    {
                        assetsFile.SetVersion(unityVersion);
                    }
                    assetsFileList.Add(assetsFile);
                    assetsFileListHash.Add(assetsFile.fileName);
                }
                catch
                {
                    //Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}");
                    resourceFileStreams.Add(fileName, stream);
                }
            }
        }
Exemple #2
0
        public static bool IsSerializedFile(EndianBinaryStream stream)
        {
            var fileSize = stream.Length;

            if (fileSize < 20)
            {
                return(false);
            }

            var reader = stream.InitReader();

            var  m_MetadataSize = reader.ReadUInt32();
            long m_FileSize     = reader.ReadUInt32();
            var  m_Version      = reader.ReadUInt32();
            long m_DataOffset   = reader.ReadUInt32();
            var  m_Endianess    = reader.ReadByte();
            var  m_Reserved     = reader.ReadBytes(3);

            if (m_Version < 22)
            {
                return(m_FileSize == fileSize && m_DataOffset <= fileSize);
            }

            if (fileSize < 48)
            {
                return(false);
            }
            m_MetadataSize = reader.ReadUInt32();
            m_FileSize     = reader.ReadInt64();
            m_DataOffset   = reader.ReadInt64();
            return(m_FileSize == fileSize && m_DataOffset <= fileSize);
        }
Exemple #3
0
        public BundleFile(EndianBinaryStream stream, string path)
        {
            var reader = stream.InitReader();

            m_Header = new Header {
                signature = reader.ReadStringToNull()
            };
            switch (m_Header.signature)
            {
            case "UnityArchive":
                break;     // TODO

            case "UnityWeb":
            case "UnityRaw":
                ReadHeaderAndBlocksInfo(reader);
                using (var blocksStream = CreateBlocksStream(path))
                {
                    ReadBlocksAndDirectory(reader, blocksStream);
                    ReadFiles(blocksStream, path);
                }
                break;

            case "UnityFS":
                ReadHeader(reader);
                ReadBlocksInfoAndDirectory(reader);
                using (var blocksStream = CreateBlocksStream(path))
                {
                    ReadBlocks(reader, blocksStream);
                    ReadFiles(blocksStream, path);
                }
                break;
            }

            reader.Dispose();
        }
Exemple #4
0
        private void LoadAssetsFile(string fullName, EndianBinaryStream stream)
        {
            var fileName = Path.GetFileName(fullName);

            if (!assetsFileListHash.Contains(fileName))
            {
                Logger.Info($"Loading {fileName}");
                try
                {
                    var assetsFile = new SerializedFile(this, fullName, stream);
                    assetsFileList.Add(assetsFile);
                    assetsFileListHash.Add(assetsFile.fileName);

                    foreach (var sharedFile in assetsFile.m_Externals)
                    {
                        var sharedFilePath = Path.Combine(Path.GetDirectoryName(fullName), sharedFile.fileName);
                        var sharedFileName = sharedFile.fileName;

                        if (!importFilesHash.Contains(sharedFileName))
                        {
                            if (!File.Exists(sharedFilePath))
                            {
                                var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
                                if (findFiles.Length > 0)
                                {
                                    sharedFilePath = findFiles[0];
                                }
                            }

                            if (File.Exists(sharedFilePath))
                            {
                                importFiles.Add(sharedFilePath);
                                importFilesHash.Add(sharedFileName);
                            }
                        }
                    }
                }
                catch
                {
                    stream.Dispose();
                    //Logger.Warning($"Unable to load assets file {fileName}");
                }
            }
            else
            {
                stream.Dispose();
            }
        }
        private static FileType CheckFileType(EndianBinaryStream stream)
        {
            var reader = stream.InitReader();

            var signature = reader.ReadStringToNull(20);

            reader.Position = 0;
            switch (signature)
            {
            case "UnityWeb":
            case "UnityRaw":
            case "UnityArchive":
            case "UnityFS":
                return(FileType.BundleFile);

            case "UnityWebData1.0":
                return(FileType.WebFile);

            default:
            {
                var magic = reader.ReadBytes(2);
                reader.Position = 0;
                if (WebFile.gzipMagic.SequenceEqual(magic))
                {
                    return(FileType.WebFile);
                }
                reader.Position = 0x20;
                magic           = reader.ReadBytes(6);
                reader.Position = 0;
                if (WebFile.brotliMagic.SequenceEqual(magic))
                {
                    return(FileType.WebFile);
                }
                if (SerializedFile.IsSerializedFile(stream))
                {
                    return(FileType.AssetsFile);
                }
                else
                {
                    return(FileType.ResourceFile);
                }
            }
            }
        }
        public byte[] GetData()
        {
            if (needSearch)
            {
                var resourceFileName = Path.GetFileName(path);

                if (assetsFile.assetsManager.resourceFileStreams.TryGetValue(resourceFileName, out var stream))
                {
                    reader = stream.InitReader();

                    needSearch = false;
                    reader.BaseStream.Position = offset;
                    return(reader.ReadBytes(size));
                }

                var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName);
                var resourceFilePath    = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName;
                if (!File.Exists(resourceFilePath))
                {
                    var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories);
                    if (findFiles.Length > 0)
                    {
                        resourceFilePath = findFiles[0];
                    }
                }
                if (File.Exists(resourceFilePath))
                {
                    stream     = new EndianBinaryStream(File.OpenRead(resourceFilePath));
                    needSearch = false;
                    assetsFile.assetsManager.resourceFileStreams.Add(resourceFileName, stream);
                    reader.BaseStream.Position = offset;
                    return(reader.ReadBytes(size));
                }

                throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
            }

            reader.BaseStream.Position = offset;
            return(reader.ReadBytes(size));
        }
Exemple #7
0
        private void LoadWebFile(string fullName, EndianBinaryStream stream)
        {
            var fileName = Path.GetFileName(fullName);

            Logger.Info("Loading " + fileName);
            try
            {
                var webFile = new WebFile(stream.InitReader());
                foreach (var file in webFile.fileList)
                {
                    var dummyPath = Path.Combine(Path.GetDirectoryName(fullName), file.fileName);
                    switch (CheckFileType(file.stream, out var fileStream))
                    {
                    case FileType.AssetsFile:
                        LoadAssetsFromMemory(dummyPath, fileStream, fullName);
                        break;

                    case FileType.BundleFile:
                        LoadBundleFile(dummyPath, fileStream, fullName);
                        break;

                    case FileType.WebFile:
                        LoadWebFile(dummyPath, fileStream);
                        break;

                    case FileType.ResourceFile:
                        resourceFileStreams.Add(file.fileName, fileStream);
                        break;
                    }
                }
            }
            catch
            {
                // Logger.Error($"Unable to load web file {fileName}");
            }
            finally
            {
                stream.Dispose();
            }
        }
Exemple #8
0
        private void LoadBundleFile(string fullName, EndianBinaryStream stream, string parentPath = null)
        {
            var fileName = Path.GetFileName(fullName);

            Logger.Info("Loading " + fileName);
            try
            {
                var bundleFile = new BundleFile(stream, fullName);
                foreach (var file in bundleFile.fileList)
                {
                    var subStream = new EndianBinaryStream(file.stream);
                    if (SerializedFile.IsSerializedFile(subStream))
                    {
                        var dummyPath = Path.GetDirectoryName(fullName) + Path.DirectorySeparatorChar + file.fileName;
                        LoadAssetsFromMemory(dummyPath, subStream, parentPath ?? fullName, bundleFile.m_Header.unityRevision);
                    }
                    else
                    {
                        resourceFileStreams.Add(file.fileName, subStream);
                    }
                }
            }
            catch
            {
                /*var str = $"Unable to load bundle file {fileName}";
                 * if (parentPath != null)
                 * {
                 *  str += $" from {Path.GetFileName(parentPath)}";
                 * }
                 * Logger.Error(str);*/
            }
            finally
            {
                stream.Dispose();
            }
        }
 public static FileType CheckFileType(string fileName, out EndianBinaryStream stream)
 {
     stream = new EndianBinaryStream(File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
     return(CheckFileType(stream));
 }
 public static FileType CheckFileType(Stream stream, out EndianBinaryStream endianStream)
 {
     endianStream = new EndianBinaryStream(stream);
     return(CheckFileType(endianStream));
 }
Exemple #11
0
        public SerializedFile(AssetsManager assetsManager, string fullName, EndianBinaryStream stream)
        {
            this.assetsManager = assetsManager;
            this.stream        = stream;

            reader = stream.InitReader();

            this.fullName = fullName;
            fileName      = Path.GetFileName(fullName);

            // Read Header
            header = new SerializedFileHeader
            {
                m_MetadataSize = reader.ReadUInt32(),
                m_FileSize     = reader.ReadUInt32(),
                m_Version      = reader.ReadUInt32(),
                m_DataOffset   = reader.ReadUInt32()
            };

            if (header.m_Version >= 9)
            {
                header.m_Endianess = reader.ReadByte();
                header.m_Reserved  = reader.ReadBytes(3);
                m_FileEndianess    = (EndianType)header.m_Endianess;
            }
            else
            {
                reader.Position = header.m_FileSize - header.m_MetadataSize;
                m_FileEndianess = (EndianType)reader.ReadByte();
            }

            if (header.m_Version >= 22)
            {
                header.m_MetadataSize = reader.ReadUInt32();
                header.m_FileSize     = reader.ReadInt64();
                header.m_DataOffset   = reader.ReadInt64();
                reader.ReadInt64(); // unknown
            }

            // Read Metadata
            if (m_FileEndianess == EndianType.LittleEndian)
            {
                reader.endian = EndianType.LittleEndian;
            }
            if (header.m_Version >= 7)
            {
                unityVersion = reader.ReadStringToNull();
                SetVersion(unityVersion);
            }
            if (header.m_Version >= 8)
            {
                m_TargetPlatform = (BuildTarget)reader.ReadInt32();
                if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
                {
                    m_TargetPlatform = BuildTarget.UnknownPlatform;
                }
            }
            if (header.m_Version >= 13)
            {
                m_EnableTypeTree = reader.ReadBoolean();
            }

            // Read Types
            var typeCount = reader.ReadInt32();

            m_Types = new List <SerializedType>(typeCount);
            for (var i = 0; i < typeCount; i++)
            {
                m_Types.Add(ReadSerializedType());
            }

            var bigIDEnabled = 0;

            if (header.m_Version >= 7 && header.m_Version < 14)
            {
                bigIDEnabled = reader.ReadInt32();
            }

            // Read Objects
            var objectCount = reader.ReadInt32();

            m_Objects     = new List <ObjectInfo>(objectCount);
            objects       = new List <Object>(objectCount);
            objectsDict   = new Dictionary <long, Object>(objectCount);
            objectsStream = new Dictionary <long, EndianBinaryStream>(objectCount);
            for (var i = 0; i < objectCount; i++)
            {
                var objectInfo = new ObjectInfo();
                if (bigIDEnabled != 0)
                {
                    objectInfo.m_PathID = reader.ReadInt64();
                }
                else if (header.m_Version < 14)
                {
                    objectInfo.m_PathID = reader.ReadInt32();
                }
                else
                {
                    reader.AlignStream();
                    objectInfo.m_PathID = reader.ReadInt64();
                }

                if (header.m_Version >= 22)
                {
                    objectInfo.byteStart = reader.ReadInt64();
                }
                else
                {
                    objectInfo.byteStart = reader.ReadUInt32();
                }

                objectInfo.byteStart += header.m_DataOffset;
                objectInfo.byteSize   = reader.ReadUInt32();
                objectInfo.typeID     = reader.ReadInt32();
                if (header.m_Version < 16)
                {
                    objectInfo.classID        = reader.ReadUInt16();
                    objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
                }
                else
                {
                    var type = m_Types[objectInfo.typeID];
                    objectInfo.serializedType = type;
                    objectInfo.classID        = type.classID;
                }
                if (header.m_Version < 11)
                {
                    var isDestroyed = reader.ReadUInt16();
                }
                if (header.m_Version >= 11 && header.m_Version < 17)
                {
                    var m_ScriptTypeIndex = reader.ReadInt16();
                    if (objectInfo.serializedType != null)
                    {
                        objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex;
                    }
                }
                if (header.m_Version == 15 || header.m_Version == 16)
                {
                    var stripped = reader.ReadByte();
                }
                m_Objects.Add(objectInfo);
            }

            if (header.m_Version >= 11)
            {
                var scriptCount = reader.ReadInt32();
                m_ScriptTypes = new List <LocalSerializedObjectIdentifier>(scriptCount);
                for (var i = 0; i < scriptCount; i++)
                {
                    var m_ScriptType = new LocalSerializedObjectIdentifier();
                    m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
                    if (header.m_Version < 14)
                    {
                        m_ScriptType.localIdentifierInFile = reader.ReadInt32();
                    }
                    else
                    {
                        reader.AlignStream();
                        m_ScriptType.localIdentifierInFile = reader.ReadInt64();
                    }
                    m_ScriptTypes.Add(m_ScriptType);
                }
            }

            var externalsCount = reader.ReadInt32();

            m_Externals = new List <FileIdentifier>(externalsCount);
            for (var i = 0; i < externalsCount; i++)
            {
                var m_External = new FileIdentifier();
                if (header.m_Version >= 6)
                {
                    var tempEmpty = reader.ReadStringToNull();
                }
                if (header.m_Version >= 5)
                {
                    m_External.guid = new Guid(reader.ReadBytes(16));
                    m_External.type = reader.ReadInt32();
                }
                m_External.pathName = reader.ReadStringToNull();
                m_External.fileName = Path.GetFileName(m_External.pathName);
                m_Externals.Add(m_External);
            }

            if (header.m_Version >= 20)
            {
                var refTypesCount = reader.ReadInt32();
                m_RefTypes = new List <SerializedType>(refTypesCount);
                for (var i = 0; i < refTypesCount; i++)
                {
                    m_RefTypes.Add(ReadSerializedType());
                }
            }

            if (header.m_Version >= 5)
            {
                var userInformation = reader.ReadStringToNull();
            }

            // reader.AlignStream(16);
        }