Example #1
0
        /// <summary>
        ///   Reads the bundle description from a <see cref="Stream"/>.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>A <see cref="BundleDescription"/> representing a description of the bundle.</returns>
        /// <exception cref="InvalidDataException">Invalid bundle header.</exception>
        /// <exception cref="InvalidDataException">The bundle has not been properly written.</exception>
        public static BundleDescription ReadBundleDescription(Stream stream)
        {
            var binaryReader = new BinarySerializationReader(stream);

            // Read header
            Header header;

            try
            {
                header = binaryReader.Read <Header>();
            }
            catch (InvalidOperationException ex)
            {
                throw new InvalidDataException("Invalid bundle header.", ex);
            }

            var result = new BundleDescription {
                Header = header
            };

            // Check magic header
            if (header.MagicHeader != Header.MagicHeaderValid)
            {
                throw new InvalidDataException("Invalid bundle header.");
            }

            // Ensure size has properly been set
            if (header.Size != stream.Length)
            {
                throw new InvalidDataException("Bundle has not been properly written.");
            }

            try
            {
                // Read dependencies
                var dependencies = result.Dependencies;
                binaryReader.Serialize(ref dependencies, ArchiveMode.Deserialize);

                // Read incremental bundles
                var incrementalBundles = result.IncrementalBundles;
                binaryReader.Serialize(ref incrementalBundles, ArchiveMode.Deserialize);

                // Read objects
                var objects = result.Objects;
                binaryReader.Serialize(ref objects, ArchiveMode.Deserialize);

                // Read assets
                var assets = result.Assets;
                binaryReader.Serialize(ref assets, ArchiveMode.Deserialize);
            }
            catch (InvalidOperationException ex)
            {
                throw new InvalidDataException("Bundle has not been properly written.", ex);
            }

            return(result);
        }
Example #2
0
        public T CopyBySerialization <T>(T obj, SerializationBackend serializationBackend)
        {
            var result = default(T);

            if (serializationBackend == SerializationBackend.Binary)
            {
                var memoryStream = new MemoryStream();
                var writer       = new BinarySerializationWriter(memoryStream);
                writer.Write(obj);
                writer.Flush();

                memoryStream.Seek(0, SeekOrigin.Begin);
                var reader = new BinarySerializationReader(memoryStream);
                reader.Serialize(ref result, ArchiveMode.Deserialize);
            }
            //else if (serializationBackend == SerializationBackend.Xml)
            //{
            //    var xmlDoc = new XmlDocument();
            //    var xmlElement = xmlDoc.CreateElement("object");

            //    var writer = new XmlSerializationWriter(xmlElement);
            //    writer.Write(obj);
            //    writer.Flush();

            //    var reader = new XmlSerializationReader(xmlElement);
            //    reader.Serialize(ref result, ArchiveMode.Deserialize);
            //}

            return(result);
        }
Example #3
0
        /// <summary>
        /// Reads the bundle description.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">
        /// Invalid bundle header
        /// or
        /// Bundle has not been properly written
        /// </exception>
        public static BundleDescription ReadBundleDescription(Stream stream)
        {
            var binaryReader = new BinarySerializationReader(stream);

            // Read header
            var header = binaryReader.Read <Header>();

            var result = new BundleDescription();

            result.Header = header;

            // Check magic header
            if (header.MagicHeader != Header.MagicHeaderValid)
            {
                throw new InvalidOperationException("Invalid bundle header");
            }

            // Ensure size has properly been set
            if (header.Size != stream.Length)
            {
                throw new InvalidOperationException("Bundle has not been properly written");
            }

            // Read dependencies
            List <string> dependencies = result.Dependencies;

            binaryReader.Serialize(ref dependencies, ArchiveMode.Deserialize);

            // Read objects
            List <KeyValuePair <ObjectId, ObjectInfo> > objects = result.Objects;

            binaryReader.Serialize(ref objects, ArchiveMode.Deserialize);

            // Read assets
            List <KeyValuePair <string, ObjectId> > assets = result.Assets;

            binaryReader.Serialize(ref assets, ArchiveMode.Deserialize);

            return(result);
        }
