1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-22 18:12:56 +08:00

Merge branch 'master' into importer-returns-live

This commit is contained in:
smoogipoo 2021-10-04 19:42:36 +09:00
commit 4871db2f86
80 changed files with 586 additions and 497 deletions

View File

@ -140,10 +140,10 @@ namespace osu.Desktop
switch (activity) switch (activity)
{ {
case UserActivity.InGame game: case UserActivity.InGame game:
return game.Beatmap.ToString(); return game.BeatmapInfo.ToString();
case UserActivity.Editing edit: case UserActivity.Editing edit:
return edit.Beatmap.ToString(); return edit.BeatmapInfo.ToString();
case UserActivity.InLobby lobby: case UserActivity.InLobby lobby:
return privacyMode.Value == DiscordRichPresenceMode.Limited ? string.Empty : lobby.Room.Name.Value; return privacyMode.Value == DiscordRichPresenceMode.Limited ? string.Empty : lobby.Room.Name.Value;

View File

@ -71,9 +71,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
originalTargetColumns = TargetColumns; originalTargetColumns = TargetColumns;
} }
public static int GetColumnCountForNonConvert(BeatmapInfo beatmap) public static int GetColumnCountForNonConvert(BeatmapInfo beatmapInfo)
{ {
var roundedCircleSize = Math.Round(beatmap.BaseDifficulty.CircleSize); var roundedCircleSize = Math.Round(beatmapInfo.BaseDifficulty.CircleSize);
return (int)Math.Max(1, roundedCircleSize); return (int)Math.Max(1, roundedCircleSize);
} }

View File

@ -13,9 +13,9 @@ namespace osu.Game.Rulesets.Mania
{ {
private FilterCriteria.OptionalRange<float> keys; private FilterCriteria.OptionalRange<float> keys;
public bool Matches(BeatmapInfo beatmap) public bool Matches(BeatmapInfo beatmapInfo)
{ {
return !keys.HasFilter || (beatmap.RulesetID == new ManiaRuleset().LegacyID && keys.IsInRange(ManiaBeatmapConverter.GetColumnCountForNonConvert(beatmap))); return !keys.HasFilter || (beatmapInfo.RulesetID == new ManiaRuleset().LegacyID && keys.IsInRange(ManiaBeatmapConverter.GetColumnCountForNonConvert(beatmapInfo)));
} }
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)

View File

@ -945,13 +945,13 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending); Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
} }
private static Task createScoreForBeatmap(OsuGameBase osu, BeatmapInfo beatmap) private static Task createScoreForBeatmap(OsuGameBase osu, BeatmapInfo beatmapInfo)
{ {
return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
{ {
OnlineScoreID = 2, OnlineScoreID = 2,
Beatmap = beatmap, Beatmap = beatmapInfo,
BeatmapInfoID = beatmap.ID BeatmapInfoID = beatmapInfo.ID
}, new ImportScoreTest.TestArchiveReader()); }, new ImportScoreTest.TestArchiveReader());
} }

View File

@ -239,7 +239,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
match = shouldMatch; match = shouldMatch;
} }
public bool Matches(BeatmapInfo beatmap) => match; public bool Matches(BeatmapInfo beatmapInfo) => match;
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) => false; public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) => false;
} }
} }

View File

@ -256,7 +256,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
{ {
public string CustomValue { get; set; } public string CustomValue { get; set; }
public bool Matches(BeatmapInfo beatmap) => true; public bool Matches(BeatmapInfo beatmapInfo) => true;
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)
{ {

View File

@ -286,7 +286,7 @@ namespace osu.Game.Tests.Visual.Background
private void setupUserSettings() private void setupUserSettings()
{ {
AddUntilStep("Song select is current", () => songSelect.IsCurrentScreen()); AddUntilStep("Song select is current", () => songSelect.IsCurrentScreen());
AddUntilStep("Song select has selection", () => songSelect.Carousel?.SelectedBeatmap != null); AddUntilStep("Song select has selection", () => songSelect.Carousel?.SelectedBeatmapInfo != null);
AddStep("Set default user settings", () => AddStep("Set default user settings", () =>
{ {
SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }).ToArray(); SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }).ToArray();

View File

@ -6,6 +6,7 @@ using NUnit.Framework;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Overlays.Login; using osu.Game.Overlays.Login;
namespace osu.Game.Tests.Visual.Menus namespace osu.Game.Tests.Visual.Menus
@ -30,12 +31,25 @@ namespace osu.Game.Tests.Visual.Menus
} }
[Test] [Test]
public void TestBasicLogin() public void TestLoginSuccess()
{ {
AddStep("logout", () => API.Logout()); AddStep("logout", () => API.Logout());
AddStep("enter password", () => loginPanel.ChildrenOfType<OsuPasswordTextBox>().First().Text = "password"); AddStep("enter password", () => loginPanel.ChildrenOfType<OsuPasswordTextBox>().First().Text = "password");
AddStep("submit", () => loginPanel.ChildrenOfType<OsuButton>().First(b => b.Text.ToString() == "Sign in").TriggerClick()); AddStep("submit", () => loginPanel.ChildrenOfType<OsuButton>().First(b => b.Text.ToString() == "Sign in").TriggerClick());
} }
[Test]
public void TestLoginFailure()
{
AddStep("logout", () =>
{
API.Logout();
((DummyAPIAccess)API).FailNextLogin();
});
AddStep("enter password", () => loginPanel.ChildrenOfType<OsuPasswordTextBox>().First().Text = "password");
AddStep("submit", () => loginPanel.ChildrenOfType<OsuButton>().First(b => b.Text.ToString() == "Sign in").TriggerClick());
}
} }
} }

View File

@ -233,7 +233,7 @@ namespace osu.Game.Tests.Visual.Online
}); });
}); });
AddAssert("shown beatmaps of current ruleset", () => overlay.Header.HeaderContent.Picker.Difficulties.All(b => b.Beatmap.Ruleset.Equals(overlay.Header.RulesetSelector.Current.Value))); AddAssert("shown beatmaps of current ruleset", () => overlay.Header.HeaderContent.Picker.Difficulties.All(b => b.BeatmapInfo.Ruleset.Equals(overlay.Header.RulesetSelector.Current.Value)));
AddAssert("left-most beatmap selected", () => overlay.Header.HeaderContent.Picker.Difficulties.First().State == BeatmapPicker.DifficultySelectorState.Selected); AddAssert("left-most beatmap selected", () => overlay.Header.HeaderContent.Picker.Difficulties.First().State == BeatmapPicker.DifficultySelectorState.Selected);
} }

View File

@ -58,10 +58,10 @@ namespace osu.Game.Tests.Visual.Online
var firstBeatmap = createBeatmap(); var firstBeatmap = createBeatmap();
var secondBeatmap = createBeatmap(); var secondBeatmap = createBeatmap();
AddStep("set first set", () => successRate.Beatmap = firstBeatmap); AddStep("set first set", () => successRate.BeatmapInfo = firstBeatmap);
AddAssert("ratings set", () => successRate.Graph.Metrics == firstBeatmap.Metrics); AddAssert("ratings set", () => successRate.Graph.Metrics == firstBeatmap.Metrics);
AddStep("set second set", () => successRate.Beatmap = secondBeatmap); AddStep("set second set", () => successRate.BeatmapInfo = secondBeatmap);
AddAssert("ratings set", () => successRate.Graph.Metrics == secondBeatmap.Metrics); AddAssert("ratings set", () => successRate.Graph.Metrics == secondBeatmap.Metrics);
static BeatmapInfo createBeatmap() => new BeatmapInfo static BeatmapInfo createBeatmap() => new BeatmapInfo
@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestOnlyFailMetrics() public void TestOnlyFailMetrics()
{ {
AddStep("set beatmap", () => successRate.Beatmap = new BeatmapInfo AddStep("set beatmap", () => successRate.BeatmapInfo = new BeatmapInfo
{ {
Metrics = new BeatmapMetrics Metrics = new BeatmapMetrics
{ {
@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestEmptyMetrics() public void TestEmptyMetrics()
{ {
AddStep("set beatmap", () => successRate.Beatmap = new BeatmapInfo AddStep("set beatmap", () => successRate.BeatmapInfo = new BeatmapInfo
{ {
Metrics = new BeatmapMetrics() Metrics = new BeatmapMetrics()
}); });

View File

@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestNoMod() public void TestNoMod()
{ {
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); AddStep("set beatmap", () => advancedStats.BeatmapInfo = exampleBeatmapInfo);
AddStep("no mods selected", () => SelectedMods.Value = Array.Empty<Mod>()); AddStep("no mods selected", () => SelectedMods.Value = Array.Empty<Mod>());
@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestManiaFirstBarText() public void TestManiaFirstBarText()
{ {
AddStep("set beatmap", () => advancedStats.Beatmap = new BeatmapInfo AddStep("set beatmap", () => advancedStats.BeatmapInfo = new BeatmapInfo
{ {
Ruleset = rulesets.GetRuleset(3), Ruleset = rulesets.GetRuleset(3),
BaseDifficulty = new BeatmapDifficulty BaseDifficulty = new BeatmapDifficulty
@ -84,11 +84,11 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestEasyMod() public void TestEasyMod()
{ {
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); AddStep("set beatmap", () => advancedStats.BeatmapInfo = exampleBeatmapInfo);
AddStep("select EZ mod", () => AddStep("select EZ mod", () =>
{ {
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); var ruleset = advancedStats.BeatmapInfo.Ruleset.CreateInstance();
SelectedMods.Value = new[] { ruleset.CreateMod<ModEasy>() }; SelectedMods.Value = new[] { ruleset.CreateMod<ModEasy>() };
}); });
@ -101,11 +101,11 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestHardRockMod() public void TestHardRockMod()
{ {
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); AddStep("set beatmap", () => advancedStats.BeatmapInfo = exampleBeatmapInfo);
AddStep("select HR mod", () => AddStep("select HR mod", () =>
{ {
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); var ruleset = advancedStats.BeatmapInfo.Ruleset.CreateInstance();
SelectedMods.Value = new[] { ruleset.CreateMod<ModHardRock>() }; SelectedMods.Value = new[] { ruleset.CreateMod<ModHardRock>() };
}); });
@ -118,13 +118,13 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestUnchangedDifficultyAdjustMod() public void TestUnchangedDifficultyAdjustMod()
{ {
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); AddStep("set beatmap", () => advancedStats.BeatmapInfo = exampleBeatmapInfo);
AddStep("select unchanged Difficulty Adjust mod", () => AddStep("select unchanged Difficulty Adjust mod", () =>
{ {
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); var ruleset = advancedStats.BeatmapInfo.Ruleset.CreateInstance();
var difficultyAdjustMod = ruleset.CreateMod<ModDifficultyAdjust>(); var difficultyAdjustMod = ruleset.CreateMod<ModDifficultyAdjust>();
difficultyAdjustMod.ReadFromDifficulty(advancedStats.Beatmap.BaseDifficulty); difficultyAdjustMod.ReadFromDifficulty(advancedStats.BeatmapInfo.BaseDifficulty);
SelectedMods.Value = new[] { difficultyAdjustMod }; SelectedMods.Value = new[] { difficultyAdjustMod };
}); });
@ -137,13 +137,13 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestChangedDifficultyAdjustMod() public void TestChangedDifficultyAdjustMod()
{ {
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); AddStep("set beatmap", () => advancedStats.BeatmapInfo = exampleBeatmapInfo);
AddStep("select changed Difficulty Adjust mod", () => AddStep("select changed Difficulty Adjust mod", () =>
{ {
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); var ruleset = advancedStats.BeatmapInfo.Ruleset.CreateInstance();
var difficultyAdjustMod = ruleset.CreateMod<OsuModDifficultyAdjust>(); var difficultyAdjustMod = ruleset.CreateMod<OsuModDifficultyAdjust>();
var originalDifficulty = advancedStats.Beatmap.BaseDifficulty; var originalDifficulty = advancedStats.BeatmapInfo.BaseDifficulty;
difficultyAdjustMod.ReadFromDifficulty(originalDifficulty); difficultyAdjustMod.ReadFromDifficulty(originalDifficulty);
difficultyAdjustMod.DrainRate.Value = originalDifficulty.DrainRate - 0.5f; difficultyAdjustMod.DrainRate.Value = originalDifficulty.DrainRate - 0.5f;

View File

@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private readonly Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>(); private readonly Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>();
private readonly HashSet<int> eagerSelectedIDs = new HashSet<int>(); private readonly HashSet<int> eagerSelectedIDs = new HashSet<int>();
private BeatmapInfo currentSelection => carousel.SelectedBeatmap; private BeatmapInfo currentSelection => carousel.SelectedBeatmapInfo;
private const int set_count = 5; private const int set_count = 5;
@ -75,11 +75,11 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
AddStep("store selection", () => selection = carousel.SelectedBeatmap); AddStep("store selection", () => selection = carousel.SelectedBeatmapInfo);
if (isIterating) if (isIterating)
AddUntilStep("selection changed", () => carousel.SelectedBeatmap != selection); AddUntilStep("selection changed", () => carousel.SelectedBeatmapInfo != selection);
else else
AddUntilStep("selection not changed", () => carousel.SelectedBeatmap == selection); AddUntilStep("selection not changed", () => carousel.SelectedBeatmapInfo == selection);
} }
} }
} }
@ -387,7 +387,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("Set non-empty mode filter", () => AddStep("Set non-empty mode filter", () =>
carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(1) }, false)); carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(1) }, false));
AddAssert("Something is selected", () => carousel.SelectedBeatmap != null); AddAssert("Something is selected", () => carousel.SelectedBeatmapInfo != null);
} }
/// <summary> /// <summary>
@ -562,7 +562,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("filter to ruleset 0", () => AddStep("filter to ruleset 0", () =>
carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false)); carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false));
AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testMixed.Beatmaps[1], false)); AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testMixed.Beatmaps[1], false));
AddAssert("unfiltered beatmap not selected", () => carousel.SelectedBeatmap.RulesetID == 0); AddAssert("unfiltered beatmap not selected", () => carousel.SelectedBeatmapInfo.RulesetID == 0);
AddStep("remove mixed set", () => AddStep("remove mixed set", () =>
{ {
@ -653,7 +653,7 @@ namespace osu.Game.Tests.Visual.SongSelect
carousel.Filter(new FilterCriteria { SearchText = Guid.NewGuid().ToString() }, false); carousel.Filter(new FilterCriteria { SearchText = Guid.NewGuid().ToString() }, false);
}); });
AddAssert("selection lost", () => carousel.SelectedBeatmap == null); AddAssert("selection lost", () => carousel.SelectedBeatmapInfo == null);
AddStep("Restore different ruleset filter", () => AddStep("Restore different ruleset filter", () =>
{ {
@ -661,7 +661,7 @@ namespace osu.Game.Tests.Visual.SongSelect
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID); eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
}); });
AddAssert("selection changed", () => carousel.SelectedBeatmap != manySets.First().Beatmaps.First()); AddAssert("selection changed", () => carousel.SelectedBeatmapInfo != manySets.First().Beatmaps.First());
} }
AddAssert("Selection was random", () => eagerSelectedIDs.Count > 2); AddAssert("Selection was random", () => eagerSelectedIDs.Count > 2);
@ -763,9 +763,9 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep($"selected is set{set}{(diff.HasValue ? $" diff{diff.Value}" : "")}", () => AddUntilStep($"selected is set{set}{(diff.HasValue ? $" diff{diff.Value}" : "")}", () =>
{ {
if (diff != null) if (diff != null)
return carousel.SelectedBeatmap == carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Skip(diff.Value - 1).First(); return carousel.SelectedBeatmapInfo == carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Skip(diff.Value - 1).First();
return carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Contains(carousel.SelectedBeatmap); return carousel.BeatmapSets.Skip(set - 1).First().Beatmaps.Contains(carousel.SelectedBeatmapInfo);
}); });
private void setSelected(int set, int diff) => private void setSelected(int set, int diff) =>
@ -800,7 +800,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
carousel.RandomAlgorithm.Value = RandomSelectAlgorithm.RandomPermutation; carousel.RandomAlgorithm.Value = RandomSelectAlgorithm.RandomPermutation;
if (!selectedSets.Any() && carousel.SelectedBeatmap != null) if (!selectedSets.Any() && carousel.SelectedBeatmapInfo != null)
selectedSets.Push(carousel.SelectedBeatmapSet); selectedSets.Push(carousel.SelectedBeatmapSet);
carousel.SelectNextRandom(); carousel.SelectNextRandom();

View File

