1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 17:32:54 +08:00

Merge branch 'beatmap-refactor/remove-online-info' into beatmap-refactor/to-model-removal-2

This commit is contained in:
Dean Herbert 2021-11-04 17:09:50 +09:00
commit d2831b1152
37 changed files with 222 additions and 350 deletions

View File

@ -39,8 +39,8 @@ namespace osu.Game.Tests.NonVisual
[Test]
public void TestCheckNullID()
{
var ourInfo = new BeatmapSetInfo { Status = BeatmapSetOnlineStatus.Loved };
var otherInfo = new BeatmapSetInfo { Status = BeatmapSetOnlineStatus.Approved };
var ourInfo = new BeatmapSetInfo { Hash = "1" };
var otherInfo = new BeatmapSetInfo { Hash = "2" };
Assert.AreNotEqual(ourInfo, otherInfo);
}

View File

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

View File

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

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -223,11 +224,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestDownloadButtonVisibleInitiallyWhenBeatmapDoesNotExist()
{
var byOnlineId = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
byOnlineId.BeatmapSet.OnlineBeatmapSetID = 1337; // Some random ID that does not exist locally.
var byOnlineId = CreateAPIBeatmap();
byOnlineId.OnlineID = 1337; // Some random ID that does not exist locally.
var byChecksum = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
byChecksum.MD5Hash = "1337"; // Some random checksum that does not exist locally.
var byChecksum = CreateAPIBeatmap();
byChecksum.Checksum = "1337"; // Some random checksum that does not exist locally.
createPlaylist(byOnlineId, byChecksum);
@ -237,8 +238,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestExplicitBeatmapItem()
{
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
beatmap.BeatmapSet.OnlineInfo.HasExplicitContent = true;
var beatmap = CreateAPIBeatmap();
Debug.Assert(beatmap.BeatmapSet != null);
beatmap.BeatmapSet.HasExplicitContent = true;
createPlaylist(beatmap);
}
@ -310,7 +314,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
}
private void createPlaylist(params BeatmapInfo[] beatmaps)
private void createPlaylist(params IBeatmapInfo[] beatmaps)
{
AddStep("create playlist", () =>
{

View File

@ -1,7 +1,6 @@
// 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.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -37,7 +36,7 @@ namespace osu.Game.Tests.Visual.Online
{
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
{
Beatmaps = new List<APIBeatmap>
Beatmaps = new[]
{
new APIBeatmap
{
@ -71,10 +70,7 @@ namespace osu.Game.Tests.Visual.Online
[Test]
public void TestEmptyBeatmapSet()
{
AddStep("load empty beatmapset", () => selector.BeatmapSet = new APIBeatmapSet
{
Beatmaps = new List<APIBeatmap>()
});
AddStep("load empty beatmapset", () => selector.BeatmapSet = new APIBeatmapSet());
AddAssert("no ruleset selected", () => selector.SelectedTab == null);
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(),
HasStoryboard = true,
Covers = new BeatmapSetOnlineCovers(),
Beatmaps = new List<APIBeatmap>
Beatmaps = new[]
{
new APIBeatmap
{
@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.Online
var set = getBeatmapSet();
set.Beatmaps = beatmaps;
set.Beatmaps = beatmaps.ToArray();
overlay.ShowBeatmapSet(set);
});
@ -211,7 +211,7 @@ namespace osu.Game.Tests.Visual.Online
});
}
set.Beatmaps = beatmaps;
set.Beatmaps = beatmaps.ToArray();
return set;
}

View File

@ -1,7 +1,6 @@
// 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.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online
static APIBeatmapSet createSet() => new APIBeatmapSet
{
Beatmaps = new List<APIBeatmap>
Beatmaps = new[]
{
new APIBeatmap
{

View File

@ -9,7 +9,6 @@ using osu.Game.Beatmaps;
using osu.Game.Online;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.BeatmapListing.Panels;
using osu.Game.Rulesets.Osu;
using osu.Game.Tests.Resources;
using osuTK;
@ -110,7 +109,7 @@ namespace osu.Game.Tests.Visual.Online
private IBeatmapSetInfo getDownloadableBeatmapSet()
{
var apiBeatmapSet = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).BeatmapSetInfo.OnlineInfo;
var apiBeatmapSet = CreateAPIBeatmapSet();
apiBeatmapSet.HasVideo = true;
apiBeatmapSet.HasStoryboard = true;
@ -120,7 +119,7 @@ namespace osu.Game.Tests.Visual.Online
private IBeatmapSetInfo getUndownloadableBeatmapSet()
{
var apiBeatmapSet = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).BeatmapSetInfo.OnlineInfo;
var apiBeatmapSet = CreateAPIBeatmapSet();
apiBeatmapSet.Artist = "test";
apiBeatmapSet.Title = "undownloadable";

View File

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

View File

@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Select;
namespace osu.Game.Tests.Visual.SongSelect
@ -32,159 +31,112 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test]
public void TestAllMetrics()
{
AddStep("all metrics", () => details.BeatmapInfo = new BeatmapInfo
AddStep("all metrics", () => details.BeatmapInfo = new APIBeatmap
{
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new APIBeatmapSet
{
Ratings = Enumerable.Range(0, 11).ToArray(),
}
},
Version = "All Metrics",
Metadata = new BeatmapMetadata
BeatmapSet = new APIBeatmapSet
{
Source = "osu!",
Tags = "this beatmap has all the metrics",
Ratings = Enumerable.Range(0, 11).ToArray(),
},
BaseDifficulty = new BeatmapDifficulty
DifficultyName = "All Metrics",
CircleSize = 7,
DrainRate = 1,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f,
StarRating = 5.3f,
FailTimes = new APIFailTimes
{
CircleSize = 7,
DrainRate = 1,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f,
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
StarDifficulty = 5.3f,
Ruleset = new OsuRuleset().RulesetInfo,
OnlineInfo = new APIBeatmap
{
FailTimes = new APIFailTimes
{
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
}
});
}
[Test]
public void TestAllMetricsExceptSource()
{
AddStep("all except source", () => details.BeatmapInfo = new BeatmapInfo
AddStep("all except source", () => details.BeatmapInfo = new APIBeatmap
{
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new APIBeatmapSet
{
Ratings = Enumerable.Range(0, 11).ToArray(),
}
},
Version = "All Metrics",
Metadata = new BeatmapMetadata
BeatmapSet = new APIBeatmapSet
{
Tags = "this beatmap has all the metrics",
Ratings = Enumerable.Range(0, 11).ToArray(),
},
BaseDifficulty = new BeatmapDifficulty
DifficultyName = "All Metrics",
CircleSize = 7,
DrainRate = 1,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f,
StarRating = 5.3f,
FailTimes = new APIFailTimes
{
CircleSize = 7,
DrainRate = 1,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f,
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
StarDifficulty = 5.3f,
Ruleset = new OsuRuleset().RulesetInfo,
OnlineInfo = new APIBeatmap
{
FailTimes = new APIFailTimes
{
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
}
});
}
[Test]
public void TestOnlyRatings()
{
AddStep("ratings", () => details.BeatmapInfo = new BeatmapInfo
AddStep("ratings", () => details.BeatmapInfo = new APIBeatmap
{
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new APIBeatmapSet
{
Ratings = Enumerable.Range(0, 11).ToArray(),
}
},
Version = "Only Ratings",
Metadata = new BeatmapMetadata
BeatmapSet = new APIBeatmapSet
{
Ratings = Enumerable.Range(0, 11).ToArray(),
Source = "osu!",
Tags = "this beatmap has ratings metrics but not retries or fails",
},
Ruleset = new OsuRuleset().RulesetInfo,
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 6,
DrainRate = 9,
OverallDifficulty = 6,
ApproachRate = 6,
},
StarDifficulty = 4.8f,
DifficultyName = "Only Ratings",
CircleSize = 6,
DrainRate = 9,
OverallDifficulty = 6,
ApproachRate = 6,
StarRating = 4.8f,
});
}
[Test]
public void TestOnlyFailsAndRetries()
{
AddStep("fails retries", () => details.BeatmapInfo = new BeatmapInfo
AddStep("fails retries", () => details.BeatmapInfo = new APIBeatmap
{
Version = "Only Retries and Fails",
Metadata = new BeatmapMetadata
DifficultyName = "Only Retries and Fails",
BeatmapSet = new APIBeatmapSet
{
Source = "osu!",
Tags = "this beatmap has retries and fails but no ratings",
},
BaseDifficulty = new BeatmapDifficulty
CircleSize = 3.7f,
DrainRate = 6,
OverallDifficulty = 6,
ApproachRate = 7,
StarRating = 2.91f,
FailTimes = new APIFailTimes
{
CircleSize = 3.7f,
DrainRate = 6,
OverallDifficulty = 6,
ApproachRate = 7,
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
Ruleset = new OsuRuleset().RulesetInfo,
StarDifficulty = 2.91f,
OnlineInfo = new APIBeatmap
{
FailTimes = new APIFailTimes
{
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
},
}
});
}
[Test]
public void TestNoMetrics()
{
AddStep("no metrics", () => details.BeatmapInfo = new BeatmapInfo
AddStep("no metrics", () => details.BeatmapInfo = new APIBeatmap
{
Version = "No Metrics",
Metadata = new BeatmapMetadata
DifficultyName = "No Metrics",
BeatmapSet = new APIBeatmapSet
{
Source = "osu!",
Tags = "this beatmap has no metrics",
},
Ruleset = new OsuRuleset().RulesetInfo,
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 5,
DrainRate = 5,
OverallDifficulty = 5.5f,
ApproachRate = 6.5f,
},
StarDifficulty = 1.97f,
CircleSize = 5,
DrainRate = 5,
OverallDifficulty = 5.5f,
ApproachRate = 6.5f,
StarRating = 1.97f,
});
}
@ -197,10 +149,9 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test]
public void TestOnlineMetrics()
{
AddStep("online ratings/retries/fails", () => details.BeatmapInfo = new BeatmapInfo
AddStep("online ratings/retries/fails", () => details.BeatmapInfo = new APIBeatmap
{
OnlineBeatmapID = 162,
Ruleset = new OsuRuleset().RulesetInfo
OnlineID = 162,
});
AddStep("set online", () => api.SetState(APIState.Online));
AddStep("set offline", () => api.SetState(APIState.Offline));

View File

@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
AddStep("setup cover", () => Child = new UpdateableOnlineBeatmapSetCover(coverType)
{
OnlineInfo = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet.OnlineInfo,
OnlineInfo = CreateAPIBeatmapSet(),
RelativeSizeAxes = Axes.Both,
Masking = true,
});
@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("setup covers", () =>
{
BeatmapSetInfo setInfo = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet;
var beatmapSet = CreateAPIBeatmapSet();
FillFlowContainer fillFlow;
@ -68,7 +68,7 @@ namespace osu.Game.Tests.Visual.UserInterface
var cover = new UpdateableOnlineBeatmapSetCover(coverType)
{
OnlineInfo = setInfo.OnlineInfo,
OnlineInfo = beatmapSet,
Height = 100,
Masking = true,
};
@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("setup cover", () => Child = updateableCover = new TestUpdateableOnlineBeatmapSetCover
{
OnlineInfo = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet.OnlineInfo,
OnlineInfo = CreateAPIBeatmapSet(),
RelativeSizeAxes = Axes.Both,
Masking = true,
});
@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("setup cover", () => Child = updateableCover = new TestUpdateableOnlineBeatmapSetCover(0)
{
OnlineInfo = createBeatmapWithCover("https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg").OnlineInfo,
OnlineInfo = createBeatmapWithCover("https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg"),
RelativeSizeAxes = Axes.Both,
Masking = true,
Alpha = 0.4f
@ -128,16 +128,13 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("wait for fade complete", () => initialCover.Alpha == 1);
AddStep("switch beatmap",
() => updateableCover.OnlineInfo = createBeatmapWithCover("https://assets.ppy.sh/beatmaps/1079428/covers/cover.jpg").OnlineInfo);
() => updateableCover.OnlineInfo = createBeatmapWithCover("https://assets.ppy.sh/beatmaps/1079428/covers/cover.jpg"));
AddUntilStep("new cover loaded", () => updateableCover.ChildrenOfType<OnlineBeatmapSetCover>().Except(new[] { initialCover }).Any());
}
private static BeatmapSetInfo createBeatmapWithCover(string coverUrl) => new BeatmapSetInfo
private static APIBeatmapSet createBeatmapWithCover(string coverUrl) => new APIBeatmapSet
{
OnlineInfo = new APIBeatmapSet
{
Covers = new BeatmapSetOnlineCovers { Cover = coverUrl }
}
Covers = new BeatmapSetOnlineCovers { Cover = coverUrl }
};
private class TestUpdateableOnlineBeatmapSetCover : UpdateableOnlineBeatmapSetCover

View File

@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps
{
[ExcludeFromDynamicCompile]
[Serializable]
public class BeatmapInfo : IEquatable<BeatmapInfo>, IHasPrimaryKey, IBeatmapInfo, IBeatmapOnlineInfo
public class BeatmapInfo : IEquatable<BeatmapInfo>, IHasPrimaryKey, IBeatmapInfo
{
public int ID { get; set; }
@ -186,7 +186,7 @@ namespace osu.Game.Beatmaps
string IBeatmapInfo.DifficultyName => Version;
[JsonIgnore]
IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata;
IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata ?? BeatmapSet?.Metadata ?? new BeatmapMetadata();
[JsonIgnore]
IBeatmapDifficultyInfo IBeatmapInfo.Difficulty => BaseDifficulty;
@ -201,24 +201,5 @@ namespace osu.Game.Beatmaps
double IBeatmapInfo.StarRating => StarDifficulty;
#endregion
#region Implementation of IBeatmapOnlineInfo
[JsonIgnore]
public int CircleCount => OnlineInfo.CircleCount;
[JsonIgnore]
public int SliderCount => OnlineInfo.SliderCount;
[JsonIgnore]
public int PlayCount => OnlineInfo.PlayCount;
[JsonIgnore]
public int PassCount => OnlineInfo.PassCount;
[JsonIgnore]
public APIFailTimes FailTimes => OnlineInfo.FailTimes;
#endregion
}
}

View File

@ -11,14 +11,14 @@ namespace osu.Game.Beatmaps
/// <summary>
/// A user-presentable display title representing this beatmap.
/// </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>
/// A user-presentable display title representing this beatmap, with localisation handling for potentially romanisable fields.
/// </summary>
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)
{
@ -32,12 +32,8 @@ namespace osu.Game.Beatmaps
public static string[] GetSearchableTerms(this IBeatmapInfo beatmapInfo) => new[]
{
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}]";
// 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

@ -6,10 +6,8 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Beatmaps
{
@ -32,13 +30,11 @@ namespace osu.Game.Beatmaps
public List<BeatmapInfo> Beatmaps { get; set; }
public BeatmapSetOnlineStatus Status { get; set; } = BeatmapSetOnlineStatus.None;
[NotNull]
public List<BeatmapSetFileInfo> Files { get; set; } = new List<BeatmapSetFileInfo>();
// This field is temporary and only used by `APIBeatmapSet.ToBeatmapSet` (soon to be removed) and tests (to be updated to provide APIBeatmapSet instead).
[NotMapped]
public APIBeatmapSet OnlineInfo { get; set; }
/// <summary>
/// The maximum star difficulty of all beatmaps in this set.
/// </summary>
@ -100,80 +96,5 @@ namespace osu.Game.Beatmaps
IEnumerable<INamedFileUsage> IBeatmapSetInfo.Files => Files;
#endregion
#region Delegation for IBeatmapSetOnlineInfo
[NotMapped]
[JsonIgnore]
public DateTimeOffset Submitted => OnlineInfo.Submitted;
[NotMapped]
[JsonIgnore]
public DateTimeOffset? Ranked => OnlineInfo.Ranked;
[NotMapped]
[JsonIgnore]
public DateTimeOffset? LastUpdated => OnlineInfo.LastUpdated;
[JsonIgnore]
public BeatmapSetOnlineStatus Status { get; set; } = BeatmapSetOnlineStatus.None;
[NotMapped]
[JsonIgnore]
public bool HasExplicitContent => OnlineInfo.HasExplicitContent;
[NotMapped]
[JsonIgnore]
public bool HasVideo => OnlineInfo.HasVideo;
[NotMapped]
[JsonIgnore]
public bool HasStoryboard => OnlineInfo.HasStoryboard;
[NotMapped]
[JsonIgnore]
public BeatmapSetOnlineCovers Covers => OnlineInfo.Covers;
[NotMapped]
[JsonIgnore]
public string Preview => OnlineInfo.Preview;
[NotMapped]
[JsonIgnore]
public double BPM => OnlineInfo.BPM;
[NotMapped]
[JsonIgnore]
public int PlayCount => OnlineInfo.PlayCount;
[NotMapped]
[JsonIgnore]
public int FavouriteCount => OnlineInfo.FavouriteCount;
[NotMapped]
[JsonIgnore]
public bool HasFavourited => OnlineInfo.HasFavourited;
[NotMapped]
[JsonIgnore]
public BeatmapSetOnlineAvailability Availability => OnlineInfo.Availability;
[NotMapped]
[JsonIgnore]
public BeatmapSetOnlineGenre Genre => OnlineInfo.Genre;
[NotMapped]
[JsonIgnore]
public BeatmapSetOnlineLanguage Language => OnlineInfo.Language;
[NotMapped]
[JsonIgnore]
public int? TrackId => OnlineInfo?.TrackId;
[NotMapped]
[JsonIgnore]
public int[] Ratings => OnlineInfo?.Ratings;
#endregion
}
}

View File

@ -57,12 +57,7 @@ namespace osu.Game.Beatmaps.Drawables
return new OnlineBeatmapSetCover(online, beatmapSetCoverType);
if (model is BeatmapInfo localModel)
{
if (localModel.BeatmapSet?.OnlineInfo != null)
return new OnlineBeatmapSetCover(localModel.BeatmapSet.OnlineInfo, beatmapSetCoverType);
return new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(localModel));
}
return new BeatmapBackgroundSprite(beatmaps.DefaultBeatmap);
}

View File

@ -21,7 +21,7 @@ namespace osu.Game.Beatmaps
/// <summary>
/// The metadata representing this beatmap. May be shared between multiple beatmaps.
/// </summary>
IBeatmapMetadataInfo? Metadata { get; }
IBeatmapMetadataInfo Metadata { get; }
/// <summary>
/// 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;
[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)
{
@ -128,7 +128,6 @@ namespace osu.Game.Online.API.Requests.Responses
OnlineBeatmapSetID = OnlineID,
Metadata = metadata,
Status = Status,
OnlineInfo = this
};
beatmapSet.Beatmaps = Beatmaps.Select(b =>

View File

@ -17,6 +17,7 @@ using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Online.Rooms.RoomStatuses;
using osu.Game.Rulesets;
@ -644,24 +645,32 @@ namespace osu.Game.Online.Multiplayer
RoomUpdated?.Invoke();
GetOnlineBeatmapSet(settings.BeatmapID, cancellationToken).ContinueWith(set => Schedule(() =>
GetOnlineBeatmapSet(settings.BeatmapID, cancellationToken).ContinueWith(task => Schedule(() =>
{
if (cancellationToken.IsCancellationRequested)
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);
}, cancellationToken);
private void updatePlaylist(MultiplayerRoomSettings settings, BeatmapSetInfo beatmapSet)
private void updatePlaylist(MultiplayerRoomSettings settings, APIBeatmapSet beatmapSet)
{
if (Room == null || !Room.Settings.Equals(settings))
return;
Debug.Assert(APIRoom != null);
var beatmap = beatmapSet.Beatmaps.Single(b => b.OnlineBeatmapID == settings.BeatmapID);
beatmap.MD5Hash = settings.BeatmapChecksum;
var beatmap = beatmapSet.Beatmaps.Single(b => b.OnlineID == settings.BeatmapID);
beatmap.Checksum = settings.BeatmapChecksum;
var ruleset = Rulesets.GetRuleset(settings.RulesetID).CreateInstance();
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
@ -694,12 +703,12 @@ namespace osu.Game.Online.Multiplayer
}
/// <summary>
/// Retrieves a <see cref="BeatmapSetInfo"/> from an online source.
/// Retrieves a <see cref="APIBeatmapSet"/> from an online source.
/// </summary>
/// <param name="beatmapId">The beatmap set ID.</param>
/// <param name="cancellationToken">A token to cancel the request.</param>
/// <returns>The <see cref="BeatmapSetInfo"/> retrieval task.</returns>
protected abstract Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default);
/// <returns>The <see cref="APIBeatmapSet"/> retrieval task.</returns>
protected abstract Task<APIBeatmapSet> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default);
/// <summary>
/// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer
@ -148,9 +148,9 @@ namespace osu.Game.Online.Multiplayer
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);
req.Success += res =>
@ -161,7 +161,7 @@ namespace osu.Game.Online.Multiplayer
return;
}
tcs.SetResult(res.ToBeatmapSet(Rulesets));
tcs.SetResult(res);
};
req.Failure += e => tcs.SetException(e);

View File

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

View File

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

View File

@ -31,7 +31,7 @@ namespace osu.Game.Online.Rooms
public bool Expired { get; set; }
[JsonIgnore]
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
public readonly Bindable<IBeatmapInfo> Beatmap = new Bindable<IBeatmapInfo>();
[JsonIgnore]
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
@ -65,13 +65,13 @@ namespace osu.Game.Online.Rooms
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);
}
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 rulesetInstance = Ruleset.Value.CreateInstance();

View File

@ -147,7 +147,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
{
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())
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.Shapes;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Online.Rooms;
using osuTK;
using osuTK.Graphics;
@ -61,7 +62,10 @@ namespace osu.Game.Screens.OnlinePlay.Components
{
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;
cancellationSource?.Cancel();

View File

@ -13,11 +13,11 @@ namespace osu.Game.Screens.OnlinePlay.Components
{
public class PlaylistItemBackground : Background
{
public readonly BeatmapInfo? BeatmapInfo;
public readonly IBeatmapInfo? Beatmap;
public PlaylistItemBackground(PlaylistItem? playlistItem)
{
BeatmapInfo = playlistItem?.Beatmap.Value;
Beatmap = playlistItem?.Beatmap.Value;
}
[BackgroundDependencyLoader]
@ -26,8 +26,8 @@ namespace osu.Game.Screens.OnlinePlay.Components
Texture? texture = null;
// prefer online cover where available.
if (BeatmapInfo?.BeatmapSet?.OnlineInfo?.Covers.Cover != null)
texture = textures.Get(BeatmapInfo.BeatmapSet.OnlineInfo.Covers.Cover);
if (Beatmap?.BeatmapSet is IBeatmapSetOnlineInfo online)
texture = textures.Get(online.Covers.Cover);
Sprite.Texture = texture ?? beatmaps.DefaultBeatmap.Background;
}
@ -38,7 +38,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
if (ReferenceEquals(this, other)) return true;
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
{
foreach (var pi in room.Playlist)
pi.MapObjects(beatmaps, rulesets);
pi.MapObjects(rulesets);
var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value);
if (existing == null)

View File

@ -80,10 +80,10 @@ namespace osu.Game.Screens.OnlinePlay.Components
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 maxDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[^1].StarDifficulty : 0, 0);
StarDifficulty minDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[0].StarRating : 0, 0);
StarDifficulty maxDifficulty = new StarDifficulty(orderedDifficulties.Length > 0 ? orderedDifficulties[^1].StarRating : 0, 0);
minDisplay.Current.Value = minDifficulty;
maxDisplay.Current.Value = maxDifficulty;

View File

@ -27,6 +27,7 @@ using osu.Game.Overlays.BeatmapSet;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play.HUD;
using osu.Game.Users;
using osuTK;
using osuTK.Graphics;
@ -45,7 +46,7 @@ namespace osu.Game.Screens.OnlinePlay
private ExplicitContentBeatmapPill explicitContentPill;
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 BindableList<Mod> requiredMods = new BindableList<Mod>();
@ -96,6 +97,7 @@ namespace osu.Game.Screens.OnlinePlay
}
private ScheduledDelegate scheduledRefresh;
private PanelBackground panelBackground;
private void scheduleRefresh()
{
@ -105,23 +107,25 @@ namespace osu.Game.Screens.OnlinePlay
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.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;
});
authorText.Clear();
if (Item.Beatmap?.Value?.Metadata?.Author != null)
if (!string.IsNullOrEmpty(Item.Beatmap.Value?.Metadata.Author))
{
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;
modDisplay.Current.Value = requiredMods.ToArray();
@ -145,10 +149,9 @@ namespace osu.Game.Screens.OnlinePlay
Alpha = 0,
AlwaysPresent = true
},
new PanelBackground
panelBackground = new PanelBackground
{
RelativeSizeAxes = Axes.Both,
Beatmap = { BindTarget = beatmap }
},
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
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()
{

View File

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

View File

@ -369,7 +369,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
var beatmap = SelectedItem.Value?.Beatmap.Value;
// 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);
}

View File

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

View File

@ -41,13 +41,13 @@ namespace osu.Game.Screens.Select
[Resolved]
private RulesetStore rulesets { get; set; }
private BeatmapInfo beatmapInfo;
private IBeatmapInfo beatmapInfo;
private APIFailTimes failTimes;
private int[] ratings;
public BeatmapInfo BeatmapInfo
public IBeatmapInfo BeatmapInfo
{
get => beatmapInfo;
set
@ -56,8 +56,11 @@ namespace osu.Game.Screens.Select
beatmapInfo = value;
failTimes = beatmapInfo?.OnlineInfo?.FailTimes;
ratings = beatmapInfo?.BeatmapSet?.OnlineInfo?.Ratings;
var onlineInfo = beatmapInfo as IBeatmapOnlineInfo;
var onlineSetInfo = beatmapInfo.BeatmapSet as IBeatmapSetOnlineInfo;
failTimes = onlineInfo?.FailTimes;
ratings = onlineSetInfo?.Ratings;
Scheduler.AddOnce(updateStatistics);
}
@ -178,9 +181,9 @@ namespace osu.Game.Screens.Select
private void updateStatistics()
{
advanced.BeatmapInfo = BeatmapInfo;
description.Text = BeatmapInfo?.Version;
source.Text = BeatmapInfo?.Metadata?.Source;
tags.Text = BeatmapInfo?.Metadata?.Tags;
description.Text = BeatmapInfo?.DifficultyName;
source.Text = BeatmapInfo?.Metadata.Source;
tags.Text = BeatmapInfo?.Metadata.Tags;
// failTimes may have been previously fetched
if (ratings != null && failTimes != null)
@ -190,7 +193,7 @@ namespace osu.Game.Screens.Select
}
// for now, let's early abort if an OnlineBeatmapID is not present (should have been populated at import time).
if (BeatmapInfo?.OnlineBeatmapID == null || api.State.Value == APIState.Offline)
if (BeatmapInfo == null || BeatmapInfo.OnlineID <= 0 || api.State.Value == APIState.Offline)
{
updateMetrics();
return;

View File

@ -39,16 +39,6 @@ namespace osu.Game.Tests.Beatmaps
BeatmapInfo.Length = 75000;
BeatmapInfo.OnlineInfo = new APIBeatmap();
BeatmapInfo.OnlineBeatmapID = Interlocked.Increment(ref onlineBeatmapID);
BeatmapInfo.BeatmapSet.OnlineInfo = new APIBeatmapSet
{
Status = BeatmapSetOnlineStatus.Ranked,
Covers = new BeatmapSetOnlineCovers
{
Cover = "https://assets.ppy.sh/beatmaps/163112/covers/cover.jpg",
Card = "https://assets.ppy.sh/beatmaps/163112/covers/card.jpg",
List = "https://assets.ppy.sh/beatmaps/163112/covers/list.jpg"
}
};
}
protected virtual Beatmap CreateBeatmap() => createTestBeatmap();

View File

@ -13,6 +13,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
using osu.Game.Online.Rooms;
@ -265,18 +266,24 @@ namespace osu.Game.Tests.Visual.Multiplayer
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);
var apiRoom = roomManager.ServerSideRooms.Single(r => r.RoomID.Value == Room.RoomID);
var set = apiRoom.Playlist.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet
?? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId)?.BeatmapSet;
IBeatmapSetInfo? set = apiRoom.Playlist.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet
?? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId)?.BeatmapSet;
if (set == null)
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)

