/// <summary>
        /// Returns the highest rank achieved for a level and a given list of difficulties.
        /// </summary>
        /// <param name="levelID">The level ID of the level to search through.</param>
        /// <param name="difficulties">A list of BeatmapDifficulties to search through. Use null to search through all difficulties.</param>
        /// <param name="characteristics">A list of characteristics to search through. Each characteristic is represented by its serialized string.
        /// Use null to search through all characteristics.</param>
        /// <returns>The highest RankModel.Rank enum found for the selected difficulties, or null if the level has not yet been completed.</returns>
        public RankModel.Rank?GetHighestRankForLevel(string levelID, IEnumerable <BeatmapDifficulty> difficulties = null, IEnumerable <string> characteristics = null)
        {
            levelID = BeatmapDetailsLoader.GetSimplifiedLevelID(levelID);

            if (difficulties == null)
            {
                difficulties = LocalLeaderboardDataHelper.AllDifficulties;
            }
            if (characteristics == null)
            {
                characteristics = AllCharacteristicStrings;
            }

            var validEntries = _playerData.levelsStatsData.Where(x =>
                                                                 x.levelID.StartsWith(levelID) &&
                                                                 x.highScore != 0 &&
                                                                 difficulties.Contains(x.difficulty) &&
                                                                 characteristics.Contains(x.beatmapCharacteristic.serializedName));

            if (validEntries.Count() > 0)
            {
                return(validEntries.Max(x => x.maxRank));
            }
            else
            {
                return(null);
            }
        }
