1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 03:03:21 +08:00

Compare commits

...

10 Commits

Author SHA1 Message Date
KermitNuggies
6c5aacf7a3
Merge 67560f1d4d into f09d8f097a 2024-12-03 17:43:47 +09:00
Dan Balasescu
f09d8f097a
Merge pull request #30953 from peppy/notification-while-chedcking-for-updates
Show an ongoing operation when checking for updates
2024-12-03 17:27:10 +09:00
Dean Herbert
457957d3b8
Refactor check-update flow to better handle unobserved exceptions 2024-12-03 14:23:10 +09:00
Dean Herbert
2ceb3f6f85
Show an ongoing operation when checking for updates
Addresses https://github.com/ppy/osu/discussions/30950.
2024-12-03 13:43:20 +09:00
KermitNuggies
67560f1d4d
Merge branch 'ppy:master' into clean-length 2024-11-30 12:05:35 +13:00
TextAdventurer12
1539ce0805 fix sliderfactor on relax 2024-11-30 11:36:58 +13:00
TextAdventurer12
d01d01a44b fix sliderfactor on touch device 2024-11-30 11:36:04 +13:00
kwotaq
ea53e984bd fix in line 2024-11-28 22:41:39 +13:00
kwotaq
9bfcb64741 add a log to aim length so it doesn't explode on really really long consistent maps 2024-11-28 22:41:32 +13:00
TextAdventurer12
fcf7e0034d create clean branch with length changes 2024-11-28 01:18:02 +13:00
6 changed files with 98 additions and 33 deletions

View File

@ -52,6 +52,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty
[JsonProperty("speed_difficult_strain_count")]
public double SpeedDifficultStrainCount { get; set; }
// DEV ATTRIBUTE - DO NOT STORE
[JsonProperty("aim_relevant_object_count")]
public double AimRelevantObjectCount { get; set; }
// DEV ATTRIBUTE - DO NOTE STORE
[JsonProperty("speed_relevant_object_count")]
public double SpeedRelevantObjectCount { get; set; }
/// <summary>
/// The perceived approach rate inclusive of rate-adjusting mods (DT/HT/etc).
/// </summary>

View File

@ -46,24 +46,41 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(h => h is OsuModFlashlight))
flashlightRating = Math.Sqrt(skills[3].DifficultyValue()) * difficulty_multiplier;
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountTopWeightedStrains();
double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountTopWeightedStrains();
if (mods.Any(m => m is OsuModTouchDevice))
{
aimRating = Math.Pow(aimRating, 0.8);
aimRatingNoSliders = Math.Pow(aimRatingNoSliders, 0.8);
flashlightRating = Math.Pow(flashlightRating, 0.8);
}
if (mods.Any(h => h is OsuModRelax))
{
aimRating *= 0.9;
aimRatingNoSliders *= 0.9;
speedRating = 0.0;
flashlightRating *= 0.7;
}
double aimRelevantObjectCount = ((OsuStrainSkill)skills[0]).CountRelevantObjects();
double aimNoSlidersRelevantObjectCount = ((OsuStrainSkill)skills[1]).CountRelevantObjects();
double speedRelevantObjectCount = ((OsuStrainSkill)skills[2]).CountRelevantObjects();
double aimLengthBonus = (aimRelevantObjectCount < 25 ? 0.8 + aimRelevantObjectCount / 150.0 : 0.9 + Math.Min(1.5, aimRelevantObjectCount / 375.0) +
(aimRelevantObjectCount > 562.5 ? Math.Log10(aimRelevantObjectCount / 562.5) : 0));
aimRating *= Math.Cbrt(aimLengthBonus);
double aimNoSlidersLengthBonus = (aimNoSlidersRelevantObjectCount < 25 ? 0.8 + aimNoSlidersRelevantObjectCount / 150.0 : 0.9 + aimNoSlidersRelevantObjectCount / 375.0);
aimRatingNoSliders *= Math.Cbrt(aimNoSlidersLengthBonus);
double speedLengthBonus = 0.9 + 0.5 * Math.Min(1.0, speedRelevantObjectCount / 500.0) +
(speedRelevantObjectCount > 500 ? Math.Log10(speedRelevantObjectCount / 500.0) * 0.3 : 0.0);
speedRating *= Math.Cbrt(speedLengthBonus);
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double baseAimPerformance = OsuStrainSkill.DifficultyToPerformance(aimRating);
double baseSpeedPerformance = OsuStrainSkill.DifficultyToPerformance(speedRating);
double baseFlashlightPerformance = 0.0;
@ -79,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
);
double starRating = basePerformance > 0.00001
? Math.Cbrt(OsuPerformanceCalculator.PERFORMANCE_BASE_MULTIPLIER) * 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4)
? Math.Cbrt(OsuPerformanceCalculator.PERFORMANCE_BASE_MULTIPLIER) * 0.026 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4)
: 0;
double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
@ -105,6 +122,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SliderFactor = sliderFactor,
AimDifficultStrainCount = aimDifficultyStrainCount,
SpeedDifficultStrainCount = speedDifficultyStrainCount,
AimRelevantObjectCount = aimRelevantObjectCount,
SpeedRelevantObjectCount = speedRelevantObjectCount,
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
OverallDifficulty = (80 - hitWindowGreat) / 6,
DrainRate = drainRate,

