mirror of
https://github.com/ppy/osu.git
synced 2025-01-26 12:25:04 +08:00
Fix scores sometimes not being re-standardised correctly
This commit is contained in:
parent
4c872094c9
commit
297168ecc4
@ -38,6 +38,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
Rank = Rank,
|
Rank = Rank,
|
||||||
Ruleset = ruleset,
|
Ruleset = ruleset,
|
||||||
Mods = mods,
|
Mods = mods,
|
||||||
|
IsLegacyScore = true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Statistics != null)
|
if (Statistics != null)
|
||||||
|
@ -185,6 +185,34 @@ namespace osu.Game.Scoring
|
|||||||
[JsonProperty("position")]
|
[JsonProperty("position")]
|
||||||
public int? Position { get; set; }
|
public int? Position { get; set; }
|
||||||
|
|
||||||
|
private bool isLegacyScore;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this <see cref="ScoreInfo"/> represents a legacy (osu!stable) score.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsLegacyScore
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (isLegacyScore)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// The above check will catch legacy online scores that have an appropriate UserString + UserId.
|
||||||
|
// For non-online scores such as those imported in, a heuristic is used based on the following table:
|
||||||
|
//
|
||||||
|
// Mode | UserString | UserId
|
||||||
|
// --------------- | ---------- | ---------
|
||||||
|
// stable | <username> | 1
|
||||||
|
// lazer | <username> | <userid>
|
||||||
|
// lazer (offline) | Guest | 1
|
||||||
|
|
||||||
|
return ID > 0 && UserID == 1 && UserString != "Guest";
|
||||||
|
}
|
||||||
|
set => isLegacyScore = value;
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<(HitResult result, int count, int? maxCount)> GetStatisticsForDisplay()
|
public IEnumerable<(HitResult result, int count, int? maxCount)> GetStatisticsForDisplay()
|
||||||
{
|
{
|
||||||
foreach (var key in OrderAttributeUtils.GetValuesInOrder<HitResult>())
|
foreach (var key in OrderAttributeUtils.GetValuesInOrder<HitResult>())
|
||||||
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -149,23 +150,38 @@ namespace osu.Game.Scoring
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int? beatmapMaxCombo = score.Beatmap.MaxCombo;
|
int beatmapMaxCombo;
|
||||||
|
|
||||||
if (beatmapMaxCombo == null)
|
if (score.IsLegacyScore)
|
||||||
{
|
{
|
||||||
if (score.Beatmap.ID == 0 || difficulties == null)
|
// This score is guaranteed to be an osu!stable score.
|
||||||
|
// The combo must be determined through either the beatmap's max combo value or the difficulty calculator, as lazer's scoring has changed and the score statistics cannot be used.
|
||||||
|
if (score.Beatmap.MaxCombo == null)
|
||||||
{
|
{
|
||||||
// We don't have enough information (max combo) to compute the score, so let's use the provided score.
|
if (score.Beatmap.ID == 0 || difficulties == null)
|
||||||
Value = score.TotalScore;
|
{
|
||||||
|
// We don't have enough information (max combo) to compute the score, so use the provided score.
|
||||||
|
Value = score.TotalScore;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can compute the max combo locally after the async beatmap difficulty computation.
|
||||||
|
difficultyBindable = difficulties().GetBindableDifficulty(score.Beatmap, score.Ruleset, score.Mods, (difficultyCancellationSource = new CancellationTokenSource()).Token);
|
||||||
|
difficultyBindable.BindValueChanged(d => updateScore(d.NewValue.MaxCombo), true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can compute the max combo locally after the async beatmap difficulty computation.
|
beatmapMaxCombo = score.Beatmap.MaxCombo.Value;
|
||||||
difficultyBindable = difficulties().GetBindableDifficulty(score.Beatmap, score.Ruleset, score.Mods, (difficultyCancellationSource = new CancellationTokenSource()).Token);
|
|
||||||
difficultyBindable.BindValueChanged(d => updateScore(d.NewValue.MaxCombo), true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
updateScore(beatmapMaxCombo.Value);
|
{
|
||||||
|
// This score is guaranteed to be an osu!lazer score.
|
||||||
|
// The combo must be determined through the score's statistics, as both the beatmap's max combo and the difficulty calculator will provide osu!stable combo values.
|
||||||
|
beatmapMaxCombo = Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r.AffectsCombo()).Select(r => score.Statistics.GetOrDefault(r)).Sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScore(beatmapMaxCombo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateScore(int beatmapMaxCombo)
|
private void updateScore(int beatmapMaxCombo)
|
||||||
|
Loading…
Reference in New Issue
Block a user