/// <summary>
        ///     Returns the score processor to use. Loads hit stats from a replay if needed.
        /// </summary>
        /// <param name="screen"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        private static ScoreProcessor GetScoreProcessor(ResultScreen screen)
        {
            // If we already have stats (for example, this is a result screen right after a player finished playing a map), use them.
            if (screen.ScoreProcessor.Stats != null)
            {
                return(screen.ScoreProcessor);
            }

            // Otherwise, get the stats from a replay.
            Replay replay = null;

            // FIXME: unify this logic with watching a replay from a ResultScreen.
            try
            {
                switch (screen.ResultsType)
                {
                case ResultScreenType.Gameplay:
                case ResultScreenType.Replay:
                    replay = screen.Replay;
                    break;

                case ResultScreenType.Score:
                    // Don't do anything for online replays since they aren't downloaded yet.
                    if (!screen.Score.IsOnline)
                    {
                        replay = new Replay($"{ConfigManager.DataDirectory.Value}/r/{screen.Score.Id}.qr");
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                NotificationManager.Show(NotificationLevel.Error, "Unable to read replay file");
                Logger.Error(e, LogType.Runtime);
            }

            // Load a replay if we got one.
            if (replay == null)
            {
                return(screen.ScoreProcessor);
            }

            var qua = ResultScreen.Map.LoadQua();

            qua.ApplyMods(replay.Mods);

            var player = new VirtualReplayPlayer(replay, qua);

            player.PlayAllFrames();

            return(player.ScoreProcessor);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="screen"></param>
        /// <param name="map"></param>
        protected GameplayRuleset(GameplayScreen screen, Qua map)
        {
            Screen         = screen;
            Map            = map;
            ScoreProcessor = CreateScoreProcessor(Map);
            CreatePlayfield();
            InputManager     = CreateInputManager();
            HitObjectManager = CreateHitObjectManager();

            StandardizedReplayPlayer = new VirtualReplayPlayer(new Replay(Map.Mode,
                                                                          ConfigManager.Username.Value, ModManager.Mods, Screen.MapHash), map, null, true);
        }
        /// <summary>
        ///     Ctor -
        /// </summary>
        /// <param name="screen"></param>
        internal ReplayInputManagerKeys(GameplayScreen screen)
        {
            Screen = screen;
            Replay = Screen.LoadedReplay;

            VirtualPlayer = new VirtualReplayPlayer(Replay, Screen.Map);
            VirtualPlayer.PlayAllFrames();

            // Populate unique key presses/releases.
            for (var i = 0; i < screen.Map.GetKeyCount(); i++)
            {
                UniquePresses.Add(false);
                UniqueReleases.Add(false);
            }
        }
        /// <summary>
        ///     Ctor -
        /// </summary>
        /// <param name="screen"></param>
        internal ReplayInputManagerKeys(GameplayScreen screen)
        {
            Screen = screen;
            Replay = Screen.LoadedReplay;

            var windows = Screen.SpectatorClient != null
                ? JudgementWindowsDatabaseCache.Standard
                : JudgementWindowsDatabaseCache.Selected.Value;

            VirtualPlayer = new VirtualReplayPlayer(Replay, Screen.Map, windows, Screen.SpectatorClient != null);

            VirtualPlayer.PlayAllFrames();

            // Populate unique key presses/releases.
            for (var i = 0; i < screen.Map.GetKeyCount(); i++)
            {
                UniquePresses.Add(false);
                UniqueReleases.Add(false);
            }
        }
        /// <summary>
        /// </summary>
        public override void Execute()
        {
            var virtualPlayer = new VirtualReplayPlayer(Replay, Map);

            virtualPlayer.Replay.Frames.ForEach(x => virtualPlayer.PlayNextFrame());

            var hits = new List <string>();

            foreach (var stat in virtualPlayer.ScoreProcessor.Stats)
            {
                var val = $"{stat.HitDifference}{(stat.HitObject.IsLongNote ? "L" : "")}";
                hits.Add(val);
            }

            Console.WriteLine(JObject.FromObject(new
            {
                Map = new
                {
                    Md5 = MapMd5,
                    Map.Artist,
                    Map.Title,
                    Map.DifficultyName,
                    Map.Mode,
                    Map.Creator,
                    Map.Length,
                    Map.MapId,
                    Map.MapSetId,
                    ObjectCount       = Map.HitObjects.Count,
                    NormalObjectCount = Map.HitObjects.FindAll(x => !x.IsLongNote).Count,
                    LongNoteCount     = Map.HitObjects.FindAll(x => x.IsLongNote).Count,
                    KeyCount          = Map.GetKeyCount(),
                },
                Replay = new
                {
                    Replay.Md5,
                    Replay.MapMd5,
                    Replay.ReplayVersion,
                    Replay.PlayerName,
                    Replay.Date,
                    Replay.TimePlayed,
                    Replay.Mode,
                    Replay.Mods,
                    Replay.PauseCount,
                    Replay.HasData,
                    FrameCount = Replay.Frames.Count,
                    Length     = Replay.Frames.Last().Time,
                    Replay.Score,
                    Replay.Accuracy,
                    Replay.MaxCombo,
                    Replay.CountMarv,
                    Replay.CountPerf,
                    Replay.CountGreat,
                    Replay.CountGood,
                    Replay.CountOkay,
                    Replay.CountMiss
                },
                VirtualReplayPlayer = new
                {
                    virtualPlayer.ScoreProcessor.Score,
                    virtualPlayer.ScoreProcessor.Accuracy,
                    virtualPlayer.ScoreProcessor.MaxCombo,
                    CountMarv  = virtualPlayer.ScoreProcessor.CurrentJudgements[Judgement.Marv],
                    CountPerf  = virtualPlayer.ScoreProcessor.CurrentJudgements[Judgement.Perf],
                    CountGreat = virtualPlayer.ScoreProcessor.CurrentJudgements[Judgement.Great],
                    CountGood  = virtualPlayer.ScoreProcessor.CurrentJudgements[Judgement.Good],
                    CountOkay  = virtualPlayer.ScoreProcessor.CurrentJudgements[Judgement.Okay],
                    CountMiss  = virtualPlayer.ScoreProcessor.CurrentJudgements[Judgement.Miss],
                    Hits       = hits
                },
            }));
        }
Example #6
0
        /// <summary>
        ///     Returns the score processor to use. Loads hit stats from a replay if needed.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public ScoreProcessor GetScoreProcessor()
        {
            // Handles the case when watching a replay in its entirety. This uses the preprocessed
            // ScoreProcessor/Replay from gameplay to get a 100% accurate score output.
            // Also avoids having to process the replay again (as done below).
            if (Gameplay != null && Gameplay.InReplayMode)
            {
                var im = Gameplay.Ruleset.InputManager as KeysInputManager;
                return(im?.ReplayInputManager.VirtualPlayer.ScoreProcessor);
            }

            // If we already have stats (for example, this is a result screen right after a player finished playing a map), use them.
            if (ScoreProcessor.Stats != null)
            {
                return(ScoreProcessor);
            }

            // Otherwise, get the stats from a replay.
            Replay replay = null;

            // FIXME: unify this logic with watching a replay from a ResultScreen.
            try
            {
                switch (ResultsType)
                {
                case ResultScreenType.Gameplay:
                case ResultScreenType.Replay:
                    replay = Replay;
                    break;

                case ResultScreenType.Score:
                    // Don't do anything for online replays since they aren't downloaded yet.
                    if (!Score.IsOnline)
                    {
                        replay = new Replay($"{ConfigManager.DataDirectory.Value}/r/{Score.Id}.qr");
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                NotificationManager.Show(NotificationLevel.Error, "Unable to read replay file");
                Logger.Error(e, LogType.Runtime);
            }

            // Load a replay if we got one.
            if (replay == null)
            {
                return(ScoreProcessor);
            }

            var qua = Map.LoadQua();

            qua.ApplyMods(replay.Mods);
            if (replay.Mods.HasFlag(ModIdentifier.Randomize))
            {
                qua.RandomizeLanes(replay.RandomizeModifierSeed);
            }

            JudgementWindows windows = null;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (Score != null && Score.JudgementWindowPreset != JudgementWindowsDatabaseCache.Standard.Name && Score.JudgementWindowMarv != 0)
            {
                windows = new JudgementWindows()
                {
                    Marvelous = Score.JudgementWindowMarv,
                    Perfect   = Score.JudgementWindowPerf,
                    Great     = Score.JudgementWindowGreat,
                    Good      = Score.JudgementWindowGood,
                    Okay      = Score.JudgementWindowOkay,
                    Miss      = Score.JudgementWindowMiss
                };
            }

            var player = new VirtualReplayPlayer(replay, qua, windows);

            player.PlayAllFrames();

            return(player.ScoreProcessor);
        }