diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 01d9446bf6..5feebe8da1 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -104,47 +104,55 @@ namespace osu.Game.Online.Multiplayer public readonly Bindable Position = new Bindable(-1); /// - /// Copies the properties from another to this room. + /// Create a copy of this room, without information specific to it, such as Room ID or host /// - /// The room to copy - /// Whether the copy should exclude information unique to a specific room (i.e. when duplicating a room) - public void CopyFrom(Room other, bool duplicate = false) + public Room CreateCopy() { - if (!duplicate) + Room newRoom = new Room { - RoomID.Value = other.RoomID.Value; + Name = { Value = Name.Value }, + Availability = { Value = Availability.Value }, + Type = { Value = Type.Value }, + MaxParticipants = { Value = MaxParticipants.Value } + }; - if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) - Host.Value = other.Host.Value; + newRoom.Playlist.AddRange(Playlist); - ChannelId.Value = other.ChannelId.Value; - Status.Value = other.Status.Value; - ParticipantCount.Value = other.ParticipantCount.Value; - EndDate.Value = other.EndDate.Value; - - if (DateTimeOffset.Now >= EndDate.Value) - Status.Value = new RoomStatusEnded(); - - if (!RecentParticipants.SequenceEqual(other.RecentParticipants)) - { - RecentParticipants.Clear(); - RecentParticipants.AddRange(other.RecentParticipants); - } - - Position.Value = other.Position.Value; - } + return newRoom; + } + public void CopyFrom(Room other) + { + RoomID.Value = other.RoomID.Value; Name.Value = other.Name.Value; + if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) + Host.Value = other.Host.Value; + + ChannelId.Value = other.ChannelId.Value; + Status.Value = other.Status.Value; Availability.Value = other.Availability.Value; Type.Value = other.Type.Value; MaxParticipants.Value = other.MaxParticipants.Value; + ParticipantCount.Value = other.ParticipantCount.Value; + EndDate.Value = other.EndDate.Value; + + if (DateTimeOffset.Now >= EndDate.Value) + Status.Value = new RoomStatusEnded(); if (!Playlist.SequenceEqual(other.Playlist)) { Playlist.Clear(); Playlist.AddRange(other.Playlist); } + + if (!RecentParticipants.SequenceEqual(other.RecentParticipants)) + { + RecentParticipants.Clear(); + RecentParticipants.AddRange(other.RecentParticipants); + } + + Position.Value = other.Position.Value; } public bool ShouldSerializeRoomID() => false; diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index 64fbae2503..db75df6054 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components public event Action StateChanged; - public Action DuplicateRoom; + public Action DuplicateRoom; private readonly Box selectionBox; private CachedModelDependencyContainer dependencies; @@ -239,7 +239,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuMenuItem("Duplicate", MenuItemType.Standard, () => DuplicateRoom?.Invoke(Room)) + new OsuMenuItem("Create copy", MenuItemType.Standard, DuplicateRoom) }; } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index f112dd80ee..206ce8da0f 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -38,7 +38,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components [Resolved] private IRoomManager roomManager { get; set; } - public Action DuplicateRoom; + [Resolved] + private LoungeSubScreen loungeSubScreen { get; set; } public RoomsContainer() { @@ -96,7 +97,13 @@ namespace osu.Game.Screens.Multi.Lounge.Components { roomFlow.Add(new DrawableRoom(room) { - DuplicateRoom = DuplicateRoom, + DuplicateRoom = () => + { + Room newRoom = room.CreateCopy(); + newRoom.Name.Value = $"Copy of {room.Name.Value}"; + + loungeSubScreen.Open(newRoom); + }, Action = () => { if (room == selectedRoom.Value) diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 5d68386398..a5b2499c76 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -18,6 +18,7 @@ using osu.Game.Screens.Multi.Match; namespace osu.Game.Screens.Multi.Lounge { + [Cached] public class LoungeSubScreen : MultiplayerSubScreen { public override string Title => "Lounge"; @@ -62,18 +63,7 @@ namespace osu.Game.Screens.Multi.Lounge RelativeSizeAxes = Axes.Both, ScrollbarOverlapsContent = false, Padding = new MarginPadding(10), - Child = roomsContainer = new RoomsContainer - { - JoinRequested = joinRequested, - DuplicateRoom = room => - { - Room newRoom = new Room(); - newRoom.CopyFrom(room, true); - newRoom.Name.Value = $"Copy of {room.Name.Value}"; - - Open(newRoom); - } - } + Child = roomsContainer = new RoomsContainer { JoinRequested = joinRequested } }, loadingLayer = new LoadingLayer(roomsContainer), }