@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestAllMetrics() public void TestAllMetrics()
{ {
AddStep("all metrics", () => details.Beatmap = new BeatmapInfo AddStep("all metrics", () => details.BeatmapInfo = new BeatmapInfo
{ {
BeatmapSet = new BeatmapSetInfo BeatmapSet = new BeatmapSetInfo
{ {
@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestAllMetricsExceptSource() public void TestAllMetricsExceptSource()
{ {
AddStep("all except source", () => details.Beatmap = new BeatmapInfo AddStep("all except source", () => details.BeatmapInfo = new BeatmapInfo
{ {
BeatmapSet = new BeatmapSetInfo BeatmapSet = new BeatmapSetInfo
{ {
@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestOnlyRatings() public void TestOnlyRatings()
{ {
AddStep("ratings", () => details.Beatmap = new BeatmapInfo AddStep("ratings", () => details.BeatmapInfo = new BeatmapInfo
{ {
BeatmapSet = new BeatmapSetInfo BeatmapSet = new BeatmapSetInfo
{ {
@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestOnlyFailsAndRetries() public void TestOnlyFailsAndRetries()
{ {
AddStep("fails retries", () => details.Beatmap = new BeatmapInfo AddStep("fails retries", () => details.BeatmapInfo = new BeatmapInfo
{ {
Version = "Only Retries and Fails", Version = "Only Retries and Fails",
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestNoMetrics() public void TestNoMetrics()
{ {
AddStep("no metrics", () => details.Beatmap = new BeatmapInfo AddStep("no metrics", () => details.BeatmapInfo = new BeatmapInfo
{ {
Version = "No Metrics", Version = "No Metrics",
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
@ -166,13 +166,13 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestNullBeatmap() public void TestNullBeatmap()
{ {
AddStep("null beatmap", () => details.Beatmap = null); AddStep("null beatmap", () => details.BeatmapInfo = null);
} }
[Test] [Test]
public void TestOnlineMetrics() public void TestOnlineMetrics()
{ {
AddStep("online ratings/retries/fails", () => details.Beatmap = new BeatmapInfo AddStep("online ratings/retries/fails", () => details.BeatmapInfo = new BeatmapInfo
{ {
OnlineBeatmapID = 162, OnlineBeatmapID = 162,
}); });

View File

@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.SongSelect
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First(); beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
leaderboard.Beatmap = beatmapInfo; leaderboard.BeatmapInfo = beatmapInfo;
}); });
clearScores(); clearScores();
@ -186,7 +186,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void checkCount(int expected) => private void checkCount(int expected) =>
AddUntilStep("Correct count displayed", () => leaderboard.ChildrenOfType<LeaderboardScore>().Count() == expected); AddUntilStep("Correct count displayed", () => leaderboard.ChildrenOfType<LeaderboardScore>().Count() == expected);
private static ScoreInfo[] generateSampleScores(BeatmapInfo beatmap) private static ScoreInfo[] generateSampleScores(BeatmapInfo beatmapInfo)
{ {
return new[] return new[]
{ {
@ -197,7 +197,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 6602580, Id = 6602580,
@ -216,7 +216,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 4608074, Id = 4608074,
@ -235,7 +235,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 1014222, Id = 1014222,
@ -254,7 +254,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 1541390, Id = 1541390,
@ -273,7 +273,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 2243452, Id = 2243452,
@ -292,7 +292,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 2705430, Id = 2705430,
@ -311,7 +311,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 7151382, Id = 7151382,
@ -330,7 +330,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 2051389, Id = 2051389,
@ -349,7 +349,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 6169483, Id = 6169483,
@ -368,7 +368,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244, MaxCombo = 244,
TotalScore = 1707827, TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, //Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
Beatmap = beatmap, Beatmap = beatmapInfo,
User = new User User = new User
{ {
Id = 6702666, Id = 6702666,
@ -385,7 +385,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void showBeatmapWithStatus(BeatmapSetOnlineStatus status) private void showBeatmapWithStatus(BeatmapSetOnlineStatus status)
{ {
leaderboard.Beatmap = new BeatmapInfo leaderboard.BeatmapInfo = new BeatmapInfo
{ {
OnlineBeatmapID = 1113057, OnlineBeatmapID = 1113057,
Status = status, Status = status,

View File

@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select next and enter", () => AddStep("select next and enter", () =>
{ {
InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>() InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>()
.First(b => ((CarouselBeatmap)b.Item).Beatmap != songSelect.Carousel.SelectedBeatmap)); .First(b => ((CarouselBeatmap)b.Item).BeatmapInfo != songSelect.Carousel.SelectedBeatmapInfo));
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select next and enter", () => AddStep("select next and enter", () =>
{ {
InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>() InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType<DrawableCarouselBeatmap>()
.First(b => ((CarouselBeatmap)b.Item).Beatmap != songSelect.Carousel.SelectedBeatmap)); .First(b => ((CarouselBeatmap)b.Item).BeatmapInfo != songSelect.Carousel.SelectedBeatmapInfo));
InputManager.PressButton(MouseButton.Left); InputManager.PressButton(MouseButton.Left);
@ -312,7 +312,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
createSongSelect(); createSongSelect();
addRulesetImportStep(2); addRulesetImportStep(2);
AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmap == null); AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmapInfo == null);
} }
[Test] [Test]
@ -322,13 +322,13 @@ namespace osu.Game.Tests.Visual.SongSelect
changeRuleset(2); changeRuleset(2);
addRulesetImportStep(2); addRulesetImportStep(2);
addRulesetImportStep(1); addRulesetImportStep(1);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 2); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.RulesetID == 2);
changeRuleset(1); changeRuleset(1);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 1); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.RulesetID == 1);
changeRuleset(0); changeRuleset(0);
AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmap == null); AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmapInfo == null);
} }
[Test] [Test]
@ -338,7 +338,7 @@ namespace osu.Game.Tests.Visual.SongSelect
changeRuleset(2); changeRuleset(2);
addRulesetImportStep(2); addRulesetImportStep(2);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 2); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.RulesetID == 2);
addRulesetImportStep(0); addRulesetImportStep(0);
addRulesetImportStep(0); addRulesetImportStep(0);
@ -355,7 +355,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Beatmap.Value = manager.GetWorkingBeatmap(target); Beatmap.Value = manager.GetWorkingBeatmap(target);
}); });
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.Equals(target)); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.Equals(target));
// this is an important check, to make sure updateComponentFromBeatmap() was actually run // this is an important check, to make sure updateComponentFromBeatmap() was actually run
AddUntilStep("selection shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap.BeatmapInfo.Equals(target)); AddUntilStep("selection shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap.BeatmapInfo.Equals(target));
@ -368,7 +368,7 @@ namespace osu.Game.Tests.Visual.SongSelect
changeRuleset(2); changeRuleset(2);
addRulesetImportStep(2); addRulesetImportStep(2);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 2); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.RulesetID == 2);
addRulesetImportStep(0); addRulesetImportStep(0);
addRulesetImportStep(0); addRulesetImportStep(0);
@ -385,7 +385,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == 0); Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == 0);
}); });
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.Equals(target)); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo.Equals(target));
AddUntilStep("has correct ruleset", () => Ruleset.Value.ID == 0); AddUntilStep("has correct ruleset", () => Ruleset.Value.ID == 0);
@ -444,7 +444,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
createSongSelect(); createSongSelect();
addManyTestMaps(); addManyTestMaps();
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo != null);
bool startRequested = false; bool startRequested = false;
@ -473,13 +473,13 @@ namespace osu.Game.Tests.Visual.SongSelect
// used for filter check below // used for filter check below
AddStep("allow convert display", () => config.SetValue(OsuSetting.ShowConvertedBeatmaps, true)); AddStep("allow convert display", () => config.SetValue(OsuSetting.ShowConvertedBeatmaps, true));
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo != null);
AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nonono"); AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nonono");
AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap); AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap);
AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmap == null); AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmapInfo == null);
BeatmapInfo target = null; BeatmapInfo target = null;
@ -494,7 +494,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Beatmap.Value = manager.GetWorkingBeatmap(target); Beatmap.Value = manager.GetWorkingBeatmap(target);
}); });
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo != null);
AddAssert("selected only shows expected ruleset (plus converts)", () => AddAssert("selected only shows expected ruleset (plus converts)", () =>
{ {
@ -502,16 +502,16 @@ namespace osu.Game.Tests.Visual.SongSelect
// special case for converts checked here. // special case for converts checked here.
return selectedPanel.ChildrenOfType<FilterableDifficultyIcon>().All(i => return selectedPanel.ChildrenOfType<FilterableDifficultyIcon>().All(i =>
i.IsFiltered || i.Item.Beatmap.Ruleset.ID == targetRuleset || i.Item.Beatmap.Ruleset.ID == 0); i.IsFiltered || i.Item.BeatmapInfo.Ruleset.ID == targetRuleset || i.Item.BeatmapInfo.Ruleset.ID == 0);
}); });
AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID); AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmapInfo?.OnlineBeatmapID == target.OnlineBeatmapID);
AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
AddStep("reset filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = string.Empty); AddStep("reset filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = string.Empty);
AddAssert("game still correct", () => Beatmap.Value?.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); AddAssert("game still correct", () => Beatmap.Value?.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
AddAssert("carousel still correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); AddAssert("carousel still correct", () => songSelect.Carousel.SelectedBeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
} }
[Test] [Test]
@ -522,13 +522,13 @@ namespace osu.Game.Tests.Visual.SongSelect
changeRuleset(0); changeRuleset(0);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo != null);
AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nonono"); AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nonono");
AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap); AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap);
AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmap == null); AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmapInfo == null);
BeatmapInfo target = null; BeatmapInfo target = null;
@ -540,15 +540,15 @@ namespace osu.Game.Tests.Visual.SongSelect
Beatmap.Value = manager.GetWorkingBeatmap(target); Beatmap.Value = manager.GetWorkingBeatmap(target);
}); });
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmapInfo != null);
AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID); AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmapInfo?.OnlineBeatmapID == target.OnlineBeatmapID);
AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nononoo"); AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nononoo");
AddUntilStep("game lost selection", () => Beatmap.Value is DummyWorkingBeatmap); AddUntilStep("game lost selection", () => Beatmap.Value is DummyWorkingBeatmap);
AddAssert("carousel lost selection", () => songSelect.Carousel.SelectedBeatmap == null); AddAssert("carousel lost selection", () => songSelect.Carousel.SelectedBeatmapInfo == null);
} }
[Test] [Test]
@ -581,9 +581,9 @@ namespace osu.Game.Tests.Visual.SongSelect
createSongSelect(); createSongSelect();
addRulesetImportStep(0); addRulesetImportStep(0);
AddStep("Move to last difficulty", () => songSelect.Carousel.SelectBeatmap(songSelect.Carousel.BeatmapSets.First().Beatmaps.Last())); AddStep("Move to last difficulty", () => songSelect.Carousel.SelectBeatmap(songSelect.Carousel.BeatmapSets.First().Beatmaps.Last()));
AddStep("Store current ID", () => previousID = songSelect.Carousel.SelectedBeatmap.ID); AddStep("Store current ID", () => previousID = songSelect.Carousel.SelectedBeatmapInfo.ID);
AddStep("Hide first beatmap", () => manager.Hide(songSelect.Carousel.SelectedBeatmapSet.Beatmaps.First())); AddStep("Hide first beatmap", () => manager.Hide(songSelect.Carousel.SelectedBeatmapSet.Beatmaps.First()));
AddAssert("Selected beatmap has not changed", () => songSelect.Carousel.SelectedBeatmap.ID == previousID); AddAssert("Selected beatmap has not changed", () => songSelect.Carousel.SelectedBeatmapInfo.ID == previousID);
} }
[Test] [Test]
@ -641,7 +641,7 @@ namespace osu.Game.Tests.Visual.SongSelect
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("Selected beatmap correct", () => songSelect.Carousel.SelectedBeatmap == filteredBeatmap); AddAssert("Selected beatmap correct", () => songSelect.Carousel.SelectedBeatmapInfo == filteredBeatmap);
} }
[Test] [Test]
@ -717,7 +717,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("Find an icon for different ruleset", () => AddStep("Find an icon for different ruleset", () =>
{ {
difficultyIcon = set.ChildrenOfType<FilterableDifficultyIcon>() difficultyIcon = set.ChildrenOfType<FilterableDifficultyIcon>()
.First(icon => icon.Item.Beatmap.Ruleset.ID == 3); .First(icon => icon.Item.BeatmapInfo.Ruleset.ID == 3);
}); });
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0); AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
@ -735,7 +735,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3); AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3);
AddAssert("Selected beatmap still same set", () => songSelect.Carousel.SelectedBeatmap.BeatmapSet.ID == previousSetID); AddAssert("Selected beatmap still same set", () => songSelect.Carousel.SelectedBeatmapInfo.BeatmapSet.ID == previousSetID);
AddAssert("Selected beatmap is mania", () => Beatmap.Value.BeatmapInfo.Ruleset.ID == 3); AddAssert("Selected beatmap is mania", () => Beatmap.Value.BeatmapInfo.Ruleset.ID == 3);
} }
@ -767,7 +767,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("Find group icon for different ruleset", () => AddStep("Find group icon for different ruleset", () =>
{ {
groupIcon = set.ChildrenOfType<FilterableGroupedDifficultyIcon>() groupIcon = set.ChildrenOfType<FilterableGroupedDifficultyIcon>()
.First(icon => icon.Items.First().Beatmap.Ruleset.ID == 3); .First(icon => icon.Items.First().BeatmapInfo.Ruleset.ID == 3);
}); });
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0); AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
@ -781,7 +781,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3); AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3);
AddAssert("Check first item in group selected", () => Beatmap.Value.BeatmapInfo.Equals(groupIcon.Items.First().Beatmap)); AddAssert("Check first item in group selected", () => Beatmap.Value.BeatmapInfo.Equals(groupIcon.Items.First().BeatmapInfo));
} }
[Test] [Test]
@ -856,7 +856,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private int getBeatmapIndex(BeatmapSetInfo set, BeatmapInfo info) => set.Beatmaps.FindIndex(b => b == info); private int getBeatmapIndex(BeatmapSetInfo set, BeatmapInfo info) => set.Beatmaps.FindIndex(b => b == info);
private int getCurrentBeatmapIndex() => getBeatmapIndex(songSelect.Carousel.SelectedBeatmapSet, songSelect.Carousel.SelectedBeatmap); private int getCurrentBeatmapIndex() => getBeatmapIndex(songSelect.Carousel.SelectedBeatmapSet, songSelect.Carousel.SelectedBeatmapInfo);
private int getDifficultyIconIndex(DrawableCarouselBeatmapSet set, FilterableDifficultyIcon icon) private int getDifficultyIconIndex(DrawableCarouselBeatmapSet set, FilterableDifficultyIcon icon)
{ {

View File

@ -37,7 +37,8 @@ namespace osu.Game.Tests.Visual.UserInterface
private ScoreManager scoreManager; private ScoreManager scoreManager;
private readonly List<ScoreInfo> importedScores = new List<ScoreInfo>(); private readonly List<ScoreInfo> importedScores = new List<ScoreInfo>();
private BeatmapInfo beatmap;
private BeatmapInfo beatmapInfo;
[Cached] [Cached]
private readonly DialogOverlay dialogOverlay; private readonly DialogOverlay dialogOverlay;
@ -55,7 +56,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Size = new Vector2(550f, 450f), Size = new Vector2(550f, 450f),
Scope = BeatmapLeaderboardScope.Local, Scope = BeatmapLeaderboardScope.Local,
Beatmap = new BeatmapInfo BeatmapInfo = new BeatmapInfo
{ {
ID = 1, ID = 1,
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
@ -84,15 +85,15 @@ namespace osu.Game.Tests.Visual.UserInterface
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default)); dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory, Scheduler)); dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory, Scheduler));
beatmap = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0]; beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0];
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
var score = new ScoreInfo var score = new ScoreInfo
{ {
OnlineScoreID = i, OnlineScoreID = i,
Beatmap = beatmap, Beatmap = beatmapInfo,
BeatmapInfoID = beatmap.ID, BeatmapInfoID = beatmapInfo.ID,
Accuracy = RNG.NextDouble(), Accuracy = RNG.NextDouble(),
TotalScore = RNG.Next(1, 1000000), TotalScore = RNG.Next(1, 1000000),
MaxCombo = RNG.Next(1, 1000), MaxCombo = RNG.Next(1, 1000),
@ -115,7 +116,7 @@ namespace osu.Game.Tests.Visual.UserInterface
leaderboard.Scores = null; leaderboard.Scores = null;
leaderboard.FinishTransforms(true); // After setting scores, we may be waiting for transforms to expire drawables leaderboard.FinishTransforms(true); // After setting scores, we may be waiting for transforms to expire drawables
leaderboard.Beatmap = beatmap; leaderboard.BeatmapInfo = beatmapInfo;
leaderboard.RefreshScores(); // Required in the case that the beatmap hasn't changed leaderboard.RefreshScores(); // Required in the case that the beatmap hasn't changed
}); });

View File

