From 671582a9255706334c67f75a0cece57a454be14a Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 10 Dec 2021 01:15:15 +0900 Subject: [PATCH] Allow host to enqeue items and items to be edited --- .../TestSceneAllPlayersQueueMode.cs | 4 +- .../Multiplayer/TestSceneHostOnlyQueueMode.cs | 24 ++++++++++- .../Multiplayer/TestSceneMultiplayer.cs | 3 +- .../TestSceneMultiplayerMatchSongSelect.cs | 2 +- .../Match/Playlist/MultiplayerPlaylist.cs | 9 +++- .../Match/Playlist/MultiplayerQueueList.cs | 6 ++- .../Multiplayer/MultiplayerMatchSongSelect.cs | 8 +++- .../Multiplayer/MultiplayerMatchSubScreen.cs | 42 +++++++------------ .../OnlinePlay/OnlinePlaySongSelect.cs | 12 +++--- 9 files changed, 67 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs index ccfae1deef..8373979308 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs @@ -87,9 +87,9 @@ namespace osu.Game.Tests.Visual.Multiplayer private void addItem(Func beatmap) { - AddStep("click edit button", () => + AddStep("click add button", () => { - InputManager.MoveMouseTo(this.ChildrenOfType().Single().AddOrEditPlaylistButton); + InputManager.MoveMouseTo(this.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs index 1de7289446..ccac3de304 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +using osu.Game.Screens.OnlinePlay; using osu.Game.Screens.OnlinePlay.Multiplayer; using osuTK.Input; @@ -74,11 +75,19 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("api room updated", () => Client.APIRoom?.QueueMode.Value == QueueMode.AllPlayers); } + [Test] + public void TestAddItemsAsHost() + { + addItem(() => OtherBeatmap); + + AddAssert("playlist contains two items", () => Client.APIRoom?.Playlist.Count == 2); + } + private void selectNewItem(Func beatmap) { AddStep("click edit button", () => { - InputManager.MoveMouseTo(this.ChildrenOfType().Single().AddOrEditPlaylistButton); + InputManager.MoveMouseTo(this.ChildrenOfType().First()); InputManager.Click(MouseButton.Left); }); @@ -90,5 +99,18 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen); AddUntilStep("selected item is new beatmap", () => Client.CurrentMatchPlayingItem.Value?.Beatmap.Value?.OnlineID == otherBeatmap.OnlineID); } + + private void addItem(Func beatmap) + { + AddStep("click add button", () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded); + AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap())); + AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen); + } } } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 2411f39ae3..5eb0abc830 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -416,8 +416,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("Enter song select", () => { var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen; - - ((MultiplayerMatchSubScreen)currentSubScreen).SelectBeatmap(); + ((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.CurrentMatchPlayingItem.Value); }); AddUntilStep("wait for song select", () => this.ChildrenOfType().FirstOrDefault()?.BeatmapSetsLoaded == true); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs index a5229702a8..d671673d3c 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs @@ -179,7 +179,7 @@ namespace osu.Game.Tests.Visual.Multiplayer public new BeatmapCarousel Carousel => base.Carousel; public TestMultiplayerMatchSongSelect(Room room, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null) - : base(room, beatmap, ruleset) + : base(room, null, beatmap, ruleset) { } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs index c3245b550f..4971489769 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,6 +20,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist { public readonly Bindable DisplayMode = new Bindable(); + /// + /// Invoked when an item requests to be edited. + /// + public Action RequestEdit; + private MultiplayerQueueList queueList; private MultiplayerHistoryList historyList; private bool firstPopulation = true; @@ -46,7 +52,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist queueList = new MultiplayerQueueList { RelativeSizeAxes = Axes.Both, - SelectedItem = { BindTarget = SelectedItem } + SelectedItem = { BindTarget = SelectedItem }, + RequestEdit = item => RequestEdit?.Invoke(item) }, historyList = new MultiplayerHistoryList { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs index 8832c9bd60..3e0f663d42 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs @@ -78,8 +78,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist private void updateDeleteButtonVisibility() { - AllowDeletion = (Item.OwnerID == api.LocalUser.Value.OnlineID || multiplayerClient.IsHost) - && SelectedItem.Value != Item; + bool isItemOwner = Item.OwnerID == api.LocalUser.Value.OnlineID || multiplayerClient.IsHost; + + AllowDeletion = isItemOwner && SelectedItem.Value != Item; + AllowEditing = isItemOwner; } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 44efef53f5..80a0289ba9 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -24,17 +24,22 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient client { get; set; } + private readonly PlaylistItem itemToEdit; + private LoadingLayer loadingLayer; /// /// Construct a new instance of multiplayer song select. /// /// The room. + /// The item to be edited. May be null, in which case a new item will be added to the playlist. /// An optional initial beatmap selection to perform. /// An optional initial ruleset selection to perform. - public MultiplayerMatchSongSelect(Room room, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null) + public MultiplayerMatchSongSelect(Room room, PlaylistItem itemToEdit = null, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null) : base(room) { + this.itemToEdit = itemToEdit; + if (beatmap != null || ruleset != null) { Schedule(() => @@ -61,6 +66,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer client.AddPlaylistItem(new MultiplayerPlaylistItem { + ID = itemToEdit?.ID ?? 0, BeatmapID = item.BeatmapID, BeatmapChecksum = item.Beatmap.Value.MD5Hash, RulesetID = item.RulesetID, diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 3a25bd7b06..96a9804067 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -14,7 +14,6 @@ using osu.Framework.Screens; using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; @@ -44,8 +43,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public override string ShortTitle => "room"; - public OsuButton AddOrEditPlaylistButton { get; private set; } - [Resolved] private MultiplayerClient client { get; set; } @@ -57,6 +54,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [CanBeNull] private IDisposable readyClickOperation; + private AddItemButton addItemButton; + public MultiplayerMatchSubScreen(Room room) : base(room) { @@ -134,12 +133,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer new Drawable[] { new OverlinedHeader("Beatmap") }, new Drawable[] { - AddOrEditPlaylistButton = new PurpleTriangleButton + addItemButton = new AddItemButton { RelativeSizeAxes = Axes.X, Height = 40, - Action = SelectBeatmap, - Alpha = 0 + Text = "Add item", + Action = () => OpenSongSelection(null) }, }, null, @@ -147,7 +146,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { new MultiplayerPlaylist { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + RequestEdit = OpenSongSelection } }, new[] @@ -220,12 +220,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } }; - internal void SelectBeatmap() + internal void OpenSongSelection(PlaylistItem itemToEdit) { if (!this.IsCurrentScreen()) return; - this.Push(new MultiplayerMatchSongSelect(Room)); + this.Push(new MultiplayerMatchSongSelect(Room, itemToEdit)); } protected override Drawable CreateFooter() => new MultiplayerMatchFooter @@ -385,23 +385,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer return; } - switch (client.Room.Settings.QueueMode) - { - case QueueMode.HostOnly: - AddOrEditPlaylistButton.Text = "Edit beatmap"; - AddOrEditPlaylistButton.Alpha = client.IsHost ? 1 : 0; - break; - - case QueueMode.AllPlayers: - case QueueMode.AllPlayersRoundRobin: - AddOrEditPlaylistButton.Text = "Add beatmap"; - AddOrEditPlaylistButton.Alpha = 1; - break; - - default: - AddOrEditPlaylistButton.Alpha = 0; - break; - } + addItemButton.Alpha = client.IsHost || Room.QueueMode.Value != QueueMode.HostOnly ? 1 : 0; Scheduler.AddOnce(UpdateMods); } @@ -466,7 +450,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer return; } - this.Push(new MultiplayerMatchSongSelect(Room, beatmap, ruleset)); + this.Push(new MultiplayerMatchSongSelect(Room, SelectedItem.Value, beatmap, ruleset)); } protected override void Dispose(bool isDisposing) @@ -481,5 +465,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer modSettingChangeTracker?.Dispose(); } + + public class AddItemButton : PurpleTriangleButton + { + } } } diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs index 4bc0b55433..63957caee3 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs @@ -33,14 +33,14 @@ namespace osu.Game.Screens.OnlinePlay [Resolved(typeof(Room), nameof(Room.Playlist))] protected BindableList Playlist { get; private set; } + [CanBeNull] + [Resolved(CanBeNull = true)] + protected IBindable SelectedItem { get; private set; } + protected override UserActivity InitialActivity => new UserActivity.InLobby(room); protected readonly Bindable> FreeMods = new Bindable>(Array.Empty()); - [CanBeNull] - [Resolved(CanBeNull = true)] - private IBindable selectedItem { get; set; } - private readonly FreeModSelectOverlay freeModSelectOverlay; private readonly Room room; @@ -80,8 +80,8 @@ namespace osu.Game.Screens.OnlinePlay // At this point, Mods contains both the required and allowed mods. For selection purposes, it should only contain the required mods. // Similarly, freeMods is currently empty but should only contain the allowed mods. - Mods.Value = selectedItem?.Value?.RequiredMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty(); - FreeMods.Value = selectedItem?.Value?.AllowedMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty(); + Mods.Value = SelectedItem?.Value?.RequiredMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty(); + FreeMods.Value = SelectedItem?.Value?.AllowedMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty(); Mods.BindValueChanged(onModsChanged); Ruleset.BindValueChanged(onRulesetChanged);