// Copyright (c) ppy Pty Ltd . 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.Bindables; using osu.Framework.Logging; using osu.Game.Beatmaps; namespace osu.Game.Online.Rooms { public class MultiplayerBeatmapTracker : DownloadTrackingComposite { public readonly IBindable SelectedItem = new Bindable(); /// /// The availability state of the currently selected playlist item. /// public IBindable Availability => availability; private readonly Bindable availability = new Bindable(); public MultiplayerBeatmapTracker() { State.BindValueChanged(_ => updateAvailability()); Progress.BindValueChanged(_ => updateAvailability()); updateAvailability(); } protected override void LoadComplete() { base.LoadComplete(); SelectedItem.BindValueChanged(item => Model.Value = item.NewValue?.Beatmap.Value.BeatmapSet, true); } protected override bool VerifyDatabasedModel(BeatmapSetInfo databasedSet) { var verified = verifyDatabasedModel(databasedSet); if (!verified) Logger.Log("The imported beatmapset does not match the online version.", LoggingTarget.Runtime, LogLevel.Important); return verified; } private bool verifyDatabasedModel(BeatmapSetInfo databasedSet) { int? beatmapId = SelectedItem.Value.Beatmap.Value.OnlineBeatmapID; string checksum = SelectedItem.Value.Beatmap.Value.MD5Hash; BeatmapInfo matchingBeatmap; if (databasedSet.Beatmaps == null) { // The given databased beatmap set is not passed in a usable state to check with. // Perform a full query instead, as per https://github.com/ppy/osu/pull/11415. matchingBeatmap = Manager.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId && b.MD5Hash == checksum); return matchingBeatmap != null; } matchingBeatmap = databasedSet.Beatmaps.FirstOrDefault(b => b.OnlineBeatmapID == beatmapId && b.MD5Hash == checksum); return matchingBeatmap != null; } protected override bool IsModelAvailableLocally() { int? beatmapId = SelectedItem.Value.Beatmap.Value.OnlineBeatmapID; string checksum = SelectedItem.Value.Beatmap.Value.MD5Hash; var beatmap = Manager.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId && b.MD5Hash == checksum); return beatmap?.BeatmapSet.DeletePending == false; } private void updateAvailability() { switch (State.Value) { case DownloadState.NotDownloaded: availability.Value = BeatmapAvailability.NotDownloaded(); break; case DownloadState.Downloading: availability.Value = BeatmapAvailability.Downloading((float)Progress.Value); break; case DownloadState.Importing: availability.Value = BeatmapAvailability.Importing(); break; case DownloadState.LocallyAvailable: availability.Value = BeatmapAvailability.LocallyAvailable(); break; default: throw new ArgumentOutOfRangeException(nameof(State)); } } } }