Merge branch 'master' into update-framework

This commit is contained in:
Salman Ahmed 2021-11-04 13:51:57 +03:00 committed by GitHub
commit aa2711e6ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 100 additions and 80 deletions

View File

@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
HasVideo = true, HasVideo = true,
HasStoryboard = true, HasStoryboard = true,
Covers = new BeatmapSetOnlineCovers(), Covers = new BeatmapSetOnlineCovers(),
Beatmaps = new List<APIBeatmap> Beatmaps = new[]
{ {
new APIBeatmap new APIBeatmap
{ {
@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
HasVideo = true, HasVideo = true,
HasStoryboard = true, HasStoryboard = true,
Covers = new BeatmapSetOnlineCovers(), Covers = new BeatmapSetOnlineCovers(),
Beatmaps = beatmaps, Beatmaps = beatmaps.ToArray(),
}; };
} }

View File

@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
{ {
RulesetID = difficulty.rulesetId, RulesetID = difficulty.rulesetId,
StarRating = difficulty.stars StarRating = difficulty.stars
}).ToList() }).ToArray()
}; };
[Test] [Test]

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -37,7 +36,7 @@ namespace osu.Game.Tests.Visual.Online
{ {
selector.BeatmapSet = new APIBeatmapSet selector.BeatmapSet = new APIBeatmapSet
{ {
Beatmaps = enabledRulesets.Select(r => new APIBeatmap { RulesetID = r.OnlineID }).ToList() Beatmaps = enabledRulesets.Select(r => new APIBeatmap { RulesetID = r.OnlineID }).ToArray()
}; };
}); });
@ -55,7 +54,7 @@ namespace osu.Game.Tests.Visual.Online
{ {
selector.BeatmapSet = new APIBeatmapSet selector.BeatmapSet = new APIBeatmapSet
{ {
Beatmaps = new List<APIBeatmap> Beatmaps = new[]
{ {
new APIBeatmap new APIBeatmap
{ {
@ -71,10 +70,7 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestEmptyBeatmapSet() public void TestEmptyBeatmapSet()
{ {
AddStep("load empty beatmapset", () => selector.BeatmapSet = new APIBeatmapSet AddStep("load empty beatmapset", () => selector.BeatmapSet = new APIBeatmapSet());
{
Beatmaps = new List<APIBeatmap>()
});
AddAssert("no ruleset selected", () => selector.SelectedTab == null); AddAssert("no ruleset selected", () => selector.SelectedTab == null);
AddAssert("all rulesets disabled", () => selector.TabContainer.TabItems.All(t => !t.Enabled.Value)); AddAssert("all rulesets disabled", () => selector.TabContainer.TabItems.All(t => !t.Enabled.Value));

View File

@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.Online
Ratings = Enumerable.Range(0, 11).ToArray(), Ratings = Enumerable.Range(0, 11).ToArray(),
HasStoryboard = true, HasStoryboard = true,
Covers = new BeatmapSetOnlineCovers(), Covers = new BeatmapSetOnlineCovers(),
Beatmaps = new List<APIBeatmap> Beatmaps = new[]
{ {
new APIBeatmap new APIBeatmap
{ {
@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.Online
var set = getBeatmapSet(); var set = getBeatmapSet();
set.Beatmaps = beatmaps; set.Beatmaps = beatmaps.ToArray();
overlay.ShowBeatmapSet(set); overlay.ShowBeatmapSet(set);
}); });
@ -211,7 +211,7 @@ namespace osu.Game.Tests.Visual.Online
}); });
} }
set.Beatmaps = beatmaps; set.Beatmaps = beatmaps.ToArray();
return set; return set;
} }

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online
static APIBeatmapSet createSet() => new APIBeatmapSet static APIBeatmapSet createSet() => new APIBeatmapSet
{ {
Beatmaps = new List<APIBeatmap> Beatmaps = new[]
{ {
new APIBeatmap new APIBeatmap
{ {

View File

@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual.Online
HasVideo = true, HasVideo = true,
HasStoryboard = true, HasStoryboard = true,
Covers = new BeatmapSetOnlineCovers(), Covers = new BeatmapSetOnlineCovers(),
Beatmaps = new List<APIBeatmap> Beatmaps = new[]
{ {
new APIBeatmap new APIBeatmap
{ {
@ -129,7 +129,7 @@ namespace osu.Game.Tests.Visual.Online
HasVideo = true, HasVideo = true,
HasStoryboard = true, HasStoryboard = true,
Covers = new BeatmapSetOnlineCovers(), Covers = new BeatmapSetOnlineCovers(),
Beatmaps = beatmaps, Beatmaps = beatmaps.ToArray(),
}; };
} }
} }

View File

@ -186,7 +186,7 @@ namespace osu.Game.Beatmaps
string IBeatmapInfo.DifficultyName => Version; string IBeatmapInfo.DifficultyName => Version;
[JsonIgnore] [JsonIgnore]
IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata; IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata ?? BeatmapSet?.Metadata ?? new BeatmapMetadata();
[JsonIgnore] [JsonIgnore]
IBeatmapDifficultyInfo IBeatmapInfo.Difficulty => BaseDifficulty; IBeatmapDifficultyInfo IBeatmapInfo.Difficulty => BaseDifficulty;

View File

@ -11,14 +11,14 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// A user-presentable display title representing this beatmap. /// A user-presentable display title representing this beatmap.
/// </summary> /// </summary>
public static string GetDisplayTitle(this IBeatmapInfo beatmapInfo) => $"{getClosestMetadata(beatmapInfo)} {getVersionString(beatmapInfo)}".Trim(); public static string GetDisplayTitle(this IBeatmapInfo beatmapInfo) => $"{beatmapInfo.Metadata} {getVersionString(beatmapInfo)}".Trim();
/// <summary> /// <summary>
/// A user-presentable display title representing this beatmap, with localisation handling for potentially romanisable fields. /// A user-presentable display title representing this beatmap, with localisation handling for potentially romanisable fields.
/// </summary> /// </summary>
public static RomanisableString GetDisplayTitleRomanisable(this IBeatmapInfo beatmapInfo, bool includeDifficultyName = true, bool includeCreator = true) public static RomanisableString GetDisplayTitleRomanisable(this IBeatmapInfo beatmapInfo, bool includeDifficultyName = true, bool includeCreator = true)
{ {
var metadata = getClosestMetadata(beatmapInfo).GetDisplayTitleRomanisable(includeCreator); var metadata = beatmapInfo.Metadata.GetDisplayTitleRomanisable(includeCreator);
if (includeDifficultyName) if (includeDifficultyName)
{ {
@ -32,12 +32,8 @@ namespace osu.Game.Beatmaps
public static string[] GetSearchableTerms(this IBeatmapInfo beatmapInfo) => new[] public static string[] GetSearchableTerms(this IBeatmapInfo beatmapInfo) => new[]
{ {
beatmapInfo.DifficultyName beatmapInfo.DifficultyName
}.Concat(getClosestMetadata(beatmapInfo).GetSearchableTerms()).Where(s => !string.IsNullOrEmpty(s)).ToArray(); }.Concat(beatmapInfo.Metadata.GetSearchableTerms()).Where(s => !string.IsNullOrEmpty(s)).ToArray();
private static string getVersionString(IBeatmapInfo beatmapInfo) => string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? string.Empty : $"[{beatmapInfo.DifficultyName}]"; private static string getVersionString(IBeatmapInfo beatmapInfo) => string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? string.Empty : $"[{beatmapInfo.DifficultyName}]";
// temporary helper methods until we figure which metadata should be where.
private static IBeatmapMetadataInfo getClosestMetadata(IBeatmapInfo beatmapInfo) =>
beatmapInfo.Metadata ?? beatmapInfo.BeatmapSet?.Metadata ?? new BeatmapMetadata();
} }
} }

View File

@ -21,7 +21,7 @@ namespace osu.Game.Beatmaps
/// <summary> /// <summary>
/// The metadata representing this beatmap. May be shared between multiple beatmaps. /// The metadata representing this beatmap. May be shared between multiple beatmaps.
/// </summary> /// </summary>
IBeatmapMetadataInfo? Metadata { get; } IBeatmapMetadataInfo Metadata { get; }
/// <summary> /// <summary>
/// The difficulty settings for this beatmap. /// The difficulty settings for this beatmap.

View File

@ -119,7 +119,7 @@ namespace osu.Game.Online.API.Requests.Responses
public string Tags { get; set; } = string.Empty; public string Tags { get; set; } = string.Empty;
[JsonProperty(@"beatmaps")] [JsonProperty(@"beatmaps")]
public IEnumerable<APIBeatmap> Beatmaps { get; set; } = Array.Empty<APIBeatmap>(); public APIBeatmap[] Beatmaps { get; set; } = Array.Empty<APIBeatmap>();
public virtual BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets) public virtual BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets)
{ {

View File

@ -17,6 +17,7 @@ using osu.Framework.Logging;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Online.Rooms.RoomStatuses; using osu.Game.Online.Rooms.RoomStatuses;
using osu.Game.Rulesets; using osu.Game.Rulesets;
@ -644,24 +645,32 @@ namespace osu.Game.Online.Multiplayer
RoomUpdated?.Invoke(); RoomUpdated?.Invoke();
GetOnlineBeatmapSet(settings.BeatmapID, cancellationToken).ContinueWith(set => Schedule(() => GetOnlineBeatmapSet(settings.BeatmapID, cancellationToken).ContinueWith(task => Schedule(() =>
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
return; return;
updatePlaylist(settings, set.Result); APIBeatmapSet beatmapSet = task.Result;
// The incoming response is deserialised without circular reference handling currently.
// Because we require using metadata from this instance, populate the nested beatmaps' sets manually here.
foreach (var b in beatmapSet.Beatmaps)
b.BeatmapSet = beatmapSet;
updatePlaylist(settings, beatmapSet);
}), TaskContinuationOptions.OnlyOnRanToCompletion); }), TaskContinuationOptions.OnlyOnRanToCompletion);
}, cancellationToken); }, cancellationToken);
private void updatePlaylist(MultiplayerRoomSettings settings, BeatmapSetInfo beatmapSet) private void updatePlaylist(MultiplayerRoomSettings settings, APIBeatmapSet beatmapSet)
{ {
if (Room == null || !Room.Settings.Equals(settings)) if (Room == null || !Room.Settings.Equals(settings))
return; return;
Debug.Assert(APIRoom != null); Debug.Assert(APIRoom != null);
var beatmap = beatmapSet.Beatmaps.Single(b => b.OnlineBeatmapID == settings.BeatmapID); var beatmap = beatmapSet.Beatmaps.Single(b => b.OnlineID == settings.BeatmapID);
beatmap.MD5Hash = settings.BeatmapChecksum;
beatmap.Checksum = settings.BeatmapChecksum;
var ruleset = Rulesets.GetRuleset(settings.RulesetID).CreateInstance(); var ruleset = Rulesets.GetRuleset(settings.RulesetID).CreateInstance();
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset)); var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
@ -694,12 +703,12 @@ namespace osu.Game.Online.Multiplayer
} }
/// <summary> /// <summary>
/// Retrieves a <see cref="BeatmapSetInfo"/> from an online source. /// Retrieves a <see cref="APIBeatmapSet"/> from an online source.
/// </summary> /// </summary>
/// <param name="beatmapId">The beatmap set ID.</param> /// <param name="beatmapId">The beatmap set ID.</param>
/// <param name="cancellationToken">A token to cancel the request.</param> /// <param name="cancellationToken">A token to cancel the request.</param>
/// <returns>The <see cref="BeatmapSetInfo"/> retrieval task.</returns> /// <returns>The <see cref="APIBeatmapSet"/> retrieval task.</returns>
protected abstract Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default); protected abstract Task<APIBeatmapSet> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>. /// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.

