Exemplo n.º 1
0
        /// <summary>
        ///		Loads this map from a given object or file path.
        /// </summary>
        /// <param name="url">Url of file to open map from.	</param>
        /// <param name="password">If a password is required to open this map, this will be used.</param>
        /// <param name="baseNode">The base node that all loading should be started from, this allows you to ignore this node and any nodes higher in the graph like the Root Camera.</param>
        /// <param name="keepPersistent">If set to true persistent ob jects will be kept.</param>
        /// <param name="keepCameras">If set to true all cameras will not be destroyed.</param>
        public void Load(object url, string password, SceneNode baseNode, bool keepPersistent, bool keepCameras)
        {
            // Keep track of the url.
            if (url is string)
            {
                _url = url as string;
            }

            // Try and open a stream to the file.
            Stream stream = StreamFactory.RequestStream(url, StreamMode.Open);

            if (stream == null)
            {
                return;
            }
            BinaryReader reader = new BinaryReader(stream);

            // Check the header of this file to make sure it really is a Fusion map file.
            if (reader.ReadChar() != 'F' || reader.ReadChar() != 'M' || reader.ReadChar() != 'P')
            {
                throw new Exception("Fusion map file has invalid header, file may be corrupt.");
            }

            // Read in the bit mask explaining the header.
            int headerBitMask = reader.ReadByte();

            if ((headerBitMask & 4) != 0)
            {
                _mapProperties.Name = reader.ReadString();
            }
            if ((headerBitMask & 8) != 0)
            {
                _mapProperties.Author = reader.ReadString();
            }
            if ((headerBitMask & 16) != 0)
            {
                _mapProperties.Description = reader.ReadString();
            }
            if ((headerBitMask & 32) != 0)
            {
                _mapProperties.Version = reader.ReadSingle();
            }

            // Read in the rest of the file into memory so we can decompress / decrypt it.
            byte[] fileData = reader.ReadBytes((int)(stream.Length - stream.Position));

            // Decrypt the data if required.
            if ((headerBitMask & 2) != 0)
            {
                fileData = DataMethods.Decrypt(fileData, password);
            }

            // Decompress the data if required.
            if ((headerBitMask & 1) != 0)
            {
                fileData = DataMethods.Inflate(fileData);
            }

            // Create a memory stream and a binary reader so we can minipulate the data better.
            MemoryStream memStream       = new MemoryStream(fileData, 0, fileData.Length);
            BinaryReader memStreamReader = new BinaryReader(memStream);

            // Read in the encryption header to make sure everything went correctly.
            if ((headerBitMask & 2) != 0 || (headerBitMask & 1) != 0)
            {
                if (memStreamReader.ReadChar() != 'C' || memStreamReader.ReadChar() != 'H' || memStreamReader.ReadChar() != 'K')
                {
                    throw new Exception("Unable to open Fusion map file, password is invalid or fils is corrupted.");
                }
            }

            // Read in the tileset pool used to render tilemap segments.
            int tilesetCount = memStreamReader.ReadByte();

            Tileset.TilesetPool.Clear();
            for (int i = 0; i < tilesetCount; i++)
            {
                if (memStreamReader.ReadBoolean() == true)
                {
                    string newTilesetUrl = memStreamReader.ReadString();

                    if (newTilesetUrl.ToString().ToLower().StartsWith("pak@"))
                    {
                        newTilesetUrl = newTilesetUrl.ToString().Substring(4); // Legacy support.
                    }
                    if (Runtime.Resources.ResourceManager.ResourceIsCached(newTilesetUrl))
                    {
                        Tileset.AddToTilesetPool(Runtime.Resources.ResourceManager.RetrieveResource(newTilesetUrl) as Tileset);
                    }
                    else
                    {
                        Runtime.Debug.DebugLogger.WriteLog("Loading tileset from " + newTilesetUrl);
                        Tileset newTileset = new Tileset();
                        newTileset.Load(newTilesetUrl);
                        Tileset.AddToTilesetPool(newTileset);
                        Runtime.Resources.ResourceManager.CacheResource(newTilesetUrl, newTileset);
                    }
                }
            }

            // Tell the scene graph to load itself from this memory stream.
            _sceneGraph.Load(memStreamReader, keepPersistent, keepCameras, baseNode);

            // Free up the memory stream and reader.
            memStream.Close();
            memStream = null;

            // Free up the reader and stream.
            stream.Close();
            stream = null;

            // Reclaim memory used during loading.
            GC.Collect();
        }