예제 #1
0
        public static bool CheckWorldExistsByGenre(Guid worldId, Genres genres)
        {
            string bucket = BokuGame.MyWorldsPath;

            if (genres != 0)
            {
                bucket = Utils.FolderNameFromFlags(genres);

                if (bucket == null)
                {
                    return(false);
                }
            }

            string fullPath = BokuGame.Settings.MediaPath + bucket + worldId.ToString() + @".Xml";

            StorageSource sources = StorageSource.All;

            if ((genres & Genres.Downloads) != 0)
            {
                sources = StorageSource.UserSpace;
            }

            return(Storage4.FileExists(fullPath, sources));
        }
예제 #2
0
        /// <summary>
        /// Update the level's metadata on disk.
        /// Does not change the level's timestamp.
        /// </summary>
        /// <param name="level"></param>
        public static void UpdateWorldMetadata(LevelMetadata level)
        {
            try
            {
                string bucket = Utils.FolderNameFromFlags(level.Genres);

                string fullPath = BokuGame.Settings.MediaPath + bucket + level.WorldId.ToString() + @".Xml";

                Xml.XmlWorldData xml = XmlWorldData.Load(fullPath, XnaStorageHelper.Instance);
                if (xml != null)
                {
                    level.ToXml(xml);

                    bool isDownload = (level.Genres & Genres.Downloads) != 0;

                    // Manage the stream ourselves so avoid level timestamp being changed.
                    Stream stream = Storage4.OpenWrite(fullPath);
                    xml.Save(stream, isDownload);
                    Storage4.Close(stream);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
        }
예제 #3
0
        /// <summary>
        /// Update the level's xml on disk.
        /// Does not change the level's timestamp.
        /// </summary>
        /// <param name="level"></param>
        public static void UpdateWorldXml(XmlWorldData xml)
        {
            try
            {
                string bucket = Utils.FolderNameFromFlags((Genres)xml.genres);

                string fullPath = BokuGame.Settings.MediaPath + bucket + xml.id.ToString() + @".Xml";

                //make sure the world exists
                if (!Storage4.FileExists(fullPath, StorageSource.All))
                {
                    return;
                }

                if (xml != null)
                {
                    bool isDownload = (xml.genres & (int)Genres.Downloads) != 0;

                    // Manage the stream ourselves so avoid level timestamp being changed.
                    Stream stream = Storage4.OpenWrite(fullPath);
                    xml.Save(stream, isDownload);
                    Storage4.Close(stream);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
        }
        private void GotThumbnail(AsyncResult ar)
        {
            AsyncResult_Thumbnail result = (AsyncResult_Thumbnail)ar;
            LevelMetadata         level  = (LevelMetadata)result.Param;
            LevelBrowserState     state  = (LevelBrowserState)level.BrowserState;

            if (result.Success)
            {
                MemoryStream stream = new MemoryStream(result.ThumbnailBytes);
                level.Thumbnail.Texture = Storage4.TextureLoad(stream);
                level.Thumbnail.Loading = false;
            }
            else
            {
                // TODO: Set thumbnail to use missing icon.
            }

            if (state.thumbnailCallback != null)
            {
                state.thumbnailCallback(level);
            }
            state.thumbnailCallback = null;

            thumbnailLoadOpCount -= 1;
        }
예제 #5
0
        /// <summary>
        /// Creates a StorageFile in the temp folder.
        /// </summary>
        /// <returns></returns>
        public static StorageFile GetTempStorageFile()
        {
            Guid        guid     = Guid.NewGuid();
            string      filename = guid.ToString() + ".tmp";
            StorageFile file     = Storage4.CreateStorageFile(TempFolder, filename);

            return(file);
        }
예제 #6
0
 private void CompleteThumbnail(LevelMetadata level)
 {
     level.Thumbnail.Loading = false;
     if (level.ThumbnailBytes != null)
     {
         MemoryStream stream = new MemoryStream(level.ThumbnailBytes);
         level.Thumbnail.Texture = Storage4.TextureLoad(stream);
         level.ThumbnailBytes    = null;
     }
 }
        static public bool TextureSaveAsPng(Texture2D tex, string name)
        {
            if (tex != null)
            {
                Stream stream = Storage4.OpenWrite(name);
                tex.SaveAsPng(stream, tex.Width, tex.Height);
                stream.Close();

                return(true);
            }
            return(false);
        }
        private bool IsAlreadyDownloaded(LevelMetadata level)
        {
            string filename = BokuGame.Settings.MediaPath + BokuGame.DownloadsPath + level.WorldId.ToString() + @".Xml";

            if (Storage4.FileExists(filename, StorageSource.UserSpace))
            {
                XmlWorldData xml = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                if (xml != null)
                {
                    LevelMetadata local = LevelMetadata.CreateFromXml(xml);

                    return(
                        local.WorldId == level.WorldId &&
                        local.Creator == level.Creator &&
                        local.LastWriteTime >= level.LastWriteTime);
                }
            }

            return(false);
        }
예제 #9
0
        /// <summary>
        /// Loads Actors.xml and initializes the list of static actors.
        /// </summary>
        /// <remarks>
        /// The actors' model and xml file isn't loaded until LoadModels is called.
        /// </remarks>
        public static void LoadActors()
        {
            if (Storage4.FileExists(XmlActorsListFileName, StorageSource.TitleSpace))
            {
                // Read our actor list from file
                var stream     = Storage4.OpenRead(XmlActorsListFileName, StorageSource.TitleSpace);
                var serializer = new XmlSerializer(typeof(XmlActorsList));
                var xmlActors  = serializer.Deserialize(stream) as XmlActorsList;
                Storage4.Close(stream);

                if (xmlActors != null)
                {
                    for (int i = 0; i < xmlActors.Actors.Length; i++)
                    {
                        var xmlStaticActor = xmlActors.Actors[i];
                        Actors.Add(xmlStaticActor.NonLocalizedName, new StaticActor(xmlStaticActor));
                    }
                }
            }
            else
            {
                Debug.Assert(false, "Missing actor file.");
            }
        }
        }   // end of ScrubTerrainFiles()

        /// <summary>
        /// Deletes the given terrain file but only after verifying that no world is using it.
        /// It any world is found that is using the file then it is not deleted.
        ///
        /// Note this still isn't perfect since when a level is deleted, the terrain file may still be left
        /// in the undo stack and hence not deleted.  No biggy.  It's better than deleting too much and it's
        /// much quicker than the above ScrubTerrainFiles().
        /// </summary>
        /// <param name="terrainFile"></param>
        void DeleteTerrainFile(string terrainFile)
        {
            string[] undoFiles          = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.UnDoPath, @"*.Xml", StorageSource.UserSpace);
            string[] myWorldsFiles      = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.MyWorldsPath, @"*.Xml", StorageSource.UserSpace);
            string[] starterWorldsFiles = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.BuiltInWorldsPath, @"*.Xml", StorageSource.TitleSpace);
            string[] downloadsFiles     = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.DownloadsPath, @"*.Xml", StorageSource.UserSpace);

            /// Undo/Resume files. We might have to fall back on these if the user deletes the
            /// world they are editing and then back back to it.
            if (undoFiles != null)
            {
                for (int i = 0; i < undoFiles.Length; ++i)
                {
                    string       filename     = undoFiles[i];
                    XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                    if (xmlWorldData == null || xmlWorldData.xmlTerrainData2 == null)
                    {
                        continue;
                    }

                    if (xmlWorldData.xmlTerrainData2.virtualMapFile == terrainFile)
                    {
                        // Found it, don't delete.
                        return;
                    }
                }
            }

            // MyWorlds
            if (myWorldsFiles != null)
            {
                for (int i = 0; i < myWorldsFiles.Length; ++i)
                {
                    string       filename     = myWorldsFiles[i];
                    XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                    if (xmlWorldData == null || xmlWorldData.xmlTerrainData2 == null)
                    {
                        continue;
                    }

                    if (xmlWorldData.xmlTerrainData2.virtualMapFile == terrainFile)
                    {
                        // Found it, don't delete.
                        return;
                    }
                }
            }

            // BuiltInWorlds
            if (starterWorldsFiles != null)
            {
                for (int i = 0; i < starterWorldsFiles.Length; ++i)
                {
                    try
                    {
                        string       filename     = starterWorldsFiles[i];
                        XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);

                        if (xmlWorldData == null || xmlWorldData.xmlTerrainData2 == null)
                        {
                            continue;
                        }

                        if (xmlWorldData.xmlTerrainData2.virtualMapFile == terrainFile)
                        {
                            // Found it, don't delete.
                            return;
                        }
                    }
                    catch
                    {
                    }
                }
            }

            // Downloads
            if (downloadsFiles != null)
            {
                for (int i = 0; i < downloadsFiles.Length; ++i)
                {
                    string       filename     = downloadsFiles[i];
                    XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                    if (xmlWorldData == null || xmlWorldData.xmlTerrainData2 == null)
                    {
                        continue;
                    }

                    if (xmlWorldData.xmlTerrainData2.virtualMapFile == terrainFile)
                    {
                        // Found it, don't delete.
                        return;
                    }
                }
            }

            // Nothing was found using this terrain file so we can delete it.
            try
            {
                terrainFile = Path.Combine(BokuGame.Settings.MediaPath, terrainFile);
                Storage4.Delete(terrainFile);
            }
            catch (Exception e)
            {
                if (e != null)
                {
                }
            }
        } // end of DeleteTerrainFile()