@ -30,7 +30,7 @@ namespace osu.Game.Tournament.Tests.Components
private void success(APIBeatmap apiBeatmap) private void success(APIBeatmap apiBeatmap)
{ {
var beatmap = apiBeatmap.ToBeatmap(rulesets); var beatmap = apiBeatmap.ToBeatmapInfo(rulesets);
Add(new TournamentBeatmapPanel(beatmap) Add(new TournamentBeatmapPanel(beatmap)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,

View File

@ -23,7 +23,7 @@ namespace osu.Game.Tournament.Tests.Components
private FillFlowContainer<TournamentBeatmapPanel> fillFlow; private FillFlowContainer<TournamentBeatmapPanel> fillFlow;
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
@ -44,12 +44,12 @@ namespace osu.Game.Tournament.Tests.Components
private void success(APIBeatmap apiBeatmap) private void success(APIBeatmap apiBeatmap)
{ {
beatmap = apiBeatmap.ToBeatmap(rulesets); beatmapInfo = apiBeatmap.ToBeatmapInfo(rulesets);
var mods = rulesets.GetRuleset(Ladder.Ruleset.Value.ID ?? 0).CreateInstance().AllMods; var mods = rulesets.GetRuleset(Ladder.Ruleset.Value.ID ?? 0).CreateInstance().AllMods;
foreach (var mod in mods) foreach (var mod in mods)
{ {
fillFlow.Add(new TournamentBeatmapPanel(beatmap, mod.Acronym) fillFlow.Add(new TournamentBeatmapPanel(beatmapInfo, mod.Acronym)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre Origin = Anchor.Centre

View File

@ -21,22 +21,22 @@ namespace osu.Game.Tournament.Components
{ {
public class SongBar : CompositeDrawable public class SongBar : CompositeDrawable
{ {
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public const float HEIGHT = 145 / 2f; public const float HEIGHT = 145 / 2f;
[Resolved] [Resolved]
private IBindable<RulesetInfo> ruleset { get; set; } private IBindable<RulesetInfo> ruleset { get; set; }
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (beatmap == value) if (beatmapInfo == value)
return; return;
beatmap = value; beatmapInfo = value;
update(); update();
} }
} }
@ -95,18 +95,18 @@ namespace osu.Game.Tournament.Components
private void update() private void update()
{ {
if (beatmap == null) if (beatmapInfo == null)
{ {
flow.Clear(); flow.Clear();
return; return;
} }
var bpm = beatmap.BeatmapSet.OnlineInfo.BPM; var bpm = beatmapInfo.BeatmapSet.OnlineInfo.BPM;
var length = beatmap.Length; var length = beatmapInfo.Length;
string hardRockExtra = ""; string hardRockExtra = "";
string srExtra = ""; string srExtra = "";
var ar = beatmap.BaseDifficulty.ApproachRate; var ar = beatmapInfo.BaseDifficulty.ApproachRate;
if ((mods & LegacyMods.HardRock) > 0) if ((mods & LegacyMods.HardRock) > 0)
{ {
@ -132,9 +132,9 @@ namespace osu.Game.Tournament.Components
default: default:
stats = new (string heading, string content)[] stats = new (string heading, string content)[]
{ {
("CS", $"{beatmap.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"), ("CS", $"{beatmapInfo.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"),
("AR", $"{ar:0.#}{hardRockExtra}"), ("AR", $"{ar:0.#}{hardRockExtra}"),
("OD", $"{beatmap.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"), ("OD", $"{beatmapInfo.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"),
}; };
break; break;
@ -142,15 +142,15 @@ namespace osu.Game.Tournament.Components
case 3: case 3:
stats = new (string heading, string content)[] stats = new (string heading, string content)[]
{ {
("OD", $"{beatmap.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"), ("OD", $"{beatmapInfo.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"),
("HP", $"{beatmap.BaseDifficulty.DrainRate:0.#}{hardRockExtra}") ("HP", $"{beatmapInfo.BaseDifficulty.DrainRate:0.#}{hardRockExtra}")
}; };
break; break;
case 2: case 2:
stats = new (string heading, string content)[] stats = new (string heading, string content)[]
{ {
("CS", $"{beatmap.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"), ("CS", $"{beatmapInfo.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"),
("AR", $"{ar:0.#}"), ("AR", $"{ar:0.#}"),
}; };
break; break;
@ -186,7 +186,7 @@ namespace osu.Game.Tournament.Components
Children = new Drawable[] Children = new Drawable[]
{ {
new DiffPiece(stats), new DiffPiece(stats),
new DiffPiece(("Star Rating", $"{beatmap.StarDifficulty:0.#}{srExtra}")) new DiffPiece(("Star Rating", $"{beatmapInfo.StarDifficulty:0.#}{srExtra}"))
} }
}, },
new FillFlowContainer new FillFlowContainer
@ -229,7 +229,7 @@ namespace osu.Game.Tournament.Components
} }
} }
}, },
new TournamentBeatmapPanel(beatmap) new TournamentBeatmapPanel(beatmapInfo)
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Width = 0.5f, Width = 0.5f,

View File

@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Components
{ {
public class TournamentBeatmapPanel : CompositeDrawable public class TournamentBeatmapPanel : CompositeDrawable
{ {
public readonly BeatmapInfo Beatmap; public readonly BeatmapInfo BeatmapInfo;
private readonly string mod; private readonly string mod;
private const float horizontal_padding = 10; private const float horizontal_padding = 10;
@ -32,11 +32,11 @@ namespace osu.Game.Tournament.Components
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>(); private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
private Box flash; private Box flash;
public TournamentBeatmapPanel(BeatmapInfo beatmap, string mod = null) public TournamentBeatmapPanel(BeatmapInfo beatmapInfo, string mod = null)
{ {
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); if (beatmapInfo == null) throw new ArgumentNullException(nameof(beatmapInfo));
Beatmap = beatmap; BeatmapInfo = beatmapInfo;
this.mod = mod; this.mod = mod;
Width = 400; Width = 400;
Height = HEIGHT; Height = HEIGHT;
@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Components
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(0.5f), Colour = OsuColour.Gray(0.5f),
BeatmapSet = Beatmap.BeatmapSet, BeatmapSet = BeatmapInfo.BeatmapSet,
}, },
new FillFlowContainer new FillFlowContainer
{ {
@ -75,8 +75,8 @@ namespace osu.Game.Tournament.Components
new TournamentSpriteText new TournamentSpriteText
{ {
Text = new RomanisableString( Text = new RomanisableString(
$"{Beatmap.Metadata.ArtistUnicode ?? Beatmap.Metadata.Artist} - {Beatmap.Metadata.TitleUnicode ?? Beatmap.Metadata.Title}", $"{BeatmapInfo.Metadata.ArtistUnicode ?? BeatmapInfo.Metadata.Artist} - {BeatmapInfo.Metadata.TitleUnicode ?? BeatmapInfo.Metadata.Title}",
$"{Beatmap.Metadata.Artist} - {Beatmap.Metadata.Title}"), $"{BeatmapInfo.Metadata.Artist} - {BeatmapInfo.Metadata.Title}"),
Font = OsuFont.Torus.With(weight: FontWeight.Bold), Font = OsuFont.Torus.With(weight: FontWeight.Bold),
}, },
new FillFlowContainer new FillFlowContainer
@ -93,7 +93,7 @@ namespace osu.Game.Tournament.Components
}, },
new TournamentSpriteText new TournamentSpriteText
{ {
Text = Beatmap.Metadata.AuthorString, Text = BeatmapInfo.Metadata.AuthorString,
Padding = new MarginPadding { Right = 20 }, Padding = new MarginPadding { Right = 20 },
Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14) Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14)
}, },
@ -105,7 +105,7 @@ namespace osu.Game.Tournament.Components
}, },
new TournamentSpriteText new TournamentSpriteText
{ {
Text = Beatmap.Version, Text = BeatmapInfo.Version,
Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14) Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14)
}, },
} }
@ -149,7 +149,7 @@ namespace osu.Game.Tournament.Components
private void updateState() private void updateState()
{ {
var found = currentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == Beatmap.OnlineBeatmapID); var found = currentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == BeatmapInfo.OnlineBeatmapID);
bool doFlash = found != choice; bool doFlash = found != choice;
choice = found; choice = found;

View File

@ -94,7 +94,7 @@ namespace osu.Game.Tournament.IPC
else else
{ {
beatmapLookupRequest = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = beatmapId }); beatmapLookupRequest = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = beatmapId });
beatmapLookupRequest.Success += b => Beatmap.Value = b.ToBeatmap(Rulesets); beatmapLookupRequest.Success += b => Beatmap.Value = b.ToBeatmapInfo(Rulesets);
API.Queue(beatmapLookupRequest); API.Queue(beatmapLookupRequest);
} }
} }

View File

@ -40,7 +40,7 @@ namespace osu.Game.Tournament.Screens
private void beatmapChanged(ValueChangedEvent<BeatmapInfo> beatmap) private void beatmapChanged(ValueChangedEvent<BeatmapInfo> beatmap)
{ {
SongBar.FadeInFromZero(300, Easing.OutQuint); SongBar.FadeInFromZero(300, Easing.OutQuint);
SongBar.Beatmap = beatmap.NewValue; SongBar.BeatmapInfo = beatmap.NewValue;
} }
} }
} }

View File

@ -238,7 +238,7 @@ namespace osu.Game.Tournament.Screens.Editors
req.Success += res => req.Success += res =>
{ {
Model.BeatmapInfo = res.ToBeatmap(rulesets); Model.BeatmapInfo = res.ToBeatmapInfo(rulesets);
updatePanel(); updatePanel();
}; };

View File

@ -246,7 +246,7 @@ namespace osu.Game.Tournament.Screens.Editors
req.Success += res => req.Success += res =>
{ {
Model.BeatmapInfo = res.ToBeatmap(rulesets); Model.BeatmapInfo = res.ToBeatmapInfo(rulesets);
updatePanel(); updatePanel();
}; };

View File

@ -147,11 +147,11 @@ namespace osu.Game.Tournament.Screens.MapPool
if (map != null) if (map != null)
{ {
if (e.Button == MouseButton.Left && map.Beatmap.OnlineBeatmapID != null) if (e.Button == MouseButton.Left && map.BeatmapInfo.OnlineBeatmapID != null)
addForBeatmap(map.Beatmap.OnlineBeatmapID.Value); addForBeatmap(map.BeatmapInfo.OnlineBeatmapID.Value);
else else
{ {
var existing = CurrentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == map.Beatmap.OnlineBeatmapID); var existing = CurrentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == map.BeatmapInfo.OnlineBeatmapID);
if (existing != null) if (existing != null)
{ {

View File

@ -182,7 +182,7 @@ namespace osu.Game.Tournament
{ {
var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID }); var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID });
API.Perform(req); API.Perform(req);
b.BeatmapInfo = req.Result?.ToBeatmap(RulesetStore); b.BeatmapInfo = req.Result?.ToBeatmapInfo(RulesetStore);
addedInfo = true; addedInfo = true;
} }
@ -203,7 +203,7 @@ namespace osu.Game.Tournament
{ {
var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID }); var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID });
req.Perform(API); req.Perform(API);
b.BeatmapInfo = req.Result?.ToBeatmap(RulesetStore); b.BeatmapInfo = req.Result?.ToBeatmapInfo(RulesetStore);
addedInfo = true; addedInfo = true;
} }

View File

@ -242,7 +242,7 @@ namespace osu.Game.Beatmaps
{ {
// GetDifficultyAsync will fall back to existing data from BeatmapInfo if not locally available // GetDifficultyAsync will fall back to existing data from BeatmapInfo if not locally available
// (contrary to GetAsync) // (contrary to GetAsync)
GetDifficultyAsync(bindable.Beatmap, rulesetInfo, mods, cancellationToken) GetDifficultyAsync(bindable.BeatmapInfo, rulesetInfo, mods, cancellationToken)
.ContinueWith(t => .ContinueWith(t =>
{ {
// We're on a threadpool thread, but we should exit back to the update thread so consumers can safely handle value-changed events. // We're on a threadpool thread, but we should exit back to the update thread so consumers can safely handle value-changed events.
@ -262,7 +262,7 @@ namespace osu.Game.Beatmaps
private StarDifficulty computeDifficulty(in DifficultyCacheLookup key) private StarDifficulty computeDifficulty(in DifficultyCacheLookup key)
{ {
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset. // In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
var beatmapInfo = key.Beatmap; var beatmapInfo = key.BeatmapInfo;
var rulesetInfo = key.Ruleset; var rulesetInfo = key.Ruleset;
try try
@ -270,7 +270,7 @@ namespace osu.Game.Beatmaps
var ruleset = rulesetInfo.CreateInstance(); var ruleset = rulesetInfo.CreateInstance();
Debug.Assert(ruleset != null); Debug.Assert(ruleset != null);
var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(key.Beatmap)); var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(key.BeatmapInfo));
var attributes = calculator.Calculate(key.OrderedMods); var attributes = calculator.Calculate(key.OrderedMods);
return new StarDifficulty(attributes); return new StarDifficulty(attributes);
@ -300,21 +300,21 @@ namespace osu.Game.Beatmaps
public readonly struct DifficultyCacheLookup : IEquatable<DifficultyCacheLookup> public readonly struct DifficultyCacheLookup : IEquatable<DifficultyCacheLookup>
{ {
public readonly BeatmapInfo Beatmap; public readonly BeatmapInfo BeatmapInfo;
public readonly RulesetInfo Ruleset; public readonly RulesetInfo Ruleset;
public readonly Mod[] OrderedMods; public readonly Mod[] OrderedMods;
public DifficultyCacheLookup([NotNull] BeatmapInfo beatmap, [CanBeNull] RulesetInfo ruleset, IEnumerable<Mod> mods) public DifficultyCacheLookup([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo ruleset, IEnumerable<Mod> mods)
{ {
Beatmap = beatmap; BeatmapInfo = beatmapInfo;
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset. // In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
Ruleset = ruleset ?? Beatmap.Ruleset; Ruleset = ruleset ?? BeatmapInfo.Ruleset;
OrderedMods = mods?.OrderBy(m => m.Acronym).Select(mod => mod.DeepClone()).ToArray() ?? Array.Empty<Mod>(); OrderedMods = mods?.OrderBy(m => m.Acronym).Select(mod => mod.DeepClone()).ToArray() ?? Array.Empty<Mod>();
} }
public bool Equals(DifficultyCacheLookup other) public bool Equals(DifficultyCacheLookup other)
=> Beatmap.ID == other.Beatmap.ID => BeatmapInfo.ID == other.BeatmapInfo.ID
&& Ruleset.ID == other.Ruleset.ID && Ruleset.ID == other.Ruleset.ID
&& OrderedMods.SequenceEqual(other.OrderedMods); && OrderedMods.SequenceEqual(other.OrderedMods);
@ -322,7 +322,7 @@ namespace osu.Game.Beatmaps
{ {
var hashCode = new HashCode(); var hashCode = new HashCode();
hashCode.Add(Beatmap.ID); hashCode.Add(BeatmapInfo.ID);
hashCode.Add(Ruleset.ID); hashCode.Add(Ruleset.ID);
foreach (var mod in OrderedMods) foreach (var mod in OrderedMods)
@ -334,12 +334,12 @@ namespace osu.Game.Beatmaps
private class BindableStarDifficulty : Bindable<StarDifficulty?> private class BindableStarDifficulty : Bindable<StarDifficulty?>
{ {
public readonly BeatmapInfo Beatmap; public readonly BeatmapInfo BeatmapInfo;
public readonly CancellationToken CancellationToken; public readonly CancellationToken CancellationToken;
public BindableStarDifficulty(BeatmapInfo beatmap, CancellationToken cancellationToken) public BindableStarDifficulty(BeatmapInfo beatmapInfo, CancellationToken cancellationToken)
{ {
Beatmap = beatmap; BeatmapInfo = beatmapInfo;
CancellationToken = cancellationToken; CancellationToken = cancellationToken;
} }
} }

View File

@ -35,7 +35,7 @@ namespace osu.Game.Beatmaps
private readonly BeatmapModelDownloader beatmapModelDownloader; private readonly BeatmapModelDownloader beatmapModelDownloader;
private readonly WorkingBeatmapCache workingBeatmapCache; private readonly WorkingBeatmapCache workingBeatmapCache;
private readonly BeatmapOnlineLookupQueue onlineBetamapLookupQueue; private readonly BeatmapOnlineLookupQueue onlineBeatmapLookupQueue;
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore<byte[]> resources, GameHost host = null, public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore<byte[]> resources, GameHost host = null,
WorkingBeatmap defaultBeatmap = null, bool performOnlineLookups = false) WorkingBeatmap defaultBeatmap = null, bool performOnlineLookups = false)
@ -48,8 +48,8 @@ namespace osu.Game.Beatmaps
if (performOnlineLookups) if (performOnlineLookups)
{ {
onlineBetamapLookupQueue = new BeatmapOnlineLookupQueue(api, storage); onlineBeatmapLookupQueue = new BeatmapOnlineLookupQueue(api, storage);
beatmapModelManager.OnlineLookupQueue = onlineBetamapLookupQueue; beatmapModelManager.OnlineLookupQueue = onlineBeatmapLookupQueue;
} }
} }
@ -183,14 +183,14 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// Delete a beatmap difficulty. /// Delete a beatmap difficulty.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap difficulty to hide.</param> /// <param name="beatmapInfo">The beatmap difficulty to hide.</param>
public void Hide(BeatmapInfo beatmap) => beatmapModelManager.Hide(beatmap); public void Hide(BeatmapInfo beatmapInfo) => beatmapModelManager.Hide(beatmapInfo);
/// <summary> /// <summary>
/// Restore a beatmap difficulty. /// Restore a beatmap difficulty.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap difficulty to restore.</param> /// <param name="beatmapInfo">The beatmap difficulty to restore.</param>
public void Restore(BeatmapInfo beatmap) => beatmapModelManager.Restore(beatmap); public void Restore(BeatmapInfo beatmapInfo) => beatmapModelManager.Restore(beatmapInfo);
#endregion #endregion
@ -330,7 +330,7 @@ namespace osu.Game.Beatmaps
public void Dispose() public void Dispose()
{ {
onlineBetamapLookupQueue?.Dispose(); onlineBeatmapLookupQueue?.Dispose();
} }
#endregion #endregion

View File

@ -173,24 +173,24 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// Delete a beatmap difficulty. /// Delete a beatmap difficulty.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap difficulty to hide.</param> /// <param name="beatmapInfo">The beatmap difficulty to hide.</param>
public void Hide(BeatmapInfo beatmap) => beatmaps.Hide(beatmap); public void Hide(BeatmapInfo beatmapInfo) => beatmaps.Hide(beatmapInfo);
/// <summary> /// <summary>
/// Restore a beatmap difficulty. /// Restore a beatmap difficulty.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap difficulty to restore.</param> /// <param name="beatmapInfo">The beatmap difficulty to restore.</param>
public void Restore(BeatmapInfo beatmap) => beatmaps.Restore(beatmap); public void Restore(BeatmapInfo beatmapInfo) => beatmaps.Restore(beatmapInfo);
/// <summary> /// <summary>
/// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>. /// Saves an <see cref="IBeatmap"/> file against a given <see cref="BeatmapInfo"/>.
/// </summary> /// </summary>
/// <param name="info">The <see cref="BeatmapInfo"/> to save the content against. The file referenced by <see cref="BeatmapInfo.Path"/> will be replaced.</param> /// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to save the content against. The file referenced by <see cref="BeatmapInfo.Path"/> will be replaced.</param>
/// <param name="beatmapContent">The <see cref="IBeatmap"/> content to write.</param> /// <param name="beatmapContent">The <see cref="IBeatmap"/> content to write.</param>
/// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param> /// <param name="beatmapSkin">The beatmap <see cref="ISkin"/> content to write, null if to be omitted.</param>
public virtual void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null) public virtual void Save(BeatmapInfo beatmapInfo, IBeatmap beatmapContent, ISkin beatmapSkin = null)
{ {
var setInfo = info.BeatmapSet; var setInfo = beatmapInfo.BeatmapSet;
using (var stream = new MemoryStream()) using (var stream = new MemoryStream())
{ {
@ -201,7 +201,7 @@ namespace osu.Game.Beatmaps
using (ContextFactory.GetForWrite()) using (ContextFactory.GetForWrite())
{ {
var beatmapInfo = setInfo.Beatmaps.Single(b => b.ID == info.ID); beatmapInfo = setInfo.Beatmaps.Single(b => b.ID == beatmapInfo.ID);
var metadata = beatmapInfo.Metadata ?? setInfo.Metadata; var metadata = beatmapInfo.Metadata ?? setInfo.Metadata;
// grab the original file (or create a new one if not found). // grab the original file (or create a new one if not found).
@ -219,7 +219,7 @@ namespace osu.Game.Beatmaps
} }
} }
WorkingBeatmapCache?.Invalidate(info); WorkingBeatmapCache?.Invalidate(beatmapInfo);
} }
/// <summary> /// <summary>

View File

@ -58,18 +58,18 @@ namespace osu.Game.Beatmaps
} }
// todo: expose this when we need to do individual difficulty lookups. // todo: expose this when we need to do individual difficulty lookups.
protected Task UpdateAsync(BeatmapSetInfo beatmapSet, BeatmapInfo beatmap, CancellationToken cancellationToken) protected Task UpdateAsync(BeatmapSetInfo beatmapSet, BeatmapInfo beatmapInfo, CancellationToken cancellationToken)
=> Task.Factory.StartNew(() => lookup(beatmapSet, beatmap), cancellationToken, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); => Task.Factory.StartNew(() => lookup(beatmapSet, beatmapInfo), cancellationToken, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler);
private void lookup(BeatmapSetInfo set, BeatmapInfo beatmap) private void lookup(BeatmapSetInfo set, BeatmapInfo beatmapInfo)
{ {
if (checkLocalCache(set, beatmap)) if (checkLocalCache(set, beatmapInfo))
return; return;
if (api?.State.Value != APIState.Online) if (api?.State.Value != APIState.Online)
return; return;
var req = new GetBeatmapRequest(beatmap); var req = new GetBeatmapRequest(beatmapInfo);
req.Failure += fail; req.Failure += fail;
@ -82,18 +82,18 @@ namespace osu.Game.Beatmaps
if (res != null) if (res != null)
{ {
beatmap.Status = res.Status; beatmapInfo.Status = res.Status;
beatmap.BeatmapSet.Status = res.BeatmapSet.Status; beatmapInfo.BeatmapSet.Status = res.BeatmapSet.Status;
beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmapInfo.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID;
beatmap.OnlineBeatmapID = res.OnlineBeatmapID; beatmapInfo.OnlineBeatmapID = res.OnlineBeatmapID;
if (beatmap.Metadata != null) if (beatmapInfo.Metadata != null)
beatmap.Metadata.AuthorID = res.AuthorID; beatmapInfo.Metadata.AuthorID = res.AuthorID;
if (beatmap.BeatmapSet.Metadata != null) if (beatmapInfo.BeatmapSet.Metadata != null)
beatmap.BeatmapSet.Metadata.AuthorID = res.AuthorID; beatmapInfo.BeatmapSet.Metadata.AuthorID = res.AuthorID;
logForModel(set, $"Online retrieval mapped {beatmap} to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}."); logForModel(set, $"Online retrieval mapped {beatmapInfo} to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.");
} }
} }
catch (Exception e) catch (Exception e)
@ -103,8 +103,8 @@ namespace osu.Game.Beatmaps
void fail(Exception e) void fail(Exception e)
{ {
beatmap.OnlineBeatmapID = null; beatmapInfo.OnlineBeatmapID = null;
logForModel(set, $"Online retrieval failed for {beatmap} ({e.Message})"); logForModel(set, $"Online retrieval failed for {beatmapInfo} ({e.Message})");
} }
} }
@ -149,7 +149,7 @@ namespace osu.Game.Beatmaps
cacheDownloadRequest.PerformAsync(); cacheDownloadRequest.PerformAsync();
} }
private bool checkLocalCache(BeatmapSetInfo set, BeatmapInfo beatmap) private bool checkLocalCache(BeatmapSetInfo set, BeatmapInfo beatmapInfo)
{ {
// download is in progress (or was, and failed). // download is in progress (or was, and failed).
if (cacheDownloadRequest != null) if (cacheDownloadRequest != null)
@ -159,9 +159,9 @@ namespace osu.Game.Beatmaps
if (!storage.Exists(cache_database_name)) if (!storage.Exists(cache_database_name))
return false; return false;
if (string.IsNullOrEmpty(beatmap.MD5Hash) if (string.IsNullOrEmpty(beatmapInfo.MD5Hash)
&& string.IsNullOrEmpty(beatmap.Path) && string.IsNullOrEmpty(beatmapInfo.Path)
&& beatmap.OnlineBeatmapID == null) && beatmapInfo.OnlineBeatmapID == null)
return false; return false;
try try
@ -174,9 +174,9 @@ namespace osu.Game.Beatmaps
{ {
cmd.CommandText = "SELECT beatmapset_id, beatmap_id, approved, user_id FROM osu_beatmaps WHERE checksum = @MD5Hash OR beatmap_id = @OnlineBeatmapID OR filename = @Path"; cmd.CommandText = "SELECT beatmapset_id, beatmap_id, approved, user_id FROM osu_beatmaps WHERE checksum = @MD5Hash OR beatmap_id = @OnlineBeatmapID OR filename = @Path";
cmd.Parameters.Add(new SqliteParameter("@MD5Hash", beatmap.MD5Hash)); cmd.Parameters.Add(new SqliteParameter("@MD5Hash", beatmapInfo.MD5Hash));
cmd.Parameters.Add(new SqliteParameter("@OnlineBeatmapID", beatmap.OnlineBeatmapID ?? (object)DBNull.Value)); cmd.Parameters.Add(new SqliteParameter("@OnlineBeatmapID", beatmapInfo.OnlineBeatmapID ?? (object)DBNull.Value));
cmd.Parameters.Add(new SqliteParameter("@Path", beatmap.Path)); cmd.Parameters.Add(new SqliteParameter("@Path", beatmapInfo.Path));
using (var reader = cmd.ExecuteReader()) using (var reader = cmd.ExecuteReader())
{ {
@ -184,18 +184,18 @@ namespace osu.Game.Beatmaps
{ {
var status = (BeatmapSetOnlineStatus)reader.GetByte(2); var status = (BeatmapSetOnlineStatus)reader.GetByte(2);
beatmap.Status = status; beatmapInfo.Status = status;
beatmap.BeatmapSet.Status = status; beatmapInfo.BeatmapSet.Status = status;
beatmap.BeatmapSet.OnlineBeatmapSetID = reader.GetInt32(0); beatmapInfo.BeatmapSet.OnlineBeatmapSetID = reader.GetInt32(0);
beatmap.OnlineBeatmapID = reader.GetInt32(1); beatmapInfo.OnlineBeatmapID = reader.GetInt32(1);
if (beatmap.Metadata != null) if (beatmapInfo.Metadata != null)
beatmap.Metadata.AuthorID = reader.GetInt32(3); beatmapInfo.Metadata.AuthorID = reader.GetInt32(3);
if (beatmap.BeatmapSet.Metadata != null) if (beatmapInfo.BeatmapSet.Metadata != null)
beatmap.BeatmapSet.Metadata.AuthorID = reader.GetInt32(3); beatmapInfo.BeatmapSet.Metadata.AuthorID = reader.GetInt32(3);
logForModel(set, $"Cached local retrieval for {beatmap}."); logForModel(set, $"Cached local retrieval for {beatmapInfo}.");
return true; return true;
} }
} }
@ -204,7 +204,7 @@ namespace osu.Game.Beatmaps
} }
catch (Exception ex) catch (Exception ex)
{ {
logForModel(set, $"Cached local retrieval for {beatmap} failed with {ex}."); logForModel(set, $"Cached local retrieval for {beatmapInfo} failed with {ex}.");
} }
return false; return false;

View File

@ -25,40 +25,40 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// Hide a <see cref="BeatmapInfo"/> in the database. /// Hide a <see cref="BeatmapInfo"/> in the database.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap to hide.</param> /// <param name="beatmapInfo">The beatmap to hide.</param>
/// <returns>Whether the beatmap's <see cref="BeatmapInfo.Hidden"/> was changed.</returns> /// <returns>Whether the beatmap's <see cref="BeatmapInfo.Hidden"/> was changed.</returns>
public bool Hide(BeatmapInfo beatmap) public bool Hide(BeatmapInfo beatmapInfo)
{ {
using (ContextFactory.GetForWrite()) using (ContextFactory.GetForWrite())
{ {
Refresh(ref beatmap, Beatmaps); Refresh(ref beatmapInfo, Beatmaps);
if (beatmap.Hidden) return false; if (beatmapInfo.Hidden) return false;
beatmap.Hidden = true; beatmapInfo.Hidden = true;
} }
BeatmapHidden?.Invoke(beatmap); BeatmapHidden?.Invoke(beatmapInfo);
return true; return true;
} }
/// <summary> /// <summary>
/// Restore a previously hidden <see cref="BeatmapInfo"/>. /// Restore a previously hidden <see cref="BeatmapInfo"/>.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap to restore.</param> /// <param name="beatmapInfo">The beatmap to restore.</param>
/// <returns>Whether the beatmap's <see cref="BeatmapInfo.Hidden"/> was changed.</returns> /// <returns>Whether the beatmap's <see cref="BeatmapInfo.Hidden"/> was changed.</returns>
public bool Restore(BeatmapInfo beatmap) public bool Restore(BeatmapInfo beatmapInfo)
{ {
using (ContextFactory.GetForWrite()) using (ContextFactory.GetForWrite())
{ {
Refresh(ref beatmap, Beatmaps); Refresh(ref beatmapInfo, Beatmaps);
if (!beatmap.Hidden) return false; if (!beatmapInfo.Hidden) return false;
beatmap.Hidden = false; beatmapInfo.Hidden = false;
} }
BeatmapRestored?.Invoke(beatmap); BeatmapRestored?.Invoke(beatmapInfo);
return true; return true;
} }

View File

@ -62,14 +62,14 @@ namespace osu.Game.Beatmaps
if (!recommendedDifficultyMapping.TryGetValue(r, out var recommendation)) if (!recommendedDifficultyMapping.TryGetValue(r, out var recommendation))
continue; continue;
BeatmapInfo beatmap = beatmaps.Where(b => b.Ruleset.Equals(r)).OrderBy(b => BeatmapInfo beatmapInfo = beatmaps.Where(b => b.Ruleset.Equals(r)).OrderBy(b =>
{ {
var difference = b.StarDifficulty - recommendation; var difference = b.StarDifficulty - recommendation;
return difference >= 0 ? difference * 2 : difference * -1; // prefer easier over harder return difference >= 0 ? difference * 2 : difference * -1; // prefer easier over harder
}).FirstOrDefault(); }).FirstOrDefault();
if (beatmap != null) if (beatmapInfo != null)
return beatmap; return beatmapInfo;
} }
return null; return null;

