예제 #1
0
        public int JumpCompatibility(LevelMetadata level, string searchString)
        {
            int result = 0;

            switch (SortBy)
            {
            case SortBy.Creator:
                result = JumpCompatibility(level.Creator, searchString);
                break;

            case SortBy.Name:
                result = JumpCompatibility(level.Name, searchString);
                break;
            }

            return(result);
        }
예제 #2
0
        public bool FindBrokenLink(ref LevelMetadata brokenLevel, ref bool forwardLink)
        {
            //initialize the out params - assume no broken link
            brokenLevel = null;
            forwardLink = false;

            //First, walk backwards to the first link
            LevelMetadata currentLink  = this;
            LevelMetadata previousLink = null;
            LevelMetadata nextLink     = null;

            while (currentLink.LinkedFromLevel != null)
            {
                //check to make sure the xml exists
                previousLink = currentLink.PreviousLink();

                if (null == previousLink)
                {
                    brokenLevel = currentLink;
                    forwardLink = false; //broke walking backwards

                    return(true);
                }
                currentLink = previousLink;
            }

            //first link now points to the beginning, walk forward to the end, ensuring we
            while (currentLink.LinkedToLevel != null)
            {
                //check to make sure the xml exists
                nextLink = currentLink.NextLink();

                if (null == nextLink)
                {
                    brokenLevel = currentLink;
                    forwardLink = false; //broke walking backwards

                    return(true);
                }
                currentLink = nextLink;
            }

            //if we made it this far, all of the links worked out
            return(false);
        }
예제 #3
0
        internal void LevelAdded(int index, LevelMetadata level)
        {
            if (level.WorldId == desiredSelection && totalOpCount == 0)
            {
                // If we were looking for a specific level and the user hasn't explicitly moved the cursor,
                // move the cursor to point at the identified level.
                totalOpCount += 1;
                QueryPointer  = index;
            }
            else if (totalOpCount > 0 && index <= QueryPointer && !Query.IsEmpty)
            {
                // If we want the cursor to remain on the current level, and the new level being added comes
                // before the current selection, this means the current level bumps forward in the query, so
                // adjust the selection to remain on the current level.
                QueryPointer += 1;
            }

            additionCallback(this, index - QueryPointer);
        }
        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);
        }
        /// <summary>
        /// Start deleting a level from the community server.  You must have adequate permissions or the server will deny your request.
        /// </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)
        {
            int index = IndexOf(worldId);

            if (index >= 0)
            {
                LevelMetadata level = allLevels[index];
                allLevels.RemoveAt(index);
                LevelRemoved(level);
            }

            return(0 != Web.Community.Async_DelWorldData2(
                       worldId,
                       Auth.Pin,
                       callback,
                       param));
        }
        public void StartDownloadingThumbnail(LevelMetadata level, ThumbnailDownloadCompleteEvent callback, bool lowPriority)
        {
            if (level != null && !level.Thumbnail.IsLoaded && !level.Thumbnail.Loading)
            {
                LevelBrowserState state = (LevelBrowserState)level.BrowserState;
                state.thumbnailCallback = callback;

                // If it already exists in the queue, move it to the end.
                queuedThumbnailLoads.Remove(level);
                queuedThumbnailLoads.Add(level);
            }

            // Only keep a max of 20 pending thumbnail loads, that way of we're just scrolling
            // to the end of the list, we can discard many of these requests as they pass out of view.
            while (queuedThumbnailLoads.Count > 20)
            {
                LevelBrowserState state = (LevelBrowserState)queuedThumbnailLoads[0].BrowserState;
                state.thumbnailCallback = null;
                queuedThumbnailLoads.RemoveAt(0);
            }
        }
