1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 12:23:21 +08:00

Make DrawableRoomPlaylistItem look up the online beatmap

This commit is contained in:
Dan Balasescu 2022-02-15 23:11:33 +09:00
parent 73ce1b324e
commit afcb7a4630
2 changed files with 57 additions and 68 deletions

View File

@ -78,7 +78,7 @@ namespace osu.Game.Online.Rooms
// handles changes to hash that didn't occur from the import process (ie. a user editing the beatmap in the editor, somehow). // handles changes to hash that didn't occur from the import process (ie. a user editing the beatmap in the editor, somehow).
realmSubscription?.Dispose(); realmSubscription?.Dispose();
realmSubscription = realm.RegisterForNotifications(r => filteredBeatmaps(), (items, changes, ___) => realmSubscription = realm.RegisterForNotifications(r => QueryBeatmapForOnlinePlay(r, SelectedItem.Value.Beatmap.Value), (items, changes, ___) =>
{ {
if (changes == null) if (changes == null)
return; return;
@ -108,12 +108,12 @@ namespace osu.Game.Online.Rooms
break; break;
case DownloadState.LocallyAvailable: case DownloadState.LocallyAvailable:
bool hashMatches = filteredBeatmaps().Any(); bool available = QueryBeatmapForOnlinePlay(realm.Realm, SelectedItem.Value.Beatmap.Value).Any();
availability.Value = hashMatches ? BeatmapAvailability.LocallyAvailable() : BeatmapAvailability.NotDownloaded(); availability.Value = available ? BeatmapAvailability.LocallyAvailable() : BeatmapAvailability.NotDownloaded();
// only display a message to the user if a download seems to have just completed. // only display a message to the user if a download seems to have just completed.
if (!hashMatches && downloadTracker.Progress.Value == 1) if (!available && downloadTracker.Progress.Value == 1)
Logger.Log("The imported beatmap set does not match the online version.", LoggingTarget.Runtime, LogLevel.Important); Logger.Log("The imported beatmap set does not match the online version.", LoggingTarget.Runtime, LogLevel.Important);
break; break;
@ -123,14 +123,15 @@ namespace osu.Game.Online.Rooms
} }
} }
private IQueryable<BeatmapInfo> filteredBeatmaps() /// <summary>
/// Performs a query for a local <see cref="BeatmapInfo"/> matching a requested one for the purpose of online play.
/// </summary>
/// <param name="realm">The realm to query from.</param>
/// <param name="beatmap">The requested beatmap.</param>
/// <returns>A beatmap query.</returns>
public static IQueryable<BeatmapInfo> QueryBeatmapForOnlinePlay(Realm realm, IBeatmapInfo beatmap)
{ {
int onlineId = SelectedItem.Value.Beatmap.Value.OnlineID; return realm.All<BeatmapInfo>().Filter("OnlineID == $0 && MD5Hash == $1 && BeatmapSet.DeletePending == false", beatmap.OnlineID, beatmap.MD5Hash);
string checksum = SelectedItem.Value.Beatmap.Value.MD5Hash;
return realm.Realm
.All<BeatmapInfo>()
.Filter("OnlineID == $0 && MD5Hash == $1 && BeatmapSet.DeletePending == false", onlineId, checksum);
} }
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -25,7 +24,6 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online; using osu.Game.Online;
using osu.Game.Online.Chat; using osu.Game.Online.Chat;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Overlays.BeatmapSet; using osu.Game.Overlays.BeatmapSet;
using osu.Game.Rulesets; using osu.Game.Rulesets;
@ -68,8 +66,8 @@ namespace osu.Game.Screens.OnlinePlay
private readonly DelayedLoadWrapper onScreenLoader = new DelayedLoadWrapper(Empty) { RelativeSizeAxes = Axes.Both }; private readonly DelayedLoadWrapper onScreenLoader = new DelayedLoadWrapper(Empty) { RelativeSizeAxes = Axes.Both };
private readonly IBindable<bool> valid = new Bindable<bool>(); private readonly IBindable<bool> valid = new Bindable<bool>();
private readonly Bindable<IBeatmapInfo> beatmap = new Bindable<IBeatmapInfo>();
private IBeatmapInfo beatmap;
private IRulesetInfo ruleset; private IRulesetInfo ruleset;
private Mod[] requiredMods; private Mod[] requiredMods;
@ -96,13 +94,12 @@ namespace osu.Game.Screens.OnlinePlay
[Resolved] [Resolved]
private UserLookupCache userLookupCache { get; set; } private UserLookupCache userLookupCache { get; set; }
[CanBeNull]
[Resolved(CanBeNull = true)]
private MultiplayerClient multiplayerClient { get; set; }
[Resolved] [Resolved]
private BeatmapLookupCache beatmapLookupCache { get; set; } private BeatmapLookupCache beatmapLookupCache { get; set; }
[Resolved]
private RealmAccess realm { get; set; }
protected override bool ShouldBeConsideredForInput(Drawable child) => AllowReordering || AllowDeletion || !AllowSelection || SelectedItem.Value == Model; protected override bool ShouldBeConsideredForInput(Drawable child) => AllowReordering || AllowDeletion || !AllowSelection || SelectedItem.Value == Model;
public DrawableRoomPlaylistItem(PlaylistItem item) public DrawableRoomPlaylistItem(PlaylistItem item)
@ -110,7 +107,6 @@ namespace osu.Game.Screens.OnlinePlay
{ {
Item = item; Item = item;
beatmap.BindTo(item.Beatmap);
valid.BindTo(item.Valid); valid.BindTo(item.Valid);
if (item.Expired) if (item.Expired)
@ -151,7 +147,6 @@ namespace osu.Game.Screens.OnlinePlay
maskingContainer.BorderThickness = isCurrent ? 5 : 0; maskingContainer.BorderThickness = isCurrent ? 5 : 0;
}, true); }, true);
beatmap.BindValueChanged(_ => Scheduler.AddOnce(refresh));
valid.BindValueChanged(_ => Scheduler.AddOnce(refresh)); valid.BindValueChanged(_ => Scheduler.AddOnce(refresh));
onScreenLoader.DelayedLoadStarted += _ => onScreenLoader.DelayedLoadStarted += _ =>
@ -166,19 +161,9 @@ namespace osu.Game.Screens.OnlinePlay
Schedule(() => ownerAvatar.User = foundUser); Schedule(() => ownerAvatar.User = foundUser);
} }
if (Item.Beatmap.Value == null) beatmap = await beatmapLookupCache.GetBeatmapAsync(Item.Beatmap.Value.OnlineID).ConfigureAwait(false);
{
IBeatmapInfo foundBeatmap;
if (multiplayerClient != null) Scheduler.AddOnce(refresh);
// This call can eventually go away (and use the else case below).
// Currently required only due to the method being overridden to provide special behaviour in tests.
foundBeatmap = await multiplayerClient.GetAPIBeatmap(Item.BeatmapID).ConfigureAwait(false);
else
foundBeatmap = await beatmapLookupCache.GetBeatmapAsync(Item.BeatmapID).ConfigureAwait(false);
Schedule(() => Item.Beatmap.Value = foundBeatmap);
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -280,18 +265,18 @@ namespace osu.Game.Screens.OnlinePlay
maskingContainer.BorderColour = colours.Red; maskingContainer.BorderColour = colours.Red;
} }
if (Item.Beatmap.Value != null) if (beatmap != null)
difficultyIconContainer.Child = new DifficultyIcon(Item.Beatmap.Value, ruleset, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(icon_height) }; difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(icon_height) };
else else
difficultyIconContainer.Clear(); difficultyIconContainer.Clear();
panelBackground.Beatmap.Value = Item.Beatmap.Value; panelBackground.Beatmap.Value = beatmap;
beatmapText.Clear(); beatmapText.Clear();
if (Item.Beatmap.Value != null) if (beatmap != null)
{ {
beatmapText.AddLink(Item.Beatmap.Value.GetDisplayTitleRomanisable(), LinkAction.OpenBeatmap, Item.Beatmap.Value.OnlineID.ToString(), null, text => beatmapText.AddLink(beatmap.GetDisplayTitleRomanisable(), LinkAction.OpenBeatmap, beatmap.OnlineID.ToString(), null, text =>
{ {
text.Truncate = true; text.Truncate = true;
}); });
@ -299,13 +284,13 @@ namespace osu.Game.Screens.OnlinePlay
authorText.Clear(); authorText.Clear();
if (!string.IsNullOrEmpty(Item.Beatmap.Value?.Metadata.Author.Username)) if (!string.IsNullOrEmpty(beatmap?.Metadata.Author.Username))
{ {
authorText.AddText("mapped by "); authorText.AddText("mapped by ");
authorText.AddUserLink(Item.Beatmap.Value.Metadata.Author); authorText.AddUserLink(beatmap.Metadata.Author);
} }
bool hasExplicitContent = (Item.Beatmap.Value?.BeatmapSet as IBeatmapSetOnlineInfo)?.HasExplicitContent == true; bool hasExplicitContent = (beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.HasExplicitContent == true;
explicitContentPill.Alpha = hasExplicitContent ? 1 : 0; explicitContentPill.Alpha = hasExplicitContent ? 1 : 0;
modDisplay.Current.Value = requiredMods.ToArray(); modDisplay.Current.Value = requiredMods.ToArray();
@ -448,31 +433,34 @@ namespace osu.Game.Screens.OnlinePlay
}; };
} }
private IEnumerable<Drawable> createButtons() => new[] private IEnumerable<Drawable> createButtons()
{ {
showResultsButton = new GrayButton(FontAwesome.Solid.ChartPie) return new[]
{ {
Size = new Vector2(30, 30), showResultsButton = new GrayButton(FontAwesome.Solid.ChartPie)
Action = () => RequestResults?.Invoke(Item), {
Alpha = AllowShowingResults ? 1 : 0, Size = new Vector2(30, 30),
TooltipText = "View results" Action = () => RequestResults?.Invoke(Item),
}, Alpha = AllowShowingResults ? 1 : 0,
Item.Beatmap.Value == null ? Empty() : new PlaylistDownloadButton(Item), TooltipText = "View results"
editButton = new PlaylistEditButton },
{ OnlinePlayBeatmapAvailabilityTracker.QueryBeatmapForOnlinePlay(realm.Realm, beatmap).Any() ? Empty() : new PlaylistDownloadButton(beatmap),
Size = new Vector2(30, 30), editButton = new PlaylistEditButton
Alpha = AllowEditing ? 1 : 0, {
Action = () => RequestEdit?.Invoke(Item), Size = new Vector2(30, 30),
TooltipText = "Edit" Alpha = AllowEditing ? 1 : 0,
}, Action = () => RequestEdit?.Invoke(Item),
removeButton = new PlaylistRemoveButton TooltipText = "Edit"
{ },
Size = new Vector2(30, 30), removeButton = new PlaylistRemoveButton
Alpha = AllowDeletion ? 1 : 0, {
Action = () => RequestDeletion?.Invoke(Item), Size = new Vector2(30, 30),
TooltipText = "Remove from playlist" Alpha = AllowDeletion ? 1 : 0,
}, Action = () => RequestDeletion?.Invoke(Item),
}; TooltipText = "Remove from playlist"
},
};
}
protected override bool OnClick(ClickEvent e) protected override bool OnClick(ClickEvent e)
{ {
@ -499,7 +487,7 @@ namespace osu.Game.Screens.OnlinePlay
private sealed class PlaylistDownloadButton : BeatmapDownloadButton private sealed class PlaylistDownloadButton : BeatmapDownloadButton
{ {
private readonly PlaylistItem playlistItem; private readonly IBeatmapInfo beatmap;
[Resolved] [Resolved]
private BeatmapManager beatmapManager { get; set; } private BeatmapManager beatmapManager { get; set; }
@ -509,10 +497,10 @@ namespace osu.Game.Screens.OnlinePlay
private const float width = 50; private const float width = 50;
public PlaylistDownloadButton(PlaylistItem playlistItem) public PlaylistDownloadButton(IBeatmapInfo beatmap)
: base(playlistItem.Beatmap.Value.BeatmapSet) : base(beatmap.BeatmapSet)
{ {
this.playlistItem = playlistItem; this.beatmap = beatmap;
Size = new Vector2(width, 30); Size = new Vector2(width, 30);
Alpha = 0; Alpha = 0;
@ -532,7 +520,7 @@ namespace osu.Game.Screens.OnlinePlay
{ {
case DownloadState.LocallyAvailable: case DownloadState.LocallyAvailable:
// Perform a local query of the beatmap by beatmap checksum, and reset the state if not matching. // Perform a local query of the beatmap by beatmap checksum, and reset the state if not matching.
if (beatmapManager.QueryBeatmap(b => b.MD5Hash == playlistItem.Beatmap.Value.MD5Hash) == null) if (beatmapManager.QueryBeatmap(b => b.MD5Hash == beatmap.MD5Hash) == null)
State.Value = DownloadState.NotDownloaded; State.Value = DownloadState.NotDownloaded;
else else
{ {