Path: blob/master/osu.Game/Database/MissingBeatmapNotification.cs
2272 views
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables.Cards; using osu.Game.Configuration; using osu.Game.IO.Archives; using osu.Game.Localisation; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Notifications; using osu.Game.Scoring; using Realms; namespace osu.Game.Database { public partial class MissingBeatmapNotification : SimpleNotification { [Resolved] private BeatmapModelDownloader beatmapDownloader { get; set; } = null!; [Resolved] private ScoreManager scoreManager { get; set; } = null!; [Resolved] private RealmAccess realm { get; set; } = null!; private readonly ArchiveReader? scoreArchive; private readonly APIBeatmapSet beatmapSetInfo; private readonly string beatmapHash; private Bindable<bool> autoDownloadConfig = null!; private Bindable<bool> noVideoSetting = null!; private BeatmapCardNano card = null!; private IDisposable? realmSubscription; /// <summary> /// Creates a new notification about a missing beatmap that needs to be downloaded to proceed with an action. /// </summary> /// <param name="beatmap">The online-retrieved beatmap to download.</param> /// <param name="beatmapHash">The hash of the beatmap that is required to proceed.</param> /// <param name="scoreArchive">Optional archive with a score. If not <see langword="null"/>, a re-import of this archive will be attempted after the missing beatmap is downloaded.</param> public MissingBeatmapNotification(APIBeatmap beatmap, string beatmapHash, ArchiveReader? scoreArchive) { beatmapSetInfo = beatmap.BeatmapSet!; this.beatmapHash = beatmapHash; this.scoreArchive = scoreArchive; } [BackgroundDependencyLoader] private void load(OsuConfigManager config) { realmSubscription = realm.RegisterForNotifications( realm => realm.All<BeatmapSetInfo>().Where(s => !s.DeletePending), beatmapsChanged); autoDownloadConfig = config.GetBindable<bool>(OsuSetting.AutomaticallyDownloadMissingBeatmaps); noVideoSetting = config.GetBindable<bool>(OsuSetting.PreferNoVideo); Content.Add(card = new BeatmapCardNano(beatmapSetInfo)); } protected override void LoadComplete() { base.LoadComplete(); if (autoDownloadConfig.Value) { Text = NotificationsStrings.DownloadingBeatmapForReplay; beatmapDownloader.Download(beatmapSetInfo, noVideoSetting.Value); } else { bool missingSetMatchesExistingOnlineId = realm.Run(r => r.All<BeatmapSetInfo>().Any(s => !s.DeletePending && s.OnlineID == beatmapSetInfo.OnlineID)); Text = missingSetMatchesExistingOnlineId ? NotificationsStrings.MismatchingBeatmapForReplay : NotificationsStrings.MissingBeatmapForReplay; } } protected override void Update() { base.Update(); card.Width = Content.DrawWidth; } private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes) { if (changes?.InsertedIndices == null) return; if (sender.Any(s => s.Beatmaps.Any(b => b.MD5Hash == beatmapHash))) { if (scoreArchive != null) { string name = scoreArchive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)); var importTask = new ImportTask(scoreArchive.GetStream(name), name); scoreManager.Import(new[] { importTask }); } realmSubscription?.Dispose(); Close(false); } } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); realmSubscription?.Dispose(); } } }