예제 #7
0
        public static LevelMetadata LoadMetadataByGenre(Guid worldId, Genres genres)
        {
            string bucket = BokuGame.MyWorldsPath;

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

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

            Xml.XmlWorldData xml = XmlWorldData.Load(fullPath, XnaStorageHelper.Instance);
            if (xml != null)
            {
                LevelMetadata data = new LevelMetadata();
                data.FromXml(xml);

                //minor hackery - seems previous versions of kodu will sometimes leave the genres set to 0
                //even though they should be updated for the bucket the level is in.  Then at load time, a run-time
                //genre is set.  This code will maintain that behavior for levels loaded through this helper
                if (bucket == BokuGame.DownloadsPath)
                {
                    //ensure downloads always have the downloads flag
                    data.Genres |= Genres.Downloads;
                }
                else if (bucket == BokuGame.BuiltInWorldsPath)
                {
                    //ensure built in worlds always have the built in flag
                    data.Genres |= Genres.BuiltInWorlds;
                }
                else if (bucket == BokuGame.MyWorldsPath)
                {
                    data.Genres |= Genres.MyWorlds;
                }

                return(data);
            }

            return(null);
        }
예제 #8
0
        public static LevelMetadata LoadMetadataUnknownGenre(Guid worldId)
        {
            LevelMetadata result = null;

            if (CheckWorldExistsByGenre(worldId, Genres.MyWorlds))
            {
                result         = LoadMetadataByGenre(worldId, Genres.MyWorlds);
                result.Genres |= Genres.MyWorlds;
            }
            else if (CheckWorldExistsByGenre(worldId, Genres.Downloads))
            {
                result         = LoadMetadataByGenre(worldId, Genres.Downloads);
                result.Genres |= Genres.Downloads;
            }
            else if (CheckWorldExistsByGenre(worldId, Genres.BuiltInWorlds))
            {
                result         = LoadMetadataByGenre(worldId, Genres.BuiltInWorlds);
                result.Genres |= Genres.BuiltInWorlds;
            }

            return(result);
        }
        public void Update()
        {
            lock (Synch)
            {
                foreach (LevelSetQuery query in queries)
                {
                    query.Update();
                }
            }

            if (thumbnailLoadOpCount == 0 && queuedThumbnailLoads.Count > 0)
            {
                // Pull from the end of the list to service newer requests first.
                LevelMetadata level = queuedThumbnailLoads[queuedThumbnailLoads.Count - 1];
                queuedThumbnailLoads.RemoveAt(queuedThumbnailLoads.Count - 1);
                thumbnailLoadOpCount += 1;
                Web.Community.Async_GetThumbnail(
                    level.WorldId,
                    level.Thumbnail,
                    GotThumbnail,
                    level);
            }
        }
 public void MetadataUpdated(LevelMetadata level)
 {
 }
        /// <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);
        }
 }                                           //True allows server side to handle matches
 public bool Matches(LevelMetadata item)
 {
     return(true);
 }
예제 #13
0
        /// <summary>
        /// Based on the current filter's tags, decides whether or not a level matches.
        /// Note that this logic must match the logic on the server side otherwise
        /// madness ensues.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        virtual public bool Matches(LevelMetadata item)
        {
            //check for server side matching
            if (ServerSideMatching)
            {
                return(true);
            }

            Genres itemGenres = item.Genres;

            if (FilterGenres == Genres.All)
            {
                return(true);
            }

            // If all the bucket tags are set, don't bother filtering on MyWorlds.
            Genres filterBuckets = FilterGenres & Genres.Buckets;

            if (filterBuckets != Genres.Buckets)
            {
                // If MyWorlds is set, filter out anything that the user didn't author.
                if ((FilterGenres & Genres.MyWorlds) != 0)
                {
                    // First look for the right name.
                    if (Auth.CreatorName == item.Creator && !string.IsNullOrEmpty(item.Checksum))
                    {
                        if (!Auth.IsValidCreatorChecksum(item.Checksum, item.LastWriteTime))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            // If no bucket bits are set, that means the bucket is All.
            if (filterBuckets == 0 || filterBuckets == Genres.Buckets)
            {
                // Must be All, so don't filter.
            }
            else
            {
                // If any bucket is set, filter out anything that doesn't match.
                if ((itemGenres & filterBuckets) == 0)
                {
                    return(false);
                }
            }

            // Now that we've filtered on the buckets, we're left with filtering on
            // the individual tags so grab that subset.
            Genres filterTags = FilterGenres & Genres.NonBucket;

            if (filterTags == Genres.NonBucket)
            {
                // All set so everything passes.
            }
            else
            {
                // Look for any matches.
                if ((int)(filterTags & itemGenres) == 0)
                {
                    // No match.
                    return(false);
                }
            }

            return(true);
        }