1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-24 05:29:57 +08:00

Merge pull request #33223 from frenzibyte/nominations-incorrect

Fix nominations count logic not updated to newer API structure
This commit is contained in:
Bartłomiej Dach
2025-05-22 08:01:45 +02:00
committed by GitHub
Unverified
4 changed files with 109 additions and 10 deletions
@@ -16,6 +16,7 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Beatmaps.Drawables.Cards;
using osu.Game.Beatmaps.Drawables.Cards.Buttons;
using osu.Game.Beatmaps.Drawables.Cards.Statistics;
using osu.Game.Graphics.Containers;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
@@ -63,7 +64,11 @@ namespace osu.Game.Tests.Visual.Beatmaps
withStatistics.NominationStatus = new BeatmapSetNominationStatus
{
Current = 1,
Required = 2
RequiredMeta =
{
MainRuleset = 2,
NonMainRuleset = 1,
}
};
var undownloadable = getUndownloadableBeatmapSet();
@@ -78,7 +83,11 @@ namespace osu.Game.Tests.Visual.Beatmaps
someDifficulties.NominationStatus = new BeatmapSetNominationStatus
{
Current = 2,
Required = 2
RequiredMeta =
{
MainRuleset = 2,
NonMainRuleset = 1,
}
};
var manyDifficulties = getManyDifficultiesBeatmapSet(100);
@@ -220,6 +229,9 @@ namespace osu.Game.Tests.Visual.Beatmaps
}
private Drawable createContent(OverlayColourScheme colourScheme, Func<APIBeatmapSet, Drawable> creationFunc)
=> createContent(colourScheme, testCases.Select(creationFunc).ToArray());
private Drawable createContent(OverlayColourScheme colourScheme, Drawable[] cards)
{
var colourProvider = new OverlayColourProvider(colourScheme);
@@ -247,7 +259,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
Direction = FillDirection.Full,
Padding = new MarginPadding(10),
Spacing = new Vector2(10),
ChildrenEnumerable = testCases.Select(creationFunc)
ChildrenEnumerable = cards
}
}
}
@@ -320,5 +332,54 @@ namespace osu.Game.Tests.Visual.Beatmaps
BeatmapCardNormal firstCard() => this.ChildrenOfType<BeatmapCardNormal>().First();
}
[Test]
public void TestNominations()
{
AddStep("create cards", () =>
{
var singleRuleset = CreateAPIBeatmapSet(Ruleset.Value);
singleRuleset.HypeStatus = new BeatmapSetHypeStatus();
singleRuleset.NominationStatus = new BeatmapSetNominationStatus
{
Current = 4,
RequiredMeta =
{
MainRuleset = 5,
NonMainRuleset = 1,
}
};
var multipleRulesets = getManyDifficultiesBeatmapSet(3);
multipleRulesets.HypeStatus = new BeatmapSetHypeStatus();
multipleRulesets.NominationStatus = new BeatmapSetNominationStatus
{
Current = 4,
RequiredMeta =
{
MainRuleset = 5,
NonMainRuleset = 1,
}
};
Child = createContent(OverlayColourScheme.Blue, new Drawable[]
{
new BeatmapCardNormal(singleRuleset),
new BeatmapCardNormal(multipleRulesets),
});
});
// first card: only has main ruleset, required nominations = main_ruleset = 5
AddAssert("first card has single ruleset", () => firstCard().BeatmapSet.Beatmaps.GroupBy(b => b.Ruleset).Count(), () => Is.EqualTo(1));
AddAssert("first card nominations = 4/5", () => firstCard().ChildrenOfType<NominationsStatistic>().Single().TooltipText.ToString(), () => Is.EqualTo("Nominations: 4/5"));
// second card: has non-main rulesets, required nominations = main_ruleset + non_main_ruleset * (count of non-main rulesets) = 5 + 1 * 2 = 7
AddAssert("second card has three rulesets", () => secondCard().BeatmapSet.Beatmaps.GroupBy(b => b.Ruleset).Count(), () => Is.EqualTo(3));
AddAssert("second card nominations = 4/7", () => secondCard().ChildrenOfType<NominationsStatistic>().Single().TooltipText.ToString(), () => Is.EqualTo("Nominations: 4/7"));
// order is reversed due to the cards being inside a reverse child-id fill flow.
BeatmapCardNormal firstCard() => this.ChildrenOfType<BeatmapCardNormal>().ElementAt(1);
BeatmapCardNormal secondCard() => this.ChildrenOfType<BeatmapCardNormal>().ElementAt(0);
}
}
}
@@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps
/// <summary>
/// The number of nominations required so that the map is eligible for qualification.
/// </summary>
[JsonProperty(@"required")]
public int Required { get; set; }
[JsonProperty(@"required_meta")]
public BeatmapSetNominationRequiredMeta RequiredMeta { get; set; } = new BeatmapSetNominationRequiredMeta();
}
}
@@ -0,0 +1,25 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Newtonsoft.Json;
namespace osu.Game.Beatmaps
{
/// <summary>
/// Contains information about the number of nominations required for a beatmap set.
/// </summary>
public class BeatmapSetNominationRequiredMeta
{
/// <summary>
/// The number of nominations required for difficulties of the main ruleset.
/// </summary>
[JsonProperty(@"main_ruleset")]
public int MainRuleset { get; set; }
/// <summary>
/// The number of nominations required for difficulties of each non-main ruleset.
/// </summary>
[JsonProperty(@"non_main_ruleset")]
public int NonMainRuleset { get; set; }
}
}
@@ -1,8 +1,10 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Resources.Localisation.Web;
namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
@@ -12,16 +14,27 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
/// </summary>
public partial class NominationsStatistic : BeatmapCardStatistic
{
private NominationsStatistic(BeatmapSetNominationStatus nominationStatus)
private NominationsStatistic(int current, int required)
{
Icon = FontAwesome.Solid.ThumbsUp;
Text = nominationStatus.Current.ToLocalisableString();
TooltipText = BeatmapsStrings.NominationsRequiredText(nominationStatus.Current.ToLocalisableString(), nominationStatus.Required.ToLocalisableString());
Text = current.ToLocalisableString();
TooltipText = BeatmapsStrings.NominationsRequiredText(current.ToLocalisableString(), required.ToLocalisableString());
}
public static NominationsStatistic? CreateFor(IBeatmapSetOnlineInfo beatmapSetOnlineInfo)
public static NominationsStatistic? CreateFor(APIBeatmapSet beatmapSet)
{
// web does not show nominations unless hypes are also present.
// see: https://github.com/ppy/osu-web/blob/8ed7d071fd1d3eaa7e43cf0e4ff55ca2fef9c07c/resources/assets/lib/beatmapset-panel.tsx#L443
=> beatmapSetOnlineInfo.HypeStatus == null || beatmapSetOnlineInfo.NominationStatus == null ? null : new NominationsStatistic(beatmapSetOnlineInfo.NominationStatus);
if (beatmapSet.HypeStatus == null || beatmapSet.NominationStatus == null)
return null;
int current = beatmapSet.NominationStatus.Current;
int requiredMainRuleset = beatmapSet.NominationStatus.RequiredMeta.MainRuleset;
int requiredNonMainRuleset = beatmapSet.NominationStatus.RequiredMeta.NonMainRuleset;
int rulesets = beatmapSet.Beatmaps.GroupBy(b => b.Ruleset).Count();
return new NominationsStatistic(current, requiredMainRuleset + requiredNonMainRuleset * (rulesets - 1));
}
}
}