1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 15:12:57 +08:00

Allow host to enqeue items and items to be edited

This commit is contained in:
Dan Balasescu 2021-12-10 01:15:15 +09:00
parent 048a495115
commit 671582a925
9 changed files with 67 additions and 43 deletions

View File

@ -87,9 +87,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void addItem(Func<BeatmapInfo> beatmap) private void addItem(Func<BeatmapInfo> beatmap)
{ {
AddStep("click edit button", () => AddStep("click add button", () =>
{ {
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen>().Single().AddOrEditPlaylistButton); InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Screens.OnlinePlay;
using osu.Game.Screens.OnlinePlay.Multiplayer; using osu.Game.Screens.OnlinePlay.Multiplayer;
using osuTK.Input; using osuTK.Input;
@ -74,11 +75,19 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("api room updated", () => Client.APIRoom?.QueueMode.Value == QueueMode.AllPlayers); 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<BeatmapInfo> beatmap) private void selectNewItem(Func<BeatmapInfo> beatmap)
{ {
AddStep("click edit button", () => AddStep("click edit button", () =>
{ {
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen>().Single().AddOrEditPlaylistButton); InputManager.MoveMouseTo(this.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistEditButton>().First());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
@ -90,5 +99,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen); AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
AddUntilStep("selected item is new beatmap", () => Client.CurrentMatchPlayingItem.Value?.Beatmap.Value?.OnlineID == otherBeatmap.OnlineID); AddUntilStep("selected item is new beatmap", () => Client.CurrentMatchPlayingItem.Value?.Beatmap.Value?.OnlineID == otherBeatmap.OnlineID);
} }
private void addItem(Func<BeatmapInfo> beatmap)
{
AddStep("click add button", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().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);
}
} }
} }

View File

@ -416,8 +416,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("Enter song select", () => AddStep("Enter song select", () =>
{ {
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen; var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.CurrentMatchPlayingItem.Value);
((MultiplayerMatchSubScreen)currentSubScreen).SelectBeatmap();
}); });
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true); AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);

View File

@ -179,7 +179,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public new BeatmapCarousel Carousel => base.Carousel; public new BeatmapCarousel Carousel => base.Carousel;
public TestMultiplayerMatchSongSelect(Room room, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null) public TestMultiplayerMatchSongSelect(Room room, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null)
: base(room, beatmap, ruleset) : base(room, null, beatmap, ruleset)
{ {
} }
} }

View File

@ -1,6 +1,7 @@
// 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;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@ -19,6 +20,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
{ {
public readonly Bindable<MultiplayerPlaylistDisplayMode> DisplayMode = new Bindable<MultiplayerPlaylistDisplayMode>(); public readonly Bindable<MultiplayerPlaylistDisplayMode> DisplayMode = new Bindable<MultiplayerPlaylistDisplayMode>();
/// <summary>
/// Invoked when an item requests to be edited.
/// </summary>
public Action<PlaylistItem> RequestEdit;
private MultiplayerQueueList queueList; private MultiplayerQueueList queueList;
private MultiplayerHistoryList historyList; private MultiplayerHistoryList historyList;
private bool firstPopulation = true; private bool firstPopulation = true;
@ -46,7 +52,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
queueList = new MultiplayerQueueList queueList = new MultiplayerQueueList
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
SelectedItem = { BindTarget = SelectedItem } SelectedItem = { BindTarget = SelectedItem },
RequestEdit = item => RequestEdit?.Invoke(item)
}, },
historyList = new MultiplayerHistoryList historyList = new MultiplayerHistoryList
{ {

View File

@ -78,8 +78,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
private void updateDeleteButtonVisibility() private void updateDeleteButtonVisibility()
{ {
AllowDeletion = (Item.OwnerID == api.LocalUser.Value.OnlineID || multiplayerClient.IsHost) bool isItemOwner = Item.OwnerID == api.LocalUser.Value.OnlineID || multiplayerClient.IsHost;
&& SelectedItem.Value != Item;
AllowDeletion = isItemOwner && SelectedItem.Value != Item;
AllowEditing = isItemOwner;
} }
} }
} }

View File