예제 #11
0
 public override Stream OpenRead(string filename)
 {
     return(Storage4.OpenRead(filename, StorageSource.All));
 }
예제 #12
0
 public override Stream OpenRead(string filename, int flags)
 {
     return(Storage4.OpenRead(filename, (StorageSource)flags));
 }
예제 #13
0
        public static bool WriteWorldDataPacketToDisk(BokuShared.Wire.WorldDataPacket packet, byte[] thumbnailBytes, DateTime timeStamp)
        {
            Stream file = null;

            try
            {
                // Check for presence of the essential world data
                if (packet == null)
                {
                    return(false);
                }
                if (packet.WorldXmlBytes == null)
                {
                    return(false);
                }
                if (packet.StuffXmlBytes == null)
                {
                    return(false);
                }

                // Read in contents of world xml buffer
                Xml.XmlWorldData xmlWorldData = Xml.XmlWorldData.Load(packet.WorldXmlBytes);
                if (xmlWorldData == null)
                {
                    return(false);
                }

                xmlWorldData.overrideLastWriteTime = timeStamp;

                xmlWorldData.id            = packet.WorldId;
                xmlWorldData.stuffFilename = BokuGame.DownloadsStuffPath + xmlWorldData.Filename;

                // Non-essential file: Write thumbnail image to disk
                if (thumbnailBytes != null)
                {
                    string ext           = Storage4.TextureExt(thumbnailBytes);
                    string thumbFilename = xmlWorldData.GetImageFilenameWithoutExtension() + "." + ext;
                    file = Storage4.OpenWrite(BokuGame.Settings.MediaPath + BokuGame.DownloadsPath + thumbFilename);
                    file.Write(thumbnailBytes, 0, thumbnailBytes.Length);
                    Storage4.Close(file);
                    file = null;
                }

                // Cubeworld virtual terrain map
                if (packet.VirtualMapBytes != null)
                {
                    file = Storage4.OpenWrite(BokuGame.Settings.MediaPath + xmlWorldData.xmlTerrainData2.virtualMapFile);
                    file.Write(packet.VirtualMapBytes, 0, packet.VirtualMapBytes.Length);
                    Storage4.Close(file);
                    file = null;
                }

                // Write stuff xml to disk
                file = Storage4.OpenWrite(BokuGame.Settings.MediaPath + xmlWorldData.stuffFilename);
                file.Write(packet.StuffXmlBytes, 0, packet.StuffXmlBytes.Length);
                Storage4.Close(file);
                file = null;

                // Clear virtual genre bits because they should not be stored.
                xmlWorldData.genres &= ~(int)Genres.Virtual;
                xmlWorldData.genres &= ~(int)Genres.Favorite;

                // Serialize xmlWorldData to disk
                string fullPath = BokuGame.Settings.MediaPath + BokuGame.DownloadsPath + xmlWorldData.Filename;
                xmlWorldData.Save(fullPath, XnaStorageHelper.Instance);

                Instrumentation.RecordEvent(Instrumentation.EventId.LevelDownloaded, xmlWorldData.name);

                return(true);
            }
            catch
            {
                if (file != null)
                {
                    Storage4.Close(file);
                }

                return(false);
            }
        }