View File

@ -9,9 +9,9 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client; using Microsoft.AspNetCore.SignalR.Client;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer namespace osu.Game.Online.Multiplayer
@ -148,9 +148,9 @@ namespace osu.Game.Online.Multiplayer
return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch)); return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch));
} }
protected override Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default) protected override Task<APIBeatmapSet> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default)
{ {
var tcs = new TaskCompletionSource<BeatmapSetInfo>(); var tcs = new TaskCompletionSource<APIBeatmapSet>();
var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);
req.Success += res => req.Success += res =>
@ -161,7 +161,7 @@ namespace osu.Game.Online.Multiplayer
return; return;
} }
tcs.SetResult(res.ToBeatmapSet(Rulesets)); tcs.SetResult(res);
}; };
req.Failure += e => tcs.SetException(e); req.Failure += e => tcs.SetException(e);

View File

@ -7,6 +7,7 @@ using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using osu.Game.Beatmaps;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -61,7 +62,7 @@ namespace osu.Game.Online.Rooms
[CanBeNull] [CanBeNull]
public MultiplayerScoresAround ScoresAround { get; set; } public MultiplayerScoresAround ScoresAround { get; set; }
public ScoreInfo CreateScoreInfo(PlaylistItem playlistItem) public ScoreInfo CreateScoreInfo(PlaylistItem playlistItem, [NotNull] BeatmapInfo beatmap)
{ {
var rulesetInstance = playlistItem.Ruleset.Value.CreateInstance(); var rulesetInstance = playlistItem.Ruleset.Value.CreateInstance();
@ -70,7 +71,7 @@ namespace osu.Game.Online.Rooms
OnlineScoreID = ID, OnlineScoreID = ID,
TotalScore = TotalScore, TotalScore = TotalScore,
MaxCombo = MaxCombo, MaxCombo = MaxCombo,
BeatmapInfo = playlistItem.Beatmap.Value, BeatmapInfo = beatmap,
BeatmapInfoID = playlistItem.BeatmapID, BeatmapInfoID = playlistItem.BeatmapID,
Ruleset = playlistItem.Ruleset.Value, Ruleset = playlistItem.Ruleset.Value,
RulesetID = playlistItem.RulesetID, RulesetID = playlistItem.RulesetID,

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Diagnostics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -52,6 +53,8 @@ namespace osu.Game.Online.Rooms
downloadTracker?.RemoveAndDisposeImmediately(); downloadTracker?.RemoveAndDisposeImmediately();
Debug.Assert(item.NewValue.Beatmap.Value.BeatmapSet != null);
downloadTracker = new BeatmapDownloadTracker(item.NewValue.Beatmap.Value.BeatmapSet); downloadTracker = new BeatmapDownloadTracker(item.NewValue.Beatmap.Value.BeatmapSet);
AddInternal(downloadTracker); AddInternal(downloadTracker);

View File

@ -31,7 +31,7 @@ namespace osu.Game.Online.Rooms
public bool Expired { get; set; } public bool Expired { get; set; }
[JsonIgnore] [JsonIgnore]
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>(); public readonly Bindable<IBeatmapInfo> Beatmap = new Bindable<IBeatmapInfo>();
[JsonIgnore] [JsonIgnore]
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>(); public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
@ -65,13 +65,13 @@ namespace osu.Game.Online.Rooms
public PlaylistItem() public PlaylistItem()
{ {
Beatmap.BindValueChanged(beatmap => BeatmapID = beatmap.NewValue?.OnlineBeatmapID ?? 0); Beatmap.BindValueChanged(beatmap => BeatmapID = beatmap.NewValue?.OnlineID ?? -1);
Ruleset.BindValueChanged(ruleset => RulesetID = ruleset.NewValue?.ID ?? 0); Ruleset.BindValueChanged(ruleset => RulesetID = ruleset.NewValue?.ID ?? 0);
} }
public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) public void MapObjects(RulesetStore rulesets)
{ {
Beatmap.Value ??= apiBeatmap.ToBeatmapInfo(rulesets); Beatmap.Value ??= apiBeatmap;
Ruleset.Value ??= rulesets.GetRuleset(RulesetID); Ruleset.Value ??= rulesets.GetRuleset(RulesetID);
Ruleset rulesetInstance = Ruleset.Value.CreateInstance(); Ruleset rulesetInstance = Ruleset.Value.CreateInstance();

View File

@ -147,7 +147,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
{ {
var icons = new List<DifficultyIcon>(); var icons = new List<DifficultyIcon>();
if (SetInfo.Beatmaps.Count() > maximum_difficulty_icons) if (SetInfo.Beatmaps.Length > maximum_difficulty_icons)
{ {
foreach (var ruleset in SetInfo.Beatmaps.Select(b => b.Ruleset).Distinct()) foreach (var ruleset in SetInfo.Beatmaps.Select(b => b.Ruleset).Distinct())
icons.Add(new GroupedDifficultyIcon(SetInfo.Beatmaps.Where(b => b.RulesetID == ruleset.OnlineID).ToList(), ruleset, this is ListBeatmapPanel ? Color4.White : colours.Gray5)); icons.Add(new GroupedDifficultyIcon(SetInfo.Beatmaps.Where(b => b.RulesetID == ruleset.OnlineID).ToList(), ruleset, this is ListBeatmapPanel ? Color4.White : colours.Gray5));

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -61,7 +62,10 @@ namespace osu.Game.Screens.OnlinePlay.Components
{ {
var beatmap = playlistItem?.Beatmap.Value; var beatmap = playlistItem?.Beatmap.Value;
if (background?.BeatmapInfo?.BeatmapSet?.OnlineInfo?.Covers.Cover == beatmap?.BeatmapSet?.OnlineInfo?.Covers.Cover) string? lastCover = (background?.Beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.Covers.Cover;
string? newCover = (beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.Covers.Cover;
if (lastCover == newCover)
return; return;
cancellationSource?.Cancel(); cancellationSource?.Cancel();

View File

@ -13,11 +13,11 @@ namespace osu.Game.Screens.OnlinePlay.Components
{ {
public class PlaylistItemBackground : Background public class PlaylistItemBackground : Background
{ {
public readonly BeatmapInfo? BeatmapInfo; public readonly IBeatmapInfo? Beatmap;
public PlaylistItemBackground(PlaylistItem? playlistItem) public PlaylistItemBackground(PlaylistItem? playlistItem)
{ {
BeatmapInfo = playlistItem?.Beatmap.Value; Beatmap = playlistItem?.Beatmap.Value;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -26,8 +26,8 @@ namespace osu.Game.Screens.OnlinePlay.Components
Texture? texture = null; Texture? texture = null;
// prefer online cover where available. // prefer online cover where available.
if (BeatmapInfo?.BeatmapSet?.OnlineInfo?.Covers.Cover != null) if (Beatmap?.BeatmapSet is IBeatmapSetOnlineInfo online)
texture = textures.Get(BeatmapInfo.BeatmapSet.OnlineInfo.Covers.Cover); texture = textures.Get(online.Covers.Cover);
Sprite.Texture = texture ?? beatmaps.DefaultBeatmap.Background; Sprite.Texture = texture ?? beatmaps.DefaultBeatmap.Background;
} }
@ -38,7 +38,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
if (ReferenceEquals(this, other)) return true; if (ReferenceEquals(this, other)) return true;
return other.GetType() == GetType() return other.GetType() == GetType()
&& ((PlaylistItemBackground)other).BeatmapInfo == BeatmapInfo; && ((PlaylistItemBackground)other).Beatmap == Beatmap;
} }
} }
} }

View File

@ -119,7 +119,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
try try
{ {
foreach (var pi in room.Playlist) foreach (var pi in room.Playlist)
pi.MapObjects(beatmaps, rulesets); pi.MapObjects(rulesets);
var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value); var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value);
if (existing == null) if (existing == null)

View File

@ -80,10 +80,10 @@ namespace osu.Game.Screens.OnlinePlay.Components
private void updateRange(object sender, NotifyCollectionChangedEventArgs e) private void updateRange(object sender, NotifyCollectionChangedEventArgs e)
{ {
var orderedDifficulties = Playlist.Select(p => p.Beatmap.Value).OrderBy(b => b.StarDifficulty).ToArray(); var orderedDifficulties = Playlist.Select(p => p.Beatmap.Value).OrderBy(b => b.StarRating).ToArray();
StarDifficulty minDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[0].StarDifficulty : 0, 0); StarDifficulty minDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[0].StarRating : 0, 0);
StarDifficulty maxDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[^1].StarDifficulty : 0, 0); StarDifficulty maxDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[^1].StarRating : 0, 0);
minDisplay.Current.Value = minDifficulty; minDisplay.Current.Value = minDifficulty;
maxDisplay.Current.Value = maxDifficulty; maxDisplay.Current.Value = maxDifficulty;

View File

@ -27,6 +27,7 @@ using osu.Game.Overlays.BeatmapSet;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
using osu.Game.Users;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -45,7 +46,7 @@ namespace osu.Game.Screens.OnlinePlay
private ExplicitContentBeatmapPill explicitContentPill; private ExplicitContentBeatmapPill explicitContentPill;
private ModDisplay modDisplay; private ModDisplay modDisplay;
private readonly Bindable<BeatmapInfo> beatmap = new Bindable<BeatmapInfo>(); private readonly Bindable<IBeatmapInfo> beatmap = new Bindable<IBeatmapInfo>();
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>(); private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
private readonly BindableList<Mod> requiredMods = new BindableList<Mod>(); private readonly BindableList<Mod> requiredMods = new BindableList<Mod>();
@ -96,6 +97,7 @@ namespace osu.Game.Screens.OnlinePlay
} }
private ScheduledDelegate scheduledRefresh; private ScheduledDelegate scheduledRefresh;
private PanelBackground panelBackground;
private void scheduleRefresh() private void scheduleRefresh()
{ {
@ -105,23 +107,25 @@ namespace osu.Game.Screens.OnlinePlay
private void refresh() private void refresh()
{ {
difficultyIconContainer.Child = new DifficultyIcon(beatmap.Value, ruleset.Value, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(32) }; difficultyIconContainer.Child = new DifficultyIcon(Item.Beatmap.Value, ruleset.Value, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(32) };
panelBackground.Beatmap.Value = Item.Beatmap.Value;
beatmapText.Clear(); beatmapText.Clear();
beatmapText.AddLink(Item.Beatmap.Value.GetDisplayTitleRomanisable(), LinkAction.OpenBeatmap, Item.Beatmap.Value.OnlineBeatmapID.ToString(), null, text => beatmapText.AddLink(Item.Beatmap.Value.GetDisplayTitleRomanisable(), LinkAction.OpenBeatmap, Item.Beatmap.Value.OnlineID.ToString(), null, text =>
{ {
text.Truncate = true; text.Truncate = true;
}); });
authorText.Clear(); authorText.Clear();
if (Item.Beatmap?.Value?.Metadata?.Author != null) if (!string.IsNullOrEmpty(Item.Beatmap.Value?.Metadata.Author))
{ {
authorText.AddText("mapped by "); authorText.AddText("mapped by ");
authorText.AddUserLink(Item.Beatmap.Value?.Metadata.Author); authorText.AddUserLink(new User { Username = Item.Beatmap.Value.Metadata.Author });
} }
bool hasExplicitContent = Item.Beatmap.Value.BeatmapSet.OnlineInfo?.HasExplicitContent == true; bool hasExplicitContent = (Item.Beatmap.Value.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();
@ -145,10 +149,9 @@ namespace osu.Game.Screens.OnlinePlay
Alpha = 0, Alpha = 0,
AlwaysPresent = true AlwaysPresent = true
}, },
new PanelBackground panelBackground = new PanelBackground
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Beatmap = { BindTarget = beatmap }
}, },
new GridContainer new GridContainer
{ {
@ -337,7 +340,7 @@ namespace osu.Game.Screens.OnlinePlay
// For now, this is the same implementation as in PanelBackground, but supports a beatmap info rather than a working beatmap // For now, this is the same implementation as in PanelBackground, but supports a beatmap info rather than a working beatmap
private class PanelBackground : Container // todo: should be a buffered container (https://github.com/ppy/osu-framework/issues/3222) private class PanelBackground : Container // todo: should be a buffered container (https://github.com/ppy/osu-framework/issues/3222)
{ {
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>(); public readonly Bindable<IBeatmapInfo> Beatmap = new Bindable<IBeatmapInfo>();
public PanelBackground() public PanelBackground()
{ {

View File

@ -384,7 +384,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
statusText.Text = "Currently playing "; statusText.Text = "Currently playing ";
beatmapText.AddLink(item.NewValue.Beatmap.Value.GetDisplayTitleRomanisable(), beatmapText.AddLink(item.NewValue.Beatmap.Value.GetDisplayTitleRomanisable(),
LinkAction.OpenBeatmap, LinkAction.OpenBeatmap,
item.NewValue.Beatmap.Value.OnlineBeatmapID.ToString(), item.NewValue.Beatmap.Value.OnlineID.ToString(),
creationParameters: s => creationParameters: s =>
{ {
s.Truncate = true; s.Truncate = true;

View File

@ -369,7 +369,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
var beatmap = SelectedItem.Value?.Beatmap.Value; var beatmap = SelectedItem.Value?.Beatmap.Value;
// Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info
var localBeatmap = beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID); var localBeatmap = beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineID);
Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap);
} }

View File

@ -32,7 +32,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
private void load(IBindable<RulesetInfo> ruleset) private void load(IBindable<RulesetInfo> ruleset)
{ {
// Sanity checks to ensure that PlaylistsPlayer matches the settings for the current PlaylistItem // Sanity checks to ensure that PlaylistsPlayer matches the settings for the current PlaylistItem
if (Beatmap.Value.BeatmapInfo.OnlineBeatmapID != PlaylistItem.Beatmap.Value.OnlineBeatmapID) if (Beatmap.Value.BeatmapInfo.OnlineBeatmapID != PlaylistItem.Beatmap.Value.OnlineID)
throw new InvalidOperationException("Current Beatmap does not match PlaylistItem's Beatmap"); throw new InvalidOperationException("Current Beatmap does not match PlaylistItem's Beatmap");
if (ruleset.Value.ID != PlaylistItem.Ruleset.Value.ID) if (ruleset.Value.ID != PlaylistItem.Ruleset.Value.ID)

View File

@ -169,7 +169,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
/// <param name="pivot">An optional pivot around which the scores were retrieved.</param> /// <param name="pivot">An optional pivot around which the scores were retrieved.</param>
private void performSuccessCallback([NotNull] Action<IEnumerable<ScoreInfo>> callback, [NotNull] List<MultiplayerScore> scores, [CanBeNull] MultiplayerScores pivot = null) private void performSuccessCallback([NotNull] Action<IEnumerable<ScoreInfo>> callback, [NotNull] List<MultiplayerScore> scores, [CanBeNull] MultiplayerScores pivot = null)
{ {
var scoreInfos = scores.Select(s => s.CreateScoreInfo(playlistItem)).ToArray(); var scoreInfos = scores.Select(s => s.CreateScoreInfo(playlistItem, Beatmap.Value.BeatmapInfo)).ToArray();
// Score panels calculate total score before displaying, which can take some time. In order to count that calculation as part of the loading spinner display duration, // Score panels calculate total score before displaying, which can take some time. In order to count that calculation as part of the loading spinner display duration,
// calculate the total scores locally before invoking the success callback. // calculate the total scores locally before invoking the success callback.

View File

@ -18,6 +18,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Spectator; using osu.Game.Online.Spectator;
using osu.Game.Overlays.BeatmapListing.Panels; using osu.Game.Overlays.BeatmapListing.Panels;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
@ -50,7 +51,6 @@ namespace osu.Game.Screens.Play
private Container beatmapPanelContainer; private Container beatmapPanelContainer;
private TriangleButton watchButton; private TriangleButton watchButton;
private SettingsCheckbox automaticDownload; private SettingsCheckbox automaticDownload;
private BeatmapSetInfo onlineBeatmap;
/// <summary> /// <summary>
/// The player's immediate online gameplay state. /// The player's immediate online gameplay state.
@ -60,6 +60,8 @@ namespace osu.Game.Screens.Play
private GetBeatmapSetRequest onlineBeatmapRequest; private GetBeatmapSetRequest onlineBeatmapRequest;
private APIBeatmapSet beatmapSet;
public SoloSpectator([NotNull] User targetUser) public SoloSpectator([NotNull] User targetUser)
: base(targetUser.Id) : base(targetUser.Id)
{ {
@ -220,10 +222,10 @@ namespace osu.Game.Screens.Play
Debug.Assert(state.BeatmapID != null); Debug.Assert(state.BeatmapID != null);
onlineBeatmapRequest = new GetBeatmapSetRequest(state.BeatmapID.Value, BeatmapSetLookupType.BeatmapId); onlineBeatmapRequest = new GetBeatmapSetRequest(state.BeatmapID.Value, BeatmapSetLookupType.BeatmapId);
onlineBeatmapRequest.Success += res => Schedule(() => onlineBeatmapRequest.Success += beatmapSet => Schedule(() =>
{ {
onlineBeatmap = res.ToBeatmapSet(rulesets); this.beatmapSet = beatmapSet;
beatmapPanelContainer.Child = new GridBeatmapPanel(res); beatmapPanelContainer.Child = new GridBeatmapPanel(this.beatmapSet);
checkForAutomaticDownload(); checkForAutomaticDownload();
}); });
@ -232,16 +234,16 @@ namespace osu.Game.Screens.Play
private void checkForAutomaticDownload() private void checkForAutomaticDownload()
{ {
if (onlineBeatmap == null) if (beatmapSet == null)
return; return;
if (!automaticDownload.Current.Value) if (!automaticDownload.Current.Value)
return; return;
if (beatmaps.IsAvailableLocally(onlineBeatmap)) if (beatmaps.IsAvailableLocally(new BeatmapSetInfo { OnlineBeatmapSetID = beatmapSet.OnlineID }))
return; return;
beatmaps.Download(onlineBeatmap); beatmaps.Download(beatmapSet);
} }
public override bool OnExiting(IScreen next) public override bool OnExiting(IScreen next)

View File

@ -13,6 +13,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus; using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
@ -265,18 +266,24 @@ namespace osu.Game.Tests.Visual.Multiplayer
return ((IMultiplayerClient)this).LoadRequested(); return ((IMultiplayerClient)this).LoadRequested();
} }
protected override Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default) protected override Task<APIBeatmapSet> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default)
{ {
Debug.Assert(Room != null); Debug.Assert(Room != null);
var apiRoom = roomManager.ServerSideRooms.Single(r => r.RoomID.Value == Room.RoomID); var apiRoom = roomManager.ServerSideRooms.Single(r => r.RoomID.Value == Room.RoomID);
var set = apiRoom.Playlist.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet IBeatmapSetInfo? set = apiRoom.Playlist.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet
?? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId)?.BeatmapSet; ?? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId)?.BeatmapSet;
if (set == null) if (set == null)
throw new InvalidOperationException("Beatmap not found."); throw new InvalidOperationException("Beatmap not found.");
return Task.FromResult(set); var apiSet = new APIBeatmapSet
{
OnlineID = set.OnlineID,
Beatmaps = set.Beatmaps.Select(b => new APIBeatmap { OnlineID = b.OnlineID }).ToArray(),
};
return Task.FromResult(apiSet);
} }
private async Task changeMatchType(MatchType type) private async Task changeMatchType(MatchType type)