mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 19:54:15 +08:00
Compare commits
9 Commits
e0bb88b49c
...
9a67d0727a
@@ -61,6 +61,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("import beatmap", () =>
|
||||
{
|
||||
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
|
||||
Realm.Write(r =>
|
||||
{
|
||||
foreach (var beatmapInfo in r.All<BeatmapInfo>())
|
||||
beatmapInfo.OnlineMD5Hash = beatmapInfo.MD5Hash;
|
||||
});
|
||||
importedSet = beatmaps.GetAllUsableBeatmapSets().First();
|
||||
InitialBeatmap = importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0);
|
||||
OtherBeatmap = importedSet.Beatmaps.Last(b => b.Ruleset.OnlineID == 0);
|
||||
|
||||
@@ -81,6 +81,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("import beatmap", () =>
|
||||
{
|
||||
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
|
||||
Realm.Write(r =>
|
||||
{
|
||||
foreach (var beatmapInfo in r.All<BeatmapInfo>())
|
||||
beatmapInfo.OnlineMD5Hash = beatmapInfo.MD5Hash;
|
||||
});
|
||||
importedSet = beatmaps.GetAllUsableBeatmapSets().First();
|
||||
});
|
||||
|
||||
|
||||
@@ -176,6 +176,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
|
||||
}
|
||||
];
|
||||
room.EndDate = DateTimeOffset.Now.AddHours(1);
|
||||
});
|
||||
|
||||
AddAssert("match has default beatmap", () => match.Beatmap.IsDefault);
|
||||
@@ -212,6 +213,11 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
|
||||
Debug.Assert(beatmap.BeatmapInfo.BeatmapSet != null);
|
||||
importedBeatmap = manager.Import(beatmap.BeatmapInfo.BeatmapSet)!.Value.Detach();
|
||||
Realm.Write(r =>
|
||||
{
|
||||
foreach (var beatmapInfo in r.All<BeatmapInfo>())
|
||||
beatmapInfo.OnlineMD5Hash = beatmapInfo.MD5Hash;
|
||||
});
|
||||
});
|
||||
|
||||
private partial class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen
|
||||
|
||||
@@ -65,7 +65,8 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
OnlineID = 1,
|
||||
DifficultyName = "Osu 1",
|
||||
Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = "11111111",
|
||||
OnlineMD5Hash = "11111111",
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
Metadata =
|
||||
{
|
||||
@@ -79,7 +80,8 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
OnlineID = 2,
|
||||
DifficultyName = "Osu 2",
|
||||
Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = "22222222",
|
||||
OnlineMD5Hash = "22222222",
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
Metadata =
|
||||
{
|
||||
@@ -93,7 +95,8 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
OnlineID = 3,
|
||||
DifficultyName = "Taiko 1",
|
||||
Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = "33333333",
|
||||
OnlineMD5Hash = "33333333",
|
||||
Ruleset = new TaikoRuleset().RulesetInfo,
|
||||
Metadata =
|
||||
{
|
||||
@@ -107,7 +110,8 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
OnlineID = 4,
|
||||
DifficultyName = "Taiko 2",
|
||||
Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = Guid.NewGuid().ToString().ComputeMD5Hash(),
|
||||
MD5Hash = "44444444",
|
||||
OnlineMD5Hash = "44444444",
|
||||
Ruleset = new TaikoRuleset().RulesetInfo,
|
||||
Metadata =
|
||||
{
|
||||
|
||||
@@ -298,7 +298,21 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||
public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query) => Realm.Run(r =>
|
||||
r.All<BeatmapInfo>().Filter($"{nameof(BeatmapInfo.BeatmapSet)}.{nameof(BeatmapSetInfo.DeletePending)} == false").FirstOrDefault(query)?.Detach());
|
||||
r.All<BeatmapInfo>().Filter($@"{nameof(BeatmapInfo.BeatmapSet)}.{nameof(BeatmapSetInfo.DeletePending)} == false").FirstOrDefault(query)?.Detach());
|
||||
|
||||
/// <summary>
|
||||
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
||||
/// Use this overload instead of <see cref="QueryBeatmap(System.Linq.Expressions.Expression{System.Func{osu.Game.Beatmaps.BeatmapInfo,bool}})"/>
|
||||
/// when Realm is unable to transform an expression to the internal Realm query syntax.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="arguments">The arguments for the query.</param>
|
||||
/// <returns>The first result for the provided query, or null if no results were found.</returns>
|
||||
public BeatmapInfo? QueryBeatmap(string query, params QueryArgument[] arguments) => Realm.Run(r =>
|
||||
r.All<BeatmapInfo>()
|
||||
.Filter($@"{nameof(BeatmapInfo.BeatmapSet)}.{nameof(BeatmapSetInfo.DeletePending)} == false")
|
||||
.Filter(query, arguments)
|
||||
.FirstOrDefault()?.Detach());
|
||||
|
||||
/// <summary>
|
||||
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
|
||||
|
||||
@@ -490,7 +490,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
|
||||
if (!screen.IsCurrentScreen())
|
||||
return;
|
||||
|
||||
var beatmap = beatmaps.QueryBeatmap(b => b.OnlineID == item.Beatmap.OnlineID);
|
||||
var beatmap = beatmaps.QueryBeatmap($@"{nameof(BeatmapInfo.OnlineID)} == $0 AND {nameof(BeatmapInfo.MD5Hash)} == {nameof(BeatmapInfo.OnlineMD5Hash)}", item.Beatmap.OnlineID);
|
||||
|
||||
screen.Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap); // this will gracefully fall back to dummy beatmap if missing locally.
|
||||
screen.Ruleset.Value = rulesets.GetRuleset(item.RulesetID);
|
||||
|
||||
@@ -46,22 +46,26 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
[Resolved]
|
||||
private OsuGame? game { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private BeatmapLookupCache beatmapLookupCache { get; set; } = null!;
|
||||
|
||||
public readonly Room Room;
|
||||
|
||||
protected readonly Bindable<PlaylistItem?> SelectedItem = new Bindable<PlaylistItem?>();
|
||||
protected Container ButtonsContainer { get; private set; } = null!;
|
||||
|
||||
private readonly Bindable<MatchType> roomType = new Bindable<MatchType>();
|
||||
private readonly Bindable<RoomCategory> roomCategory = new Bindable<RoomCategory>();
|
||||
private readonly Bindable<bool> hasPassword = new Bindable<bool>();
|
||||
|
||||
private DrawableRoomParticipantsList? drawableRoomParticipantsList;
|
||||
private RoomSpecialCategoryPill? specialCategoryPill;
|
||||
private PasswordProtectedIcon? passwordIcon;
|
||||
private EndDateInfo? endDateInfo;
|
||||
private SpriteText? roomName;
|
||||
private UpdateableBeatmapBackgroundSprite background = null!;
|
||||
private DelayedLoadWrapper wrapper = null!;
|
||||
private CancellationTokenSource? beatmapLookupCancellation;
|
||||
|
||||
/// <summary>
|
||||
/// A fully-populated representation of the selected item's current beatmap.
|
||||
/// </summary>
|
||||
private readonly Bindable<IBeatmapInfo?> currentBeatmap = new Bindable<IBeatmapInfo?>();
|
||||
|
||||
protected RoomPanel(Room room)
|
||||
{
|
||||
@@ -99,9 +103,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Background5,
|
||||
},
|
||||
background = CreateBackground().With(d =>
|
||||
CreateBackground().With(d =>
|
||||
{
|
||||
d.RelativeSizeAxes = Axes.Both;
|
||||
d.Beatmap.BindTarget = currentBeatmap;
|
||||
}),
|
||||
wrapper = new DelayedLoadWrapper(() =>
|
||||
new Container
|
||||
@@ -206,7 +211,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
},
|
||||
new RoomStatusText(Room)
|
||||
{
|
||||
SelectedItem = { BindTarget = SelectedItem }
|
||||
Beatmap = { BindTarget = currentBeatmap }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,7 +285,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
updateRoomHasPassword();
|
||||
};
|
||||
|
||||
SelectedItem.BindValueChanged(item => background.Beatmap.Value = item.NewValue?.Beatmap, true);
|
||||
SelectedItem.BindValueChanged(onSelectedItemChanged, true);
|
||||
}
|
||||
|
||||
private void onRoomPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
@@ -305,6 +310,30 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void onSelectedItemChanged(ValueChangedEvent<PlaylistItem?> item)
|
||||
{
|
||||
if (item.NewValue?.Beatmap.OnlineID == item.OldValue?.Beatmap.OnlineID)
|
||||
return;
|
||||
|
||||
beatmapLookupCancellation?.Cancel();
|
||||
beatmapLookupCancellation?.Dispose();
|
||||
|
||||
if (item.NewValue?.Beatmap == null)
|
||||
{
|
||||
currentBeatmap.Value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var cancellationSource = beatmapLookupCancellation = new CancellationTokenSource();
|
||||
|
||||
beatmapLookupCache.GetBeatmapAsync(item.NewValue.Beatmap.OnlineID, cancellationSource.Token)
|
||||
.ContinueWith(task => Schedule(() =>
|
||||
{
|
||||
if (!cancellationSource.IsCancellationRequested)
|
||||
currentBeatmap.Value = task.GetResultSafely();
|
||||
}), cancellationSource.Token);
|
||||
}
|
||||
|
||||
private void updateRoomName()
|
||||
{
|
||||
if (roomName != null)
|
||||
@@ -406,14 +435,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
private partial class RoomStatusText : CompositeDrawable
|
||||
{
|
||||
public readonly IBindable<PlaylistItem?> SelectedItem = new Bindable<PlaylistItem?>();
|
||||
public readonly Bindable<IBeatmapInfo?> Beatmap = new Bindable<IBeatmapInfo?>();
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapLookupCache beatmapLookupCache { get; set; } = null!;
|
||||
|
||||
private readonly Room room;
|
||||
private SpriteText statusText = null!;
|
||||
private LinkFlowContainer beatmapText = null!;
|
||||
@@ -469,14 +495,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
SelectedItem.BindValueChanged(onSelectedItemChanged, true);
|
||||
|
||||
Beatmap.BindValueChanged(onBeatmapChanged, true);
|
||||
}
|
||||
|
||||
private CancellationTokenSource? beatmapLookupCancellation;
|
||||
|
||||
private void onSelectedItemChanged(ValueChangedEvent<PlaylistItem?> item)
|
||||
private void onBeatmapChanged(ValueChangedEvent<IBeatmapInfo?> beatmap)
|
||||
{
|
||||
beatmapLookupCancellation?.Cancel();
|
||||
beatmapText.Clear();
|
||||
|
||||
if (room.Type == MatchType.Playlists)
|
||||
@@ -485,31 +509,17 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
return;
|
||||
}
|
||||
|
||||
var beatmap = item.NewValue?.Beatmap;
|
||||
if (beatmap == null)
|
||||
return;
|
||||
statusText.Text = "Currently playing ";
|
||||
|
||||
var cancellationSource = beatmapLookupCancellation = new CancellationTokenSource();
|
||||
beatmapLookupCache.GetBeatmapAsync(beatmap.OnlineID, cancellationSource.Token)
|
||||
.ContinueWith(task => Schedule(() =>
|
||||
{
|
||||
if (cancellationSource.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var retrievedBeatmap = task.GetResultSafely();
|
||||
|
||||
statusText.Text = "Currently playing ";
|
||||
|
||||
if (retrievedBeatmap != null)
|
||||
{
|
||||
beatmapText.AddLink(retrievedBeatmap.GetDisplayTitleRomanisable(),
|
||||
LinkAction.OpenBeatmap,
|
||||
retrievedBeatmap.OnlineID.ToString(),
|
||||
creationParameters: s => s.Truncate = true);
|
||||
}
|
||||
else
|
||||
beatmapText.AddText("unknown beatmap");
|
||||
}), cancellationSource.Token);
|
||||
if (beatmap.NewValue != null)
|
||||
{
|
||||
beatmapText.AddLink(beatmap.NewValue.GetDisplayTitleRomanisable(),
|
||||
LinkAction.OpenBeatmap,
|
||||
beatmap.NewValue.OnlineID.ToString(),
|
||||
creationParameters: s => s.Truncate = true);
|
||||
}
|
||||
else
|
||||
beatmapText.AddText("unknown beatmap");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,7 +448,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
|
||||
// Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info
|
||||
int beatmapId = GetGameplayBeatmap().OnlineID;
|
||||
var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineID == beatmapId);
|
||||
var localBeatmap = beatmapManager.QueryBeatmap($@"{nameof(BeatmapInfo.OnlineID)} == $0 AND {nameof(BeatmapInfo.MD5Hash)} == {nameof(BeatmapInfo.OnlineMD5Hash)}", beatmapId);
|
||||
Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap);
|
||||
UserModsSelectOverlay.Beatmap.Value = Beatmap.Value;
|
||||
|
||||
|
||||
@@ -596,8 +596,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
|
||||
// Update global gameplay state to correspond to the new selection.
|
||||
// Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info
|
||||
int beatmapId = gameplayBeatmap.OnlineID;
|
||||
var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineID == beatmapId);
|
||||
var localBeatmap = beatmapManager.QueryBeatmap($@"{nameof(BeatmapInfo.OnlineID)} == $0 AND {nameof(BeatmapInfo.MD5Hash)} == {nameof(BeatmapInfo.OnlineMD5Hash)}", gameplayBeatmap.OnlineID);
|
||||
Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap);
|
||||
Ruleset.Value = gameplayRuleset;
|
||||
Mods.Value = UserMods.Value.Concat(item.RequiredMods.Select(m => m.ToMod(rulesetInstance))).ToArray();
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
var b = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
|
||||
b.BeatmapInfo.MD5Hash = test_beatmap_hash.Value.md5;
|
||||
b.BeatmapInfo.OnlineMD5Hash = test_beatmap_hash.Value.md5;
|
||||
b.BeatmapInfo.Hash = test_beatmap_hash.Value.sha2;
|
||||
|
||||
return b;
|
||||
|
||||
Reference in New Issue
Block a user