예제 #14
0
 public override Stream OpenWrite(string filename)
 {
     return(Storage4.OpenWrite(filename));
 }
예제 #15
0
        public static BokuShared.Wire.WorldPacket ReadWorldPacketFromDisk(string worldFullPathAndName, string bucket)
        {
            BokuShared.Wire.WorldPacket packet = null;
            Stream file = null;

            try
            {
                string localLevelPath = BokuGame.Settings.MediaPath + bucket;
                string worldFilename  = Path.GetFileName(worldFullPathAndName);

                // Read contents of world xml to retrieve the names of the dependent
                // files we need to upload
                Xml.XmlWorldData xmlWorldData = XmlWorldData.Load(localLevelPath + worldFilename, XnaStorageHelper.Instance);
                if (xmlWorldData == null)
                {
                    return(null);
                }

                // Clear virtual genre bits in case they got saved (server clears them too).
                xmlWorldData.genres &= ~(int)Genres.Virtual;

                packet = new BokuShared.Wire.WorldPacket();
                packet.Info.WorldId     = packet.Data.WorldId = xmlWorldData.id;
                packet.Info.Name        = xmlWorldData.name;
                packet.Info.Description = xmlWorldData.description;
                packet.Info.Creator     = xmlWorldData.creator;
                packet.Info.IdHash      = "";
                packet.Info.Genres      = xmlWorldData.genres;

                string imageFileName = xmlWorldData.GetImageFilenameWithoutExtension();

                // VirtualMap
                file = Storage4.OpenRead(BokuGame.Settings.MediaPath + xmlWorldData.xmlTerrainData2.virtualMapFile, StorageSource.All);
                packet.Data.VirtualMapBytes = new byte[file.Length];
                file.Read(packet.Data.VirtualMapBytes, 0, (int)file.Length);
                Storage4.Close(file);

                // Stuff xml
                file = Storage4.OpenRead(BokuGame.Settings.MediaPath + xmlWorldData.stuffFilename, StorageSource.All);
                packet.Data.StuffXmlBytes = new byte[file.Length];
                file.Read(packet.Data.StuffXmlBytes, 0, (int)file.Length);
                Storage4.Close(file);

                // Optional: don't worry if we don't have a thumbnail image.
                try
                {
                    file = null;
                    file = Storage4.TextureFileOpenRead(localLevelPath + imageFileName);

                    if (file != null)
                    {
                        packet.Info.ThumbnailBytes = new byte[file.Length];
                        file.Read(packet.Info.ThumbnailBytes, 0, (int)file.Length);
                        Storage4.Close(file);
                    }
                }
                catch { }


                // Try To load Snapshot image.
                try
                {
                    file = null;
                    file = Storage4.TextureFileOpenRead(localLevelPath + imageFileName, Storage4.TextureFileType.jpg);

                    if (file != null)
                    {
                        packet.Info.ScreenshotBytes = new byte[file.Length];
                        file.Read(packet.Info.ScreenshotBytes, 0, (int)file.Length);
                        Storage4.Close(file);
                    }
                }
                catch { }


                // We've successfully read all required files. We may now upload them to the server.
                file = Storage4.OpenRead(localLevelPath + worldFilename, StorageSource.All);
                packet.Data.WorldXmlBytes = new byte[file.Length];
                file.Read(packet.Data.WorldXmlBytes, 0, (int)file.Length);
                Storage4.Close(file);

                Instrumentation.RecordEvent(Instrumentation.EventId.LevelUploaded, xmlWorldData.name);
            }
            catch
            {
                if (file != null)
                {
                    Storage4.Close(file);
                }
                packet = null;
            }

            return(packet);
        }
