diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index b0376b547d..20bf2ee5c7 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -9,7 +9,6 @@ using osu.Game.Replays; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Replays; -using osu.Game.Users; namespace osu.Game.Rulesets.Catch.Replays { @@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Replays public CatchAutoGenerator(Beatmap beatmap) : base(beatmap) { - Replay = new Replay { User = new User { Username = @"Autoplay" } }; + Replay = new Replay(); } protected Replay Replay; diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 52672e6f17..c58d66c66a 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -8,7 +8,6 @@ using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; -using osu.Game.Users; namespace osu.Game.Rulesets.Mania.Replays { @@ -23,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Replays public ManiaAutoGenerator(ManiaBeatmap beatmap) : base(beatmap) { - Replay = new Replay { User = new User { Username = @"Autoplay" } }; + Replay = new Replay(); columnActions = new ManiaAction[Beatmap.TotalColumns]; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs index ce5d3dae44..7ef01e075c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Scoring; +using osu.Game.Users; namespace osu.Game.Rulesets.Osu.Mods { @@ -17,6 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods protected override Score CreateReplayScore(Beatmap beatmap) => new Score { + ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } }, Replay = new OsuAutoGenerator(beatmap).Generate() }; } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 12d130ef53..6dc5e42258 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using osu.Game.Replays; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Replays; -using osu.Game.Users; namespace osu.Game.Rulesets.Osu.Replays { @@ -38,13 +37,7 @@ namespace osu.Game.Rulesets.Osu.Replays protected OsuAutoGeneratorBase(Beatmap beatmap) : base(beatmap) { - Replay = new Replay - { - User = new User - { - Username = @"Autoplay", - } - }; + Replay = new Replay(); // We are using ApplyModsToRate and not ApplyModsToTime to counteract the speed up / slow down from HalfTime / DoubleTime so that we remain at a constant framerate of 60 fps. FrameDelay = ApplyModsToRate(1000.0 / 60.0); diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index f089877f38..2794a3c166 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -9,7 +9,6 @@ using osu.Game.Replays; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Replays; -using osu.Game.Users; namespace osu.Game.Rulesets.Taiko.Replays { @@ -20,13 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Replays public TaikoAutoGenerator(Beatmap beatmap) : base(beatmap) { - Replay = new Replay - { - User = new User - { - Username = @"Autoplay", - } - }; + Replay = new Replay(); } protected Replay Replay; diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index fb6f735d2d..26167cb24a 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Beatmaps.IO int fireCount = 0; // ReSharper disable once AccessToModifiedClosure - manager.ItemAdded += (_, __) => fireCount++; + manager.ItemAdded += (_, __, ___) => fireCount++; manager.ItemRemoved += _ => fireCount++; var imported = loadOszIntoOsu(osu); diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index 1f2d99a7d8..e0ea613534 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Linq; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Scoring; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual @@ -19,13 +20,10 @@ namespace osu.Game.Tests.Visual Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(Beatmap.Value); - // We have the replay - var replay = dummyRulesetContainer.Replay; - // Reset the mods Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); - return new ReplayPlayer(replay); + return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.Replay }); } } } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index f1920b43cc..baeeaf81a4 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -78,7 +78,7 @@ namespace osu.Game.Beatmaps.Drawables } } - private void setAdded(BeatmapSetInfo s, bool existing) => Schedule(() => + private void setAdded(BeatmapSetInfo s, bool existing, bool silent) => Schedule(() => { if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) DownloadState.Value = DownloadStatus.Downloaded; diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index a7c2aad260..50767608af 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -32,7 +32,7 @@ namespace osu.Game.Database where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { - public delegate void ItemAddedDelegate(TModel model, bool existing); + public delegate void ItemAddedDelegate(TModel model, bool existing, bool silent); /// /// Set an endpoint for notifications to be posted to. @@ -110,7 +110,7 @@ namespace osu.Game.Database ContextFactory = contextFactory; ModelStore = modelStore; - ModelStore.ItemAdded += s => handleEvent(() => ItemAdded?.Invoke(s, false)); + ModelStore.ItemAdded += (item, silent) => handleEvent(() => ItemAdded?.Invoke(item, false, silent)); ModelStore.ItemRemoved += s => handleEvent(() => ItemRemoved?.Invoke(s)); Files = new FileStore(contextFactory, storage); @@ -211,7 +211,7 @@ namespace osu.Game.Database model.Hash = computeHash(archive); - return Import(model, archive); + return Import(model, false, archive); } catch (Exception e) { @@ -245,8 +245,9 @@ namespace osu.Game.Database /// Import an item from a . /// /// The model to be imported. + /// Whether the user should be notified fo the import. /// An optional archive to use for model population. - public TModel Import(TModel item, ArchiveReader archive = null) + public TModel Import(TModel item, bool silent = false, ArchiveReader archive = null) { delayEvents(); @@ -266,7 +267,7 @@ namespace osu.Game.Database { Undelete(existing); Logger.Log($"Found existing {typeof(TModel)} for {item} (ID {existing.ID}). Skipping import.", LoggingTarget.Database); - handleEvent(() => ItemAdded?.Invoke(existing, true)); + handleEvent(() => ItemAdded?.Invoke(existing, true, silent)); return existing; } @@ -276,7 +277,7 @@ namespace osu.Game.Database Populate(item, archive); // import to store - ModelStore.Add(item); + ModelStore.Add(item, silent); } catch (Exception e) { @@ -507,7 +508,7 @@ namespace osu.Game.Database /// /// The new model proposed for import. Note that has not yet been run on this model. /// An existing model which matches the criteria to skip importing, else null. - protected virtual TModel CheckForExisting(TModel model) => ModelStore.ConsumableItems.FirstOrDefault(b => b.Hash == model.Hash); + protected virtual TModel CheckForExisting(TModel model) => model.Hash == null ? null : ModelStore.ConsumableItems.FirstOrDefault(b => b.Hash == model.Hash); private DbSet queryModel() => ContextFactory.Get().Set(); diff --git a/osu.Game/Database/MutableDatabaseBackedStore.cs b/osu.Game/Database/MutableDatabaseBackedStore.cs index 69a1f57cc4..dc2fe54aac 100644 --- a/osu.Game/Database/MutableDatabaseBackedStore.cs +++ b/osu.Game/Database/MutableDatabaseBackedStore.cs @@ -16,7 +16,9 @@ namespace osu.Game.Database public abstract class MutableDatabaseBackedStore : DatabaseBackedStore where T : class, IHasPrimaryKey, ISoftDelete { - public event Action ItemAdded; + public delegate void ItemAddedDelegate(T model, bool silent); + + public event ItemAddedDelegate ItemAdded; public event Action ItemRemoved; protected MutableDatabaseBackedStore(IDatabaseContextFactory contextFactory, Storage storage = null) @@ -33,7 +35,8 @@ namespace osu.Game.Database /// Add a to the database. /// /// The item to add. - public void Add(T item) + /// Whether the user should be notified of the addition. + public void Add(T item, bool silent) { using (var usage = ContextFactory.GetForWrite()) { @@ -41,7 +44,7 @@ namespace osu.Game.Database context.Attach(item); } - ItemAdded?.Invoke(item); + ItemAdded?.Invoke(item, silent); } /// @@ -54,7 +57,7 @@ namespace osu.Game.Database usage.Context.Update(item); ItemRemoved?.Invoke(item); - ItemAdded?.Invoke(item); + ItemAdded?.Invoke(item, true); } /// @@ -89,7 +92,7 @@ namespace osu.Game.Database item.DeletePending = false; } - ItemAdded?.Invoke(item); + ItemAdded?.Invoke(item, true); return true; } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index eeeb24d7d4..cd40d4793a 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -148,7 +148,7 @@ namespace osu.Game { this.frameworkConfig = frameworkConfig; - ScoreManager.ItemAdded += (score, _) => Schedule(() => LoadScore(score)); + ScoreManager.ItemAdded += (score, _, silent) => Schedule(() => LoadScore(score, silent)); if (!Host.IsPrimaryInstance) { @@ -248,43 +248,69 @@ namespace osu.Game /// The beatmap to show. public void ShowBeatmap(int beatmapId) => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId); - protected void LoadScore(ScoreInfo score) + protected void LoadScore(ScoreInfo score, bool silent) { + if (silent) + return; + scoreLoad?.Cancel(); var menu = intro.ChildScreen; if (menu == null) { - scoreLoad = Schedule(() => LoadScore(score)); + scoreLoad = Schedule(() => LoadScore(score, false)); return; } - if (!menu.IsCurrentScreen) + var databasedScore = ScoreManager.GetScore(score); + var databasedScoreInfo = databasedScore.ScoreInfo; + if (databasedScore.Replay == null) { - menu.MakeCurrent(); - this.Delay(500).Schedule(() => LoadScore(score), out scoreLoad); + Logger.Log("The loaded score has no replay data.", LoggingTarget.Information); return; } - var databasedBeatmap = BeatmapManager.QueryBeatmap(b => b.ID == score.Beatmap.ID); - + var databasedBeatmap = BeatmapManager.QueryBeatmap(b => b.ID == databasedScoreInfo.Beatmap.ID); if (databasedBeatmap == null) + { + Logger.Log("Tried to load a score for a beatmap we don't have!", LoggingTarget.Information); + return; + } + + if (!currentScreen.AllowExternalScreenChange) { notifications.Post(new SimpleNotification { - Text = @"Tried to load a score for a beatmap we don't have!", - Icon = FontAwesome.fa_life_saver, + Text = $"Click here to watch {databasedScoreInfo.User.Username} on {databasedScoreInfo.Beatmap}", + Activated = () => + { + loadScore(); + return true; + } }); + return; } - ruleset.Value = score.Ruleset; + loadScore(); - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); - Beatmap.Value.Mods.Value = score.Mods; + void loadScore() + { + if (!menu.IsCurrentScreen) + { + menu.MakeCurrent(); + this.Delay(500).Schedule(loadScore, out scoreLoad); + return; + } - menu.Push(new PlayerLoader(new ReplayPlayer(ScoreManager.GetScore(score).Replay))); + ruleset.Value = databasedScoreInfo.Ruleset; + + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); + Beatmap.Value.Mods.Value = databasedScoreInfo.Mods; + + currentScreen.Push(new PlayerLoader(new ReplayPlayer(databasedScore))); + } } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 5b98d92654..44556a6360 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -174,7 +174,7 @@ namespace osu.Game.Overlays.Direct }; } - private void setAdded(BeatmapSetInfo s, bool existing) => Schedule(() => + private void setAdded(BeatmapSetInfo s, bool existing, bool silent) => Schedule(() => { if (s.OnlineBeatmapSetID == SetInfo.OnlineBeatmapSetID) progressBar.FadeOut(500); diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index a2a835a259..b619abbc2f 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Music [BackgroundDependencyLoader] private void load(BeatmapManager beatmaps, IBindableBeatmap beatmap) { - beatmaps.GetAllUsableBeatmapSets().ForEach(b => addBeatmapSet(b, false)); + beatmaps.GetAllUsableBeatmapSets().ForEach(b => addBeatmapSet(b, false, false)); beatmaps.ItemAdded += addBeatmapSet; beatmaps.ItemRemoved += removeBeatmapSet; @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Music beatmapBacking.ValueChanged += _ => updateSelectedSet(); } - private void addBeatmapSet(BeatmapSetInfo obj, bool existing) => Schedule(() => + private void addBeatmapSet(BeatmapSetInfo obj, bool existing, bool silent) => Schedule(() => { if (existing) return; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 31fceebc93..2dc997d5ed 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -214,7 +214,7 @@ namespace osu.Game.Overlays beatmapSets.Insert(index, beatmapSetInfo); } - private void handleBeatmapAdded(BeatmapSetInfo obj, bool existing) + private void handleBeatmapAdded(BeatmapSetInfo obj, bool existing, bool silent) { if (existing) return; diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index e03bf856c9..23f35d5d3a 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Settings.Sections private void itemRemoved(SkinInfo s) => Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => i.ID != s.ID).ToArray()); - private void itemAdded(SkinInfo s, bool existing) + private void itemAdded(SkinInfo s, bool existing, bool silent) { if (existing) return; diff --git a/osu.Game/Replays/Replay.cs b/osu.Game/Replays/Replay.cs index 966849c783..bb6d9e7637 100644 --- a/osu.Game/Replays/Replay.cs +++ b/osu.Game/Replays/Replay.cs @@ -3,13 +3,11 @@ using System.Collections.Generic; using osu.Game.Rulesets.Replays; -using osu.Game.Users; namespace osu.Game.Replays { public class Replay { - public User User; public List Frames = new List(); } } diff --git a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs index 7fc0d97f9b..13fe021f95 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs @@ -45,7 +45,7 @@ namespace osu.Game.Scoring.Legacy currentBeatmap = workingBeatmap.Beatmap; score.ScoreInfo.Beatmap = currentBeatmap.BeatmapInfo; - score.ScoreInfo.User = score.Replay.User = new User { Username = sr.ReadString() }; + score.ScoreInfo.User = new User { Username = sr.ReadString() }; // MD5Hash sr.ReadString(); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index a2f156f6c3..663f441f2f 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -57,6 +57,8 @@ namespace osu.Game.Scoring public List GetAllUsableScores() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList(); + public IEnumerable QueryScores(Expression> query) => ModelStore.ConsumableItems.AsNoTracking().Where(query); + public ScoreInfo Query(Expression> query) => ModelStore.ConsumableItems.AsNoTracking().FirstOrDefault(query); } } diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index cafd718055..974e42dda0 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -29,6 +29,8 @@ namespace osu.Game.Screens.Menu protected override bool AllowBackButton => buttons.State != ButtonSystemState.Initial; + public override bool AllowExternalScreenChange => true; + private readonly BackgroundScreenDefault background; private Screen songSelect; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 00309fbcd5..69f2b6ef9d 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -34,6 +34,8 @@ namespace osu.Game.Screens protected virtual bool AllowBackButton => true; + public virtual bool AllowExternalScreenChange => false; + /// /// Override to create a BackgroundMode for the current screen. /// Note that the instance created may not be the used instance if it matches the BackgroundMode equality clause. diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 24592ebedc..bf44e9e636 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -67,6 +67,9 @@ namespace osu.Game.Screens.Play /// private DecoupleableInterpolatingFramedClock adjustableClock; + [Resolved] + private ScoreManager scoreManager { get; set; } + private PauseContainer pauseContainer; private RulesetInfo ruleset; @@ -273,13 +276,10 @@ namespace osu.Game.Screens.Play { if (!IsCurrentScreen) return; - var score = new ScoreInfo - { - Beatmap = Beatmap.Value.BeatmapInfo, - Ruleset = ruleset - }; - ScoreProcessor.PopulateScore(score); - score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; + var score = CreateScore(); + if (RulesetContainer.Replay == null) + scoreManager.Import(score, true); + Push(new Results(score)); onCompletionEvent = null; @@ -287,6 +287,20 @@ namespace osu.Game.Screens.Play } } + protected virtual ScoreInfo CreateScore() + { + var score = new ScoreInfo + { + Beatmap = Beatmap.Value.BeatmapInfo, + Ruleset = ruleset, + User = api.LocalUser.Value + }; + + ScoreProcessor.PopulateScore(score); + + return score; + } + private bool onFail() { if (Beatmap.Value.Mods.Value.OfType().Any(m => !m.AllowFail)) diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 9204a49ac9..fe77fd57f2 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -1,23 +1,25 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Replays; +using osu.Game.Scoring; namespace osu.Game.Screens.Play { public class ReplayPlayer : Player { - public Replay Replay; + private readonly Score score; - public ReplayPlayer(Replay replay) + public ReplayPlayer(Score score) { - Replay = replay; + this.score = score; } protected override void LoadComplete() { base.LoadComplete(); - RulesetContainer.SetReplay(Replay); + RulesetContainer.SetReplay(score.Replay); } + + protected override ScoreInfo CreateScore() => score.ScoreInfo; } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 2b94c11bf9..a65cc6f096 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -179,6 +179,9 @@ namespace osu.Game.Screens.Select.Leaderboards private APIAccess api; private BeatmapInfo beatmap; + [Resolved] + private ScoreManager scoreManager { get; set; } + private ScheduledDelegate pendingUpdateScores; public BeatmapInfo Beatmap @@ -216,6 +219,8 @@ namespace osu.Game.Screens.Select.Leaderboards api.OnStateChange -= handleApiStateChange; } + public void RefreshScores() => updateScores(); + private GetScoresRequest getScoresRequest; private void handleApiStateChange(APIState oldState, APIState newState) @@ -242,8 +247,8 @@ namespace osu.Game.Screens.Select.Leaderboards { if (Scope == LeaderboardScope.Local) { - // TODO: get local scores from wherever here. - PlaceholderState = PlaceholderState.NoScores; + Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray(); + PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; return; } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 1a405190e7..b5d333aee4 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -108,6 +108,8 @@ namespace osu.Game.Screens.Select removeAutoModOnResume = false; } + BeatmapDetails.Leaderboard.RefreshScores(); + Beatmap.Value.Track.Looping = true; base.OnResuming(last); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 360032c37c..f4af4f9068 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -40,6 +40,8 @@ namespace osu.Game.Screens.Select protected virtual bool ShowFooter => true; + public override bool AllowExternalScreenChange => true; + /// /// Can be null if is false. /// @@ -503,7 +505,7 @@ namespace osu.Game.Screens.Select } } - private void onBeatmapSetAdded(BeatmapSetInfo s, bool existing) => Carousel.UpdateBeatmapSet(s); + private void onBeatmapSetAdded(BeatmapSetInfo s, bool existing, bool silent) => Carousel.UpdateBeatmapSet(s); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));