Example #4
0
        protected virtual List <T> ReadEntries(Stream localStream)
        {
            var reader  = new BinarySerializationReader(localStream);
            var entries = new List <T>();

            while (localStream.Position < localStream.Length)
            {
                var entry = new T();
                reader.Serialize(ref entry, ArchiveMode.Deserialize);
                entries.Add(entry);
            }
            return(entries);
        }
Example #5
0
 /// <summary>
 /// Loads intermediate data used for building a navigation mesh
 /// </summary>
 /// <param name="objectId">The unique Id for this data in the object database</param>
 /// <returns>The found cached build or null if there is no previous build</returns>
 private NavigationMesh LoadIntermediateData(ObjectId objectId)
 {
     try
     {
         var objectDatabase = ContentManager.FileProvider.ObjectDatabase;
         using (var stream = objectDatabase.OpenStream(objectId))
         {
             var            reader = new BinarySerializationReader(stream);
             NavigationMesh result = new NavigationMesh();
             reader.Serialize(ref result, ArchiveMode.Deserialize);
             return(result);
         }
     }
     catch (Exception ex)
     {
         return(null);
     }
 }
        public static async Task UnpackAPK()
        {
            // get the apk last update time
            var packageManager = PlatformAndroid.Context.PackageManager;
            var packageInfo    = packageManager.GetPackageInfo(PlatformAndroid.Context.PackageName, PackageInfoFlags.Activities);
            var lastUpdateTime = packageInfo.LastUpdateTime;
            var sourceDir      = PlatformAndroid.Context.ApplicationInfo.SourceDir;

            // evaluate if asset data should be extracted from apk file
            var shouldExtractAssets = true;

            if (ApplicationTemporary.FileExists(LastExtractedApkFileName))
            {
                Int64 extractedLastUpdateTime = 0;
                using (var file = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Open, VirtualFileAccess.Read))
                {
                    var binaryReader = new BinarySerializationReader(file);
                    binaryReader.Serialize(ref extractedLastUpdateTime, ArchiveMode.Deserialize);
                }

                shouldExtractAssets = extractedLastUpdateTime != lastUpdateTime;
            }

            // Copy assets
            if (shouldExtractAssets)
            {
                var assets = PlatformAndroid.Context.Assets;

                // Make sure assets exists
                var logger = GlobalLogger.GetLogger("VFS");
                CopyFileOrDirectory(logger, sourceDir, "assets/data/", string.Empty);

                // update value of extracted last update time
                using (var stream = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.None))
                {
                    var binaryWriter = new BinarySerializationWriter(stream);
                    binaryWriter.Write(lastUpdateTime);
                }
            }
        }
Example #7
0
        public static unsafe Image LoadFromMemory(IntPtr pSource, int size, bool makeACopy, GCHandle?handle)
        {
            var stream = new BinarySerializationReader(new NativeMemoryStream((byte *)pSource, size));

            // Read and check magic code
            var magicCode = stream.ReadUInt32();

            if (magicCode != MagicCode)
            {
                return(null);
            }

            // Read header
            var imageDescription = new ImageDescription();

            ImageDescriptionSerializer.Serialize(ref imageDescription, ArchiveMode.Deserialize, stream);

            if (makeACopy)
            {
                var buffer = Utilities.AllocateMemory(size);
                Utilities.CopyMemory(buffer, pSource, size);
                pSource   = buffer;
                makeACopy = false;
            }

            var image = new Image(imageDescription, pSource, 0, handle, !makeACopy);

            var totalSizeInBytes = stream.ReadInt32();

            if (totalSizeInBytes != image.TotalSizeInBytes)
            {
                throw new InvalidOperationException("Image size is different than expected.");
            }

            // Read image data
            stream.Serialize(image.DataPointer, image.TotalSizeInBytes);

            return(image);
        }