예제 #16
0
        }   // end of XmlHelpTextData ReadFromXml()

        private static XmlHelpTextData Load(string filename)
        {
            XmlHelpTextData data   = null;
            Stream          stream = null;

            // First try with StorageSoruce.All so we get the version downloaded
            // from the servers.  If that fails then get the TitleSpace version.
            try
            {
                stream = Storage4.OpenRead(filename, StorageSource.All);

                XmlSerializer serializer = new XmlSerializer(typeof(XmlHelpTextData));
                data = (XmlHelpTextData)serializer.Deserialize(stream);
            }
            catch (Exception e)
            {
                data = null;
                if (e != null)
                {
#if !NETFX_CORE
                    string message = e.Message;
                    if (e.InnerException != null)
                    {
                        message += e.InnerException.Message;
                    }
                    System.Windows.Forms.MessageBox.Show(
                        message,
                        "Error reading " + filename,
                        System.Windows.Forms.MessageBoxButtons.OK,
                        System.Windows.Forms.MessageBoxIcon.Error
                        );
#endif
                }
            }
            finally
            {
                Storage4.Close(stream);
            }

            // If we don't have data.  Delete the server version of
            // the file and try loading the TitleSpace version.
            if (data == null)
            {
                // Don't delete the server version since this might actually be someone
                // trying to do a localization.
                //Storage4.Delete(filename);

                try
                {
                    stream = Storage4.OpenRead(filename, StorageSource.TitleSpace);

                    XmlSerializer serializer = new XmlSerializer(typeof(XmlHelpTextData));
                    data = (XmlHelpTextData)serializer.Deserialize(stream);
                }
                catch (Exception)
                {
                    data = null;
                }
                finally
                {
                    Storage4.Close(stream);
                }
            }

            return(data);
        } // end of XmlHelpTextData Load()
