public override PPTuple GetPerformance()
        {
            int pos = Beatmap.GetPosition(Time, out int nobject);

            if (_cleared == true)
            {
                _maxPpResult = SendCalculateCtb(new ArraySegment <byte>(Beatmap.RawData), Mods);
                if (_maxPpResult != null)
                {
                    _ppTuple.MaxPP         = CalculatePp(_maxPpResult, Mods, 100, _maxPpResult.FullCombo, 0);
                    _ppTuple.MaxAccuracyPP = 0;
                    _ppTuple.MaxSpeedPP    = 0;
                    _ppTuple.MaxAimPP      = 0;
                }

                FullCombo = _maxPpResult.FullCombo;

                _cleared = false;
            }

            if (_lastAcc != Accuracy)
            {
                if (_maxPpResult != null)
                {
                    double fcpp = CalculatePp(_maxPpResult, Mods, Accuracy, _maxPpResult.FullCombo, 0);
                    _ppTuple.FullComboPP         = fcpp;
                    _ppTuple.FullComboAccuracyPP = 0;
                    _ppTuple.FullComboSpeedPP    = 0;
                    _ppTuple.FullComboAimPP      = 0;
                }
            }

            _lastAcc = Accuracy;

            bool needUpdate = _last_max_combo != MaxCombo;

            needUpdate |= _last_nmiss != CountMiss;


            if (needUpdate)
            {
                if (nobject > 0)
                {
                    CtbServerResult ctbServerResult;
                    ctbServerResult = SendCalculateCtb(new ArraySegment <byte>(Beatmap.RawData, 0, pos), Mods);
                    if (ctbServerResult != null)
                    {
                        _ppTuple.RealTimePP         = CalculatePp(ctbServerResult, Mods, Accuracy, MaxCombo, CountMiss);
                        _ppTuple.RealTimeAccuracyPP = 0;
                        _ppTuple.RealTimeSpeedPP    = 0;
                        _ppTuple.RealTimeAimPP      = 0;
                        RealTimeMaxCombo            = ctbServerResult.FullCombo;
                    }
                }
            }

            return(_ppTuple);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculates the pp.
        /// </summary>
        /// <param name="serverResult">The server result.</param>
        /// <param name="ar">The ar.</param>
        /// <param name="mods">The mods.</param>
        /// <param name="acc">The acc (0-100).</param>
        /// <param name="maxCombo">The maximum combo.</param>
        /// <param name="nmiss">The nmiss.</param>
        /// <returns></returns>
        public static double CalculatePp(CtbServerResult serverResult, uint mods, double acc, int maxCombo, int nmiss)
        {
            acc /= 100.0;

            double pp           = Math.Pow(((5 * serverResult.Stars / 0.0049) - 4), 2) / 100000;
            double length_bonus = 0.95 + 0.4 * Math.Min(1, maxCombo / 3000.0);

            if (maxCombo > 3000)
            {
                length_bonus += Math.Log10(maxCombo / 3000.0) * 0.5;
            }

            pp *= length_bonus;
            pp *= Math.Pow(0.97, nmiss);
            pp *= Math.Min(Math.Pow(maxCombo, 0.8) / Math.Pow(serverResult.FullCombo, 0.8), 1);

            if (serverResult.ApproachRate > 9)
            {
                pp *= 1 + 0.1 * (serverResult.ApproachRate - 9);
            }
            if (serverResult.ApproachRate < 8)
            {
                pp *= 1 + 0.025 * (8 - serverResult.ApproachRate);
            }

            if (mods.HasMod(ModsInfo.Mods.Hidden))
            {
                pp *= 1.05 + 0.075 * (10 - Math.Min(10, serverResult.ApproachRate));
            }
            if (mods.HasMod(ModsInfo.Mods.Flashlight))
            {
                pp *= 1.35 * length_bonus;
            }

            pp *= Math.Pow(acc, 5.5);

            if (mods.HasMod(ModsInfo.Mods.NoFail))
            {
                pp *= 0.9;
            }
            if (mods.HasMod(ModsInfo.Mods.SpunOut))
            {
                pp *= 0.95;
            }

            return(pp);
        }
Ejemplo n.º 3
0
        public CtbServerResult SendCalculateCtb(ArraySegment <byte> content, uint mods)
        {
            if (!CtbServerRunning)
            {
                RestartCtbServer();
                return(new CtbServerResult());
            }

            if (content.Count == 0)
            {
                return(new CtbServerResult());
            }

            try
            {
                lock (_tcpClient)
                {
                    var stream = _tcpClient.GetStream();
                    using (var sw = new BinaryWriter(stream, Encoding.UTF8, true))
                    {
                        sw.Write(CALCULATE_CTB_PP);
                        sw.Write(content.Count);
                        stream.Write(content.Array, content.Offset, content.Count);
                        sw.Write(mods); //mods
                    }

                    using (var br = new BinaryReader(stream, Encoding.UTF8, true))
                    {
                        var ret = new CtbServerResult();
                        ret.Stars        = br.ReadDouble();
                        ret.FullCombo    = br.ReadInt32();
                        ret.ApproachRate = br.ReadDouble();
                        return(ret);
                    }
                }
            }
            catch (Exception e)
            {
#if DEBUG
                Sync.Tools.IO.CurrentIO.WriteColor($"[RTPPD::CTB]:{e.Message}", ConsoleColor.Yellow);
#endif
                _tcpClient.Close();
                ConnectCtbServer();
                return(null);
            }
        }
Ejemplo n.º 4
0
        public override void HandleExtraData(Dictionary <string, object> extra, Dictionary <string, string> map_info)
        {
            calc_cache = null;
            SetBeatmap(extra["ortdp_beatmap"] as OsuRTDataProvider.BeatmapInfo.Beatmap);
            SetMod((Mods.ModsInfo)extra["Mods"]);

            var list = extra["AccuracyList"] as List <float>;

            foreach (var acc in list)
            {
                var pp = GetData(acc, RequireType.PP);
                map_info[$"pp:{acc:F2}%"] = pp?.ToString("F2") ?? "0";
            }

            map_info["ar"] = GetData(100, RequireType.AR)?.ToString("F2") ?? map_info["ar"];
            var star = GetData(100, RequireType.Star)?.ToString("F2");

            if (!string.IsNullOrWhiteSpace(star))
            {
                map_info["stars"] = star;
            }
        }
Ejemplo n.º 5
0
        private double?GetData(float acc, RequireType require)
        {
            int retry = 15;

            while (retry != 0)
            {
                try
                {
                    if (calc_cache == null)
                    {
                        calc_cache = ctb_pp_calc.SendCalculateCtb(new ArraySegment <byte>(this.ctb_pp_calc.Beatmap.RawData), ctb_pp_calc.Mods);
                    }
                    switch (require)
                    {
                    case RequireType.PP:
                        return(CalculatePp(calc_cache, ctb_pp_calc.Mods, acc, calc_cache.FullCombo, 0));

                    case RequireType.Star:
                        return(calc_cache.Stars);

                    case RequireType.AR:
                        return(calc_cache.ApproachRate);

                    default:
                        return(null);
                    }
                }
                catch
                {
                    Thread.Sleep(50);
                    retry--;
                }
            }

            return(0);
        }