1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 11:37:28 +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).
realmSubscription?.Dispose();
realmSubscription = realm.RegisterForNotifications(r => filteredBeatmaps(), (items, changes, ___) =>
realmSubscription = realm.RegisterForNotifications(r => QueryBeatmapForOnlinePlay(r, SelectedItem.Value.Beatmap.Value), (items, changes, ___) =>
{
if (changes == null)
return;
@ -108,12 +108,12 @@ namespace osu.Game.Online.Rooms
break;
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.
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);
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;
string checksum = SelectedItem.Value.Beatmap.Value.MD5Hash;
return realm.Realm
.All<BeatmapInfo>()
.Filter("OnlineID == $0 && MD5Hash == $1 && BeatmapSet.DeletePending == false", onlineId, checksum);
return realm.All<BeatmapInfo>().Filter("OnlineID == $0 && MD5Hash == $1 && BeatmapSet.DeletePending == false", beatmap.OnlineID, beatmap.MD5Hash);
}
protected override void Dispose(bool isDisposing)

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -25,7 +24,6 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online;
using osu.Game.Online.Chat;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.BeatmapSet;
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 IBindable<bool> valid = new Bindable<bool>();
private readonly Bindable<IBeatmapInfo> beatmap = new Bindable<IBeatmapInfo>();
private IBeatmapInfo beatmap;
private IRulesetInfo ruleset;
private Mod[] requiredMods;
@ -96,13 +94,12 @@ namespace osu.Game.Screens.OnlinePlay
[Resolved]
private UserLookupCache userLookupCache { get; set; }
[CanBeNull]
[Resolved(CanBeNull = true)]
private MultiplayerClient multiplayerClient { get; set; }
[Resolved]
private BeatmapLookupCache beatmapLookupCache { get; set; }
[Resolved]
private RealmAccess realm { get; set; }
protected override bool ShouldBeConsideredForInput(Drawable child) => AllowReordering || AllowDeletion || !AllowSelection || SelectedItem.Value == Model;
public DrawableRoomPlaylistItem(PlaylistItem item)
@ -110,7 +107,6 @@ namespace osu.Game.Screens.OnlinePlay
{
Item = item;
beatmap.BindTo(item.Beatmap);
valid.BindTo(item.Valid);
if (item.Expired)
@ -151,7 +147,6 @@ namespace osu.Game.Screens.OnlinePlay
maskingContainer.BorderThickness = isCurrent ? 5 : 0;
}, true);
beatmap.BindValueChanged(_ => Scheduler.AddOnce(refresh));
valid.BindValueChanged(_ => Scheduler.AddOnce(refresh));
onScreenLoader.DelayedLoadStarted += _ =>
@ -166,19 +161,9 @@ namespace osu.Game.Screens.OnlinePlay
Schedule(() => ownerAvatar.User = foundUser);
}
if (Item.Beatmap.Value == null)
{
IBeatmapInfo foundBeatmap;
beatmap = await beatmapLookupCache.GetBeatmapAsync(Item.Beatmap.Value.OnlineID).ConfigureAwait(false);
if (multiplayerClient != null)
// 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);
}
Scheduler.AddOnce(refresh);
}
catch (Exception e)
{
@ -280,18 +265,18 @@ namespace osu.Game.Screens.OnlinePlay
maskingContainer.BorderColour = colours.Red;
}
if (Item.Beatmap.Value != null)
difficultyIconContainer.Child = new DifficultyIcon(Item.Beatmap.Value, ruleset, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(icon_height) };
if (beatmap != null)
difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(icon_height) };
else
difficultyIconContainer.Clear();
panelBackground.Beatmap.Value = Item.Beatmap.Value;
panelBackground.Beatmap.Value = beatmap;
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;
});
@ -299,13 +284,13 @@ namespace osu.Game.Screens.OnlinePlay
authorText.Clear();
if (!string.IsNullOrEmpty(Item.Beatmap.Value?.Metadata.Author.Username))
if (!string.IsNullOrEmpty(beatmap?.Metadata.Author.Username))
{
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;
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),
Action = () => RequestResults?.Invoke(Item),
Alpha = AllowShowingResults ? 1 : 0,
TooltipText = "View results"
},
Item.Beatmap.Value == null ? Empty() : new PlaylistDownloadButton(Item),
editButton = new PlaylistEditButton
{
Size = new Vector2(30, 30),
Alpha = AllowEditing ? 1 : 0,
Action = () => RequestEdit?.Invoke(Item),
TooltipText = "Edit"
},
removeButton = new PlaylistRemoveButton
{
Size = new Vector2(30, 30),
Alpha = AllowDeletion ? 1 : 0,
Action = () => RequestDeletion?.Invoke(Item),
TooltipText = "Remove from playlist"
},
};
showResultsButton = new GrayButton(FontAwesome.Solid.ChartPie)
{
Size = new Vector2(30, 30),
Action = () => RequestResults?.Invoke(Item),
Alpha = AllowShowingResults ? 1 : 0,
TooltipText = "View results"
},
OnlinePlayBeatmapAvailabilityTracker.QueryBeatmapForOnlinePlay(realm.Realm, beatmap).Any() ? Empty() : new PlaylistDownloadButton(beatmap),
editButton = new PlaylistEditButton
{
Size = new Vector2(30, 30),
Alpha = AllowEditing ? 1 : 0,
Action = () => RequestEdit?.Invoke(Item),
TooltipText = "Edit"
},
removeButton = new PlaylistRemoveButton
{
Size = new Vector2(30, 30),
Alpha = AllowDeletion ? 1 : 0,
Action = () => RequestDeletion?.Invoke(Item),
TooltipText = "Remove from playlist"
},
};
}
protected override bool OnClick(ClickEvent e)
{
@ -499,7 +487,7 @@ namespace osu.Game.Screens.OnlinePlay
private sealed class PlaylistDownloadButton : BeatmapDownloadButton
{
private readonly PlaylistItem playlistItem;
private readonly IBeatmapInfo beatmap;
[Resolved]
private BeatmapManager beatmapManager { get; set; }
@ -509,10 +497,10 @@ namespace osu.Game.Screens.OnlinePlay
private const float width = 50;
public PlaylistDownloadButton(PlaylistItem playlistItem)
: base(playlistItem.Beatmap.Value.BeatmapSet)
public PlaylistDownloadButton(IBeatmapInfo beatmap)
: base(beatmap.BeatmapSet)
{
this.playlistItem = playlistItem;
this.beatmap = beatmap;
Size = new Vector2(width, 30);
Alpha = 0;
@ -532,7 +520,7 @@ namespace osu.Game.Screens.OnlinePlay
{
case DownloadState.LocallyAvailable:
// 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;
else
{