예제 #17
0
        /// <summary>
        /// Returns true on success, false if failed.
        /// </summary>
        public bool ReadFromXml(string filename)
        {
            bool success = true;

            // Fix up the filename with the full path.
            var defaultFile = Path.Combine(Localizer.DefaultLanguageDir, filename);

            // Read the Xml file into local data.
            XmlHelpTextData data = Load(defaultFile);

            // Build a dictionary with the default info
            var dict = new Dictionary <string, TweakScreenHelp.HelpText>(data.helpText.Count);

            foreach (var helpText in data.helpText)
            {
                dict[helpText.id] = helpText;
            }

            // Is our run-time local language different from the default?
            if (!Localizer.IsLocalDefault)
            {
                var localPath = Localizer.LocalLanguageDir;

                // Do we have a directory for the local language?
                if (localPath != null)
                {
                    var localFile = Path.Combine(localPath, filename);

                    if (Storage4.FileExists(localFile, StorageSource.All))
                    {
                        var localData = Load(localFile);
                        var localDict = new Dictionary <string, TweakScreenHelp.HelpText>(localData.helpText.Count);
                        foreach (var helpText in localData.helpText)
                        {
                            localDict[helpText.id] = helpText;
                        }

                        // Replace as much of the default data as we can with localized data
                        var keys = dict.Keys.ToArray();
                        foreach (var key in keys)
                        {
                            if (localDict.ContainsKey(key))
                            {
                                if (Localizer.ShouldReportMissing && localDict[key].desc.Equals(dict[key].desc, StringComparison.OrdinalIgnoreCase))
                                {
                                    Localizer.ReportIdentical(filename, key);
                                }

                                dict[key] = localDict[key];
                            }
                            else
                            {
                                Localizer.ReportMissing(filename, key);
                            }
                        }

                        data.helpText = dict.Values.ToList();
                    }
                    else
                    {
                        Localizer.ReportMissing(filename, "CAN'T FIND FILE!");
                    }
                }
                else
                {
                    Localizer.ReportMissing(localPath, "CAN'T FIND PATH FOR THIS LANGUAGE!");
                }
            }

            if (data == null)
            {
                success = false;
            }
            else
            {
                this.helpText = data.helpText;
            }

            return(success);
        }   // end of XmlHelpTextData ReadFromXml()
        private void ScrubTerrainFiles()
        {
            //  Build a list of all terrain files in user storage.
            //  For each world in local storage (all three bins)
            //      get the XmlWorldData file
            //      from the XmlWorldData file, get the terrain filename
            //      remove that filename from the list
            //
            //  Any terrain filenames still on the list should be deleted
            //  since they're no longer referenced by any files.

            string[] terrainFiles = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.TerrainPath, @"*.raw", StorageSource.UserSpace);

            // If nothing to scrub, just return.
            if (terrainFiles == null)
            {
                return;
            }

            string[] undoFiles          = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.UnDoPath, @"*.Xml", StorageSource.UserSpace);
            string[] myWorldsFiles      = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.MyWorldsPath, @"*.Xml", StorageSource.UserSpace);
            string[] starterWorldsFiles = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.BuiltInWorldsPath, @"*.Xml", StorageSource.TitleSpace);
            string[] downloadsFiles     = Storage4.GetFiles(BokuGame.Settings.MediaPath + BokuGame.DownloadsPath, @"*.Xml", StorageSource.UserSpace);

            /// Undo/Resume files. We might have to fall back on these if the user deletes the
            /// world they are editing and then back back to it.
            if (undoFiles != null)
            {
                for (int i = 0; i < undoFiles.Length; ++i)
                {
                    string       filename     = undoFiles[i];
                    XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                    if (xmlWorldData == null)
                    {
                        continue;
                    }

                    if (xmlWorldData.xmlTerrainData2 != null)
                    {
                        string terrainName = Path.Combine(Storage4.UserLocation, BokuGame.Settings.MediaPath, xmlWorldData.xmlTerrainData2.virtualMapFile);
                        for (int j = 0; j < terrainFiles.Length; ++j)
                        {
                            if (terrainName == terrainFiles[j])
                            {
                                // Remove this file.
                                terrainFiles[j] = null;
                                break;
                            }
                        }
                    }
                }
            }

            // MyWorlds
            if (myWorldsFiles != null)
            {
                for (int i = 0; i < myWorldsFiles.Length; ++i)
                {
                    string       filename     = myWorldsFiles[i];
                    XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                    if (xmlWorldData == null)
                    {
                        continue;
                    }

                    if (xmlWorldData.xmlTerrainData2 != null)
                    {
                        string terrainName = Path.Combine(Storage4.UserLocation, BokuGame.Settings.MediaPath, xmlWorldData.xmlTerrainData2.virtualMapFile);
                        for (int j = 0; j < terrainFiles.Length; ++j)
                        {
                            if (terrainName == terrainFiles[j])
                            {
                                // Remove this file.
                                terrainFiles[j] = null;
                                break;
                            }
                        }
                    }
                }
            }

            // BuiltInWorlds
            if (starterWorldsFiles != null)
            {
                for (int i = 0; i < starterWorldsFiles.Length; ++i)
                {
                    try
                    {
                        string       filename     = starterWorldsFiles[i];
                        XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                        if (xmlWorldData == null)
                        {
                            continue;
                        }

                        if (xmlWorldData.xmlTerrainData2 != null)
                        {
                            string terrainName = Path.Combine(Storage4.UserLocation, BokuGame.Settings.MediaPath, xmlWorldData.xmlTerrainData2.virtualMapFile);
                            for (int j = 0; j < terrainFiles.Length; ++j)
                            {
                                if (terrainName == terrainFiles[j])
                                {
                                    // Remove this file.
                                    terrainFiles[j] = null;
                                    break;
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }

            // Downloads
            if (downloadsFiles != null)
            {
                for (int i = 0; i < downloadsFiles.Length; ++i)
                {
                    string       filename     = downloadsFiles[i];
                    XmlWorldData xmlWorldData = XmlWorldData.Load(filename, XnaStorageHelper.Instance);
                    if (xmlWorldData == null)
                    {
                        continue;
                    }

                    if (xmlWorldData.xmlTerrainData2 != null)
                    {
                        string terrainName = Path.Combine(Storage4.UserLocation, BokuGame.Settings.MediaPath, xmlWorldData.xmlTerrainData2.virtualMapFile);
                        for (int j = 0; j < terrainFiles.Length; ++j)
                        {
                            if (terrainName == terrainFiles[j])
                            {
                                // Remove this file.
                                terrainFiles[j] = null;
                                break;
                            }
                        }
                    }
                }
            }

            int deleteCount = 0;

            // Now, anything that's left in the list should be fair game for deletion.
            for (int i = 0; i < terrainFiles.Length; i++)
            {
                if (terrainFiles[i] != null)
                {
                    if (Storage4.FileExists(terrainFiles[i], StorageSource.UserSpace))
                    {
                        if (Storage4.Delete(terrainFiles[i]))
                        {
                            deleteCount += 1;
                        }
                    }
                }
            }

            //System.Diagnostics.Debug.WriteLine(String.Format("Scrubbed {0} terrain files", deleteCount));
        }   // end of ScrubTerrainFiles()
        /// <summary>
        /// Delete a level from the local system.  Returns false if not yet initialized.
        /// </summary>
        /// <param name="worldId"></param>
        /// <param name="callback"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public bool StartDeletingLevel(
            Guid worldId,
            Genres bucket,
            BokuAsyncCallback callback,
            object param)
        {
            bool deleted = false;

            bucket &= Genres.SharableBins;

            // Verify exactly one bucket is specified
            Debug.Assert(bucket != 0);
            Debug.Assert((int)bucket == int.MinValue || MyMath.IsPowerOfTwo((int)bucket));

            string worldFilename = null;
            string stuffFilename = null;
            string thumbFilename = null;

            LevelMetadata record = null;

            string stuffPath = String.Empty;
            string worldPath = String.Empty;

            if (0 != (bucket & Genres.MyWorlds))
            {
                stuffPath = BokuGame.MyWorldsStuffPath;
                worldPath = BokuGame.MyWorldsPath;
            }
            else if (0 != (bucket & Genres.Downloads))
            {
                stuffPath = BokuGame.DownloadsStuffPath;
                worldPath = BokuGame.DownloadsPath;
            }


            lock (Synch)
            {
                for (int i = 0; i < allLevels.Count; ++i)
                {
                    record = allLevels[i];

                    if (record.WorldId == worldId && (record.Genres & bucket) == bucket)
                    {
                        worldFilename = Path.Combine(BokuGame.Settings.MediaPath, worldPath + worldId.ToString() + @".Xml");
                        stuffFilename = Path.Combine(BokuGame.Settings.MediaPath, stuffPath + worldId.ToString() + @".Xml");
                        thumbFilename = Path.Combine(BokuGame.Settings.MediaPath, worldPath + worldId.ToString());

                        // Need to get the terrain file before we delete the main file.  BUT the terrain should be
                        // deleted after, otherwise the usage test will find the main file and always thing that
                        // the terrain file is in use.
                        string terrainFilename = null;
                        try
                        {
                            // Only delete terrain file if no longer referenced.
                            XmlWorldData xmlWorldData = XmlWorldData.Load(worldFilename, XnaStorageHelper.Instance);
                            terrainFilename = xmlWorldData.xmlTerrainData2.virtualMapFile;
                        }
                        catch { }

                        // Note : Delete() handles non-existent files just fine.
                        Storage4.Delete(worldFilename);
                        Storage4.Delete(stuffFilename);
                        Storage4.Delete(thumbFilename + @".dds");
                        Storage4.Delete(thumbFilename + @".jpg");
                        Storage4.Delete(thumbFilename + @".png");

                        // Only deletes terrain file if no other world is using it.  (including autosaves)
                        DeleteTerrainFile(terrainFilename);

                        LevelMetadata level = allLevels[i];
                        allLevels.RemoveAt(i);

                        LevelRemoved_Synched(level);

                        deleted = true;

                        break;
                    }
                }
            }

            AsyncResult result = new AsyncResult();

            result.Success = deleted;
            result.Param   = param;
            result.Seconds = 0;

            if (callback != null)
            {
                callback(result);
            }

            return(deleted);
        }
예제 #20
0
        public static void Init()
        {
            //
            // Mirroring data.
            //

            string[] mirrorData = Storage4.ReadAllLines(@"Content\Xml\Unicode\BidiMirroring.txt", StorageSource.TitleSpace);

            if (mirrorData != null)
            {
                for (int i = 0; i < mirrorData.Length; i++)
                {
                    if (!String.IsNullOrEmpty(mirrorData[i]) && !mirrorData[i].StartsWith("#"))
                    {
                        string[] fields = mirrorData[i].Split(new char[] { ';', '#' });
                        // Note, this will throw when it tries to parse the lines in the header.
                        // Feel free to ignore those lines.
                        try
                        {
                            int code   = int.Parse(fields[0], NumberStyles.HexNumber);
                            int mirror = int.Parse(fields[1], NumberStyles.HexNumber);

                            mirrorDict.Add((char)code, (char)mirror);
                        }
                        catch
                        {
                        }
                    }
                }   // end of loop over each line.
            }

            string[] unicodeData = Storage4.ReadAllLines(@"Content\Xml\Unicode\UnicodeData.txt", StorageSource.TitleSpace);

            if (unicodeData != null)
            {
                for (int i = 0; i < unicodeData.Length; i++)
                {
                    string[] fields = unicodeData[i].Split(';');
                    int      code   = 0;

                    // If we throw trying to parse the code, just skip this glyph.
                    try
                    {
                        code = int.Parse(fields[0], NumberStyles.HexNumber);
                    }
                    catch
                    {
                        continue;
                    }

                    UnicodeCharData data = new UnicodeCharData();
                    data.c    = (char)code;
                    data.name = fields[1];
                    data.type = fields[4];
                    data.decompositionMapping = fields[5];
                    data.mirrored             = fields[9] == "Y";

                    // Ignore Arabic contextual forms for ligatures.  This was causing too much breakage.
                    if (data.name.Contains("LIGATURE") && data.name.Contains("ARABIC"))
                    {
                        continue;
                    }

                    if (data.decompositionMapping.StartsWith("<isolated>"))
                    {
                        // Parse may throw.  If it does, just ignore this line.
                        try
                        {
                            data.baseForm = (char)int.Parse(fields[5].Substring(fields[5].Length - 4), NumberStyles.HexNumber);

                            DecompMappingData dm = null;
                            decompMappingDict.TryGetValue(data.baseForm, out dm);
                            if (dm == null)
                            {
                                dm = new DecompMappingData();
                                decompMappingDict.Add(data.baseForm, dm);
                                dm.c = data.baseForm;
                            }
                            dm.isolated = data.c;
                        }
                        catch { }
                    }
                    else if (data.decompositionMapping.StartsWith("<initial>"))
                    {
                        // Parse may throw.  If it does, just ignore this line.
                        try
                        {
                            data.baseForm = (char)int.Parse(fields[5].Substring(fields[5].Length - 4), NumberStyles.HexNumber);

                            DecompMappingData dm = null;
                            decompMappingDict.TryGetValue(data.baseForm, out dm);
                            if (dm == null)
                            {
                                dm = new DecompMappingData();
                                decompMappingDict.Add(data.baseForm, dm);
                                dm.c = data.baseForm;
                            }
                            dm.initial = data.c;
                        }
                        catch { }
                    }
                    else if (data.decompositionMapping.StartsWith("<medial>"))
                    {
                        // Parse may throw.  If it does, just ignore this line.
                        try
                        {
                            data.baseForm = (char)int.Parse(fields[5].Substring(fields[5].Length - 4), NumberStyles.HexNumber);

                            DecompMappingData dm = null;
                            decompMappingDict.TryGetValue(data.baseForm, out dm);
                            if (dm == null)
                            {
                                dm = new DecompMappingData();
                                decompMappingDict.Add(data.baseForm, dm);
                                dm.c = data.baseForm;
                            }
                            dm.medial = data.c;
                        }
                        catch { }
                    }
                    else if (data.decompositionMapping.StartsWith("<final>"))
                    {
                        // Parse may throw.  If it does, just ignore this line.
                        try
                        {
                            data.baseForm = (char)int.Parse(fields[5].Substring(fields[5].Length - 4), NumberStyles.HexNumber);

                            DecompMappingData dm = null;
                            decompMappingDict.TryGetValue(data.baseForm, out dm);
                            if (dm == null)
                            {
                                dm = new DecompMappingData();
                                decompMappingDict.Add(data.baseForm, dm);
                                dm.c = data.baseForm;
                            }
                            dm.final = data.c;
                        }
                        catch { }
                    }

                    // Get ligature data from Decompostion Mapping field.  Note that we're filtering
                    // on only getting Arabic ligatures and ignoring other languages.  This is because
                    // it's too easy to find ligatures with no matching glyphs.
                    if (data.name.Contains("ARABIC LIGATURE") && !string.IsNullOrEmpty(data.decompositionMapping))
                    {
                        // HACK Finding too many missing characters so only look for the one required ligature.
                        if (data.c != 0xfefb)
                        {
                            continue;
                        }

                        // Parse out the chars that combine to form this ligature.
                        int      index = data.decompositionMapping.LastIndexOf('>');
                        string[] args  = data.decompositionMapping.Substring(index + 1).Trim().Split(' ');

                        // Parse may throw.  If it does, just ignore this ligature.
                        try
                        {
                            char   c0    = (char)int.Parse(args[0], NumberStyles.HexNumber);
                            char[] chars = new char[args.Length - 1];
                            for (int c = 0; c < args.Length - 1; c++)
                            {
                                chars[c] = (char)int.Parse(args[c + 1], NumberStyles.HexNumber);
                            }

                            // Create or add to the ligature entry.  Note that the entry
                            // uses the first character of the pair for the key.
                            LigatureData ld = null;
                            ligatureDict.TryGetValue(c0, out ld);

                            // Create new dictionary entry if needed.
                            if (ld == null)
                            {
                                ld           = new LigatureData();
                                ld.c         = c0;
                                ld.ligatures = new List <LigatureEntry>();

                                ligatureDict.Add(c0, ld);
                            }
                            // Add new entry.
                            LigatureEntry le = new LigatureEntry();
                            le.chars  = chars;
                            le.joined = data.c;
                            ld.ligatures.Add(le);
                        }
                        catch { }
                    }

                    if (data.mirrored)
                    {
                        mirrorDict.TryGetValue(data.c, out data.mirroredChar);
                    }

                    if (code >= 0 && code <= 0xFFFF)  //UTF-16 BMP code points only
                    {
                        bool inRange = data.name.EndsWith(", First>");
                        if (inRange)                                    // Add all characters within a specified range.
                        {
                            data.name.Replace(", First", String.Empty); // Remove range indicator from name .
                            fields = unicodeData[++i].Split(';');

                            // Parse may throw.  If it does, just ignore this range?
                            // Not totally sure if this is the right thing to do...
                            try
                            {
                                int endCharCode = int.Parse(fields[0], NumberStyles.HexNumber);

                                if (!fields[1].EndsWith(", Last>"))
                                {
                                    throw new Exception("Expected end-of-range indicator.");
                                }

                                for (int codeInRange = code; codeInRange <= endCharCode; codeInRange++)
                                {
                                    charDict.Add((char)codeInRange, data);
                                }
                            }
                            catch { }
                        }
                        else
                        {
                            charDict.Add((char)code, data);
                        }
                    }
                }   // end of loop over each line.
            }

            // For ligatures, we need to be greedy and try to apply longer conversions
            // before shorter ones.  So, sort all the ligatures in the dictionary by
            // the number of characters putting the longest first.
            foreach (LigatureData ld in ligatureDict.Values)
            {
                ld.ligatures.Sort();
            }
        }   // end of Init()
예제 #21
0
 private Stream OpenTextureStream(string texFilename)
 {
     return(Storage4.TextureFileOpenRead(texFilename));
 }
예제 #22
0
 public override void Close(Stream stream)
 {
     Storage4.Close(stream);
 }