View File

@ -37,7 +37,7 @@ namespace osu.Game.Beatmaps.Drawables
} }
[NotNull] [NotNull]
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
[CanBeNull] [CanBeNull]
private readonly RulesetInfo ruleset; private readonly RulesetInfo ruleset;
@ -56,26 +56,26 @@ namespace osu.Game.Beatmaps.Drawables
/// <summary> /// <summary>
/// Creates a new <see cref="DifficultyIcon"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination. /// Creates a new <see cref="DifficultyIcon"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap to show the difficulty of.</param> /// <param name="beatmapInfo">The beatmap to show the difficulty of.</param>
/// <param name="ruleset">The ruleset to show the difficulty with.</param> /// <param name="ruleset">The ruleset to show the difficulty with.</param>
/// <param name="mods">The mods to show the difficulty with.</param> /// <param name="mods">The mods to show the difficulty with.</param>
/// <param name="shouldShowTooltip">Whether to display a tooltip when hovered.</param> /// <param name="shouldShowTooltip">Whether to display a tooltip when hovered.</param>
public DifficultyIcon([NotNull] BeatmapInfo beatmap, [CanBeNull] RulesetInfo ruleset, [CanBeNull] IReadOnlyList<Mod> mods, bool shouldShowTooltip = true) public DifficultyIcon([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo ruleset, [CanBeNull] IReadOnlyList<Mod> mods, bool shouldShowTooltip = true)
: this(beatmap, shouldShowTooltip) : this(beatmapInfo, shouldShowTooltip)
{ {
this.ruleset = ruleset ?? beatmap.Ruleset; this.ruleset = ruleset ?? beatmapInfo.Ruleset;
this.mods = mods ?? Array.Empty<Mod>(); this.mods = mods ?? Array.Empty<Mod>();
} }
/// <summary> /// <summary>
/// Creates a new <see cref="DifficultyIcon"/> that follows the currently-selected ruleset and mods. /// Creates a new <see cref="DifficultyIcon"/> that follows the currently-selected ruleset and mods.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap to show the difficulty of.</param> /// <param name="beatmapInfo">The beatmap to show the difficulty of.</param>
/// <param name="shouldShowTooltip">Whether to display a tooltip when hovered.</param> /// <param name="shouldShowTooltip">Whether to display a tooltip when hovered.</param>
/// <param name="performBackgroundDifficultyLookup">Whether to perform difficulty lookup (including calculation if necessary).</param> /// <param name="performBackgroundDifficultyLookup">Whether to perform difficulty lookup (including calculation if necessary).</param>
public DifficultyIcon([NotNull] BeatmapInfo beatmap, bool shouldShowTooltip = true, bool performBackgroundDifficultyLookup = true) public DifficultyIcon([NotNull] BeatmapInfo beatmapInfo, bool shouldShowTooltip = true, bool performBackgroundDifficultyLookup = true)
{ {
this.beatmap = beatmap ?? throw new ArgumentNullException(nameof(beatmap)); this.beatmapInfo = beatmapInfo ?? throw new ArgumentNullException(nameof(beatmapInfo));
this.shouldShowTooltip = shouldShowTooltip; this.shouldShowTooltip = shouldShowTooltip;
this.performBackgroundDifficultyLookup = performBackgroundDifficultyLookup; this.performBackgroundDifficultyLookup = performBackgroundDifficultyLookup;
@ -105,7 +105,7 @@ namespace osu.Game.Beatmaps.Drawables
Child = background = new Box Child = background = new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = colours.ForStarDifficulty(beatmap.StarDifficulty) // Default value that will be re-populated once difficulty calculation completes Colour = colours.ForStarDifficulty(beatmapInfo.StarDifficulty) // Default value that will be re-populated once difficulty calculation completes
}, },
}, },
new ConstrainedIconContainer new ConstrainedIconContainer
@ -114,27 +114,27 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
Icon = (ruleset ?? beatmap.Ruleset)?.CreateInstance()?.CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } Icon = (ruleset ?? beatmapInfo.Ruleset)?.CreateInstance()?.CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }
}, },
}; };
if (performBackgroundDifficultyLookup) if (performBackgroundDifficultyLookup)
iconContainer.Add(new DelayedLoadUnloadWrapper(() => new DifficultyRetriever(beatmap, ruleset, mods) { StarDifficulty = { BindTarget = difficultyBindable } }, 0)); iconContainer.Add(new DelayedLoadUnloadWrapper(() => new DifficultyRetriever(beatmapInfo, ruleset, mods) { StarDifficulty = { BindTarget = difficultyBindable } }, 0));
else else
difficultyBindable.Value = new StarDifficulty(beatmap.StarDifficulty, 0); difficultyBindable.Value = new StarDifficulty(beatmapInfo.StarDifficulty, 0);
difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars)); difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars));
} }
ITooltip<DifficultyIconTooltipContent> IHasCustomTooltip<DifficultyIconTooltipContent>.GetCustomTooltip() => new DifficultyIconTooltip(); ITooltip<DifficultyIconTooltipContent> IHasCustomTooltip<DifficultyIconTooltipContent>.GetCustomTooltip() => new DifficultyIconTooltip();
DifficultyIconTooltipContent IHasCustomTooltip<DifficultyIconTooltipContent>.TooltipContent => shouldShowTooltip ? new DifficultyIconTooltipContent(beatmap, difficultyBindable) : null; DifficultyIconTooltipContent IHasCustomTooltip<DifficultyIconTooltipContent>.TooltipContent => shouldShowTooltip ? new DifficultyIconTooltipContent(beatmapInfo, difficultyBindable) : null;
private class DifficultyRetriever : Component private class DifficultyRetriever : Component
{ {
public readonly Bindable<StarDifficulty> StarDifficulty = new Bindable<StarDifficulty>(); public readonly Bindable<StarDifficulty> StarDifficulty = new Bindable<StarDifficulty>();
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
private readonly RulesetInfo ruleset; private readonly RulesetInfo ruleset;
private readonly IReadOnlyList<Mod> mods; private readonly IReadOnlyList<Mod> mods;
@ -143,9 +143,9 @@ namespace osu.Game.Beatmaps.Drawables
[Resolved] [Resolved]
private BeatmapDifficultyCache difficultyCache { get; set; } private BeatmapDifficultyCache difficultyCache { get; set; }
public DifficultyRetriever(BeatmapInfo beatmap, RulesetInfo ruleset, IReadOnlyList<Mod> mods) public DifficultyRetriever(BeatmapInfo beatmapInfo, RulesetInfo ruleset, IReadOnlyList<Mod> mods)
{ {
this.beatmap = beatmap; this.beatmapInfo = beatmapInfo;
this.ruleset = ruleset; this.ruleset = ruleset;
this.mods = mods; this.mods = mods;
} }
@ -157,8 +157,8 @@ namespace osu.Game.Beatmaps.Drawables
{ {
difficultyCancellation = new CancellationTokenSource(); difficultyCancellation = new CancellationTokenSource();
localStarDifficulty = ruleset != null localStarDifficulty = ruleset != null
? difficultyCache.GetBindableDifficulty(beatmap, ruleset, mods, difficultyCancellation.Token) ? difficultyCache.GetBindableDifficulty(beatmapInfo, ruleset, mods, difficultyCancellation.Token)
: difficultyCache.GetBindableDifficulty(beatmap, difficultyCancellation.Token); : difficultyCache.GetBindableDifficulty(beatmapInfo, difficultyCancellation.Token);
localStarDifficulty.BindValueChanged(d => localStarDifficulty.BindValueChanged(d =>
{ {
if (d.NewValue is StarDifficulty diff) if (d.NewValue is StarDifficulty diff)

View File

@ -89,7 +89,7 @@ namespace osu.Game.Beatmaps.Drawables
public void SetContent(DifficultyIconTooltipContent content) public void SetContent(DifficultyIconTooltipContent content)
{ {
difficultyName.Text = content.Beatmap.Version; difficultyName.Text = content.BeatmapInfo.Version;
starDifficulty.UnbindAll(); starDifficulty.UnbindAll();
starDifficulty.BindTo(content.Difficulty); starDifficulty.BindTo(content.Difficulty);
@ -109,12 +109,12 @@ namespace osu.Game.Beatmaps.Drawables
internal class DifficultyIconTooltipContent internal class DifficultyIconTooltipContent
{ {
public readonly BeatmapInfo Beatmap; public readonly BeatmapInfo BeatmapInfo;
public readonly IBindable<StarDifficulty> Difficulty; public readonly IBindable<StarDifficulty> Difficulty;
public DifficultyIconTooltipContent(BeatmapInfo beatmap, IBindable<StarDifficulty> difficulty) public DifficultyIconTooltipContent(BeatmapInfo beatmapInfo, IBindable<StarDifficulty> difficulty)
{ {
Beatmap = beatmap; BeatmapInfo = beatmapInfo;
Difficulty = difficulty; Difficulty = difficulty;
} }
} }

View File

@ -6,7 +6,7 @@ using osu.Framework.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osuTK.Graphics; using osuTK.Graphics;
namespace osu.Game.Overlays.AccountCreation namespace osu.Game.Graphics
{ {
public class ErrorTextFlowContainer : OsuTextFlowContainer public class ErrorTextFlowContainer : OsuTextFlowContainer
{ {

View File

@ -35,9 +35,8 @@ namespace osu.Game.Online.API
public string WebsiteRootUrl { get; } public string WebsiteRootUrl { get; }
/// <summary> public Exception LastLoginError { get; private set; }
/// The username/email provided by the user when initiating a login.
/// </summary>
public string ProvidedUsername { get; private set; } public string ProvidedUsername { get; private set; }
private string password; private string password;
@ -136,14 +135,23 @@ namespace osu.Game.Online.API
// save the username at this point, if the user requested for it to be. // save the username at this point, if the user requested for it to be.
config.SetValue(OsuSetting.Username, config.Get<bool>(OsuSetting.SaveUsername) ? ProvidedUsername : string.Empty); config.SetValue(OsuSetting.Username, config.Get<bool>(OsuSetting.SaveUsername) ? ProvidedUsername : string.Empty);
if (!authentication.HasValidAccessToken && !authentication.AuthenticateWithLogin(ProvidedUsername, password)) if (!authentication.HasValidAccessToken)
{ {
//todo: this fails even on network-related issues. we should probably handle those differently. LastLoginError = null;
//NotificationOverlay.ShowMessage("Login failed!");
log.Add(@"Login failed!"); try
password = null; {
authentication.Clear(); authentication.AuthenticateWithLogin(ProvidedUsername, password);
continue; }
catch (Exception e)
{
//todo: this fails even on network-related issues. we should probably handle those differently.
LastLoginError = e;
log.Add(@"Login failed!");
password = null;
authentication.Clear();
continue;
}
} }
var userReq = new GetUserRequest(); var userReq = new GetUserRequest();

View File

@ -32,6 +32,8 @@ namespace osu.Game.Online.API
public string WebsiteRootUrl => "http://localhost"; public string WebsiteRootUrl => "http://localhost";
public Exception LastLoginError { get; private set; }
/// <summary> /// <summary>
/// Provide handling logic for an arbitrary API request. /// Provide handling logic for an arbitrary API request.
/// Should return true is a request was handled. If null or false return, the request will be failed with a <see cref="NotSupportedException"/>. /// Should return true is a request was handled. If null or false return, the request will be failed with a <see cref="NotSupportedException"/>.
@ -40,6 +42,8 @@ namespace osu.Game.Online.API
private readonly Bindable<APIState> state = new Bindable<APIState>(APIState.Online); private readonly Bindable<APIState> state = new Bindable<APIState>(APIState.Online);
private bool shouldFailNextLogin;
/// <summary> /// <summary>
/// The current connectivity state of the API. /// The current connectivity state of the API.
/// </summary> /// </summary>
@ -74,6 +78,18 @@ namespace osu.Game.Online.API
public void Login(string username, string password) public void Login(string username, string password)
{ {
state.Value = APIState.Connecting;
if (shouldFailNextLogin)
{
LastLoginError = new APIException("Not powerful enough to login.", new ArgumentException(nameof(shouldFailNextLogin)));
state.Value = APIState.Offline;
shouldFailNextLogin = false;
return;
}
LastLoginError = null;
LocalUser.Value = new User LocalUser.Value = new User
{ {
Username = username, Username = username,
@ -102,5 +118,7 @@ namespace osu.Game.Online.API
IBindable<User> IAPIProvider.LocalUser => LocalUser; IBindable<User> IAPIProvider.LocalUser => LocalUser;
IBindableList<User> IAPIProvider.Friends => Friends; IBindableList<User> IAPIProvider.Friends => Friends;
IBindable<UserActivity> IAPIProvider.Activity => Activity; IBindable<UserActivity> IAPIProvider.Activity => Activity;
public void FailNextLogin() => shouldFailNextLogin = true;
} }
} }

View File

@ -3,6 +3,7 @@
#nullable enable #nullable enable
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Users; using osu.Game.Users;
@ -55,6 +56,11 @@ namespace osu.Game.Online.API
/// </summary> /// </summary>
string WebsiteRootUrl { get; } string WebsiteRootUrl { get; }
/// <summary>
/// The last login error that occurred, if any.
/// </summary>
Exception? LastLoginError { get; }
/// <summary> /// <summary>
/// The current connection state of the API. /// The current connection state of the API.
/// This is not thread-safe and should be scheduled locally if consumed from a drawable component. /// This is not thread-safe and should be scheduled locally if consumed from a drawable component.

View File

@ -1,8 +1,10 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Net.Http; using System.Net.Http;
using Newtonsoft.Json;
using osu.Framework.Bindables; using osu.Framework.Bindables;
namespace osu.Game.Online.API namespace osu.Game.Online.API
@ -32,10 +34,10 @@ namespace osu.Game.Online.API
this.endpoint = endpoint; this.endpoint = endpoint;
} }
internal bool AuthenticateWithLogin(string username, string password) internal void AuthenticateWithLogin(string username, string password)
{ {
if (string.IsNullOrEmpty(username)) return false; if (string.IsNullOrEmpty(username)) throw new ArgumentException("Missing username.");
if (string.IsNullOrEmpty(password)) return false; if (string.IsNullOrEmpty(password)) throw new ArgumentException("Missing password.");
using (var req = new AccessTokenRequestPassword(username, password) using (var req = new AccessTokenRequestPassword(username, password)
{ {
@ -49,13 +51,27 @@ namespace osu.Game.Online.API
{ {
req.Perform(); req.Perform();
} }
catch catch (Exception ex)
{ {
return false; Token.Value = null;
var throwableException = ex;
try
{
// attempt to decode a displayable error string.
var error = JsonConvert.DeserializeObject<OAuthError>(req.GetResponseString() ?? string.Empty);
if (error != null)
throwableException = new APIException(error.UserDisplayableError, ex);
}
catch
{
}
throw throwableException;
} }
Token.Value = req.ResponseObject; Token.Value = req.ResponseObject;
return true;
} }
} }
@ -182,5 +198,19 @@ namespace osu.Game.Online.API
base.PrePerform(); base.PrePerform();
} }
} }
private class OAuthError
{
public string UserDisplayableError => !string.IsNullOrEmpty(Hint) ? Hint : ErrorIdentifier;
[JsonProperty("error")]
public string ErrorIdentifier { get; set; }
[JsonProperty("hint")]
public string Hint { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
}
} }
} }

View File

@ -8,13 +8,13 @@ namespace osu.Game.Online.API.Requests
{ {
public class GetBeatmapRequest : APIRequest<APIBeatmap> public class GetBeatmapRequest : APIRequest<APIBeatmap>
{ {
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
public GetBeatmapRequest(BeatmapInfo beatmap) public GetBeatmapRequest(BeatmapInfo beatmapInfo)
{ {
this.beatmap = beatmap; this.beatmapInfo = beatmapInfo;
} }
protected override string Target => $@"beatmaps/lookup?id={beatmap.OnlineBeatmapID}&checksum={beatmap.MD5Hash}&filename={System.Uri.EscapeUriString(beatmap.Path ?? string.Empty)}"; protected override string Target => $@"beatmaps/lookup?id={beatmapInfo.OnlineBeatmapID}&checksum={beatmapInfo.MD5Hash}&filename={System.Uri.EscapeUriString(beatmapInfo.Path ?? string.Empty)}";
} }
} }

View File

@ -15,20 +15,20 @@ namespace osu.Game.Online.API.Requests
{ {
public class GetScoresRequest : APIRequest<APILegacyScores> public class GetScoresRequest : APIRequest<APILegacyScores>
{ {
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
private readonly BeatmapLeaderboardScope scope; private readonly BeatmapLeaderboardScope scope;
private readonly RulesetInfo ruleset; private readonly RulesetInfo ruleset;
private readonly IEnumerable<IMod> mods; private readonly IEnumerable<IMod> mods;
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable<IMod> mods = null) public GetScoresRequest(BeatmapInfo beatmapInfo, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable<IMod> mods = null)
{ {
if (!beatmap.OnlineBeatmapID.HasValue) if (!beatmapInfo.OnlineBeatmapID.HasValue)
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}."); throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
if (scope == BeatmapLeaderboardScope.Local) if (scope == BeatmapLeaderboardScope.Local)
throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard"); throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
this.beatmap = beatmap; this.beatmapInfo = beatmapInfo;
this.scope = scope; this.scope = scope;
this.ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset)); this.ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset));
this.mods = mods ?? Array.Empty<IMod>(); this.mods = mods ?? Array.Empty<IMod>();
@ -42,7 +42,7 @@ namespace osu.Game.Online.API.Requests
foreach (APILegacyScoreInfo score in r.Scores) foreach (APILegacyScoreInfo score in r.Scores)
{ {
score.Beatmap = beatmap; score.BeatmapInfo = beatmapInfo;
score.OnlineRulesetID = ruleset.ID.Value; score.OnlineRulesetID = ruleset.ID.Value;
} }
@ -50,12 +50,12 @@ namespace osu.Game.Online.API.Requests
if (userScore != null) if (userScore != null)
{ {
userScore.Score.Beatmap = beatmap; userScore.Score.BeatmapInfo = beatmapInfo;
userScore.Score.OnlineRulesetID = ruleset.ID.Value; userScore.Score.OnlineRulesetID = ruleset.ID.Value;
} }
} }
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores{createQueryParameters()}"; protected override string Target => $@"beatmaps/{beatmapInfo.OnlineBeatmapID}/scores{createQueryParameters()}";
private string createQueryParameters() private string createQueryParameters()
{ {

View File

@ -64,7 +64,7 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"max_combo")] [JsonProperty(@"max_combo")]
private int? maxCombo { get; set; } private int? maxCombo { get; set; }
public virtual BeatmapInfo ToBeatmap(RulesetStore rulesets) public virtual BeatmapInfo ToBeatmapInfo(RulesetStore rulesets)
{ {
var set = BeatmapSet?.ToBeatmapSet(rulesets); var set = BeatmapSet?.ToBeatmapSet(rulesets);

View File

@ -116,7 +116,7 @@ namespace osu.Game.Online.API.Requests.Responses
beatmapSet.Beatmaps = beatmaps?.Select(b => beatmapSet.Beatmaps = beatmaps?.Select(b =>
{ {
var beatmap = b.ToBeatmap(rulesets); var beatmap = b.ToBeatmapInfo(rulesets);
beatmap.BeatmapSet = beatmapSet; beatmap.BeatmapSet = beatmapSet;
beatmap.Metadata = beatmapSet.Metadata; beatmap.Metadata = beatmapSet.Metadata;
return beatmap; return beatmap;

View File

@ -37,7 +37,7 @@ namespace osu.Game.Online.API.Requests.Responses
OnlineScoreID = OnlineScoreID, OnlineScoreID = OnlineScoreID,
Date = Date, Date = Date,
PP = PP, PP = PP,
Beatmap = Beatmap, Beatmap = BeatmapInfo,
RulesetID = OnlineRulesetID, RulesetID = OnlineRulesetID,
Hash = Replay ? "online" : string.Empty, // todo: temporary? Hash = Replay ? "online" : string.Empty, // todo: temporary?
Rank = Rank, Rank = Rank,
@ -100,7 +100,7 @@ namespace osu.Game.Online.API.Requests.Responses
public DateTimeOffset Date { get; set; } public DateTimeOffset Date { get; set; }
[JsonProperty(@"beatmap")] [JsonProperty(@"beatmap")]
public BeatmapInfo Beatmap { get; set; } public BeatmapInfo BeatmapInfo { get; set; }
[JsonProperty("accuracy")] [JsonProperty("accuracy")]
public double Accuracy { get; set; } public double Accuracy { get; set; }
@ -114,10 +114,10 @@ namespace osu.Game.Online.API.Requests.Responses
set set
{ {
// extract the set ID to its correct place. // extract the set ID to its correct place.
Beatmap.BeatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = value.ID }; BeatmapInfo.BeatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = value.ID };
value.ID = 0; value.ID = 0;
Beatmap.Metadata = value; BeatmapInfo.Metadata = value;
} }
} }

View File

@ -16,7 +16,7 @@ namespace osu.Game.Online.API.Requests.Responses
public int PlayCount { get; set; } public int PlayCount { get; set; }
[JsonProperty] [JsonProperty]
private BeatmapInfo beatmap { get; set; } private BeatmapInfo beatmapInfo { get; set; }
[JsonProperty] [JsonProperty]
private APIBeatmapSet beatmapSet { get; set; } private APIBeatmapSet beatmapSet { get; set; }
@ -24,9 +24,9 @@ namespace osu.Game.Online.API.Requests.Responses
public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets)
{ {
BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets);
beatmap.BeatmapSet = setInfo; beatmapInfo.BeatmapSet = setInfo;
beatmap.Metadata = setInfo.Metadata; beatmapInfo.Metadata = setInfo.Metadata;
return beatmap; return beatmapInfo;
} }
} }
} }

View File

@ -37,27 +37,27 @@ namespace osu.Game.Online.Chat
base.LoadComplete(); base.LoadComplete();
string verb; string verb;
BeatmapInfo beatmap; BeatmapInfo beatmapInfo;
switch (api.Activity.Value) switch (api.Activity.Value)
{ {
case UserActivity.InGame game: case UserActivity.InGame game:
verb = "playing"; verb = "playing";
beatmap = game.Beatmap; beatmapInfo = game.BeatmapInfo;
break; break;
case UserActivity.Editing edit: case UserActivity.Editing edit:
verb = "editing"; verb = "editing";
beatmap = edit.Beatmap; beatmapInfo = edit.BeatmapInfo;
break; break;
default: default:
verb = "listening to"; verb = "listening to";
beatmap = currentBeatmap.Value.BeatmapInfo; beatmapInfo = currentBeatmap.Value.BeatmapInfo;
break; break;
} }
var beatmapString = beatmap.OnlineBeatmapID.HasValue ? $"[{api.WebsiteRootUrl}/b/{beatmap.OnlineBeatmapID} {beatmap}]" : beatmap.ToString(); var beatmapString = beatmapInfo.OnlineBeatmapID.HasValue ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineBeatmapID} {beatmapInfo}]" : beatmapInfo.ToString();
channelManager.PostMessage($"is {verb} {beatmapString}", true, target); channelManager.PostMessage($"is {verb} {beatmapString}", true, target);
Expire(); Expire();