Beispiel #2
0
        private static string GetCustomLevelHash(string levelID)
        {
            var simplifiedID = BeatmapDetailsLoader.GetSimplifiedLevelID(levelID);

            if (simplifiedID.StartsWith(CustomLevelLoader.kCustomLevelPrefixId))
            {
                return(simplifiedID.Substring(CustomLevelLoader.kCustomLevelPrefixId.Length));
            }
            else
            {
                return(simplifiedID);
            }
        }
        /// <summary>
        /// Check whether the level has been full combo'd in party mode.
        /// All duplicate custom beatmaps are treated as full combo'd if any of the duplicates have been full combo'd at least once.
        /// </summary>
        /// <param name="levelID">The level ID of the beatmap.</param>
        /// <param name="difficulties">A list of difficulties to check for a full combo (optional).</param>
        /// <param name="playerName">The name of the player on the local leaderboards (optional).</param>
        /// <returns>True if the player(s) has/have achieved a full combo on the beatmap, otherwise false</returns>
        public bool HasFullComboForLevel(string levelID, IEnumerable <BeatmapDifficulty> difficulties = null, string playerName = null)
        {
            levelID = BeatmapDetailsLoader.GetSimplifiedLevelID(levelID);

            if (difficulties == null || difficulties.Count() == 0)
            {
                difficulties = AllDifficulties;
            }

            // get any level duplicates
            List <string> duplicateLevelIDs = GetActualLevelIDs(levelID);

            StringBuilder sb = new StringBuilder();

            foreach (var levID in duplicateLevelIDs)
            {
                foreach (var characteristic in AllCharacteristicStrings)
                {
                    foreach (var difficulty in difficulties)
                    {
                        sb.Clear();
                        sb.Append(levID);
                        sb.Append(characteristic);
                        sb.Append(difficulty.ToString());
                        string leaderboardID = sb.ToString();
                        var    scores        = _localLeaderboardsModel.GetScores(leaderboardID, LocalLeaderboardsModel.LeaderboardType.AllTime);

                        if (scores != null)
                        {
                            if (scores.Any(x => x._fullCombo && (x._playerName == playerName || playerName == null)))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Check whether the player has achieved a full combo for a level on any characteristic and difficulty.
        /// Optionally, you can limit the search for a full combo to a specific characteristic and/or difficulties.
        /// All duplicate custom beatmaps are treated as full combo'd if any of the duplicates have been full combo'd at least once.
        /// </summary>
        /// <param name="levelID">The level ID of the beatmap.</param>
        /// <param name="characteristicName">The serialized name of the characteristic to check for a full combo (optional).</param>
        /// <param name="difficulties">A list of difficulties to check for a full combo (optional).</param>
        /// <returns>True if the player has achieved a full combo on the beatmap, otherwise false.</returns>
        public bool HasFullComboForLevel(string levelID, string characteristicName = null, List <BeatmapDifficulty> difficulties = null)
        {
            levelID = BeatmapDetailsLoader.GetSimplifiedLevelID(levelID);

            if (difficulties != null && difficulties.Count == 0)
            {
                difficulties = null;
            }

            if (!string.IsNullOrEmpty(characteristicName) && difficulties != null)
            {
                return(_playerData.levelsStatsData.Any(x =>
                                                       x.levelID.StartsWith(levelID) &&
                                                       x.beatmapCharacteristic.serializedName == characteristicName &&
                                                       difficulties.Contains(x.difficulty) &&
                                                       x.validScore && x.fullCombo && x.maxCombo != 0));
            }
            else if (!string.IsNullOrEmpty(characteristicName))
            {
                return(_playerData.levelsStatsData.Any(x =>
                                                       x.levelID.StartsWith(levelID) &&
                                                       x.beatmapCharacteristic.serializedName == characteristicName &&
                                                       x.validScore && x.fullCombo && x.maxCombo != 0));
            }
            else if (difficulties != null)
            {
                return(_playerData.levelsStatsData.Any(x =>
                                                       x.levelID.StartsWith(levelID) &&
                                                       difficulties.Contains(x.difficulty) &&
                                                       x.validScore && x.fullCombo && x.maxCombo != 0));
            }
            else
            {
                return(_playerData.levelsStatsData.Any(x => x.levelID.StartsWith(levelID) && x.validScore && x.fullCombo && x.maxCombo != 0));
            }
        }
 /// <summary>
 /// Returns the number of times the player has played a beatmap.
 /// </summary>
 /// <param name="levelID">The level ID of the beatmap to check.</param>
 /// <returns>An integer representing the number of times the player has played the beatmap.</returns>
 public int GetPlayCountForLevel(string levelID)
 {
     levelID = BeatmapDetailsLoader.GetSimplifiedLevelID(levelID);
     return(_playerData.levelsStatsData.Where(x => x.levelID.StartsWith(levelID)).Sum(x => x.playCount));
 }
        // beatmaps have to be loaded after everything is created, since only then will the loading view exist
        private void LoadBeatmaps()
        {
            IPreviewBeatmapLevel[] levelsToLoad;

            if (PluginConfig.ShowFirstTimeLoadingText)
            {
                // first time loading should load all custom levels for cache
                var allCustomLevels = SongCore.Loader.CustomLevels.Values.Select(x => x as IPreviewBeatmapLevel).ToList();
                allCustomLevels.AddRange(_unfilteredLevels);
                levelsToLoad = allCustomLevels.Distinct().ToArray();
            }
            else
            {
                levelsToLoad = _unfilteredLevels;
            }

            _filterMainViewController.ShowLoadingView();

            BeatmapDetailsLoader.instance.StartLoading(levelsToLoad,
                                                       delegate(int loaded)
            {
                // on update, show updated progress text
                _filterMainViewController.UpdateLoadingProgressText(loaded, levelsToLoad.Length);
            },
                                                       delegate(BeatmapDetails[] levels)
            {
                // on finish
                _filterSideViewController.FilterListActive         = true;
                _filterSideViewController.QuickFilterSectionActive = true;

                // NOTE: this quick filter check is done here, since the text size calculation cannot be done during DidActivate
                // it also can't happen before FilterListActive is set to true, otherwise the first time this text is shown,
                // it will be a tenth of the size of what it should be
                _filterSideViewController.CheckSelectedQuickFilter();

                if (_currentFilter != null)
                {
                    FilterSelected(_currentFilter);
                    _filterSideViewController.SelectFilterCell(FilterList.ActiveFilters.IndexOf(_currentFilter));
                }
                else
                {
                    FilterSelected(FilterList.ActiveFilters.First());
                    _filterSideViewController.SelectFilterCell(0);
                }
                RefreshUI();

                _beatmapDetails = new Dictionary <IPreviewBeatmapLevel, BeatmapDetails>(_unfilteredLevels.Length);
                foreach (var level in _unfilteredLevels)
                {
                    // if a custom level's level ID contains the name of its folder, strip it out
                    var details = levels.FirstOrDefault(x => x?.LevelID == BeatmapDetailsLoader.GetSimplifiedLevelID(level));
                    if (details == null)
                    {
                        continue;
                    }

                    _beatmapDetails[level] = details;
                }

                PluginConfig.ShowFirstTimeLoadingText = false;
            });
        }