Example #8
0
        /// <summary>
        /// Gets and cache the asset url referenced by the chunk with the given identifier.
        /// </summary>
        /// <param name="objectId">The object identifier.</param>
        /// <returns>The list of asset url referenced.</returns>
        private List <string> GetChunkReferences(ref ObjectId objectId)
        {
            List <string> references;

            // Check the cache
            if (!referencesByObjectId.TryGetValue(objectId, out references))
            {
                // First time, need to scan it
                referencesByObjectId[objectId] = references = new List <string>();

                // Open stream to read list of chunk references
                using (var stream = AssetManager.FileProvider.OpenStream("obj/" + objectId, VirtualFileMode.Open, VirtualFileAccess.Read))
                {
                    // Read chunk header
                    var streamReader = new BinarySerializationReader(stream);
                    var header       = ChunkHeader.Read(streamReader);

                    // Only process chunks
                    if (header != null)
                    {
                        if (header.OffsetToReferences != -1)
                        {
                            // Seek to where references are stored and deserialize them
                            streamReader.NativeStream.Seek(header.OffsetToReferences, SeekOrigin.Begin);

                            List <ChunkReference> chunkReferences = null;
                            streamReader.Serialize(ref chunkReferences, ArchiveMode.Deserialize);

                            foreach (var chunkReference in chunkReferences)
                            {
                                references.Add(chunkReference.Location);
                            }
                        }
                    }
                }
            }

            return(references);
        }