View File

@ -13,9 +13,9 @@ namespace osu.Game.Online.Rooms
[JsonProperty("checksum")] [JsonProperty("checksum")]
public string Checksum { get; set; } public string Checksum { get; set; }
public override BeatmapInfo ToBeatmap(RulesetStore rulesets) public override BeatmapInfo ToBeatmapInfo(RulesetStore rulesets)
{ {
var b = base.ToBeatmap(rulesets); var b = base.ToBeatmapInfo(rulesets);
b.MD5Hash = Checksum; b.MD5Hash = Checksum;
return b; return b;
} }

View File

@ -70,7 +70,7 @@ namespace osu.Game.Online.Rooms
public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets)
{ {
Beatmap.Value ??= apiBeatmap.ToBeatmap(rulesets); Beatmap.Value ??= apiBeatmap.ToBeatmapInfo(rulesets);
Ruleset.Value ??= rulesets.GetRuleset(RulesetID); Ruleset.Value ??= rulesets.GetRuleset(RulesetID);
Ruleset rulesetInstance = Ruleset.Value.CreateInstance(); Ruleset rulesetInstance = Ruleset.Value.CreateInstance();

View File

@ -38,16 +38,16 @@ namespace osu.Game.Overlays.BeatmapSet
} }
} }
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (value == beatmap) return; if (value == beatmapInfo) return;
beatmap = value; beatmapInfo = value;
updateDisplay(); updateDisplay();
} }
@ -57,7 +57,7 @@ namespace osu.Game.Overlays.BeatmapSet
{ {
bpm.Value = BeatmapSet?.OnlineInfo?.BPM.ToLocalisableString(@"0.##") ?? (LocalisableString)"-"; bpm.Value = BeatmapSet?.OnlineInfo?.BPM.ToLocalisableString(@"0.##") ?? (LocalisableString)"-";
if (beatmap == null) if (beatmapInfo == null)
{ {
length.Value = string.Empty; length.Value = string.Empty;
circleCount.Value = string.Empty; circleCount.Value = string.Empty;
@ -65,11 +65,11 @@ namespace osu.Game.Overlays.BeatmapSet
} }
else else
{ {
length.TooltipText = BeatmapsetsStrings.ShowStatsTotalLength(TimeSpan.FromMilliseconds(beatmap.Length).ToFormattedDuration()); length.TooltipText = BeatmapsetsStrings.ShowStatsTotalLength(TimeSpan.FromMilliseconds(beatmapInfo.Length).ToFormattedDuration());
length.Value = TimeSpan.FromMilliseconds(beatmap.Length).ToFormattedDuration(); length.Value = TimeSpan.FromMilliseconds(beatmapInfo.Length).ToFormattedDuration();
circleCount.Value = beatmap.OnlineInfo.CircleCount.ToLocalisableString(@"N0"); circleCount.Value = beatmapInfo.OnlineInfo.CircleCount.ToLocalisableString(@"N0");
sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToLocalisableString(@"N0"); sliderCount.Value = beatmapInfo.OnlineInfo.SliderCount.ToLocalisableString(@"N0");
} }
} }

View File

@ -178,21 +178,21 @@ namespace osu.Game.Overlays.BeatmapSet
} }
starRatingContainer.FadeOut(100); starRatingContainer.FadeOut(100);
Beatmap.Value = Difficulties.FirstOrDefault()?.Beatmap; Beatmap.Value = Difficulties.FirstOrDefault()?.BeatmapInfo;
plays.Value = BeatmapSet?.OnlineInfo.PlayCount ?? 0; plays.Value = BeatmapSet?.OnlineInfo.PlayCount ?? 0;
favourites.Value = BeatmapSet?.OnlineInfo.FavouriteCount ?? 0; favourites.Value = BeatmapSet?.OnlineInfo.FavouriteCount ?? 0;
updateDifficultyButtons(); updateDifficultyButtons();
} }
private void showBeatmap(BeatmapInfo beatmap) private void showBeatmap(BeatmapInfo beatmapInfo)
{ {
version.Text = beatmap?.Version; version.Text = beatmapInfo?.Version;
} }
private void updateDifficultyButtons() private void updateDifficultyButtons()
{ {
Difficulties.Children.ToList().ForEach(diff => diff.State = diff.Beatmap == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected); Difficulties.Children.ToList().ForEach(diff => diff.State = diff.BeatmapInfo == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected);
} }
public class DifficultiesContainer : FillFlowContainer<DifficultySelectorButton> public class DifficultiesContainer : FillFlowContainer<DifficultySelectorButton>
@ -216,7 +216,7 @@ namespace osu.Game.Overlays.BeatmapSet
private readonly Box backgroundBox; private readonly Box backgroundBox;
private readonly DifficultyIcon icon; private readonly DifficultyIcon icon;
public readonly BeatmapInfo Beatmap; public readonly BeatmapInfo BeatmapInfo;
public Action<BeatmapInfo> OnHovered; public Action<BeatmapInfo> OnHovered;
public Action<BeatmapInfo> OnClicked; public Action<BeatmapInfo> OnClicked;
@ -241,9 +241,9 @@ namespace osu.Game.Overlays.BeatmapSet
} }
} }
public DifficultySelectorButton(BeatmapInfo beatmap) public DifficultySelectorButton(BeatmapInfo beatmapInfo)
{ {
Beatmap = beatmap; BeatmapInfo = beatmapInfo;
Size = new Vector2(size); Size = new Vector2(size);
Margin = new MarginPadding { Horizontal = tile_spacing / 2 }; Margin = new MarginPadding { Horizontal = tile_spacing / 2 };
@ -260,7 +260,7 @@ namespace osu.Game.Overlays.BeatmapSet
Alpha = 0.5f Alpha = 0.5f
} }
}, },
icon = new DifficultyIcon(beatmap, shouldShowTooltip: false) icon = new DifficultyIcon(beatmapInfo, shouldShowTooltip: false)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -273,7 +273,7 @@ namespace osu.Game.Overlays.BeatmapSet
protected override bool OnHover(HoverEvent e) protected override bool OnHover(HoverEvent e)
{ {
fadeIn(); fadeIn();
OnHovered?.Invoke(Beatmap); OnHovered?.Invoke(BeatmapInfo);
return base.OnHover(e); return base.OnHover(e);
} }
@ -286,7 +286,7 @@ namespace osu.Game.Overlays.BeatmapSet
protected override bool OnClick(ClickEvent e) protected override bool OnClick(ClickEvent e)
{ {
OnClicked?.Invoke(Beatmap); OnClicked?.Invoke(BeatmapInfo);
return base.OnClick(e); return base.OnClick(e);
} }

