mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 05:52:54 +08:00
Make StatefulMultiplayerClient control current playlist item
This commit is contained in:
parent
855d24dce7
commit
3ff9e14e35
@ -36,18 +36,26 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
[Key(5)]
|
[Key(5)]
|
||||||
public IEnumerable<APIMod> AllowedMods { get; set; } = Enumerable.Empty<APIMod>();
|
public IEnumerable<APIMod> AllowedMods { get; set; } = Enumerable.Empty<APIMod>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only used for client-side mutation.
|
||||||
|
/// </summary>
|
||||||
|
[Key(6)]
|
||||||
|
public int PlaylistItemId { get; set; }
|
||||||
|
|
||||||
public bool Equals(MultiplayerRoomSettings other)
|
public bool Equals(MultiplayerRoomSettings other)
|
||||||
=> BeatmapID == other.BeatmapID
|
=> BeatmapID == other.BeatmapID
|
||||||
&& BeatmapChecksum == other.BeatmapChecksum
|
&& BeatmapChecksum == other.BeatmapChecksum
|
||||||
&& RequiredMods.SequenceEqual(other.RequiredMods)
|
&& RequiredMods.SequenceEqual(other.RequiredMods)
|
||||||
&& AllowedMods.SequenceEqual(other.AllowedMods)
|
&& AllowedMods.SequenceEqual(other.AllowedMods)
|
||||||
&& RulesetID == other.RulesetID
|
&& RulesetID == other.RulesetID
|
||||||
&& Name.Equals(other.Name, StringComparison.Ordinal);
|
&& Name.Equals(other.Name, StringComparison.Ordinal)
|
||||||
|
&& PlaylistItemId == other.PlaylistItemId;
|
||||||
|
|
||||||
public override string ToString() => $"Name:{Name}"
|
public override string ToString() => $"Name:{Name}"
|
||||||
+ $" Beatmap:{BeatmapID} ({BeatmapChecksum})"
|
+ $" Beatmap:{BeatmapID} ({BeatmapChecksum})"
|
||||||
+ $" RequiredMods:{string.Join(',', RequiredMods)}"
|
+ $" RequiredMods:{string.Join(',', RequiredMods)}"
|
||||||
+ $" AllowedMods:{string.Join(',', AllowedMods)}"
|
+ $" AllowedMods:{string.Join(',', AllowedMods)}"
|
||||||
+ $" Ruleset:{RulesetID}";
|
+ $" Ruleset:{RulesetID}"
|
||||||
|
+ $" Item:{PlaylistItemId}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly BindableList<int> CurrentMatchPlayingUserIds = new BindableList<int>();
|
public readonly BindableList<int> CurrentMatchPlayingUserIds = new BindableList<int>();
|
||||||
|
|
||||||
|
public readonly Bindable<PlaylistItem?> CurrentMatchPlayingItem = new Bindable<PlaylistItem?>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -94,9 +96,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
private Room? apiRoom;
|
private Room? apiRoom;
|
||||||
|
|
||||||
// Todo: This is temporary, until the multiplayer server returns the item id on match start or otherwise.
|
|
||||||
private int playlistItemId;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
@ -142,7 +141,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
{
|
{
|
||||||
Room = joinedRoom;
|
Room = joinedRoom;
|
||||||
apiRoom = room;
|
apiRoom = room;
|
||||||
playlistItemId = room.Playlist.SingleOrDefault()?.ID ?? 0;
|
|
||||||
}, cancellationSource.Token);
|
}, cancellationSource.Token);
|
||||||
|
|
||||||
// Update room settings.
|
// Update room settings.
|
||||||
@ -218,7 +216,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
BeatmapChecksum = item.GetOr(existingPlaylistItem).Beatmap.Value.MD5Hash,
|
BeatmapChecksum = item.GetOr(existingPlaylistItem).Beatmap.Value.MD5Hash,
|
||||||
RulesetID = item.GetOr(existingPlaylistItem).RulesetID,
|
RulesetID = item.GetOr(existingPlaylistItem).RulesetID,
|
||||||
RequiredMods = item.HasValue ? item.Value.AsNonNull().RequiredMods.Select(m => new APIMod(m)).ToList() : Room.Settings.RequiredMods,
|
RequiredMods = item.HasValue ? item.Value.AsNonNull().RequiredMods.Select(m => new APIMod(m)).ToList() : Room.Settings.RequiredMods,
|
||||||
AllowedMods = item.HasValue ? item.Value.AsNonNull().AllowedMods.Select(m => new APIMod(m)).ToList() : Room.Settings.AllowedMods
|
AllowedMods = item.HasValue ? item.Value.AsNonNull().AllowedMods.Select(m => new APIMod(m)).ToList() : Room.Settings.AllowedMods,
|
||||||
|
PlaylistItemId = Room.Settings.PlaylistItemId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,14 +505,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Room.Settings = settings;
|
Room.Settings = settings;
|
||||||
apiRoom.Name.Value = Room.Settings.Name;
|
apiRoom.Name.Value = Room.Settings.Name;
|
||||||
|
|
||||||
// The playlist update is delayed until an online beatmap lookup (below) succeeds.
|
// The current item update is delayed until an online beatmap lookup (below) succeeds.
|
||||||
// In-order for the client to not display an outdated beatmap, the playlist is forcefully cleared here.
|
// In-order for the client to not display an outdated beatmap, the current item is forcefully cleared here.
|
||||||
apiRoom.Playlist.Clear();
|
CurrentMatchPlayingItem.Value = null;
|
||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
|
|
||||||
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
||||||
|
|
||||||
req.Success += res =>
|
req.Success += res =>
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
@ -540,18 +538,21 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
|
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
|
||||||
var allowedMods = settings.AllowedMods.Select(m => m.ToMod(ruleset));
|
var allowedMods = settings.AllowedMods.Select(m => m.ToMod(ruleset));
|
||||||
|
|
||||||
PlaylistItem playlistItem = new PlaylistItem
|
// Update an existing playlist item from the API room, or create a new item.
|
||||||
{
|
var playlistItem = apiRoom.Playlist.FirstOrDefault(i => i.ID == settings.PlaylistItemId);
|
||||||
ID = playlistItemId,
|
|
||||||
Beatmap = { Value = beatmap },
|
|
||||||
Ruleset = { Value = ruleset.RulesetInfo },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
if (playlistItem == null)
|
||||||
|
apiRoom.Playlist.Add(playlistItem = new PlaylistItem());
|
||||||
|
|
||||||
|
playlistItem.ID = settings.PlaylistItemId;
|
||||||
|
playlistItem.Beatmap.Value = beatmap;
|
||||||
|
playlistItem.Ruleset.Value = ruleset.RulesetInfo;
|
||||||
|
playlistItem.RequiredMods.Clear();
|
||||||
playlistItem.RequiredMods.AddRange(mods);
|
playlistItem.RequiredMods.AddRange(mods);
|
||||||
|
playlistItem.AllowedMods.Clear();
|
||||||
playlistItem.AllowedMods.AddRange(allowedMods);
|
playlistItem.AllowedMods.AddRange(allowedMods);
|
||||||
|
|
||||||
apiRoom.Playlist.Clear(); // Clearing should be unnecessary, but here for sanity.
|
CurrentMatchPlayingItem.Value = playlistItem;
|
||||||
apiRoom.Playlist.Add(playlistItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -28,9 +28,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
|
|
||||||
private Sample sampleStart;
|
private Sample sampleStart;
|
||||||
|
|
||||||
[Resolved(typeof(Room), nameof(Room.Playlist))]
|
|
||||||
protected BindableList<PlaylistItem> Playlist { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Any mods applied by/to the local user.
|
/// Any mods applied by/to the local user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -74,7 +71,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
||||||
SelectedItem.Value = Playlist.FirstOrDefault();
|
|
||||||
|
|
||||||
managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy();
|
managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy();
|
||||||
managerUpdated.BindValueChanged(beatmapUpdated);
|
managerUpdated.BindValueChanged(beatmapUpdated);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@ -269,7 +268,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Playlist.BindCollectionChanged(onPlaylistChanged, true);
|
SelectedItem.BindValueChanged(onSelectedItemChanged);
|
||||||
|
SelectedItem.BindTo(client.CurrentMatchPlayingItem);
|
||||||
|
|
||||||
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
||||||
UserMods.BindValueChanged(onUserModsChanged);
|
UserMods.BindValueChanged(onUserModsChanged);
|
||||||
|
|
||||||
@ -300,11 +301,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
return base.OnBackButton();
|
return base.OnBackButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onPlaylistChanged(object sender, NotifyCollectionChangedEventArgs e)
|
private void onSelectedItemChanged(ValueChangedEvent<PlaylistItem> item)
|
||||||
{
|
{
|
||||||
SelectedItem.Value = Playlist.LastOrDefault();
|
if (item.NewValue?.AllowedMods.Any() != true)
|
||||||
|
|
||||||
if (SelectedItem.Value?.AllowedMods.Any() != true)
|
|
||||||
{
|
{
|
||||||
userModsSection.Hide();
|
userModsSection.Hide();
|
||||||
userModsSelectOverlay.Hide();
|
userModsSelectOverlay.Hide();
|
||||||
@ -313,7 +312,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
userModsSection.Show();
|
userModsSection.Show();
|
||||||
userModsSelectOverlay.IsValidMod = m => SelectedItem.Value.AllowedMods.Any(a => a.GetType() == m.GetType());
|
userModsSelectOverlay.IsValidMod = m => item.NewValue.AllowedMods.Any(a => a.GetType() == m.GetType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
[Resolved(typeof(Room), nameof(Room.RoomID))]
|
[Resolved(typeof(Room), nameof(Room.RoomID))]
|
||||||
private Bindable<int?> roomId { get; set; }
|
private Bindable<int?> roomId { get; set; }
|
||||||
|
|
||||||
|
[Resolved(typeof(Room), nameof(Room.Playlist))]
|
||||||
|
private BindableList<PlaylistItem> playlist { get; set; }
|
||||||
|
|
||||||
private MatchSettingsOverlay settingsOverlay;
|
private MatchSettingsOverlay settingsOverlay;
|
||||||
private MatchLeaderboard leaderboard;
|
private MatchLeaderboard leaderboard;
|
||||||
|
|
||||||
@ -117,7 +120,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
new DrawableRoomPlaylistWithResults
|
new DrawableRoomPlaylistWithResults
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Items = { BindTarget = Playlist },
|
Items = { BindTarget = playlist },
|
||||||
SelectedItem = { BindTarget = SelectedItem },
|
SelectedItem = { BindTarget = SelectedItem },
|
||||||
RequestShowResults = item =>
|
RequestShowResults = item =>
|
||||||
{
|
{
|
||||||
@ -222,7 +225,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
|
|
||||||
// Set the first playlist item.
|
// Set the first playlist item.
|
||||||
// This is scheduled since updating the room and playlist may happen in an arbitrary order (via Room.CopyFrom()).
|
// This is scheduled since updating the room and playlist may happen in an arbitrary order (via Room.CopyFrom()).
|
||||||
Schedule(() => SelectedItem.Value = Playlist.FirstOrDefault());
|
Schedule(() => SelectedItem.Value = playlist.FirstOrDefault());
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user