Example #9
0
        private static void Collect(HashSet <ObjectId> objectIds, ObjectId objectId, IAssetIndexMap assetIndexMap)
        {
            // Already added?
            if (!objectIds.Add(objectId))
            {
                return;
            }

            using (var stream = AssetManager.FileProvider.OpenStream(DatabaseFileProvider.ObjectIdUrl + objectId, VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                // Read chunk header
                var streamReader = new BinarySerializationReader(stream);
                var header       = ChunkHeader.Read(streamReader);

                // Only process chunks
                if (header != null)
                {
                    if (header.OffsetToReferences != -1)
                    {
                        // Seek to where references are stored and deserialize them
                        streamReader.NativeStream.Seek(header.OffsetToReferences, SeekOrigin.Begin);

                        List <ChunkReference> references = null;
                        streamReader.Serialize(ref references, ArchiveMode.Deserialize);

                        foreach (var reference in references)
                        {
                            ObjectId refObjectId;
                            var      databaseFileProvider = DatabaseFileProvider.ResolveObjectId(reference.Location, out refObjectId);
                            if (databaseFileProvider != null)
                            {
                                Collect(objectIds, refObjectId, databaseFileProvider.AssetIndexMap);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Synchronizes files to an android device.
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="device">The device.</param>
        /// <param name="fileMapping">The file mapping (relative target path, source HDD filename).</param>
        /// <param name="androidPath">The android path.</param>
        /// <param name="cacheFile">The cache file.</param>
        public static void Synchronize(Logger logger, string device, Dictionary<string, string> fileMapping, string androidPath, string cacheFile)
        {
            // Ensure android path ends up with directory separator
            if (!androidPath.EndsWith("/"))
                androidPath = androidPath + "/";

            // Search files
            var currentVersions = fileMapping
                .ToDictionary(x => x.Key, x => new FileVersion(x.Value));

            // Try to read previous cache file
            var previousVersions = new Dictionary<string, FileVersion>();
            try
            {
                using (var file = File.OpenRead(cacheFile))
                {
                    var binaryReader = new BinarySerializationReader(file);
                    binaryReader.Serialize(ref previousVersions, ArchiveMode.Deserialize);
                }
            }
            catch (IOException)
            {
            }

            var filesToRemove = new List<string>();
            var filesToUpload = new List<string>();

            // Remove unecessary files (in previousVersions but not in currentVersions)
            foreach (var file in previousVersions.Where(x => !currentVersions.ContainsKey(x.Key)))
            {
                filesToRemove.Add(file.Key);
            }

            // Upload files that are either not uploaded yet, or not up to date
            foreach (var file in currentVersions)
            {
                FileVersion fileVersion;
                if (!previousVersions.TryGetValue(file.Key, out fileVersion)
                    || fileVersion.FileSize != file.Value.FileSize
                    || fileVersion.LastModifiedDate != file.Value.LastModifiedDate)
                {
                    filesToUpload.Add(file.Key);
                }
            }

            // Upload files
            foreach (var file in filesToUpload)
            {
                if (logger != null)
                    logger.Verbose("Copying file {0}", file);
                RunAdb(device, string.Format("push \"{0}\" \"{1}\"", fileMapping[file], androidPath + file.Replace('\\', '/')));
            }

            // Remove files
            foreach (var file in filesToRemove)
            {
                if (logger != null)
                    logger.Verbose("Deleting file {0}", file);
                RunAdb(device, string.Format("shell \"rm {0}\"", androidPath + file.Replace('\\', '/')));
            }

            // Write new cache file
            using (var file = File.Create(cacheFile))
            {
                var binaryWriter = new BinarySerializationWriter(file);
                binaryWriter.Write(currentVersions);
            }
        }
Example #11
0
        /// <summary>
        /// Synchronizes files to an android device.
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <param name="device">The device.</param>
        /// <param name="fileMapping">The file mapping (relative target path, source HDD filename).</param>
        /// <param name="androidPath">The android path.</param>
        /// <param name="cacheFile">The cache file.</param>
        public static void Synchronize(Logger logger, string device, Dictionary <string, string> fileMapping, string androidPath, string cacheFile)
        {
            // Ensure android path ends up with directory separator
            if (!androidPath.EndsWith("/"))
            {
                androidPath = androidPath + "/";
            }

            // Search files
            var currentVersions = fileMapping
                                  .ToDictionary(x => x.Key, x => new FileVersion(x.Value));

            // Try to read previous cache file
            var previousVersions = new Dictionary <string, FileVersion>();

            try
            {
                using (var file = File.OpenRead(cacheFile))
                {
                    var binaryReader = new BinarySerializationReader(file);
                    binaryReader.Serialize(ref previousVersions, ArchiveMode.Deserialize);
                }
            }
            catch (IOException)
            {
            }

            var filesToRemove = new List <string>();
            var filesToUpload = new List <string>();

            // Remove unecessary files (in previousVersions but not in currentVersions)
            foreach (var file in previousVersions.Where(x => !currentVersions.ContainsKey(x.Key)))
            {
                filesToRemove.Add(file.Key);
            }

            // Upload files that are either not uploaded yet, or not up to date
            foreach (var file in currentVersions)
            {
                FileVersion fileVersion;
                if (!previousVersions.TryGetValue(file.Key, out fileVersion) ||
                    fileVersion.FileSize != file.Value.FileSize ||
                    fileVersion.LastModifiedDate != file.Value.LastModifiedDate)
                {
                    filesToUpload.Add(file.Key);
                }
            }

            // Upload files
            foreach (var file in filesToUpload)
            {
                if (logger != null)
                {
                    logger.Verbose("Copying file {0}", file);
                }
                RunAdb(device, string.Format("push \"{0}\" \"{1}\"", fileMapping[file], androidPath + file.Replace('\\', '/')));
            }

            // Remove files
            foreach (var file in filesToRemove)
            {
                if (logger != null)
                {
                    logger.Verbose("Deleting file {0}", file);
                }
                RunAdb(device, string.Format("shell \"rm {0}\"", androidPath + file.Replace('\\', '/')));
            }

            // Write new cache file
            using (var file = File.Create(cacheFile))
            {
                var binaryWriter = new BinarySerializationWriter(file);
                binaryWriter.Write(currentVersions);
            }
        }