View File

@ -211,7 +211,7 @@ namespace osu.Game.Overlays.BeatmapSet
Picker.Beatmap.ValueChanged += b => Picker.Beatmap.ValueChanged += b =>
{ {
Details.Beatmap = b.NewValue; Details.BeatmapInfo = b.NewValue;
externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineBeatmapSetID}#{b.NewValue?.Ruleset.ShortName}/{b.NewValue?.OnlineBeatmapID}"; externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineBeatmapSetID}#{b.NewValue?.Ruleset.ShortName}/{b.NewValue?.OnlineBeatmapID}";
}; };
} }

View File

@ -37,16 +37,16 @@ namespace osu.Game.Overlays.BeatmapSet
} }
} }
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (value == beatmap) return; if (value == beatmapInfo) return;
basic.Beatmap = advanced.Beatmap = beatmap = value; basic.BeatmapInfo = advanced.BeatmapInfo = beatmapInfo = value;
} }
} }

View File

@ -24,10 +24,10 @@ namespace osu.Game.Overlays.BeatmapSet
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>(); public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => successRate.Beatmap; get => successRate.BeatmapInfo;
set => successRate.Beatmap = value; set => successRate.BeatmapInfo = value;
} }
public Info() public Info()

View File

@ -23,16 +23,16 @@ namespace osu.Game.Overlays.BeatmapSet
private readonly Bar successRate; private readonly Bar successRate;
private readonly Container percentContainer; private readonly Container percentContainer;
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (value == beatmap) return; if (value == beatmapInfo) return;
beatmap = value; beatmapInfo = value;
updateDisplay(); updateDisplay();
} }
@ -40,15 +40,15 @@ namespace osu.Game.Overlays.BeatmapSet
private void updateDisplay() private void updateDisplay()
{ {
int passCount = beatmap?.OnlineInfo?.PassCount ?? 0; int passCount = beatmapInfo?.OnlineInfo?.PassCount ?? 0;
int playCount = beatmap?.OnlineInfo?.PlayCount ?? 0; int playCount = beatmapInfo?.OnlineInfo?.PlayCount ?? 0;
var rate = playCount != 0 ? (float)passCount / playCount : 0; var rate = playCount != 0 ? (float)passCount / playCount : 0;
successPercent.Text = rate.ToLocalisableString(@"0.#%"); successPercent.Text = rate.ToLocalisableString(@"0.#%");
successRate.Length = rate; successRate.Length = rate;
percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic);
Graph.Metrics = beatmap?.Metrics; Graph.Metrics = beatmapInfo?.Metrics;
} }
public SuccessRate() public SuccessRate()

View File

@ -61,7 +61,7 @@ namespace osu.Game.Overlays
Header.HeaderContent.Picker.Beatmap.ValueChanged += b => Header.HeaderContent.Picker.Beatmap.ValueChanged += b =>
{ {
info.Beatmap = b.NewValue; info.BeatmapInfo = b.NewValue;
ScrollFlow.ScrollToStart(); ScrollFlow.ScrollToStart();
}; };
} }

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
@ -42,6 +43,9 @@ namespace osu.Game.Overlays.Login
Spacing = new Vector2(0, 5); Spacing = new Vector2(0, 5);
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
ErrorTextFlowContainer errorText;
Children = new Drawable[] Children = new Drawable[]
{ {
username = new OsuTextBox username = new OsuTextBox
@ -57,6 +61,11 @@ namespace osu.Game.Overlays.Login
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
TabbableContentContainer = this, TabbableContentContainer = this,
}, },
errorText = new ErrorTextFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Remember username", LabelText = "Remember username",
@ -97,6 +106,9 @@ namespace osu.Game.Overlays.Login
}; };
password.OnCommit += (sender, newText) => performLogin(); password.OnCommit += (sender, newText) => performLogin();
if (api?.LastLoginError?.Message is string error)
errorText.AddErrors(new[] { error });
} }
public override bool AcceptsFocus => true; public override bool AcceptsFocus => true;

View File

@ -15,12 +15,12 @@ namespace osu.Game.Overlays.Profile.Sections
/// </summary> /// </summary>
public abstract class BeatmapMetadataContainer : OsuHoverContainer public abstract class BeatmapMetadataContainer : OsuHoverContainer
{ {
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
protected BeatmapMetadataContainer(BeatmapInfo beatmap) protected BeatmapMetadataContainer(BeatmapInfo beatmapInfo)
: base(HoverSampleSet.Submit) : base(HoverSampleSet.Submit)
{ {
this.beatmap = beatmap; this.beatmapInfo = beatmapInfo;
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
} }
@ -30,19 +30,19 @@ namespace osu.Game.Overlays.Profile.Sections
{ {
Action = () => Action = () =>
{ {
if (beatmap.OnlineBeatmapID != null) if (beatmapInfo.OnlineBeatmapID != null)
beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value); beatmapSetOverlay?.FetchAndShowBeatmap(beatmapInfo.OnlineBeatmapID.Value);
else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) else if (beatmapInfo.BeatmapSet?.OnlineBeatmapSetID != null)
beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value); beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmapInfo.BeatmapSet.OnlineBeatmapSetID.Value);
}; };
Child = new FillFlowContainer Child = new FillFlowContainer
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = CreateText(beatmap), Children = CreateText(beatmapInfo),
}; };
} }
protected abstract Drawable[] CreateText(BeatmapInfo beatmap); protected abstract Drawable[] CreateText(BeatmapInfo beatmapInfo);
} }
} }

View File