View File

@ -175,27 +175,42 @@ namespace osu.Game.Tests.Visual
protected virtual IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset);
protected APIBeatmapSet CreateAPIBeatmapSet(RulesetInfo ruleset)
/// <summary>
/// Returns a sample API Beatmap with BeatmapSet populated.
/// </summary>
/// <param name="ruleset">The ruleset to create the sample model using. osu! ruleset will be used if not specified.</param>
protected APIBeatmap CreateAPIBeatmap(RulesetInfo ruleset = null)
{
var beatmap = CreateBeatmap(ruleset).BeatmapInfo;
var beatmapSet = CreateAPIBeatmapSet(ruleset ?? Ruleset.Value);
// Avoid circular reference.
var beatmap = beatmapSet.Beatmaps.First();
beatmapSet.Beatmaps = Array.Empty<APIBeatmap>();
// Populate the set as that's generally what we expect from the API.
beatmap.BeatmapSet = beatmapSet;
return beatmap;
}
/// <summary>
/// Returns a sample API BeatmapSet with beatmaps populated.
/// </summary>
/// <param name="ruleset">The ruleset to create the sample model using. osu! ruleset will be used if not specified.</param>
protected APIBeatmapSet CreateAPIBeatmapSet(RulesetInfo ruleset = null)
{
var beatmap = CreateBeatmap(ruleset ?? Ruleset.Value).BeatmapInfo;
return new APIBeatmapSet
{
Covers = beatmap.BeatmapSet.Covers,
OnlineID = beatmap.BeatmapSet.OnlineID,
Status = beatmap.BeatmapSet.Status,
Preview = beatmap.BeatmapSet.Preview,
HasFavourited = beatmap.BeatmapSet.HasFavourited,
PlayCount = beatmap.BeatmapSet.PlayCount,
FavouriteCount = beatmap.BeatmapSet.FavouriteCount,
BPM = beatmap.BeatmapSet.BPM,
HasExplicitContent = beatmap.BeatmapSet.HasExplicitContent,
HasVideo = beatmap.BeatmapSet.HasVideo,
HasStoryboard = beatmap.BeatmapSet.HasStoryboard,
Submitted = beatmap.BeatmapSet.Submitted,
Ranked = beatmap.BeatmapSet.Ranked,
LastUpdated = beatmap.BeatmapSet.LastUpdated,
TrackId = beatmap.BeatmapSet.TrackId,
Status = BeatmapSetOnlineStatus.Ranked,
Covers = new BeatmapSetOnlineCovers
{
Cover = "https://assets.ppy.sh/beatmaps/163112/covers/cover.jpg",
Card = "https://assets.ppy.sh/beatmaps/163112/covers/card.jpg",
List = "https://assets.ppy.sh/beatmaps/163112/covers/list.jpg"
},
Title = beatmap.BeatmapSet.Metadata.Title,
TitleUnicode = beatmap.BeatmapSet.Metadata.TitleUnicode,
Artist = beatmap.BeatmapSet.Metadata.Artist,
@ -203,9 +218,6 @@ namespace osu.Game.Tests.Visual
Author = beatmap.BeatmapSet.Metadata.Author,
AuthorID = beatmap.BeatmapSet.Metadata.AuthorID,
AuthorString = beatmap.BeatmapSet.Metadata.AuthorString,
Availability = beatmap.BeatmapSet.Availability,
Genre = beatmap.BeatmapSet.Genre,
Language = beatmap.BeatmapSet.Language,
Source = beatmap.BeatmapSet.Metadata.Source,
Tags = beatmap.BeatmapSet.Metadata.Tags,
Beatmaps = new[]