View File

@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{
public class OsuPerformanceCalculator : PerformanceCalculator
{
public const double PERFORMANCE_BASE_MULTIPLIER = 1.15; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things.
public const double PERFORMANCE_BASE_MULTIPLIER = 1.152; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things.
private bool usingClassicSliderAccuracy;
@ -137,10 +137,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{
double aimValue = OsuStrainSkill.DifficultyToPerformance(attributes.AimDifficulty);
double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount);
@ -153,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (score.Mods.Any(h => h is OsuModRelax))
approachRateFactor = 0.0;
aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
aimValue *= 1.0 + approachRateFactor;
if (score.Mods.Any(m => m is OsuModBlinds))
aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * attributes.DrainRate * attributes.DrainRate);
@ -201,10 +197,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedValue = OsuStrainSkill.DifficultyToPerformance(attributes.SpeedDifficulty);
double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount);
@ -212,7 +204,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33);
speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
speedValue *= 1.0 + approachRateFactor;
if (score.Mods.Any(m => m is OsuModBlinds))
{

View File

@ -57,6 +57,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty;
}
/// <summary>
/// Returns the number of relevant objects weighted against the top strain.
/// </summary>
public double CountRelevantObjects()
{
double consistentTopStrain = DifficultyValue() / 10; // What would the top strain be if all strain values were identical
if (consistentTopStrain == 0)
return 0.0;
//Being consistently difficult for 1000 notes should be worth more than being consistently difficult for 100.
double totalStrains = ObjectStrains.Count;
double lengthFactor = 0.74 * Math.Pow(0.9987, totalStrains);
//// Use a weighted sum of all strains. Constants are arbitrary and give nice values
return ObjectStrains.Sum(s => (1.1 - lengthFactor)/ (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88 - lengthFactor / 4.0))));
}
public static double DifficultyToPerformance(double difficulty) => Math.Pow(5.0 * Math.Max(1.0, difficulty / 0.0675) - 4.0, 3.0) / 100000.0;
}
}

View File

@ -44,6 +44,11 @@ namespace osu.Game.Localisation
/// </summary>
public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates");
/// <summary>
/// "Checking for updates"
/// </summary>
public static LocalisableString CheckingForUpdates => new TranslatableString(getKey(@"checking_for_updates"), @"Checking for updates");
/// <summary>
/// "Open osu! folder"
/// </summary>

View File

@ -4,7 +4,6 @@
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Framework.Logging;
@ -13,6 +12,7 @@ using osu.Framework.Screens;
using osu.Framework.Statistics;
using osu.Game.Configuration;
using osu.Game.Localisation;
using osu.Game.Online.Multiplayer;
using osu.Game.Overlays.Notifications;
using osu.Game.Overlays.Settings.Sections.Maintenance;
using osu.Game.Updater;
@ -36,8 +36,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
[Resolved]
private Storage storage { get; set; } = null!;
[Resolved]
private OsuGame? game { get; set; }
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, OsuGame? game)
private void load(OsuConfigManager config)
{
Add(new SettingsEnumDropdown<ReleaseStream>
{
@ -50,23 +53,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
Add(checkForUpdatesButton = new SettingsButton
{
Text = GeneralSettingsStrings.CheckUpdate,
Action = () =>
{
checkForUpdatesButton.Enabled.Value = false;
Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(task => Schedule(() =>
{
if (!task.GetResultSafely())
{
notifications?.Post(new SimpleNotification
{
Text = GeneralSettingsStrings.RunningLatestRelease(game!.Version),
Icon = FontAwesome.Solid.CheckCircle,
});
}
checkForUpdatesButton.Enabled.Value = true;
}));
}
Action = () => checkForUpdates().FireAndForget()
});
}
@ -94,6 +81,44 @@ namespace osu.Game.Overlays.Settings.Sections.General
}
}
private async Task checkForUpdates()
{
if (updateManager == null || game == null)
return;
checkForUpdatesButton.Enabled.Value = false;
var checkingNotification = new ProgressNotification
{
Text = GeneralSettingsStrings.CheckingForUpdates,
};
notifications?.Post(checkingNotification);
try
{
bool foundUpdate = await updateManager.CheckForUpdateAsync().ConfigureAwait(true);
if (!foundUpdate)
{
notifications?.Post(new SimpleNotification
{
Text = GeneralSettingsStrings.RunningLatestRelease(game.Version),
Icon = FontAwesome.Solid.CheckCircle,
});
}
}
catch
{
}
finally
{
// This sequence allows the notification to be immediately dismissed.
checkingNotification.State = ProgressNotificationState.Cancelled;
checkingNotification.Close(false);
checkForUpdatesButton.Enabled.Value = true;
}
}
private void exportLogs()
{
ProgressNotification notification = new ProgressNotification