@ -22,12 +22,12 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
private const int cover_width = 100; private const int cover_width = 100;
private const int corner_radius = 6; private const int corner_radius = 6;
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
private readonly int playCount; private readonly int playCount;
public DrawableMostPlayedBeatmap(BeatmapInfo beatmap, int playCount) public DrawableMostPlayedBeatmap(BeatmapInfo beatmapInfo, int playCount)
{ {
this.beatmap = beatmap; this.beatmapInfo = beatmapInfo;
this.playCount = playCount; this.playCount = playCount;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Width = cover_width, Width = cover_width,
BeatmapSet = beatmap.BeatmapSet, BeatmapSet = beatmapInfo.BeatmapSet,
}, },
new Container new Container
{ {
@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new Drawable[]
{ {
new MostPlayedBeatmapMetadataContainer(beatmap), new MostPlayedBeatmapMetadataContainer(beatmapInfo),
new LinkFlowContainer(t => new LinkFlowContainer(t =>
{ {
t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular);
@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
}.With(d => }.With(d =>
{ {
d.AddText("mapped by "); d.AddText("mapped by ");
d.AddUserLink(beatmap.Metadata.Author); d.AddUserLink(beatmapInfo.Metadata.Author);
}), }),
} }
}, },
@ -120,23 +120,23 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer
{ {
public MostPlayedBeatmapMetadataContainer(BeatmapInfo beatmap) public MostPlayedBeatmapMetadataContainer(BeatmapInfo beatmapInfo)
: base(beatmap) : base(beatmapInfo)
{ {
} }
protected override Drawable[] CreateText(BeatmapInfo beatmap) => new Drawable[] protected override Drawable[] CreateText(BeatmapInfo beatmapInfo) => new Drawable[]
{ {
new OsuSpriteText new OsuSpriteText
{ {
Text = new RomanisableString( Text = new RomanisableString(
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ", $"{beatmapInfo.Metadata.TitleUnicode ?? beatmapInfo.Metadata.Title} [{beatmapInfo.Version}] ",
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] "), $"{beatmapInfo.Metadata.Title ?? beatmapInfo.Metadata.TitleUnicode} [{beatmapInfo.Version}] "),
Font = OsuFont.GetFont(weight: FontWeight.Bold) Font = OsuFont.GetFont(weight: FontWeight.Bold)
}, },
new OsuSpriteText new OsuSpriteText
{ {
Text = "by " + new RomanisableString(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist), Text = "by " + new RomanisableString(beatmapInfo.Metadata.ArtistUnicode, beatmapInfo.Metadata.Artist),
Font = OsuFont.GetFont(weight: FontWeight.Regular) Font = OsuFont.GetFont(weight: FontWeight.Regular)
}, },
}; };

View File

@ -245,27 +245,27 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer
{ {
public ScoreBeatmapMetadataContainer(BeatmapInfo beatmap) public ScoreBeatmapMetadataContainer(BeatmapInfo beatmapInfo)
: base(beatmap) : base(beatmapInfo)
{ {
} }
protected override Drawable[] CreateText(BeatmapInfo beatmap) => new Drawable[] protected override Drawable[] CreateText(BeatmapInfo beatmapInfo) => new Drawable[]
{ {
new OsuSpriteText new OsuSpriteText
{ {
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
Text = new RomanisableString( Text = new RomanisableString(
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ", $"{beatmapInfo.Metadata.TitleUnicode ?? beatmapInfo.Metadata.Title} ",
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} "), $"{beatmapInfo.Metadata.Title ?? beatmapInfo.Metadata.TitleUnicode} "),
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true) Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
}, },
new OsuSpriteText new OsuSpriteText
{ {
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
Text = "by " + new RomanisableString(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist), Text = "by " + new RomanisableString(beatmapInfo.Metadata.ArtistUnicode, beatmapInfo.Metadata.Artist),
Font = OsuFont.GetFont(size: 12, italics: true) Font = OsuFont.GetFont(size: 12, italics: true)
}, },
}; };

View File

@ -14,15 +14,15 @@ namespace osu.Game.Rulesets.Filter
public interface IRulesetFilterCriteria public interface IRulesetFilterCriteria
{ {
/// <summary> /// <summary>
/// Checks whether the supplied <paramref name="beatmap"/> satisfies ruleset-specific custom criteria, /// Checks whether the supplied <paramref name="beatmapInfo"/> satisfies ruleset-specific custom criteria,
/// in addition to the ones mandated by song select. /// in addition to the ones mandated by song select.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap to test the criteria against.</param> /// <param name="beatmapInfo">The beatmap to test the criteria against.</param>
/// <returns> /// <returns>
/// <c>true</c> if the beatmap matches the ruleset-specific custom filtering criteria, /// <c>true</c> if the beatmap matches the ruleset-specific custom filtering criteria,
/// <c>false</c> otherwise. /// <c>false</c> otherwise.
/// </returns> /// </returns>
bool Matches(BeatmapInfo beatmap); bool Matches(BeatmapInfo beatmapInfo);
/// <summary> /// <summary>
/// Attempts to parse a single custom keyword criterion, given by the user via the song select search box. /// Attempts to parse a single custom keyword criterion, given by the user via the song select search box.

View File

@ -10,12 +10,12 @@ namespace osu.Game.Screens.Edit.Components.Menus
{ {
public class DifficultyMenuItem : StatefulMenuItem<bool> public class DifficultyMenuItem : StatefulMenuItem<bool>
{ {
public BeatmapInfo Beatmap { get; } public BeatmapInfo BeatmapInfo { get; }
public DifficultyMenuItem(BeatmapInfo beatmapInfo, bool selected, Action<BeatmapInfo> difficultyChangeFunc) public DifficultyMenuItem(BeatmapInfo beatmapInfo, bool selected, Action<BeatmapInfo> difficultyChangeFunc)
: base(beatmapInfo.Version ?? "(unnamed)", null) : base(beatmapInfo.Version ?? "(unnamed)", null)
{ {
Beatmap = beatmapInfo; BeatmapInfo = beatmapInfo;
State.Value = selected; State.Value = selected;
if (!selected) if (!selected)

View File

@ -48,7 +48,7 @@ namespace osu.Game.Screens.Select
/// <summary> /// <summary>
/// The currently selected beatmap. /// The currently selected beatmap.
/// </summary> /// </summary>
public BeatmapInfo SelectedBeatmap => selectedBeatmap?.Beatmap; public BeatmapInfo SelectedBeatmapInfo => selectedBeatmap?.BeatmapInfo;
private CarouselBeatmap selectedBeatmap => selectedBeatmapSet?.Beatmaps.FirstOrDefault(s => s.State.Value == CarouselItemState.Selected); private CarouselBeatmap selectedBeatmap => selectedBeatmapSet?.Beatmaps.FirstOrDefault(s => s.State.Value == CarouselItemState.Selected);
@ -65,7 +65,7 @@ namespace osu.Game.Screens.Select
private CarouselBeatmapSet selectedBeatmapSet; private CarouselBeatmapSet selectedBeatmapSet;
/// <summary> /// <summary>
/// Raised when the <see cref="SelectedBeatmap"/> is changed. /// Raised when the <see cref="SelectedBeatmapInfo"/> is changed.
/// </summary> /// </summary>
public Action<BeatmapInfo> SelectionChanged; public Action<BeatmapInfo> SelectionChanged;
@ -212,7 +212,7 @@ namespace osu.Game.Screens.Select
// If the selected beatmap is about to be removed, store its ID so it can be re-selected if required // If the selected beatmap is about to be removed, store its ID so it can be re-selected if required
if (existingSet?.State?.Value == CarouselItemState.Selected) if (existingSet?.State?.Value == CarouselItemState.Selected)
previouslySelectedID = selectedBeatmap?.Beatmap.ID; previouslySelectedID = selectedBeatmap?.BeatmapInfo.ID;
var newSet = createCarouselSet(beatmapSet); var newSet = createCarouselSet(beatmapSet);
@ -233,7 +233,7 @@ namespace osu.Game.Screens.Select
// check if we can/need to maintain our current selection. // check if we can/need to maintain our current selection.
if (previouslySelectedID != null) if (previouslySelectedID != null)
select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == previouslySelectedID) ?? newSet); select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.BeatmapInfo.ID == previouslySelectedID) ?? newSet);
itemsCache.Invalidate(); itemsCache.Invalidate();
Schedule(() => BeatmapSetsChanged?.Invoke()); Schedule(() => BeatmapSetsChanged?.Invoke());
@ -242,15 +242,15 @@ namespace osu.Game.Screens.Select
/// <summary> /// <summary>
/// Selects a given beatmap on the carousel. /// Selects a given beatmap on the carousel.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap to select.</param> /// <param name="beatmapInfo">The beatmap to select.</param>
/// <param name="bypassFilters">Whether to select the beatmap even if it is filtered (i.e., not visible on carousel).</param> /// <param name="bypassFilters">Whether to select the beatmap even if it is filtered (i.e., not visible on carousel).</param>
/// <returns>True if a selection was made, False if it wasn't.</returns> /// <returns>True if a selection was made, False if it wasn't.</returns>
public bool SelectBeatmap(BeatmapInfo beatmap, bool bypassFilters = true) public bool SelectBeatmap(BeatmapInfo beatmapInfo, bool bypassFilters = true)
{ {
// ensure that any pending events from BeatmapManager have been run before attempting a selection. // ensure that any pending events from BeatmapManager have been run before attempting a selection.
Scheduler.Update(); Scheduler.Update();
if (beatmap?.Hidden != false) if (beatmapInfo?.Hidden != false)
return false; return false;
foreach (CarouselBeatmapSet set in beatmapSets) foreach (CarouselBeatmapSet set in beatmapSets)
@ -258,7 +258,7 @@ namespace osu.Game.Screens.Select
if (!bypassFilters && set.Filtered.Value) if (!bypassFilters && set.Filtered.Value)
continue; continue;
var item = set.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); var item = set.Beatmaps.FirstOrDefault(p => p.BeatmapInfo.Equals(beatmapInfo));
if (item == null) if (item == null)
// The beatmap that needs to be selected doesn't exist in this set // The beatmap that needs to be selected doesn't exist in this set
@ -472,7 +472,7 @@ namespace osu.Game.Screens.Select
private float? scrollTarget; private float? scrollTarget;
/// <summary> /// <summary>
/// Scroll to the current <see cref="SelectedBeatmap"/>. /// Scroll to the current <see cref="SelectedBeatmapInfo"/>.
/// </summary> /// </summary>
/// <param name="immediate"> /// <param name="immediate">
/// Whether the scroll position should immediately be shifted to the target, delegating animation to visible panels. /// Whether the scroll position should immediately be shifted to the target, delegating animation to visible panels.
@ -720,7 +720,7 @@ namespace osu.Game.Screens.Select
if (state.NewValue == CarouselItemState.Selected) if (state.NewValue == CarouselItemState.Selected)
{ {
selectedBeatmapSet = set; selectedBeatmapSet = set;
SelectionChanged?.Invoke(c.Beatmap); SelectionChanged?.Invoke(c.BeatmapInfo);
itemsCache.Invalidate(); itemsCache.Invalidate();
ScrollToSelected(); ScrollToSelected();

View File

@ -17,9 +17,9 @@ namespace osu.Game.Screens.Select
[Resolved] [Resolved]
private ScoreManager scoreManager { get; set; } private ScoreManager scoreManager { get; set; }
public BeatmapClearScoresDialog(BeatmapInfo beatmap, Action onCompletion) public BeatmapClearScoresDialog(BeatmapInfo beatmapInfo, Action onCompletion)
{ {
BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}"; BodyText = $@"{beatmapInfo.Metadata?.Artist} - {beatmapInfo.Metadata?.Title}";
Icon = FontAwesome.Solid.Eraser; Icon = FontAwesome.Solid.Eraser;
HeaderText = @"Clearing all local scores. Are you sure?"; HeaderText = @"Clearing all local scores. Are you sure?";
Buttons = new PopupDialogButton[] Buttons = new PopupDialogButton[]
@ -29,7 +29,7 @@ namespace osu.Game.Screens.Select
Text = @"Yes. Please.", Text = @"Yes. Please.",
Action = () => Action = () =>
{ {
Task.Run(() => scoreManager.Delete(scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == beatmap.ID).ToList())) Task.Run(() => scoreManager.Delete(scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == beatmapInfo.ID).ToList()))
.ContinueWith(_ => onCompletion); .ContinueWith(_ => onCompletion);
} }
}, },

View File

@ -22,7 +22,7 @@ namespace osu.Game.Screens.Select
{ {
beatmap = value; beatmap = value;
Details.Beatmap = value?.BeatmapInfo; Details.BeatmapInfo = value?.BeatmapInfo;
} }
} }

View File

@ -41,16 +41,16 @@ namespace osu.Game.Screens.Select
[Resolved] [Resolved]
private RulesetStore rulesets { get; set; } private RulesetStore rulesets { get; set; }
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (value == beatmap) return; if (value == beatmapInfo) return;
beatmap = value; beatmapInfo = value;
Scheduler.AddOnce(updateStatistics); Scheduler.AddOnce(updateStatistics);
} }
@ -170,26 +170,26 @@ namespace osu.Game.Screens.Select
private void updateStatistics() private void updateStatistics()
{ {
advanced.Beatmap = Beatmap; advanced.BeatmapInfo = BeatmapInfo;
description.Text = Beatmap?.Version; description.Text = BeatmapInfo?.Version;
source.Text = Beatmap?.Metadata?.Source; source.Text = BeatmapInfo?.Metadata?.Source;
tags.Text = Beatmap?.Metadata?.Tags; tags.Text = BeatmapInfo?.Metadata?.Tags;
// metrics may have been previously fetched // metrics may have been previously fetched
if (Beatmap?.BeatmapSet?.Metrics != null && Beatmap?.Metrics != null) if (BeatmapInfo?.BeatmapSet?.Metrics != null && BeatmapInfo?.Metrics != null)
{ {
updateMetrics(); updateMetrics();
return; return;
} }
// for now, let's early abort if an OnlineBeatmapID is not present (should have been populated at import time). // for now, let's early abort if an OnlineBeatmapID is not present (should have been populated at import time).
if (Beatmap?.OnlineBeatmapID == null || api.State.Value == APIState.Offline) if (BeatmapInfo?.OnlineBeatmapID == null || api.State.Value == APIState.Offline)
{ {
updateMetrics(); updateMetrics();
return; return;
} }
var requestedBeatmap = Beatmap; var requestedBeatmap = BeatmapInfo;
var lookup = new GetBeatmapRequest(requestedBeatmap); var lookup = new GetBeatmapRequest(requestedBeatmap);
@ -197,11 +197,11 @@ namespace osu.Game.Screens.Select
{ {
Schedule(() => Schedule(() =>
{ {
if (beatmap != requestedBeatmap) if (beatmapInfo != requestedBeatmap)
// the beatmap has been changed since we started the lookup. // the beatmap has been changed since we started the lookup.
return; return;
var b = res.ToBeatmap(rulesets); var b = res.ToBeatmapInfo(rulesets);
if (requestedBeatmap.BeatmapSet == null) if (requestedBeatmap.BeatmapSet == null)
requestedBeatmap.BeatmapSet = b.BeatmapSet; requestedBeatmap.BeatmapSet = b.BeatmapSet;
@ -218,7 +218,7 @@ namespace osu.Game.Screens.Select
{ {
Schedule(() => Schedule(() =>
{ {
if (beatmap != requestedBeatmap) if (beatmapInfo != requestedBeatmap)
// the beatmap has been changed since we started the lookup. // the beatmap has been changed since we started the lookup.
return; return;
@ -232,12 +232,12 @@ namespace osu.Game.Screens.Select
private void updateMetrics() private void updateMetrics()
{ {
var hasRatings = beatmap?.BeatmapSet?.Metrics?.Ratings?.Any() ?? false; var hasRatings = beatmapInfo?.BeatmapSet?.Metrics?.Ratings?.Any() ?? false;
var hasRetriesFails = (beatmap?.Metrics?.Retries?.Any() ?? false) || (beatmap?.Metrics?.Fails?.Any() ?? false); var hasRetriesFails = (beatmapInfo?.Metrics?.Retries?.Any() ?? false) || (beatmapInfo?.Metrics?.Fails?.Any() ?? false);
if (hasRatings) if (hasRatings)
{ {
ratings.Metrics = beatmap.BeatmapSet.Metrics; ratings.Metrics = beatmapInfo.BeatmapSet.Metrics;
ratings.FadeIn(transition_duration); ratings.FadeIn(transition_duration);
} }
else else
@ -249,7 +249,7 @@ namespace osu.Game.Screens.Select
if (hasRetriesFails) if (hasRetriesFails)
{ {
failRetryGraph.Metrics = beatmap.Metrics; failRetryGraph.Metrics = beatmapInfo.Metrics;
failRetryContainer.FadeIn(transition_duration); failRetryContainer.FadeIn(transition_duration);
} }
else else

View File

@ -12,11 +12,11 @@ namespace osu.Game.Screens.Select.Carousel
{ {
public override float TotalHeight => DrawableCarouselBeatmap.HEIGHT; public override float TotalHeight => DrawableCarouselBeatmap.HEIGHT;
public readonly BeatmapInfo Beatmap; public readonly BeatmapInfo BeatmapInfo;
public CarouselBeatmap(BeatmapInfo beatmap) public CarouselBeatmap(BeatmapInfo beatmapInfo)
{ {
Beatmap = beatmap; BeatmapInfo = beatmapInfo;
State.Value = CarouselItemState.Collapsed; State.Value = CarouselItemState.Collapsed;
} }
@ -28,36 +28,36 @@ namespace osu.Game.Screens.Select.Carousel
bool match = bool match =
criteria.Ruleset == null || criteria.Ruleset == null ||
Beatmap.RulesetID == criteria.Ruleset.ID || BeatmapInfo.RulesetID == criteria.Ruleset.ID ||
(Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps); (BeatmapInfo.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps);
if (Beatmap.BeatmapSet?.Equals(criteria.SelectedBeatmapSet) == true) if (BeatmapInfo.BeatmapSet?.Equals(criteria.SelectedBeatmapSet) == true)
{ {
// only check ruleset equality or convertability for selected beatmap // only check ruleset equality or convertability for selected beatmap
Filtered.Value = !match; Filtered.Value = !match;
return; return;
} }
match &= !criteria.StarDifficulty.HasFilter || criteria.StarDifficulty.IsInRange(Beatmap.StarDifficulty); match &= !criteria.StarDifficulty.HasFilter || criteria.StarDifficulty.IsInRange(BeatmapInfo.StarDifficulty);
match &= !criteria.ApproachRate.HasFilter || criteria.ApproachRate.IsInRange(Beatmap.BaseDifficulty.ApproachRate); match &= !criteria.ApproachRate.HasFilter || criteria.ApproachRate.IsInRange(BeatmapInfo.BaseDifficulty.ApproachRate);
match &= !criteria.DrainRate.HasFilter || criteria.DrainRate.IsInRange(Beatmap.BaseDifficulty.DrainRate); match &= !criteria.DrainRate.HasFilter || criteria.DrainRate.IsInRange(BeatmapInfo.BaseDifficulty.DrainRate);
match &= !criteria.CircleSize.HasFilter || criteria.CircleSize.IsInRange(Beatmap.BaseDifficulty.CircleSize); match &= !criteria.CircleSize.HasFilter || criteria.CircleSize.IsInRange(BeatmapInfo.BaseDifficulty.CircleSize);
match &= !criteria.OverallDifficulty.HasFilter || criteria.OverallDifficulty.IsInRange(Beatmap.BaseDifficulty.OverallDifficulty); match &= !criteria.OverallDifficulty.HasFilter || criteria.OverallDifficulty.IsInRange(BeatmapInfo.BaseDifficulty.OverallDifficulty);
match &= !criteria.Length.HasFilter || criteria.Length.IsInRange(Beatmap.Length); match &= !criteria.Length.HasFilter || criteria.Length.IsInRange(BeatmapInfo.Length);
match &= !criteria.BPM.HasFilter || criteria.BPM.IsInRange(Beatmap.BPM); match &= !criteria.BPM.HasFilter || criteria.BPM.IsInRange(BeatmapInfo.BPM);
match &= !criteria.BeatDivisor.HasFilter || criteria.BeatDivisor.IsInRange(Beatmap.BeatDivisor); match &= !criteria.BeatDivisor.HasFilter || criteria.BeatDivisor.IsInRange(BeatmapInfo.BeatDivisor);
match &= !criteria.OnlineStatus.HasFilter || criteria.OnlineStatus.IsInRange(Beatmap.Status); match &= !criteria.OnlineStatus.HasFilter || criteria.OnlineStatus.IsInRange(BeatmapInfo.Status);
match &= !criteria.Creator.HasFilter || criteria.Creator.Matches(Beatmap.Metadata.AuthorString); match &= !criteria.Creator.HasFilter || criteria.Creator.Matches(BeatmapInfo.Metadata.AuthorString);
match &= !criteria.Artist.HasFilter || criteria.Artist.Matches(Beatmap.Metadata.Artist) || match &= !criteria.Artist.HasFilter || criteria.Artist.Matches(BeatmapInfo.Metadata.Artist) ||
criteria.Artist.Matches(Beatmap.Metadata.ArtistUnicode); criteria.Artist.Matches(BeatmapInfo.Metadata.ArtistUnicode);
match &= !criteria.UserStarDifficulty.HasFilter || criteria.UserStarDifficulty.IsInRange(Beatmap.StarDifficulty); match &= !criteria.UserStarDifficulty.HasFilter || criteria.UserStarDifficulty.IsInRange(BeatmapInfo.StarDifficulty);
if (match) if (match)
{ {
var terms = Beatmap.SearchableTerms; var terms = BeatmapInfo.SearchableTerms;
foreach (var criteriaTerm in criteria.SearchTerms) foreach (var criteriaTerm in criteria.SearchTerms)
match &= terms.Any(term => term.Contains(criteriaTerm, StringComparison.InvariantCultureIgnoreCase)); match &= terms.Any(term => term.Contains(criteriaTerm, StringComparison.InvariantCultureIgnoreCase));
@ -66,16 +66,16 @@ namespace osu.Game.Screens.Select.Carousel
// this should be done after text matching so we can prioritise matching numbers in metadata. // this should be done after text matching so we can prioritise matching numbers in metadata.
if (!match && criteria.SearchNumber.HasValue) if (!match && criteria.SearchNumber.HasValue)
{ {
match = (Beatmap.OnlineBeatmapID == criteria.SearchNumber.Value) || match = (BeatmapInfo.OnlineBeatmapID == criteria.SearchNumber.Value) ||
(Beatmap.BeatmapSet?.OnlineBeatmapSetID == criteria.SearchNumber.Value); (BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID == criteria.SearchNumber.Value);
} }
} }
if (match) if (match)
match &= criteria.Collection?.Beatmaps.Contains(Beatmap) ?? true; match &= criteria.Collection?.Beatmaps.Contains(BeatmapInfo) ?? true;
if (match && criteria.RulesetCriteria != null) if (match && criteria.RulesetCriteria != null)
match &= criteria.RulesetCriteria.Matches(Beatmap); match &= criteria.RulesetCriteria.Matches(BeatmapInfo);
Filtered.Value = !match; Filtered.Value = !match;
} }
@ -89,13 +89,13 @@ namespace osu.Game.Screens.Select.Carousel
{ {
default: default:
case SortMode.Difficulty: case SortMode.Difficulty:
var ruleset = Beatmap.RulesetID.CompareTo(otherBeatmap.Beatmap.RulesetID); var ruleset = BeatmapInfo.RulesetID.CompareTo(otherBeatmap.BeatmapInfo.RulesetID);
if (ruleset != 0) return ruleset; if (ruleset != 0) return ruleset;
return Beatmap.StarDifficulty.CompareTo(otherBeatmap.Beatmap.StarDifficulty); return BeatmapInfo.StarDifficulty.CompareTo(otherBeatmap.BeatmapInfo.StarDifficulty);
} }
} }
public override string ToString() => Beatmap.ToString(); public override string ToString() => BeatmapInfo.ToString();
} }
} }

View File

@ -47,8 +47,8 @@ namespace osu.Game.Screens.Select.Carousel
{ {
if (LastSelected == null || LastSelected.Filtered.Value) if (LastSelected == null || LastSelected.Filtered.Value)
{ {
if (GetRecommendedBeatmap?.Invoke(Children.OfType<CarouselBeatmap>().Where(b => !b.Filtered.Value).Select(b => b.Beatmap)) is BeatmapInfo recommended) if (GetRecommendedBeatmap?.Invoke(Children.OfType<CarouselBeatmap>().Where(b => !b.Filtered.Value).Select(b => b.BeatmapInfo)) is BeatmapInfo recommended)
return Children.OfType<CarouselBeatmap>().First(b => b.Beatmap == recommended); return Children.OfType<CarouselBeatmap>().First(b => b.BeatmapInfo == recommended);
} }
return base.GetNextToSelect(); return base.GetNextToSelect();
@ -91,7 +91,7 @@ namespace osu.Game.Screens.Select.Carousel
/// <summary> /// <summary>
/// All beatmaps which are not filtered and valid for display. /// All beatmaps which are not filtered and valid for display.
/// </summary> /// </summary>
protected IEnumerable<BeatmapInfo> ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value || b.State.Value == CarouselItemState.Selected).Select(b => b.Beatmap); protected IEnumerable<BeatmapInfo> ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value || b.State.Value == CarouselItemState.Selected).Select(b => b.BeatmapInfo);
private int compareUsingAggregateMax(CarouselBeatmapSet other, Func<BeatmapInfo, double> func) private int compareUsingAggregateMax(CarouselBeatmapSet other, Func<BeatmapInfo, double> func)
{ {

View File

@ -40,7 +40,7 @@ namespace osu.Game.Screens.Select.Carousel
private const float height = MAX_HEIGHT * 0.6f; private const float height = MAX_HEIGHT * 0.6f;
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
private Sprite background; private Sprite background;
@ -68,7 +68,7 @@ namespace osu.Game.Screens.Select.Carousel
public DrawableCarouselBeatmap(CarouselBeatmap panel) public DrawableCarouselBeatmap(CarouselBeatmap panel)
{ {
beatmap = panel.Beatmap; beatmapInfo = panel.BeatmapInfo;
Item = panel; Item = panel;
} }
@ -109,7 +109,7 @@ namespace osu.Game.Screens.Select.Carousel
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Children = new Drawable[] Children = new Drawable[]
{ {
new DifficultyIcon(beatmap, shouldShowTooltip: false) new DifficultyIcon(beatmapInfo, shouldShowTooltip: false)
{ {
Scale = new Vector2(1.8f), Scale = new Vector2(1.8f),
}, },
@ -129,7 +129,7 @@ namespace osu.Game.Screens.Select.Carousel
{ {
new OsuSpriteText new OsuSpriteText
{ {
Text = beatmap.Version, Text = beatmapInfo.Version,
Font = OsuFont.GetFont(size: 20), Font = OsuFont.GetFont(size: 20),
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft Origin = Anchor.BottomLeft
@ -142,7 +142,7 @@ namespace osu.Game.Screens.Select.Carousel
}, },
new OsuSpriteText new OsuSpriteText
{ {
Text = $"{(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author.Username}", Text = $"{(beatmapInfo.Metadata ?? beatmapInfo.BeatmapSet.Metadata).Author.Username}",
Font = OsuFont.GetFont(italics: true), Font = OsuFont.GetFont(italics: true),
Anchor = Anchor.BottomLeft, Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft Origin = Anchor.BottomLeft
@ -156,7 +156,7 @@ namespace osu.Game.Screens.Select.Carousel
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
new TopLocalRank(beatmap) new TopLocalRank(beatmapInfo)
{ {
Scale = new Vector2(0.8f), Scale = new Vector2(0.8f),
Size = new Vector2(40, 20) Size = new Vector2(40, 20)
@ -200,7 +200,7 @@ namespace osu.Game.Screens.Select.Carousel
protected override bool OnClick(ClickEvent e) protected override bool OnClick(ClickEvent e)
{ {
if (Item.State.Value == CarouselItemState.Selected) if (Item.State.Value == CarouselItemState.Selected)
startRequested?.Invoke(beatmap); startRequested?.Invoke(beatmapInfo);
return base.OnClick(e); return base.OnClick(e);
} }
@ -216,7 +216,7 @@ namespace osu.Game.Screens.Select.Carousel
if (Item.State.Value != CarouselItemState.Collapsed) if (Item.State.Value != CarouselItemState.Collapsed)
{ {
// We've potentially cancelled the computation above so a new bindable is required. // We've potentially cancelled the computation above so a new bindable is required.
starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, (starDifficultyCancellationSource = new CancellationTokenSource()).Token); starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmapInfo, (starDifficultyCancellationSource = new CancellationTokenSource()).Token);
starDifficultyBindable.BindValueChanged(d => starDifficultyBindable.BindValueChanged(d =>
{ {
starCounter.Current = (float)(d.NewValue?.Stars ?? 0); starCounter.Current = (float)(d.NewValue?.Stars ?? 0);
@ -233,13 +233,13 @@ namespace osu.Game.Screens.Select.Carousel
List<MenuItem> items = new List<MenuItem>(); List<MenuItem> items = new List<MenuItem>();
if (startRequested != null) if (startRequested != null)
items.Add(new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested(beatmap))); items.Add(new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested(beatmapInfo)));
if (editRequested != null) if (editRequested != null)
items.Add(new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested(beatmap))); items.Add(new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested(beatmapInfo)));
if (beatmap.OnlineBeatmapID.HasValue && beatmapOverlay != null) if (beatmapInfo.OnlineBeatmapID.HasValue && beatmapOverlay != null)
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => beatmapOverlay.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value))); items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => beatmapOverlay.FetchAndShowBeatmap(beatmapInfo.OnlineBeatmapID.Value)));
if (collectionManager != null) if (collectionManager != null)
{ {
@ -251,7 +251,7 @@ namespace osu.Game.Screens.Select.Carousel
} }
if (hideRequested != null) if (hideRequested != null)
items.Add(new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested(beatmap))); items.Add(new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested(beatmapInfo)));
return items.ToArray(); return items.ToArray();
} }
@ -262,12 +262,12 @@ namespace osu.Game.Screens.Select.Carousel
return new ToggleMenuItem(collection.Name.Value, MenuItemType.Standard, s => return new ToggleMenuItem(collection.Name.Value, MenuItemType.Standard, s =>
{ {
if (s) if (s)
collection.Beatmaps.Add(beatmap); collection.Beatmaps.Add(beatmapInfo);
else else
collection.Beatmaps.Remove(beatmap); collection.Beatmaps.Remove(beatmapInfo);
}) })
{ {
State = { Value = collection.Beatmaps.Contains(beatmap) } State = { Value = collection.Beatmaps.Contains(beatmapInfo) }
}; };
} }

View File

@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select.Carousel
public readonly CarouselBeatmap Item; public readonly CarouselBeatmap Item;
public FilterableDifficultyIcon(CarouselBeatmap item) public FilterableDifficultyIcon(CarouselBeatmap item)
: base(item.Beatmap, performBackgroundDifficultyLookup: false) : base(item.BeatmapInfo, performBackgroundDifficultyLookup: false)
{ {
filtered.BindTo(item.Filtered); filtered.BindTo(item.Filtered);
filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100));

View File

@ -16,7 +16,7 @@ namespace osu.Game.Screens.Select.Carousel
public readonly List<CarouselBeatmap> Items; public readonly List<CarouselBeatmap> Items;
public FilterableGroupedDifficultyIcon(List<CarouselBeatmap> items, RulesetInfo ruleset) public FilterableGroupedDifficultyIcon(List<CarouselBeatmap> items, RulesetInfo ruleset)
: base(items.Select(i => i.Beatmap).ToList(), ruleset, Color4.White) : base(items.Select(i => i.BeatmapInfo).ToList(), ruleset, Color4.White)
{ {
Items = items; Items = items;

View File

@ -86,7 +86,7 @@ namespace osu.Game.Screens.Select.Carousel
var beatmaps = carouselSet.Beatmaps.ToList(); var beatmaps = carouselSet.Beatmaps.ToList();
return beatmaps.Count > maximum_difficulty_icons return beatmaps.Count > maximum_difficulty_icons
? (IEnumerable<DifficultyIcon>)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) ? (IEnumerable<DifficultyIcon>)beatmaps.GroupBy(b => b.BeatmapInfo.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key))
: beatmaps.Select(b => new FilterableDifficultyIcon(b)); : beatmaps.Select(b => new FilterableDifficultyIcon(b));
} }
} }

View File

@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select.Carousel
{ {
public class TopLocalRank : UpdateableRank public class TopLocalRank : UpdateableRank
{ {
private readonly BeatmapInfo beatmap; private readonly BeatmapInfo beatmapInfo;
[Resolved] [Resolved]
private ScoreManager scores { get; set; } private ScoreManager scores { get; set; }
@ -31,10 +31,10 @@ namespace osu.Game.Screens.Select.Carousel
private IBindable<WeakReference<ScoreInfo>> itemUpdated; private IBindable<WeakReference<ScoreInfo>> itemUpdated;
private IBindable<WeakReference<ScoreInfo>> itemRemoved; private IBindable<WeakReference<ScoreInfo>> itemRemoved;
public TopLocalRank(BeatmapInfo beatmap) public TopLocalRank(BeatmapInfo beatmapInfo)
: base(null) : base(null)
{ {
this.beatmap = beatmap; this.beatmapInfo = beatmapInfo;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Carousel
{ {
if (weakScore.NewValue.TryGetTarget(out var score)) if (weakScore.NewValue.TryGetTarget(out var score))
{ {
if (score.BeatmapInfoID == beatmap.ID) if (score.BeatmapInfoID == beatmapInfo.ID)
fetchAndLoadTopScore(); fetchAndLoadTopScore();
} }
} }
@ -79,10 +79,10 @@ namespace osu.Game.Screens.Select.Carousel
private ScoreInfo fetchTopScore() private ScoreInfo fetchTopScore()
{ {
if (scores == null || beatmap == null || ruleset?.Value == null || api?.LocalUser.Value == null) if (scores == null || beatmapInfo == null || ruleset?.Value == null || api?.LocalUser.Value == null)
return null; return null;
return scores.QueryScores(s => s.UserID == api.LocalUser.Value.Id && s.BeatmapInfoID == beatmap.ID && s.RulesetID == ruleset.Value.ID && !s.DeletePending) return scores.QueryScores(s => s.UserID == api.LocalUser.Value.Id && s.BeatmapInfoID == beatmapInfo.ID && s.RulesetID == ruleset.Value.ID && !s.DeletePending)
.OrderByDescending(s => s.TotalScore) .OrderByDescending(s => s.TotalScore)
.FirstOrDefault(); .FirstOrDefault();
} }

View File

@ -38,16 +38,16 @@ namespace osu.Game.Screens.Select.Details
protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate; protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate;
private readonly StatisticRow starDifficulty; private readonly StatisticRow starDifficulty;
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (value == beatmap) return; if (value == beatmapInfo) return;
beatmap = value; beatmapInfo = value;
updateStatistics(); updateStatistics();
} }
@ -106,7 +106,7 @@ namespace osu.Game.Screens.Select.Details
private void updateStatistics() private void updateStatistics()
{ {
BeatmapDifficulty baseDifficulty = Beatmap?.BaseDifficulty; BeatmapDifficulty baseDifficulty = BeatmapInfo?.BaseDifficulty;
BeatmapDifficulty adjustedDifficulty = null; BeatmapDifficulty adjustedDifficulty = null;
if (baseDifficulty != null && mods.Value.Any(m => m is IApplicableToDifficulty)) if (baseDifficulty != null && mods.Value.Any(m => m is IApplicableToDifficulty))
@ -117,7 +117,7 @@ namespace osu.Game.Screens.Select.Details
mod.ApplyToDifficulty(adjustedDifficulty); mod.ApplyToDifficulty(adjustedDifficulty);
} }
switch (Beatmap?.Ruleset?.ID ?? 0) switch (BeatmapInfo?.Ruleset?.ID ?? 0)
{ {
case 3: case 3:
// Account for mania differences locally for now // Account for mania differences locally for now
@ -145,13 +145,13 @@ namespace osu.Game.Screens.Select.Details
{ {
starDifficultyCancellationSource?.Cancel(); starDifficultyCancellationSource?.Cancel();
if (Beatmap == null) if (BeatmapInfo == null)
return; return;
starDifficultyCancellationSource = new CancellationTokenSource(); starDifficultyCancellationSource = new CancellationTokenSource();
var normalStarDifficulty = difficultyCache.GetDifficultyAsync(Beatmap, ruleset.Value, null, starDifficultyCancellationSource.Token); var normalStarDifficulty = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, null, starDifficultyCancellationSource.Token);
var moddedStarDifficulty = difficultyCache.GetDifficultyAsync(Beatmap, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token); var moddedStarDifficulty = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token);
Task.WhenAll(normalStarDifficulty, moddedStarDifficulty).ContinueWith(_ => Schedule(() => Task.WhenAll(normalStarDifficulty, moddedStarDifficulty).ContinueWith(_ => Schedule(() =>
{ {

View File

@ -25,17 +25,17 @@ namespace osu.Game.Screens.Select.Leaderboards
[Resolved] [Resolved]
private RulesetStore rulesets { get; set; } private RulesetStore rulesets { get; set; }
private BeatmapInfo beatmap; private BeatmapInfo beatmapInfo;
public BeatmapInfo Beatmap public BeatmapInfo BeatmapInfo
{ {
get => beatmap; get => beatmapInfo;
set set
{ {
if (beatmap == value) if (beatmapInfo == value)
return; return;
beatmap = value; beatmapInfo = value;
Scores = null; Scores = null;
UpdateScores(); UpdateScores();
@ -116,7 +116,7 @@ namespace osu.Game.Screens.Select.Leaderboards
if (score.NewValue.TryGetTarget(out var scoreInfo)) if (score.NewValue.TryGetTarget(out var scoreInfo))
{ {
if (Beatmap?.ID != scoreInfo.BeatmapInfoID) if (BeatmapInfo?.ID != scoreInfo.BeatmapInfoID)
return; return;
} }
@ -132,7 +132,7 @@ namespace osu.Game.Screens.Select.Leaderboards
loadCancellationSource?.Cancel(); loadCancellationSource?.Cancel();
loadCancellationSource = new CancellationTokenSource(); loadCancellationSource = new CancellationTokenSource();
if (Beatmap == null) if (BeatmapInfo == null)
{ {
PlaceholderState = PlaceholderState.NoneSelected; PlaceholderState = PlaceholderState.NoneSelected;
return null; return null;
@ -141,7 +141,7 @@ namespace osu.Game.Screens.Select.Leaderboards
if (Scope == BeatmapLeaderboardScope.Local) if (Scope == BeatmapLeaderboardScope.Local)
{ {
var scores = scoreManager var scores = scoreManager
.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID && s.Ruleset.ID == ruleset.Value.ID); .QueryScores(s => !s.DeletePending && s.Beatmap.ID == BeatmapInfo.ID && s.Ruleset.ID == ruleset.Value.ID);
if (filterMods && !mods.Value.Any()) if (filterMods && !mods.Value.Any())
{ {
@ -168,7 +168,7 @@ namespace osu.Game.Screens.Select.Leaderboards
return null; return null;
} }
if (Beatmap.OnlineBeatmapID == null || Beatmap?.Status <= BeatmapSetOnlineStatus.Pending) if (BeatmapInfo.OnlineBeatmapID == null || BeatmapInfo?.Status <= BeatmapSetOnlineStatus.Pending)
{ {
PlaceholderState = PlaceholderState.Unavailable; PlaceholderState = PlaceholderState.Unavailable;
return null; return null;
@ -188,7 +188,7 @@ namespace osu.Game.Screens.Select.Leaderboards
else if (filterMods) else if (filterMods)
requestMods = mods.Value; requestMods = mods.Value;
var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope, requestMods); var req = new GetScoresRequest(BeatmapInfo, ruleset.Value ?? BeatmapInfo.Ruleset, Scope, requestMods);
req.Success += r => req.Success += r =>
{ {

View File

@ -29,8 +29,8 @@ namespace osu.Game.Screens.Select
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
BeatmapInfo beatmap = beatmapManager.QueryBeatmap(b => b.ID == score.BeatmapInfoID); BeatmapInfo beatmapInfo = beatmapManager.QueryBeatmap(b => b.ID == score.BeatmapInfoID);
Debug.Assert(beatmap != null); Debug.Assert(beatmapInfo != null);
BodyText = $"{score.User} ({score.DisplayAccuracy}, {score.Rank})"; BodyText = $"{score.User} ({score.DisplayAccuracy}, {score.Rank})";

View File

@ -23,7 +23,7 @@ namespace osu.Game.Screens.Select
{ {
base.Beatmap = value; base.Beatmap = value;
Leaderboard.Beatmap = value is DummyWorkingBeatmap ? null : value?.BeatmapInfo; Leaderboard.BeatmapInfo = value is DummyWorkingBeatmap ? null : value?.BeatmapInfo;
} }
} }

View File

@ -345,22 +345,22 @@ namespace osu.Game.Screens.Select
/// </summary> /// </summary>
protected abstract BeatmapDetailArea CreateBeatmapDetailArea(); protected abstract BeatmapDetailArea CreateBeatmapDetailArea();
public void Edit(BeatmapInfo beatmap = null) public void Edit(BeatmapInfo beatmapInfo = null)
{ {
if (!AllowEditing) if (!AllowEditing)
throw new InvalidOperationException($"Attempted to edit when {nameof(AllowEditing)} is disabled"); throw new InvalidOperationException($"Attempted to edit when {nameof(AllowEditing)} is disabled");
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap ?? beatmapNoDebounce); Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo ?? beatmapInfoNoDebounce);
this.Push(new EditorLoader()); this.Push(new EditorLoader());
} }
/// <summary> /// <summary>
/// Call to make a selection and perform the default action for this SongSelect. /// Call to make a selection and perform the default action for this SongSelect.
/// </summary> /// </summary>
/// <param name="beatmap">An optional beatmap to override the current carousel selection.</param> /// <param name="beatmapInfo">An optional beatmap to override the current carousel selection.</param>
/// <param name="ruleset">An optional ruleset to override the current carousel selection.</param> /// <param name="ruleset">An optional ruleset to override the current carousel selection.</param>
/// <param name="customStartAction">An optional custom action to perform instead of <see cref="OnStart"/>.</param> /// <param name="customStartAction">An optional custom action to perform instead of <see cref="OnStart"/>.</param>
public void FinaliseSelection(BeatmapInfo beatmap = null, RulesetInfo ruleset = null, Action customStartAction = null) public void FinaliseSelection(BeatmapInfo beatmapInfo = null, RulesetInfo ruleset = null, Action customStartAction = null)
{ {
// This is very important as we have not yet bound to screen-level bindables before the carousel load is completed. // This is very important as we have not yet bound to screen-level bindables before the carousel load is completed.
if (!Carousel.BeatmapSetsLoaded) if (!Carousel.BeatmapSetsLoaded)
@ -377,10 +377,10 @@ namespace osu.Game.Screens.Select
// avoid attempting to continue before a selection has been obtained. // avoid attempting to continue before a selection has been obtained.
// this could happen via a user interaction while the carousel is still in a loading state. // this could happen via a user interaction while the carousel is still in a loading state.
if (Carousel.SelectedBeatmap == null) return; if (Carousel.SelectedBeatmapInfo == null) return;
if (beatmap != null) if (beatmapInfo != null)
Carousel.SelectBeatmap(beatmap); Carousel.SelectBeatmap(beatmapInfo);
if (selectionChangedDebounce?.Completed == false) if (selectionChangedDebounce?.Completed == false)
{ {
@ -435,18 +435,18 @@ namespace osu.Game.Screens.Select
} }
// We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds.
private BeatmapInfo beatmapNoDebounce; private BeatmapInfo beatmapInfoNoDebounce;
private RulesetInfo rulesetNoDebounce; private RulesetInfo rulesetNoDebounce;
private void updateSelectedBeatmap(BeatmapInfo beatmap) private void updateSelectedBeatmap(BeatmapInfo beatmapInfo)
{ {
if (beatmap == null && beatmapNoDebounce == null) if (beatmapInfo == null && beatmapInfoNoDebounce == null)
return; return;
if (beatmap?.Equals(beatmapNoDebounce) == true) if (beatmapInfo?.Equals(beatmapInfoNoDebounce) == true)
return; return;
beatmapNoDebounce = beatmap; beatmapInfoNoDebounce = beatmapInfo;
performUpdateSelected(); performUpdateSelected();
} }
@ -467,12 +467,12 @@ namespace osu.Game.Screens.Select
/// </summary> /// </summary>
private void performUpdateSelected() private void performUpdateSelected()
{ {
var beatmap = beatmapNoDebounce; var beatmap = beatmapInfoNoDebounce;
var ruleset = rulesetNoDebounce; var ruleset = rulesetNoDebounce;
selectionChangedDebounce?.Cancel(); selectionChangedDebounce?.Cancel();
if (beatmapNoDebounce == null) if (beatmapInfoNoDebounce == null)
run(); run();
else else
selectionChangedDebounce = Scheduler.AddDelayed(run, 200); selectionChangedDebounce = Scheduler.AddDelayed(run, 200);
@ -803,11 +803,11 @@ namespace osu.Game.Screens.Select
dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap));
} }
private void clearScores(BeatmapInfo beatmap) private void clearScores(BeatmapInfo beatmapInfo)
{ {
if (beatmap == null || beatmap.ID <= 0) return; if (beatmapInfo == null || beatmapInfo.ID <= 0) return;
dialogOverlay?.Push(new BeatmapClearScoresDialog(beatmap, () => dialogOverlay?.Push(new BeatmapClearScoresDialog(beatmapInfo, () =>
// schedule done here rather than inside the dialog as the dialog may fade out and never callback. // schedule done here rather than inside the dialog as the dialog may fade out and never callback.
Schedule(() => BeatmapDetails.Refresh()))); Schedule(() => BeatmapDetails.Refresh())));
} }

View File

@ -20,8 +20,8 @@ namespace osu.Game.Skinning
protected override bool AllowManiaSkin => false; protected override bool AllowManiaSkin => false;
protected override bool UseCustomSampleBanks => true; protected override bool UseCustomSampleBanks => true;
public LegacyBeatmapSkin(BeatmapInfo beatmap, IResourceStore<byte[]> storage, IStorageResourceProvider resources) public LegacyBeatmapSkin(BeatmapInfo beatmapInfo, IResourceStore<byte[]> storage, IStorageResourceProvider resources)
: base(createSkinInfo(beatmap), new LegacySkinResourceStore<BeatmapSetFileInfo>(beatmap.BeatmapSet, storage), resources, beatmap.Path) : base(createSkinInfo(beatmapInfo), new LegacySkinResourceStore<BeatmapSetFileInfo>(beatmapInfo.BeatmapSet, storage), resources, beatmapInfo.Path)
{ {
// Disallow default colours fallback on beatmap skins to allow using parent skin combo colours. (via SkinProvidingContainer) // Disallow default colours fallback on beatmap skins to allow using parent skin combo colours. (via SkinProvidingContainer)
Configuration.AllowDefaultComboColoursFallback = false; Configuration.AllowDefaultComboColoursFallback = false;
@ -76,7 +76,7 @@ namespace osu.Game.Skinning
return base.GetSample(sampleInfo); return base.GetSample(sampleInfo);
} }
private static SkinInfo createSkinInfo(BeatmapInfo beatmap) => private static SkinInfo createSkinInfo(BeatmapInfo beatmapInfo) =>
new SkinInfo { Name = beatmap.ToString(), Creator = beatmap.Metadata?.AuthorString }; new SkinInfo { Name = beatmapInfo.ToString(), Creator = beatmapInfo.Metadata?.AuthorString };
} }
} }

View File

@ -111,8 +111,8 @@ namespace osu.Game.Tests.Beatmaps
public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.DarkGoldenrod; public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.DarkGoldenrod;
public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) public TestBeatmapSkin(BeatmapInfo beatmapInfo, bool hasColours)
: base(beatmap, new ResourceStore<byte[]>(), null) : base(beatmapInfo, new ResourceStore<byte[]>(), null)
{ {
if (hasColours) if (hasColours)
{ {

View File

@ -27,13 +27,13 @@ namespace osu.Game.Users
public abstract class InGame : UserActivity public abstract class InGame : UserActivity
{ {
public BeatmapInfo Beatmap { get; } public BeatmapInfo BeatmapInfo { get; }
public RulesetInfo Ruleset { get; } public RulesetInfo Ruleset { get; }
protected InGame(BeatmapInfo info, RulesetInfo ruleset) protected InGame(BeatmapInfo beatmapInfo, RulesetInfo ruleset)
{ {
Beatmap = info; BeatmapInfo = beatmapInfo;
Ruleset = ruleset; Ruleset = ruleset;
} }
@ -42,8 +42,8 @@ namespace osu.Game.Users
public class InMultiplayerGame : InGame public class InMultiplayerGame : InGame
{ {
public InMultiplayerGame(BeatmapInfo beatmap, RulesetInfo ruleset) public InMultiplayerGame(BeatmapInfo beatmapInfo, RulesetInfo ruleset)
: base(beatmap, ruleset) : base(beatmapInfo, ruleset)
{ {
} }
@ -52,27 +52,27 @@ namespace osu.Game.Users
public class InPlaylistGame : InGame public class InPlaylistGame : InGame
{ {
public InPlaylistGame(BeatmapInfo beatmap, RulesetInfo ruleset) public InPlaylistGame(BeatmapInfo beatmapInfo, RulesetInfo ruleset)
: base(beatmap, ruleset) : base(beatmapInfo, ruleset)
{ {
} }
} }
public class InSoloGame : InGame public class InSoloGame : InGame
{ {
public InSoloGame(BeatmapInfo info, RulesetInfo ruleset) public InSoloGame(BeatmapInfo beatmapInfo, RulesetInfo ruleset)
: base(info, ruleset) : base(beatmapInfo, ruleset)
{ {
} }
} }
public class Editing : UserActivity public class Editing : UserActivity
{ {
public BeatmapInfo Beatmap { get; } public BeatmapInfo BeatmapInfo { get; }
public Editing(BeatmapInfo info) public Editing(BeatmapInfo info)
{ {
Beatmap = info; BeatmapInfo = info;
} }
public override string Status => @"Editing a beatmap"; public override string Status => @"Editing a beatmap";