@ -24,17 +24,22 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
[Resolved] [Resolved]
private MultiplayerClient client { get; set; } private MultiplayerClient client { get; set; }
private readonly PlaylistItem itemToEdit;
private LoadingLayer loadingLayer; private LoadingLayer loadingLayer;
/// <summary> /// <summary>
/// Construct a new instance of multiplayer song select. /// Construct a new instance of multiplayer song select.
/// </summary> /// </summary>
/// <param name="room">The room.</param> /// <param name="room">The room.</param>
/// <param name="itemToEdit">The item to be edited. May be null, in which case a new item will be added to the playlist.</param>
/// <param name="beatmap">An optional initial beatmap selection to perform.</param> /// <param name="beatmap">An optional initial beatmap selection to perform.</param>
/// <param name="ruleset">An optional initial ruleset selection to perform.</param> /// <param name="ruleset">An optional initial ruleset selection to perform.</param>
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) : base(room)
{ {
this.itemToEdit = itemToEdit;
if (beatmap != null || ruleset != null) if (beatmap != null || ruleset != null)
{ {
Schedule(() => Schedule(() =>
@ -61,6 +66,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
client.AddPlaylistItem(new MultiplayerPlaylistItem client.AddPlaylistItem(new MultiplayerPlaylistItem
{ {
ID = itemToEdit?.ID ?? 0,
BeatmapID = item.BeatmapID, BeatmapID = item.BeatmapID,
BeatmapChecksum = item.Beatmap.Value.MD5Hash, BeatmapChecksum = item.Beatmap.Value.MD5Hash,
RulesetID = item.RulesetID, RulesetID = item.RulesetID,

View File

@ -14,7 +14,6 @@ using osu.Framework.Screens;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online; using osu.Game.Online;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
@ -44,8 +43,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
public override string ShortTitle => "room"; public override string ShortTitle => "room";
public OsuButton AddOrEditPlaylistButton { get; private set; }
[Resolved] [Resolved]
private MultiplayerClient client { get; set; } private MultiplayerClient client { get; set; }
@ -57,6 +54,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
[CanBeNull] [CanBeNull]
private IDisposable readyClickOperation; private IDisposable readyClickOperation;
private AddItemButton addItemButton;
public MultiplayerMatchSubScreen(Room room) public MultiplayerMatchSubScreen(Room room)
: base(room) : base(room)
{ {
@ -134,12 +133,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
new Drawable[] { new OverlinedHeader("Beatmap") }, new Drawable[] { new OverlinedHeader("Beatmap") },
new Drawable[] new Drawable[]
{ {
AddOrEditPlaylistButton = new PurpleTriangleButton addItemButton = new AddItemButton
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = 40, Height = 40,
Action = SelectBeatmap, Text = "Add item",
Alpha = 0 Action = () => OpenSongSelection(null)
}, },
}, },
null, null,
@ -147,7 +146,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{ {
new MultiplayerPlaylist new MultiplayerPlaylist
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both,
RequestEdit = OpenSongSelection
} }
}, },
new[] new[]
@ -220,12 +220,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
} }
}; };
internal void SelectBeatmap() internal void OpenSongSelection(PlaylistItem itemToEdit)
{ {
if (!this.IsCurrentScreen()) if (!this.IsCurrentScreen())
return; return;
this.Push(new MultiplayerMatchSongSelect(Room)); this.Push(new MultiplayerMatchSongSelect(Room, itemToEdit));
} }
protected override Drawable CreateFooter() => new MultiplayerMatchFooter protected override Drawable CreateFooter() => new MultiplayerMatchFooter
@ -385,23 +385,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
return; return;
} }
switch (client.Room.Settings.QueueMode) addItemButton.Alpha = client.IsHost || Room.QueueMode.Value != QueueMode.HostOnly ? 1 : 0;
{
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;
}
Scheduler.AddOnce(UpdateMods); Scheduler.AddOnce(UpdateMods);
} }
@ -466,7 +450,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
return; return;
} }
this.Push(new MultiplayerMatchSongSelect(Room, beatmap, ruleset)); this.Push(new MultiplayerMatchSongSelect(Room, SelectedItem.Value, beatmap, ruleset));
} }
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
@ -481,5 +465,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
modSettingChangeTracker?.Dispose(); modSettingChangeTracker?.Dispose();
} }
public class AddItemButton : PurpleTriangleButton
{
}
} }
} }

View File

@ -33,14 +33,14 @@ namespace osu.Game.Screens.OnlinePlay
[Resolved(typeof(Room), nameof(Room.Playlist))] [Resolved(typeof(Room), nameof(Room.Playlist))]
protected BindableList<PlaylistItem> Playlist { get; private set; } protected BindableList<PlaylistItem> Playlist { get; private set; }
[CanBeNull]
[Resolved(CanBeNull = true)]
protected IBindable<PlaylistItem> SelectedItem { get; private set; }
protected override UserActivity InitialActivity => new UserActivity.InLobby(room); protected override UserActivity InitialActivity => new UserActivity.InLobby(room);
protected readonly Bindable<IReadOnlyList<Mod>> FreeMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>()); protected readonly Bindable<IReadOnlyList<Mod>> FreeMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
[CanBeNull]
[Resolved(CanBeNull = true)]
private IBindable<PlaylistItem> selectedItem { get; set; }
private readonly FreeModSelectOverlay freeModSelectOverlay; private readonly FreeModSelectOverlay freeModSelectOverlay;
private readonly Room room; 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. // 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. // Similarly, freeMods is currently empty but should only contain the allowed mods.
Mods.Value = selectedItem?.Value?.RequiredMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty<Mod>(); Mods.Value = SelectedItem?.Value?.RequiredMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty<Mod>();
FreeMods.Value = selectedItem?.Value?.AllowedMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty<Mod>(); FreeMods.Value = SelectedItem?.Value?.AllowedMods.Select(m => m.DeepClone()).ToArray() ?? Array.Empty<Mod>();
Mods.BindValueChanged(onModsChanged); Mods.BindValueChanged(onModsChanged);
Ruleset.BindValueChanged(onRulesetChanged); Ruleset.BindValueChanged(onRulesetChanged);